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

📄 compress.c

📁 PPPoE协议在Psos中的实现源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* @(#) pSOSystem/PowerPC V2.1.2: drivers/slip/compress.c 1.4 95/07/25 13:53:25 */
/************************************************************************/
/*                                                                      */
/*   MODULE: slcompress.c                                               */
/*   PRODUCT: pNA+                                                      */
/*   PURPOSE: Van Jacobson header compression                           */
/*   DATE: 93/12/01                                                     */
/*                                                                      */
/*----------------------------------------------------------------------*/
/*                                                                      */
/*              Copyright 1993, Integrated Systems Inc.                 */
/*                      ALL RIGHTS RESERVED                             */
/*                                                                      */
/*   This computer program is the property of Integrated Systems Inc.   */
/*   Santa Clara, California, U.S.A. and may not be copied              */
/*   in any form or by any means, whether in part or in whole,          */
/*   except under license expressly granted by Integrated Systems Inc.  */
/*                                                                      */
/*   All copies of this program, whether in part or in whole, and       */
/*   whether modified or not, must display this and all other           */
/*   embedded copyright and ownership notices in full.                  */
/*                                                                      */
/*----------------------------------------------------------------------*/
/*                                                                      */
/* Global Procedures:                                                   */
/*                                                                      */
/*                                                                      */
/************************************************************************/
/*
 * Routines to compress and uncompess tcp packets (for transmission
 * over low speed serial lines.
 *
 * Copyright (c) 1989, 1991 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.
 *
 *  Van Jacobson (van@ee.lbl.gov), Dec 31, 1989:
 *  - Initial distribution.
 */
#ifndef lint
static char rcsid[] =
    "@(#) $Header: compress.c,v 1.1 97/07/23 10:26:40 kapil Exp $ (LBL)";
#endif

#include <string.h>

#include "bsp.h"
#include "pna.h"
#include "ppp.h"

#include "compress.h"

#ifndef SL_NO_STATS
#define INCR(counter) (++comp->counter)
#else
#define INCR(counter) ((void) 0)
#endif

/*#define BCMP(p1, p2, n) bcmp((char *)(p1), (char *)(p2), (int)(n))*/
/*#define BCOPY(p1, p2, n) slbcopy((U_CHAR *)(p1), (U_CHAR *)(p2), (int)(n))*/
/*#ifndef KERNEL
#define ovbcopy slbcopy
#endif*/

#define BCMP(p0, p1, n)    memcmp  (p0, p1, n)
#define BCOPY(p0, p1, n)   memmove (p1, p0, n)
#define ovbcopy(p0, p1, n) memmove (p1, p0, n)

/*
 * sizeof(word) MUST BE A POWER OF TWO
 * SO THAT wmask BELOW IS ALL ONES
 */
typedef int word;       /* "word" used for optimal copy speed */
#define wsize   sizeof(word)
#define wmask   (wsize - 1)

/*----------------------------------------------------------------------*/
/* prototypes                                                           */
/*----------------------------------------------------------------------*/
/*static int bcmp(char *b1, char *b2, int n);*/
/*extern void bzero(char *cp, long size);*/

#if 0
/************************************************************************/
/*   slbcopy: BSD style byte copying                                    */
/*  INPUTS: b1 - source, b2 - dest, n - length                          */
/* RETURNS:                                                             */
/* OUTPUTS:                                                             */
/* NOTE(S): Handles overlap.                                            */
/************************************************************************/
void
slbcopy(U_CHAR *src0, U_CHAR *dst0, int length)
{
    register U_CHAR *dst = dst0;
    register const U_CHAR *src = src0;
    register int t;

    if (length == 0 || dst == src)      /* nothing to do */
        return;

    /*
     * Macros: loop-t-times; and loop-t-times, t>0
     */
#define TLOOP(s) if (t) TLOOP1(s)
#define TLOOP1(s) do { s; } while (--t)

    if ((unsigned long)dst < (unsigned long)src) {
        /*
         * Copy forward.
         */
        t = (int)src;   /* only need low bits */
        if ((t | (int)dst) & wmask) {
            /*
             * Try to align operands.  This cannot be done
             * unless the low bits match.
             */
            if ((t ^ (int)dst) & wmask || length < wsize)
                t = length;
            else
                t = wsize - (t & wmask);
            length -= t;
            TLOOP1(*dst++ = *src++);
        }
        /*
         * Copy whole words, then mop up any trailing bytes.
         */
        t = length / wsize;
        TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
        t = length & wmask;
        TLOOP(*dst++ = *src++);
    } else {
        /*
         * Copy backwards.  Otherwise essentially the same.
         * Alignment works as before, except that it takes
         * (t&wmask) bytes to align, not wsize-(t&wmask).
         */
        src += length;
        dst += length;
        t = (int)src;
        if ((t | (int)dst) & wmask) {
            if ((t ^ (int)dst) & wmask || length <= wsize)
                t = length;
            else
                t &= wmask;
            length -= t;
            TLOOP1(*--dst = *--src);
        }
        t = length / wsize;
        TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
        t = length & wmask;
        TLOOP(*--dst = *--src);
    }
}
#endif

#if 0
/************************************************************************/
/*   bcmp : BSD-style string comparison (of same length)                */
/*  INPUTS: b1 - string1; b2 - string2; n - size                        */
/* RETURNS:                                                             */
/* OUTPUTS: 0 - identical; nonzero otherwise                            */
/* NOTE(S):                                                             */
/************************************************************************/
static int bcmp(char *b1, char *b2, int n)
{
if (!n) return 0;
while (n--)
  {
  if (*b1++ != *b2++) return 1;
  }
return 0;
}
#endif

void
sl_compress_init(struct slcompress *comp)
{
    register U_INT i;
    register struct cstate *tstate = comp->tstate;

    bzero((char *)comp, sizeof(*comp));
    for (i = MAX_STATES - 1; i > 0; --i) {
        tstate[i].cs_id = i;
        tstate[i].cs_next = &tstate[i - 1];
    }
    tstate[0].cs_next = &tstate[MAX_STATES - 1];
    tstate[0].cs_id = 0;
    comp->last_cs = &tstate[0];
    comp->last_recv = 255;
    comp->last_xmit = 255;
    comp->flags = SLF_TOSS;
}


/* ENCODE encodes a number that is known to be non-zero.  ENCODEZ
 * checks for zero (since 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); \
    } \
}

#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_LONG)*cp++); \
    } \
}

#define DECODEU(f) { \
    if (*cp == 0) {\
        (f) = htons((cp[1] << 8) | cp[2]); \
        cp += 3; \
    } else { \
        (f) = htons((U_LONG)*cp++); \
    } \
}


U_CHAR
sl_compress_tcp(struct mbuf *m, struct ip *ip, struct slcompress *comp,
                int compress_cid)
{
    register struct cstate *cs = comp->last_cs->cs_next;
    register U_INT hlen = ip->ip_hl;
    register struct tcphdr *oth;
    register struct tcphdr *th;
    register U_INT deltaS, deltaA;
    register U_INT changes = 0;
    U_CHAR new_seq[16];
    register U_CHAR *cp = new_seq;

    /*
     * Bail if this is an IP fragment or if the TCP packet isn't
     * `compressible' (i.e., ACK isn't set or some other control bit is
     * set).  (We assume that the caller has already made sure the
     * packet is IP proto TCP).
     */
    if ((ip->ip_off & htons(0x3fff)) || m->m_len < 40)
        return (TYPE_IP);

    th = (struct tcphdr *)&((int *)ip)[hlen];
    if ((th->th_flags & (TH_SYN|TH_FIN|TH_RST|TH_ACK)) != TH_ACK)
        return (TYPE_IP);
    /*
     * Packet is compressible -- we're going to send either a
     * COMPRESSED_TCP or UNCOMPRESSED_TCP packet.  Either way we need
     * to locate (or create) the connection state.  Special case the
     * most recently used connection since it's most likely to be used
     * again & we don't have to do any reordering if it's used.
     */
    INCR(sls_packets);
    if (ip->ip_src.s_addr != cs->cs_ip.ip_src.s_addr ||
        ip->ip_dst.s_addr != cs->cs_ip.ip_dst.s_addr ||
        *(int *)th != ((int *)&cs->cs_ip)[cs->cs_ip.ip_hl]) {
        /*
         * Wasn't the first -- search for it.
         *
         * States are kept in a circularly linked list with
         * last_cs pointing to the end of the list.  The
         * list is kept in lru order by moving a state to the
         * head of the list whenever it is referenced.  Since
         * the list is short and, empirically, the connection
         * we want is almost always near the front, we locate
         * states via linear search.  If we don't find a state
         * for the datagram, the oldest state is (re-)used.
         */
        register struct cstate *lcs;
        register struct cstate *lastcs = comp->last_cs;

        do {
            lcs = cs; cs = cs->cs_next;
            INCR(sls_searches);
            if (ip->ip_src.s_addr == cs->cs_ip.ip_src.s_addr
                && ip->ip_dst.s_addr == cs->cs_ip.ip_dst.s_addr
                && *(int *)th == ((int *)&cs->cs_ip)[cs->cs_ip.ip_hl])
                goto found;
        } while (cs != lastcs);

        /*
         * Didn't find it -- re-use oldest cstate.  Send an
         * uncompressed packet that tells the other side what
         * connection number we're using for this conversation.
         * Note that since the state list is circular, the oldest
         * state points to the newest and we only need to set
         * last_cs to update the lru linkage.
         */
        INCR(sls_misses);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -