RFC 1662
PPP in HDLC-like Framing
RFC 1662: PPP in HDLC-like Framing ๐
okay bestie, this is RFC 1662 and it's giving STANDARDS TRACK ๐ (part 1 of 5, so hang tight ๐ซถ). It's STD 51 and the category is Standards Track. The editor is W. Simpson from Daydreamer, and the doc is dated July 1994 ๐ธ. It obsoletes RFC 1549, so 1549 is retired and this one is the new hotness โจ.
Status of This Memo
okay so this part is the fine print ๐ It says this is an Internet standards track protocol for the Internet community, and it wants your discussion and suggestions for improvements ๐. For the official standardization state and status, check the current edition of the "Internet Official Protocol Standards" (STD 1) ๐. Distribution of this memo is unlimited ๐ฆ.
Abstract
the whole point is that the Point-to-Point Protocol (PPP) [1] gives us a standard way to carry multi-protocol datagrams over point-to-point links ๐ง. This document is all about how to use HDLC-like framing for PPP encapsulated packets ๐.
Table of Contents
1. Introduction .......................................... 1
1.1 Specification of Requirements ................... 2
1.2 Terminology ..................................... 2
2. Physical Layer Requirements ........................... 3
3. The Data Link Layer ................................... 4
3.1 Frame Format .................................... 5
3.2 Modification of the Basic Frame ................. 7
4. Octet-stuffed framing ................................. 8
4.1 Flag Sequence ................................... 8
4.2 Transparency .................................... 8
4.3 Invalid Frames .................................. 9
4.4 Time Fill ....................................... 9
4.4.1 Octet-synchronous ............................... 9
4.4.2 Asynchronous .................................... 9
4.5 Transmission Considerations ..................... 10
4.5.1 Octet-synchronous ............................... 10
4.5.2 Asynchronous .................................... 10
5. Bit-stuffed framing ................................... 11
5.1 Flag Sequence ................................... 11
5.2 Transparency .................................... 11
5.3 Invalid Frames .................................. 11
5.4 Time Fill ....................................... 11
5.5 Transmission Considerations ..................... 12
6. Asynchronous to Synchronous Conversion ................ 13
7. Additional LCP Configuration Options .................. 14
7.1 Async-Control-Character-Map (ACCM) .............. 14
APPENDICES ................................................... 17
A. Recommended LCP Options ............................... 17
B. Automatic Recognition of PPP Frames ................... 17
C. Fast Frame Check Sequence (FCS) Implementation ........ 18
C.1 FCS table generator ............................. 18
C.2 16-bit FCS Computation Method ................... 19
C.3 32-bit FCS Computation Method ................... 21
SECURITY CONSIDERATIONS ...................................... 24
REFERENCES ................................................... 24
ACKNOWLEDGEMENTS ............................................. 25
CHAIR'S ADDRESS .............................................. 25
EDITOR'S ADDRESS ............................................. 25
1. Introduction โจ
okay so this spec covers framing over bit-oriented and octet-oriented synchronous links, plus 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 ๐.
there's an escape mechanism so control data like XON/XOFF can get sent through the link transparently, and so spurious control data that gets injected by in-between hardware and software can be removed ๐ซถ.
some protocols expect error-free transmission and only do error detection on a conditional basis, or skip it entirely ๐ญ. PPP uses the HDLC Frame Check Sequence for error detection ๐ฅ. It's commonly available in hardware, and a software implementation is provided too ๐ .
1.1. Specification of Requirements
this section explains the requirement words. They're often capitalized, so watch for them ๐
- MUST: this word, or the adjective "required", means the definition is an absolute requirement of the spec ๐
- MUST NOT: this phrase means the definition is an absolute prohibition of the spec ๐ซ
- SHOULD: this word, or the adjective "recommended", means there may be valid reasons in particular circumstances to ignore this item ๐ธ. But the full implications must be understood and carefully weighed before picking a different course ๐ง
- MAY: this word, or the adjective "optional", means this item is one of an allowed set of alternatives ๐ฆ. An implementation that doesn't include this option MUST be prepared to interoperate with another implementation that does include it ๐ซถ
1.2. Terminology
this doc uses these terms a lot, so here's the tea ๐ต
datagram: the unit of transmission in the network layer (like IP) ๐. A datagram may be encapsulated in one or more packets passed to the data link layer ๐ฆframe: the unit of transmission at the data link layer ๐. A frame may include a header and/or a trailer, along with some number of units of data โจpacket: the basic unit of encapsulation, passed across the interface between the network layer and the data link layer ๐. A packet is usually mapped to a frame, but the exceptions are when data link layer fragmentation is happening, or when multiple packets get packed into a single frame ๐งpeer: the other end of the point-to-point link ๐silently discard: the implementation discards the packet 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 works across most DTE/DCE interfaces, like EIA RS-232-E, EIA RS-422, and CCITT V.35 ๐. The only absolute requirement PPP has is a full-duplex circuit, either dedicated or circuit-switched ๐ธ. It needs to run in asynchronous (start/stop), bit-synchronous, or octet-synchronous mode, and be transparent to PPP Data Link Layer frames ๐ฆ.
Interface Format
PPP presents an octet interface to the physical layer ๐. There's no provision for sub-octets to be supplied or accepted, so no sub-octet business here ๐ โโ๏ธ.
Transmission Rate
PPP doesn't put any restrictions on transmission rate, other than whatever the particular DTE/DCE interface allows โก.
Control Signals
PPP doesn't require control signals like Request To Send (RTS), Clear To Send (CTS), Data Carrier Detect (DCD), and Data Terminal Ready (DTR) ๐ .
when they're available, using these signals can unlock more functionality and performance โจ. Specifically, these signals SHOULD be used to signal the Up and Down events in the LCP Option Negotiation Automaton [1] ๐ฅ. When these signals aren't available, the implementation MUST signal the Up event to LCP upon initialization, and SHOULD NOT signal the Down event ๐ซถ.
since signalling isn't required, the physical layer MAY be decoupled from the data link layer ๐ฆ, which hides the transient details of the physical transport ๐ซง. This has implications for mobility in cellular radio networks, and other rapidly switching links ๐ก.
when moving from cell to cell within the same zone, an implementation MAY choose to treat the entire zone as a single link, even though transmission is switched among several frequencies ๐ผ. The link is considered to be with the central control unit for the zone, not the individual cell transceivers ๐ข. Even so, the link SHOULD re-establish its configuration whenever it's switched to a different administration ๐.
due to the bursty nature of data traffic, some implementations have chosen to disconnect the physical layer during periods of inactivity, then reconnect when traffic resumes, without telling the data link layer ๐. Robust implementations should avoid using this trick over-zealously, since the price for decreased setup latency is decreased security ๐. Implementations SHOULD signal the Down event whenever "significant time" has elapsed since the link was disconnected โฐ. The value for "significant time" is a matter of major debate, and it's based on the tariffs, call setup times, and security concerns of the installation ๐.
3. The Data Link Layer ๐ง
PPP uses the principles described in the ISO 3309-1979 HDLC frame structure, most recently the fourth edition 3309:1991 [2] ๐. That one specifies modifications that allow HDLC to be used in asynchronous environments ๐.
the PPP control procedures use the Control field encodings described in ISO 4335-1979 HDLC elements of procedures, most recently the fourth edition 4335:1991 [4] ๐.
This should not be construed to indicate that every feature of the above recommendations is included in PPP. Each feature that is included is explicitly described in the following sections. ๐
to stay consistent with standard Internet practice, and avoid confusion for people 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 contrary to standard ISO and CCITT practice, which orders bits as transmitted (network bit order) ๐. So keep this in mind when you compare this document with the international standards documents ๐.
3.1. Frame Format ๐
Okay bestie, here's the PPP HDLC-like frame structure at a glance ๐ It leaves out the sync bits (like start and stop bits on async links) and any bits or octets that get inserted for transparency. Everything gets sent left to right โจ
+----------+----------+----------+
| Flag | Address | Control |
| 01111110 | 11111111 | 00000011 |
+----------+----------+----------+
+----------+-------------+---------+
| Protocol | Information | Padding |
| 8/16 bits| * | * |
+----------+-------------+---------+
+----------+----------+-----------------
| FCS | Flag | Inter-frame Fill
|16/32 bits| 01111110 | or next Address
+----------+----------+-----------------
The Protocol, Information and Padding fields are explained in the Point-to-Point Protocol Encapsulation [1] ๐
Flag Sequence ๐ฉ
Every frame starts and ends with a Flag Sequence, which is the binary sequence 01111110 (hex 0x7e). Every implementation keeps checking for this flag, because it's how frame synchronization works ๐ซถ
Only one Flag Sequence is required between two frames. Two Flag Sequences back to back make an empty frame. That gets silently discarded and does not count as an FCS error ๐
Address Field ๐
The Address field is one octet holding the binary sequence 11111111 (hex 0xff), which is the All-Stations address. Individual station addresses are not assigned, so it's all about the All-Stations address ๐
It MUST always be recognized and received.
Other address lengths and values may be defined later, or by prior agreement. Frames with unrecognized Addresses SHOULD be silently discarded.
Control Field ๐๏ธ
The Control field is one octet holding the binary sequence 00000011 (hex 0x03). That's the Unnumbered Information (UI) command with the Poll/Final (P/F) bit set to zero โจ
Other Control field values may be defined later, or by prior agreement. Frames with unrecognized Control field values SHOULD be silently discarded.
Frame Check Sequence (FCS) Field ๐
The FCS field defaults to 16 bits (two octets). It's sent least significant octet first, and that octet holds the coefficient of the highest term ๐งฎ
A 32-bit (four octet) FCS is also defined. Its use may be negotiated as described in "PPP LCP Extensions" [5] ๐ฆ
Other FCS lengths may be defined later, or by prior agreement.
The FCS is calculated over all bits of the Address, Control, Protocol, Information and Padding fields. It does not include start and stop bits (async), bits (sync) or octets (async or sync) that got inserted for transparency. The Flag Sequences and the FCS field itself are not included either ๐
When octets are received which are flagged in the Async-Control-Character-Map, they are discarded before calculating the FCS.
For more on how the FCS is specified, check out the Appendices ๐
The end of the Information and Padding fields is found by locating the closing Flag Sequence and removing the Frame Check Sequence field. Easy peasy ๐ธ
3.2. Modification of the Basic Frame ๐ฆ
The Link Control Protocol can negotiate changes to the standard HDLC-like frame structure. However, modified frames will always be clearly distinguishable from standard frames ๐
Address-and-Control-Field-Compression ๐๏ธ
When you use standard HDLC-like framing, the Address and Control fields hold the hex values 0xff and 0x03 respectively. When other Address or Control field values are in use, Address-and-Control-Field-Compression MUST NOT be negotiated ๐ซ
On transmission, compressed Address and Control fields are simply omitted โจ
On reception, the Address and Control fields get decompressed by looking at the first two octets. If those contain 0xff and 0x03, they're assumed to be the Address and Control fields. If not, it's assumed the fields were compressed and never got transmitted ๐ง
By definition, the first octet of a two octet Protocol field will never be0xff(since it is not even). The Protocol field value0x00ffis not allowed (reserved) to avoid ambiguity when Protocol-Field-Compression is enabled and the first Information field octet is0x03. ๐
4. Octet-stuffed framing ๐งธ
This chapter gives a quick summary of how HDLC-like framing works on 8-bit asynchronous and octet-synchronous links ๐
4.1. Flag Sequence ๐ฉ
The Flag Sequence marks the beginning or end of a frame. The octet stream gets checked one octet at a time for the value 01111110 (hex 0x7e) ๐
4.2. Transparency ๐ช
This uses an octet stuffing procedure. The Control Escape octet is defined as binary 01111101 (hex 0x7d), most significant bit first ๐
As a minimum, sending implementations MUST escape the Flag Sequence and Control Escape octets.
After FCS computation, the transmitter checks the entire frame between the two Flag Sequences. Each Flag Sequence, each Control Escape octet, and any octet flagged in the sending Async-Control-Character-Map (ACCM) gets replaced by a two octet sequence. That sequence is the Control Escape octet followed by the original octet exclusive-or'd with hex 0x20 โจ
This is bit 5 complemented, where the bit positions are numbered 76543210 (the 6th bit as used in ISO numbered 87654321 -- BEWARE when comparing documents).
Receiving implementations MUST correctly process all Control Escape sequences ๐ซถ
On reception, before FCS computation, each octet with a value less than hex 0x20 gets checked. If it's flagged in the receiving ACCM, it just gets removed, because it may have been inserted by intervening data communications equipment ๐งน Each Control Escape octet is removed too, and the octet after it is exclusive-or'd with hex 0x20. The exception is when that octet is the Flag Sequence, which aborts a frame ๐
A few examples should make this clearer. Escaped data goes over the link like this:
0x7e is encoded as 0x7d, 0x5e. (Flag Sequence)
0x7d is encoded as 0x7d, 0x5d. (Control Escape)
0x03 is encoded as 0x7d, 0x23. (ETX)
Some modems with software flow control may intercept outgoing DC1 and DC3 while ignoring the 8th (parity) bit. Data like that goes over the link like this:
0x11 is encoded as 0x7d, 0x31. (XON)
0x13 is encoded as 0x7d, 0x33. (XOFF)
0x91 is encoded as 0x7d, 0xb1. (XON with parity set)
0x93 is encoded as 0x7d, 0xb3. (XOFF with parity set)
4.3. Invalid Frames ๐ โโ๏ธ
Frames that are too short (less than 4 octets when using the 16-bit FCS) get silently discarded. The same goes for frames that end with a Control Escape octet immediately followed by a closing Flag Sequence, and frames where octet-framing is violated (by sending a "0" stop bit where a "1" bit is expected). None of those count as an FCS error ๐
4.4. Time Fill โณ
4.4.1. Octet-synchronous ๐
There is no provision for inter-octet time fill.
The Flag Sequence MUST be transmitted during inter-frame time fill.
4.4.2. Asynchronous ๐ก
Inter-octet time fill MUST be accomplished by transmitting continuous "1" bits (mark-hold state) ๐ซ
Inter-frame time fill can be seen as extended inter-octet time fill. Doing this can save one octet per frame, which means less delay and more bandwidth ๐ It works because a Flag Sequence can be both a frame end and a frame begin. After any frame has been received, an idle receiver will always be in a frame begin state.
Robust transmitters should avoid using this trick over-zealously, because the price for less delay is less reliability ๐ฌ Noisy links may cause the receiver to pick up 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 stuck onto the noise characters, causing an invalid frame (with high reliability) ๐ฅ
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. Transmitters SHOULD send an open Flag Sequence whenever "appreciable time" has passed since the prior closing Flag Sequence. The maximum value for "appreciable time" is likely no greater than the typing rate of a slow typist, about 1 second โจ๏ธ
4.5. Transmission Considerations ๐ถ
4.5.1. Octet-synchronous ๐งฉ
The definition of the various encodings and scrambling is the responsibility of the DTE/DCE equipment in use, and it's outside the scope of this specification ๐
4.5.2. Asynchronous ๐ค
All octets are transmitted least significant bit first, with one start bit, eight bits of data, and one stop bit. There is no provision for seven bit asynchronous links ๐ซ
5. Bit-stuffed framing ๐งต
This chapter gives a quick summary of how HDLC-like framing works on bit-synchronous links ๐
5.1. Flag Sequence ๐ฉ
The Flag Sequence marks the beginning or end of a frame, and it's used for frame synchronization. The bit stream gets checked one bit at a time for the binary sequence 01111110 (hex 0x7e) ๐
The "shared zero mode" Flag Sequence 011111101111110 SHOULD NOT be used. When it can't be avoided, that implementation MUST ensure the first Flag Sequence detected (the end of the frame) is promptly communicated to the link layer. Shared zero mode gets in the way of interoperability with bit-synchronous to asynchronous and bit-synchronous to octet-synchronous converters ๐ค
5.2. Transparency ๐ช
After FCS computation, the transmitter checks the entire frame between the two Flag Sequences. A "0" bit is inserted after every run of five contiguous "1" bits (including the last 5 bits of the FCS), so a Flag Sequence never gets faked ๐ญ
On reception, before FCS computation, any "0" bit that directly follows five contiguous "1" bits gets discarded โ๏ธ
5.3. Invalid Frames ๐ซ
Frames that are too short (less than 4 octets when using the 16-bit FCS), or that end with a sequence of more than six "1" bits, get silently discarded. They don't count as an FCS error ๐
5.4. Time Fill โฐ
There is no provision for inter-octet time fill.
The Flag Sequence SHOULD be transmitted during inter-frame time fill. However, certain types of circuit-switched links require mark idle (continuous ones), especially the ones that calculate accounting based on periods of bit activity ๐ธ When mark idle is used on a bit-synchronous link, the implementation MUST ensure at least 15 consecutive "1" bits between Flags during the idle period, and that the Flag Sequence is always generated at the beginning of a frame after an idle period ๐ง
This differs from practice in ISO 3309, which allows 7 to 14 bit mark idle. ๐
5.5. Transmission Considerations โจ
okay bestie, first things first: every octet gets sent least significant bit first ๐ซถ no cap.
The encodings and scrambling are the DTE/DCE equipment's job, which is totally outside the scope of this spec ๐
Real talk though: PPP doesn't care how the bit stream is represented underneath, but if nobody agrees on transmission standards it'll wreck interoperability just as much as missing data link standards ๐ญ. At 56 Kbps through 2.0 Mbps, NRZ is the most widely available option right now, so it's recommended as a default ๐ธ.
When you're allowed to configure the encoding, NRZI is recommended as an alternative ๐ฆ because it's relatively immune to signal inversion configuration errors, and it MAY allow connection without an expensive DSU/CSU. Plot twist though: NRZI makes the missing x1 factor of the 16-bit FCS even worse ๐. So one error in 215 goes undetected (instead of one in 216), and triple errors aren't detected at all.
Heads up: when NRZI is in use, it's recommended that the 32-bit FCS gets negotiated, because that one includes the x1 factor ๐จ
At higher speeds of up to 45 Mbps, some implementors went with the ANSI High Speed Synchronous Interface [HSSI] ๐. The experience is still pretty limited, so implementors are encouraged to cooperate on choosing transmission encoding ๐.
6. Asynchronous to Synchronous Conversion ๐
Lowkey super common: there may be some asynchronous-to-synchronous converters (some are built into modems and cellular interfaces), which means one end is async PPP and the other end is sync ๐. The converter is responsible for doing all the stuffing conversions during operation.
To make this work, synchronous PPP implementations MUST always respond to the Async-Control-Character-Map Configuration Option with the LCP Configure-Ack ๐ซถ. But bestie, accepting the option does not imply that the synchronous side will do any ACCM mapping. All of that octet mapping gets handled by the asynchronous-to-synchronous converter instead โจ.
7. Additional LCP Configuration Options ๐
The Configuration Option format and basic options are already defined for LCP [1] ๐.
Up-to-date values of the LCP Option Type field are specified in the most recent "Assigned Numbers" RFC [10]. This document is all about the following value:
2 Async-Control-Character-Map
7.1. Async-Control-Character-Map (ACCM) ๐ง
Description
This Configuration Option gives us a way to negotiate control character transparency on asynchronous links ๐ธ.
Each end of the asynchronous link keeps two Async-Control-Character-Maps. The receiving ACCM is 32 bits, but the sending ACCM can be up to 256 bits. That gives four distinct ACCMs in total, two in each direction of the link ๐.
For asynchronous links, the default receiving ACCM is 0xffffffff. The default sending ACCM is 0xffffffff, plus the Control Escape and Flag Sequence characters themselves, plus whatever other outgoing characters are flagged (by prior configuration) as likely to be intercepted ๐. For other types of links, the default value is 0, since there's no need for mapping.
The default inclusion of all octets less than 0x20 lets all ASCII control characters [6] excluding DEL (Delete) get transparently communicated through all known data communications equipment โจ.
The transmitter MAY also send octets with values in the range 0x40 through 0xff (except 0x5e) in Control Escape format ๐
. Since these octet values aren't negotiable, this doesn't solve the problem of receivers that can't handle all non-control characters. Also, since the technique doesn't affect the 8th bit, it doesn't solve problems for communications links that can only send 7-bit characters ๐ญ.
Note that this specification differs in detail from later amendments, such as 3309:1991/Amendment 2 [3]. However, that "extended transparency" only gets applied by "prior agreement". Using the transparency methods in this specification counts as a prior agreement with respect to PPP ๐ค.
For compatibility with 3309:1991/Amendment 2, the transmitter MAY escape DEL and ACCM equivalents with the 8th (most significant) bit set. No change is required in the receiving algorithm ๐ซง.
Following ACCM negotiation, the transmitter SHOULD cease escaping DEL ๐.
However, it's rarely necessary to map all control characters, and often it's unnecessary to map any control characters at all. The Configuration Option is used to inform the peer which control characters MUST remain mapped when the peer sends them ๐ฃ.
The peer MAY still send any other octets in mapped format, if it's necessary because of constraints known to the peer. The peer SHOULD Configure-Nak with the logical union of the sets of mapped octets, so that when such octets are spuriously introduced they can be ignored on receipt ๐งน.
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 | ACCM
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
ACCM (cont) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Type
2
Length
6
ACCM
The ACCM field is four octets, and it indicates the set of control characters to be mapped. The map is sent most significant octet first ๐ฏ.
Each numbered bit corresponds to the octet of the same value. If the bit is cleared to zero, then that octet need not be mapped. If the bit is set to one, then that octet MUST remain mapped. For example, if bit 19 is set to zero, then the ASCII control character 19 (DC3, Control-S) MAY be sent in the clear ๐.
Note: The least significant bit of the least significant octet (the final octet transmitted) is numbered bit 0, and would map to the ASCII control character NUL ๐ง
A. Recommended LCP Options ๐
The following Configurations Options are recommended:
High Speed links
- Magic Number
- Link Quality Monitoring
- No Address and Control Field Compression
- No Protocol Field Compression
Low Speed or Asynchronous links
- Async Control Character Map
- Magic Number
- Address and Control Field Compression
- Protocol Field Compression
B. Automatic Recognition of PPP Frames ๐
It's sometimes desirable to detect PPP frames, for example during a login sequence. The following octet sequences all begin valid PPP LCP frames:
7e ff 03 c0 21
7e ff 7d 23 c0 21
7e 7d df 7d 23 c0 21
Note that the first two forms are not a valid username for Unix. However, only the third form generates a correctly checksummed PPP frame, whenever 03 and ff are taken as the control characters ETX and DEL without regard to parity (they are correct for an even parity link) and discarded ๐.
Many implementations deal with this by putting the interface into packet mode when one of the above username patterns is detected during login, without examining the initial PPP checksum. The initial incoming PPP frame is discarded, but a Configure-Request is sent immediately ๐.
C. Fast Frame Check Sequence (FCS) Implementation ๐งฎ
The FCS was originally designed with hardware implementations in mind. A serial bit stream is transmitted on the wire, the FCS is calculated over the serial data as it goes out, and the complement of the resulting FCS is appended to the serial stream, followed by the Flag Sequence ๐ก.
The receiver has no way of determining that it has finished calculating the received FCS until it detects the Flag Sequence. So the FCS was designed so that a particular pattern results when the FCS operation passes over the complemented FCS. A good frame is indicated by this "good FCS" value ๐.
C.1. FCS table generator ๐ง
The following code creates the lookup table used to calculate the FCS-16.
/*
* Generate a FCS-16 table.
*
* Drew D. Perkins at Carnegie Mellon University.
*
* Code liberally borrowed from Mohsen Banan and D. Hugh Redelmeier.
*/
/*
* The FCS-16 generator polynomial: x**0 + x**5 + x**12 + x**16.
*/
#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("\t0x%04x", v & 0xFFFF);
if (++b == 256)
break;
printf(",");
}
printf("\n};\n");
}
C.2. 16-bit FCS Computation Method โจ
okay so this is the table lookup trick for the 16-bit Frame Check Sequence ๐ง It works byte by byte as the data comes into the interface, so you don't have to wait for the whole frame. It's based on [7], [8], and [9], and honestly it's giving speed + elegance ๐
/*
* 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.
*/
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 PPPINITFCS16 0xffff /* Initial FCS value */
#define PPPGOODFCS16 0xf0b8 /* Good final FCS value */
/*
* Calculate a new fcs given the current fcs and the new data.
*/
u16 pppfcs16(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);
}
/*
* How to use the fcs
*/
tryfcs16(cp, len)
register unsigned char *cp;
register int len;
{
u16 trialfcs;
/* add on output */
trialfcs = pppfcs16( PPPINITFCS16, cp, len );
trialfcs ^= 0xffff; /* complement */
cp[len] = (trialfcs & 0x00ff); /* least significant byte first */
cp[len+1] = ((trialfcs >> 8) & 0x00ff);
/* check on input */
trialfcs = pppfcs16( PPPINITFCS16, cp, len + 2 );
if ( trialfcs == PPPGOODFCS16 )
printf("Good FCS\n");
}
C.3. 32-bit FCS Computation Method ๐
now the big sibling! ๐ This one does the same table lookup thing, but for a 32-bit Frame Check Sequence, again as data arrives at the interface.
/*
* The FCS-32 generator polynomial: x**0 + x**1 + x**2 + x**4 + x**5
* + x**7 + x**8 + x**10 + x**11 + x**12 + x**16
* + x**22 + x**23 + x**26 + x**32.
*/
/*
* u32 represents an unsigned 32-bit number. Adjust the typedef for
* your hardware.
*/
typedef unsigned long u32;
static u32 fcstab_32[256] =
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
#define PPPINITFCS32 0xffffffff /* Initial FCS value */
#define PPPGOODFCS32 0xdebb20e3 /* Good final FCS value */
/*
* Calculate a new FCS given the current FCS and the new data.
*/
u32 pppfcs32(fcs, cp, len)
register u32 fcs;
register unsigned char *cp;
register int len;
{
ASSERT(sizeof (u32) == 4);
ASSERT(((u32) -1) > 0);
while (len--)
fcs = (((fcs) >> 8) ^ fcstab_32[((fcs) ^ (*cp++)) & 0xff]);
return (fcs);
}
/*
* How to use the fcs
*/
tryfcs32(cp, len)
register unsigned char *cp;
register int len;
{
u32 trialfcs;
/* add on output */
trialfcs = pppfcs32( PPPINITFCS32, cp, len );
trialfcs ^= 0xffffffff; /* complement */
cp[len] = (trialfcs & 0x00ff); /* least significant byte first */
cp[len+1] = ((trialfcs >>= 8) & 0x00ff);
cp[len+2] = ((trialfcs >>= 8) & 0x00ff);
cp[len+3] = ((trialfcs >> 8) & 0x00ff);
/* check on input */
trialfcs = pppfcs32( PPPINITFCS32, cp, len + 4 );
if ( trialfcs == PPPGOODFCS32 )
printf("Good FCS\n");
}
Security Considerations ๐ฅ
okay bestie, this part is serious ๐ญ The Physical Layer Requirements section already mentioned that the link layer might not get told when the physical layer's connected state changes. That's a real problem, because it means you can end up leaning way too hard on the integrity and security of switching systems and administrations ๐ An insertion attack might go totally unnoticed, and an attacker who can spoof the same calling identity might be able to dodge link authentication. Not okay. Stay alert, periodt ๐
References ๐
[1] Simpson, W., Editor, "The Point-to-Point Protocol (PPP)",
STD 50, RFC 1661, Daydreamer, July 1994.
[2] ISO/IEC 3309:1991(E), "Information Technology -
Telecommunications and information exchange between systems -
High-level data link control (HDLC) procedures - Frame
structure", International Organization For
Standardization, Fourth edition 1991-06-01.
[3] ISO/IEC 3309:1991/Amd.2:1992(E), "Information Technology -
Telecommunications and information exchange between systems -
High-level data link control (HDLC) procedures - Frame
structure - Amendment 2: Extended transparency options for
start/stop transmission", International Organization For
Standardization, 1992-01-15.
[4] ISO/IEC 4335:1991(E), "Information Technology -
Telecommunications and information exchange between systems -
High-level data link control (HDLC) procedures - Elements of
procedures", International Organization For Standardization,
Fourth edition 1991-09-15.
[5] Simpson, W., Editor, "PPP LCP Extensions", RFC 1570,
Daydreamer, January 1994.
[6] ANSI X3.4-1977, "American National Standard Code for
Information Interchange", American National Standards
Institute, 1977.
[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] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, RFC
1340, USC/Information Sciences Institute, July 1992.
Acknowledgements ๐ซถ
this doc is the product of the Point-to-Point Protocol Working Group of the Internet Engineering Task Force (IETF) ๐ธ Comments should be sent to the ietf-ppp@merit.edu mailing list.
this spec is built on earlier RFCs, and lots of people contributed to those, so shoutouts to all of them ๐
the 32-bit FCS example code came from Karl Fox (Morning Star Technologies) โจ
and a special thank you to Morning Star Technologies for the computing resources and network access support that made writing this spec possible ๐ฆ
Chair's Address ๐
the working group can be reached through the current chair:
Fred Baker
Advanced Computer Communications
315 Bollay Drive
Santa Barbara, California 93117
fbaker@acc.com
Editor's Address โจ
okay so if you have questions about this memo, you can reach out to the editor directly ๐ bestie, here's where to find them:
William Allen Simpson
Daydreamer
Computer Systems Consulting Services
1384 Fontaine
Madison Heights, Michigan 48071
their emails are Bill.Simpson@um.cc.umich.edu and bsimpson@MorningStar.com ๐ฌ๐ฆ
that's the whole editor's section, and honestly he's the one who wrote the book on this stuff ๐
๐ฆ where this page comes from
- ietf: rfc1662 1994-07
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms