RFC 1661

The Point-to-Point Protocol (PPP)

๐Ÿ“… published July 1994, from ietf

RFC 1661: The Point-to-Point Protocol (PPP) ๐ŸŽ€

okay bestie, this is RFC 1661, the PPP spec ๐Ÿ’–. W. Simpson is the Editor, and it's from Daydreamer ๐Ÿงš. It's dated July 1994 ๐ŸŒธ. It's on the Standards Track ๐Ÿ”ฅ and it's in STD 51 ๐Ÿ‘‘. It obsoletes RFC 1548 โœจ.


Status of This Memo ๐Ÿ“œ

so this doc specifies an Internet standards track protocol for the Internet community ๐ŸŒˆ, and it's literally asking for discussion and suggestions for improvements ๐Ÿ’…. For the standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1) ๐Ÿ‘‘. Distribution of this memo is unlimited, so share it with everyone ๐Ÿฆ‹.

Abstract ๐Ÿซถ

PPP gives you a standard way to transport multi-protocol datagrams over point-to-point links ๐Ÿ”—. It has three main parts:

  1. a method for encapsulating multi-protocol datagrams ๐ŸŽ€
  2. a Link Control Protocol (LCP) for establishing, configuring, and testing the data-link connection ๐Ÿ› ๏ธ
  3. a family of Network Control Protocols (NCPs) for establishing and configuring different network-layer protocols ๐ŸŒธ

This doc defines the PPP organization and methodology, plus the PPP encapsulation ๐Ÿ’œ. It also brings in an extensible option negotiation mechanism that can negotiate a rich assortment of configuration parameters and gives you extra management functions ๐Ÿ’…. The LCP is described in terms of this mechanism โœจ.

Table of Contents ๐Ÿงพ

     1.     Introduction ..........................................    1
        1.1       Specification of Requirements ...................    2
        1.2       Terminology .....................................    3

     2.     PPP Encapsulation .....................................    4
     3.     PPP Link Operation ....................................    6
        3.1       Overview ........................................    6
        3.2       Phase Diagram ...................................    6
        3.3       Link Dead (physical-layer not ready) ............    7
        3.4       Link Establishment Phase ........................    7
        3.5       Authentication Phase ............................    8
        3.6       Network-Layer Protocol Phase ....................    8
        3.7       Link Termination Phase ..........................    9

     4.     The Option Negotiation Automaton ......................   11
        4.1       State Transition Table ..........................   12
        4.2       States ..........................................   14
        4.3       Events ..........................................   16
        4.4       Actions .........................................   21
        4.5       Loop Avoidance ..................................   23
        4.6       Counters and Timers .............................   24

     5.     LCP Packet Formats ....................................   26
        5.1       Configure-Request ...............................   28
        5.2       Configure-Ack ...................................   29
        5.3       Configure-Nak ...................................   30
        5.4       Configure-Reject ................................   31
        5.5       Terminate-Request and Terminate-Ack .............   33
        5.6       Code-Reject .....................................   34
        5.7       Protocol-Reject .................................   35
        5.8       Echo-Request and Echo-Reply .....................   36
        5.9       Discard-Request .................................   37

     6.     LCP Configuration Options .............................   39
        6.1       Maximum-Receive-Unit (MRU) ......................   41
        6.2       Authentication-Protocol .........................   42
        6.3       Quality-Protocol ................................   43
        6.4       Magic-Number ....................................   45
        6.5       Protocol-Field-Compression (PFC) ................   48
        6.6       Address-and-Control-Field-Compression (ACFC)

     SECURITY CONSIDERATIONS ......................................   51
     REFERENCES ...................................................   51
     ACKNOWLEDGEMENTS .............................................   51
     CHAIR'S ADDRESS ..............................................   52
     EDITOR'S ADDRESS .............................................   52

1. Introduction ๐ŸŒธ

okay so PPP is built for simple links that carry packets between two peers ๐Ÿ’Œ. These links give you full-duplex, simultaneous bi-directional operation, and they're assumed to deliver packets in order โœจ. The goal is a common solution for easily connecting a wide variety of hosts, bridges and routers [1] ๐ŸŒˆ.

Encapsulation ๐ŸŽ€

The PPP encapsulation lets you multiplex different network-layer protocols at the same time over the same link ๐Ÿงš. It was carefully designed to stay compatible with the most commonly used supporting hardware ๐Ÿ”ง.

Only 8 additional octets are needed to form the encapsulation when you're using the default HDLC-like framing ๐Ÿ’–. When bandwidth is at a premium, the encapsulation and framing can be shortened to 2 or 4 octets ๐Ÿฆ‹.

To support high-speed implementations, the default encapsulation uses only simple fields, and only one of them needs to be examined for demultiplexing ๐Ÿ”ฅ. The default header and information fields fall on 32-bit boundaries, and the trailer may be padded to an arbitrary boundary ๐Ÿ’….

Link Control Protocol ๐Ÿ› ๏ธ

PPP has a Link Control Protocol (LCP) so it can be versatile enough to port to all kinds of environments ๐ŸŒธ. The LCP automatically agrees on the encapsulation format options, handles varying limits on packet sizes, detects a looped-back link and other common misconfiguration errors, and terminates the link ๐Ÿ‘‘. There are also optional extras: authenticating the identity of the peer on the link, and figuring out when a link is functioning properly and when it's failing ๐Ÿซถ.

Network Control Protocols ๐ŸŒ

Point-to-Point links tend to make lots of problems with the current family of network protocols worse ๐Ÿ˜ญ. Assigning and managing IP addresses is already a problem in LAN environments, and it's especially hard over circuit-switched point-to-point links like dial-up modem servers ๐Ÿ“ž. A family of Network Control Protocols (NCPs) handles these problems, and each one manages the specific needs of its own network-layer protocol ๐Ÿ’œ. These NCPs are defined in companion documents ๐Ÿ“š.

Configuration โญ

PPP links are supposed to be easy to configure ๐ŸŽ€. The standard defaults handle all the common configurations, so you mostly don't have to think about it ๐Ÿ’–. An implementor can specify improvements to the default configuration, and those get automatically communicated to the peer with no operator intervention needed ๐Ÿงš. And if the link needs to work in an environment where it otherwise couldn't, the operator can explicitly configure options for it ๐Ÿ”ฅ.

This self-configuration runs through an extensible option negotiation mechanism, where each end of the link describes its capabilities and requirements to the other ๐Ÿ’…. This mechanism is specified in terms of the Link Control Protocol (LCP), but the same facilities are designed to be reused by other control protocols, especially the NCPs ๐ŸŒˆ.

1.1. Specification of Requirements ๐Ÿ“

so this document uses several words to signal the requirements of the specification ๐ŸŽ€. They're often capitalized, and here's what each one means ๐Ÿ‘‘:

   MUST      This word, or the adjective "required", means that the
             definition is an absolute requirement of the specification.

   MUST NOT  This phrase means that the definition is an absolute
             prohibition of the specification.

   SHOULD    This word, or the adjective "recommended", means that there
             may exist valid reasons in particular circumstances to
             ignore this item, but the full implications must be
             understood and carefully weighed before choosing a
             different course.

   MAY       This word, or the adjective "optional", means that this
             item is one of an allowed set of alternatives.  An
             implementation which does not include this option MUST be
             prepared to interoperate with another implementation which
             does include the option.

1.2. Terminology ๐Ÿ“–

this doc uses these terms a lot ๐Ÿ’•:

  • datagram ๐Ÿ“ฆ: The unit of transmission in the network layer (such as IP). A datagram may be encapsulated in one or more packets passed to the data link layer.
  • frame ๐Ÿ–ผ๏ธ: The unit of transmission at the data link layer. A frame may include a header and/or a trailer, along with some number of units of data.
  • packet ๐ŸŽ: The basic unit of encapsulation, which is passed across the interface between the network layer and the data link layer. A packet is usually mapped to a frame. The exceptions are when data link layer fragmentation is being performed, or when multiple packets are incorporated into a single frame.
  • peer ๐Ÿซ‚: The other end of the point-to-point link.
  • silently discard ๐Ÿคซ: The implementation discards the packet without further processing. The implementation SHOULD provide the capability of logging the error, including the contents of the silently discarded packet, and SHOULD record the event in a statistics counter.

2. PPP Encapsulation โœจ

okay so PPP encapsulation is basically how PPP sorts out which protocol a datagram belongs to ๐ŸŽ€ It's giving multiprotocol organization. This encapsulation needs framing so the receiver can tell where a packet starts and stops. The companion docs spell out how framing works, so go read those if you want the details ๐Ÿงš

Here's the lineup of fields, sent left to right:

        +----------+-------------+---------+
        | Protocol | Information | Padding |
        | 8/16 bits|      *      |    *    |
        +----------+-------------+---------+

Protocol Field

the Protocol field is one or two octets, and its value tells you which datagram is riding inside the Information field ๐Ÿ’… It goes most significant octet first, both when it's sent and when it's received.

this field follows the ISO 3309 extension mechanism for address fields, which is very giving tbh. Every Protocol value MUST be odd, meaning the least significant bit of the least significant octet MUST equal "1" ๐Ÿ”ฅ And every Protocol MUST be assigned so that the least significant bit of the most significant octet equals "0". Frames that break these rules MUST be treated as having an unrecognized Protocol. no exceptions, bestie ๐Ÿ˜ญ

the ranges have their own vibes:

  • Values from "0" to "3" are the network-layer protocols carrying specific packets ๐ŸŒˆ
  • Values from "8" to "b" belong to the matching Network Control Protocols (NCPs), if there is one.
  • Values from "4" to "7" are for low-volume protocols that don't have an NCP ๐Ÿ“
  • Values from "c" to "f" are link-layer Control Protocols, like LCP ๐Ÿ’œ

the most up-to-date values live in the latest "Assigned Numbers" RFC [2]. This spec reserves the following ones:

Value (in hex)  Protocol Name

0001            Padding Protocol
0003 to 001f    reserved (transparency inefficient)
007d            reserved (Control Escape)
00cf            reserved (PPP NLPID)
00ff            reserved (compression inefficient)

8001 to 801f    unused
807d            unused
80cf            unused
80ff            unused

c021            Link Control Protocol
c023            Password Authentication Protocol
c025            Link Quality Report
c223            Challenge Handshake Authentication Protocol

if you're building a brand new protocol, you MUST get a number from the Internet Assigned Numbers Authority (IANA), at IANA@isi.edu. no shortcuts, periodt ๐Ÿ’–

Information Field

the Information field is zero or more octets ๐Ÿฆ‹ It holds the datagram for whatever protocol the Protocol field names.

the largest the Information field can be, counting Padding but not the Protocol field, is called the Maximum Receive Unit (MRU). The default is 1500 octets โœจ Consenting PPP implementations can agree on a different MRU through negotiation, so the number isn't set in stone.

Padding

on transmission, the Information field MAY be padded with any number of octets, up to the MRU ๐ŸŒธ It's on each protocol to tell the padding apart from the real information. that's a whole vibe check ๐Ÿ™ˆ

3.1. Overview

so to get communications going over a point-to-point link, each end of the PPP link MUST first send LCP packets to configure and test the data link ๐Ÿ’… Once the link is up, the peer MAY be authenticated.

after that, PPP MUST send NCP packets to pick and set up one or more network-layer protocols. Once every chosen network-layer protocol is configured, its datagrams can finally flow over the link ๐ŸŽ€

the link stays configured until explicit LCP or NCP packets close it down, or until an outside event happens (like an inactivity timer running out or a network admin stepping in) ๐Ÿงš

3.2. Phase Diagram

while PPP is configuring, maintaining and terminating the point-to-point link, it moves through several distinct phases. Here's the simplified state diagram:

+------+        +-----------+           +--------------+
|      | UP     |           | OPENED    |              | SUCCESS/NONE
| Dead |------->| Establish |---------->| Authenticate |--+
|      |        |           |           |              |  |
+------+        +-----------+           +--------------+  |
   ^               |                        |             |
   |          FAIL |                   FAIL |             |
   +<--------------+             +----------+             |
   |                             |                        |
   |            +-----------+    |           +---------+  |
   |       DOWN |           |    |   CLOSING |         |  |
   +------------| Terminate |<---+<----------| Network |<-+
                |           |                |         |
                +-----------+                +---------+

not every transition is drawn in this diagram, so the following semantics MUST be followed ๐Ÿ‘‘

the link always starts and ends in this phase ๐ŸŒˆ When an external event (like carrier detection or a network admin's configuration) shows the physical layer is ready to go, PPP moves on to the Link Establishment phase.

while in this phase, the LCP automaton (we'll get to it later) sits in the Initial or Starting states. Moving into Link Establishment sends an Up event to the LCP automaton โœจ

Implementation Note: Typically, a link goes back to this phase on its own after a modem disconnects. On a hard-wired link, this phase might be super short, just long enough to detect that the device is there ๐Ÿงš

the Link Control Protocol (LCP) sets up the connection by trading Configure packets ๐Ÿค The exchange is finished, and the LCP Opened state is reached, once a Configure-Ack packet (more on this later) has been both sent and received.

all Configuration Options start at their default values unless the configuration exchange changes them. Check out the chapter on LCP Configuration Options for the full tea โ˜•

it's important to note that LCP only configures Configuration Options that don't depend on a particular network-layer protocol ๐Ÿ’– Each network-layer protocol gets configured by its own Network Control Protocol (NCP) during the Network-Layer Protocol phase.

any non-LCP packets received during this phase MUST be silently discarded ๐Ÿ™…โ€โ™€๏ธ

getting a Configure-Request from LCP sends you back to the Link Establishment phase, whether you were in the Network-Layer Protocol phase or the Authentication phase ๐Ÿ”„

3.5. Authentication Phase

on some links, you might want the peer to prove who it is before any network-layer protocol packets get exchanged ๐Ÿ”

by default, authentication is not mandatory. But if an implementation wants its peer to authenticate with a specific authentication protocol, it MUST request that protocol during the Link Establishment phase ๐Ÿ’…

authentication SHOULD happen as soon as possible after the link is established. Link quality determination MAY happen at the same time, though ๐Ÿฆ‹ An implementation MUST NOT let link quality determination packets hold up authentication forever.

moving from the Authentication phase to the Network-Layer Protocol phase MUST NOT happen until authentication has finished. If authentication fails, the authenticator SHOULD go to the Link Termination phase instead ๐Ÿ’€

during this phase, only Link Control Protocol, authentication protocol, and link quality monitoring packets are allowed. Every other packet received here MUST be silently discarded ๐Ÿ™ˆ

Implementation Notes: An implementation SHOULD NOT fail authentication just because of a timeout or a lack of response. The authentication SHOULD allow some kind of retransmission, and only head to the Link Termination phase once a number of authentication attempts has been exceeded ๐Ÿซถ The implementation that starts the Link Termination phase is the one that refused authentication to its peer ๐Ÿ‘‘

3.6. Network-Layer Protocol Phase

once PPP has finished the earlier phases, each network-layer protocol (like IP, IPX, or AppleTalk) MUST be configured separately by its appropriate Network Control Protocol (NCP) ๐ŸŒธ

each NCP MAY be Opened and Closed at any time ๐Ÿ”

Implementation Note: an implementation might take a lot of time to determine link quality at first, so implementations SHOULD avoid fixed timeouts when waiting for their peers to configure an NCP โณ

after an NCP reaches the Opened state, PPP carries the matching network-layer protocol packets ๐Ÿš€ Any supported network-layer protocol packets that show up while the corresponding NCP is not Opened MUST be silently discarded.

Implementation Note: while LCP is Opened, any protocol packet the implementation doesn't support MUST be returned in a Protocol-Reject (we'll cover that one later). Only supported protocols get silently discarded ๐Ÿ’…

during this phase, link traffic can be any mix of LCP, NCP, and network-layer protocol packets ๐ŸŒˆ

PPP can end the link at any time ๐Ÿ’€ That might happen because of loss of carrier, an authentication failure, a link quality failure, an idle-period timer expiring, or someone administratively closing the link.

LCP closes the link through an exchange of Terminate packets ๐ŸŽ€ When the link is closing, PPP tells the network-layer protocols so they can do whatever they need to do.

after the Terminate packets have been exchanged, the implementation SHOULD signal the physical layer to disconnect so the link termination actually sticks, especially after an authentication failure ๐Ÿ”Œ The sender of the Terminate-Request SHOULD disconnect after getting a Terminate-Ack, or after the Restart counter runs out. The receiver of a Terminate-Request SHOULD wait for its peer to disconnect, and MUST NOT disconnect until at least one Restart time has passed after it sent a Terminate-Ack โฐ PPP SHOULD then head to the Link Dead phase.

any non-LCP packets received during this phase MUST be silently discarded ๐Ÿ™…โ€โ™€๏ธ

Implementation Note: closing the link with LCP is enough. There's no need for each NCP to send a flurry of Terminate packets ๐Ÿ’… And the fact that one NCP has Closed is not a good enough reason to terminate the PPP link, even if that NCP was the only one in the Opened state ๐Ÿฆ‹

4. The Option Negotiation Automaton โœจ

okay so this is the brain of the whole negotiation thing ๐Ÿง ๐Ÿ’œ It's a finite-state automaton, which just means a little machine that's always sitting in one state and hops to another based on events (stuff that happens to it, like getting an Open command, a timer running out, or a packet showing up) and then does actions (stuff it does back, like starting a timer or sending a packet to the peer). Slay. ๐Ÿ’…

Some packet types are lumped together in the automaton descriptions: Configure-Naks and Configure-Rejects, Code-Rejects and Protocol-Rejects, and Echo-Requests, Echo-Replies and Discard-Requests. ๐Ÿ™ˆ They don't do the same job, and we'll get to why later, but the machine treats them exactly the same, so they always cause the same transitions. Lowkey helpful for keeping the table small. ๐ŸŽ€

Here are the events and actions, with their short names:

Events                                   Actions

Up   = lower layer is Up                 tlu = This-Layer-Up
Down = lower layer is Down               tld = This-Layer-Down
Open = administrative Open               tls = This-Layer-Started
Close= administrative Close              tlf = This-Layer-Finished

TO+  = Timeout with counter > 0          irc = Initialize-Restart-Count
TO-  = Timeout with counter expired      zrc = Zero-Restart-Count

RCR+ = Receive-Configure-Request (Good)  scr = Send-Configure-Request
RCR- = Receive-Configure-Request (Bad)
RCA  = Receive-Configure-Ack             sca = Send-Configure-Ack
RCN  = Receive-Configure-Nak/Rej         scn = Send-Configure-Nak/Rej

RTR  = Receive-Terminate-Request         str = Send-Terminate-Request
RTA  = Receive-Terminate-Ack             sta = Send-Terminate-Ack

RUC  = Receive-Unknown-Code              scj = Send-Code-Reject
RXJ+ = Receive-Code-Reject (permitted)
    or Receive-Protocol-Reject
RXJ- = Receive-Code-Reject (catastrophic)
    or Receive-Protocol-Reject
RXR  = Receive-Echo-Request              ser = Send-Echo-Reply
    or Receive-Echo-Reply
    or Receive-Discard-Request

4.1. State Transition Table

Here's the full state transition table. ๐Ÿฆ‹ States go across the top and events go down the side. Each cell is written as action/new-state, and if there are several actions they're separated by commas (they can wrap onto the next line if they need the room). The order of multiple actions doesn't matter, so do them in whatever order is easiest for your code. ๐ŸŒธ A state might have a letter after it, which points to a footnote. A dash ('-') means that transition is illegal, so it's basically a "nope, not happening" ๐Ÿ™…โ€โ™€๏ธ

      | State
      |    0         1         2         3         4         5
Events| Initial   Starting  Closed    Stopped   Closing   Stopping
------+-----------------------------------------------------------
 Up   |    2     irc,scr/6     -         -         -         -
 Down |    -         -         0       tls/1       0         1
 Open |  tls/1       1     irc,scr/6     3r        5r        5r
 Close|    0       tlf/0       2         2         4         4
      |
  TO+ |    -         -         -         -       str/4     str/5
  TO- |    -         -         -         -       tlf/2     tlf/3
      |
 RCR+ |    -         -       sta/2 irc,scr,sca/8   4         5
 RCR- |    -         -       sta/2 irc,scr,scn/6   4         5
 RCA  |    -         -       sta/2     sta/3       4         5
 RCN  |    -         -       sta/2     sta/3       4         5
      |
 RTR  |    -         -       sta/2     sta/3     sta/4     sta/5
 RTA  |    -         -         2         3       tlf/2     tlf/3
      |
 RUC  |    -         -       scj/2     scj/3     scj/4     scj/5
 RXJ+ |    -         -         2         3         4         5
 RXJ- |    -         -       tlf/2     tlf/3     tlf/2     tlf/3
      |
 RXR  |    -         -         2         3         4         5
      | State
      |    6         7         8           9
Events| Req-Sent  Ack-Rcvd  Ack-Sent    Opened
------+-----------------------------------------
 Up   |    -         -         -           -
 Down |    1         1         1         tld/1
 Open |    6         7         8           9r
 Close|irc,str/4 irc,str/4 irc,str/4 tld,irc,str/4
      |
  TO+ |  scr/6     scr/6     scr/8         -
  TO- |  tlf/3p    tlf/3p    tlf/3p        -
      |
 RCR+ |  sca/8   sca,tlu/9   sca/8   tld,scr,sca/8
 RCR- |  scn/6     scn/7     scn/6   tld,scr,scn/6
 RCA  |  irc/7     scr/6x  irc,tlu/9   tld,scr/6x
 RCN  |irc,scr/6   scr/6x  irc,scr/8   tld,scr/6x
      |
 RTR  |  sta/6     sta/6     sta/6   tld,zrc,sta/5
 RTA  |    6         6         8       tld,scr/6
      |
 RUC  |  scj/6     scj/7     scj/8       scj/9
 RXJ+ |    6         6         8           9
 RXJ- |  tlf/3     tlf/3     tlf/3   tld,irc,str/5
      |
 RXR  |    6         7         8         ser/9

Next, the Restart timer. โฐ You can tell which states have it running by spotting the TO events in them. Only three actions start or restart it: Send-Configure-Request, Send-Terminate-Request and Zero-Restart-Count. And whenever the machine moves from a state where the timer is running to a state where it isn't, the timer gets stopped. Simple, but so important. ๐Ÿ’–

Two more things to know about the design. The events and actions follow a message passing architecture, not a signalling architecture. ๐Ÿ“จ So if you need an action to control specific signals (like DTR), you'll probably need extra actions for that. ๐Ÿ”Œ

And these footnote markers explain some special cases:

  • [p] is the Passive option. Check the Stopped state discussion for the deets. ๐Ÿงš
  • [r] is the Restart option. Check the Open event discussion. ๐Ÿ”„
  • [x] is the crossed connection. Check the RCA event discussion. โœจ

4.2. States

Okay, now let's walk through each state in more detail! ๐ŸŒˆ

Initial

In the Initial state, the lower layer is unavailable (Down), and no Open has occurred. ๐Ÿ˜ด The Restart timer is not running here.

Starting

Starting is the Open-side buddy of Initial. โœจ An administrative Open has been started, but the lower layer is still Down, so we're just waiting around. The Restart timer is not running in Starting either.

When the lower layer comes Up, a Configure-Request gets sent. ๐Ÿš€

Closed

In Closed, the link is available (Up), but no Open has happened yet. ๐ŸŒธ The Restart timer is not running in Closed.

If a Configure-Request shows up here, a Terminate-Ack gets sent back. Terminate-Acks are silently discarded so we don't end up in a loop. ๐Ÿ”๐Ÿ™…โ€โ™€๏ธ

Stopped

Stopped is the Open-side buddy of Closed. ๐Ÿ‘ฏโ€โ™€๏ธ The automaton lands here when it's waiting for a Down event after the This-Layer-Finished action, or after it has sent a Terminate-Ack. The Restart timer is not running in Stopped.

When a Configure-Request comes in, an appropriate response is sent. If it's any other packet, a Terminate-Ack is sent. Again, Terminate-Acks are silently discarded to avoid creating a loop. ๐Ÿซถ

Rationale:

Stopped is basically the junction for link termination, link configuration failure and other automaton failure modes. ๐Ÿ›ฃ๏ธ These might sound like separate states, but they've been combined on purpose. ๐Ÿ’…

There's also a race condition between the Down event response (from the This-Layer-Finished action) and the Receive-Configure-Request event. ๐Ÿ˜ญ If a Configure-Request arrives before the Down event, the Down event supercedes it and sends the automaton back to the Starting state. This is what stops an attack by repetition. ๐Ÿ›ก๏ธ

Implementation Option:

After the peer stops responding to Configure-Requests, an implementation MAY wait passively for the peer to send Configure-Requests instead. ๐Ÿ‘€ In that case, the This-Layer-Finished action isn't used for the TO- event in Req-Sent, Ack-Rcvd and Ack-Sent. This option is useful for dedicated circuits, or circuits that have no status signals available. It SHOULD NOT be used for switched circuits, though. โš ๏ธ

Closing

In Closing, the automaton is trying to terminate the connection. ๐Ÿšช A Terminate-Request has been sent and the Restart timer is running, but no Terminate-Ack has come back yet.

When a Terminate-Ack arrives, we move into the Closed state. โœ… If the Restart timer expires, a new Terminate-Request is sent and the Restart timer restarts. After the Restart timer has expired Max-Terminate times, the automaton enters Closed. ๐Ÿซ 

Stopping

Stopping is the Open-side buddy of Closing. ๐Ÿค A Terminate-Request has been sent and the Restart timer is running, but a Terminate-Ack hasn't come back yet.

Rationale:

Stopping gives a clear chance to shut a link down before any new traffic gets through. ๐Ÿšง Once the link has terminated, a new configuration can happen by going through Stopped or Starting. ๐Ÿ”„

Request-Sent

In Request-Sent, the automaton is trying to configure the connection. ๐Ÿ› ๏ธ A Configure-Request has been sent and the Restart timer is running. But no Configure-Ack has been received yet, and none has been sent either.

Ack-Received

In Ack-Received, a Configure-Request has been sent and a Configure-Ack has been received. ๐ŸŽ‰ The Restart timer is still running, since a Configure-Ack hasn't been sent yet.

Ack-Sent

In Ack-Sent, both a Configure-Request and a Configure-Ack have been sent, but a Configure-Ack hasn't been received yet. ๐Ÿ“ค The Restart timer is running, since that Configure-Ack is still missing.

Opened

In Opened, a Configure-Ack has been both sent and received. ๐Ÿฅณ That's the big moment! The Restart timer is not running here.

When the automaton enters Opened, the implementation SHOULD signal the upper layers that it is now Up. ๐ŸŒŸ And when it leaves Opened, the implementation SHOULD signal the upper layers that it is now Down. ๐Ÿ“‰

4.3. Events ๐ŸŽ€

Okay bestie, every transition and action in this automaton is set off by an event โœจ Here's the whole lineup ๐Ÿ’…

Up ๐ŸŒˆ

This event happens when a lower layer says it's ready to carry packets ๐Ÿš€

Usually a modem handling or calling process (or some other way of hooking the PPP link up to the physical media) uses this to tell LCP that the link is entering the Link Establishment phase ๐Ÿ”Œ

LCP can also use it to tell each NCP that the link is entering the Network-Layer Protocol phase ๐Ÿ’– So the This-Layer-Up action from LCP sets off the Up event in the NCP. Chain reaction, iconic ๐Ÿฆ‹

Down ๐Ÿ’€

This event happens when a lower layer says it's no longer ready to carry packets ๐Ÿ“‰

Usually a modem handling or calling process (or another way of coupling the PPP link to the physical media) uses this to tell LCP that the link is entering the Link Dead phase ๐Ÿชฆ

LCP can also use it to tell each NCP that the link is leaving the Network-Layer Protocol phase. So the This-Layer-Down action from LCP triggers the Down event in the NCP ๐Ÿซถ

Open ๐Ÿ”“

This event means the link is administratively available for traffic โœจ In other words, the network administrator (a human or a program) has said the link is allowed to be Opened. When this happens and the link isn't already in the Opened state, the automaton tries to send configuration packets to the peer ๐Ÿ“จ

If the automaton can't begin configuration (the lower layer is Down, or a previous Close event hasn't finished yet), the link's establishment gets automatically delayed โณ

When a Terminate-Request comes in, or other things happen that make the link unavailable, the automaton moves to a state where the link is ready to re-open. No extra admin action needed ๐Ÿ™Œ

Implementation Option:

Experience has shown that users will run an extra Open command when they want to renegotiate the link. That might mean they want new values negotiated ๐Ÿค”

But that isn't what the Open event is for ๐Ÿ™… So it's suggested that when an Open user command runs in the Opened, Closing, Stopping, or Stopped states, the implementation issues a Down event, immediately followed by an Up event. Be careful that a Down event from some other source can't sneak in the middle ๐Ÿ‘€

The Down followed by an Up causes an orderly renegotiation of the link, going through Starting to Request-Sent. It renegotiates without any harmful side effects ๐ŸŒธ

Close ๐Ÿšซ

This event means the link is not available for traffic ๐Ÿ™…โ€โ™€๏ธ The network administrator (human or program) has said the link is not allowed to be Opened. When this happens and the link isn't already in the Closed state, the automaton tries to terminate the connection. Further attempts to re-configure the link are denied until a new Open event shows up ๐Ÿ”’

Implementation Note:

When authentication fails, the link SHOULD be terminated, so nobody can keep attacking it by repetition or hit other users with denial of service ๐Ÿ›‘๐Ÿ˜ค Since the link is administratively available (by definition), this can be done by simulating a Close event to the LCP, immediately followed by an Open event. Be careful that a Close event from another source can't sneak in ๐Ÿ‘€

The Close followed by an Open causes an orderly termination, going through Closing to the Stopping state. Then the This-Layer-Finished action can disconnect the link ๐Ÿ”Œ The automaton then waits in the Stopped or Starting states for the next connection attempt ๐Ÿงš

Timeout (TO+,TO-) โฐ

This event means the Restart timer has expired. The Restart timer is used to time responses to Configure-Request and Terminate-Request packets โฑ๏ธ

TO+ means the Restart counter is still greater than zero, which triggers the matching Configure-Request or Terminate-Request packet to be retransmitted ๐Ÿ”

TO- means the Restart counter is not greater than zero, so no more packets need retransmitting ๐Ÿ›‘

Receive-Configure-Request (RCR+,RCR-) ๐Ÿ“ฌ

This event happens when a Configure-Request packet arrives from the peer. The Configure-Request says the peer wants to open a connection, and it may specify Configuration Options. There's a fuller description of the Configure-Request packet in a later section ๐Ÿ“–

RCR+ means the Configure-Request was acceptable, and it triggers sending a matching Configure-Ack โœ…

RCR- means the Configure-Request was unacceptable, and it triggers sending a matching Configure-Nak or Configure-Reject ๐Ÿ™…

Implementation Note:

These events can happen on a connection that's already in the Opened state. The implementation MUST be prepared to immediately renegotiate the Configuration Options ๐Ÿ”ฅ

Receive-Configure-Ack (RCA) ๐Ÿฅ‚

This event happens when a valid Configure-Ack packet arrives from the peer. A Configure-Ack is a positive response to a Configure-Request packet. An out of sequence or otherwise invalid packet is silently discarded ๐Ÿ—‘๏ธ

Implementation Note:

The correct packet has already arrived before the automaton reaches Ack-Rcvd or Opened, so it's extremely unlikely that another one will show up. As specified, all invalid Ack/Nak/Rej packets are silently discarded, and they don't affect the automaton's transitions ๐Ÿคซ

That said, a correctly formed packet can still arrive through a coincidentally-timed cross-connection ๐Ÿคฏ It's more likely to be the result of an implementation error, though. At the very least, this occurrence SHOULD be logged ๐Ÿ“

Receive-Configure-Nak/Rej (RCN) ๐Ÿ™ˆ

This event happens when a valid Configure-Nak or Configure-Reject packet arrives from the peer. Both of these are negative responses to a Configure-Request packet. An out of sequence or otherwise invalid packet is silently discarded ๐Ÿ—‘๏ธ

Implementation Note:

Configure-Nak and Configure-Reject cause the same state transition in the automaton, but these packets have significantly different effects on the Configuration Options sent in the resulting Configure-Request packet ๐Ÿงฉ

Receive-Terminate-Request (RTR) ๐Ÿ›‘

This event happens when a Terminate-Request packet arrives. It means the peer wants to close the connection ๐Ÿ‘‹

Implementation Note:

This event is not identical to the Close event (see above), and it doesn't override the Open commands of the local network administrator. The implementation MUST be prepared to receive a new Configure-Request without network administrator intervention ๐Ÿ’ช

Receive-Terminate-Ack (RTA) ๐Ÿ”„

This event happens when a Terminate-Ack packet arrives from the peer. A Terminate-Ack is usually a response to a Terminate-Request packet. It may also show that the peer is in the Closed or Stopped states, and it serves to re-synchronize the link configuration ๐Ÿซ‚

Receive-Unknown-Code (RUC) โ“

This event happens when an un-interpretable packet arrives from the peer. A Code-Reject packet is sent back in response ๐Ÿ™ƒ

Receive-Code-Reject, Receive-Protocol-Reject (RXJ+,RXJ-) ๐Ÿšจ

This event happens when a Code-Reject or a Protocol-Reject packet arrives from the peer ๐Ÿ“ฎ

RXJ+ happens when the rejected value is acceptable, like a Code-Reject of an extended code or a Protocol-Reject of an NCP. These are all within the scope of normal operation ๐Ÿ‘ The implementation MUST stop sending the offending packet type.

RXJ- happens when the rejected value is catastrophic, like a Code-Reject of Configure-Request or a Protocol-Reject of LCP! This event communicates an unrecoverable error that terminates the connection ๐Ÿ’€

Receive-Echo-Request, Receive-Echo-Reply, Receive-Discard-Request (RXR) ๐Ÿ“

This event happens when an Echo-Request, Echo-Reply or Discard-Request packet arrives from the peer. An Echo-Reply is a response to an Echo-Request packet. There's no reply to an Echo-Reply or a Discard-Request packet ๐ŸŒˆ

4.4. Actions โœจ

okay so actions are what the automaton does when an event hits ๐Ÿ’… they're usually about sending packets and/or starting or stopping the Restart timer ๐Ÿงš

Illegal-Event (-)

this one is for an event that can't happen in a properly built automaton ๐Ÿ™ˆ if it does, the implementation has an internal error that should be reported and logged ๐Ÿšจ no transition happens, and the implementation SHOULD NOT reset or freeze. just keep going, bestie ๐Ÿซถ

This-Layer-Up (tlu)

this action tells the upper layers that the automaton is entering the Opened state ๐ŸŽ‰

usually the LCP uses this to send the Up event to an NCP, the Authentication Protocol, or the Link Quality Protocol. an NCP MAY also use it to say the link is ready for its network layer traffic ๐ŸŒˆ

This-Layer-Down (tld)

this one tells the upper layers that the automaton is leaving the Opened state ๐Ÿ“‰

usually the LCP uses it to send the Down event to an NCP, the Authentication Protocol, or the Link Quality Protocol. an NCP MAY also use it to say the link is no longer available for its network layer traffic ๐Ÿฅบ

This-Layer-Started (tls)

this action tells the lower layers that the automaton is entering the Starting state, and that the lower layer is needed for the link ๐Ÿ”Œ the lower layer SHOULD respond with an Up event once it's available โœจ

the results of this action are highly implementation dependent ๐Ÿคทโ€โ™€๏ธ

This-Layer-Finished (tlf)

this one tells the lower layers that the automaton is entering the Initial, Closed or Stopped states, so the lower layer isn't needed for the link anymore ๐Ÿงน the lower layer SHOULD respond with a Down event once it has terminated ๐Ÿ’œ

typically, the LCP MAY use this to advance to the Link Dead phase, and an NCP MAY use it to tell the LCP that the link can terminate when no other NCPs are open ๐Ÿฆ‹

the results of this action are highly implementation dependent ๐Ÿคทโ€โ™€๏ธ

Initialize-Restart-Count (irc)

this sets the Restart counter to the right value (Max-Terminate or Max-Configure) ๐Ÿ”ข the counter goes down by one for every transmission, including the very first one ๐Ÿ“‰

Implementation Note: on top of setting the Restart counter, the implementation MUST set the timeout period to the initial value when Restart timer backoff is used. no skipping this part, bestie ๐Ÿ˜ค

Zero-Restart-Count (zrc)

this sets the Restart counter to zero 0๏ธโƒฃ

Implementation Note: this action lets the FSA pause before it heads to the final state it wants, so the peer has time to process traffic ๐Ÿซง besides zeroing the Restart counter, the implementation MUST set the timeout period to an appropriate value. iconic behaviour ๐Ÿ‘‘

Send-Configure-Request (scr)

a Configure-Request packet gets sent ๐Ÿ“จ this says "I want to open a connection with this specific set of Configuration Options" ๐Ÿ’… the Restart timer starts when the Configure-Request goes out, so a lost packet doesn't leave everyone hanging ๐Ÿ›Ÿ and the Restart counter goes down each time a Configure-Request is sent ๐Ÿ“‰

Send-Configure-Ack (sca)

a Configure-Ack packet gets sent โœ… it says "got your Configure-Request, and everything in it is acceptable" ๐Ÿฅฐ

Send-Configure-Nak (scn)

a Configure-Nak or Configure-Reject packet gets sent, whichever one fits ๐Ÿ™…โ€โ™€๏ธ this is the negative response for a Configure-Request with options that aren't acceptable ๐Ÿ’€

Configure-Nak packets refuse a Configuration Option's value and suggest a new one that works ๐Ÿ’ก Configure-Reject packets refuse to negotiate a Configuration Option at all, usually because it isn't recognized or implemented ๐Ÿšซ the chapter on LCP Packet Formats explains how to choose between them in more detail ๐Ÿ“–

Send-Terminate-Request (str)

a Terminate-Request packet gets sent ๐Ÿ‘‹ it says "I'd like to close this connection" ๐Ÿฅ€ the Restart timer starts when it goes out, to protect against packet loss โฑ๏ธ and the Restart counter goes down each time a Terminate-Request is sent ๐Ÿ“‰

Send-Terminate-Ack (sta)

a Terminate-Ack packet gets sent ๐Ÿซก it acknowledges a Terminate-Request, or just helps keep the automatons in sync ๐Ÿ”„

Send-Code-Reject (scj)

a Code-Reject packet gets sent ๐Ÿ™… this happens when an unknown type of packet shows up ๐Ÿ‘€

Send-Echo-Reply (ser)

an Echo-Reply packet gets sent ๐Ÿ“ it acknowledges an Echo-Request ๐Ÿ’œ


4.5. Loop Avoidance

the protocol makes a reasonable attempt at avoiding Configuration Option negotiation loops ๐Ÿ” BUT it does NOT guarantee that loops won't happen ๐Ÿ˜ฌ like any negotiation, two PPP implementations can be configured with conflicting policies and never converge ๐Ÿ’€ it's also possible to set up policies that DO converge but take forever to get there ๐Ÿข

implementors should keep this in mind and SHOULD implement loop detection mechanisms or higher level timeouts. future-proof your code, bestie ๐Ÿ›ก๏ธ


4.6. Counters and Timers

Restart Timer

there's one special timer used by the automaton โฐ the Restart timer times the transmissions of Configure-Request and Terminate-Request packets ๐Ÿ“ฆ when it expires, it causes a Timeout event and the matching Configure-Request or Terminate-Request gets retransmitted ๐Ÿ”

the Restart timer MUST be configurable, but SHOULD default to three (3) seconds โณ

Implementation Note: the Restart timer SHOULD be based on the speed of the link ๐ŸŽ๏ธ the default is built for low speed links (2,400 to 9,600 bps) with high switching latency, like typical telephone lines โ˜Ž๏ธ higher speed links, or links with low switching latency, SHOULD have correspondingly faster retransmission times โšก

instead of a constant value, the Restart timer MAY start at a small initial value and climb up to the configured final value ๐Ÿ“ˆ each successive value below the final one SHOULD be at least twice the previous value 2๏ธโƒฃ the initial value SHOULD be big enough to cover the size of the packets, twice the round trip time at the link speed, and at least an extra 100 milliseconds so the peer can process the packets before replying ๐Ÿง  some circuits add another 200 milliseconds of satellite delay ๐Ÿ›ฐ๏ธ and round trip times for modems running at 14,400 bps have been measured anywhere from 160 to more than 600 milliseconds ๐Ÿ“Š

Max-Terminate

there's one required restart counter for Terminate-Requests ๐Ÿ”ข Max-Terminate is the number of Terminate-Request packets sent without getting a Terminate-Ack back, before assuming the peer can't respond ๐Ÿซฅ Max-Terminate MUST be configurable, but SHOULD default to two (2) transmissions 2๏ธโƒฃ

Max-Configure

a similar counter is recommended for Configure-Requests ๐ŸŽ€ Max-Configure is the number of Configure-Request packets sent without getting a valid Configure-Ack, Configure-Nak or Configure-Reject back, before assuming the peer can't respond ๐Ÿ“ฌ Max-Configure MUST be configurable, but SHOULD default to ten (10) transmissions ๐Ÿ”Ÿ

Max-Failure

a related counter is recommended for Configure-Nak ๐Ÿ™ƒ Max-Failure is the number of Configure-Nak packets sent without sending a Configure-Ack, before assuming the configuration just isn't converging ๐ŸŒ€ any further Configure-Nak packets for peer-requested options get turned into Configure-Reject packets, and locally desired options stop being appended ๐Ÿšซ Max-Failure MUST be configurable, but SHOULD default to five (5) transmissions 5๏ธโƒฃ


5. LCP Packet Formats โœจ

there are three classes of LCP packets, bestie ๐Ÿ“š

  1. Link Configuration packets used to establish and configure a link (Configure-Request, Configure-Ack, Configure-Nak and Configure-Reject). ๐Ÿ”ง
  2. Link Termination packets used to terminate a link (Terminate-Request and Terminate-Ack). ๐Ÿ‘‹
  3. Link Maintenance packets used to manage and debug a link (Code-Reject, Protocol-Reject, Echo-Request, Echo-Reply, and Discard-Request). ๐Ÿ› ๏ธ

in the interest of simplicity, the LCP packet has no version field ๐Ÿซถ a correctly working LCP implementation will always answer unknown Protocols and Codes with an easily recognizable LCP packet ๐Ÿ’– that gives other versions a predictable fallback, which is so clean ๐Ÿงผ

no matter which Configuration Options are enabled, all LCP Link Configuration, Link Termination, and Code-Reject packets (codes 1 through 7) are always sent as if no Configuration Options were negotiated ๐ŸŽฏ every Configuration Option specifies a default value, so these packets stay recognizable even when one end of the link wrongly thinks the link is open ๐Ÿฅน

exactly one LCP packet is encapsulated in the PPP Information field, and the PPP Protocol field says type hex c021 (Link Control Protocol) ๐Ÿ“ฆ

here's a summary of the Link Control Protocol packet format ๐Ÿ‘€ the fields are sent from left to right โžก๏ธ

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Code      |  Identifier   |            Length             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |    Data ...
   +-+-+-+-+

Code

the Code field is one octet, and it tells you what kind of LCP packet this is ๐Ÿท๏ธ when a packet comes in with an unknown Code field, a Code-Reject packet gets sent back ๐Ÿ™…

the up-to-date values of the LCP Code field are in the most recent "Assigned Numbers" RFC [2] ๐Ÿ“– this document covers these values:

   1       Configure-Request
   2       Configure-Ack
   3       Configure-Nak
   4       Configure-Reject
   5       Terminate-Request
   6       Terminate-Ack
   7       Code-Reject
   8       Protocol-Reject
   9       Echo-Request
   10      Echo-Reply
   11      Discard-Request

Identifier

the Identifier field is one octet, and it helps match requests with their replies ๐Ÿชช when a packet arrives with an invalid Identifier field, it gets silently discarded without affecting the automaton ๐Ÿซฅ

Length

the Length field is two octets, and it says how long the LCP packet is, counting the Code, Identifier, Length and Data fields ๐Ÿ“ the Length MUST NOT exceed the MRU of the link ๐Ÿšง

octets outside the range of the Length field are treated as padding and ignored on reception ๐Ÿซง when a packet arrives with an invalid Length field, it gets silently discarded without affecting the automaton ๐Ÿคซ

Data

the Data field is zero or more octets, as the Length field says ๐Ÿ“ฆ the format of the Data field depends on the Code field ๐Ÿ’…

5.1. Configure-Request ๐Ÿ’–

Description ๐Ÿ’…

okay bestie, so when an implementation wants to open a connection it MUST transmit a Configure-Request ๐Ÿ“จ think of it like the opening text that says "hey, wanna chat with these settings?" โœจ The Options field holds whatever changes you want to the link defaults, and ngl you SHOULD NOT include Configuration Options that already have default values ๐Ÿ™„ no need to repeat yourself. When a Configure-Request comes in, an appropriate reply MUST be transmitted. Period. ๐Ÿซถ

Here's the packet layout. Fields go left to right ๐Ÿ‘€

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Code      |  Identifier   |            Length             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | Options ...
   +-+-+-+-+

Code ๐Ÿ”ข

1 for Configure-Request. ๐ŸŽ€

Identifier ๐Ÿชช

The Identifier field MUST be changed whenever the contents of the Options field changes, and whenever a valid reply has been received for a previous request. For retransmissions, the Identifier MAY remain unchanged. Basically, new message, new ID, unless you're just resending the same thing ๐Ÿ’…

Options ๐Ÿงฉ

The Options field is variable in length and holds a list of zero or more Configuration Options that the sender wants to negotiate. All Configuration Options are always negotiated simultaneously, so it's a whole package deal ๐Ÿ“ฆ The format of Configuration Options gets explained in a later chapter, so stay tuned ๐Ÿฆ‹

5.2. Configure-Ack ๐ŸŒธ

Description โœ…

If every Configuration Option received in a Configure-Request is recognizable and every value is acceptable, then the implementation MUST transmit a Configure-Ack. ๐Ÿฅฐ The acknowledged Configuration Options MUST NOT be reordered or modified in any way. Hands off, they're perfect as is ๐Ÿ’…

When a Configure-Ack comes in, the Identifier field MUST match that of the last transmitted Configure-Request. Also, the Configuration Options in a Configure-Ack MUST exactly match those of the last transmitted Configure-Request. Anything invalid gets silently discarded ๐Ÿซฅ no drama, just gone.

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Code      |  Identifier   |            Length             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | Options ...
   +-+-+-+-+

Code ๐Ÿ”ข

2 for Configure-Ack. ๐Ÿ’œ

Identifier ๐Ÿชช

The Identifier field is a copy of the Identifier field of the Configure-Request that caused this Configure-Ack. Matching IDs, very cute ๐Ÿฅน

Options ๐Ÿงฉ

The Options field is variable in length and holds a list of zero or more Configuration Options that the sender is acknowledging. All Configuration Options are always acknowledged simultaneously ๐Ÿซถ

5.3. Configure-Nak ๐Ÿ™ˆ

Description ๐Ÿค”

If every instance of the received Configuration Options is recognizable, but some values are not acceptable, then the implementation MUST transmit a Configure-Nak. โš ๏ธ The Options field gets filled with only the unacceptable Configuration Options from the Configure-Request. All the acceptable ones get filtered out of the Configure-Nak, but otherwise the Configuration Options from the Configure-Request MUST NOT be reordered. Order matters, bestie ๐Ÿง

Options which have no value fields, aka boolean options, MUST use the Configure-Reject reply instead. Different vibe, different reply ๐Ÿ™…โ€โ™€๏ธ

Each Configuration Option that's only allowed a single instance MUST be modified to a value acceptable to the Configure-Nak sender. The default value MAY be used when it differs from the requested value. ๐Ÿ“

When a particular type of Configuration Option can be listed more than once with different values, the Configure-Nak MUST include a list of all values for that option which are acceptable to the Configure-Nak sender. That includes acceptable values that were already in the Configure-Request, so nothing gets left out ๐Ÿ“

Last but not least, an implementation might be set up to request negotiation of a specific Configuration Option. If that option isn't listed, then it MAY be appended to the list of Nak'd Configuration Options, which prompts the peer to include it in its next Configure-Request packet. Any value fields for the option MUST indicate values acceptable to the Configure-Nak sender. Sneaky, but iconic ๐Ÿ˜โœจ

When a Configure-Nak comes in, the Identifier field MUST match that of the last transmitted Configure-Request. Invalid packets are silently discarded ๐Ÿซฅ

Getting a valid Configure-Nak means that when a new Configure-Request gets sent, the Configuration Options MAY be modified as the Configure-Nak specified. When multiple instances of a Configuration Option show up, the peer SHOULD select a single value to include in its next Configure-Request packet. Pick one, babe ๐Ÿ’…

Some Configuration Options have a variable length. Since the peer has modified the Nak'd Option, the implementation MUST be able to handle an Option length that's different from the original Configure-Request. Be flexible, it's a whole mood ๐Ÿฆ‹

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Code      |  Identifier   |            Length             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | Options ...
   +-+-+-+-+

Code ๐Ÿ”ข

3 for Configure-Nak. ๐ŸŒˆ

Identifier ๐Ÿชช

The Identifier field is a copy of the Identifier field of the Configure-Request that caused this Configure-Nak. ๐Ÿซถ

Options ๐Ÿงฉ

The Options field is variable in length and holds a list of zero or more Configuration Options that the sender is Nak'ing. All Configuration Options are always Nak'd simultaneously. ๐Ÿ’ซ

5.4. Configure-Reject ๐Ÿšซ

Description ๐Ÿ™…โ€โ™€๏ธ

If some Configuration Options received in a Configure-Request aren't recognizable, or they aren't acceptable for negotiation (as set by a network administrator), then the implementation MUST transmit a Configure-Reject. ๐Ÿ›‘ The Options field gets filled with only the unacceptable Configuration Options from the Configure-Request. All the recognizable and negotiable ones get filtered out of the Configure-Reject. Otherwise the Configuration Options MUST NOT be reordered or modified in any way. ๐Ÿงผ

When a Configure-Reject comes in, the Identifier field MUST match that of the last transmitted Configure-Request. Also, the Configuration Options in a Configure-Reject MUST be a proper subset of those in the last transmitted Configure-Request. Invalid packets get silently discarded ๐Ÿซฅ

Getting a valid Configure-Reject means that when a new Configure-Request gets sent, it MUST NOT include any of the Configuration Options listed in the Configure-Reject. Those are officially off the menu ๐Ÿšท

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Code      |  Identifier   |            Length             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | Options ...
   +-+-+-+-+

Code ๐Ÿ”ข

4 for Configure-Reject. ๐ŸŒท

Identifier ๐Ÿชช

The Identifier field is a copy of the Identifier field of the Configure-Request that caused this Configure-Reject. ๐ŸŽ€

Options ๐Ÿงฉ

The Options field is variable in length and holds a list of zero or more Configuration Options that the sender is rejecting. All Configuration Options are always rejected simultaneously. Rough, but clean โœ‚๏ธ

5.5. Terminate-Request and Terminate-Ack ๐Ÿ‘‹

Description ๐Ÿฅ€

LCP has Terminate-Request and Terminate-Ack Codes so it can close a connection properly. Like a graceful exit, no ghosting ๐Ÿ‘ป

An implementation that wants to close a connection SHOULD transmit a Terminate-Request. Terminate-Request packets SHOULD continue to be sent until a Terminate-Ack is received, the lower layer indicates that it has gone down, or a big enough number have been transmitted that the peer is down with reasonable certainty. Keep knocking, but know when to stop ๐Ÿšช

When a Terminate-Request comes in, a Terminate-Ack MUST be transmitted. Always reply, always ๐Ÿซถ

Getting a Terminate-Ack that nobody asked for means the peer is in the Closed or Stopped states, or it's otherwise in need of re-negotiation. Plot twist ๐Ÿ˜ณ

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Code      |  Identifier   |            Length             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |    Data ...
   +-+-+-+-+

Code ๐Ÿ”ข

5 for Terminate-Request;

6 for Terminate-Ack. โœจ

Identifier ๐Ÿชช

On transmission, the Identifier field MUST be changed whenever the content of the Data field changes, and whenever a valid reply has been received for a previous request. For retransmissions, the Identifier MAY remain unchanged. ๐Ÿ”

On reception, the Identifier field of the Terminate-Request is copied into the Identifier field of the Terminate-Ack packet. Copy-paste energy ๐Ÿ’…

Data ๐Ÿ“ฆ

The Data field is zero or more octets and holds uninterpreted data for the sender to use. The data may be any binary value. The end of the field is marked by the Length. ๐Ÿงธ

5.6. Code-Reject ๐Ÿซฃ

Description ๐Ÿšจ

If an LCP packet shows up with an unknown Code, that means the peer is running a different version. This MUST be reported back to the sender of the unknown Code by transmitting a Code-Reject. Let them know, no secrets ๐Ÿคซ

When a Code-Reject comes in for a code that's fundamental to this version of the protocol, the implementation SHOULD report the problem and drop the connection. It's unlikely the situation can be fixed automatically, so cutting it off is the move ๐Ÿ’”

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Code      |  Identifier   |            Length             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | Rejected-Packet ...
   +-+-+-+-+-+-+-+-+

Code ๐Ÿ”ข

7 for Code-Reject. ๐Ÿฆ‹

Identifier ๐Ÿชช

The Identifier field MUST be changed for each Code-Reject sent. Fresh ID every time ๐Ÿ†•

Rejected-Packet ๐Ÿ“ฎ

The Rejected-Packet field holds a copy of the LCP packet being rejected. It starts with the Information field, and it doesn't include any Data Link Layer headers or an FCS. The Rejected-Packet MUST be truncated to comply with the peer's established MRU. Keep it short and respect their limits ๐Ÿฅฐ

5.7. Protocol-Reject ๐Ÿฆ‹

Description

okay so this is the moment the peer tries to use a protocol you don't speak ๐Ÿ’€ a PPP packet shows up with a Protocol field you don't recognize, which basically means they're trying to set up something new. if the LCP automaton is in the Opened state, then this MUST be reported back to the peer by transmitting a Protocol-Reject. โœจ

upon reception of a Protocol-Reject, the implementation MUST stop sending packets of the indicated protocol at the earliest opportunity. no more sending that protocol once you've been rejected, bestie ๐Ÿ™…โ€โ™€๏ธ

Protocol-Reject packets can only be sent in the LCP Opened state. Protocol-Reject packets received in any state other than the LCP Opened state SHOULD be silently discarded. ๐ŸŒธ

A summary of the Protocol-Reject packet format is shown below. The fields are transmitted from left to right.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Code      |  Identifier   |            Length             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|       Rejected-Protocol       |      Rejected-Information ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Code

8 for Protocol-Reject. ๐ŸŽ€

Identifier

The Identifier field MUST be changed for each Protocol-Reject sent. ๐Ÿ”ฅ

Rejected-Protocol

The Rejected-Protocol field is two octets, and contains the PPP Protocol field of the packet which is being rejected. so it's basically the receipt, naming the exact protocol that got turned away ๐Ÿงพ

Rejected-Information

The Rejected-Information field contains a copy of the packet which is being rejected. It begins with the Information field, and does not include any Data Link Layer headers nor an FCS. The Rejected-Information MUST be truncated to comply with the peer's established MRU. so the copy gets chopped down to fit what the peer already agreed to receive, no drama ๐Ÿ’…


5.8. Echo-Request and Echo-Reply ๐Ÿซง

Description

LCP includes Echo-Request and Echo-Reply Codes in order to provide a Data Link Layer loopback mechanism for use in exercising both directions of the link. this is so iconic for debugging, link quality checks, performance testing, and literally a bunch of other stuff ๐Ÿงชโœจ

upon reception of an Echo-Request in the LCP Opened state, an Echo-Reply MUST be transmitted. bounce it right back, bestie ๐Ÿ“

Echo-Request and Echo-Reply packets MUST only be sent in the LCP Opened state. Echo-Request and Echo-Reply packets received in any state other than the LCP Opened state SHOULD be silently discarded. ๐Ÿ™ˆ

A summary of the Echo-Request and Echo-Reply packet formats is shown below. The fields are transmitted from left to right.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Code      |  Identifier   |            Length             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Magic-Number                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    Data ...
+-+-+-+-+

Code

9 for Echo-Request;

10 for Echo-Reply. ๐Ÿชž

Identifier

On transmission, the Identifier field MUST be changed whenever the content of the Data field changes, and whenever a valid reply has been received for a previous request. For retransmissions, the Identifier MAY remain unchanged. basically new content or a fresh reply means a new ID, but resending the same thing is totally fine ๐Ÿ”

On reception, the Identifier field of the Echo-Request is copied into the Identifier field of the Echo-Reply packet. the reply gets the same ID as the request it's answering, so they can be matched up ๐Ÿค

Magic-Number

The Magic-Number field is four octets, and aids in detecting links which are in the looped-back condition. Until the Magic-Number Configuration Option has been successfully negotiated, the Magic-Number MUST be transmitted as zero. See the Magic-Number Configuration Option for further explanation. this is the field that helps you catch a link that's accidentally talking to itself ๐Ÿ”„ and before it's been negotiated it has to be a big fat zero 0๏ธโƒฃ

Data

The Data field is zero or more octets, and contains uninterpreted data for use by the sender. The data may consist of any binary value. The end of the field is indicated by the Length. so the sender can put whatever bytes they want in here, and the Length tells you where it stops ๐Ÿ“ฆ


5.9. Discard-Request ๐Ÿ—‘๏ธ

Description

LCP includes a Discard-Request Code in order to provide a Data Link Layer sink mechanism for use in exercising the local to remote direction of the link. this is like a black hole for packets, and it's useful for debugging, performance testing, and a bunch of other things ๐Ÿ•ณ๏ธ๐Ÿ’œ

Discard-Request packets MUST only be sent in the LCP Opened state. On reception, the receiver MUST silently discard any Discard-Request that it receives. no reply, no fuss, just gone ๐Ÿ‘‹

A summary of the Discard-Request packet format is shown below. The fields are transmitted from left to right.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Code      |  Identifier   |            Length             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Magic-Number                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    Data ...
+-+-+-+-+

Code

11 for Discard-Request. ๐Ÿงน

Identifier

The Identifier field MUST be changed for each Discard-Request sent. ๐Ÿ”

Magic-Number

The Magic-Number field is four octets, and aids in detecting links which are in the looped-back condition. Until the Magic-Number Configuration Option has been successfully negotiated, the Magic-Number MUST be transmitted as zero. See the Magic-Number Configuration Option for further explanation. same energy as the Echo packets, same zero rule 0๏ธโƒฃ

Data

The Data field is zero or more octets, and contains uninterpreted data for use by the sender. The data may consist of any binary value. The end of the field is indicated by the Length. ๐Ÿ“ฆ


6. LCP Configuration Options ๐ŸŽ€

LCP Configuration Options allow negotiation of modifications to the default characteristics of a point-to-point link. If a Configuration Option is not included in a Configure-Request packet, the default value for that Configuration Option is assumed. so if you don't mention an option, you just get the default, periodt ๐Ÿ’–

Some Configuration Options MAY be listed more than once. The effect of this is Configuration Option specific, and is specified by each such Configuration Option description. (None of the Configuration Options in this specification can be listed more than once.) โœจ

The end of the list of Configuration Options is indicated by the Length field of the LCP packet. ๐Ÿ

Unless otherwise specified, all Configuration Options apply in a half-duplex fashion; typically, in the receive direction of the link from the point of view of the Configure-Request sender. so it's usually about the direction heading toward the person who sent the request ๐Ÿงญ

Design Philosophy

The options indicate additional capabilities or requirements of the implementation that is requesting the option. An implementation which does not understand any option SHOULD interoperate with one which implements every option. the vibe is "we can still be friends even if we don't both know every option" ๐Ÿซถ

A default is specified for each option which allows the link to correctly function without negotiation of the option, although perhaps with less than optimal performance. so the link still works, it's just not as glowy as it could be โœจ

Except where explicitly specified, acknowledgement of an option does not require the peer to take any additional action other than the default. so a yes to an option doesn't mean extra work for the other side ๐Ÿ’…

It is not necessary to send the default values for the options in a Configure-Request. no need to repeat what everyone already knows ๐Ÿ™„

A summary of the Configuration Option format is shown below. The fields are transmitted from left to right.

 0                   1
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Type      |    Length     |    Data ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Type

The Type field is one octet, and indicates the type of Configuration Option. Up-to-date values of the LCP Option Type field are specified in the most recent "Assigned Numbers" RFC [2]. This document concerns the following values: ๐Ÿ”ข

0       RESERVED
1       Maximum-Receive-Unit
3       Authentication-Protocol
4       Quality-Protocol
5       Magic-Number
7       Protocol-Field-Compression
8       Address-and-Control-Field-Compression

Length

The Length field is one octet, and indicates the length of this Configuration Option including the Type, Length and Data fields.

If a negotiable Configuration Option is received in a Configure-Request, but with an invalid or unrecognized Length, a Configure-Nak SHOULD be transmitted which includes the desired Configuration Option with an appropriate Length and Data. so you politely say "hm, fix that length and try again" ๐Ÿ™

Data

The Data field is zero or more octets, and contains information specific to the Configuration Option. The format and length of the Data field is determined by the Type and Length fields.

When the Data field is indicated by the Length to extend beyond the end of the Information field, the entire packet is silently discarded without affecting the automaton. yikes, if the length runs off the edge, the whole packet just vanishes and the automaton doesn't even blink ๐Ÿซ 


6.1. Maximum-Receive-Unit (MRU) ๐Ÿ“

Description

This Configuration Option may be sent to inform the peer that the implementation can receive larger packets, or to request that the peer send smaller packets. it's the "hey, I can handle big stuff" or "hey, could you keep it smaller?" option ๐Ÿ“

The default value is 1500 octets. If smaller packets are requested, an implementation MUST still be able to receive the full 1500 octet information field in case link synchronization is lost. so even if you ask for smaller packets, you still have to be ready for the full 1500 if the link gets out of sync ๐Ÿ›Ÿ

Implementation Note:

This option is used to indicate an implementation capability. The peer is not required to maximize the use of the capacity. For example, when a MRU is indicated which is 2048 octets, the peer is not required to send any packet with 2048 octets. The peer need not Configure-Nak to indicate that it will only send smaller packets, since the implementation will always require support for at least 1500 octets. ๐Ÿ’ก basically saying "I can take 2048" doesn't mean the other side has to send 2048, and the 1500 minimum is always expected anyway

A summary of the Maximum-Receive-Unit Configuration Option format is shown below. The fields are transmitted from left to right.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Type      |    Length     |      Maximum-Receive-Unit     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Type

1

Length

4

Maximum-Receive-Unit

The Maximum-Receive-Unit field is two octets, and specifies the maximum number of octets in the Information and Padding fields. It does not include the framing, Protocol field, FCS, nor any transparency bits or bytes. this is the size of the payload only, not the wrapping around it ๐ŸŽ

6.2. Authentication-Protocol โœจ

Description ๐Ÿ”

okay so on some links you might want to make sure your peer proves who they are before any network-layer protocol packets get to flow, bestie. main character security energy ๐Ÿ’…

This Configuration Option gives you a way to negotiate which specific protocol will handle that authentication. By default, authentication is not required, so nobody has to show ID unless you ask for it ๐Ÿซถ

An implementation MUST NOT include multiple Authentication-Protocol Configuration Options in its Configure-Request packets. Instead, it SHOULD attempt to configure the most desirable protocol first ๐ŸŽฏ If that protocol gets Configure-Nak'd, then the implementation SHOULD attempt the next most desirable protocol in the next Configure-Request. it's giving "one option at a time, we're not overwhelming anyone" ๐Ÿ’€

The implementation sending the Configure-Request is basically saying "hey, I expect you to authenticate to me" ๐Ÿฆ‹ If an implementation sends a Configure-Ack, then it's agreeing to authenticate with the protocol that was specified. An implementation receiving a Configure-Ack SHOULD expect the peer to authenticate with the acknowledged protocol ๐Ÿ’œ

There's no rule that authentication has to be full-duplex, or that the same protocol has to be used in both directions. Different protocols in each direction? totally fine, iconic ๐ŸŒˆ Of course, what actually works depends on the specific protocols you negotiate โœจ

Here's the summary of the Authentication-Protocol Configuration Option format. The fields go from left to right ๐ŸŽ€

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Type      |    Length     |     Authentication-Protocol   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |    Data ...
   +-+-+-+-+

Type ๐ŸŒธ

3

Length ๐Ÿงš

>= 4

Authentication-Protocol ๐Ÿ”‘

The Authentication-Protocol field is two octets long, and it tells you which authentication protocol you want. The values here are always the same as the PPP Protocol field values for that same authentication protocol, so there's no separate guessing game ๐Ÿ™ˆ

Up-to-date values of the Authentication-Protocol field are listed in the most recent "Assigned Numbers" RFC [2]. Right now the current values are:

Value (in hex)  Protocol

c023            Password Authentication Protocol
c223            Challenge Handshake Authentication Protocol

Data ๐Ÿ’–

The Data field is zero or more octets, and it holds any extra data the particular protocol needs. Zero is a totally valid amount, no pressure โœจ


6.3. Quality-Protocol ๐Ÿ“Š

Description ๐Ÿ“ˆ

okay so on some links you might want to figure out when, and how often, the link is dropping data ๐Ÿ‘€ This is called link quality monitoring, and honestly it's giving detective era ๐Ÿ•ต๏ธโ€โ™€๏ธ

This Configuration Option gives you a way to negotiate which specific protocol gets used for link quality monitoring. By default, link quality monitoring is disabled, so it's opt-in only ๐Ÿซถ

The implementation sending the Configure-Request is saying that it expects to receive monitoring information from its peer ๐Ÿฆ‹ If an implementation sends a Configure-Ack, then it's agreeing to send the specified protocol. An implementation receiving a Configure-Ack SHOULD expect the peer to send the acknowledged protocol ๐Ÿ’œ

Same vibe as before: there's no requirement that quality monitoring be full-duplex, or that the same protocol be used in both directions. Different protocols per direction? perfectly acceptable ๐ŸŒˆ What actually works depends on the specific protocols negotiated โœจ

Here's the summary of the Quality-Protocol Configuration Option format. Fields go left to right, as always ๐ŸŽ€

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Type      |    Length     |        Quality-Protocol       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |    Data ...
   +-+-+-+-+

Type ๐Ÿ“

4

Length ๐Ÿง

>= 4

Quality-Protocol ๐Ÿ“ก

The Quality-Protocol field is two octets long, and it says which link quality monitoring protocol you want. Just like the Authentication-Protocol field, the values are always the same as the PPP Protocol field values for that same monitoring protocol ๐Ÿ’…

Up-to-date values of the Quality-Protocol field are specified in the most recent "Assigned Numbers" RFC [2]. Current values are assigned as follows:

Value (in hex)  Protocol

c025            Link Quality Report

Data ๐Ÿฆ‹

The Data field is zero or more octets, and it contains additional data as determined by the particular protocol. Zero is valid, periodt ๐Ÿ’œ

6.4. Magic-Number ๐Ÿงฒ

Description

Okay so this one is the looped-back link detective ๐Ÿ•ต๏ธโ€โ™€๏ธ. It helps spot links that are looped back on themselves, plus some other Data Link Layer weirdness ๐Ÿงถ. Some other Configuration Options, like the Quality-Protocol one, MAY be required to use it too. By default it's not negotiated, and zero gets stuffed in wherever a Magic-Number would've gone ๐Ÿ™ˆ

Before you even ask for it, you MUST pick your Magic-Number ๐Ÿ’–. It is recommended that you pick it in the most random way possible so you can be basically certain nobody else picked the same one ๐ŸŽฒ. A good move is to start from a unique seed. Stuff like machine serial numbers, other network hardware addresses, time-of-day clocks, and so on all count ๐Ÿ•ฐ๏ธ. The really good seeds are timing measurements of physical events, like packet arrivals on other connected networks, server response times, or how fast a human is typing โŒจ๏ธโœจ. And the more sources you mix together at once, the better ๐ŸŒˆ

When a Configure-Request shows up with a Magic-Number Configuration Option, you compare its Magic-Number with the one in the last Configure-Request you sent to your peer. If they're different, the link isn't looped back, and you SHOULD acknowledge the Magic-Number ๐Ÿฅฐ. If they're the same, then it's possible (but not certain) that the link is looped back and that this Configure-Request is literally the one you just sent ๐Ÿ˜ณ. To check, you MUST send a Configure-Nak with a different Magic-Number value ๐Ÿ”„. Don't send a new Configure-Request until normal processing says so, meaning until a Configure-Nak comes back or the Restart timer runs out โณ. You SHOULD NOT spam them ๐Ÿ™…โ€โ™€๏ธ

Now, if a Configure-Nak comes back with a Magic-Number that's different from the one in the last Configure-Nak you sent, that proves the link isn't looped back and gives you a unique number ๐ŸŽ‰. If the Magic-Number matches the one you sent in your last Configure-Nak, the looped-back suspicion goes up, and you MUST choose a new Magic-Number ๐Ÿ”. Either way, you SHOULD send a new Configure-Request with the new Magic-Number ๐Ÿš€

If the link really is looped back, this whole loop (send Configure-Request, receive Configure-Request, send Configure-Nak, receive Configure-Nak) just keeps going forever ๐ŸŒ€. If it's not looped back, it might happen a couple of times, but it's extremely unlikely to keep happening. More likely, the two ends pick different Magic-Numbers pretty quickly and the loop ends ๐Ÿ’…. Here's the probability of collisions, assuming both ends pick Magic-Numbers with a perfectly uniform distribution ๐Ÿ“Š:

         Number of Collisions        Probability
         --------------------   ---------------------
                 1              1/2**32    = 2.3 E-10
                 2              1/2**32**2 = 5.4 E-20
                 3              1/2**32**3 = 1.3 E-29

Good sources of uniqueness or randomness are required for this divergence to happen ๐Ÿซถ. If you can't find a good source, it is recommended that you don't enable this Configuration Option at all. In that case, you SHOULD NOT transmit Configure-Requests with the option, and any Magic-Number Configuration Options your peer sends SHOULD be either acknowledged or rejected ๐Ÿ™ƒ. Looped-back links can't be reliably detected by you then, although your peer might still be able to detect them ๐Ÿคทโ€โ™€๏ธ

If you DO transmit a Configure-Request with a Magic-Number Configuration Option, you MUST NOT respond with a Configure-Reject when you receive a Configure-Request with a Magic-Number Configuration Option. Basically, if you want to use Magic-Numbers, you MUST also let your peer use them too ๐Ÿค

If you get a Configure-Reject in response to your Configure-Request, it can only mean one thing: the link isn't looped back, and your peer won't be using Magic-Numbers ๐Ÿ’โ€โ™€๏ธ. In that case, you SHOULD act as if the negotiation was successful, as if you'd gotten a Configure-Ack instead โœ…

The Magic-Number can also detect looped-back links during normal operation, not just during option negotiation ๐Ÿ‘€. Every LCP Echo-Request, Echo-Reply, and Discard-Request packet has a Magic-Number field. If the Magic-Number was successfully negotiated, you MUST send these packets with the Magic-Number field set to your negotiated Magic-Number ๐Ÿ“ฆ

You SHOULD inspect the Magic-Number field on every packet you receive. Every received Magic-Number field MUST be equal to either zero or the peer's unique Magic-Number, depending on whether or not the peer negotiated one ๐Ÿ”

If you receive a Magic-Number field equal to your own negotiated Magic-Number, that's a looped-back link ๐Ÿ”๐Ÿ˜ฑ. If you get a Magic-Number that's not your negotiated local one, not the peer's negotiated one, and not zero (in case the peer didn't negotiate one either), that means the link has been (mis)configured to talk to a different peer ๐Ÿ“ก

The recovery procedures for either case are unspecified and can vary between implementations ๐Ÿ› ๏ธ. A somewhat pessimistic approach is to assume an LCP Down event ๐Ÿ“‰. A further Open event will then start the process of re-establishing the link, which can't finish until the looped-back condition is gone and Magic-Numbers are successfully negotiated ๐Ÿ”’. A more optimistic approach (for a looped-back link) is to start transmitting LCP Echo-Request packets until you get an appropriate Echo-Reply, which tells you the looped-back condition has ended ๐Ÿฅณ

A summary of the Magic-Number Configuration Option format is shown below. The fields are transmitted from left to right ๐Ÿ‘‡

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Type      |    Length     |          Magic-Number
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         Magic-Number (cont)       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Type

5 ๐ŸŽ€

Length

6 ๐ŸŽ€

Magic-Number

This field is four octets long, and holds a number that's very likely to be unique to one end of the link ๐Ÿ’œ. A Magic-Number of zero is illegal, so it MUST always be Nak'd if it isn't Rejected outright ๐Ÿšซ


6.5. Protocol-Field-Compression (PFC) ๐Ÿ—œ๏ธ

Description

This Configuration Option lets you negotiate compressing the PPP Protocol field ๐Ÿงƒ. By default, all implementations MUST transmit packets with two-octet PPP Protocol fields ๐Ÿ“ฎ

PPP Protocol field numbers are picked so that some values can be squished down into a single octet, which is clearly different from the two-octet form ๐Ÿช„. You send this Configuration Option to tell your peer that you can receive those single-octet Protocol fields ๐Ÿ‘‚

Like I mentioned before, the Protocol field uses an extension mechanism that matches the ISO 3309 extension mechanism for the Address field. The Least Significant Bit (LSB) of each octet says whether the Protocol field keeps going. A binary "0" as the LSB means the Protocol field continues with the next octet, and a binary "1" as the LSB marks the last octet ๐Ÿ”š. Also, any number of "0" octets can be stuck on the front and still mean the same value. (Think about 3: it's 00000011, and it's also 00000000 00000011 ๐Ÿ˜Œ)

On low-speed links, you want to save bandwidth by sending as little repeated data as possible ๐Ÿข. Protocol-Field-Compression gives you a trade-off between simple implementation and bandwidth efficiency โš–๏ธ. If it's successfully negotiated, the ISO 3309 extension mechanism can be used to compress the Protocol field down to one octet instead of two ๐Ÿ“‰. The vast majority of packets can be compressed, since data protocols usually have Protocol field values under 256 ๐Ÿฅ‡

Compressed Protocol fields MUST NOT be transmitted unless this Configuration Option has been negotiated ๐Ÿšท. Once it has been, PPP implementations MUST accept PPP packets with either double-octet or single-octet Protocol fields, and MUST NOT tell them apart ๐Ÿซฅ

The Protocol field is never compressed when sending any LCP packet ๐Ÿ™…โ€โ™€๏ธ. That rule keeps LCP packets unambiguously recognisable ๐Ÿ”

When a Protocol field is compressed, the Data Link Layer FCS field is calculated on the compressed frame, not the original uncompressed frame ๐Ÿงฎ

A summary of the Protocol-Field-Compression Configuration Option format is shown below. The fields are transmitted from left to right ๐Ÿ‘‡

    0                   1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Type      |    Length     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Type

7 ๐ŸŽ€

Length

2 ๐ŸŽ€


6.6. Address-and-Control-Field-Compression (ACFC) ๐ŸŒธ

Description

This Configuration Option lets you negotiate compressing the Data Link Layer Address and Control fields ๐Ÿชถ. By default, all implementations MUST transmit frames with Address and Control fields that fit the link framing ๐Ÿ“ฆ

Those two fields usually have constant values on point-to-point links, so they're super easy to compress ๐Ÿ˜Ž. You send this Configuration Option to tell your peer that you can receive compressed Address and Control fields ๐Ÿ’Œ

If you get a compressed frame and Address-and-Control-Field-Compression wasn't negotiated, you MAY silently discard the frame ๐Ÿซฅ

The Address and Control fields MUST NOT be compressed when sending any LCP packet ๐Ÿ™…โ€โ™€๏ธ. That's how LCP packets stay unambiguously recognisable ๐Ÿ”

When the Address and Control fields are compressed, the Data Link Layer FCS field is calculated on the compressed frame, not the original uncompressed frame ๐Ÿงฎ

A summary of the Address-and-Control-Field-Compression configuration option format is shown below. The fields are transmitted from left to right ๐Ÿ‘‡

    0                   1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Type      |    Length     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Type

8 ๐ŸŽ€

Length

2 ๐ŸŽ€


Security Considerations ๐Ÿ”

Security issues get briefly discussed in a few places: the Authentication Phase, the Close event, and the Authentication-Protocol Configuration Option. Don't skip those parts, bestie, they matter ๐Ÿ˜ญ๐Ÿซถ

References ๐Ÿ“šโœจ

okay so this is where the receipts live, bestie ๐Ÿงพ๐Ÿ’…

[1] Perkins, D., "Requirements for an Internet Standard Point-to-Point Protocol", RFC 1547, Carnegie Mellon University, December 1993.

[2] Reynolds, J., and Postel, J., "Assigned Numbers", STD 2, RFC 1340, USC/Information Sciences Institute, July 1992.

Acknowledgements ๐Ÿซถ

this doc is the product of the Point-to-Point Protocol Working Group of the IETF ๐ŸŒธ if you have comments, send them to the ietf-ppp@merit.edu mailing list, obviously ๐Ÿ’–

honestly so much of the text comes from the working group requirements [1], plus RFCs 1171 & 1172. Drew Perkins wrote those while he was at Carnegie Mellon University, and Russ Hobby wrote them at the University of California at Davis ๐ŸŽ€

William Simpson was the main one who brought in consistent terminology and philosophy, and he redesigned the phase and negotiation state machines. he really did that ๐Ÿ‘‘๐Ÿ”ฅ

Many people spent so much time helping build the Point-to-Point Protocol ๐Ÿฆ‹ there are way too many to list, but these people deserve special thanks: Rick Adams, Ken Adelman, Fred Baker, Mike Ballard, Craig Fox, Karl Fox, Phill Gross, Kory Hamzeh, former WG chair Russ Hobby, David Kaufman, former WG chair Steve Knowles, Mark Lewis, former WG chair Brian Lloyd, John LoVerso, Bill Melohn, Mike Patton, former WG chair Drew Perkins, Greg Satz, John Shriver, Vernon Schryver, and Asher Waldfogel โœจ๐Ÿงš

Special thanks to Morning Star Technologies for providing computing resources and network access support while this specification was being written ๐ŸŒˆ

Chair's Address ๐Ÿ“ฎ

the working group could be reached through the current chair ๐Ÿ’Œ

   Fred Baker
   Advanced Computer Communications
   315 Bollay Drive
   Santa Barbara, California  93117

   fbaker@acc.com

Editor's Address ๐Ÿ’œ

if you have questions about this memo, you can also reach out to the editor ๐Ÿ™ˆ

   William Allen Simpson
   Daydreamer
   Computer Systems Consulting Services
   1384 Fontaine
   Madison Heights, Michigan  48071

   Bill.Simpson@um.cc.umich.edu
       bsimpson@MorningStar.com
๐Ÿ“ฆ where this page comes from