X-Git-Url: https://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=modules%2Fbsd-comp.c;h=d30e0d25f69da08dc4781cdfc6e1b58e85f0e9c0;hp=85d3e54c76ec973d45a87e9c204e9e5b45f86aa7;hb=416f33f79891785c39465e6b3f1010ee92fb78aa;hpb=605baf6d76e6c9b4e94e626063ab52408364dfeb diff --git a/modules/bsd-comp.c b/modules/bsd-comp.c index 85d3e54..d30e0d2 100644 --- a/modules/bsd-comp.c +++ b/modules/bsd-comp.c @@ -38,20 +38,40 @@ */ /* - * This version is for use with STREAMS under SunOS 4.x. + * This version is for use with STREAMS under SunOS 4.x, + * DEC Alpha OSF/1, and AIX 4.x. * - * $Id: bsd-comp.c,v 1.5 1994/10/21 06:30:15 paulus Exp $ + * $Id: bsd-comp.c,v 1.8 1994/12/08 00:35:33 paulus Exp $ */ +#ifdef __aix4__ +#include +#endif #include #include #include -#include #include #include #include #include +#ifdef sun +#include +#define ALLOCATE(n) kmem_alloc((n), KMEM_NOSLEEP) +#define FREE(p, n) kmem_free((p), (n)) +#endif + +#ifdef __osf__ +#include +#define ALLOCATE(n) kalloc((n)) +#define FREE(p, n) kfree((p), (n)) +#endif + +#ifdef __aix4__ +#define ALLOCATE(n) xmalloc((n), 0, pinned_heap) +#define FREE(p, n) xmfree((p), pinned_heap) +#endif + #define PACKETPTR mblk_t * #include @@ -97,8 +117,9 @@ struct bsd_db { u_char maxbits; u_char debug; u_char unit; - u_short mru; u_short seqno; /* sequence number of next packet */ + u_int hdrlen; /* header length to preallocate */ + u_int mru; u_int maxmaxcode; /* largest valid code */ u_int max_ent; /* largest code in use */ u_int in_count; /* uncompressed bytes, aged */ @@ -144,7 +165,7 @@ static void bsd_free __P((void *state)); static int bsd_comp_init __P((void *state, u_char *options, int opt_len, int unit, int debug)); static int bsd_decomp_init __P((void *state, u_char *options, int opt_len, - int unit, int mru, int debug)); + int unit, int hdrlen, int mru, int debug)); static int bsd_compress __P((void *state, mblk_t **mret, mblk_t *mp, int slen, int maxolen)); static void bsd_incomp __P((void *state, mblk_t *dmsg)); @@ -273,6 +294,7 @@ bsd_comp_stats(state, stats) struct compstat *stats; { struct bsd_db *db = (struct bsd_db *) state; + u_int out; stats->unc_bytes = db->uncomp_bytes; stats->unc_packets = db->uncomp_count; @@ -280,9 +302,14 @@ bsd_comp_stats(state, stats) stats->comp_packets = db->comp_count; stats->inc_bytes = db->incomp_bytes; stats->inc_packets = db->incomp_count; - stats->ratio = (double) db->in_count; - if (db->bytes_out != 0) - stats->ratio /= db->bytes_out; + stats->ratio = db->in_count; + out = db->bytes_out; + if (stats->ratio <= 0x7fffff) + stats->ratio <<= 8; + else + out >>= 8; + if (out != 0) + stats->ratio /= out; } /* @@ -345,7 +372,7 @@ bsd_alloc(options, opt_len, decomp) maxmaxcode = MAXCODE(bits); newlen = sizeof(*db) + (hsize-1) * (sizeof(db->dict[0])); - db = (struct bsd_db *) kmem_alloc(newlen, KMEM_NOSLEEP); + db = (struct bsd_db *) ALLOCATE(newlen); if (!db) return NULL; bzero(db, sizeof(*db) - sizeof(db->dict)); @@ -353,10 +380,9 @@ bsd_alloc(options, opt_len, decomp) if (!decomp) { db->lens = NULL; } else { - db->lens = (u_short *) kmem_alloc((maxmaxcode+1) * sizeof(db->lens[0]), - KMEM_NOSLEEP); + db->lens = (u_short *) ALLOCATE((maxmaxcode+1) * sizeof(db->lens[0])); if (!db->lens) { - kmem_free(db, newlen); + FREE(db, newlen); return NULL; } } @@ -377,8 +403,8 @@ bsd_free(state) struct bsd_db *db = (struct bsd_db *) state; if (db->lens) - kmem_free(db->lens, (db->maxmaxcode+1) * sizeof(db->lens[0])); - kmem_free(db, db->totlen); + FREE(db->lens, (db->maxmaxcode+1) * sizeof(db->lens[0])); + FREE(db, db->totlen); } static void * @@ -401,10 +427,10 @@ bsd_decomp_alloc(options, opt_len) * Initialize the database. */ static int -bsd_init(db, options, opt_len, unit, mru, debug, decomp) +bsd_init(db, options, opt_len, unit, hdrlen, mru, debug, decomp) struct bsd_db *db; u_char *options; - int opt_len, unit, mru, debug, decomp; + int opt_len, unit, hdrlen, mru, debug, decomp; { int i; @@ -426,12 +452,12 @@ bsd_init(db, options, opt_len, unit, mru, debug, decomp) } db->unit = unit; + db->hdrlen = hdrlen; db->mru = mru; - db->clear_count = -1; if (debug) db->debug = 1; - bsd_clear(db); + bsd_reset(db); return 1; } @@ -443,21 +469,20 @@ bsd_comp_init(state, options, opt_len, unit, debug) int opt_len, unit, debug; { return bsd_init((struct bsd_db *) state, options, opt_len, - unit, 0, debug, 0); + unit, 0, 0, debug, 0); } static int -bsd_decomp_init(state, options, opt_len, unit, mru, debug) +bsd_decomp_init(state, options, opt_len, unit, hdrlen, mru, debug) void *state; u_char *options; - int opt_len, unit, mru, debug; + int opt_len, unit, hdrlen, mru, debug; { return bsd_init((struct bsd_db *) state, options, opt_len, - unit, mru, debug, 1); + unit, hdrlen, mru, debug, 1); } - /* * compress a packet * One change from the BSD compress command is that when the @@ -611,7 +636,7 @@ bsd_compress(state, mretp, mp, slen, maxolen) if (dictp->codem1 >= max_ent) goto nomatch; } while (dictp->f.fcode != fcode); - ent = dictp->codem1+1; /* finally found (prefix,suffix) */ + ent = dictp->codem1 + 1; /* finally found (prefix,suffix) */ continue; nomatch: @@ -638,12 +663,15 @@ bsd_compress(state, mretp, mp, slen, maxolen) } ent = c; } - OUTPUT(ent); /* output the last code */ + OUTPUT(ent); /* output the last code */ db->bytes_out += olen; db->in_count += ilen; + if (bitno < 32) + ++db->bytes_out; /* count complete bytes */ + if (bsd_check(db)) - OUTPUT(CLEAR); /* do not count the CLEAR */ + OUTPUT(CLEAR); /* do not count the CLEAR */ /* * Pad dribble bits of last code with ones. @@ -789,10 +817,10 @@ bsd_incomp(state, dmsg) db->in_count += ilen; (void)bsd_check(db); - ++db->comp_count; - db->comp_bytes += bitno / 8; ++db->incomp_count; db->incomp_bytes += ilen; + ++db->uncomp_count; + db->uncomp_bytes += ilen; /* Increase code size if we would have without the packet * boundary and as the decompressor will. @@ -804,6 +832,19 @@ bsd_incomp(state, dmsg) /* * Decompress "BSD Compress" + * + * Because of patent problems, we return DECOMP_ERROR for errors + * found by inspecting the input data and for system problems, but + * DECOMP_FATALERROR for any errors which could possibly be said to + * be being detected "after" decompression. For DECOMP_ERROR, + * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be + * infringing a patent of Motorola's if we do, so we take CCP down + * instead. + * + * Given that the frame has the correct sequence number and a good FCS, + * errors such as invalid codes in the input most likely indicate a + * bug, so we return DECOMP_FATALERROR for them in order to turn off + * compression, even though they are detected by inspecting the input. */ static int bsd_decompress(state, cmsg, dmpp) @@ -861,9 +902,10 @@ bsd_decompress(state, cmsg, dmpp) /* * Allocate one message block to start with. */ - if ((dmsg = allocb(DECOMP_CHUNK, BPRI_MED)) == NULL) + if ((dmsg = allocb(DECOMP_CHUNK + db->hdrlen, BPRI_MED)) == NULL) return DECOMP_ERROR; mret = dmsg; + dmsg->b_wptr += db->hdrlen; dmsg->b_rptr = wptr = dmsg->b_wptr; /* Fill in the ppp header, but not the last byte of the protocol @@ -883,6 +925,7 @@ bsd_decompress(state, cmsg, dmpp) break; rptr = cmsg->b_rptr; len = cmsg->b_wptr - rptr; + ilen += len; continue; /* handle 0-length buffers */ } @@ -917,11 +960,11 @@ bsd_decompress(state, cmsg, dmpp) } } bsd_clear(db); - explen = 0; + explen = ilen = 0; break; } - if (incode > max_ent+2 || incode > db->maxmaxcode + if (incode > max_ent + 2 || incode > db->maxmaxcode || incode > max_ent && oldcode == CLEAR) { freemsg(dmsg); if (db->debug) { @@ -930,7 +973,7 @@ bsd_decompress(state, cmsg, dmpp) printf("max_ent=0x%x dlen=%d seqno=%d\n", max_ent, dlen, db->seqno); } - return DECOMP_FATALERROR; + return DECOMP_FATALERROR; /* probably a bug */ } /* Special case for KwKwK string. */