1*4882a593Smuzhiyun #ifndef _SLHC_H 2*4882a593Smuzhiyun #define _SLHC_H 3*4882a593Smuzhiyun /* 4*4882a593Smuzhiyun * Definitions for tcp compression routines. 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * $Header: slcompress.h,v 1.10 89/12/31 08:53:02 van Exp $ 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * Copyright (c) 1989 Regents of the University of California. 9*4882a593Smuzhiyun * All rights reserved. 10*4882a593Smuzhiyun * 11*4882a593Smuzhiyun * Redistribution and use in source and binary forms are permitted 12*4882a593Smuzhiyun * provided that the above copyright notice and this paragraph are 13*4882a593Smuzhiyun * duplicated in all such forms and that any documentation, 14*4882a593Smuzhiyun * advertising materials, and other materials related to such 15*4882a593Smuzhiyun * distribution and use acknowledge that the software was developed 16*4882a593Smuzhiyun * by the University of California, Berkeley. The name of the 17*4882a593Smuzhiyun * University may not be used to endorse or promote products derived 18*4882a593Smuzhiyun * from this software without specific prior written permission. 19*4882a593Smuzhiyun * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 20*4882a593Smuzhiyun * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 21*4882a593Smuzhiyun * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22*4882a593Smuzhiyun * 23*4882a593Smuzhiyun * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: 24*4882a593Smuzhiyun * - Initial distribution. 25*4882a593Smuzhiyun * 26*4882a593Smuzhiyun * 27*4882a593Smuzhiyun * modified for KA9Q Internet Software Package by 28*4882a593Smuzhiyun * Katie Stevens (dkstevens@ucdavis.edu) 29*4882a593Smuzhiyun * University of California, Davis 30*4882a593Smuzhiyun * Computing Services 31*4882a593Smuzhiyun * - 01-31-90 initial adaptation 32*4882a593Smuzhiyun * 33*4882a593Smuzhiyun * - Feb 1991 Bill_Simpson@um.cc.umich.edu 34*4882a593Smuzhiyun * variable number of conversation slots 35*4882a593Smuzhiyun * allow zero or one slots 36*4882a593Smuzhiyun * separate routines 37*4882a593Smuzhiyun * status display 38*4882a593Smuzhiyun */ 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun /* 41*4882a593Smuzhiyun * Compressed packet format: 42*4882a593Smuzhiyun * 43*4882a593Smuzhiyun * The first octet contains the packet type (top 3 bits), TCP 44*4882a593Smuzhiyun * 'push' bit, and flags that indicate which of the 4 TCP sequence 45*4882a593Smuzhiyun * numbers have changed (bottom 5 bits). The next octet is a 46*4882a593Smuzhiyun * conversation number that associates a saved IP/TCP header with 47*4882a593Smuzhiyun * the compressed packet. The next two octets are the TCP checksum 48*4882a593Smuzhiyun * from the original datagram. The next 0 to 15 octets are 49*4882a593Smuzhiyun * sequence number changes, one change per bit set in the header 50*4882a593Smuzhiyun * (there may be no changes and there are two special cases where 51*4882a593Smuzhiyun * the receiver implicitly knows what changed -- see below). 52*4882a593Smuzhiyun * 53*4882a593Smuzhiyun * There are 5 numbers which can change (they are always inserted 54*4882a593Smuzhiyun * in the following order): TCP urgent pointer, window, 55*4882a593Smuzhiyun * acknowledgment, sequence number and IP ID. (The urgent pointer 56*4882a593Smuzhiyun * is different from the others in that its value is sent, not the 57*4882a593Smuzhiyun * change in value.) Since typical use of SLIP links is biased 58*4882a593Smuzhiyun * toward small packets (see comments on MTU/MSS below), changes 59*4882a593Smuzhiyun * use a variable length coding with one octet for numbers in the 60*4882a593Smuzhiyun * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the 61*4882a593Smuzhiyun * range 256 - 65535 or 0. (If the change in sequence number or 62*4882a593Smuzhiyun * ack is more than 65535, an uncompressed packet is sent.) 63*4882a593Smuzhiyun */ 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun /* 66*4882a593Smuzhiyun * Packet types (must not conflict with IP protocol version) 67*4882a593Smuzhiyun * 68*4882a593Smuzhiyun * The top nibble of the first octet is the packet type. There are 69*4882a593Smuzhiyun * three possible types: IP (not proto TCP or tcp with one of the 70*4882a593Smuzhiyun * control flags set); uncompressed TCP (a normal IP/TCP packet but 71*4882a593Smuzhiyun * with the 8-bit protocol field replaced by an 8-bit connection id -- 72*4882a593Smuzhiyun * this type of packet syncs the sender & receiver); and compressed 73*4882a593Smuzhiyun * TCP (described above). 74*4882a593Smuzhiyun * 75*4882a593Smuzhiyun * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and 76*4882a593Smuzhiyun * is logically part of the 4-bit "changes" field that follows. Top 77*4882a593Smuzhiyun * three bits are actual packet type. For backward compatibility 78*4882a593Smuzhiyun * and in the interest of conserving bits, numbers are chosen so the 79*4882a593Smuzhiyun * IP protocol version number (4) which normally appears in this nibble 80*4882a593Smuzhiyun * means "IP packet". 81*4882a593Smuzhiyun */ 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun #include <linux/ip.h> 85*4882a593Smuzhiyun #include <linux/tcp.h> 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun /* SLIP compression masks for len/vers byte */ 88*4882a593Smuzhiyun #define SL_TYPE_IP 0x40 89*4882a593Smuzhiyun #define SL_TYPE_UNCOMPRESSED_TCP 0x70 90*4882a593Smuzhiyun #define SL_TYPE_COMPRESSED_TCP 0x80 91*4882a593Smuzhiyun #define SL_TYPE_ERROR 0x00 92*4882a593Smuzhiyun 93*4882a593Smuzhiyun /* Bits in first octet of compressed packet */ 94*4882a593Smuzhiyun #define NEW_C 0x40 /* flag bits for what changed in a packet */ 95*4882a593Smuzhiyun #define NEW_I 0x20 96*4882a593Smuzhiyun #define NEW_S 0x08 97*4882a593Smuzhiyun #define NEW_A 0x04 98*4882a593Smuzhiyun #define NEW_W 0x02 99*4882a593Smuzhiyun #define NEW_U 0x01 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun /* reserved, special-case values of above */ 102*4882a593Smuzhiyun #define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ 103*4882a593Smuzhiyun #define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ 104*4882a593Smuzhiyun #define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun #define TCP_PUSH_BIT 0x10 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun /* 109*4882a593Smuzhiyun * data type and sizes conversion assumptions: 110*4882a593Smuzhiyun * 111*4882a593Smuzhiyun * VJ code KA9Q style generic 112*4882a593Smuzhiyun * u_char byte_t unsigned char 8 bits 113*4882a593Smuzhiyun * u_short int16 unsigned short 16 bits 114*4882a593Smuzhiyun * u_int int16 unsigned short 16 bits 115*4882a593Smuzhiyun * u_long unsigned long unsigned long 32 bits 116*4882a593Smuzhiyun * int int32 long 32 bits 117*4882a593Smuzhiyun */ 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun typedef __u8 byte_t; 120*4882a593Smuzhiyun typedef __u32 int32; 121*4882a593Smuzhiyun 122*4882a593Smuzhiyun /* 123*4882a593Smuzhiyun * "state" data for each active tcp conversation on the wire. This is 124*4882a593Smuzhiyun * basically a copy of the entire IP/TCP header from the last packet 125*4882a593Smuzhiyun * we saw from the conversation together with a small identifier 126*4882a593Smuzhiyun * the transmit & receive ends of the line use to locate saved header. 127*4882a593Smuzhiyun */ 128*4882a593Smuzhiyun struct cstate { 129*4882a593Smuzhiyun byte_t cs_this; /* connection id number (xmit) */ 130*4882a593Smuzhiyun bool initialized; /* true if initialized */ 131*4882a593Smuzhiyun struct cstate *next; /* next in ring (xmit) */ 132*4882a593Smuzhiyun struct iphdr cs_ip; /* ip/tcp hdr from most recent packet */ 133*4882a593Smuzhiyun struct tcphdr cs_tcp; 134*4882a593Smuzhiyun unsigned char cs_ipopt[64]; 135*4882a593Smuzhiyun unsigned char cs_tcpopt[64]; 136*4882a593Smuzhiyun int cs_hsize; 137*4882a593Smuzhiyun }; 138*4882a593Smuzhiyun #define NULLSLSTATE (struct cstate *)0 139*4882a593Smuzhiyun 140*4882a593Smuzhiyun /* 141*4882a593Smuzhiyun * all the state data for one serial line (we need one of these per line). 142*4882a593Smuzhiyun */ 143*4882a593Smuzhiyun struct slcompress { 144*4882a593Smuzhiyun struct cstate *tstate; /* transmit connection states (array)*/ 145*4882a593Smuzhiyun struct cstate *rstate; /* receive connection states (array)*/ 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun byte_t tslot_limit; /* highest transmit slot id (0-l)*/ 148*4882a593Smuzhiyun byte_t rslot_limit; /* highest receive slot id (0-l)*/ 149*4882a593Smuzhiyun 150*4882a593Smuzhiyun byte_t xmit_oldest; /* oldest xmit in ring */ 151*4882a593Smuzhiyun byte_t xmit_current; /* most recent xmit id */ 152*4882a593Smuzhiyun byte_t recv_current; /* most recent rcvd id */ 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun byte_t flags; 155*4882a593Smuzhiyun #define SLF_TOSS 0x01 /* tossing rcvd frames until id received */ 156*4882a593Smuzhiyun 157*4882a593Smuzhiyun int32 sls_o_nontcp; /* outbound non-TCP packets */ 158*4882a593Smuzhiyun int32 sls_o_tcp; /* outbound TCP packets */ 159*4882a593Smuzhiyun int32 sls_o_uncompressed; /* outbound uncompressed packets */ 160*4882a593Smuzhiyun int32 sls_o_compressed; /* outbound compressed packets */ 161*4882a593Smuzhiyun int32 sls_o_searches; /* searches for connection state */ 162*4882a593Smuzhiyun int32 sls_o_misses; /* times couldn't find conn. state */ 163*4882a593Smuzhiyun 164*4882a593Smuzhiyun int32 sls_i_uncompressed; /* inbound uncompressed packets */ 165*4882a593Smuzhiyun int32 sls_i_compressed; /* inbound compressed packets */ 166*4882a593Smuzhiyun int32 sls_i_error; /* inbound error packets */ 167*4882a593Smuzhiyun int32 sls_i_tossed; /* inbound packets tossed because of error */ 168*4882a593Smuzhiyun 169*4882a593Smuzhiyun int32 sls_i_runt; 170*4882a593Smuzhiyun int32 sls_i_badcheck; 171*4882a593Smuzhiyun }; 172*4882a593Smuzhiyun #define NULLSLCOMPR (struct slcompress *)0 173*4882a593Smuzhiyun 174*4882a593Smuzhiyun /* In slhc.c: */ 175*4882a593Smuzhiyun struct slcompress *slhc_init(int rslots, int tslots); 176*4882a593Smuzhiyun void slhc_free(struct slcompress *comp); 177*4882a593Smuzhiyun 178*4882a593Smuzhiyun int slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, 179*4882a593Smuzhiyun unsigned char *ocp, unsigned char **cpp, int compress_cid); 180*4882a593Smuzhiyun int slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize); 181*4882a593Smuzhiyun int slhc_remember(struct slcompress *comp, unsigned char *icp, int isize); 182*4882a593Smuzhiyun int slhc_toss(struct slcompress *comp); 183*4882a593Smuzhiyun 184*4882a593Smuzhiyun #endif /* _SLHC_H */ 185