⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vj.c

📁 PPP协议C语言源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -