RFC 1553

Compressing IPX Headers Over WAN Media (CIPX)

๐Ÿ“… published December 1993, from ietf

Compressing IPX Headers Over WAN Media (CIPX) ๐ŸŽ€

Network Working Group ๐ŸŒธ S. Mathur and M. Lewis from Telebit Corporation wrote this one. Request for Comments: 1553 โœจ It's on the Standards Track ๐Ÿ’… and the date is December 1993. The title block doesn't list anything it obsoletes or updates.

Status of this Memo โœจ

This doc is an Internet standards track protocol for the Internet community, and it's literally asking everyone to chime in with discussion and suggestions for improvements ๐Ÿซถ. For the current standardization state and status of this protocol, check the "Internet Official Protocol Standards" (STD 1). Distribution of this memo is unlimited ๐ŸŒˆ.

Abstract ๐Ÿฆ‹

Okay so this doc describes a way to compress the headers of IPX datagrams, and it's called CIPX ๐Ÿ’–. The whole point is that it can seriously boost performance over lower speed wide area network (WAN) media. For normal IPX packet traffic, CIPX can get a compression ratio of about 2:1, counting both the IPX header and the data, which is giving main character energy ๐Ÿ‘‘. It works on different kinds of WAN media, including ones that support PPP and X.25 ๐Ÿ”ฅ.

This memo is a product of the Point-to-Point Protocol Extensions (PPPEXT) Working Group of the IETF. Comments should go to the authors and the ietf-ppp@ucdavis.edu mailing list ๐Ÿ’œ.

Specification of Requirements ๐ŸŽ€

In this document, a few words are used to signify the requirements of the specification. They're often capitalized, so watch for them ๐Ÿ‘€.

MUST: This word, or the adjective "required", means that the definition is an absolute requirement of the specification. No cap, it's non-negotiable ๐Ÿ”ฅ.

MUST NOT: This phrase means that the definition is an absolute prohibition of the specification. Absolutely not, bestie ๐Ÿ’€.

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

MAY: This word, or the adjective "optional", means that this item is one of an allowed set of alternatives. An implementation which does not include this option MUST be prepared to interoperate with another implementation which does include the option ๐ŸŒˆ. So even if your build skips it, you still have to play nice with the ones that have it ๐Ÿซถ.

Introduction ๐Ÿงš

Internetwork Packet Exchange (IPX) is a protocol defined by the Novell Corporation [1] ๐Ÿ’…. It's derived from the Internet Datagram Protocol (IDP) of the Xerox Network Systems (XNS) family of protocols. IPX is a datagram, connectionless protocol, so it doesn't need an acknowledgment for each packet sent ๐Ÿฆ‹. It corresponds to the network layer of the ISO model ๐ŸŒธ.

Usually, there's a transport layer protocol sitting above IPX. The most common one is the Netware Core Protocol (NCP), which handles file server access ๐Ÿ“. The Sequenced Packet Exchange (SPX) is the reliable, connection-based transport protocol that applications commonly use โœจ.

An IPX packet has a 30 octet IPX header, and it's usually followed by the transport layer protocol header. The NCP header is 6 octets long, and the SPX header is 12 octets long ๐Ÿ’–.

Okay, two strategies get described below for compressing IPX headers. This specification requires that implementations of CIPX support both IPX header compression strategies ๐Ÿ˜ญ. These algorithms are based on the ones Van Jacobson described [2] for TCP/IP packets, so they're not coming out of nowhere ๐Ÿ”ฅ.

The first strategy compresses only the IPX header. This algorithm can be used on any IPX packet without affecting the transport protocol ๐ŸŽ€. It squishes a 30 octet IPX header down into a one to seven octet header ๐Ÿซง.

The second strategy compresses the combined IPX and NCP headers. This algorithm only compresses NCP packets with NCP type of 0x2222 and 0x3333 ๐ŸŒˆ. It takes a 36 octet NCP/IPX header and turns it into a one to eight octet header ๐Ÿ’….

Lastly, it's possible, and honestly often desirable, to use this type of header compression together with some type of data compression โœจ.

Data compression comes in lots of forms. Link bit stream compression is a common approach over very low speed asynchronous links, and modems usually handle it transparently ๐Ÿ“ž. Transparent bit stream compression is also offered in some DSUs, routers and bridges ๐Ÿ“. Data compression can be provided using protocols such as CCITT V.42bis[3], MNP 5, Lempel-Ziv, or LAPB[4] ๐Ÿงš.

When you use both header and data compression, the order matters a LOT ๐Ÿ˜ญ. When sending packets, data compression MUST be done after header compression. Conversely, when receiving packets, data decompression MUST be done before header decompression. Don't mix that up, bestie ๐Ÿ’€.

IPX Compression Algorithm ๐Ÿฆ‹

The normal IPX header has these fields: checksum, packet length, transport control (hop count), packet type, and destination and source address fields ๐ŸŽ€.

                             +-----------------------+
                             |       Checksum        |
                             +-----------------------+
                             |     Packet Length     |
                             +-----------+-----------+
                             |    Hops   |Packet Type|
                             +-----------+-----------+
                             |      Destination      |
                             |        Address        |
                             |      (12 Octets)      |
                             +-----------------------+
                             |        Source         |
                             |        Address        |
                             |      (12 Octets)      |
                             +-----------------------+

                                 IPX PACKET HEADER

The diagram above is shown without the field alignment details, so consider each field separately and think about how it typically changes ๐Ÿ‘€.

Historically, Novell hasn't used the Checksum field in the IPX header, and it's required that this field be set to 0xFFFF. Since the Checksum field stays constant, it's clear that the value can be compressed ๐Ÿง .

Where Checksums are implemented (not 0xFFFF), the Checksum MUST be included in the compressed packet. Recalculating the checksum would destroy the end-to-end reliability of the connection, so no shortcuts ๐Ÿ˜ค. Fun fact, Checksums are now implemented in the Fault Tolerant Servers ๐ŸŒธ.

For most links, the Packet Length can be figured out from the MAC layer ๐ŸŒˆ. There are cases where it can't, though. For example, some hardware devices pad packets to a required minimum length. For links where the IPX packet length can't be determined from the MAC layer, the packet length needs to be included in the compressed packet ๐Ÿซถ.

The Transport Control (Hops) field usually doesn't change between two end-points. For the purposes of compression, we'll assume it never changes, so this field won't be examined when determining a connection ๐Ÿงš.

The Packet Type field is constant for any connection โœจ.

The Destination and Source Address fields are each made up of 12 octets: a Network (4 octets), Node (6 octets), and Socket (2 octets) field. An IPX connection is the logical association between two endpoints known by a given source and destination address pair ๐Ÿ’–. For any specific IPX connection, the Destination and Source Address fields are constant ๐Ÿ’….

So the fields that may need to be included in the compressed IPX header are the Checksum and the Packet Length ๐ŸŽ€.

While using this IPX header compression algorithm, packets can be lost ๐Ÿ˜ญ. The loss of an Initial packet is a problem. If that happens and the sender later tries to send a compressed packet, the receiving end can't decompress it correctly ๐Ÿ’€.

The IPX header doesn't have enough information to tell when a re-transmission has occurred ๐Ÿ™ˆ. Because of that, the sender of an Initial packet needs to be guaranteed that the packet has been received. So this spec provides a mechanism for Confirmation of an Initial packet ๐Ÿซถ.

NCP/IPX Header Compression ๐Ÿ’œ

Since most IPX packets are Netware Core Protocol packets (packet type 17), compressing the NCP header gives us added performance ๐Ÿš€. A minimal CIPX implementation MUST also implement NCP/IPX compression. No skipping this one ๐Ÿ”ฅ.

                                  +------------+
                                  |    NCP     |
                                  |    Type    |
                                  +------------+
                                  |  Sequence  |
                                  |   Number   |
                                  +------------+
                                  | Connection |
                                  |(low octet) |
                                  +------------+
                                  |   Task     |
                                  |   Number   |
                                  +------------+
                                  | Connection |
                                  |(high octet)|
                                  +------------+

                                    NCP HEADER

The NCP header is 6 octets long and has these fields: NCP type, sequence number, connection number and task number ๐ŸŽ€.

These are the NCP type field values that are currently defined:

             1111   Create Connection
             2222   NCP request from workstation
             3333   NCP reply from file server
             5555   Destroy Connection
             7777   Burst Mode Packet
             9999   Server Busy Packet

This NCP header compression algorithm only compresses packets with a type field value of 0x2222 or 0x3333 ๐ŸŒˆ. If the NCP type is 0x2222, it's a request from the client to the server. If it's 0x3333, it's a response from the server to the client ๐Ÿ’…. Every other NCP packet type doesn't get compressed at the NCP level, but it still gets compressed at the IPX level โœจ. The Create Connection (0x111), Destroy Connection (0x5555) and Server Busy (0x9999) packets aren't exchanged often enough to justify special NCP compression ๐Ÿงš. The Burst Mode (0x7777) packet is discussed below ๐Ÿฆ‹.

The connection number is constant for a given connection ๐Ÿ’–.

The sequence number goes up by one for each new request, so it can be determined implicitly. The decompressor increments the sequence number for each compressed packet it receives for a connection ๐Ÿง .

The task number can change unpredictably, although it might stay constant for several packets. If the NCP task number is different from the last one for this connection, the NCP task number must be included ๐Ÿซถ.

If an NCP packet is lost, it gets retransmitted through the normal transport layer mechanisms ๐Ÿ”. The Initial NCP packet doesn't require confirmation, because a re-transmitted packet can be easily identified. You do this by comparing the sequence number of the packet to the sequence number of the previous packet. If the sequence number isn't exactly one greater than the previous packet, a new Initial packet must be sent, although the same connection slot may be used ๐ŸŒธ.

When a compressed packet gets lost, the sequence number will be too small. If the IPX Checksum is present, the loss can be spotted at the destination system because of an incorrect checksum ๐Ÿ”. When there's no checksum, the loss is more likely to be detected when a later retransmission shows up ๐Ÿฅฒ.

NCP Burst Mode Packets ๐ŸŽ€

okay so the burst mode protocol uses the NCP type value of 0x7777 ๐Ÿ’… and this packet type is giving main character energy because it does not have the normal NCP header we talked about. instead it gets a 36 octet burst header ๐Ÿฆ‹ the NCP header compression algorithm should not be used to compress this packet, ngl. the IPX header inside it is still compressible with the IPX header compression algorithm we already described โœจ

SPX Packets

SPX packets are typically used by apps that need reliable service, like print servers ๐Ÿ–จ๏ธ๐ŸŒธ it's possible to apply a similar NCP/IPX technique to SPX/IPX packets, but we haven't described such a mechanism yet ๐Ÿ™ˆ the IPX header in this packet is still compressible with the IPX header compression algorithm described above, so it's not all doom and gloom ๐Ÿ’–

Compression Header

IPX compression should be negotiated by some means (eg. IPXCP or IPXWAN) ๐Ÿซถ each end has to negotiate the desired options, like the maximum number of concurrent connections that will be maintained in each direction. once IPX compression is negotiated, every IPX packet sent over that link gets a CIPX header added to the beginning of the packet ๐Ÿงš the CIPX header is variable in length, so it's not a one-size-fits-all situation.

the one octet CIPX header is added even when a regular IPX packet is sent over the link!! ๐Ÿ˜ญ by including the CIPX header on every packet, we can run CIPX over various WAN links as if it were a normal IPX packet โœจ it doesn't rely on any new link specific packet demultiplexing, which is so clean ๐Ÿ‘‘

implementations of this compression protocol must maintain send and receive tables that track the state of each connection ๐Ÿ“ the original header for each connection is stored in a "slot". typically each client-server connection uses a separate slot. both sides keep a copy of the full IPX header for each slot. the sending side (compressor) uses this info to figure out which fields have changed, and the receiving side (decompressor) uses it to rebuild the original packet header ๐Ÿ’œ

the CIPX packet header specifies the type of the packet and any options for that packet. the minimum CIPX header is one octet in length ๐ŸŒˆ

   7   6   5   4   3   2   1   0
 +---+---+---+---+---+---+---+---+
 |   |   |   |   |   |   |   |   |
 +---+---+---+---+---+---+---+---+
   ^   ^   ^   ^   ^   ^   ^   ^
   |   |   |   |   |   |   |   |
   |   |   |   |   |___|___|___|___ Packet Type
   |   |   |   |                    0    Compressed
   |   |   |   |                    1    Regular
   |   |   |   |                    3    Confirmed Initial
   |   |   |   |                    5    Confirm
   |   |   |   |                    7    Unconfirmed Initial
   |   |   |   |                    9    Reject
   |   |   |   |                   11-15 Reserved
   |   |   |   |
   |__ |__ |__ |___________________ Packet Type Dependent Flags

                          FLAGS OCTET

as can be seen above, the low order bits specify the packet type ๐ŸŽ€ all Compressed packets have a lowest bit of zero, and the other packet types are odd numbers. it's giving binary math vibes, iykyk ๐Ÿค“

okay this part is SO important: the Flags octet MUST NOT contain the value 0xFF ๐Ÿšจ this is necessary to tell the CIPX flags octet apart from a normal IPX header with a 0xFFFF checksum field. it's important to be able to recognize a normal IPX header regardless of the state of compression. it's possible with some link layer protocols, like X.25 Permanent Virtual Circuits, that one end of the link may fail and start sending regular IPX packets without the CIPX header. CIPX implementations MUST recognize this situation and renegotiate the use of CIPX ๐Ÿ˜ญ๐Ÿ’€

each packet type has associated flag bits, called Packet Type Dependent Flags ๐Ÿ’… different packet types have different Packet Type Dependent Flags. all bits that are reserved or not specified must be set to zero ๐ŸŒธ

since none of the packet types other than Compressed currently uses any of the flag bits, the packet type field could easily be expanded ๐Ÿฆ‹ any future expansion must ensure that at least one of the bits in the Flags octet remains zero so the value cannot be 0xFF. the bestie in the future will thank us ๐Ÿซถ

Compressed Packet

this type of packet does not contain a packet header (either 30 byte IPX, or 36 byte NCP) ๐Ÿงš a slot number tells the receiver which saved header to use to rebuild the original packet header before passing the packet up to IPX โœจ

   ________________________________ Slot Number
   |                                0    Assume same as last packet
   |                                1    Included in packet
   |
   |   ____________________________ Checksum
   |   |                            0    Assume 0xFFFF
   |   |                            1    Included in packet
   |   |
   |   |   ________________________ Length
   |   |   |                        0    Determine from MAC length
   |   |   |                        1    Included in packet
   |   |   |
   |   |   |   ____________________ Task Number (NCP only)
   |   |   |   |                    0    Assume same as last packet
   |   |   |   |                    1    Included in packet
   |   |   |   |
   |   |   |   |   ________________ Reserved (Must be zero)
   |   |   |   |   |   |   |
   |   |   |   |   |   |   |   ____ Packet Type
   |   |   |   |   |   |   |   |    0    Compressed Packet
   v   v   v   v   v   v   v   v
 +---+---+---+---+---+---+---+---+
 |   |   |   |   | 0 | 0 | 0 | 0 |
 +---+---+---+---+---+---+---+---+
   7   6   5   4   3   2   1   0

consider each flag in the flags octet, looking at the high order bits working toward the lower order bits ๐Ÿ‘€ each of the fields is optional, but if it's present it will show up in the same order in the compressed packet header ๐Ÿ’–

Slot Number

the slot number flag says the slot number field is included in the compressed packet ๐ŸŽ€ the slot number field is one octet in length and specifies the number of the slot that corresponds to the Initial packet header. slots are numbered starting at zero and go up to the maximum number of slots minus one ๐Ÿ”ข

by default, slot compression is disabled ๐Ÿ™…โ€โ™€๏ธ if negotiated, slot compression can be enabled for those slots that were created by the Unconfirmed Initial packet. when set to one (1), the slot number flag indicates the inclusion of the the slot number in the compressed packet. when set to zero (0), it indicates the omission of the the slot number and the use of the same slot number as for the last packet ๐Ÿ’œ

Implementation Note ๐Ÿ“:

   Slot compression MUST only be enabled in a receiver which can
   account for all erroneous and discarded packets.  When a packet
   has been discarded, the slot number is indeterminate for future
   packets.  The decompressor MUST discard all further packets
   until a slot number is received.

Checksum

when set to one (1), the checksum flag says the compressed packet will include the 2 octet checksum ๐Ÿงฎ when set to zero (0), the omission of the checksum is indicated and the decompressor is to assume the checksum is 0xFFFF. note that meaningful checksums must be included in the packet with the checksum flag set to one (1) โœจ

Length

when set to one (1), the length flag indicates the inclusion of the IPX data length field in the compressed packet. when set to zero (0), it indicates the omission of the IPX data length field in the compressed packet ๐ŸŒˆ

this is the Length field from the original IPX packet header ๐Ÿ’… it specifies the length of the IPX header and data in the packet before compression. it does not include the CIPX compression fields such as flags, slot number, checksum, length field, or the NCP task number. note that it is preferable to determine the length field from the MAC layer whenever possible, by subtracting the length of the compression header fields and adding the length of the saved packet header ๐Ÿฆ‹

since every octet is significant over lower speed WAN links, there's an optimization in how the length is specified ๐Ÿซถ it can be a one, two or three octet field. if the length is in the range 0 to 127, it's a one octet field. if the length is in the range 128 to 16383, it's a two octet field in high to low order, with the first octet in the range 128 to 191. otherwise, if the length is greater than 16383, the first octet contains 192, and the second and third octets contain the full length. (this scheme is extensible to 8 octets, but currently is not required in the IPX protocol suite ๐Ÿงš)

   +-+-+-+-+-+-+-+-+
   |0|   length    |   length < 128
   +-+-+-+-+-+-+-+-+

   ONE OCTET LENGTH FIELD

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |1 0|          length           |   length < 16384
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   TWO OCTET LENGTH FIELD

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |1 1 0 0 0 0 0 0|            length             |  length < 65535
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   THREE OCTET LENGTH FIELD

Task Number

when set to one (1), the NCP task number flag says the NCP task number is included in the compressed packet (see NCP/IPX compression above) ๐ŸŽ€ when set to zero (0), it indicates the omission of the NCP task number in the compressed packet. when the NCP task number isn't included, we use the same NCP task number as the last packet ๐Ÿ’–

based on the bits set in the flags octet, the optional portions are included in the compressed IPX header ๐ŸŒธ the minimum compressed IPX header contains only the Flags octet. all fields in the original IPX header have been compressed out of the header ๐Ÿซง the maximum compressed IPX header can include up to 7 octets (the Flags, Slot, Checksum (2 octets), and Length (3 octets) fields), or 8 octets if the NCP Task Number is included. the minimum and maximum compressed IPX packets are shown below. header fields are one octet in length except where noted ๐Ÿ‘‘

        +--------+---------
        | Flags  | DATA ...
        |  0x00  |
        +--------+---------

        MINIMUM COMPRESSED IPX PACKET

        +--------+--------+---------+---------+---------
        | Flags  |  Slot  |Checksum | Length  | DATA ...
        |  0xE0  | Number |2 octets |3 octets |
        +--------+--------+---------+---------+---------

        MAXIMUM COMPRESSED IPX PACKET

        +--------+--------+---------+---------+--------+---------
        | Flags  |  Slot  |Checksum | Length  |NCP Task| DATA ...
        |  0xF0  | Number |2 octets |3 octets | Number |
        +--------+--------+---------+---------+--------+---------

        MAXIMUM COMPRESSED NCP/IPX PACKET

Regular Packet โœจ

okay so the Regular packet type is basically the "no compression, thank you" option ๐Ÿ™…โ€โ™€๏ธ it's used for an IPX packet that we're not going to compress, either because it can't be compressed or because the sender just decided not to bother ๐Ÿ’…

          7   6   5   4   3   2   1   0
        +---+---+---+---+---+---+---+---+
        | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
        +---+---+---+---+---+---+---+---+
          ^   ^   ^   ^   ^   ^   ^   ^
          |   |   |   |   |   |   |   |
          |   |   |   |   |___|___|___|___ Packet Type
          |   |   |   |                    1    Regular
          |   |   |   |
          |__ |__ |__ |___________________ Reserved (must be zero)

Regular packets are honestly rare ๐Ÿฅฒ they usually show up when the device doesn't have enough memory to set up a new compression slot. This type is also there for future, totally unforeseen changes to IPX that might wreck compression, so it's kind of a backup plan ๐Ÿฆ‹

Implementation Note:

The Regular Packet can be used for packets that are sporadic, which are not worth setting-up a compression slot. This may be hard to determine for specific protocols. Various methods such as hold-down and least-recently-used timers are currently being used.

Receiving one is super simple: you just strip off the 1 octet header and pass the packet up to IPX ๐ŸŽ€

The whole IPX packet comes right after the single Flags octet. And quick reminder, for a Regular Packet (not compressed or uncompressed) the slot number field is not included ๐Ÿซถ


Confirmed Initial Packet ๐Ÿ”ฅ

the Confirmed Initial packet is the compressor saying "hey, here's the original header I'm going to keep using for compression, can you please confirm you got it?" ๐Ÿ™ the high order 4 bits are reserved so more protocols can be added later (future-proofing is so iconic ๐Ÿ‘‘)

          7   6   5   4   3   2   1   0
        +---+---+---+---+---+---+---+---+
        | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
        +---+---+---+---+---+---+---+---+
          ^   ^   ^   ^   ^   ^   ^   ^
          |   |   |   |   |   |   |   |
          |   |   |   |   |___|___|___|___ Packet Type
          |   |   |   |                    3     Confirmed Initial
          |   |   |   |
          |__ |__ |__ |___________________ 0     IPX Protocol
                                           1-15  Reserved

This packet tells the receiver to link the IPX packet header with a slot number. The sender does this every time a different header format gets used for a slot, or when it hasn't gotten a Confirmation Packet back from the receiver yet ๐Ÿงš

The lower 4 bits of the Flags octet say this is a Confirmed Initial CIPX packet. The high 4 bits are reserved for expansion to support additional protocols. After the Flags octet comes the Slot Number and then an ID field, which is one octet long ๐Ÿ’œ

So for each slot, the ID goes up by one with every new header sent. Different slots can have the same ID, no drama ๐Ÿ™ˆ the combo of slot and ID is what uniquely identifies a header. In practice the ID octet can be any number that stays unique for a "reasonably long period" of time. How long that is depends on transmission speed, round trip delays, and network load. There must be very little chance of duplicate slot and ID combinations during that period, or the receiver won't know which header is being talked about, and that's a whole mess ๐Ÿ’€

Implementation Note:

There is no requirement to hold or resend the Confirmed Initial packet until confirmation. When a new packet with the same IPX header is to be sent, another Confirmed Initial packet should be sent using the same slot, the same ID, and the new packet data.

When a new packet with a different IPX header is to be sent, it may be sent using a slot which has not received confirmation. A Confirmed Initial packet is sent with the same slot, an incremented ID, and the new packet data. Assuming a least-recently-used policy for selecting a slot for a new IPX header, this provides the ability to reuse slots when a Confirmed Initial packet has been sent but not confirmed. ๐ŸŒˆ

          +---------+---------+---------+-/       /-+----------
          |  Flags  |   Slot  |   ID    |    IPX    |  DATA ...
          |   0x03  |  Number |         |   Header  |
          +---------+---------+---------+-/       /-+----------

CONFIRMED INITIAL PACKET

Quick note: a Confirmed Initial header is followed by a complete IPX packet ๐ŸŽ


Confirm Packet ๐Ÿ’–

the Confirm packet is the decompressor replying "yep, got your Confirmed Initial, we're good" ๐Ÿซถ once the compressor gets this, it can start sending Compressed frames ๐Ÿฆ‹

          7   6   5   4   3   2   1   0
        +---+---+---+---+---+---+---+---+
        | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
        +---+---+---+---+---+---+---+---+
          ^   ^   ^   ^   ^   ^   ^   ^
          |   |   |   |   |   |   |   |
          |   |   |   |   |___|___|___|___ Packet Type
          |   |   |   |                    5    Confirm
          |   |   |   |
          |__ |__ |__ |___________________ Reserved (must be zero)

A Confirm Packet is exactly 3 octets long ๐Ÿ“ it's made up of the Flags, Slot Number and ID fields. The Slot Number field holds the number of the slot being acknowledged, and the ID field holds the ID of the Confirmed Initial Packet being acknowledged. Super clean โœจ

        +---------+---------+----------+
        |  Flags  |   Slot  |    ID    |
        |   0x05  |  Number |          |
        +---------+---------+----------+

CONFIRM PACKET


Unconfirmed Initial Packet ๐Ÿงšโ€โ™€๏ธ

the Unconfirmed Initial packet is the compressor saying "here's the header I'll keep using" but without asking for a confirmation back ๐Ÿ‘€ after sending one, the compressor is allowed to immediately start sending Compressed packets, no waiting around โฉ

          7   6   5   4   3   2   1   0
        +---+---+---+---+---+---+---+---+
        | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 |
        +---+---+---+---+---+---+---+---+
          ^   ^   ^   ^   ^   ^   ^   ^
          |   |   |   |   |   |   |   |
          |   |   |   |   |___|___|___|___ Packet Type
          |   |   |   |                    7     Unconfirmed Initial
          |   |   |   |
          |__ |__ |__ |___________________ 0     NCP Protocol
                                           1-15  Reserved

This packet tells the receiver to link the IPX packet header with a slot number, and the sender does it each time a different header format is sent for a given slot ๐Ÿ’œ The lower 4 bits of the Flags octet say this is an Unconfirmed Initial CIPX packet, and the high 4 bits are reserved for more protocols later. The Flags octet is always followed by the Slot Number.

        +---------+---------+-/        /-+-/       /-+---------
        |  Flags  |   Slot  |    IPX     |    NCP    | NCP
        |   0x07  |  Number |   Header   |   Header  | DATA ...
        +---------+---------+-/        /-+-/       /-+---------

UNCONFIRMED INITIAL PACKET

Also, an Unconfirmed Initial header is followed by a complete IPX packet ๐Ÿ“


Reject Packet ๐Ÿ™…โ€โ™€๏ธ

the Reject packet is the decompressor's way of saying "I got a CIPX packet with a header I don't support, sorry bestie" ๐Ÿ’… it's there so CIPX can be extended in the future without chaos ๐ŸŒธ

          7   6   5   4   3   2   1   0
        +---+---+---+---+---+---+---+---+
        | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
        +---+---+---+---+---+---+---+---+
          ^   ^   ^   ^   ^   ^   ^   ^
          |   |   |   |   |   |   |   |
          |   |   |   |   |___|___|___|___ Packet Type
          |   |   |   |                    9    Reject
          |   |   |   |
          |__ |__ |__ |___________________ Reserved (must be zero)

A Reject Packet is exactly 3 octets long and has the Flags, Slot Number and Rejected Flags fields ๐Ÿ“ฆ

The Slot Number field holds the slot number of the packet being rejected. Since the real packet type might be unknown or misunderstood, this field actually holds the second octet of the rejected packet. In the normal case of a known CIPX packet type, this will be the slot number of an initial packet ๐Ÿง 

The Rejected Flags field holds the first octet of the packet being rejected. The packet type field is left untouched. Any flags that were correctly recognized should be cleared. The leftover flags show which specific features are being rejected. This info should be enough for implementations to adjust how they use certain packet types or dependent flags ๐ŸŽฏ

Implementation Note:

The Flags value of 0xFF is not a valid CIPX packet type. Hence, such a packet type should be recognized as a standard IPX header and forwarded without CIPX processing to the appropriate routines. Under no circumstances should a Flags value of 0xFF be rejected in a Reject Packet. โš ๏ธ

          +---------+---------+----------+
          |  Flags  |   Slot  | Rejected |
          |   0x09  |  Number |  Flags   |
          +---------+---------+----------+

REJECT PACKET


okay this part is about how the two ends agree on header compression over PPP links [5]. Header compression can be negotiated by IPXCP [6], and by default, no compression is enabled ๐Ÿ™…โ€โ™€๏ธ

The IPX-Compression-Protocol Configuration Option is what says "I can receive compressed packets." Each end of the link has to request this option separately if it wants bi-directional compression ๐Ÿ”

The PPP Protocol field gets set to the same value as the usual IPX packets, and all IPX packets sent over the link MUST conform to the compressed format ๐Ÿซถ

Here's a summary of the IPX-Compression-Protocol Configuration Option format used to negotiate Telebit IPX header compression (CIPX). The fields go left to right ๐Ÿ‘€

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |     Type      |    Length     |    IPX-Compression-Protocol   |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |  Max-Slot-Id  |    Options    |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Type

  • Value: 3

Length

  • Value: 6

IPX-Compression-Protocol

  • 0002 (hex) for Telebit Compressed IPX headers (CIPX). ๐Ÿฆ‹

Max-Slot-Id

The Max-Slot-Id field is one octet and indicates the maximum slot identifier. This is one less than the actual number of slots; the slot identifier has values from zero to Max-Slot-Id. ๐Ÿงš

Options

Okay so the Options field is ONE octet ๐Ÿ’– and it's the "logical or" of these values, so you just stack whatever features you want:

  • 0: No options. ๐Ÿซถ
  • 1: The slot identifier may be compressed. โœจ Heads up though: the slot identifier must not be compressed if the PPP link level has no way to tell the decompression module about a reception error. Syncing back up after errors depends on getting a packet with the slot identifier, so this one's not optional, bestie ๐Ÿ˜ญ
  • 2: Redefine Compressed Packet type bits 1-3. ๐Ÿฆ‹ Packet types were picked so that only the Compressed Packet type is an even value with a lowest bit of zero. Everything else is odd with a lowest bit of one. That means you only have to check one bit to spot a Compressed Packet, and the other 7 bits are free to carry status. Those 7 bits are the upper 4 bits (permanently defined as packet dependent flags) plus bits 1-3, which are otherwise part of the Packet Type. Redefining bits 1-3 of the Compressed Packet type is left for future expansion ๐ŸŒธ
      7   6   5   4   3   2   1   0
    +---+---+---+---+---+---+---+---+
    |   |   |   |   |   |   |   | 0 |
    +---+---+---+---+---+---+---+---+
      ^   ^   ^   ^   ^   ^   ^   ^
      |   |   |   |   |   |   |   |___ Packet Type
      |   |   |   |   |   |   |        0    Compressed Packet
      |   |   |   |   |   |   |
      |   |   |   |   |___|___|_______ Redefined bits
      |   |   |   |
      |___|___|___|___________________ Compressed Packet flags

By default this feature is not enabled, and this flag is set to zero. When it's set to one, it means you want to use the feature. ๐Ÿ’…

"IPXWAN" is the protocol Novell uses to swap the router-to-router info it needs before it starts sending regular IPX routing information and traffic over WAN datalinks [7]. To negotiate the Telebit compression option, we use Novell's allocated option number for CIPX (00) in the IPXWAN timer request/response packet ๐Ÿงš

The Timer Request packet carries this Telebit compression option:

     WOption Number       80        - Define compression type
     WAccept Option       01        - 0=No, 1=Yes, 3=N/A
     WOption Data Len     00 03     - Length of option
     WOption Data         00        - Telebit's compression (CIPX)
     WOption Data         XX        - Compression options
     WOption Data         NN        - Compression slots

Where the WOption Data fields are:

  • 00: Telebit's compression option described in this document (CIPX).
  • XX: Compression options, defined as below:
        0x01   Compress slot ID when possible
        0x02   Redefine Compressed Packet type bits 1-3.
  • NN: The requested # of compression slots.

The Accept Option (for compression type) must be set to YES if the option is supported and NO if it isn't. A Timer Response must respond with only one header compression type set to YES. ๐ŸŽ€

The Timer Response packet that accepts the option looks like this:

     WOption Number       80        - Define compression type
     WAccept Option       01        - 0=No, 1=Yes, 3=N/A
     WOption Data Len     00 03     - Length of option
     WOption Data         00        - Telebit's compression (CIPX)
     WOption Data         XX        - Compression options
     WOption Data         NN        - Compression slots

Where the WOption Data fields are:

  • 00: Telebit's compression option described in this document (CIPX).
  • XX: Compression options, defined as below:
        0x01   Compress slot ID when possible
        0x02   Redefine Compressed Packet type bits 1-3.
  • NN: The negotiated # of slots (the lower of each side's requested number of slots).

IPX packets (except IPXWAN packets, obviously) aren't sent over the link until IPXWAN negotiations are done. Once they're complete, regular IPX packets can go over the link ๐ŸŒˆ

If both ends agree on the compression options, the IPX packets get sent using the specified options. If either end doesn't accept a compression option, that option just won't be used, and compression happens with whatever options are left. Options, by definition, are not required. Implementations MUST support CIPX without any options. ๐Ÿ”ฅ

It's the job of the router sending the IPXWAN Timer Response to tell the other router which options will be used. The Timer Response MUST contain a subset of the options received in a Timer Request. ๐Ÿ‘‘

To be super clear, IPXWAN sets up a symmetrical compression link. Compression is configured the same way in both directions, so each end uses the same number of slots and the same compression options. It is illegal for link ends to use different numbers of slots or different options. ๐Ÿšซ

IPX Compression Performance

The performance of this algorithm depends on the number of active connections and the number of slots negotiated. If the number of slots is greater than the number of connections, the hit rate should be very high, which gives a very high compression ratio ๐Ÿ“ Performance also depends on the average size of the IPX packets. If the average packet size is small, compression gives a more noticeable performance boost โœจ

                             avg_data_len + uncomp_header_len
        Compression ratio = ----------------------------------
                             avg_data_len + avg_comp_header_len

Here, avg_data_len is the average length of data in the IPX packet, and uncomp_head_len is the uncompressed header length, which is fixed at 30 octets. avg_comp_header_len is the average length of the compressed IPX header. The minimum compressed IPX header is 1 octet long. The maximum compressed NCP/IPX header is 8 octets (including the NCP task number), but since no implementation yet sends packets longer than 16K, 7 octets is the commonly encountered maximum. A reasonable avg_comp_header_len is 2, assuming you include the flag and slot number octets ๐Ÿ™ˆ

The maximum data length in an IPX packet is 546 octets (576 octets minus the 30 octet IPX header), though newer implementations may send packets of up to 4096 octets. The minimum data length in an IPX packet is 1 octet. Within the normal distribution of small NCP packets, a reasonable avg_data_len is 26 octets ๐Ÿ’œ

                                 546 + 30
        Minimal Compression    = -------- =  1.04
                                 546 + 6

                                 1 + 30
        Maximal Compression    = ------   = 15.50
                                 1 + 1

                                 26 + 30
        Likely Compression     = -------  =  2.00
                                 26 + 2

Security Considerations

Okay, security time, and I'm taking it seriously ๐Ÿ”’ IPX has some security features, and they're all fully applicable to CIPX. CIPX does not significantly change the basic security of IPX.

References

[1] Novell Inc., "IPX Router Specification", September 1992, Part Number: 107-000029-001

[2] Jacobson, Van, "Compressing TCP/IP Headers for Low-Speed Serial Links", RFC 1144, February 1990

[3] CCITT Recommendation V.42bis Error Correcting Procedures for DCEs using Error Correction Procedures

[4] ISO 7776, Information Processing Systems - Data Communication - High Level Data Link Control Procedures - Description of the X.25 LAPB-Compatible DTE Data Link Procedures

[5] Simpson, W. A., "The Point-to-Point Protocol (PPP)", RFC 1548, December 1993

[6] Simpson, W. A., "The PPP Internet Packet Exchange Control Protocol (IPXCP)", RFC 1552, December 1993

[7] Allen, Michael, "Novell IPX Over Various WAN Media [IPXWAN]", RFC 1551, December 1993

Acknowledgements

This compression algorithm pulls in lots of ideas from the Van Jacobson TCP/IP header compression algorithm ๐Ÿซถ

Michael Allen from Novell gave a ton of valuable feedback while this algorithm was being designed. David Piscitello from Bellcore and Marty Del Vecchio at Shiva Corp. made several good suggestions. Bill Simpson was a huge help driving PPP, and specifically IPXCP, on the standards course ๐Ÿ’–

Chair's Address

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

      EMail: fbaker@acc.com

Authors' Addresses

      Saroop Mathur
      Telebit Corp.
      1315 Chesapeake Terrace
      Sunnyvale, CA 94089-1100

      EMail: mathur@telebit.com

      Mark S. Lewis
      Telebit Corp.
      1315 Chesapeake Terrace
      Sunnyvale, CA 94089-1100

      EMail: Mark.S.Lewis@telebit.com
๐Ÿ“ฆ where this page comes from