Annotation of embedaddon/mpd/src/ccp_pred1.c, revision 1.1

1.1     ! misho       1: 
        !             2: /*
        !             3:  * ccp_pred1.c
        !             4:  *
        !             5:  * Rewritten by Alexander Motin <mav@FreeBSD.org>
        !             6:  * Written by Archie Cobbs <archie@freebsd.org>
        !             7:  * Copyright (c) 1995-1999 Whistle Communications, Inc. All rights reserved.
        !             8:  * See ``COPYRIGHT.whistle''
        !             9:  */
        !            10: 
        !            11: /*
        !            12:  * pred1.c
        !            13:  *
        !            14:  * Test program for Dave Rand's rendition of the predictor algorithm
        !            15:  *
        !            16:  * Updated by: archie@freebsd.org (Archie Cobbs)
        !            17:  * Updated by: iand@labtam.labtam.oz.au (Ian Donaldson)
        !            18:  * Updated by: Carsten Bormann <cabo@cs.tu-berlin.de>
        !            19:  * Original  : Dave Rand <dlr@bungi.com>/<dave_rand@novell.com>
        !            20:  */
        !            21: 
        !            22: #include "ppp.h"
        !            23: #include "ccp.h"
        !            24: #include "util.h"
        !            25: #include "ngfunc.h"
        !            26: 
        !            27: #ifdef USE_NG_PRED1
        !            28: #include <netgraph/ng_message.h>
        !            29: #include <netgraph.h>
        !            30: #endif
        !            31: 
        !            32: /*
        !            33:  * DEFINITIONS
        !            34:  */
        !            35: 
        !            36:   #define PRED1_DECOMP_BUF_SIZE        4096
        !            37: 
        !            38:   #define PRED1_MAX_BLOWUP(n)  ((n) * 9 / 8 + 24)
        !            39: 
        !            40: /*
        !            41:  * The following hash code is the heart of the algorithm:
        !            42:  * It builds a sliding hash sum of the previous 3-and-a-bit characters
        !            43:  * which will be used to index the guess table.
        !            44:  * A better hash function would result in additional compression,
        !            45:  * at the expense of time.
        !            46:  */
        !            47: 
        !            48:   #define IHASH(x) p->iHash = (p->iHash << 4) ^ (x)
        !            49:   #define OHASH(x) p->oHash = (p->oHash << 4) ^ (x)
        !            50: 
        !            51: /*
        !            52:  * INTERNAL FUNCTIONS
        !            53:  */
        !            54: 
        !            55:   static int   Pred1Init(Bund b, int direction);
        !            56:   static void  Pred1Cleanup(Bund b, int direction);
        !            57: #ifndef USE_NG_PRED1
        !            58:   static Mbuf  Pred1Compress(Bund b, Mbuf plain);
        !            59:   static Mbuf  Pred1Decompress(Bund b, Mbuf comp);
        !            60: #endif
        !            61: 
        !            62:   static u_char        *Pred1BuildConfigReq(Bund b, u_char *cp, int *ok);
        !            63:   static void   Pred1DecodeConfigReq(Fsm fp, FsmOption opt, int mode);
        !            64:   static Mbuf  Pred1RecvResetReq(Bund b, int id, Mbuf bp, int *noAck);
        !            65:   static Mbuf  Pred1SendResetReq(Bund b);
        !            66:   static void  Pred1RecvResetAck(Bund b, int id, Mbuf bp);
        !            67:   static int    Pred1Negotiated(Bund b, int xmit);
        !            68:   static int    Pred1SubtractBloat(Bund b, int size);
        !            69:   static int    Pred1Stat(Context ctx, int dir);
        !            70: 
        !            71: #ifndef USE_NG_PRED1
        !            72:   static int   Compress(Bund b, u_char *source, u_char *dest, int len);
        !            73:   static int   Decompress(Bund b, u_char *source, u_char *dest, int slen, int dlen);
        !            74:   static void  SyncTable(Bund b, u_char *source, u_char *dest, int len);
        !            75: #endif
        !            76: 
        !            77: /*
        !            78:  * GLOBAL VARIABLES
        !            79:  */
        !            80: 
        !            81:   const struct comptype        gCompPred1Info =
        !            82:   {
        !            83:     "pred1",
        !            84:     CCP_TY_PRED1,
        !            85:     1,
        !            86:     Pred1Init,
        !            87:     NULL,
        !            88:     NULL,
        !            89:     NULL,
        !            90:     Pred1SubtractBloat,
        !            91:     Pred1Cleanup,
        !            92:     Pred1BuildConfigReq,
        !            93:     Pred1DecodeConfigReq,
        !            94:     Pred1SendResetReq,
        !            95:     Pred1RecvResetReq,
        !            96:     Pred1RecvResetAck,
        !            97:     Pred1Negotiated,
        !            98:     Pred1Stat,
        !            99: #ifndef USE_NG_PRED1
        !           100:     Pred1Compress,
        !           101:     Pred1Decompress,
        !           102: #else
        !           103:     NULL,
        !           104:     NULL,
        !           105: #endif
        !           106:   };
        !           107: 
        !           108: /*
        !           109:  * Pred1Init()
        !           110:  */
        !           111: 
        !           112: static int
        !           113: Pred1Init(Bund b, int dir)
        !           114: {
        !           115: #ifndef USE_NG_PRED1
        !           116:     Pred1Info  p = &b->ccp.pred1;
        !           117: 
        !           118:     if (dir == COMP_DIR_XMIT) {
        !           119:        p->oHash = 0;
        !           120:        p->OutputGuessTable = Malloc(MB_COMP, PRED1_TABLE_SIZE);
        !           121:     } else {
        !           122:        p->iHash = 0;
        !           123:        p->InputGuessTable = Malloc(MB_COMP, PRED1_TABLE_SIZE);
        !           124:     }
        !           125: #else
        !           126:     struct ngm_mkpeer  mp;
        !           127:     struct ng_pred1_config conf;
        !           128:     const char         *pred1hook, *ppphook;
        !           129:     char               path[NG_PATHSIZ];
        !           130:     ng_ID_t             id;
        !           131: 
        !           132:     memset(&conf, 0, sizeof(conf));
        !           133:     conf.enable = 1;
        !           134:     if (dir == COMP_DIR_XMIT) {
        !           135:         ppphook = NG_PPP_HOOK_COMPRESS;
        !           136:         pred1hook = NG_PRED1_HOOK_COMP;
        !           137:     } else {
        !           138:         ppphook = NG_PPP_HOOK_DECOMPRESS;
        !           139:         pred1hook = NG_PRED1_HOOK_DECOMP;
        !           140:     }
        !           141: 
        !           142:     /* Attach a new PRED1 node to the PPP node */
        !           143:     snprintf(path, sizeof(path), "[%x]:", b->nodeID);
        !           144:     strcpy(mp.type, NG_PRED1_NODE_TYPE);
        !           145:     strcpy(mp.ourhook, ppphook);
        !           146:     strcpy(mp.peerhook, pred1hook);
        !           147:     if (NgSendMsg(gCcpCsock, path,
        !           148:            NGM_GENERIC_COOKIE, NGM_MKPEER, &mp, sizeof(mp)) < 0) {
        !           149:        Perror("[%s] can't create %s node", b->name, mp.type);
        !           150:        return(-1);
        !           151:     }
        !           152: 
        !           153:     strlcat(path, ppphook, sizeof(path));
        !           154: 
        !           155:     id = NgGetNodeID(-1, path);
        !           156:     if (dir == COMP_DIR_XMIT) {
        !           157:        b->ccp.comp_node_id = id;
        !           158:     } else {
        !           159:        b->ccp.decomp_node_id = id;
        !           160:     }
        !           161: 
        !           162:     /* Configure PRED1 node */
        !           163:     snprintf(path, sizeof(path), "[%x]:", id);
        !           164:     if (NgSendMsg(gCcpCsock, path,
        !           165:            NGM_PRED1_COOKIE, NGM_PRED1_CONFIG, &conf, sizeof(conf)) < 0) {
        !           166:        Perror("[%s] can't config %s node at %s",
        !           167:            b->name, NG_PRED1_NODE_TYPE, path);
        !           168:        NgFuncShutdownNode(gCcpCsock, b->name, path);
        !           169:        return(-1);
        !           170:     }
        !           171: #endif
        !           172:     return 0;
        !           173: }
        !           174: 
        !           175: /*
        !           176:  * Pred1Cleanup()
        !           177:  */
        !           178: 
        !           179: void
        !           180: Pred1Cleanup(Bund b, int dir)
        !           181: {
        !           182: #ifndef USE_NG_PRED1
        !           183:     Pred1Info  p = &b->ccp.pred1;
        !           184: 
        !           185:     if (dir == COMP_DIR_XMIT) {
        !           186:        assert(p->OutputGuessTable);
        !           187:        Freee(p->OutputGuessTable);
        !           188:        p->OutputGuessTable = NULL;
        !           189:        memset(&p->xmit_stats, 0, sizeof(p->xmit_stats));
        !           190:     } else {
        !           191:        assert(p->InputGuessTable);
        !           192:        Freee(p->InputGuessTable);
        !           193:        p->InputGuessTable = NULL;
        !           194:        memset(&p->recv_stats, 0, sizeof(p->recv_stats));
        !           195:     }
        !           196: #else
        !           197:     char               path[NG_PATHSIZ];
        !           198: 
        !           199:     /* Remove node */
        !           200:     if (dir == COMP_DIR_XMIT) {
        !           201:        snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
        !           202:        b->ccp.comp_node_id = 0;
        !           203:     } else {
        !           204:        snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
        !           205:        b->ccp.decomp_node_id = 0;
        !           206:     }
        !           207:     NgFuncShutdownNode(gCcpCsock, b->name, path);
        !           208: #endif
        !           209: }
        !           210: 
        !           211: #ifndef USE_NG_PRED1
        !           212: /*
        !           213:  * Pred1Compress()
        !           214:  *
        !           215:  * Compress a packet and return a compressed version.
        !           216:  * The original is untouched.
        !           217:  */
        !           218: 
        !           219: Mbuf
        !           220: Pred1Compress(Bund b, Mbuf plain)
        !           221: {
        !           222:   u_char       *wp, *uncomp, *comp;
        !           223:   u_int16_t    fcs;
        !           224:   int          len;
        !           225:   Mbuf         res;
        !           226:   int          orglen;
        !           227:   Pred1Info    p = &b->ccp.pred1;
        !           228:   
        !           229:   orglen = MBLEN(plain);
        !           230:   uncomp = MBDATA(plain);
        !           231:   
        !           232:   p->xmit_stats.InOctets += orglen;
        !           233:   p->xmit_stats.FramesPlain++;
        !           234:   
        !           235:   res = mballoc(PRED1_MAX_BLOWUP(orglen + 2));
        !           236:   comp = MBDATA(res);
        !           237: 
        !           238:   wp = comp;
        !           239: 
        !           240:   *wp++ = (orglen >> 8) & 0x7F;
        !           241:   *wp++ = orglen & 0xFF;
        !           242: 
        !           243: /* Compute FCS */
        !           244: 
        !           245:   fcs = Crc16(PPP_INITFCS, comp, 2);
        !           246:   fcs = Crc16(fcs, uncomp, orglen);
        !           247:   fcs = ~fcs;
        !           248: 
        !           249: /* Compress data */
        !           250: 
        !           251:   len = Compress(b, uncomp, wp, orglen);
        !           252: 
        !           253: /* What happened? */
        !           254: 
        !           255:   if (len < orglen)
        !           256:   {
        !           257:     *comp |= 0x80;
        !           258:     wp += len;
        !           259:     p->xmit_stats.FramesComp++;
        !           260:   }
        !           261:   else
        !           262:   {
        !           263:     memcpy(wp, uncomp, orglen);
        !           264:     wp += orglen;
        !           265:     p->xmit_stats.FramesUncomp++;
        !           266:   }
        !           267: 
        !           268: /* Add FCS */
        !           269: 
        !           270:   *wp++ = fcs & 0xFF;
        !           271:   *wp++ = fcs >> 8;
        !           272: 
        !           273:   res->cnt = (wp - comp);
        !           274:   
        !           275:   mbfree(plain);
        !           276:   Log(LG_CCP2, ("[%s] Pred1: orig (%d) --> comp (%d)", b->name, orglen, res->cnt));
        !           277: 
        !           278:   p->xmit_stats.OutOctets += res->cnt;
        !           279: 
        !           280:   return res;
        !           281: }
        !           282: 
        !           283: /*
        !           284:  * Pred1Decompress()
        !           285:  *
        !           286:  * Decompress a packet and return a compressed version.
        !           287:  * The original is untouched.
        !           288:  */
        !           289: 
        !           290: Mbuf
        !           291: Pred1Decompress(Bund b, Mbuf mbcomp)
        !           292: {
        !           293:   u_char       *uncomp, *comp;
        !           294:   u_char       *cp;
        !           295:   u_int16_t    len, len1, cf, lenn;
        !           296:   u_int16_t    fcs;
        !           297:   int           orglen;
        !           298:   Mbuf         mbuncomp;
        !           299:   Pred1Info    p = &b->ccp.pred1;
        !           300: 
        !           301:   orglen = MBLEN(mbcomp);
        !           302:   comp = MBDATA(mbcomp);
        !           303:   cp = comp;
        !           304:   
        !           305:   p->recv_stats.InOctets += orglen;
        !           306:   
        !           307:   mbuncomp = mballoc(PRED1_DECOMP_BUF_SIZE);
        !           308:   uncomp = MBDATA(mbuncomp);
        !           309: 
        !           310: /* Get initial length value */
        !           311:   len = *cp++ << 8;
        !           312:   len += *cp++;
        !           313:   
        !           314:   cf = (len & 0x8000);
        !           315:   len &= 0x7fff;
        !           316:   
        !           317: /* Is data compressed or not really? */
        !           318:   if (cf)
        !           319:   {
        !           320:     p->recv_stats.FramesComp++;
        !           321:     len1 = Decompress(b, cp, uncomp, orglen - 4, PRED1_DECOMP_BUF_SIZE);
        !           322:     if (len != len1)   /* Error is detected. Send reset request */
        !           323:     {
        !           324:       Log(LG_CCP2, ("[%s] Length error (%d) --> len (%d)", b->name, len, len1));
        !           325:       p->recv_stats.Errors++;
        !           326:       mbfree(mbcomp);
        !           327:       mbfree(mbuncomp);
        !           328:       CcpSendResetReq(b);
        !           329:       return NULL;
        !           330:     }
        !           331:     cp += orglen - 4;
        !           332:   }
        !           333:   else
        !           334:   {
        !           335:     p->recv_stats.FramesUncomp++;
        !           336:     SyncTable(b, cp, uncomp, len);
        !           337:     cp += len;
        !           338:   }
        !           339: 
        !           340:   mbuncomp->cnt = len;
        !           341: 
        !           342:   /* Check CRC */
        !           343:   lenn = htons(len);
        !           344:   fcs = Crc16(PPP_INITFCS, (u_char *)&lenn, 2);
        !           345:   fcs = Crc16(fcs, uncomp, len);
        !           346:   fcs = Crc16(fcs, cp, 2);
        !           347: 
        !           348: #ifdef DEBUG
        !           349:     if (fcs != PPP_GOODFCS)
        !           350:       Log(LG_CCP2, ("fcs = %04x (%s), len = %x, olen = %x",
        !           351:           fcs, (fcs == PPP_GOODFCS)? "good" : "bad", len, orglen));
        !           352: #endif
        !           353: 
        !           354:   if (fcs != PPP_GOODFCS)
        !           355:   {
        !           356:     Log(LG_CCP2, ("[%s] Pred1: Bad CRC-16", b->name));
        !           357:     p->recv_stats.Errors++;
        !           358:     mbfree(mbcomp);
        !           359:     mbfree(mbuncomp);
        !           360:     CcpSendResetReq(b);
        !           361:     return NULL;
        !           362:   }
        !           363: 
        !           364:   Log(LG_CCP2, ("[%s] Pred1: orig (%d) <-- comp (%d)", b->name, mbuncomp->cnt, orglen));
        !           365:   mbfree(mbcomp);
        !           366:   
        !           367:   p->recv_stats.FramesPlain++;
        !           368:   p->recv_stats.OutOctets += mbuncomp->cnt;
        !           369:     
        !           370:   return mbuncomp;
        !           371: }
        !           372: #endif
        !           373: 
        !           374: /*
        !           375:  * Pred1RecvResetReq()
        !           376:  */
        !           377: 
        !           378: static Mbuf
        !           379: Pred1RecvResetReq(Bund b, int id, Mbuf bp, int *noAck)
        !           380: {
        !           381: #ifndef USE_NG_PRED1
        !           382:   Pred1Info     p = &b->ccp.pred1;
        !           383:   Pred1Init(b, COMP_DIR_XMIT);
        !           384:   p->xmit_stats.Errors++;
        !           385: #else
        !           386:     char               path[NG_PATHSIZ];
        !           387:     /* Forward ResetReq to the Predictor1 compression node */
        !           388:     snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
        !           389:     if (NgSendMsg(gCcpCsock, path,
        !           390:            NGM_PRED1_COOKIE, NGM_PRED1_RESETREQ, NULL, 0) < 0) {
        !           391:        Perror("[%s] reset to %s node", b->name, NG_PRED1_NODE_TYPE);
        !           392:     }
        !           393: #endif
        !           394: return(NULL);
        !           395: }
        !           396: 
        !           397: /*
        !           398:  * Pred1SendResetReq()
        !           399:  */
        !           400: 
        !           401: static Mbuf
        !           402: Pred1SendResetReq(Bund b)
        !           403: {
        !           404: #ifndef USE_NG_PRED1
        !           405:     Pred1Init(b, COMP_DIR_RECV);
        !           406: #endif
        !           407:     return(NULL);
        !           408: }
        !           409: 
        !           410: /*
        !           411:  * Pred1RecvResetAck()
        !           412:  */
        !           413: 
        !           414: static void
        !           415: Pred1RecvResetAck(Bund b, int id, Mbuf bp)
        !           416: {
        !           417: #ifndef USE_NG_PRED1
        !           418:     Pred1Init(b, COMP_DIR_RECV);
        !           419: #else
        !           420:     char               path[NG_PATHSIZ];
        !           421:     /* Forward ResetReq to the Predictor1 decompression node */
        !           422:     snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
        !           423:     if (NgSendMsg(gCcpCsock, path,
        !           424:            NGM_PRED1_COOKIE, NGM_PRED1_RESETREQ, NULL, 0) < 0) {
        !           425:        Perror("[%s] reset to %s node", b->name, NG_PRED1_NODE_TYPE);
        !           426:     }
        !           427: #endif
        !           428: }
        !           429: 
        !           430: /*
        !           431:  * Pred1BuildConfigReq()
        !           432:  */
        !           433: 
        !           434: static u_char *
        !           435: Pred1BuildConfigReq(Bund b, u_char *cp, int *ok)
        !           436: {
        !           437:   cp = FsmConfValue(cp, CCP_TY_PRED1, 0, NULL);
        !           438:   *ok = 1;
        !           439:   return (cp);
        !           440: }
        !           441: 
        !           442: /*
        !           443:  * Pred1DecodeConfigReq()
        !           444:  */
        !           445: 
        !           446: static void
        !           447: Pred1DecodeConfigReq(Fsm fp, FsmOption opt, int mode)
        !           448: {
        !           449:   /* Deal with it */
        !           450:   switch (mode) {
        !           451:     case MODE_REQ:
        !           452:        FsmAck(fp, opt);
        !           453:       break;
        !           454: 
        !           455:     case MODE_NAK:
        !           456:       break;
        !           457:   }
        !           458: }
        !           459: 
        !           460: /*
        !           461:  * Pred1Negotiated()
        !           462:  */
        !           463: 
        !           464: static int
        !           465: Pred1Negotiated(Bund b, int dir)
        !           466: {
        !           467:   return 1;
        !           468: }
        !           469: 
        !           470: /*
        !           471:  * Pred1SubtractBloat()
        !           472:  */
        !           473: 
        !           474: static int
        !           475: Pred1SubtractBloat(Bund b, int size)
        !           476: {
        !           477:   return(size - 4);
        !           478: }
        !           479: 
        !           480: static int
        !           481: Pred1Stat(Context ctx, int dir) 
        !           482: {
        !           483: #ifndef USE_NG_PRED1
        !           484:     Pred1Info  p = &ctx->bund->ccp.pred1;
        !           485:     
        !           486:     switch (dir) {
        !           487:        case COMP_DIR_XMIT:
        !           488:            Printf("\tBytes\t: %llu -> %llu (%+lld%%)\r\n",
        !           489:                (unsigned long long)p->xmit_stats.InOctets,
        !           490:                (unsigned long long)p->xmit_stats.OutOctets,
        !           491:                ((p->xmit_stats.InOctets!=0)?
        !           492:                    ((long long)(p->xmit_stats.OutOctets - p->xmit_stats.InOctets)
        !           493:                        *100/(long long)p->xmit_stats.InOctets):
        !           494:                    0));
        !           495:            Printf("\tFrames\t: %llu -> %lluc + %lluu\r\n",
        !           496:                (unsigned long long)p->xmit_stats.FramesPlain,
        !           497:                (unsigned long long)p->xmit_stats.FramesComp,
        !           498:                (unsigned long long)p->xmit_stats.FramesUncomp);
        !           499:            Printf("\tErrors\t: %llu\r\n",
        !           500:                (unsigned long long)p->recv_stats.Errors);
        !           501:            break;
        !           502:        case COMP_DIR_RECV:
        !           503:            Printf("\tBytes\t: %llu <- %llu (%+lld%%)\r\n",
        !           504:                (unsigned long long)p->recv_stats.OutOctets,
        !           505:                (unsigned long long)p->recv_stats.InOctets,
        !           506:                ((p->recv_stats.OutOctets!=0)?
        !           507:                    ((long long)(p->recv_stats.InOctets - p->recv_stats.OutOctets)
        !           508:                        *100/(long long)p->recv_stats.OutOctets):
        !           509:                    0));
        !           510:            Printf("\tFrames\t: %llu <- %lluc + %lluu\r\n",
        !           511:                (unsigned long long)p->xmit_stats.FramesPlain,
        !           512:                (unsigned long long)p->xmit_stats.FramesComp,
        !           513:                (unsigned long long)p->xmit_stats.FramesUncomp);
        !           514:            Printf("\tErrors\t: %llu\r\n",
        !           515:                (unsigned long long)p->recv_stats.Errors);
        !           516:            break;
        !           517:        default:
        !           518:            assert(0);
        !           519:     }
        !           520:     return (0);
        !           521: #else
        !           522:     Bund                       b = ctx->bund;
        !           523:     char                       path[NG_PATHSIZ];
        !           524:     struct ng_pred1_stats      stats;
        !           525:     union {
        !           526:        u_char                  buf[sizeof(struct ng_mesg) + sizeof(stats)];
        !           527:        struct ng_mesg          reply;
        !           528:     }                          u;
        !           529: 
        !           530:     switch (dir) {
        !           531:        case COMP_DIR_XMIT:
        !           532:            snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, b->name,
        !           533:                NG_PPP_HOOK_COMPRESS);
        !           534:            break;
        !           535:        case COMP_DIR_RECV:
        !           536:            snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, b->name,
        !           537:                NG_PPP_HOOK_DECOMPRESS);
        !           538:            break;
        !           539:        default:
        !           540:            assert(0);
        !           541:     }
        !           542:     if (NgFuncSendQuery(path, NGM_PRED1_COOKIE, NGM_PRED1_GET_STATS, NULL, 0, 
        !           543:        &u.reply, sizeof(u), NULL) < 0) {
        !           544:            Perror("[%s] can't get %s stats", b->name, NG_PRED1_NODE_TYPE);
        !           545:            return(0);
        !           546:     }
        !           547:     memcpy(&stats, u.reply.data, sizeof(stats));
        !           548:     switch (dir) {
        !           549:        case COMP_DIR_XMIT:
        !           550:            Printf("\tBytes\t: %llu -> %llu (%+lld%%)\r\n",
        !           551:                stats.InOctets,
        !           552:                stats.OutOctets,
        !           553:                ((stats.InOctets!=0)?
        !           554:                    ((int64_t)(stats.OutOctets - stats.InOctets)*100/(int64_t)stats.InOctets):
        !           555:                    0));
        !           556:            Printf("\tFrames\t: %llu -> %lluc + %lluu\r\n",
        !           557:                stats.FramesPlain,
        !           558:                stats.FramesComp,
        !           559:                stats.FramesUncomp);
        !           560:            Printf("\tErrors\t: %llu\r\n",
        !           561:                stats.Errors);
        !           562:            break;
        !           563:        case COMP_DIR_RECV:
        !           564:            Printf("\tBytes\t: %llu <- %llu (%+lld%%)\r\n",
        !           565:                stats.OutOctets,
        !           566:                stats.InOctets,
        !           567:                ((stats.OutOctets!=0)?
        !           568:                    ((int64_t)(stats.InOctets - stats.OutOctets)*100/(int64_t)stats.OutOctets):
        !           569:                    0));
        !           570:            Printf("\tFrames\t: %llu <- %lluc + %lluu\r\n",
        !           571:                stats.FramesPlain,
        !           572:                stats.FramesComp,
        !           573:                stats.FramesUncomp);
        !           574:            Printf("\tErrors\t: %llu\r\n",
        !           575:                stats.Errors);
        !           576:            break;
        !           577:        default:
        !           578:            assert(0);
        !           579:     }
        !           580:     return (0);
        !           581: #endif
        !           582: }
        !           583: 
        !           584: #ifndef USE_NG_PRED1
        !           585: /*
        !           586:  * Compress()
        !           587:  */
        !           588: 
        !           589: static int
        !           590: Compress(Bund b, u_char *source, u_char *dest, int len)
        !           591: {
        !           592:   Pred1Info    p = &b->ccp.pred1;
        !           593:   int          i, bitmask;
        !           594:   u_char       flags;
        !           595:   u_char       *flagdest, *orgdest;
        !           596: 
        !           597:   orgdest = dest;
        !           598:   while (len)
        !           599:   {
        !           600:     flagdest = dest++; flags = 0;   /* All guess wrong initially */
        !           601:     for (bitmask=1, i=0; i < 8 && len; i++, bitmask <<= 1) {
        !           602:       if (p->OutputGuessTable[p->oHash] == *source)
        !           603:        flags |= bitmask;       /* Guess was right - don't output */
        !           604:       else
        !           605:       {
        !           606:        p->OutputGuessTable[p->oHash] = *source;
        !           607:        *dest++ = *source;      /* Guess wrong, output char */
        !           608:       }
        !           609:       OHASH(*source++);
        !           610:       len--;
        !           611:     }
        !           612:     *flagdest = flags;
        !           613:   }
        !           614:   return(dest - orgdest);
        !           615: }
        !           616: 
        !           617: /*
        !           618:  * Decompress()
        !           619:  *
        !           620:  * Returns decompressed size, or -1 if we ran out of space
        !           621:  */
        !           622: 
        !           623: static int
        !           624: Decompress(Bund b, u_char *source, u_char *dest, int slen, int dlen)
        !           625: {
        !           626:   Pred1Info    p = &b->ccp.pred1;
        !           627:   int          i, bitmask;
        !           628:   u_char       flags, *orgdest;
        !           629: 
        !           630:   orgdest = dest;
        !           631:   while (slen)
        !           632:   {
        !           633:     flags = *source++;
        !           634:     slen--;
        !           635:     for (i=0, bitmask = 1; i < 8; i++, bitmask <<= 1)
        !           636:     {
        !           637:       if (dlen <= 0)
        !           638:        return(-1);
        !           639:       if (flags & bitmask)
        !           640:        *dest = p->InputGuessTable[p->iHash];           /* Guess correct */
        !           641:       else
        !           642:       {
        !           643:        if (!slen)
        !           644:          break;                        /* we seem to be really done -- cabo */
        !           645:        p->InputGuessTable[p->iHash] = *source;         /* Guess wrong */
        !           646:        *dest = *source++;                              /* Read from source */
        !           647:        slen--;
        !           648:       }
        !           649:       IHASH(*dest++);
        !           650:       dlen--;
        !           651:     }
        !           652:   }
        !           653:   return(dest - orgdest);
        !           654: }
        !           655: 
        !           656: /*
        !           657:  * SyncTable()
        !           658:  */
        !           659: 
        !           660: static void
        !           661: SyncTable(Bund b, u_char *source, u_char *dest, int len)
        !           662: {
        !           663:   Pred1Info    p = &b->ccp.pred1;
        !           664: 
        !           665:   while (len--)
        !           666:   {
        !           667:     if (p->InputGuessTable[p->iHash] != *source)
        !           668:       p->InputGuessTable[p->iHash] = *source;
        !           669:     IHASH(*dest++ = *source++);
        !           670:   }
        !           671: }
        !           672: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>