1*38369Skarels /* 2*38369Skarels * THIS CODE IS NOT FOR DISTRIBUTION! 3*38369Skarels * KEEP YOUR GRUBBY HANDS OFF UNLESS AUTHORIZED BY VAN JACOBSON TO COPY! 4*38369Skarels * ASK SAM, MIKE, OR BILL ABOUT IT. 5*38369Skarels */ 6*38369Skarels 7*38369Skarels /* 8*38369Skarels * Definitions for tcp compression routines. 9*38369Skarels * 10*38369Skarels * Copyright (c) 1988, 1989 by Van Jacobson, Lawrence Berkeley Laboratory 11*38369Skarels * All rights reserved. 12*38369Skarels * 13*38369Skarels * $Header: slcompress.h,v 1.3 89/03/19 18:10:38 van Locked $ 14*38369Skarels */ 15*38369Skarels 16*38369Skarels #define MAX_STATES 16 /* must be > 2 and < 256 */ 17*38369Skarels #define MAX_HDR MLEN /* XXX 4bsd-ism: should really be 128 */ 18*38369Skarels 19*38369Skarels /* 20*38369Skarels * Compressed packet format: 21*38369Skarels * 22*38369Skarels * The first octet contains the packet type (top 3 bits), TCP 23*38369Skarels * 'push' bit, and flags that indicate which of the 4 TCP sequence 24*38369Skarels * numbers have changed (bottom 5 bits). The next octet is a 25*38369Skarels * conversation number that associates a saved IP/TCP header with 26*38369Skarels * the compressed packet. The next two octets are the TCP checksum 27*38369Skarels * from the original datagram. The next 0 to 15 octets are 28*38369Skarels * sequence number changes, one change per bit set in the header 29*38369Skarels * (there may be no changes and there are two special cases where 30*38369Skarels * the receiver implicitly knows what changed -- see below). 31*38369Skarels * 32*38369Skarels * { Note that the ip version number field this overlays is 4 bits 33*38369Skarels * wide, and that we use type 4 to pass thru unaltered packets, 34*38369Skarels * type 5 to pass thru uncompressed packets that will be state 35*38369Skarels * information indexed by conversation. If msb (e.g type 8) is 36*38369Skarels * set, the other type bits are stolen to encode the difference 37*38369Skarels * information of a compressed TCP packet. -wfj } 38*38369Skarels * 39*38369Skarels * There are 5 numbers which can change (they are always inserted 40*38369Skarels * in the following order): TCP urgent pointer, window, 41*38369Skarels * acknowlegement, sequence number and IP ID. (The urgent pointer 42*38369Skarels * is different from the others in that its value is sent, not the 43*38369Skarels * change in value.) Since typical use of SLIP links is biased 44*38369Skarels * toward small packets (see comments on MTU/MSS below), changes 45*38369Skarels * use a variable length coding with one octet for numbers in the 46*38369Skarels * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the 47*38369Skarels * range 256 - 65535 or 0. (If the change in sequence number or 48*38369Skarels * ack is more than 65535, an uncompressed packet is sent.) 49*38369Skarels */ 50*38369Skarels 51*38369Skarels /* 52*38369Skarels * Packet types (must not conflict with IP protocol version) 53*38369Skarels * 54*38369Skarels * The top nibble of the first octet is the packet type. There are 55*38369Skarels * three possible types: IP (not proto TCP or tcp with one of the 56*38369Skarels * control flags set); uncompressed TCP (a normal IP/TCP packet but 57*38369Skarels * with the 8-bit protocol field replaced by an 8-bit connection id -- 58*38369Skarels * this type of packet syncs the sender & receiver); and compressed 59*38369Skarels * TCP (described above). 60*38369Skarels * 61*38369Skarels * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and 62*38369Skarels * is logically part of the 4-bit "changes" field that follows. Top 63*38369Skarels * three bits are actual packet type. For backward compatibility 64*38369Skarels * and in the interest of conserving bits, numbers are chosen so the 65*38369Skarels * IP protocol version number (4) which normally appears in this nibble 66*38369Skarels * means "IP packet". 67*38369Skarels */ 68*38369Skarels 69*38369Skarels /* packet types */ 70*38369Skarels #define TYPE_IP 0x40 71*38369Skarels #define TYPE_UNCOMPRESSED_TCP 0x50 72*38369Skarels #define TYPE_COMPRESSED_TCP 0x80 73*38369Skarels #define TYPE_ERROR 0x00 74*38369Skarels 75*38369Skarels /* Bits in first octet of compressed packet */ 76*38369Skarels #define NEW_C 0x40 /* flag bits for what changed in a packet */ 77*38369Skarels #define NEW_I 0x20 78*38369Skarels #define NEW_S 0x08 79*38369Skarels #define NEW_A 0x04 80*38369Skarels #define NEW_W 0x02 81*38369Skarels #define NEW_U 0x01 82*38369Skarels 83*38369Skarels /* reserved, special-case values of above */ 84*38369Skarels #define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ 85*38369Skarels #define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ 86*38369Skarels #define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) 87*38369Skarels 88*38369Skarels #define TCP_PUSH_BIT 0x10 89*38369Skarels 90*38369Skarels 91*38369Skarels /* 92*38369Skarels * "state" data for each active tcp conversation on the wire. This is 93*38369Skarels * basically a copy of the entire IP/TCP header from the last packet 94*38369Skarels * we saw from the conversation together with a small identifier 95*38369Skarels * the transmit & receive ends of the line use to locate saved header. 96*38369Skarels */ 97*38369Skarels struct cstate { 98*38369Skarels struct cstate *cs_next; /* next most recently used cstate (xmit only) */ 99*38369Skarels u_short cs_hlen; /* size of hdr (receive only) */ 100*38369Skarels u_char cs_id; /* connection # associated with this state */ 101*38369Skarels u_char cs_filler; 102*38369Skarels union { 103*38369Skarels char hdr[MAX_HDR]; 104*38369Skarels struct ip csu_ip; /* ip/tcp hdr from most recent packet */ 105*38369Skarels } u; 106*38369Skarels }; 107*38369Skarels #define cs_ip u.csu_ip 108*38369Skarels 109*38369Skarels /* 110*38369Skarels * all the state data for one serial line (we need one of these 111*38369Skarels * per line). 112*38369Skarels */ 113*38369Skarels struct slcompress { 114*38369Skarels struct cstate *last_cs; /* most recently used tstate */ 115*38369Skarels u_char last_recv; /* last rcvd conn. id */ 116*38369Skarels u_char last_xmit; /* last sent conn. id */ 117*38369Skarels u_short flags; 118*38369Skarels struct cstate tstate[MAX_STATES]; /* xmit connection states */ 119*38369Skarels struct cstate rstate[MAX_STATES]; /* receive connection states */ 120*38369Skarels }; 121*38369Skarels /* flag values */ 122*38369Skarels #define SLF_TOSS 1 /* tossing rcvd frames because of input err */ 123*38369Skarels 124*38369Skarels extern void sl_compress_init(/* struct slcompress * */); 125*38369Skarels extern u_char sl_compress_tcp(/* struct mbuf *, struct ip *, struct slcompress * */); 126*38369Skarels extern struct mbuf *sl_uncompress_tcp(/* struct mbuf *, u_char, struct slcompress * */); 127