RFC 1548

The Point-to-Point Protocol (PPP)

๐Ÿ“… published December 1993, from ietf

The Point-to-Point Protocol (PPP) ๐Ÿ’–

okay bestie, this is RFC 1548 ๐Ÿ’… and it's the spec for PPP, the Point-to-Point Protocol. W. Simpson of Daydreamer wrote it in December 1993. It's a Standards Track doc, which means it's aiming to become a real Internet standard ๐Ÿ”ฅ. It obsoletes RFC 1331, so this one replaces that older version ๐Ÿฆ‹. The header doesn't list anything it updates.

Status of This Memo โœจ

this doc is an Internet standards track protocol for the Internet community, and it's literally asking for discussion and suggestions for improvements ๐Ÿซถ. If you want the official standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1). And the distribution of this memo is unlimited, so share it with everyone ๐ŸŒˆ.

Abstract ๐ŸŒธ

PPP gives us 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 document defines the PPP organization and methodology, plus the PPP encapsulation. It also has an extensible option negotiation mechanism that can negotiate a whole bunch of configuration parameters and provides extra management functions ๐Ÿ”ฅ. The PPP Link Control Protocol (LCP) is described in terms of this mechanism ๐Ÿ’….

This document is the product of the Point-to-Point Protocol Working Group of the Internet Engineering Task Force (IETF). Comments should be submitted to the ietf-ppp@ucdavis.edu mailing list ๐Ÿ’Œ.

Table of Contents ๐Ÿ“‹

1.   Introduction ................................................3
1.1  Specification of Requirements ...............................4
1.2  Terminology .................................................5
2.   PPP Encapsulation ...........................................5
3.   PPP Link Operation ..........................................8
3.1  Overview ....................................................8
3.2  Phase Diagram ...............................................8
3.3  Link Dead (physical-layer not ready) ........................9
3.4  Link Establishment Phase ....................................9
3.5  Authentication Phase ........................................9
3.6  Network-Layer Protocol Phase ................................10
3.7  Link Termination Phase ......................................10
4.   The Option Negotiation Automaton ............................11
4.1  State Diagram ...............................................12
4.2  State Transition Table ......................................14
4.3  A Day in the Life ...........................................15
4.4  States ......................................................16
4.5  Events ......................................................19
4.6  Actions .....................................................23
4.7  Loop Avoidance ..............................................26
4.8  Counters and Timers .........................................26
5.   LCP Packet Formats ..........................................27
5.1  Configure-Request ...........................................29
5.2  Configure-Ack ...............................................30
5.3  Configure-Nak ...............................................31
5.4  Configure-Reject ............................................33
5.5  Terminate-Request and Terminate-Ack .........................34
5.6  Code-Reject .................................................35
5.7  Protocol-Reject .............................................36
5.8  Echo-Request and Echo-Reply .................................37
5.9  Discard-Request .............................................39
6.   LCP Configuration Options ...................................40
6.1  Maximum-Receive-Unit ........................................41
6.2  Async-Control-Character-Map .................................42
6.3  Authentication-Protocol .....................................43
6.4  Quality-Protocol ............................................45
6.5  Magic-Number ................................................46
6.6  Protocol-Field-Compression ..................................49
6.7  Address-and-Control-Field-Compression .......................50
APPENDIX A. LCP Recommended Options ..............................51
SECURITY CONSIDERATIONS ..........................................51
REFERENCES .......................................................52
ACKNOWLEDGEMENTS .................................................52
CHAIR'S ADDRESS ..................................................52
EDITOR'S ADDRESS .................................................53

1. Introduction โœจ

Encapsulation ๐ŸŽ€

okay so the PPP encapsulation lets several network-layer protocols share the same link at the same time ๐Ÿซง. The goal is one common solution that makes it easy to connect a wide variety of hosts, bridges and routers [1] ๐Ÿ’–.

The encapsulation was carefully designed to stay compatible with the most commonly used supporting hardware ๐Ÿ”ง.

With the default HDLC framing, the encapsulation only adds 8 extra octets ๐Ÿ“. When bandwidth is precious, the encapsulation and framing can shrink to 2 or 4 octets ๐Ÿ’œ.

For high-speed implementations, the default encapsulation uses simple fields, and only one of them needs to be examined for demultiplexing ๐Ÿš€. The default header and information fields line up on 32-bit boundaries, and the trailer can be padded to an arbitrary boundary ๐ŸŒˆ.

PPP needs to work in lots of different environments, so it has a Link Control Protocol (LCP) ๐ŸŒธ. The LCP handles a lot of the heavy lifting: it automatically agrees on the encapsulation format options, deals with different limits on packet sizes, authenticates the identity of the peer on the link, figures out when a link is working properly and when it's dead, detects a looped-back link and other common misconfiguration errors, and terminates the link when it's done ๐Ÿ’….

Network Control Protocols ๐ŸŒท

point-to-point links make a lot of existing network protocol problems worse ๐Ÿ˜ญ. Take assigning and managing IP addresses: that's annoying even on a LAN, and it's especially painful over circuit-switched point-to-point links like dial-up modem servers ๐Ÿ“ž. That's where the family of Network Control Protocols (NCPs) comes in ๐Ÿซถ. Each NCP handles 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 cover all the common configurations, so most of the time you don't have to do anything โœจ. An implementor can specify improvements to the default configuration, and those get communicated to the peer automatically, no operator intervention needed ๐Ÿค–. And if the link needs special settings to work in an environment where it otherwise couldn't, the operator can explicitly configure those options too ๐Ÿ”ง.

This self-configuration runs through an extensible option negotiation mechanism, where each end of the link tells the other what it can do and what it needs ๐Ÿซง. The mechanism is described in terms of the Link Control Protocol (LCP), but the same facilities are designed to be used by other control protocols too, especially the NCPs ๐ŸŒˆ.

1.1 Specification of Requirements ๐Ÿ“œ

this document uses a few words to signal the requirements of the specification. They're often written in capitals ๐Ÿ” .

MUST ๐Ÿ’…

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

MUST NOT ๐Ÿšซ

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

SHOULD ๐ŸŒŸ

This word, or the adjective "recommended", means there may be valid reasons in particular circumstances to ignore this item. But the full implications have to be understood and carefully weighed before choosing a different course ๐Ÿง.

MAY ๐Ÿฆ‹

This word, or the adjective "optional", means this item is one of an allowed set of alternatives. An implementation that doesn't include this option MUST be prepared to interoperate with another implementation that does include it ๐Ÿค.

1.2 Terminology ๐Ÿ“–

this document uses the following terms a lot, so here's the tea ๐Ÿต:

datagram ๐Ÿ“ฆ

The unit of transmission in the network layer (like IP). A datagram may be encapsulated in one or more packets passed down 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, passed across the interface between the network layer and the data link layer. A packet usually maps to a frame. The exceptions are when data link layer fragmentation is being performed, or when multiple packets are packed into a single frame ๐Ÿงฉ.

peer ๐Ÿซ‚

The other end of the point-to-point link ๐Ÿ’œ.

silently discard ๐Ÿ™ˆ

This means the implementation throws the packet away without any further processing ๐Ÿ—‘๏ธ. The implementation SHOULD provide the ability to log the error, including the contents of the silently discarded packet, and SHOULD record the event in a statistics counter ๐Ÿ“Š. Yes, both of those are SHOULDs, so log it and count it ๐Ÿ’….

2. PPP Encapsulation ๐ŸŽ€

Okay so the PPP encapsulation is how we tell apart multiprotocol datagrams, and it's giving organized ๐Ÿ’…. This encapsulation needs framing to show where it starts and where it ends. The framing methods live in companion documents, so keep those handy ๐Ÿฆ‹

The summary below shows the fields, sent from left to right โœจ

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

Protocol Field

The Protocol field is two octets long, and its value tells you which datagram is tucked into the Information field of the packet ๐Ÿ’– It gets sent and received most significant octet first.

This field follows the ISO 3309 extension mechanism for address fields, so it's giving structure ๐Ÿ‘‘ Every Protocol MUST be odd, meaning the least significant bit of the least significant octet MUST equal "1". Every Protocol MUST also be assigned so that the least significant bit of the most significant octet equals "0". If a frame doesn't follow these rules, it MUST be treated as having an unrecognized Protocol. No cap, that's a hard rule ๐Ÿ˜ญ

Protocol field values in the "0" to "3" range identify the network-layer protocol of specific packets ๐ŸŒˆ Values in the "8" to "b" range identify packets that belong to the matching Network Control Protocols (NCPs), if there are any โœจ

Protocol field values in the "4" to "7" range are for protocols with low volume traffic that don't have an NCP ๐Ÿงš Values in the "c" to "f" range mark packets as link-layer Control Protocols, like LCP ๐ŸŒธ

The up-to-date values live in the most recent "Assigned Numbers" RFC [2]. Here's the current list ๐Ÿ“

     Value (in hex)  Protocol Name

     0001            Padding Protocol
     0003 to 001f    reserved (transparency inefficient)
     0021            Internet Protocol
     0023            OSI Network Layer
     0025            Xerox NS IDP
     0027            DECnet Phase IV
     0029            Appletalk
     002b            Novell IPX
     002d            Van Jacobson Compressed TCP/IP
     002f            Van Jacobson Uncompressed TCP/IP
     0031            Bridging PDU
     0033            Stream Protocol (ST-II)
     0035            Banyan Vines
     0037            unused
     0039            AppleTalk EDDP
     003b            AppleTalk SmartBuffered
     003d            Multi-Link
     005d            reserved (compression inefficient)
     00cf            reserved (PPP NLPID)
     00fd            1st choice compression
     00ff            reserved (compression inefficient)

     0201            802.1d Hello Packets
     0203            IBM Source Routing BPDU
     0231            Luxcom
     0233            Sigma Network Systems

     8021            Internet Protocol Control Protocol
     8023            OSI Network Layer Control Protocol
     8025            Xerox NS IDP Control Protocol
     8027            DECnet Phase IV Control Protocol
     8029            Appletalk Control Protocol
     802b            Novell IPX Control Protocol
     802d            Reserved
     802f            Reserved
     8031            Bridging NCP
     8033            Stream Protocol Control Protocol
     8035            Banyan Vines Control Protocol
     8037            unused
     8039            Reserved
     803b            Reserved
     803d            Multi-Link Control Protocol
     80fd            Compression Control Protocol
     80ff            Reserved

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

If you're a developer making a brand-new protocol, you MUST get a number from the Internet Assigned Numbers Authority (IANA), at IANA@isi.edu. That's non-negotiable bestie ๐Ÿซถ

Information Field

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

The maximum length of the Information field, Padding included, is called the Maximum Receive Unit (MRU), and it defaults to 1500 octets ๐Ÿ’œ Consenting PPP implementations can agree on other MRU values through negotiation, which is so iconic ๐ŸŒˆ

Padding

On transmission, the Information field MAY be padded with an arbitrary number of octets, up to the MRU ๐ŸŽ€ Each protocol is responsible for telling padding octets apart from real information, so it's on them to get that right ๐Ÿ™ˆ


3.1 Overview

Alright, so to set up communications over a point-to-point link, each end of the PPP link MUST first send LCP packets to configure and test the data link ๐Ÿ”ฅ After the link is up, the peer MAY be authenticated. Then PPP MUST send NCP packets to pick and configure one or more network-layer protocols ๐Ÿ’… Once every chosen network-layer protocol is configured, datagrams from each of them can start flowing over the link ๐Ÿฆ‹

The link stays configured until explicit LCP or NCP packets shut it down, or until some external event happens, like an inactivity timer expiring or a network administrator stepping in ๐Ÿ“

3.2 Phase Diagram

While PPP is busy configuring, maintaining, and terminating the point-to-point link, the link moves through several distinct phases ๐Ÿงš

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

The link always begins and ends in this phase ๐ŸŒธ When an external event, like carrier detection or a network administrator's configuration, tells us the physical layer is ready to go, PPP moves on to the Link Establishment phase โœจ

During this phase, the LCP automaton (described below) sits in the Initial or Starting states ๐Ÿ’– Moving into the Link Establishment phase sends an Up event to the automaton.

Implementation Note: Typically, a link goes back to this phase on its own after a modem disconnects. On a hard-wired line, 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 through an exchange of Configure packets ๐Ÿ‘‘ The exchange is complete, and the LCP Opened state is entered, once a Configure-Ack packet (described below) has been both sent and received ๐ŸŽ€

All Configuration Options are assumed to be at default values unless the configuration exchange changes them ๐ŸŒˆ Check out the section on LCP Configuration Options for more on that.

It's important to know that LCP only configures the Configuration Options that don't depend on a particular network-layer protocol ๐Ÿ’… Configuring each individual network-layer protocol is handled by separate Network Control Protocols (NCPs) during the Network-Layer Protocol phase โœจ

Any non-LCP packets received during this phase MUST be silently discarded ๐Ÿ˜ญ

3.5 Authentication Phase

On some links, it might be desirable to require a peer to authenticate itself before any network-layer protocol packets get exchanged ๐Ÿ”ฅ

By default, authentication is not mandatory ๐Ÿฆ‹ If an implementation wants the peer to authenticate with a specific authentication protocol, then it MUST negotiate that authentication protocol during the Link Establishment phase ๐Ÿ’œ

Authentication SHOULD take place as soon as possible after link establishment ๐Ÿ“ However, link quality determination MAY happen at the same time. An implementation MUST NOT let the exchange of link quality determination packets delay authentication indefinitely, so no stalling ๐Ÿ™…โ€โ™€๏ธ

Moving from the Authentication phase to the Network-Layer Protocol phase MUST NOT happen until authentication has completed using the negotiated authentication protocol ๐Ÿงš If authentication fails, PPP SHOULD move on to the Link Termination phase instead ๐Ÿ’€

Any Network Control Protocol or network-layer protocol packets received during this phase MUST be silently discarded ๐ŸŒธ

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 own appropriate Network Control Protocol (NCP) ๐Ÿ‘‘

Each NCP MAY be Opened and Closed at any time โœจ

Implementation Note: Because an implementation might take a significant amount of time for link quality determination at first, implementations SHOULD avoid fixed timeouts when waiting for their peers to configure an NCP ๐Ÿซถ

After an NCP has reached the Opened state, PPP carries the matching network-layer protocol packets ๐Ÿ’– Any network-layer protocol packets received while the corresponding NCP is not in the Opened state MUST be silently discarded ๐Ÿ˜ญ

Implementation Note: There's an exception to the paragraphs above, thanks to the LCP Protocol-Reject (described below). While LCP is in the Opened state, any protocol packet the implementation doesn't support MUST be returned in a Protocol-Reject. Only supported protocols get silently discarded ๐Ÿ’…

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

okay so PPP can end the link literally whenever it wants ๐Ÿ’€ The loss of carrier, an authentication failure, link quality tanking, an idle-period timer running out, or someone administratively closing the link can all do it. LCP handles the closing by swapping Terminate packets back and forth. Once the link starts closing, PPP lets the network-layer protocols know so they can take whatever action makes sense for them ๐Ÿฆ‹

After the Terminate packets have been exchanged, the implementation SHOULD signal the physical layer to disconnect so the termination actually sticks, especially when authentication failed ๐Ÿ”ฅ The sender of the Terminate-Request SHOULD disconnect after it gets a Terminate-Ack, or after the Restart counter expires. The receiver of a Terminate-Request SHOULD wait for the peer to disconnect, and it MUST NOT disconnect until at least one Restart time has passed after it sent a Terminate-Ack. PPP SHOULD proceed to the Link Dead phase โœจ

Any non-LCP packets received during this phase MUST be silently discarded ๐Ÿ™ˆ

Implementation Note: The closing of the link by LCP is sufficient. There is no need for each NCP to send a flurry of Terminate packets. Conversely, the fact that one NCP has Closed is not sufficient reason to cause the termination of the PPP link, even if that NCP was the only NCP currently in the Opened state. ๐Ÿ’…

4. The Option Negotiation Automaton โœจ

the finite-state automaton is built out of events, actions and state transitions. Events include things like receiving external commands such as Open and Close, the Restart timer expiring, and packets arriving from a peer. Actions include starting the Restart timer and sending packets to the peer ๐Ÿงš

Some packet types are not told apart in the automaton descriptions: Configure-Naks and Configure-Rejects, Code-Rejects and Protocol-Rejects, and Echo-Requests, Echo-Replies and Discard-Requests. They do have different jobs, which we'll get to later, but they always cause the same transitions ๐ŸŽ€

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-Counter
TO-  = Timeout with counter expired     zrc = Zero-Restart-Counter

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 Diagram ๐Ÿฆ‹

the simplified state diagram below shows the sequence of events for reaching agreement on Configuration Options (which opens the PPP link) and for later terminating the link ๐Ÿ’–

This diagram is not a complete representation of the automaton. Implementation MUST be done by consulting the actual state transition table ๐Ÿ™ˆ

Events are in upper case and actions are in lower case. For these purposes, the state machine starts out in the Closed state. Once the Opened state has been reached, both ends of the link have met the requirement of having both sent and received a Configure-Ack packet ๐ŸŒˆ

              RCR                    TO+
            +--sta-->+             +------->+
            |        |             |        |
      +-------+      |   RTA +-------+      | Close +-------+
      |       |<-----+<------|       |<-str-+<------|       |
      |Closed |              |Closing|              |Opened |
      |       | Open         |       |              |       |
      |       |------+       |       |              |       |
      +-------+      |       +-------+              +-------+
                     |                                ^
                     |                                |
                     |         +-sca----------------->+
                     |         |                      ^
             RCN,TO+ V    RCR+ |     RCR-         RCA |    RCN,TO+
            +------->+         |   +------->+         |   +--scr-->+
            |        |         |   |        |         |   |        |
      +-------+      |   TO+ +-------+      |       +-------+      |
      |       |<-scr-+<------|       |<-scn-+       |       |<-----+
      | Req-  |              | Ack-  |              | Ack-  |
      | Sent  | RCA          | Rcvd  |              | Sent  |
+-scn->|       |------------->|       |       +-sca->|       |
|     +-------+              +-------+       |      +-------+
|  RCR- |   | RCR+                           |   RCR+ |   | RCR-
|       |   +------------------------------->+<-------+   |
|       |                                                 |
+<------+<------------------------------------------------+

4.2 State Transition Table ๐Ÿ“

the complete state transition table is right here ๐ŸŒธ States go across the top and events go down the side. Each entry is written as action/new-state. If there are several actions they're separated by commas, and they can keep going onto the next line when there's not enough room. The order of multiple actions is up to the implementation. A state can be followed by a letter, which points to a footnote. A dash (-) means an illegal transition โœจ

       | 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         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

the states where the Restart timer is running can be spotted by the presence of TO events. Only the Send-Configure-Request, Send-Terminate-Request and Zero-Restart-Counter actions start or restart the Restart timer. The Restart timer gets stopped whenever the automaton moves from a state where the timer is running to one where it isn't ๐Ÿฆ‹

  • [p] Passive option; see Stopped state discussion. ๐ŸŒท
  • [r] Restart option; see Open event discussion. ๐ŸŒท
  • [x] Crossed connection; see RCA event discussion. ๐ŸŒท

4.3 A Day in the Life ๐ŸŒˆ

okay bestie, here's a walkthrough of how a typical implementation might use the automaton to run LCP in a dial-up setup ๐Ÿ“ž

  • The Network Access Server gets powered on (Initial state, Link Dead phase) ๐Ÿ’ป
  • A config file says a certain link is for PPP access (Open: tls/Starting). The This-Layer-Started event turns DTR on for a modem so it's ready to take calls ๐ŸŽ€
  • An incoming call gets answered. The modem's CD triggers configuration negotiation (Up: irc,scr/Req-Sent, Link Establishment phase) ๐Ÿ“ž
  • A Configure-Request comes in and gets acknowledged (RCR+: sca/Ack-Sent) ๐Ÿ’Œ
  • The Request gets acknowledged too (RCA: irc,tlu/Opened). The This-Layer-Up event kicks off the authentication and quality monitoring protocols (Authentication phase) ๐Ÿ”
  • Once authentication and quality monitoring are happy, they send an Up event to start the available NCPs (Network-Layer Protocol phase) ๐Ÿš€
  • Later on the peer is done and closes the link. A Terminate-Request shows up (RTR: tld,zrc,sta/Stopping, Termination phase) ๐Ÿ‘‹ The This-Layer-Down action sends the Down event to any NCPs, and the Terminate-Ack gets sent. The Zero-Restart-Counter action makes the link wait for the peer to process the Terminate-Ack, with no retries ๐Ÿ™…โ€โ™€๏ธ
  • When the Restart Timer times out (TO-: tlf/Stopped), the This-Layer-Finished action tells the modem to hang up by dropping DTR ๐Ÿ“ด
  • When the modem's CD drops (Down: tls/Starting), the This-Layer-Started action raises DTR again so the modem is ready for the next call, which puts us back in the Link Dead phase ๐Ÿ’œ

4.4 States

Okay, bestie, let's go state by state ๐Ÿฆ‹ Each one is a little mood for the automaton, and I'm obsessed with how they fit together โœจ

Initial ๐ŸŒ™

The Initial state is where the lower layer is unavailable (Down) and no Open has happened yet. The Restart timer is not running in here ๐Ÿ’ค

Starting ๐Ÿš€

Starting is the Open counterpart to Initial. An administrative Open has been started, but the lower layer is still Down ๐Ÿซ  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 Up, but no Open has happened. The Restart timer is not running here.

When Configure-Request packets come in, 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 counterpart to Closed. The automaton lands here while 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 Configure-Request packets arrive, an appropriate response gets sent. When other packets arrive, a Terminate-Ack gets sent. Terminate-Acks are silently discarded to avoid creating a loop ๐Ÿ’…

Rationale:

Stopped is a junction state ๐Ÿ‘‘ It handles link termination, link configuration failure, and other automaton failure modes. These states could be separate, but they've been combined here on purpose โœจ

There's a race condition between the Down event response (from the This-Layer-Finished action) and the Receive-Configure-Request event ๐Ÿ˜ณ If a Configure-Request shows up before the Down event, the Down event supersedes it and returns the automaton to the Starting state. That's how it stops an attack by repetition ๐Ÿ›ก๏ธ

Implementation Option:

After the peer fails to respond to Configure-Requests, an implementation MAY wait passively for the peer to send Configure-Requests ๐Ÿ•Š๏ธ In this case, the This-Layer-Finished action is not used for the TO- event in the Request-Sent, Ack-Received and Ack-Sent states.

This option is useful for dedicated circuits, or circuits with no status signals available ๐Ÿ”Œ It SHOULD NOT be used for switched circuits ๐Ÿ™…โ€โ™€๏ธ

Closing ๐Ÿšช

In Closing, the automaton tries to end the connection ๐Ÿฅ€ A Terminate-Request has been sent and the Restart timer is running, but a Terminate-Ack hasn't come back yet.

When a Terminate-Ack is received, the Closed state gets entered. When the Restart timer expires, a new Terminate-Request is sent and the Restart timer is restarted ๐Ÿ”„ After the Restart timer has expired Max-Terminate times, this action may be skipped, and the Closed state may be entered.

Stopping ๐ŸงŠ

Stopping is the Open counterpart to Closing. A Terminate-Request has been sent and the Restart timer is running, but no Terminate-Ack has arrived yet.

Rationale:

Stopping gives the link a well-defined chance to terminate before any new traffic gets through ๐Ÿšฆ Once the link has terminated, a new configuration can happen via the Stopped or Starting states ๐Ÿ”

Request-Sent ๐Ÿ“จ

In Request-Sent, the automaton tries to configure the connection ๐Ÿ› ๏ธ A Configure-Request has been sent and the Restart timer is running, but a Configure-Ack hasn't 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, a Configure-Request and a Configure-Ack have both been sent, but no Configure-Ack has been received yet โณ The Restart timer is always running in this state.

Opened ๐ŸŒธ

In Opened, a Configure-Ack has been both sent and received ๐ŸŽ€ The Restart timer is not running in Opened.

When the automaton enters Opened, the implementation SHOULD signal the upper layers that it is now Up ๐Ÿ†™ When it leaves Opened, the implementation SHOULD signal the upper layers that it is now Down ๐Ÿ†˜

4.5 Events

Okay bestie, events are what make the automaton do stuff! ๐Ÿ’… Every transition and action is caused by an event, so let's go through them one by one โœจ

Up

The Up event happens when a lower layer says it's ready to carry packets ๐Ÿฆ‹ Usually a modem handling or calling process, or some other coupling of the PPP link to the physical media, uses this to tell LCP that the link is entering Link Establishment phase.

LCP can also use it to tell each NCP that the link is entering Network-Layer Protocol phase. So the This-Layer-Up action from LCP sets off the Up event in the NCP. Iykyk ๐Ÿซถ

Down

The Down event is the opposite: a lower layer says it's no longer ready to carry packets ๐ŸŒธ Again, a modem handling or calling process (or another coupling of the PPP link to the physical media) usually uses this to tell LCP that the link is entering Link Dead phase.

LCP can use it too, to tell each NCP that the link is leaving Network-Layer Protocol phase. That means the This-Layer-Down action from LCP triggers the Down event in the NCP ๐Ÿ’–

Open

The Open event means the link is administratively available for traffic. The network administrator (human or program) has said the link is allowed to be Opened ๐ŸŽ€ When this happens and the link is not in the Opened state, the automaton tries to send configuration packets to the peer.

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

When a Terminate-Request is received, or other events make the link unavailable, the automaton moves to a state where the link is ready to re-open. No extra admin intervention needed, so easy ๐Ÿงš

Implementation Option:

Users keep running an extra Open command when they want to renegotiate, which might mean new values need to be negotiated ๐Ÿ‘€ But that's not what Open is supposed to mean! 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. That renegotiates the link without any harmful side effects โœจ

Close

The Close 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 get denied until a new Open event happens.

Implementation Note:

When authentication fails, the link SHOULD be terminated, so attackers can't keep trying and launch denial of service against other users ๐Ÿ’€ Since the link is administratively available (by definition), you can do this by simulating a Close event to the LCP, immediately followed by an Open event.

The Close followed by an Open causes an orderly termination of the link. It progresses from the Closing state to the Stopping state, and 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 indicates that the Restart timer has expired. The Restart timer is used to time responses to Configure-Request and Terminate-Request packets โฐ

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

The TO- event means the Restart counter is not greater than zero, so no more packets need retransmitting. We're done here ๐ŸŒˆ

Receive-Configure-Request (RCR+,RCR-)

This event occurs when a Configure-Request packet is received from the peer. The Configure-Request packet says "I want to open a connection!" and may specify Configuration Options ๐Ÿ’œ It's described more fully in a later section.

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

The RCR- event means the Configure-Request was unacceptable, and it triggers the sending of 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)

The Receive-Configure-Ack event occurs when a valid Configure-Ack packet is received from the peer. A Configure-Ack is a positive response to a Configure-Request ๐ŸŽ€ An out of sequence or otherwise invalid packet gets silently discarded. Bye ๐Ÿ‘‹

Implementation Note:

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

Still, a correctly formed packet could 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 occurs when a valid Configure-Nak or Configure-Reject packet is received from the peer. Both are negative responses to a Configure-Request ๐Ÿ’… 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)

The Receive-Terminate-Request event occurs when a Terminate-Request packet is received. That means the peer wants to close the connection ๐Ÿฅบ

Implementation Note:

This event is not the same thing as 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)

The Receive-Terminate-Ack event occurs when a Terminate-Ack packet is received from the peer. A Terminate-Ack is usually a response to a Terminate-Request ๐Ÿงš It can also mean the peer is in the Closed or Stopped states, and it helps re-synchronize the link configuration.

Receive-Unknown-Code (RUC)

The Receive-Unknown-Code event occurs when an un-interpretable packet is received from the peer. A Code-Reject packet is sent back in response ๐Ÿคทโ€โ™€๏ธ

Receive-Code-Reject, Receive-Protocol-Reject (RXJ+,RXJ-)

This event occurs when a Code-Reject or a Protocol-Reject packet is received from the peer ๐Ÿซฃ

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

The RXJ- event 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 occurs when an Echo-Request, Echo-Reply or Discard-Request packet is received from the peer. An Echo-Reply is a response to an Echo-Request ๐Ÿ“ There is no reply to an Echo-Reply or a Discard-Request.

4.6. Actions

Okay bestie, actions are what the automaton actually does when an event hits ๐Ÿ’… They usually mean sending packets and/or starting or stopping the Restart timer โฑ๏ธโœจ

Illegal-Event (-)

This is the "literally should never happen" one ๐Ÿ˜ญ It means an event showed up that a properly implemented automaton can't ever get. That's an internal error on the implementation's side, so it should be reported and logged. No transition is taken, and the implementation SHOULD NOT reset or freeze ๐Ÿ™ˆ

This-Layer-Up (tlu)

Main character energy ๐Ÿ‘‘ This action tells the upper layers that the automaton is entering the Opened state.

Usually the LCP uses this to signal the Up event to an NCP, Authentication Protocol, or Link Quality Protocol. Or, an NCP can use it to say the link is available for its network layer traffic, since it MAY be used by a NCP for that exact purpose ๐Ÿซถ

This-Layer-Down (tld)

The opposite vibe ๐Ÿฅ€ This action tells the upper layers that the automaton is leaving the Opened state.

Usually the LCP uses this to signal the Down event to an NCP, Authentication Protocol, or Link Quality Protocol. An NCP MAY also use it to indicate that the link is no longer available for its network layer traffic ๐Ÿ’œ

This-Layer-Started (tls)

This one goes DOWN the stack โฌ‡๏ธ It 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 ๐ŸŒธ

Implementation Note:

The results here are highly implementation dependent ๐Ÿ™ƒ

The transitions where this event is indicated are defined for a message passing architecture, not a signalling architecture. If you want this action to control specific signals (like DTR), other transitions are likely to be required (Open in Closed, RCR in Stopped) ๐Ÿงš

This-Layer-Finished (tlf)

Clean-up crew ๐Ÿงน This action tells the lower layers that the automaton is entering the Stopped or Closed states, so the lower layer is no longer needed for the link. The lower layer SHOULD respond with a Down event once it has terminated ๐Ÿ“

Typically, this action MAY be used by the LCP to advance to the Link Dead phase, or it MAY be used by an NCP to tell the LCP that the link may terminate when there are no other NCPs open โœจ

Implementation Note:

The results here are highly implementation dependent ๐Ÿ™ƒ

The transitions where this event is indicated are defined for a message passing architecture, not a signalling architecture. If you want this action to control specific signals (like DTR), other transitions are likely to be required (Close in Starting, Down in Closing) ๐Ÿฆ‹

Initialize-Restart-Counter (irc)

This action sets the Restart counter to the right value, which is either Max-Terminate or Max-Configure ๐Ÿ”ข The counter gets decremented for every transmission, including the first one.

Implementation Note:

Setting the Restart counter isn't the only thing going on here. The implementation MUST set the timeout period to the initial value when Restart timer backoff is used ๐Ÿ’…

Zero-Restart-Counter (zrc)

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

Implementation Note:

This action lets the FSA pause before it moves on to the desired final state, which gives traffic a chance to get processed by the peer ๐Ÿซง Besides zeroing the Restart counter, the implementation MUST set the timeout period to an appropriate value.

Send-Configure-Request (scr)

This one sends a Configure-Request packet ๐Ÿ“จ It says "I want to open a connection with this specific set of Configuration Options." The Restart timer starts when the Configure-Request is transmitted, so there's a safety net against packet loss ๐Ÿฅ… The Restart counter gets decremented each time a Configure-Request is sent.

Send-Configure-Ack (sca)

This one sends a Configure-Ack packet โœ… It acknowledges a Configure-Request that came in with an acceptable set of Configuration Options. Yes queen ๐Ÿ‘‘

Send-Configure-Nak (scn)

This one sends a Configure-Nak or Configure-Reject packet, whichever fits ๐Ÿ™…โ€โ™€๏ธ It's the negative response, reporting a Configure-Request with an unacceptable set of Configuration Options. Configure-Nak packets refuse a Configuration Option value and suggest a new, acceptable one ๐Ÿ’ก Configure-Reject packets refuse all negotiation about a Configuration Option, usually because it isn't recognized or implemented. The difference between Configure-Nak and Configure-Reject is explained more fully in the section on LCP Packet Formats ๐Ÿ“–

Send-Terminate-Request (str)

This one sends a Terminate-Request packet ๐Ÿ‘‹ It says "I'd like to close this connection, please." The Restart timer starts when the Terminate-Request is transmitted, to guard against packet loss ๐Ÿ›Ÿ The Restart counter gets decremented each time a Terminate-Request is sent.

Send-Terminate-Ack (sta)

This one sends a Terminate-Ack packet ๐Ÿซถ It acknowledges a Terminate-Request, or otherwise helps keep the state machines in sync ๐Ÿ”„

Send-Code-Reject (scj)

This one sends a Code-Reject packet ๐Ÿšซ It's the "huh, I don't know that packet type" response, indicating a packet of an unknown type came in ๐Ÿคทโ€โ™€๏ธ

Send-Echo-Reply (ser)

This one sends an Echo-Reply packet ๐Ÿ“ It acknowledges an Echo-Request, basically a friendly "heard you!" ๐Ÿ’–


4.7. Loop Avoidance

The protocol makes a reasonable attempt at avoiding Configuration Option negotiation loops ๐Ÿ” However, the protocol does NOT guarantee that loops won't happen. Negotiation is negotiation, and it's totally possible to set up two PPP implementations with conflicting policies that will never converge ๐Ÿ’€ It's also possible to set up policies that do converge but take forever to get there ๐ŸŒ

So implementors should keep this in mind, and SHOULD implement loop detection mechanisms or higher level timeouts ๐Ÿ›ก๏ธ


4.8. Counters and Timers

Restart Timer

There's one special timer in this automaton, the Restart timer โฐ It times transmissions of Configure-Request and Terminate-Request packets. When it expires, it causes a Timeout event and retransmits the corresponding Configure-Request or Terminate-Request packet ๐Ÿ” 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 value is designed for low speed (2,400 to 9,600 bps), high switching latency links (typical telephone lines). Higher speed links, or links with low switching latency, SHOULD have correspondingly faster retransmission times โšก

Instead of one constant value, the Restart timer MAY begin at a small initial value and increase up to the configured final value ๐Ÿ“ˆ Each successive value that's less than the final value SHOULD be at least twice the previous value. The initial value SHOULD be large enough to account for the size of the packets, twice the round trip time for transmission at the link speed, and at least an additional 100 milliseconds so the peer has time to process the packets before responding ๐Ÿง  Some circuits add another 200 milliseconds of satellite delay ๐Ÿ›ฐ๏ธ Round trip times for modems operating at 14,400 bps have been measured in the range of 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 receiving a Terminate-Ack before we assume the peer just can't respond ๐Ÿซ  Max-Terminate MUST be configurable, but SHOULD default to two (2) transmissions.

Max-Configure

A similar counter is recommended for Configure-Requests ๐Ÿ’– Max-Configure is the number of Configure-Request packets sent without receiving a valid Configure-Ack, Configure-Nak, or Configure-Reject before we assume the peer is unable to 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 we assume configuration isn't converging ๐Ÿ“‰ Any further Configure-Nak packets get converted to Configure-Reject packets. Max-Failure MUST be configurable, but SHOULD default to ten (10) transmissions ๐ŸŽ€

5. LCP Packet Formats โœจ

okay so LCP has three classes of packets, and each one has its own job ๐Ÿ’…

  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).

This doc is describing Version 1 of the Link Control Protocol ๐ŸŽ€ bestie, there is literally no version field in the LCP packet, because simplicity is the whole vibe. If a new LCP version ever shows up, the plan is to use a new PPP Protocol field value to tell Version 1 apart from everything else. And a Version 1 implementation that's working properly will always answer unknown Protocols (other versions included) with an easily recognizable Version 1 packet ๐Ÿฆ‹ so the other versions get a predictable fallback. Iconic design, honestly.

No matter which Configuration Options are turned on, all the Link Configuration, Link Termination, and Code-Reject packets (codes 1 through 7) are always sent as if no Configuration Options were enabled ๐Ÿ”’. Why? So they stay recognizable even when one end of the link thinks it's open when it actually isn't ๐Ÿ™ˆ

Implementation Note: In particular, the Async-Control-Character-Map (ACCM) default for the type of link is used, and no address, control, or protocol field compression is allowed. Exactly one LCP packet is encapsulated in the PPP Information field, where the PPP Protocol field indicates type hex c021 (Link Control Protocol). ๐Ÿ’–

Here's the summary of the Link Control Protocol packet format ๐ŸŒธ 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             |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |    Data ...
  +-+-+-+-+

Code

The Code field is one octet and tells you what kind of LCP packet you're looking at ๐Ÿ‘€ If a packet shows up with an invalid Code field, a Code-Reject packet gets sent back. Rude, but fair ๐Ÿ’…

The up-to-date values of the LCP Code field live in the most recent "Assigned Numbers" RFC [2]. This spec is focused on 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's how requests and replies get matched up ๐Ÿงš If a packet comes in with an invalid Identifier field, it's silently discarded. No drama, just gone ๐Ÿซฅ

Length

The Length field is two octets and it tells you the length of the LCP packet, counting the Code, Identifier, Length and Data fields ๐Ÿ“ Any octets outside the range of the Length field get treated as padding and ignored when received. If a packet has an invalid Length field, it's silently discarded too ๐Ÿ’€

Data

The Data field is zero or more octets, as the Length field says. Its format is decided by the Code field ๐ŸŽ€

5.1 Configure-Request

Description

An implementation that wants to open a connection MUST transmit an LCP packet with the Code field set to 1 (Configure-Request), and the Options field filled with any desired changes to the link defaults ๐ŸŒˆ Configuration Options SHOULD NOT be included with default values, because why repeat what's already the default? ๐Ÿ™„

Upon reception of a Configure-Request, an appropriate reply MUST be transmitted ๐Ÿ’–

Here's the summary of the Configure-Request packet format ๐Ÿฆ‹

   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 content of the Options field changes, and whenever a valid reply has been received for a previous request ๐Ÿ”„ For retransmissions, the Identifier MAY remain unchanged ๐Ÿซถ

Options

The Options field is variable in length and holds the list of zero or more Configuration Options that the sender wants to negotiate ๐Ÿ“ All Configuration Options are always negotiated simultaneously, so it's a group project. The format of Configuration Options gets more detail in a later section.

5.2 Configure-Ack

Description

If every Configuration Option received in a Configure-Request is recognizable and all values are acceptable, then the implementation MUST transmit an LCP packet with the Code field set to 2 (Configure-Ack), the Identifier field copied from the received Configure-Request, and the Options field copied from the received Configure-Request ๐Ÿ‘‘ The acknowledged Configuration Options MUST NOT be reordered or modified in any way. Hands off! ๐Ÿ™…โ€โ™€๏ธ

On reception of a Configure-Ack, the Identifier field MUST match that of the last transmitted Configure-Request. On top of that, the Configuration Options in a Configure-Ack MUST exactly match those of the last transmitted Configure-Request ๐ŸŽฏ Invalid packets are silently discarded.

Here's the summary of the Configure-Ack packet format ๐ŸŒธ

   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 from the Configure-Request that caused this Configure-Ack ๐Ÿชž

Options

The Options field is variable in length and holds the 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 element of the received Configuration Options is recognizable but some values are not acceptable, then the implementation MUST transmit an LCP packet with the Code field set to 3 (Configure-Nak), the Identifier field copied from the received Configure-Request, and the Options field filled with only the unacceptable Configuration Options from the Configure-Request ๐Ÿ™ƒ All the acceptable Configuration Options get filtered out of the Configure-Nak, but otherwise the Configuration Options from the Configure-Request MUST NOT be reordered. Order matters, babe ๐Ÿ’œ

Options which have no value fields (boolean options) MUST use the Configure-Reject reply instead ๐Ÿšซ

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 present in the Configure-Request ๐Ÿ“‹

Finally, an implementation may be configured to request the 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 is a nudge to get the peer to include that option in its next Configure-Request packet. Any value fields for the option MUST indicate values acceptable to the Configure-Nak sender ๐ŸŒŸ

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

Reception of a valid Configure-Nak means a new Configure-Request MAY be sent, with the Configuration Options modified as the Configure-Nak specified ๐Ÿ” When multiple instances of a Configuration Option are present, the peer SHOULD select a single value to include in its next Configure-Request packet. One value, one vibe โœจ

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 ๐Ÿ“ Growth arc unlocked ๐Ÿฆ‹

Here's the summary of the Configure-Nak packet format ๐ŸŽ€

   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 from the Configure-Request that caused this Configure-Nak ๐Ÿช„

Options

The Options field is variable in length and holds the 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

okay so, if a Configure-Request comes in with Configuration Options that are unrecognizable or that your network admin has said are not okay to negotiate, then the implementation MUST send back an LCP packet with the Code field set to 4 (Configure-Reject), the Identifier field copied from that Configure-Request, and the Options field filled with ONLY the unacceptable Configuration Options ๐Ÿ™…โ€โ™€๏ธ. Everything that's recognizable and negotiable gets filtered out of the Configure-Reject. But the options that do make it in MUST NOT be reordered or modified in any way. Don't touch the vibe, bestie ๐Ÿ’…

When a Configure-Reject arrives, the Identifier field MUST match the one from the last Configure-Request you sent. The Configuration Options in the Configure-Reject MUST also be a proper subset of the ones in that last Configure-Request. If a packet doesn't pass these checks, it's invalid and gets silently discarded ๐Ÿซฅ

If you get a valid Configure-Reject, that means you SHOULD send a new Configure-Request that leaves out every Configuration Option listed in the Configure-Reject. Glow up time โœจ

Here's a quick peek at the Configure-Reject packet format. 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

The Code is 4 for Configure-Reject ๐Ÿ“

Identifier

The Identifier field is a copy of the Identifier field from the Configure-Request that caused this Configure-Reject. It's giving echo, but make it useful ๐Ÿ”

Options

The Options field is variable length and holds a list of zero or more Configuration Options that the sender is rejecting. All of them get rejected at the same time, no splitting the squad ๐Ÿ‘‘


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

Description

LCP has Terminate-Request and Terminate-Ack Codes so you can close a connection politely and not ghost anyone ๐Ÿซถ

If an LCP implementation wants to close a connection, it SHOULD send an LCP packet with the Code field set to 5 (Terminate-Request), and the Data field can hold whatever data you want. Terminate-Request packets SHOULD keep getting sent until a Terminate-Ack shows up, the lower layer says it has gone down, or enough have been sent that the peer is down with reasonable certainty. Basically, keep knocking until someone answers ๐Ÿšช

When a Terminate-Request comes in, an LCP packet MUST be sent back with the Code field set to 6 (Terminate-Ack), the Identifier field copied from the Terminate-Request packet, and the Data field filled with whatever data you like ๐Ÿ’œ

If a Terminate-Ack shows up without anyone asking for it, that means the peer is in the Closed or Stopped states, or it's otherwise in need of re-negotiation. Plot twist ๐Ÿ˜ณ

Here's the Terminate-Request and Terminate-Ack packet format. Still left to right, obviously ๐Ÿงš

   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 is 5 for Terminate-Request, and 6 for Terminate-Ack ๐ŸŒธ

Identifier

When sending, the Identifier field MUST change whenever the content of the Data field changes, and whenever a valid reply has come back for a previous request. For retransmissions, the Identifier MAY stay the same, so you're allowed to be consistent there ๐Ÿซ . When receiving, the Identifier field of the Terminate-Request gets copied into the Identifier field of the Terminate-Ack packet.

Data

The Data field is zero or more octets and holds uninterpreted data for the sender to use. It can be any binary value and any length from zero up to the peer's established MRU minus four. No judgment on what's in there ๐Ÿคทโ€โ™€๏ธ


5.6. Code-Reject ๐Ÿ™ˆ

Description

If an LCP packet shows up with a Code nobody recognizes, that means one of the LCP implementations is either faulty or incomplete. Not a vibe ๐Ÿ’€. This MUST be reported back to whoever sent the unknown Code, by sending an LCP packet with the Code field set to 7 (Code-Reject) and the inducing packet copied into the Rejected-Information field.

When a Code-Reject arrives, the implementation SHOULD report the error, because the situation is unlikely to fix itself automatically. Somebody has to step in ๐Ÿ› ๏ธ

Here's the Code-Reject packet format, 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
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |     Code      |  Identifier   |            Length             |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  | Rejected-Packet ...
  +-+-+-+-+-+-+-+-+

Code

The Code is 7 for Code-Reject ๐Ÿ’

Identifier

The Identifier field MUST change for every Code-Reject that gets sent. No copy-pasting IDs here ๐Ÿ™…โ€โ™€๏ธ

Rejected-Information

The Rejected-Information field holds a copy of the LCP packet being rejected. It starts with the Information field and does not include any Data Link Layer headers or an FCS. The Rejected-Information MUST be truncated so it complies with the peer's established MRU โœ‚๏ธ


5.7. Protocol-Reject ๐ŸŒˆ

Description

If a PPP packet arrives with a Protocol field nobody knows, that means the peer is trying to use a protocol that isn't supported. This usually happens when the peer tries to configure a new protocol, so it's kind of a big moment ๐Ÿ˜ญ

If the LCP state machine is in the Opened state, this error MUST be reported back to the peer by sending an LCP packet with the Code field set to 8 (Protocol-Reject), the Rejected-Protocol field set to the received Protocol, and the inducing packet copied into the Rejected-Information field ๐Ÿ“จ

When a Protocol-Reject comes in, the implementation MUST stop sending packets of the indicated protocol at the earliest opportunity. Hard stop, no more of that protocol ๐Ÿ›‘

Protocol-Reject packets can only be sent in the LCP Opened state. If a Protocol-Reject is received in any state other than the LCP Opened state, it SHOULD be silently discarded ๐Ÿซฅ

Here's the Protocol-Reject packet format ๐Ÿง

   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

The Code is 8 for Protocol-Reject ๐Ÿ’–

Identifier

The Identifier field MUST change for every Protocol-Reject that gets sent ๐Ÿ”

Rejected-Protocol

The Rejected-Protocol field is two octets and holds the PPP Protocol field of the packet being rejected. Two octets, just like that ๐Ÿฆ‹

Rejected-Information

The Rejected-Information field holds a copy of the packet being rejected. It starts with the Information field and does not include any Data Link Layer headers or an FCS. The Rejected-Information MUST be truncated so it complies with the peer's established MRU โœ‚๏ธ


5.8. Echo-Request and Echo-Reply ๐Ÿชž

Description

LCP has Echo-Request and Echo-Reply Codes so you can run a Data Link Layer loopback, which lets you exercise both directions of the link. This is super useful for debugging, checking link quality, performance testing, and a bunch of other stuff too ๐Ÿ”

An Echo-Request sender transmits an LCP packet with the Code field set to 9 (Echo-Request), the Identifier field set, the local Magic-Number (if any) inserted, and the Data field filled with whatever data you want, but not going over the peer's established MRU minus eight. Keep it reasonable, bestie ๐Ÿ“

When an Echo-Request is received, an LCP packet MUST be sent back with the Code field set to 10 (Echo-Reply), the Identifier field copied from the received Echo-Request, the local Magic-Number (if any) inserted, and the Data field copied from the Echo-Request. If the data is too big, truncate it as needed so you don't go over the peer's established MRU ๐Ÿช„

Echo-Request and Echo-Reply packets may only be sent in the LCP Opened state. If an Echo-Request or Echo-Reply is received in any state other than the LCP Opened state, it SHOULD be silently discarded ๐Ÿ™ƒ

Here's the Echo-Request and Echo-Reply packet format โœจ

    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

The Code is 9 for Echo-Request, and 10 for Echo-Reply ๐Ÿงšโ€โ™€๏ธ

Identifier

When sending, the Identifier field MUST change whenever the content of the Data field changes, and whenever a valid reply has come back for a previous request. For retransmissions, the Identifier MAY stay the same ๐Ÿซถ

When receiving, the Identifier field of the Echo-Request gets copied into the Identifier field of the Echo-Reply packet ๐Ÿ’œ

Magic-Number

The Magic-Number field is four octets and helps detect links that are in the looped-back condition, which is a whole mood ๐Ÿ”„. Until the Magic-Number Configuration Option has been successfully negotiated, the Magic-Number MUST be transmitted as zero. For more on this, check out the Magic-Number Configuration Option section ๐Ÿ’…

Data

The Data field is zero or more octets and holds uninterpreted data for the sender to use. It can be any binary value and any length from zero up to the peer's established MRU minus eight. Anything goes, as long as it fits ๐ŸŒธ

5.9. Discard-Request

Description

okay so LCP has this Discard-Request Code ๐Ÿ—‘๏ธโœจ basically it's a Data Link Layer sink, aka a place where data goes to vanish, and it's for poking at the local-to-remote direction of the link. bestie this is so useful for debugging, performance testing, and a bunch of other stuff ๐Ÿ’…

the sender sends an LCP packet with the Code field set to 11 (Discard-Request), sets the Identifier field, drops in the local Magic-Number (if there is one), and fills the Data field with whatever data they want, as long as it doesn't go over the peer's established MRU minus eight ๐ŸŽ€

Discard-Request packets may only be sent in the LCP Opened state. Also, the receiver MUST simply throw away any Discard-Request that it receives. no reading it, no answering it, just bye ๐Ÿ‘‹

Here's a quick look at the Discard-Request packet format. 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             |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                         Magic-Number                          |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |    Data ...
  +-+-+-+-+

Code

11 for Discard-Request. โœจ

Identifier

The Identifier field MUST be changed for each Discard-Request sent. no reusing IDs, bestie ๐Ÿ™…โ€โ™€๏ธ

Magic-Number

The Magic-Number field is four octets ๐Ÿ”ฎ and it helps detect links that have been looped back. Until the Magic-Number Configuration Option has been successfully negotiated, the Magic-Number MUST be transmitted as zero. For more on this, check out the Magic-Number Configuration Option ๐Ÿ’œ

Data

The Data field is zero or more octets ๐ŸŒธ and it holds uninterpreted data that the sender can use for whatever. It can be any binary value, and it can be anywhere from zero to the peer's established MRU minus four in length ๐Ÿงš


6. LCP Configuration Options โœจ

LCP Configuration Options are how you negotiate changes to the default settings of a point-to-point link ๐Ÿฆ‹ If a Configuration Option isn't in a Configure-Request packet, the default value for it is assumed, so no drama there ๐Ÿ’–

Some Configuration Options MAY be listed more than once. What happens when that's allowed depends on the specific option, and each option's description spells it out ๐ŸŽ€ (None of the Configuration Options in this specification can be listed more than once, so you're good, bestie.)

The end of the Configuration Options list is marked by the length of the LCP packet ๐Ÿ“

Unless it says otherwise, all Configuration Options work in a half-duplex way. Usually that means the receive direction of the link, seen from the point of view of whoever sent the Configure-Request ๐ŸŒˆ

Here's the Configuration Option format. Fields go 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 it tells you which type of Configuration Option you're looking at. The up-to-date values for the LCP Option Type field are in the most recent "Assigned Numbers" RFC [2] ๐Ÿ“š

This specification covers the following values:

         1       Maximum-Receive-Unit
         2       Async-Control-Character-Map
         3       Authentication-Protocol
         4       Quality-Protocol
         5       Magic-Number
         6       RESERVED
         7       Protocol-Field-Compression
         8       Address-and-Control-Field-Compression

Length

The Length field is one octet, and it's the length of the whole Configuration Option, counting the Type, Length and Data fields ๐Ÿ“ If a negotiable Configuration Option shows up in a Configure-Request with an invalid Length, a Configure-Nak SHOULD be transmitted. That Configure-Nak should include the desired Configuration Option with an appropriate Length and Data ๐Ÿซถ

Data

The Data field is zero or more octets ๐Ÿ’œ and holds information specific to the Configuration Option. Its format and length come from the Type and Length fields, so the two work as a team ๐Ÿ‘ฏโ€โ™€๏ธ


6.1. Maximum-Receive-Unit

Description

This Configuration Option lets you tell your peer that your side can receive bigger packets ๐Ÿ“ฆ, or ask the peer to send you smaller ones ๐Ÿค

The default value is 1500 octets. If you ask for smaller packets, an implementation MUST still be able to receive the full 1500 octet information field, just in case link synchronization gets lost ๐Ÿ˜ญ

Implementation Note

This option is about saying what an implementation is capable of ๐Ÿ’… The peer isn't required to max it out. For example, if an MRU of 2048 octets is indicated, the peer doesn't have to send anything that's 2048 octets. The peer also doesn't need to Configure-Nak just to say it'll only send smaller packets, because the implementation always has to support at least 1500 octets anyway ๐ŸŒธ

Here's the Maximum-Receive-Unit Configuration Option format. 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
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Type      |    Length     |      Maximum-Receive-Unit     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Type

1 ๐Ÿ”ข

Length

4 ๐Ÿ”ข

Maximum-Receive-Unit

The Maximum-Receive-Unit field is two octets, and it gives the maximum number of octets in the Information and Padding fields. It doesn't count the framing, the Protocol field, the FCS, or any transparency bits or bytes ๐ŸŽ€


6.2. Async-Control-Character-Map

Description

This Configuration Option is a way to negotiate control character transparency on asynchronous links ๐Ÿงš

On asynchronous links, the default value is 0xffffffff. That means every octet below 0x20 gets mapped into an appropriate two octet sequence. On most other links the default is 0, because there's no need for mapping ๐Ÿ“

Here's the tea though: it's rarely necessary to map every control character, and often you don't need to map any at all ๐Ÿ™ˆ This Configuration Option tells the peer which control characters MUST remain mapped whenever the peer sends them. The peer MAY still send any other octets in mapped format if it's necessary because of constraints the peer knows about. The peer SHOULD Configure-Nak with the logical union of the sets of mapped octets, so that if those octets show up by accident, they can be ignored when received ๐Ÿ’œ

Here's the Async-Control-Character-Map Configuration Option format. 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
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Type      |    Length     |  Async-Control-Character-Map
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         ACCM (cont)           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Type

2 ๐Ÿ”ข

Length

6 ๐Ÿ”ข

Async-Control-Character-Map

The Async-Control-Character-Map field is four octets, and it shows the set of control characters that should be mapped. The map is sent most significant octet first ๐Ÿฆ‹

Each numbered bit matches the octet with the same value. If a bit is cleared to zero, that octet doesn't need to be mapped. If a bit is set to one, that octet MUST remain mapped. For example, if bit 19 is set to zero, then ASCII control character 19 (DC3, Control-S) MAY be sent in the clear โœจ

Note: The least significant bit of the least significant octet (the final octet transmitted) is numbered bit 0, and it maps to the ASCII control character NUL. ๐Ÿ™ƒ

6.3. Authentication-Protocol

Description

Sometimes on a link you want the peer to prove who it is before any network-layer protocol packets get exchanged ๐Ÿ” By default, authentication isn't required.

This Configuration Option is how you negotiate a specific authentication protocol ๐ŸŽ€ 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, the implementation SHOULD attempt the next most desirable protocol in the next Configure-Request ๐Ÿ’…

If an implementation sends a Configure-Ack with this Configuration Option, it's agreeing to authenticate with the specified protocol ๐Ÿซถ An implementation that receives a Configure-Ack with this Configuration Option SHOULD expect the peer to authenticate with the acknowledged protocol ๐Ÿ‘€

There's no requirement that authentication be full duplex, or that the same protocol be used in both directions. It's totally fine for different protocols to be used in each direction ๐ŸŒˆ Of course, that depends on which specific protocols got negotiated.

Here's the Authentication-Protocol Configuration Option format. 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
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Type      |    Length     |     Authentication-Protocol   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |    Data ...
   +-+-+-+-+

Type

3 ๐Ÿ”ข

Length

= 4 ๐Ÿ“

Authentication-Protocol

The Authentication-Protocol field is two octets, and it says which authentication protocol is wanted. The values are always the same as the PPP Protocol field values for that same authentication protocol ๐Ÿงš

The up-to-date values for the Authentication-Protocol field are in the most recent "Assigned Numbers" RFC [2]. The current values are assigned like this:

  Value (in hex)    Protocol

  c023              Password Authentication Protocol
  c223              Challenge Handshake Authentication Protocol

Data

The Data field is zero or more octets ๐Ÿ’– and holds additional data, depending on the particular protocol.

6.4 Quality-Protocol ๐ŸŽ€

Description

okay bestie, on some links you literally want to know when and how often the link is dropping data ๐Ÿ‘€ That's called link quality monitoring โœจ

This option lets the two ends negotiate a specific protocol for doing that monitoring ๐Ÿ’… By default, link quality monitoring is disabled ๐Ÿ™ˆ

Quality monitoring doesn't have to be full duplex, and the same protocol doesn't have to be used in both directions. Different protocols each way is totally fine ๐Ÿฆ‹ Whatever works depends on which specific protocols got negotiated, obviously.

A summary of the Quality-Protocol 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     |        Quality-Protocol       |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |    Data ...
  +-+-+-+-+

Type

4 ๐Ÿ“

Length

>= 4 ๐Ÿ’–

Quality-Protocol

The Quality-Protocol field is two octets and tells you which link quality monitoring protocol is wanted ๐ŸŽฏ 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 holds extra data, depending on the particular protocol ๐Ÿงš


6.5 Magic-Number โœจ

Description

okay so this option helps detect looped-back links and other Data Link Layer anomalies ๐Ÿ” This Configuration Option MAY be required by some other Configuration Options, like the Quality-Protocol one. By default the Magic-Number isn't negotiated, and zero gets inserted wherever a Magic-Number might otherwise go ๐Ÿคท

Before this Configuration Option is requested, an implementation MUST choose its Magic-Number ๐ŸŽฒ It's recommended that the Magic-Number be chosen in the most random manner possible, so an implementation can be super confident it ends up with a unique number. A good way to pick a unique random number is to start with a unique seed ๐ŸŒฑ Suggested sources of uniqueness include machine serial numbers, other network hardware addresses, time-of-day clocks, and so on. Particularly good random number seeds are precise measurements of the inter-arrival time of physical events, like packet reception on other connected networks, server response time, or how fast a human types โŒจ๏ธ It's also suggested that as many sources as possible get used at the same time.

When a Configure-Request comes in with a Magic-Number Configuration Option, the received Magic-Number gets compared with the Magic-Number of the last Configure-Request sent to the peer ๐Ÿ‘€

If the two Magic-Numbers are different, the link isn't looped-back, and the Magic-Number SHOULD be acknowledged ๐Ÿ™Œ If the two are equal, it's possible (but not certain!) that the link is looped-back and this Configure-Request is actually the one that was last sent ๐Ÿ˜ณ To figure that out, a Configure-Nak MUST be sent specifying a different Magic-Number value. A new Configure-Request SHOULD NOT be sent to the peer until normal processing would cause it to be sent (that is, until a Configure-Nak is received or the Restart timer runs out) โณ

Receiving a Configure-Nak with a Magic-Number different from the one in the last Configure-Nak sent to the peer proves the link isn't looped-back, and gives you a unique Magic-Number ๐ŸŽ‰ If the Magic-Number is equal to the one sent in the last Configure-Nak, the chance of a looped-back link goes up, and a new Magic-Number MUST be chosen. Either way, a new Configure-Request SHOULD be sent with the new Magic-Number ๐Ÿ’–

If the link is indeed looped-back, this sequence (transmit Configure-Request, receive Configure-Request, transmit Configure-Nak, receive Configure-Nak) repeats over and over again ๐Ÿ˜ญ If the link isn't looped-back, the sequence might happen a few times, but it's extremely unlikely to keep repeating. More likely, the Magic-Numbers chosen at each end quickly diverge and end the sequence ๐Ÿฆ‹ The table below shows the probability of collisions, assuming both ends of the link select 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 a good source of uniqueness can't be found, it's recommended that this Configuration Option not be enabled. Configure-Requests with the option SHOULD NOT be transmitted, and any Magic-Number Configuration Options the peer sends SHOULD be either acknowledged or rejected. In this case, loop-backs can't be reliably detected by the implementation, although they may still be detectable by the peer ๐Ÿ™ˆ

If an implementation does transmit a Configure-Request with a Magic-Number Configuration Option, then it MUST NOT respond with a Configure-Reject if it receives a Configure-Request with a Magic-Number Configuration Option. That is, if an implementation wants to use Magic Numbers, it MUST also allow its peer to do so ๐Ÿซถ If an implementation does receive a Configure-Reject in response to a Configure-Request, it can only mean the link isn't looped-back, and its peer won't be using Magic-Numbers. In this case, an implementation SHOULD act as if the negotiation had been successful (as if it had instead received a Configure-Ack) โœ…

The Magic-Number can also be used to detect looped-back links during normal operation, not just during Configuration Option negotiation ๐Ÿ‘€ All LCP Echo-Request, Echo-Reply, and Discard-Request packets have a Magic-Number field. If Magic-Number has been successfully negotiated, an implementation MUST transmit these packets with the Magic-Number field set to its negotiated Magic-Number ๐Ÿ’…

The Magic-Number field of these packets SHOULD be inspected on reception. All received Magic-Number fields MUST be equal to either zero or the peer's unique Magic-Number, depending on whether or not the peer negotiated a Magic-Number. Receiving a Magic-Number field equal to the negotiated local Magic-Number means the link is looped-back ๐Ÿ” Receiving a Magic-Number that's neither the negotiated local Magic-Number nor the peer's negotiated Magic-Number (or zero, if the peer didn't negotiate one) means the link has been (mis)configured to talk to a different peer ๐Ÿ˜ฌ

How to recover from either case is unspecified and can vary from implementation to implementation ๐Ÿคท A somewhat pessimistic approach is to assume an LCP Down event. A further Open event will begin re-establishing the link, which can't finish until the loop-back condition ends and Magic-Numbers get successfully negotiated. A more optimistic approach (in the case of a loop-back) is to start transmitting LCP Echo-Request packets until an appropriate Echo-Reply is received, which shows the loop-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

The Magic-Number field is four octets and indicates a number which is very likely to be unique to one end of the link ๐Ÿงš A Magic-Number of zero is illegal and MUST always be Nak'd, if it is not Rejected outright ๐Ÿšซ

6.6 Protocol-Field-Compression ๐Ÿ—œ๏ธโœจ

Description

okay bestie, this option is all about negotiating compression for the PPP Protocol field ๐Ÿ’… by default, every implementation MUST send packets with two octet PPP Protocol fields, no shortcuts ๐Ÿ™ˆ

the cute part is that some Protocol field numbers can squish down into one octet, and that single-octet form is clearly different from the two-octet one ๐ŸŽ€ this option is how you tell your peer "hey, I can receive those tiny single-octet Protocol fields" ๐Ÿฆ‹

quick refresher from earlier: 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 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. any number of "0" octets can go in front and it still means the same value. like, 3 is 00000011 and it's also 00000000 00000011 ๐Ÿงš same vibe, different outfit ๐Ÿ’œ

on low speed links, bandwidth is precious ๐Ÿ’€ so you want to send as little redundant data as possible ๐Ÿ“ Protocol-Field-Compression gives you a trade-off between implementation simplicity and bandwidth efficiency โœจ if it gets negotiated, the ISO 3309 extension mechanism can be used to squish the Protocol field down to one octet instead of two. and honestly, most packets qualify, since data protocols usually get Protocol field values under 256 ๐Ÿ‘‘

now the important rules ๐Ÿšจ

Compressed Protocol fields MUST NOT be transmitted unless this Configuration Option has been negotiated. once it IS negotiated, 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. this rule is what guarantees LCP packets can always be recognized without any confusion ๐Ÿ”ฅ

and 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.7 Address-and-Control-Field-Compression ๐ŸŒธ

Description

this one is the sister option ๐Ÿ’– it negotiates compression of the Data Link Layer Address and Control fields. by default, every implementation MUST send frames with Address and Control fields that fit the link framing ๐Ÿ“ฆ

these fields usually have constant values on point-to-point links, so they're super easy to compress ๐Ÿฅฐ this option just tells the peer "I can receive compressed Address and Control fields" ๐Ÿฆ‹

if you receive a compressed frame but Address-and-Control-Field-Compression was never negotiated, the implementation MAY silently discard the frame ๐Ÿ™ˆ

the Address and Control fields MUST NOT be compressed when sending any LCP packet. same energy as before: this keeps LCP packets unambiguously recognizable โœจ

and 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

The following Configurations Options are recommended:

SYNC LINES

Magic Number
Link Quality Monitoring
No Address and Control Field Compression
No Protocol Field Compression

ASYNC LINES

Async Control Character Map
Magic Number
Address and Control Field Compression
Protocol Field Compression

Security Considerations ๐Ÿšจ

Security issues are briefly discussed in sections concerning the Authentication Phase, the Close event, and the Authentication-Protocol Configuration Option. Further discussion is in a companion document entitled PPP Authentication Protocols. so yes, go read that companion doc, it's the real tea ๐Ÿต๐Ÿ˜ญ

References

  • [1] Perkins, D., "Requirements for an Internet Standard Point-to-Point Protocol", RFC 1547, December 1993.
  • [2] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, RFC 1340, USC/Information Sciences Institute, July 1992.

Acknowledgments ๐Ÿซถ

Much of the text in this document is taken from the WG Requirements, and RFCs 1171 & 1172, by Drew Perkins of Carnegie Mellon University, and by Russ Hobby of the University of California at Davis. the people who came before us are literally iconic ๐Ÿ‘‘

Many people spent significant time helping to develop the Point-to-Point Protocol. The complete list of people is too numerous to list, but the following people deserve special thanks: Rick Adams (UUNET), Ken Adelman (TGV), Fred Baker (ACC), Mike Ballard (Telebit), Craig Fox (Network Systems), Karl Fox (Morning Star Technologies), Phill Gross (AN&S), former WG chair Russ Hobby (UC Davis), David Kaufman (Proteon), former WG chair Steve Knowles (FTP Software), former WG chair Brian Lloyd (L&A), John LoVerso (Xylogics), Bill Melohn (Sun Microsystems), Mike Patton (MIT), former WG chair Drew Perkins (Fore), Greg Satz (cisco systems), John Shriver (Proteon), Vernon Schryver (Silicon Graphics), and Asher Waldfogel (Wellfleet). the whole squad ๐ŸŒˆ

The "Day in the Life" example was instigated by Kory Hamzeh (Avatar). In this version, improvements in wording were also provided by Scott Ginsburg, Mark Moraes, and Timon Sloan, as they worked on implementations. ๐Ÿ“

Special thanks to Morning Star Technologies for providing computing resources and network access support for writing this specification. ๐Ÿ’œ

Chair's Address ๐Ÿฆ‹

The working group can be contacted via the current chair:

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

EMail: fbaker@acc.com

Editor's Address โœจ

Questions about this memo can also be directed to:

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

EMail: Bill.Simpson@um.cc.umich.edu

that's the whole thing, bestie ๐ŸŒˆ PPP is officially wrapped up and we ate every single section ๐Ÿ’…๐ŸŽ€

๐Ÿ“ฆ where this page comes from