home *** CD-ROM | disk | FTP | other *** search
- /*
- * The code in this file is derived from and very similar to the example
- * implementation provided in RFC 1144, and is therefore sort-of covered
- * by its copyright:
- *
- * Copyright (C) 1989 Regents of the University of California.
- *
- * modified for KA9Q Internet Software Package by
- * Katie Stevens (dkstevens@ucdavis.edu)
- * University of California, Davis
- * Computing Services
- * - 01-31-90 initial adaptation
- *
- * - Feb 1991 Bill_Simpson@um.cc.umich.edu
- * variable number of conversation slots
- * allow zero or one slots
- * separate routines
- * status display
- *
- * This adaptation (for cslip.device) by Olaf 'Rhialto' Seibert.
- */
-
- /*
- * Compressed packet format:
- *
- * The first octet contains the packet type (top 3 bits), TCP
- * 'push' bit, and flags that indicate which of the 4 TCP sequence
- * numbers have changed (bottom 5 bits). The next octet is a
- * conversation number that associates a saved IP/TCP header with
- * the compressed packet. The next two octets are the TCP checksum
- * from the original datagram. The next 0 to 15 octets are
- * sequence number changes, one change per bit set in the header
- * (there may be no changes and there are two special cases where
- * the receiver implicitly knows what changed -- see below).
- *
- * There are 5 numbers which can change (they are always inserted
- * in the following order): TCP urgent pointer, window,
- * acknowlegement, sequence number and IP ID. (The urgent pointer
- * is different from the others in that its value is sent, not the
- * change in value.) Since typical use of SLIP links is biased
- * toward small packets (see comments on MTU/MSS below), changes
- * use a variable length coding with one octet for numbers in the
- * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the
- * range 256 - 65535 or 0. (If the change in sequence number or
- * ack is more than 65535, an uncompressed packet is sent.)
- */
-
- /*
- * Packet types (must not conflict with IP protocol version)
- *
- * The top nibble of the first octet is the packet type. There are
- * three possible types: IP (not proto TCP or tcp with one of the
- * control flags set); uncompressed TCP (a normal IP/TCP packet but
- * with the 8-bit protocol field replaced by an 8-bit connection id --
- * this type of packet syncs the sender & receiver); and compressed
- * TCP (described above).
- *
- * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and
- * is logically part of the 4-bit "changes" field that follows. Top
- * three bits are actual packet type. For backward compatibility
- * and in the interest of conserving bits, numbers are chosen so the
- * IP protocol version number (4) which normally appears in this nibble
- * means "IP packet".
- */
-
- typedef unsigned long u_long;
- typedef unsigned int u_int;
- typedef unsigned short u_short;
- typedef unsigned char u_char;
-
- typedef unsigned short int16;
- typedef unsigned long int32;
-
- /* IP and TCP header format */
-
- struct ip_header {
- char v_ihl; /* Version + IP header length */
- #define IPVERSION 4
- char tos; /* Type of service */
- int16 length; /* Total length */
- int16 id; /* Identification */
- int16 fl_offs; /* Flags + fragment offset */
-
- #define F_OFFSET 0x1fff /* Offset field */
- #define DF 0x4000 /* Don't fragment flag */
- #define MF 0x2000 /* More Fragments flag */
-
- char ttl; /* Time to live */
- char protocol; /* Protocol */
- int16 checksum; /* Header checksum */
- int32 source; /* Source address */
- int32 dest; /* Destination address */
- };
-
- /* TCP segment header */
- struct tcp_header {
- int16 source; /* Source port */
- int16 dest; /* Destination port */
- int32 seq; /* Sequence number */
- int32 ack; /* Acknowledgment number */
- char offset; /* Data offset */
- char flags; /* Flags, data offset */
- #define DSHIFT 4 /* Data offset field */
- #define DMASK 0x0f /* Mask for normalized data offset field */
- #define URG 0x20 /* URGent flag */
- #define ACK 0x10 /* ACKnowledgment flag */
- #define PSH 0x08 /* PuSH flag */
- #define RST 0x04 /* ReSeT flag */
- #define SYN 0x02 /* SYNchronize flag */
- #define FIN 0x01 /* FINal flag */
- int16 wnd; /* Receiver flow control window */
- int16 checksum; /* Header + data checksum */
- int16 up; /* Urgent pointer */
- };
-
- /* IP protocol field values */
- #define TCP_PTCL 6 /* Transmission Control Protocol */
-
- #define lonibble(x) ((x) & 0x0F)
-
- struct mbuf {
- u_char *m_off; /* pointer to start of data */
- int m_len; /* length of data */
- };
- #define mtod(m, t) ((t)(m->m_off))
-
- /* Appendix 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 the first octet of the compressed packet
- */
-
- /* flag bits for what changed in a packet */
-
- #define NEW_C 0x40 /* Connection id */
- #define NEW_I 0x20 /* IP ID field (change != 1) */
- #define TCP_PUSH_BIT 0x10 /* TCP PUSH bit */
-
- #define NEW_S 0x08 /* Sequence number */
- #define NEW_A 0x04 /* Acknowledgement */
- #define NEW_W 0x02 /* Window size */
- #define NEW_U 0x01 /* Urgent pointer */
-
- /* 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 TCP/IP header from the last packet together
- * with a small identifier the transmit & receive ends of the line use to
- * locate the 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 {
- u_char csu_hdr[MAX_HDR];
- int32 csu_hdr4[1];
- struct ip_header 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
- #define cs_hdr4 slcs_u.csu_hdr4
-
- /*
- * all the state data for one serial line (we need one of these per line).
- */
- struct slcompress {
- struct cstate *tstate; /* transmit connection states (array)*/
- struct cstate *rstate; /* receive connection states (array)*/
-
- u_char tslot_limit; /* highest transmit slot id (0-l)*/
- u_char rslot_limit; /* highest receive slot id (0-l)*/
-
- struct cstate *last_cs; /* most recently used tstate */
- u_char last_recv; /* last received connection id */
- u_char last_xmit; /* last sent connection id */
- u_char flags;
-
- u_long sls_o_nontcp; /* outbound non-TCP packets */
- u_long sls_o_tcp; /* outbound TCP packets */
- u_long sls_o_uncompressed; /* outbound uncompressed packets */
- u_long sls_o_compressed;/* outbound compressed packets */
- u_long sls_o_searches; /* searches for connection state */
- u_long sls_o_misses; /* times couldn't find conn. state */
-
- u_long sls_i_ip; /* inbound non-TCP packets */
- u_long sls_i_uncompressed; /* inbound uncompressed packets */
- u_long sls_i_compressed;/* inbound compressed packets */
- u_long sls_i_error; /* inbound error packets */
- u_long sls_i_tossed; /* inbound packets tossed because of error */
-
- signed char on; /* ==SL_ON: on, >0: trycount, ==0: off */
- };
-
- /* last_xmit/last_recv initial value */
- #define NO_CID 255
-
- /* flag values */
- #define SLF_TOSS 1 /* tossing rcvd frames because of input err */
- #define SLF_ALLOWED 2 /* allow receiving compression */
- #define SLF_ON 4 /* use compression */
-
- /* optional trycount feature */
- #define TRYCOUNT 3 /* try 3 TCP_UNCOMPRESSED packets */
- #define SL_ON -1 /* use compression */
-
- /*
- * 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 the current 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_short)*cp++); \
- } \
- }
-
- #define DECODEU(f) { \
- if (*cp == 0) { \
- (f) = htons(((cp[1] << 8) | cp[2])); \
- cp += 3; \
- } else { \
- (f) = htons((u_short)*cp++); \
- } \
- }
-
- #define BCOPY(s, d, l) memcpy(d, s, l)
- #define BCMP(s, d, l) memcmp(d, s, l)
-
- #define htons(s) (s) /* on big-endian machines, that is */
- #define ntohs(s) (s)
- #define htonl(l) (l)
- #define ntohl(l) (l)
-
- /* Sana2 special stats values */
-
- #define S2SS_CSLIP_O_NONTCP ((S2WireType_CSLIP << 16) | 1)
- #define S2SS_CSLIP_O_TCP ((S2WireType_CSLIP << 16) | 2)
- #define S2SS_CSLIP_O_UNCOMPRESSED ((S2WireType_CSLIP << 16) | 3)
- #define S2SS_CSLIP_O_COMPRESSED ((S2WireType_CSLIP << 16) | 4)
- #define S2SS_CSLIP_O_SEARCHES ((S2WireType_CSLIP << 16) | 5)
- #define S2SS_CSLIP_O_MISSES ((S2WireType_CSLIP << 16) | 6)
-
- #define S2SS_CSLIP_I_IP ((S2WireType_CSLIP << 16) | 17)
- #define S2SS_CSLIP_I_UNCOMPRESSED ((S2WireType_CSLIP << 16) | 18)
- #define S2SS_CSLIP_I_COMPRESSED ((S2WireType_CSLIP << 16) | 19)
- #define S2SS_CSLIP_I_ERROR ((S2WireType_CSLIP << 16) | 20)
- #define S2SS_CSLIP_I_TOSSED ((S2WireType_CSLIP << 16) | 21)
-
- /* Prototypes for functions defined in cslip.c */
-
- u_char sl_compress_tcp(struct mbuf *m, struct slcompress *comp);
- void sl_xmit_error(struct slcompress *comp);
- struct mbuf *sl_uncompress_tcp(struct mbuf *m, u_int type, struct slcompress *comp);
- void sl_compress_init(struct slcompress *comp, int, int);
- void sl_compress_deinit(struct slcompress *comp);
-
-