?? vj.c
字號:
#include <net.h>
#include <local.h>
#include <support.h>
#include "ppp.h"
struct CONNstate {
struct CONNstate *next;
unsigned char id;
unsigned char null;
unsigned char TCPIPhdr[128];
};
struct LINEstate {
struct CONNstate *TXlast;
unsigned char RXid, TXid;
char flags;
struct CONNstate TXstate[MAXSLOTS];
struct CONNstate RXstate[MAXSLOTS];
};
#ifndef LITTLE
#define GETLONGp(w, ptr, offs) w.s[0] = ((unsigned short *)ptr)[offs/2], \
w.s[1] = ((unsigned short *)ptr)[1+(offs/2)]
#define PUTLONGp(w, ptr, offs) ((unsigned short *)ptr)[offs/2] = w.s[0], \
((unsigned short *)ptr)[1+(offs/2)] = w.s[1]
#else
#define GETLONGp(w, ptr, offs) w.c[0] = ptr[offs+3], w.c[1] = ptr[offs+2], \
w.c[2] = ptr[offs+1], w.c[3] = ptr[offs+0]
#define PUTLONGp(w, ptr, offs) ptr[offs+0] = w.c[3], ptr[offs+1] = w.c[2], \
ptr[offs+2] = w.c[1], ptr[offs+3] = w.c[0]
#endif
/* Routines to perform the Van Jacobsson compression and decompression. */
#define ENCODEZ(val, cp) \
if (val >= 256 || val == 0) \
*cp++ = 0, *cp++ = val>>8; \
*cp++ = val
#define ENCODE(val, cp) \
if (val >= 256) \
*cp++ = 0, *cp++ = val>>8; \
*cp++ = val
#define DECODE(val, cp) \
if ((val = *cp++) == 0) \
val = *cp++<<8, val |= *cp++
#define VERLEN 0
#define TLEN 1
#define FRID 2
#define FRAGM 3
#define TIME 8
#define PROT 9
#define CHKSUM 5
#define FROM 12
#define MYPORT 0
#define HERPORT 1
#define SEQNO 4
#define ACKNO 8
#define HDRLEN 12
#define FLAGS 13
#define WINDOW 7
#define T_CHKSUM 8
#define URGP 9
/* VJ Compression change tracking bits */
#define BITurg 0x01
#define BITwin 0x02
#define BITack 0x04
#define BITseq 0x08
#define BITpsh 0x10
#define BITid 0x20
#define BITcon 0x40
static struct LINEstate LINEstate[NNETS];
unsigned char RXslots[NNETS], TXslots[NNETS], TXixcomp[NNETS];
/*
** * * * * * *
** vjInit() Make VJ compression ready to handle packets
**
** void vjInit(int netno)
**
** PARAMETERS:
** (in) int netno The network interface number
**
** DESCRIPTION:
** This function will initialize all VJ data so that it is
** ready to handle network traffic. This function is called
** after PPP has finished all negotiations.
*/
void vjInit(int netno)
{
int i1;
struct LINEstate *LINEstatep;
LINEstatep = &LINEstate[netno];
memset((void *)LINEstatep, 0, sizeof(*LINEstatep));
LINEstatep->TXid = LINEstatep->RXid = 255;
for (i1=0; i1<MAXSLOTS; i1++) {
LINEstatep->TXstate[i1].next = &LINEstatep->TXstate[i1+1];
LINEstatep->TXstate[i1].id = (unsigned char)i1;
LINEstatep->RXstate[i1].next = &LINEstatep->RXstate[i1+1];
LINEstatep->RXstate[i1].id = (unsigned char)i1;
}
LINEstatep->TXstate[TXslots[netno]].next = &LINEstatep->TXstate[0];
LINEstatep->RXstate[RXslots[netno]].next = &LINEstatep->RXstate[0];
LINEstatep->TXlast = &LINEstatep->TXstate[TXslots[netno]];
}
/*
** * * * * * *
** vjWrite() Attempt to compress a frame
**
** int vjWrite(MESS *mess, MESS **mpp)
**
** PARAMETERS:
** (in) MESS *mess A pointer to a frame to format out of
** (in/out) MESS **mpp The value result formatted frame pointer
**
** RETURNS:
** PROTip No compression possible
** PROTcomp Packet successfully compressed
** PROTuncomp First packet in compressed sequence
**
** DESCRIPTION:
** This function will input a PPP frame and attempt to compress it
** using Van Jacobson compression.
**
** * * * * * *
**
** MODIFICATION HISTORY:
**
** 15-JUL-1999 BSK Chg: Taken from ppp.c
**
** * * * * * *
*/
int vjWrite(MESS *mess, MESS **mpp)
{
int i1, netno;
unsigned int hlen, ihlen, thlen, us1;
unsigned char changes[16], changeflag, *cp;
unsigned long deltaS, deltaA;
unsigned char *ihdrp, *ihdrp2;
unsigned char *thdrp, *thdrp2;
MESS *mp2;
struct LINEstate *LINEstatep;
struct CONNstate *CONNstatep, *CONNstatep2;
union {unsigned char c[4]; short s[2]; long l;} UL3, UL4;
netno = mess->netno; /* Network connection for message */
/* Point to IP header */
ihdrp = (unsigned char *)mess + MESSH_SZ + LHDRSZ;
/*
** Check to see if compression is required. Will not do compresion if:
** Protocol is not TCP (6)
** Message is a fragment
** ACK is not set
** SYN, FIN, RST is set
*/
if (ihdrp[PROT] != 6 || /* Not TCP */
((unsigned short *)ihdrp)[FRAGM] & NC2(0x3fff)) /* IP fragment*/
goto nocompr;
ihlen = (ihdrp[VERLEN] & 0xf) * 4; /* length of data */
thdrp = (unsigned char *)ihdrp + ihlen; /* point to TCP header */
if ((thdrp[FLAGS] & 0x17) != 0x10) /* Flags: ACK ~set, FIN,SYN,RST set */
goto nocompr;
thlen = (thdrp[HDRLEN] >> 4) << 2; /* total header size */
hlen = ihlen + thlen;
/* Find or create the connection state by scanning the linked list. */
LINEstatep = &LINEstate[netno];
CONNstatep = LINEstatep->TXlast;
for (;;) {
CONNstatep2 = CONNstatep;
CONNstatep = CONNstatep->next;
ihdrp2 = (unsigned char *)CONNstatep->TCPIPhdr;
thdrp2 = (unsigned char *)(CONNstatep->TCPIPhdr +
(ihdrp2[VERLEN] & 0xf) * 4);
if (memcmp(CONNstatep->TCPIPhdr+12, ihdrp+FROM, 12) == 0 &&
((unsigned short *)thdrp)[MYPORT] ==
((unsigned short *)thdrp2)[MYPORT] &&
((unsigned short *)thdrp)[HERPORT] ==
((unsigned short *)thdrp2)[HERPORT] )
goto found;
if (CONNstatep == LINEstatep->TXlast)
break;
}
LINEstatep->TXlast = CONNstatep2;
goto uncompr;
/* here we found an existing entry and make it fresh */
found:
if (CONNstatep == LINEstatep->TXlast)
LINEstatep->TXlast = CONNstatep2;
else {
CONNstatep2->next = CONNstatep->next;
CONNstatep->next = LINEstatep->TXlast->next;
LINEstatep->TXlast->next = CONNstatep;
}
/* Check for changes not handled by the compression */
if (((unsigned short *)ihdrp)[VERLEN] != ((unsigned short *)ihdrp2)[VERLEN])
goto uncompr;
if (((unsigned short *)ihdrp)[FRAGM] != ((unsigned short *)ihdrp2)[FRAGM])
goto uncompr;
if (ihdrp[TIME] != ihdrp2[TIME])
goto uncompr;
if (thdrp[HDRLEN] != thdrp2[HDRLEN])
goto uncompr;
if (((unsigned short *)thdrp)[URGP] !=
((unsigned short *)thdrp2)[URGP] && (thdrp[FLAGS] & S_URG) == 0)
goto uncompr;
if (thlen > 20)
if (memcmp((char *)thdrp+20, (char *)thdrp2+20, thlen-20))
goto uncompr;
/* Encode the header changes */
cp = changes; /* point to change list */
changeflag = 0;
if (thdrp[FLAGS] & S_URG) { /* urgent bit set */
changeflag |= BITurg; /* 0x01 */
us1 = NC2(((unsigned short *)thdrp)[URGP]);
ENCODEZ(us1, cp);
}
/* Window change */
if ((us1 = NC2(((unsigned short *)thdrp)[WINDOW]) -
NC2(((unsigned short *)thdrp2)[WINDOW])) != 0) {
changeflag |= BITwin; /* 0x02 */
ENCODE(us1, cp);
}
/* Acknowledge number chagned */
GETLONGp(UL3, thdrp, ACKNO);
GETLONGp(UL4, thdrp2, ACKNO);
if ((deltaA = UL3.l - UL4.l) != 0) {
if (deltaA > 0xffff)
goto uncompr;
us1 = (unsigned short)deltaA;
changeflag |= BITack; /* 0x04 */
ENCODE(us1, cp);
}
/* Sequence number changed */
GETLONGp(UL3, thdrp, SEQNO);
GETLONGp(UL4, thdrp2, SEQNO);
if ((deltaS = UL3.l - UL4.l) != 0) {
if (deltaS > 0xffff)
goto uncompr;
us1 = (unsigned short)deltaS;
changeflag |= BITseq; /* 0x08 */
ENCODE(us1, cp);
}
/* Analyze the nature of the changes */
switch (changeflag) {
/* No changes: must be data following ACK, or we don't compress */
case 0:
if (((unsigned short *)ihdrp)[TLEN] !=
((unsigned short *)ihdrp2)[TLEN] &&
((unsigned short *)ihdrp2)[TLEN] == NC2(hlen))
break;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -