Connected: An Internet Encyclopedia
RFC 1144 - A.1 Definitions and State Data

Top: Connected: An Internet Encyclopedia
Up: Requests For Comments
Up: RFC 1144
Up: A Sample Implementation
Prev: A Sample Implementation
Next: A.2 Compression

### A.1 Definitions and State Data

       #define MAX_STATES 16   /* must be >2 and <255 */
       #define MAX_HDR 128     /* max TCP+IP hdr length (by protocol def) */

       /* packet types */
       #define TYPE_IP 0x40
       #define TYPE_UNCOMPRESSED_TCP 0x70
       #define TYPE_COMPRESSED_TCP 0x80
       #define TYPE_ERROR 0x00 /* this is not a type that ever appears on
                                * the wire.  The receive framer uses it to
                                * tell the decompressor there was a packet
                                * transmission error. */
       /*
        * Bits in first octet of compressed packet
        */

       /* flag bits for what changed in a packet */

       #define NEW_C  0x40
       #define NEW_I  0x20
       #define TCP_PUSH_BIT 0x10

       #define NEW_S  0x08
       #define NEW_A  0x04
       #define NEW_W  0x02
       #define NEW_U  0x01

       /* reserved, special-case values of above */
       #define SPECIAL_I (NEW_S|NEW_W|NEW_U)        /* echoed interactive traffic */
       #define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U)  /* unidirectional data */
       #define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U)

       /*
        * "state" data for each active tcp conversation on the wire.  This is
        * basically a copy of the entire IP/TCP header from the last packet together
        * with a small identifier the transmit & receive ends of the line use to
        * locate saved header.
        */
       struct cstate {
            struct cstate *cs_next;  /* next most recently used cstate (xmit only) */
            u_short cs_hlen;         /* size of hdr (receive only) */
            u_char cs_id;            /* connection # associated with this state */
            u_char cs_filler;
            union {
                 char hdr[MAX_HDR];
                 struct ip csu_ip;   /* ip/tcp hdr from most recent packet */
            } slcs_u;
       };
       #define cs_ip slcs_u.csu_ip
       #define cs_hdr slcs_u.csu_hdr

       /*
        * all the state data for one serial line (we need one of these per line).
        */
       struct slcompress {
            struct cstate *last_cs;            /* most recently used tstate */
            u_char last_recv;                  /* last rcvd conn. id */
            u_char last_xmit;                  /* last sent conn. id */
            u_short flags;
            struct cstate tstate[MAX_STATES];  /* xmit connection states */
            struct cstate rstate[MAX_STATES];  /* receive connection states */
       };

       /* flag values */
       #define SLF_TOSS 1       /* tossing rcvd frames because of input err */

       /*
        * The following macros are used to encode and decode numbers.  They all
        * assume that `cp' points to a buffer where the next byte encoded (decoded)
        * is to be stored (retrieved).  Since the decode routines do arithmetic,
        * they have to convert from and to network byte order.
        */

       /*
        * ENCODE encodes a number that is known to be non-zero.  ENCODEZ checks for
        * zero (zero has to be encoded in the long, 3 byte form).
        */
       #define ENCODE(n) { \
            if ((u_short)(n) >= 256) { \
                 *cp++ = 0; \
                 cp[1] = (n); \
                 cp[0] = (n) >> 8; \
                 cp += 2; \
            } else { \
                 *cp++ = (n); \
            } \
       }
       #define ENCODEZ(n) { \
            if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \
                 *cp++ = 0; \
                 cp[1] = (n); \
                 cp[0] = (n) >> 8; \
                 cp += 2; \
            } else { \
                 *cp++ = (n); \
            } \
       }

       /*
        * DECODEL takes the (compressed) change at byte cp and adds it to the
        * current value of packet field 'f' (which must be a 4-byte (long) integer
        * in network byte order).  DECODES does the same for a 2-byte (short) field.
        * DECODEU takes the change at cp and stuffs it into the (short) field f.
        * 'cp' is updated to point to the next field in the compressed header.
        */
       #define DECODEL(f) { \
            if (*cp == 0) {\
                 (f) = htonl(ntohl(f) + ((cp[1] << 8) | cp[2])); \
                 cp += 3; \
            } else { \
                 (f) = htonl(ntohl(f) + (u_long)*cp++); \
            } \
       }
       #define DECODES(f) { \
            if (*cp == 0) {\
                 (f) = htons(ntohs(f) + ((cp[1] << 8) | cp[2])); \
                 cp += 3; \
            } else { \
                 (f) = htons(ntohs(f) + (u_long)*cp++); \
            } \
       }
       #define DECODEU(f) { \
            if (*cp == 0) {\
                 (f) = htons((cp[1] << 8) | cp[2]); \
                 cp += 3; \
            } else { \
                 (f) = htons((u_long)*cp++); \
            } \
       }

Next: A.2 Compression

Connected: An Internet Encyclopedia
RFC 1144 - A.1 Definitions and State Data