257 lines
7 KiB
C
257 lines
7 KiB
C
|
#ifndef _VJSLIP_
|
||
|
#define _VJSLIP_
|
||
|
|
||
|
/*
|
||
|
* Copyright (c) 1989 Regents of the University of California.
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms are
|
||
|
* permitted provided that the above copyright notice and this
|
||
|
* paragraph are duplicated in all such forms and that any
|
||
|
* documentation, advertising materials, and other materials
|
||
|
* related to such distribution and use acknowledge that the
|
||
|
* software was developed by the University of California,
|
||
|
* Berkeley. The name of the University may not be used to
|
||
|
* endorse or promote products derived from this software
|
||
|
* without specific prior written permission.
|
||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS
|
||
|
* OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE
|
||
|
* IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A
|
||
|
* PARTICULAR PURPOSE.
|
||
|
*/
|
||
|
|
||
|
|
||
|
// A.1 Definitions and State Data
|
||
|
|
||
|
#define MAX_VJ_STATES 16 /* must be >2 and <255 */
|
||
|
#define MAX_HDR 128 /* max TCP+IP hdr length (by protocol def) */
|
||
|
|
||
|
|
||
|
//
|
||
|
// NT is little endian, so we follow these rules
|
||
|
//
|
||
|
#if (defined(_M_IX86) && (_MSC_FULL_VER > 13009037)) || ((defined(_M_AMD64) || defined(_M_IA64)) && (_MSC_FULL_VER > 13009175))
|
||
|
#define ntohs(x) _byteswap_ushort((USHORT)(x))
|
||
|
#define ntohl(x) _byteswap_ulong((ULONG)(x))
|
||
|
#else
|
||
|
#define ntohs(x) (USHORT)( ((x) >> 8) + (((x) & 0xFF) << 8) )
|
||
|
|
||
|
#define ntohl(x) (ULONG) ( ((x) >> 24) + (((x) & 0xFF0000) >> 8) +\
|
||
|
(((x) & 0xFF00) << 8) + (((x) & 0xFF) << 24) )
|
||
|
#endif
|
||
|
|
||
|
#define htons(x) ntohs(x)
|
||
|
#define htonl(x) ntohl(x)
|
||
|
|
||
|
|
||
|
/* 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) */
|
||
|
USHORT cs_hlen; /* size of hdr (receive only) */
|
||
|
UCHAR cs_id; /* connection # associated with this state */
|
||
|
UCHAR cs_filler;
|
||
|
union {
|
||
|
UCHAR hdr[MAX_HDR];
|
||
|
struct ip_v4 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).
|
||
|
*/
|
||
|
typedef struct slcompress slcompress;
|
||
|
|
||
|
struct slcompress {
|
||
|
struct cstate *last_cs; /* most recently used tstate */
|
||
|
UCHAR last_recv; /* last rcvd conn. id */
|
||
|
UCHAR last_xmit; /* last sent conn. id */
|
||
|
USHORT flags;
|
||
|
UCHAR MaxStates;
|
||
|
//
|
||
|
// Some Statistics
|
||
|
//
|
||
|
ULONG OutPackets;
|
||
|
ULONG OutCompressed;
|
||
|
ULONG OutSearches;
|
||
|
ULONG OutMisses;
|
||
|
ULONG InUncompressed;
|
||
|
ULONG InCompressed;
|
||
|
ULONG InErrors;
|
||
|
ULONG InTossed;
|
||
|
|
||
|
struct cstate tstate[MAX_VJ_STATES]; /* xmit connection states */
|
||
|
struct cstate rstate[MAX_VJ_STATES]; /* receive connection states */
|
||
|
};
|
||
|
|
||
|
struct mbuf {
|
||
|
PUCHAR m_off; // pointer to start of data
|
||
|
UINT m_len; // length of data
|
||
|
};
|
||
|
|
||
|
#define mtod(m,t) ((t)(m->m_off))
|
||
|
|
||
|
/* 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 ((USHORT)(n) >= 256) { \
|
||
|
*cp++ = 0; \
|
||
|
cp[1] = (UCHAR)(n); \
|
||
|
cp[0] = (UCHAR)((n) >> 8); \
|
||
|
cp += 2; \
|
||
|
} else { \
|
||
|
*cp++ = (UCHAR)(n); \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
#define ENCODEZ(n) { \
|
||
|
if ((USHORT)(n) >= 256 || (USHORT)(n) == 0) { \
|
||
|
*cp++ = 0; \
|
||
|
cp[1] = (UCHAR)(n); \
|
||
|
cp[0] = (UCHAR)((n) >> 8); \
|
||
|
cp += 2; \
|
||
|
} else { \
|
||
|
*cp++ = (UCHAR)(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) { \
|
||
|
ULONG _x_ = ntohl(f); \
|
||
|
if (*cp == 0) {\
|
||
|
_x_ += ((cp[1] << 8) + cp[2]); \
|
||
|
(f) = htonl(_x_); \
|
||
|
cp += 3; \
|
||
|
} else { \
|
||
|
_x_ += *cp; \
|
||
|
(f) = htonl(_x_); \
|
||
|
cp++; \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
#define DECODES(f) { \
|
||
|
USHORT _x_= ntohs(f); \
|
||
|
if (*cp == 0) {\
|
||
|
_x_ += ((cp[1] << 8) + cp[2]); \
|
||
|
(f) = htons(_x_); \
|
||
|
cp += 3; \
|
||
|
} else { \
|
||
|
_x_ += *cp; \
|
||
|
(f) = htons(_x_); \
|
||
|
cp++; \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
#define DECODEU(f) { \
|
||
|
USHORT _x_; \
|
||
|
if (*cp == 0) {\
|
||
|
_x_=(cp[1] << 8) + cp[2]; \
|
||
|
(f) = htons(_x_); \
|
||
|
cp += 3; \
|
||
|
} else { \
|
||
|
_x_=*cp; \
|
||
|
(f) = htons(_x_); \
|
||
|
cp++; \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
typedef UCHAR UNALIGNED * PUUCHAR;
|
||
|
|
||
|
|
||
|
UCHAR
|
||
|
sl_compress_tcp(
|
||
|
PUUCHAR UNALIGNED *m_off, // Frame start (points to IP header)
|
||
|
PULONG m_len, // Length of entire frame
|
||
|
PULONG precomph_len, // Length of tcp/ip header pre-comp
|
||
|
PULONG postcomph_len, // Length of tcp/ip header post-comp
|
||
|
struct slcompress *comp, // Compression struct for this link
|
||
|
ULONG compress_cid); // Compress connection id boolean
|
||
|
|
||
|
//LONG
|
||
|
//sl_uncompress_tcp(
|
||
|
// PUUCHAR UNALIGNED *bufp,
|
||
|
// LONG len,
|
||
|
// UCHAR type,
|
||
|
// struct slcompress *comp);
|
||
|
LONG
|
||
|
sl_uncompress_tcp(
|
||
|
PUUCHAR UNALIGNED *InBuffer,
|
||
|
PLONG InLength,
|
||
|
UCHAR UNALIGNED *OutBuffer,
|
||
|
PLONG OutLength,
|
||
|
UCHAR type,
|
||
|
struct slcompress *comp
|
||
|
);
|
||
|
|
||
|
NDIS_STATUS
|
||
|
sl_compress_init(
|
||
|
struct slcompress **comp,
|
||
|
UCHAR MaxStates);
|
||
|
|
||
|
VOID
|
||
|
sl_compress_terminate(
|
||
|
struct slcompress **comp
|
||
|
);
|
||
|
|
||
|
#endif // _VJSLIP_
|
||
|
|