RFC 1331
The Point-to-Point Protocol (PPP) for the Transmission of Multi-protocol Datagrams over Point-to-Point Links
RFC 1331: The Point-to-Point Protocol (PPP) for the Transmission of Multi-protocol Datagrams over Point-to-Point Links ๐
okay bestie, this is the doc that gave us PPP ๐ It's a Standards Track spec from the IAB, written by W. Simpson (Daydreamer), dated May 1992. It obsoletes RFCs 1171 and 1172, which means it replaces them, so those older docs are out of the picture. Not gonna lie, I'm obsessed with how this one pulled everything together โจ
Status of this Memo ๐
ngl this part is kinda important so read it. This RFC is an IAB standards track protocol spec for the Internet community. It's also asking people for discussion and suggestions for improvements ๐ซถ For the current standardization state and status of this protocol, check the latest edition of the "IAB Official Protocol Standards" doc. And the memo can be distributed with no restrictions (distribution is unlimited) ๐
Abstract ๐ฆ
so PPP is how you send datagrams over serial point-to-point links ๐ It has three main parts:
- A way to encapsulate datagrams over serial links (wrapping them up so they travel safely) ๐
- A Link Control Protocol (LCP) for establishing, configuring, and testing the data-link connection ๐งช
- A family of Network Control Protocols (NCPs) for establishing and configuring different network-layer protocols ๐ง
This doc defines the PPP encapsulation scheme plus LCP, which is an extensible option negotiation protocol. It can negotiate a whole bunch of configuration parameters and also does some extra management stuff. Main character energy, literally ๐
This RFC is a product of the Point-to-Point Protocol Working Group of the IETF. If you have comments, send them to the ietf-ppp@ucdavis.edu mailing list ๐
Table of Contents ๐
1. Introduction .......................................... 1
1.1 Specification of Requirements ................... 3
1.2 Terminology ..................................... 3
2. Physical Layer Requirements ........................... 4
3. The Data Link Layer ................................... 5
3.1 Frame Format .................................... 6
4. PPP Link Operation .................................... 10
4.1 Overview ........................................ 10
4.2 Phase Diagram ................................... 10
4.3 Link Dead (physical-layer not ready) ............ 10
4.4 Link Establishment Phase ........................ 11
4.5 Authentication Phase ............................ 11
4.6 Network-Layer Protocol Phase .................... 12
4.7 Link Termination Phase .......................... 12
5. The Option Negotiation Automaton ...................... 14
5.1 State Diagram ................................... 15
5.2 State Transition Table .......................... 16
5.3 States .......................................... 18
5.4 Events .......................................... 20
5.5 Actions ......................................... 24
5.6 Loop Avoidance .................................. 26
5.7 Counters and Timers ............................. 27
6. LCP Packet Formats .................................... 28
6.1 Configure-Request ............................... 30
6.2 Configure-Ack ................................... 31
6.3 Configure-Nak ................................... 32
6.4 Configure-Reject ................................ 33
6.5 Terminate-Request and Terminate-Ack ............. 35
6.6 Code-Reject ..................................... 36
6.7 Protocol-Reject ................................. 38
6.8 Echo-Request and Echo-Reply ..................... 39
6.9 Discard-Request ................................. 40
7. LCP Configuration Options ............................. 42
7.1 Format .......................................... 43
7.2 Maximum-Receive-Unit ............................ 44
7.3 Async-Control-Character-Map ..................... 45
7.4 Authentication-Protocol ......................... 47
7.5 Quality-Protocol ................................ 49
7.6 Magic-Number .................................... 51
7.7 Protocol-Field-Compression ...................... 54
7.8 Address-and-Control-Field-Compression ........... 56
APPENDICES ................................................... 58
A. Asynchronous HDLC ..................................... 58
B. Fast Frame Check Sequence (FCS) Implementation ........ 61
B.1 FCS Computation Method .......................... 61
B.2 Fast FCS table generator ........................ 63
C. LCP Recommended Options ............................... 64
SECURITY CONSIDERATIONS ...................................... 65
REFERENCES ................................................... 65
ACKNOWLEDGEMENTS ............................................. 66
CHAIR'S ADDRESS .............................................. 66
AUTHOR'S ADDRESS ............................................. 66
1. Introduction ๐ธ
Motivation
okay so the Internet has been blowing up ๐ The number of hosts running TCP/IP has grown explosively over the last few years. Most of them sit on Local Area Networks (LANs), with Ethernet being the big one. A bunch of the others are on Wide Area Networks (WANs) like X.25 style Public Data Networks (PDNs). But relatively few hosts use simple point-to-point (serial) links, even though those are among the oldest ways to do data comms and almost every host supports them. Asynchronous RS-232-C [1] interfaces are basically everywhere ๐
Encapsulation
one reason there aren't many point-to-point IP links is that there's no standard encapsulation protocol ๐ญ There are tons of non-standard ones (and at least one de facto standard), but nothing has been agreed on as an Internet Standard. Meanwhile, LANs have standard encapsulation schemes already, so it's kinda unfair lol ๐
PPP gives you encapsulation over both bit-oriented synchronous links and asynchronous links with 8 bits of data and no parity. These links MUST be full-duplex, but they MAY be either dedicated or circuit-switched. PPP is built on HDLC for its encapsulation ๐
PPP is designed to stay compatible with the hardware people actually use โจ It also has an escape mechanism so control data like XON/XOFF can go across the link transparently, and so spurious control data that intervening hardware or software injects into the link can be removed ๐งน
The PPP encapsulation also lets you multiplex different network-layer protocols at the same time over one link. The goal is one common solution for easily connecting a wide variety of hosts, bridges and routers ๐
Some protocols need error-free transmission, and they either do error detection only conditionally or don't do it at all. PPP uses the HDLC Frame Check Sequence for error detection ๐ง It's commonly available in hardware, and a software implementation is provided too.
By default, the encapsulation only adds 8 extra octets ๐ฌ In environments where bandwidth is precious, it can be shrunk down to as few as 2 octets. For fast hardware, PPP makes sure the default encapsulation header and information fields land on 32-bit boundaries, and it lets the trailer get padded out to an arbitrary boundary ๐
Link Control Protocol
here's the big deal, though: PPP is more than just an encapsulation scheme ๐ค To be versatile enough to port across a wide range of environments, PPP has a Link Control Protocol (LCP). The LCP is used to automatically agree on the encapsulation format options, handle varying limits on packet sizes, authenticate the identity of the peer on the link, figure out when a link is working properly and when it's dead, detect a looped-back link and other common misconfigurations, and terminate the link ๐ซ
Network Control Protocols
point-to-point links make a lot of existing network protocol problems worse ๐ For example, assigning and managing IP addresses is annoying even on LANs, but it's especially rough over circuit-switched 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. Those NCPs are defined in other documents ๐
Configuration
PPP is meant to be easy to configure ๐ฅฐ The standard defaults should handle all the common setups out of the box. An implementor can specify improvements to the defaults, and those get automatically communicated to the peer with no operator babysitting. And if needed, the operator can explicitly configure link options so it works in environments where it otherwise couldn't ๐ซถ
The self-configuration happens through an extensible option negotiation mechanism, where each end of the link tells the other about its capabilities and requirements. This doc specifies the option negotiation in terms of LCP, but the same facilities can be used by the Internet Protocol Control Protocol (IPCP) and the others in the NCP family ๐ง
1.1. Specification of Requirements
okay so this section explains the vocab ๐ A few words get used to signal the requirements of the spec, and they're often written in capitals. Here's what each one means ๐
MUST
this word (or the adjective "required") means the definition is an absolute requirement of the spec. No wiggle room ๐
MUST NOT
this phrase means the definition is an absolute prohibition of the spec. Hard no ๐ซ
SHOULD
this word (or the adjective "recommended") means there may be valid reasons in particular circumstances to ignore the item, but the full implications should be understood and carefully weighed before picking a different path ๐ค
MAY
this word (or the adjective "optional") means the 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. So be nice to your bestie's implementation, periodt ๐
Note to self: the next part of this doc picks up at Section 1.2 (Terminology), so stay tuned! ๐ง
1.2. Terminology ๐
okay so this doc keeps using a couple of terms over and over, so let's lock them in first ๐
- 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 capability of logging the error, including the contents of the silently discarded packet, and SHOULD record the event in a statistics counter. ๐
2. Physical Layer Requirements ๐โจ
PPP is literally so chill about hardware ๐ญ It works over any DTE/DCE interface (for example EIA RS-232-C, EIA RS-422, EIA RS-423 and CCITT V.35). The one hard requirement is a full-duplex circuit, either dedicated or circuit-switched, that can run in asynchronous (start/stop) or synchronous bit-serial mode, as long as it's transparent to PPP Data Link Layer frames. PPP doesn't put any limits on transmission rate, other than whatever the particular DTE/DCE interface you're using already imposes. ๐
PPP does not require any particular synchronous encoding, such as FM, NRZ, or NRZI. ๐
Implementation Note: NRZ is currently the most widely available, so on that basis it is recommended as a default. When configuring the encoding is allowed, NRZI is recommended as an alternative, because of its relative immunity to signal inversion configuration errors. ๐
PPP does not require the use of modem control signals, such as Request To Send (RTS), Clear To Send (CTS), Data Carrier Detect (DCD), and Data Terminal Ready (DTR). ๐
Implementation Note: When they're available, using these signals can allow greater functionality and performance. In particular, such signals SHOULD be used to signal the Up and Down events in the Option Negotiation Automaton (described below). โญ
3. The Data Link Layer ๐ง
okay this part is the foundation, so pay attention bestie ๐ PPP borrows the principles, terminology, and frame structure of the International Organization For Standardization's (ISO) High-level Data Link Control (HDLC) procedures (ISO 3309-1979 [2]), as modified by ISO 3309:1984/PDAD1 "Addendum 1: Start/stop transmission" [5]. ISO 3309-1979 covers the HDLC frame structure for synchronous environments. ISO 3309:1984/PDAD1 proposes changes to ISO 3309-1979 so it can work in asynchronous environments. ๐ฆ
The PPP control procedures use the definitions and Control field encodings standardized in ISO 4335-1979 [3] and ISO 4335-1979/Addendum 1-1979 [4]. The PPP frame structure is also consistent with CCITT Recommendation X.25 LAPB [6], since that one is based on HDLC too. ๐ง
The purpose of this memo is NOT to re-document what's already standardized in ISO 3309 (sorry, I mean it's not the point of this doc ๐ ). We assume the reader already knows HDLC, or has access to a copy of [2] or [6]. Instead, this paper gives a concise summary and points out the specific options and features PPP uses. Since "Addendum 1: Start/stop transmission" isn't yet standardized and widely available, it gets summarized in Appendix A. ๐
To stay consistent with standard Internet practice, and to avoid confusing people who are used to reading RFCs, all binary numbers in the following descriptions are in Most Significant Bit to Least Significant Bit order, reading from left to right, unless otherwise indicated. Note that this is the opposite of standard ISO and CCITT practice, which orders bits as transmitted (i.e., network bit order). Keep this in mind when you compare this document with the international standards documents. ๐
3.1. Frame Format ๐ผ๏ธ
A summary of the standard PPP frame structure is shown below. This figure does not include start/stop bits (for asynchronous links), or any bits or octets inserted for transparency. The fields are transmitted from left to right. โจ
+----------+----------+----------+----------+------------
| Flag | Address | Control | Protocol | Information
| 01111110 | 11111111 | 00000011 | 16 bits | *
+----------+----------+----------+----------+------------
---+----------+----------+-----------------
| FCS | Flag | Inter-frame Fill
| 16 bits | 01111110 | or next Address
---+----------+----------+-----------------
Inter-frame Time Fill โณ
For asynchronous links, inter-frame time fill SHOULD be done the same way as inter-octet time fill, by transmitting continuous "1" bits (mark-hold state). ๐ซ
For synchronous links, the Flag Sequence SHOULD be transmitted during inter-frame time fill. There is no provision for inter-octet time fill. ๐คทโโ๏ธ
Implementation Note: Mark idle (continuous ones) SHOULD NOT be used for idle synchronous inter-frame time fill. However, certain types of circuit-switched links require mark idle, particularly those that calculate accounting based on bit activity. When mark idle is used on a synchronous link, the implementation MUST ensure at least 15 consecutive "1" bits between Flags, and that the Flag Sequence is generated at the beginning and end of a frame. ๐ง
Flag Sequence ๐ฉ
The Flag Sequence is a single octet and marks the beginning or end of a frame. It's the binary sequence 01111110 (hexadecimal 0x7e). ๐ธ
The Flag is a frame separator. Only one Flag is required between two frames. Two consecutive Flags make an empty frame, which gets ignored. ๐
Implementation Note: The "shared zero mode" Flag Sequence "011111101111110" SHOULD NOT be used. When it can't be avoided, such an implementation MUST ensure that the first Flag Sequence detected (the end of the frame) is promptly communicated to the link layer. ๐จ
Address Field ๐
The Address field is a single octet and contains the binary sequence 11111111 (hexadecimal 0xff), the All-Stations address. PPP does not assign individual station addresses. The All-Stations address MUST always be recognized and received. Other address lengths and values may be defined at a later time, or by prior agreement. Frames with unrecognized Addresses SHOULD be silently discarded, and reported through the normal network management facility. ๐ฃ
Control Field ๐๏ธ
The Control field is a single octet and contains the binary sequence 00000011 (hexadecimal 0x03), the Unnumbered Information (UI) command with the P/F bit set to zero. Frames with other Control field values SHOULD be silently discarded. ๐ซ
Protocol Field ๐งฉ
The Protocol field is two octets, and its value tells you which protocol is encapsulated in the Information field of the frame. ๐
This Protocol field is defined by PPP and is not a field defined by HDLC. However, it is consistent with the ISO 3309 extension mechanism for Address fields. All Protocols MUST be odd; the least significant bit of the least significant octet MUST equal "1". Also, all Protocols MUST be assigned such that the least significant bit of the most significant octet equals "0". Frames received that don't follow these rules MUST be considered as having an unrecognized Protocol, and handled as specified by the LCP. The Protocol field is transmitted and received most significant octet first. ๐ข
Protocol field values in the "0---" to "3---" range identify the network-layer protocol of specific datagrams, and values in the "8---" to "b---" range identify datagrams belonging to the associated Network Control Protocols (NCPs), if any. ๐
Protocol field values in the "4---" to "7---" range are used for protocols with low volume traffic that have no associated NCP. Protocol field values in the "c---" to "f---" range identify datagrams as link-layer Control Protocols (such as LCP). ๐ฆ
The most up-to-date values of the Protocol field are specified in the most recent "Assigned Numbers" RFC [11]. Current values are assigned as follows: ๐
Value (in hex) Protocol Name
0001 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 reserved (until 1993)
00ff reserved (compression inefficient)
0201 802.1d Hello Packets
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
c021 Link Control Protocol
c023 Password Authentication Protocol
c025 Link Quality Report
c223 Challenge Handshake Authentication Protocol
Developers of new protocols MUST obtain a number from the Internet Assigned Numbers Authority (IANA), at IANA@isi.edu. ๐
Information Field ๐ฆ
The Information field is zero or more octets. It contains the datagram for the protocol named in the Protocol field. The end of the Information field is found by locating the closing Flag Sequence and allowing two octets for the Frame Check Sequence field. The default maximum length of the Information field is 1500 octets. By negotiation, consenting PPP implementations may use other values for the maximum Information field length. ๐ฅฐ
On transmission, the Information field may be padded with an arbitrary number of octets, up to the maximum length. It is the responsibility of each protocol to tell padding octets apart from real information. ๐ซง
Frame Check Sequence (FCS) Field ๐
The Frame Check Sequence field is normally 16 bits (two octets). Other FCS lengths may be defined at a later time, or by prior agreement. ๐งฎ
The FCS field is calculated over all bits of the Address, Control, Protocol and Information fields, not including any start and stop bits (asynchronous) and any bits (synchronous) or octets (asynchronous) inserted for transparency. This does not include the Flag Sequences or the FCS field itself. The FCS is transmitted with the coefficient of the highest term first. โจ
Note: When octets are received which are flagged in the Async-Control-Character-Map, they are discarded before calculating the FCS. See the description in Appendix A. ๐งน
For more information on the specification of the FCS, see ISO 3309 [2] or CCITT X.25 [6]. ๐
Note: A fast, table-driven implementation of the 16-bit FCS algorithm is shown in Appendix B. This implementation is based on [7], [8], and [9]. ๐๏ธ
Modifications to the Basic Frame Format ๐จ
The Link Control Protocol can negotiate modifications to the standard PPP frame structure. However, modified frames will always be clearly distinguishable from standard frames. ๐ฆ
4. PPP Link Operation ๐โจ
4.1. Overview ๐
okay so before PPP can do literally anything, both ends of the point-to-point link have to send LCP packets to configure and test the data link ๐โจ. Once the link is up, the peer might get authenticated ๐. Then PPP sends NCP packets to pick and configure one or more network-layer protocols ๐ง. Once each chosen protocol is configured, its datagrams can finally flow over the link ๐.
The link stays configured until explicit LCP or NCP packets shut it down, or until something outside the protocol happens, like an inactivity timer running out or a network administrator stepping in ๐ฐ๏ธ๐ .
4.2. Phase Diagram ๐ฆ
while PPP is busy configuring, maintaining, and terminating the link, it moves through a bunch of distinct phases, and this diagram shows how they connect ๐:
+------+ +-----------+ +--------------+
| | UP | | OPENED | | SUCCESS/NONE
| Dead |------->| Establish |---------->| Authenticate |--+
| | | | | | |
+------+ +-----------+ +--------------+ |
^ FAIL | FAIL | |
+<--------------+ +----------+ |
| | |
| +-----------+ | +---------+ |
| DOWN | | | CLOSING | | |
+------------| Terminate |<---+<----------| Network |<-+
| | | |
+-----------+ +---------+
4.3. Link Dead (physical-layer not ready) ๐ค
every link starts and ends in this phase, no exceptions ๐ซถ. When something external happens, like carrier detection or a network administrator configuring the link, and tells PPP the physical layer is ready to go, PPP moves on to the Link Establishment phase ๐.
while we're in this phase, the LCP automaton (we'll get to it later) is sitting in its Initial or Starting states ๐ด. Moving into Link Establishment sends an Up event to the automaton โก.
Implementation Note:
Typically, a link goes back to this phase automatically 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 ๐.
4.4. Link Establishment Phase ๐ค
the Link Control Protocol (LCP) sets up the connection by trading Configure packets back and forth ๐ฌ. The exchange is finished, and the LCP Opened state is reached, once a Configure-Ack packet has been both sent and received โ . Any non-LCP packets that show up during this phase MUST be silently discarded ๐.
every Configuration Option starts out at its default value unless the configuration exchange changes it ๐งธ. Check out the section on LCP Configuration Options for more details ๐.
it's really important to know that LCP only configures the options that don't depend on any particular network-layer protocol ๐ธ. Configuring each network-layer protocol is the job of its own Network Control Protocol (NCP), and that happens during the Network-Layer Protocol phase ๐งโโ๏ธ.
4.5. Authentication Phase ๐
sometimes a link wants the peer to prove who it is before any network-layer protocol packets are allowed to flow ๐ต๏ธโโ๏ธ.
by default, authentication isn't required ๐ โโ๏ธ. But if an implementation insists that the peer uses some specific authentication protocol, then it MUST negotiate that authentication protocol during the Link Establishment phase ๐.
authentication SHOULD happen as soon as possible after link establishment ๐โโ๏ธ. Link quality determination MAY happen at the same time ๐. An implementation MUST NOT let the link quality determination packets hold up authentication forever โณ.
moving from the Authentication phase to the Network-Layer Protocol phase MUST NOT happen until the peer has been successfully authenticated with the negotiated authentication protocol ๐ซ. If authentication fails, PPP SHOULD go to the Link Termination phase instead ๐.
4.6. Network-Layer Protocol Phase ๐
once PPP has finished the earlier phases, each network-layer protocol (like IP) MUST be configured separately by its own appropriate Network Control Protocol (NCP) ๐ .
each NCP can be Opened and Closed whenever it wants ๐.
Implementation Note:
Since an implementation might take a while to figure out link quality first, implementations SHOULD avoid fixed timeouts while they wait for their peers to configure an NCP โฐ.
once an NCP reaches the Opened state, PPP carries the packets for the matching network-layer protocol ๐ฆ. Any network-layer protocol packets that arrive while the corresponding NCP is NOT in the Opened state SHOULD be silently discarded ๐ซฅ.
during this phase, the link can carry any mix of LCP, NCP, and network-layer protocol packets ๐. Any NCP or network-layer protocol packets that show up during any other phase SHOULD be silently discarded ๐.
Implementation Note:
There's one exception to all of that, because of the LCP Protocol-Reject (we'll cover it later) ๐ฆ. While LCP is in the Opened state, any protocol packet the implementation doesn't support MUST be sent back in a Protocol-Reject ๐ฎ. Only the supported protocols get silently discarded โจ.
4.7. Link Termination Phase ๐
PPP can end the link at any time ๐. Usually a human user asks for it, but it might also happen because of something physical, like losing carrier, failing authentication, failing link quality, or an idle-period timer running out โฒ๏ธ.
LCP closes the link through an exchange of Terminate packets ๐ซง. While the link is closing, PPP lets the network-layer protocols know so they can do whatever they need to ๐.
after the Terminate packets have been exchanged, the implementation SHOULD signal the physical layer to disconnect so the termination actually sticks ๐, especially if authentication failed ๐จ. The sender of the Terminate-Request SHOULD disconnect after it gets a Terminate-Ack, or after the Restart counter runs out โฑ๏ธ. The receiver of a Terminate-Request SHOULD wait for its peer to disconnect, and MUST NOT disconnect until at least one Restart time has passed after it sent a Terminate-Ack ๐งโโ๏ธ. PPP SHOULD then move on to the Link Dead phase ๐ฑ.
Implementation Note:
LCP closing the link is enough ๐. Each NCP does NOT need to send its own flurry of Terminate packets ๐ช๏ธ. And just because an NCP has Closed doesn't mean the PPP link should be terminated, even if that NCP was the only one in the Opened state ๐.
5. The Option Negotiation Automaton ๐ค
the finite-state automaton is built out of events, actions, and state transitions ๐งฉ. Events include external commands like 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, namely Configure-Naks and Configure-Rejects, Code-Rejects and Protocol-Rejects, and Echo-Requests, Echo-Replies and Discard-Requests, aren't told apart in the automaton descriptions ๐ฏ. They do have different jobs, which we'll get into 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-Start
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
- = illegal action
5.1. State Diagram ๐บ๏ธ
this simplified state diagram walks through how both ends agree on Configuration Options (which opens the PPP link) and later how the link gets terminated ๐.
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-
| | +------------------------------->+<-------+ |
| | |
+<-------+<------------------------------------------------+
This diagram is NOT a complete picture 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 this purpose, the state machine starts out in the Closed state ๐. Once the Opened state is reached, both ends of the link have sent and received a Configure-Ack packet ๐ฅณ.
5.2. State Transition Table โจ
okay so here's the whole state transition table bestie ๐
states go across the top and events go down the side. every box reads as action/new-state, and if there's more than one action they're separated by commas (they can wrap onto the next line if they need the space). a state might have a letter after it, and that's just a little footnote ๐ซถ
Rationale:
ngl the old versions used a simplified non-deterministic finite-state automaton with a ton of detail hiding in the semantics, and that caused interoperability problems because everybody read it differently ๐ญ
this table works like the older versions, except the up/down flags are now explicit states and the active/passive paradigm is gone ๐ฆ it's believed that this table interoperates with the previous versions better than those versions do themselves ๐
| 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 tld,scj,scr/6
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 are easy to spot, they're the ones with TO events ๐ only the Send-Configure-Request, Send-Terminate-Request and Zero-Restart-Counter actions start or restart the Restart timer ๐ and when you move from a state where the timer is running to one where it isn't, the Restart timer SHOULD be stopped ๐
[p] Passive option; see Stopped state discussion. ๐ธ
[r] Restart option; see Open event discussion. ๐ง
[x] Crossed connection; see RCA event discussion. ๐
5.3. States ๐
here's a more detailed look at each automaton state, bestie ๐ซถ
Initial
in the Initial state the lower layer is unavailable (Down) and no Open has happened yet ๐ด the Restart timer is not running in the Initial state ๐ค
Starting
Starting is the Open counterpart to Initial ๐ฆ an administrative Open has been started, but the lower layer is still unavailable (Down) ๐ญ the Restart timer is not running in Starting ๐
once the lower layer becomes available (Up), a Configure-Request gets sent ๐
Closed
in the Closed state the link is available (Up), but no Open has occurred ๐ธ the Restart timer is not running in Closed โจ
when Configure-Request packets come in, a Terminate-Ack gets sent ๐ Terminate-Acks are silently discarded so we don't end up creating a loop ๐
Stopped
Stopped is the Open counterpart to Closed ๐ it's where the automaton lands when it's waiting for a Down event after the This-Layer-Finished action, or after sending 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 ๐ and again, Terminate-Acks are silently discarded to avoid creating a loop ๐
Rationale:
Stopped is a junction state ๐ it covers link termination, link configuration failure, and other automaton failure modes, and these potentially separate states got combined into one ๐งฉ
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 will supercede and send the automaton back to Starting ๐ซ this is how it prevents 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 that case the This-Layer-Finished action isn't used for the TO- event in Req-Sent, Ack-Rcvd and Ack-Sent ๐ท
this option is useful for dedicated circuits, or circuits that have no status signals available ๐ but it SHOULD NOT be used for switched circuits ๐ โโ๏ธ
Closing
in Closing, the automaton tries to terminate 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 gets 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 a Terminate-Ack hasn't been received yet ๐ซง
Rationale:
Stopping gives you a well defined chance to terminate a link 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 one hasn't 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 because a Configure-Ack hasn't been sent yet โฑ๏ธ
Ack-Sent
in Ack-Sent, both a Configure-Request and a Configure-Ack have been sent, but a Configure-Ack hasn't been received yet ๐ฌ the Restart timer is always running in Ack-Sent ๐โโ๏ธ
Opened
Opened is the big moment ๐ here 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 ๐ and when it leaves Opened, the implementation SHOULD signal the upper layers that it is now Down โฌ๏ธ iconic behaviour, no notes ๐
5.4. Events โจ
okay so, the whole automaton runs on events ๐ Every transition and action happens because something triggered it, so let's go through the cast one by one bestie ๐
Up
The Up event happens when a lower layer says "hey, I'm ready to carry packets!" ๐ฆ Usually this is how LCP finds out the link is entering the Link Establishment phase ๐ธ, or how an NCP learns the link is entering the Network-Layer Protocol phase โจ
Down
The Down event is the opposite energy ๐ญ It happens when a lower layer says it's no longer ready to carry packets. Usually LCP gets this to know the link is heading into the Link Dead phase ๐, or an NCP gets it to know the link is leaving the Network-Layer Protocol phase ๐ฅ
Open
The Open event means the link is administratively available for traffic ๐ In other words, the network admin (a human or a program) has said "yep, this link is allowed to be Opened" ๐ When Open happens and the link is not already in the Opened state, the automaton tries to send configuration packets to the peer ๐ง
If the automaton can't start configuring yet (the lower layer is Down, or a previous Close hasn't finished), the link's establishment just gets automatically delayed โณ no drama, it just waits its turn ๐ซถ
When a Terminate-Request gets received, or other stuff happens that makes the link unavailable, the automaton moves to a state where the link is ready to re-open ๐ฆ No extra admin intervention should be necessary, which is lowkey iconic ๐
Implementation Note:
Experience has shown that users will run an extra Open command when they want to renegotiate the link ๐ But that's not what the Open event is for! So it's suggested that when an Open user command gets run while in the Opened, Closing, Stopping, or Stopped states, the implementation issues a Down event, immediately followed by an Up event โจ That makes the link renegotiate without any harmful side effects ๐
Close
The Close event means the link is not available for traffic ๐ โโ๏ธ The network admin (human or program) has said the link is not allowed to be Opened. When Close 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 brand new Open event shows up ๐
Timeout (TO+,TO-)
This one is the Restart timer going off โฐ The Restart timer is what times the responses to Configure-Request and Terminate-Request packets ๐ธ
The TO+ event means the Restart counter is still greater than zero, so the matching Configure-Request or Terminate-Request gets retransmitted ๐
The TO- event means the Restart counter is not greater than zero, so there are no more packets to retransmit, and we're done with that one ๐ง
Receive-Configure-Request (RCR+,RCR-)
This event happens when a Configure-Request packet arrives from the peer ๐ฌ It says "I want to open a connection!" and it may include Configuration Options ๐ We'll get into the Configure-Request packet in more detail in a later section ๐
The RCR+ event means the Configure-Request was acceptable, so it triggers sending back a matching Configure-Ack โ
The RCR- event means the Configure-Request was unacceptable, so it triggers sending back a matching Configure-Nak or Configure-Reject ๐ โโ๏ธ
Implementation Note:
These events can happen on a connection that's already in the Opened state ๐ณ So the implementation MUST be prepared to immediately renegotiate the Configuration Options ๐
Receive-Configure-Ack (RCA)
This event happens when a valid Configure-Ack packet arrives from the peer ๐ฅฐ A Configure-Ack is the positive reply to a Configure-Request. If a packet is out of sequence or otherwise invalid, it gets silently discarded ๐ซฅ
Implementation Note:
By the time we reach the Ack-Rcvd or Opened states, the correct packet has already been received, so it's extremely unlikely that another one shows up ๐คทโโ๏ธ As specified, all invalid Ack/Nak/Rej packets are silently discarded and don't affect the automaton's transitions ๐
That said, it's not impossible for a correctly formed packet to arrive through a coincidentally-timed cross-connection ๐ It's way more likely to be an implementation error though ๐ At the very least, this occurrence should be logged ๐
Receive-Configure-Nak/Rej (RCN)
This event happens when a valid Configure-Nak or Configure-Reject packet arrives from the peer ๐ Both are negative replies to a Configure-Request. Out of sequence or otherwise invalid packets get silently discarded, same as before ๐ซ
Implementation Note:
Even though Configure-Nak and Configure-Reject cause the same state transition in the automaton, they have seriously different effects on the Configuration Options sent in the resulting Configure-Request packet ๐ So don't treat them as twins, bestie ๐
Receive-Terminate-Request (RTR)
This event happens when a Terminate-Request packet arrives ๐ช It means the peer wants to close the connection.
Implementation Note:
This event is not the same as the Close event, and it does NOT override the Open commands of the local network administrator ๐ โโ๏ธ The implementation MUST be prepared to receive a new Configure-Request without any network administrator intervention ๐ฆ
Receive-Terminate-Ack (RTA)
This event happens when a Terminate-Ack packet arrives from the peer ๐ท A Terminate-Ack is usually the reply 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)
This event happens when an un-interpretable packet arrives from the peer ๐คจ When that happens, a Code-Reject packet gets sent back in response ๐ค
Receive-Code-Reject, Receive-Protocol-Reject (RXJ+,RXJ-)
This event happens when a Code-Reject or a Protocol-Reject packet arrives from the peer ๐
The RXJ+ event happens when the rejected value is acceptable, like a Code-Reject for an extended code, or a Protocol-Reject for an NCP ๐ฟ These are totally within the scope of normal operation, so no panic ๐ซถ 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 one communicates an unrecoverable error that terminates the connection ๐
Receive-Echo-Request, Receive-Echo-Reply, Receive-Discard-Request (RXR)
This event happens when an Echo-Request, Echo-Reply or Discard-Request packet arrives from the peer ๐จ The Echo-Reply is the response to an Echo-Request ๐ช There is no reply to an Echo-Reply or a Discard-Request, so that's the end of that conversation ๐ค
5.5. Actions
okay bestie, actions are what the automaton actually does ๐ They get triggered by events, and they usually mean sending packets and/or starting or stopping the Restart timer โฑ๏ธ๐ฆ
Illegal-Event (-)
this one's the "wait, that's not supposed to happen" action ๐ It indicates an event that SHOULD NOT occur. The implementation probably has an internal error ๐
This-Layer-Up (tlu)
this one tells the upper layers that the automaton is entering the Opened state โจ
Typically, this action MAY be used by the LCP to signal the Up event to a NCP, Authentication Protocol, or Link Quality Protocol, or MAY be used by a NCP to indicate that the link is available for its traffic. ๐ธ
This-Layer-Down (tld)
the opposite energy ๐ฅ It tells the upper layers that the automaton is leaving the Opened state.
Typically, this action MAY be used by the LCP to signal the Down event to a NCP, Authentication Protocol, or Link Quality Protocol, or MAY be used by a NCP to indicate that the link is no longer available for its traffic. ๐
This-Layer-Start (tls)
this one talks to the lower layers ๐ง It means the automaton is entering the Starting state and the lower layer is needed for the link. The lower layer SHOULD respond with an Up event when it's available.
This action is highly implementation dependent. ๐คทโโ๏ธ
This-Layer-Finished (tlf)
also a lower-layer chat ๐ซถ It means the automaton is entering the Stopped or Closed states, and the lower layer is no longer needed for the link. The lower layer SHOULD respond with a Down event when it has terminated.
Typically, this action MAY be used by the LCP to advance to the Link Dead phase, or MAY be used by a NCP to indicate to the LCP that the link may terminate when there are no other NCPs open. ๐
This action is highly implementation dependent. ๐
Initialize-Restart-Counter (irc)
this one sets the Restart counter to the appropriate value (Max-Terminate or Max-Configure) ๐ฅ The counter is decremented for each transmission, including the first one.
Zero-Restart-Counter (zrc)
this one sets the Restart counter to zero ๐
Implementation Note: This action lets the FSA pause before it moves on to the desired final state. In addition to zeroing the Restart counter, the implementation MUST set the timeout period to an appropriate value. โณโจ
Send-Configure-Request (scr)
this one transmits a Configure-Request packet ๐จ That's the "hey, I'd like to open a connection with this specific set of Configuration Options" move ๐ The Restart timer starts when the Configure-Request is sent, to guard against packet loss. The Restart counter gets decremented each time a Configure-Request goes out.
Send-Configure-Ack (sca)
this one transmits a Configure-Ack packet ๐ It acknowledges that a Configure-Request came in with an acceptable set of Configuration Options. Yes queen ๐
Send-Configure-Nak (scn)
this one transmits a Configure-Nak or Configure-Reject packet, whichever is appropriate ๐ โโ๏ธ It's the negative response for a Configure-Request with an unacceptable set of Configuration Options. Configure-Nak packets are used to refuse a Configuration Option value and to suggest a new, acceptable one. Configure-Reject packets are used to refuse all negotiation about a Configuration Option, typically because it isn't recognized or implemented. The difference between Configure-Nak and Configure-Reject is covered more fully in the section on LCP Packet Formats ๐ฆ
Send-Terminate-Request (str)
this one transmits a Terminate-Request packet ๐ That's the "okay, I'd like to close this connection" message. The Restart timer starts when the Terminate-Request is sent, to guard against packet loss. The Restart counter gets decremented each time a Terminate-Request is sent. ๐ฅน
Send-Terminate-Ack (sta)
this one transmits a Terminate-Ack packet ๐ซก It acknowledges a Terminate-Request, or otherwise helps synchronize the state machines. Teamwork makes the dream work ๐ง
Send-Code-Reject (scj)
this one transmits a Code-Reject packet ๐ It indicates that an unknown type of packet came in. Not it ๐
Send-Echo-Reply (ser)
this one transmits an Echo-Reply packet ๐ It acknowledges that an Echo-Request came in. Hi, I'm here, hbu? ๐
5.6. Loop Avoidance
okay so the protocol makes a reasonable attempt at avoiding Configuration Option negotiation loops ๐ BUT it does NOT guarantee that loops won't happen ๐ญ Like with any negotiation, you can configure two PPP implementations with conflicting policies that will literally never converge ๐ It's also possible to configure policies that do converge, but take significant time to do it ๐ข Implementors should keep this in mind and should implement loop detection mechanisms or higher level timeouts. Be prepared, bestie ๐ก๏ธโจ
5.7. Counters and Timers
Restart Timer
there's one special timer used by the automaton โฐ The Restart timer times transmissions of Configure-Request and Terminate-Request packets. When it expires, it causes a Timeout event and retransmission of the corresponding Configure-Request or Terminate-Request packet. The Restart timer MUST be configurable, but MAY 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 (19,200 bps or less), high switching latency links (typical telephone lines) ๐ Higher speed links, or links with low switching latency, SHOULD have correspondingly faster retransmission times. โก
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 assuming the peer is unable to 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 assuming 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 assuming the 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. ๐ซโก๏ธ๐ โโ๏ธ
6. LCP Packet Formats โจ
okay so there are three classes of LCP packets ๐
- Link Configuration packets used to establish and configure a link (Configure-Request, Configure-Ack, Configure-Nak and Configure-Reject).
- Link Termination packets used to terminate a link (Terminate-Request and Terminate-Ack).
- Link Maintenance packets used to manage and debug a link (Code-Reject, Protocol-Reject, Echo-Request, Echo-Reply, and Discard-Request).
This document describes Version 1 of the Link Control Protocol ๐ฆ In the interest of simplicity, there's no version field in the LCP packet. If a new version of LCP is ever needed, the intention is that a new Data Link Layer Protocol field value will be used to tell Version 1 LCP apart from all other versions ๐ A correctly functioning Version 1 LCP implementation will always respond to unknown Protocols (including other versions) with an easily recognizable Version 1 packet, which gives other versions a deterministic fallback mechanism. Clever, right? ๐ง ๐
Regardless of which Configuration Options are enabled, all LCP Link Configuration, Link Termination, and Code-Reject packets (codes 1 through 7) are always sent in the full, standard form, as if no Configuration Options were enabled ๐ก๏ธ This makes sure LCP Configure-Request packets are always recognizable, even when one end of the link mistakenly thinks the link is open. ๐ซถ
Exactly one Link Control Protocol packet is encapsulated in the Information field of PPP Data Link Layer frames where the Protocol field indicates type hex c021 (Link Control Protocol) ๐ฆ
A summary of the Link Control Protocol packet format is shown below. The fields are transmitted from left to right. ๐
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Code | Identifier | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data ...
+-+-+-+-+
Code
the Code field is one octet and identifies the kind of LCP packet ๐ท๏ธ When a packet is received with an invalid Code field, a Code-Reject packet is transmitted. ๐ โโ๏ธ
The most up-to-date values of the LCP Code field are specified in the most recent "Assigned Numbers" RFC [11]. Current values are assigned as follows: ๐
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
12 RESERVED
Identifier
the Identifier field is one octet and helps match requests with replies ๐ When a packet is received with an invalid Identifier field, the packet is silently discarded. ๐คซ
Length
the Length field is two octets and indicates the length of the LCP packet, including the Code, Identifier, Length and Data fields ๐ Octets outside the range of the Length field should be treated as Data Link Layer padding and should be ignored on reception. When a packet is received with an invalid Length field, the packet is silently discarded. ๐งน
Data
the Data field is zero or more octets, as indicated by the Length field ๐ฆ The format of the Data field is determined by the Code field. โจ
6.1. Configure-Request ๐
Description
okay so, if a LCP implementation wants to open a connection, it MUST send a LCP packet with the Code field set to 1 (Configure-Request) and the Options field filled with whatever default link Configuration Options it wants to change. ๐
When a Configure-Request comes in, an appropriate reply MUST be sent back. no skipping the reply, bestie ๐ซถ
Here's the Configure-Request packet format. Fields go left to right, like reading a text ๐
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. it's giving "first message in the chat" ๐ฌ
Identifier
The Identifier field SHOULD be changed on every transmission โจ On reception, the Identifier field should be copied into the Identifier field of the appropriate reply packet. that's how the replies know who they're answering ๐ง
Options
The Options field is variable in length and holds a list of zero or more Configuration Options the sender wants to negotiate. All Configuration Options get negotiated at the same time, no splitting them up ๐ธ The format of Configuration Options gets its own section later, so stay tuned ๐
6.2. Configure-Ack ๐ฆ
Description
If every Configuration Option in a Configure-Request is both recognizable and acceptable, then a LCP implementation should send a LCP packet with the Code field set to 2 (Configure-Ack), the Identifier field copied from the Configure-Request, and the Options field copied from the Configure-Request too. ๐ The acknowledged Configuration Options MUST NOT be reordered or modified in any way. hands off, they're perfect as they are ๐
โโ๏ธ
When a Configure-Ack comes in, the Identifier field must match the last Configure-Request that was sent. Also, the Configuration Options in a Configure-Ack must exactly match the ones in that last Configure-Request. if anything's off, the packet gets silently discarded ๐
Here's 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. the "yes, slay" packet ๐
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 a list of zero or more Configuration Options the sender is acknowledging. All Configuration Options are acknowledged at once, every time ๐
6.3. Configure-Nak ๐
Description
If every element of a received Configuration Option is recognizable but some of them aren't acceptable, then a LCP implementation should send a LCP packet with the Code field set to 3 (Configure-Nak), the Identifier field copied from the Configure-Request, and the Options field filled with only the unacceptable Configuration Options from that Configure-Request. the acceptable ones get filtered out of the Configure-Nak, but the leftover options MUST NOT be reordered. no shuffling allowed ๐
โโ๏ธ
Each of the Nak'd Configuration Options MUST be modified to a value the Configure-Nak sender finds acceptable ๐ซถ Options with no value fields (boolean options) use the Configure-Reject reply instead, so they don't get Nak'd ๐ง
Finally, an implementation may be configured to request negotiation of a specific option. If that option isn't on the list, then it may be added to the list of Nak'd Configuration Options, so the peer knows to list that option in its next Configure-Request packet โจ Any value fields for the option MUST indicate values acceptable to the Configure-Nak sender. no sneaky values ๐
When a Configure-Nak comes in, the Identifier field must match the last Configure-Request that was sent. Invalid packets are silently discarded ๐
Getting a valid Configure-Nak means a new Configure-Request MAY be sent, with the Configuration Options changed the way the Configure-Nak said ๐ฆ
Some Configuration Options have a variable length. Since the peer modified the Nak'd Option, the implementation MUST be able to handle an Option length that's different from the original Configure-Request. be flexible, it's a whole vibe ๐ธ
Here's 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. the "close, but no" packet ๐
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 a list of zero or more Configuration Options the sender is Nak'ing. All Configuration Options get Nak'd simultaneously ๐
6.4. Configure-Reject ๐ซ
Description
If some Configuration Options in a Configure-Request aren't recognizable, or they aren't acceptable for negotiation (as set by a network administrator), then a LCP implementation should send a LCP packet with the Code field set to 4 (Configure-Reject), the Identifier field copied from the Configure-Request, and the Options field filled with only the unacceptable Configuration Options from that Configure-Request. the recognizable and negotiable ones get filtered out, but the Configuration Options MUST NOT be reordered or modified in any way. ๐
When a Configure-Reject comes in, the Identifier field must match the last Configure-Request that was sent. Also, the Configuration Options in a Configure-Reject must be a proper subset of the ones in that last Configure-Request. Invalid packets get silently discarded ๐
Getting a valid Configure-Reject means a new Configure-Request SHOULD be sent, one that doesn't include any of the Configuration Options listed in the Configure-Reject ๐ง
Here's the Configure-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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options ...
+-+-+-+-+
Code
4 for Configure-Reject. the "not for us" packet ๐
Identifier
The Identifier field is a copy of the Identifier field from the Configure-Request that caused this Configure-Reject ๐ธ
Options
The Options field is variable in length and holds a list of zero or more Configuration Options the sender is rejecting. All Configuration Options are rejected together, as a group ๐
6.5. Terminate-Request and Terminate-Ack ๐
Description
LCP has Terminate-Request and Terminate-Ack Codes so there's a proper way to close a connection ๐ฆ
A LCP implementation that wants to close a connection should send a LCP packet with the Code field set to 5 (Terminate-Request) and the Data field filled with whatever data it wants. Terminate-Request packets should keep getting sent until a Terminate-Ack is received, the lower layer says it has gone down, or enough of them have been sent that the peer is definitely down (with reasonable certainty) ๐ง
When a Terminate-Request comes in, a LCP packet MUST be sent with the Code field set to 6 (Terminate-Ack), the Identifier field copied from the Terminate-Request, and the Data field filled with any data the sender wants ๐ซถ
Getting a Terminate-Ack nobody asked for means the peer is in the Closed or Stopped states, or it otherwise needs to renegotiate ๐
Here's the format for Terminate-Request and Terminate-Ack packets. 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
5for Terminate-Request6for Terminate-Ack
Identifier
The Identifier field is one octet and helps match requests with replies ๐
Data
The Data field is zero or more octets and holds uninterpreted data for the sender to use ๐ The data can be any binary value and any length from zero up to the peer's established maximum Information field length minus four. bestie, that's a whole range ๐
6.6. Code-Reject ๐จ
Description
Getting a LCP packet with an unknown Code means one of the LCP implementations talking to each other is faulty or incomplete ๐ญ That error MUST be reported back to the sender of the unknown Code by sending a 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 comes in, the implementation SHOULD report the error. the situation probably can't get fixed automatically, so someone needs to look at it ๐
Here's the Code-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-Packet ...
+-+-+-+-+-+-+-+-+
Code
7 for Code-Reject ๐ง
Identifier
The Identifier field is one octet and is for the transmitter to use ๐ธ
Rejected-Information
The Rejected-Information field has a copy of the LCP packet being rejected. It begins with the Information field, and it doesn't include any PPP Data Link Layer headers or the FCS โจ
The Rejected-Information MUST be truncated to fit the peer's established maximum Information field length. chop it down, no exceptions ๐ซถ
6.7. Protocol-Reject
Description
Okay bestie, so when a PPP frame shows up with a Data Link Layer Protocol we don't recognise ๐, the peer is basically knocking on the door for a protocol we don't speak. This usually happens when they're trying to set up a brand-new protocol ๐ง. If the LCP state machine is in the Opened state, you MUST report it back by sending an LCP packet with the Code field set to 8 (Protocol-Reject), the Rejected-Protocol field set to the Protocol you received, and the inducing packet copied into the Rejected-Information field ๐.
When a Protocol-Reject comes in, your LCP implementation SHOULD stop sending frames of the rejected protocol ๐ .
Protocol-Reject packets may only be sent in the LCP Opened state. Any Protocol-Reject received in a state other than Opened SHOULD be silently discarded ๐ซถ.
Packet Format
A summary of the Protocol-Reject packet format is shown below. The fields go from left to right โจ.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Code | Identifier | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Rejected-Protocol | Rejected-Information ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Code
8 for Protocol-Reject.
Identifier
The Identifier field is one octet, and it's for the transmitter to use ๐.
Rejected-Protocol
The Rejected-Protocol field is two octets and holds the Protocol of the Data Link Layer frame being rejected ๐ซ.
Rejected-Information
The Rejected-Information field is a copy of the frame being rejected. It starts with the Information field and does NOT include any PPP Data Link Layer headers or the FCS. The Rejected-Information MUST be truncated so it fits the peer's established maximum Information field length ๐ง.
6.8. Echo-Request and Echo-Reply
Description
LCP has Echo-Request and Echo-Reply Codes that give you a Data Link Layer loopback ๐, so you can test both directions of the link. It's super useful for debugging, link quality checks, performance testing, and a bunch of other stuff ๐.
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 inserted, and the Data field filled with whatever data you want. That data can go up to, but not past, the peer's established maximum Information field length minus eight ๐.
When an Echo-Request is received, an LCP packet MUST be transmitted with the Code field set to 10 (Echo-Reply), the Identifier field copied from the Echo-Request, the local Magic-Number inserted, and the Data field copied from the Echo-Request. Truncate as needed so you don't go past the peer's established maximum Information field length โ๏ธ.
Echo-Request and Echo-Reply packets may only be sent in the LCP Opened state. Echo-Request and Echo-Reply packets received in any other state SHOULD be silently discarded ๐คซ.
Packet Format
A summary of the Echo-Request and Echo-Reply packet formats is shown below. The fields go from left to right ๐.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Code | Identifier | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Magic-Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data ...
+-+-+-+-+
Code
9 for Echo-Request;
10 for Echo-Reply.
Identifier
The Identifier field is one octet, and it helps match Echo-Requests with Echo-Replies ๐งฉ.
Magic-Number
The Magic-Number field is four octets, and it helps detect links that are in the looped-back condition ๐. Unless modified by a Configuration Option, the Magic-Number MUST be transmitted as zero and MUST be ignored on reception. See the Magic-Number Configuration Option for further explanation ๐.
Data
The Data field is zero or more octets and holds uninterpreted data for the sender to use ๐ฆ. The data can be any binary value and any length from zero up to the peer's established maximum Information field length minus eight ๐ซง.
6.9. Discard-Request
Description
LCP includes a Discard-Request Code, which gives you a Data Link Layer data sink ๐ณ๏ธ. It's for exercising the local-to-remote direction of the link. It's handy for debugging, performance testing, and lots of other things ๐ธ.
A discard sender transmits an LCP packet with the Code field set to 11 (Discard-Request), the Identifier field set, the local Magic-Number inserted, and the Data field filled with whatever data you want, up to but not exceeding the peer's established maximum Information field length minus eight ๐.
A discard receiver MUST simply throw away a Discard-Request that it receives ๐๏ธ.
Discard-Request packets may only be sent in the LCP Opened state.
Packet Format
A summary of the Discard-Request packet format is shown below. The fields go from left to right ๐ฆ.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Code | Identifier | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Magic-Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data ...
+-+-+-+-+
Code
11 for Discard-Request.
Identifier
The Identifier field is one octet, and it's for use by the Discard-Request transmitter ๐ฎ.
Magic-Number
The Magic-Number field is four octets, and it helps detect links that are in the looped-back condition ๐. Unless modified by a configuration option, the Magic-Number MUST be transmitted as zero and MUST be ignored on reception. See the Magic-Number Configuration Option for further explanation ๐.
Data
The Data field is zero or more octets and holds uninterpreted data for the sender to use. The data can be any binary value and any length from zero up to the peer's established maximum Information field length minus four ๐ท.
7. LCP Configuration Options
LCP Configuration Options let you negotiate changes to the standard characteristics of a point-to-point link โจ. Things you can negotiate include the maximum receive unit, async control character mapping, the link authentication method, and more ๐. If a Configuration Option isn't included in a Configure-Request packet, the default value for that option is assumed ๐ .
The end of the list of Configuration Options is marked by the length of the LCP packet ๐.
Unless otherwise specified, each Configuration Option is NOT listed more than once in a Configuration Options list. Some Configuration Options MAY be listed more than once. What that does is specific to each option and is spelled out by each such option ๐ง.
Also unless otherwise specified, all Configuration Options apply in a half-duplex fashion. Once negotiated, they only apply to one direction of the link. Usually that's the receive direction, seen from the point of view of the Configure-Request sender ๐ฅ.
7.1. Format
A summary of the Configuration Option format is shown below. The fields go from left to right ๐.
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length | Data ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Type
The Type field is one octet and tells you what type of Configuration Option it is ๐ท๏ธ. The most up-to-date values of the LCP Option Type field are in the most recent "Assigned Numbers" RFC [11]. The current values are assigned like this:
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 gives the length of this 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. It should include the desired Configuration Option with an appropriate Length and Data ๐.
Data
The Data field is zero or more octets and holds the value or other info for this Configuration Option ๐ซง. Its format and length are determined by the Type and Length fields ๐.
7.2. Maximum-Receive-Unit
Description
This Configuration Option can be sent to tell the peer that your implementation can receive larger frames. It can also be used to ask the peer to send smaller frames ๐ฆ. If smaller frames are requested, an implementation MUST still be able to receive 1500 octet frames, just in case link synchronization gets lost ๐.
A summary of the Maximum-Receive-Unit Configuration Option format is shown below. The fields go from left to right ๐ฆ.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length | Maximum-Receive-Unit |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Type
1
Length
4
Maximum-Receive-Unit
The Maximum-Receive-Unit field is two octets and indicates the new maximum receive unit ๐. The Maximum-Receive-Unit covers only the Data Link Layer Information field. It does NOT include the header, padding, FCS, or any transparency bits or bytes ๐ โโ๏ธ.
Default
1500
7.3. Async-Control-Character-Map โจ
Description
okay bestie so this option lets you negotiate control character mapping on async links ๐ง by default PPP maps ALL the control characters into an appropriate two character sequence ๐ญ but honestly it's rarely necessary to map every single one, and often you don't need to map any ๐ so a PPP implementation can use this option to tell its peer which control characters must stay mapped and which ones don't need to stay mapped when the peer sends them ๐ซถ the peer can still send them in mapped format if it's needed because of constraints on its end ๐ธ
here's the spicy part ๐ฅ some Point-to-Point links use synchronous-to-asynchronous converters (some are built right into modems ๐ ) so you can end up with a synchronous PPP implementation on one end and an asynchronous one on the other. the converter is responsible for doing all the mapping conversions during operation ๐ to make this work, synchronous PPP implementations MUST always accept an Async-Control-Character-Map Configuration Option (it MUST always respond to an LCP Configure-Request specifying this Configuration Option with an LCP Configure-Ack โจ). BUT accepting it doesn't mean the synchronous side is going to do any character mapping, because synchronous PPP uses bit-stuffing instead of character-stuffing ๐ฆ all that mapping gets handled by the asynchronous-to-synchronous converter, periodt ๐
A summary of the Async-Control-Character-Map 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 | Async-Control-Character-Map
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
ACCM (cont) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Type
2
Length
6
Async-Control-Character-Map
The Async-Control-Character-Map field is four octets and indicates the new async control character map ๐ง the map is encoded in big-endian fashion, where each numbered bit corresponds to the ASCII control character of the same value. If the bit is cleared to zero, then that ASCII control character need not be mapped. If the bit is set to one, then that ASCII control character must remain mapped. E.g., if bit 19 is set to zero, then the ASCII control character 19 (DC3, Control-S) may be sent in the clear โจ
Note: The bit ordering of the map is as described in section 3.1, Most Significant Bit to Least Significant Bit. The least significant bit of the least significant octet (the final octet transmitted) is numbered bit 0, and would map to the ASCII control character NUL. ๐
Default
All ones (0xffffffff). ๐
7.4. Authentication-Protocol ๐
Description
on some links it might be desirable to require a peer to authenticate itself before any network-layer protocol packets get exchanged ๐ this option gives you a way to negotiate the use of a specific authentication protocol. by default, authentication is not necessary ๐
okay here's the vibe check โจ an implementation SHOULD 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 Rejected, then the implementation could attempt the next most desirable protocol in the next Configure-Request ๐ฆ
now for the receiving side ๐ซถ an implementation that gets a Configure-Request specifying Authentication-Protocols MAY choose at most one of the negotiable authentication protocols, and MUST send a Configure-Reject including the other specified authentication protocols. the implementation MAY reject all of the proposed authentication protocols too ๐
if an implementation sends a Configure-Ack with this Configuration Option, then it's agreeing to authenticate with the specified protocol ๐ and an implementation that receives a Configure-Ack with this Configuration Option SHOULD expect the peer to authenticate with the acknowledged protocol ๐ธ
there is no requirement that authentication be full duplex, or that the same protocol be used in both directions. it's perfectly acceptable for different protocols to be used in each direction ๐ this will, of course, depend on the specific protocols negotiated โจ
A summary of the Authentication-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 | Authentication-Protocol |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data ...
+-+-+-+-+
Type
3
Length
>= 4
Authentication-Protocol
The Authentication-Protocol field is two octets and indicates the authentication protocol desired. Values for this field are always the same as the PPP Data Link Layer Protocol field values for that same authentication protocol ๐
the most up-to-date values of the Authentication-Protocol field are specified in the most recent "Assigned Numbers" RFC [11]. current values are assigned as follows ๐
Value (in hex) Protocol
c023 Password Authentication Protocol
c223 Challenge Handshake Authentication
Protocol
Data
The Data field is zero or more octets and contains additional data as determined by the particular protocol ๐
Default
No authentication protocol necessary. ๐ธ
7.5. Quality-Protocol ๐
Description
on some links it might be desirable to figure out when, and how often, the link is dropping data ๐ญ this process is called link quality monitoring โจ
this option gives you a way to negotiate the use of a specific protocol for link quality monitoring ๐ by default, link quality monitoring is disabled ๐ฆ
there is no requirement that quality monitoring be full duplex, or that the same protocol be used in both directions. it's perfectly acceptable for different protocols to be used in each direction ๐ซถ this will, of course, depend on the specific protocols negotiated ๐
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 indicates the link quality monitoring protocol desired. Values for this field are always the same as the PPP Data Link Layer Protocol field values for that same monitoring protocol ๐ง
the most up-to-date values of the Quality-Protocol field are specified in the most recent "Assigned Numbers" RFC [11]. current values are assigned as follows ๐
Value (in hex) Protocol
c025 Link Quality Report
Data
The Data field is zero or more octets and contains additional data as determined by the particular protocol ๐
Default
None ๐
7.6. Magic-Number โจ
Description
Okay bestie, this Configuration Option is how you catch looped-back links and other Data Link Layer weirdness ๐ต๏ธโโ๏ธ. Some other Configuration Options, like the Monitoring-Protocol Configuration Option, MAY be required to have it. Lowkey iconic. ๐
Before you even request this option, you have to pick your Magic-Number ๐ . It is recommended that the Magic-Number be chosen in the most random manner possible, so that an implementation will arrive at a unique number with very high probability. A good way to pick a unique random number is to start with an unique seed ๐ฑ. Suggested sources of uniqueness include machine serial numbers, other network hardware addresses, time-of-day clocks, etc. โฐ The really slay seeds are precise measurements of the inter-arrival time of physical events, like packet reception on other connected networks, server response time, or the typing rate of a human user โจ๏ธ. And it's also suggested that you use as many sources as possible at the same time. Main character energy ๐.
Now, when a Configure-Request comes in with a Magic-Number Configuration Option, you compare the received Magic-Number with the Magic-Number of the last Configure-Request you sent to the peer ๐. If they're different, the link is NOT looped-back, and the Magic-Number should be acknowledged. ๐ If they're equal, then it's possible (but not certain) that the link is looped-back and that this Configure-Request is actually the one you last sent ๐ญ. To check, a Configure-Nak should be sent specifying a different Magic-Number value. And you should not send a new Configure-Request to the peer until normal processing would cause it to be sent (i.e., 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 you sent to the peer proves the link is not looped-back, and it indicates a unique Magic-Number ๐ฆ. If the Magic-Number is equal to the one in the last Configure-Nak you sent, the looped-back possibility goes up, so you should choose a new Magic-Number ๐. Either way, a new Configure-Request should be sent with the new Magic-Number โจ.
If the link is actually looped-back, this sequence (transmit Configure-Request, receive Configure-Request, transmit Configure-Nak, receive Configure-Nak) will repeat over and over again ๐๐. If the link is NOT looped-back, the sequence might happen a few times, but it's extremely unlikely to happen repeatedly. Way more likely, the Magic-Numbers picked at either end will quickly diverge, and that ends the sequence ๐. The table below shows the probability of collisions, assuming both ends of the link pick Magic-Numbers with a perfectly uniform distribution ๐:
Number of Collisions Probability
-------------------- ---------------------
1 1/2**32 = 2.3 E-10
2 1/2**32**2 = 5.4 E-20
3 1/2**32**3 = 1.3 E-29
Good sources of uniqueness or randomness are required for this divergence to happen ๐ซถ. If you can't find a good source of uniqueness, it is recommended that this Configuration Option NOT be enabled. In that case, Configure-Requests with the option SHOULD NOT be transmitted, and any Magic-Number Configuration Options the peer sends SHOULD be either acknowledged or rejected ๐. Here's the tea: loop-backs can't be reliably detected by the implementation in this case, although the peer might still be able to detect them ๐ซ .
If an implementation DOES transmit a Configure-Request with a Magic-Number Configuration Option, then it MUST NOT respond with a Configure-Reject if its peer also transmits a Configure-Request with a Magic-Number Configuration Option ๐ค. Basically, if you want to use Magic Numbers, you MUST also let your peer do the same, no drama. If an implementation does receive a Configure-Reject in response to a Configure-Request, it can only mean that the link is not looped-back, and that its peer will not 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, which MUST normally be zero, and MUST normally be ignored on reception ๐ซฅ. 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 one ๐.
Receiving a Magic-Number field equal to the negotiated local Magic-Number means you've got a looped-back link ๐. 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 ๐.
The procedures for recovering from either case are unspecified and may vary from implementation to implementation ๐คทโโ๏ธ. A somewhat pessimistic procedure is to assume an LCP Down event ๐ฌ. A further Open event will start the process of re-establishing the link, which can't finish until the loop-back condition ends and Magic-Numbers are successfully negotiated ๐ง. A more optimistic procedure (in the case of a loop-back) is to start transmitting LCP Echo-Request packets until an appropriate Echo-Reply is received, which indicates the loop-back condition has ended ๐ธ.
Format
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 isn't Rejected outright ๐ซ.
Default
None. ๐ซง
7.7. Protocol-Field-Compression ๐ฆ
Description
This Configuration Option lets you negotiate the compression of the Data Link Layer Protocol field ๐๏ธ. By default, all implementations MUST transmit standard PPP frames with two octet Protocol fields. But PPP Protocol field numbers are picked so that some values can be squished into a single octet form that's clearly different from the two octet form ๐งฉ. This Configuration Option is sent to tell the peer that your implementation can receive those single octet Protocol fields ๐ฌ. Compressed Protocol fields MUST NOT be transmitted unless this Configuration Option has been negotiated ๐ซ.
As mentioned before, the Protocol field uses an extension mechanism that's consistent with the ISO 3309 extension mechanism for the Address field ๐ง . The Least Significant Bit (LSB) of each octet is used to show whether the Protocol field keeps going. A binary "0" as the LSB means the Protocol field continues with the following octet. A binary "1" as the LSB marks the last octet of the Protocol field ๐. Here's a fun fact: any number of "0" octets can be put in front of the field and it still means the same value (look at the two versions of 3, 00000011 and 00000000 00000011) ๐ค.
To keep things simple, the standard PPP frame uses this and always sends Protocol fields in a two octet form ๐ซถ. Protocol field values less than 256 (decimal) get a single zero octet in front of them, even though sending that zero (the most significant octet) isn't necessary ๐.
But on low speed links, you want to save bandwidth by sending as little redundant data as possible ๐ข. The Protocol Compression Configuration Option lets you trade off between simplicity of implementation and bandwidth efficiency โ๏ธ. If it's successfully negotiated, the ISO 3309 extension mechanism can be used to compress the Protocol field down to one octet instead of two ๐จ. Most frames can be compressed, since data protocols usually have Protocol field values less than 256 ๐ฅฐ.
Also, PPP implementations must continue to be robust, and they MUST accept PPP frames with either double-octet or single-octet Protocol fields, and they MUST NOT distinguish between them ๐ซก.
The Protocol field is never compressed when sending any LCP packet. This rule makes sure LCP packets are always recognized without any confusion ๐.
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 โ๏ธ
Default
Disabled. ๐ โโ๏ธ
7.8. Address-and-Control-Field-Compression โจ
Description
okay so this option is how two peers agree to compress the Data Link Layer Address and Control fields ๐ By default, every implementation MUST transmit frames with Address and Control fields and MUST use the hexadecimal values 0xff and 0x03 respectively. These fields always have the same values, so they're super easy to compress ๐ Sending this option just tells the other side that you're able to receive compressed Address and Control fields ๐ซถ
Compressing them is literally just leaving them out ๐ฆ A Protocol field is two octets, and by definition its first octet will never be 0xff. The Protocol field value 0x00ff is not allowed (reserved) to avoid ambiguity, so the receiver can tell what's going on ๐ง
When something comes in, the receiver looks at the first two octets. If they're 0xff and 0x03, those are the Address and Control fields. If not, the fields were compressed and never got sent at all ๐
If a compressed frame shows up when Address-and-Control-Field-Compression hasn't been negotiated, the implementation MAY silently discard the frame. ๐
The Address and Control fields MUST NOT be compressed when sending any LCP packet. This is the rule that keeps LCP packets 100% recognizable, no cap ๐ฅ
When the Address and Control fields are compressed, the Data Link Layer FCS field gets 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 go 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
Default
Not compressed. ๐
A. Asynchronous HDLC ๐ฆ
This appendix goes over the changes to ISO 3309-1979 that were proposed in ISO 3309:1984/PDAD1, as used in the Point-to-Point Protocol. These changes make it possible to use HDLC on 8-bit asynchronous links โจ
Transmission Considerations
Every octet gets sent with one start bit, eight bits of data, and one stop bit. Neither PPP nor ISO 3309:1984/PDAD1 has anything for seven-bit asynchronous links, so those are a no-go ๐
Flag Sequence
The Flag Sequence is one octet, and it marks where a frame begins or ends. It's the binary sequence 01111110 (hexadecimal 0x7e) ๐
Transparency
On asynchronous links, we use a character stuffing procedure ๐ง The Control Escape octet is binary 01111101 (hexadecimal 0x7d), and the bit positions are numbered 87654321 (not 76543210, BEWARE) โ ๏ธ
After the FCS is computed, the transmitter looks at the whole frame between the two Flag Sequences. Each Flag Sequence, each Control Escape octet, and each octet with a value under hexadecimal 0x20 that's flagged in the Remote Async-Control-Character-Map gets replaced by a two-octet sequence. That sequence is the Control Escape octet followed by the original octet with bit 6 complemented (i.e., exclusive-or'd with hexadecimal 0x20) ๐
Before the FCS is computed, the receiver looks at the whole frame between the two Flag Sequences. Each octet with a value under hexadecimal 0x20 gets checked. If it's flagged in the Local Async-Control-Character-Map, it just gets removed (it may have been inserted by intervening data communications equipment) ๐ซถ For each Control Escape octet, that octet is removed too, but bit 6 of the octet right after it gets complemented. A Control Escape octet sitting right before the closing Flag Sequence means the frame is invalid ๐
Note: Including all octets under hexadecimal 0x20 lets all ASCII control characters [10] except DEL (Delete) get passed along transparently through almost all known data communications equipment โจ
The transmitter may also send octets in the range 0x40 through 0xff (except 0x5e) in Control Escape format. Since these octet values aren't negotiable, this doesn't fix the problem of receivers that can't handle every non-control character ๐ญ And because this technique doesn't touch the 8th bit, it also doesn't solve problems for links that can only send 7-bit characters ๐
Here are a few examples to make it clearer. Packet data goes over the link like this:
0x7e is encoded as 0x7d, 0x5e.
0x7d is encoded as 0x7d, 0x5d.
0x01 is encoded as 0x7d, 0x21.
Some modems with software flow control might intercept outgoing DC1 and DC3 while ignoring the 8th (parity) bit. That data would go over the link like this:
0x11 is encoded as 0x7d, 0x31.
0x13 is encoded as 0x7d, 0x33.
0x91 is encoded as 0x7d, 0xb1.
0x93 is encoded as 0x7d, 0xb3.
Aborting a Transmission
On asynchronous links, a frame can be aborted by sending a "0" stop bit where a "1" bit is expected (framing error), or by sending a Control Escape octet followed right away by a closing Flag Sequence ๐
Time Fill
On asynchronous links, inter-octet and inter-frame time fill MUST be done by sending continuous "1" bits (mark-hold state) ๐
Note: On asynchronous links, inter-frame time fill can be thought of as extended inter-octet time fill. Doing that can save one octet per frame, which means less delay and more bandwidth ๐ This works because a Flag Sequence can act as both a frame close and a frame begin. After any frame has been received, an idle receiver is always in a frame begin state.
Robust transmitters should avoid using this trick too zealously, because the price of less delay is less reliability ๐ฌ Noisy links can make the receiver take in garbage characters and read them as part of an incoming frame. If the transmitter doesn't send a new opening Flag Sequence before the next frame, that frame gets tacked onto the noise characters and becomes an invalid frame (with high reliability). To avoid this, transmitters should send an opening Flag Sequence whenever "appreciable time" has passed since the prior closing Flag Sequence. It's suggested that implementations get the best results by always sending an opening Flag Sequence when the new frame isn't back-to-back with the last one. The maximum value for "appreciable time" is likely no greater than the typing rate of a slow-to-average typist, say 1 second โจ๏ธ
B. Fast Frame Check Sequence (FCS) Implementation ๐งฎ
B.1. FCS Computation Method
The following code does a table lookup to calculate the Frame Check Sequence as data arrives at the interface. This implementation is based on [7], [8], and [9]. The table is created by the code in section B.2.
/*
* u16 represents an unsigned 16-bit number. Adjust the typedef for
* your hardware.
*/
typedef unsigned short u16;
/*
* FCS lookup table as calculated by the table generator in section
* B.2.
*/
static u16 fcstab[256] = {
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};
#define PPPINITFCS 0xffff /* Initial FCS value */
#define PPPGOODFCS 0xf0b8 /* Good final FCS value */
/*
* Calculate a new fcs given the current fcs and the new data.
*/
u16 pppfcs(fcs, cp, len)
register u16 fcs;
register unsigned char *cp;
register int len;
{
ASSERT(sizeof (u16) == 2);
ASSERT(((u16) -1) > 0);
while (len--)
fcs = (fcs >> 8) ^ fcstab[(fcs ^ *cp++) & 0xff];
return (fcs);
}
B.2. Fast FCS table generator ๐ง
The following code builds the lookup table used to calculate the FCS.
/*
* Generate a FCS table for the HDLC FCS.
*
* Drew D. Perkins at Carnegie Mellon University.
*
* Code liberally borrowed from Mohsen Banan and D. Hugh Redelmeier.
*/
/*
* The HDLC polynomial: x**0 + x**5 + x**12 + x**16 (0x8408).
*/
#define P 0x8408
main()
{
register unsigned int b, v;
register int i;
printf("typedef unsigned short u16;\n");
printf("static u16 fcstab[256] = {");
for (b = 0; ; ) {
if (b % 8 == 0)
printf("\n");
v = b;
for (i = 8; i--; )
v = v & 1 ? (v >> 1) ^ P : v >> 1;
printf("0x%04x", v & 0xFFFF);
if (++b == 256)
break;
printf(",");
}
printf("\n};\n");
}
C. LCP Recommended Options ๐
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 โจ
okay so security gets its own little moment bestie ๐๐ญ the big takeaways are sprinkled through the parts about the Authentication Phase and the Authentication-Protocol Configuration Option ๐ . there's also a whole separate doc planned called PPP Authentication Protocols, so stay tuned for that one ๐ฆ
References ๐
Here's the reading list, bestie ๐ซถ
- [1] Electronic Industries Association, EIA Standard RS-232-C, "Interface Between Data Terminal Equipment and Data Communications Equipment Employing Serial Binary Data Interchange", August 1969.
- [2] International Organization For Standardization, ISO Standard 3309-1979, "Data communication - High-level data link control procedures - Frame structure", 1979.
- [3] International Organization For Standardization, ISO Standard 4335-1979, "Data communication - High-level data link control procedures - Elements of procedures", 1979.
- [4] International Organization For Standardization, ISO Standard 4335-1979/Addendum 1, "Data communication - High-level data link control procedures - Elements of procedures - Addendum 1", 1979.
- [5] International Organization For Standardization, Proposed Draft International Standard ISO 3309:1983/PDAD1, "Information processing systems - Data communication - High-level data link control procedures - Frame structure - Addendum 1: Start/stop transmission", 1984.
- [6] International Telecommunication Union, CCITT Recommendation X.25, "Interface Between Data Terminal Equipment (DTE) and Data Circuit Terminating Equipment (DCE) for Terminals Operating in the Packet Mode on Public Data Networks", CCITT Red Book, Volume VIII, Fascicle VIII.3, Rec. X.25., October 1984.
- [7] Perez, "Byte-wise CRC Calculations", IEEE Micro, June, 1983.
- [8] Morse, G., "Calculating CRC's by Bits and Bytes", Byte, September 1986.
- [9] LeVan, J., "A Fast CRC", Byte, November 1987.
- [10] American National Standards Institute, ANSI X3.4-1977, "American National Standard Code for Information Interchange", 1977.
- [11] Reynolds, J., and J. Postel, "Assigned Numbers", RFC 1060, USC/Information Sciences Institute, March 1990.
Acknowledgments ๐
okay the credit list is giving main character energy ๐ this doc is built on the WG Requirements (unpublished) and RFCs 1171 & 1172, by Drew Perkins of Carnegie Mellon University, and by Russ Hobby of the University of California at Davis ๐ธ
so many people put serious time into helping build the Point-to-Point Protocol ๐ the full list is way too long to write out, but the special shoutouts go to: Rick Adams (UUNET), Ken Adelman (TGV), Fred Baker (ACC), Mike Ballard (Telebit), Craig Fox (NSC), Karl Fox (Morning Star Technologies), Phill Gross (NRI), former WG chair Russ Hobby (UC Davis), David Kaufman (Proteon), former WG chair Steve Knowles (FTP Software), John LoVerso (Xylogics), Bill Melohn (Sun Microsystems), Mike Patton (MIT), former WG chair Drew Perkins (CMU), Greg Satz (cisco systems) and Asher Waldfogel (Wellfleet) ๐โจ
Chair's Address ๐ง
if you want to reach the working group, go through the current chair:
Brian Lloyd
Lloyd & Associates
3420 Sudbury Road
Cameron Park, California 95682
Phone: (916) 676-1147
EMail: brian@ray.lloyd.com
Author's Address ๐
questions about this memo can also go to:
William Allen Simpson
Daydreamer
Computer Systems Consulting Services
P O Box 6205
East Lansing, MI 48826-6025
EMail: bsimpson@ray.lloyd.com
๐ฆ where this page comes from
- ietf: rfc1331 1992-05
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms