9c749ffb8b
add some logging functionality which I find very useful. 'set debug link' will record just link up/down and address assignments. 'set debug connect' will record the entire chat dialog 'set debug carrier' will record just chat lines including 'CARRIER' (so that I can be sure I'm getting a 28.8 line). There was a global change required to permit LogPrintf to take a bit mask instead of a bit position value (to permit logging some events on either of two flags, so that no change in 'set debug lcp' would result from the code supporting 'link'. Thus the diffs are rather long for such a small change. The man page is also touched. Oh, and there was a slight syntax problem in route.c Reviewed by: phk Submitted by: Tony Kimball <alk@Think.COM>
226 lines
5.2 KiB
C
226 lines
5.2 KiB
C
#include "fsm.h"
|
|
#include "hdlc.h"
|
|
#include "lcpproto.h"
|
|
#include "ccp.h"
|
|
|
|
/*
|
|
*
|
|
* $Id: pred.c,v 1.5 1996/01/30 11:08:48 dfr Exp $
|
|
*
|
|
* pred.c -- Test program for Dave Rand's rendition of the
|
|
* predictor algorithm
|
|
* Updated by: iand@labtam.labtam.oz.au (Ian Donaldson)
|
|
* Updated by: Carsten Bormann <cabo@cs.tu-berlin.de>
|
|
* Original : Dave Rand <dlr@bungi.com>/<dave_rand@novell.com>
|
|
*/
|
|
|
|
/* The following hash code is the heart of the algorithm:
|
|
* It builds a sliding hash sum of the previous 3-and-a-bit characters
|
|
* which will be used to index the guess table.
|
|
* A better hash function would result in additional compression,
|
|
* at the expense of time.
|
|
*/
|
|
#define IHASH(x) iHash = (iHash << 4) ^ (x)
|
|
#define OHASH(x) oHash = (oHash << 4) ^ (x)
|
|
|
|
static unsigned short int iHash, oHash;
|
|
static unsigned char InputGuessTable[65536];
|
|
static unsigned char OutputGuessTable[65536];
|
|
|
|
static int
|
|
compress(source, dest, len)
|
|
unsigned char *source, *dest;
|
|
int len;
|
|
{
|
|
int i, bitmask;
|
|
unsigned char *flagdest, flags, *orgdest;
|
|
|
|
orgdest = dest;
|
|
while (len) {
|
|
flagdest = dest++; flags = 0; /* All guess wrong initially */
|
|
for (bitmask=1, i=0; i < 8 && len; i++, bitmask <<= 1) {
|
|
if (OutputGuessTable[oHash] == *source) {
|
|
flags |= bitmask; /* Guess was right - don't output */
|
|
} else {
|
|
OutputGuessTable[oHash] = *source;
|
|
*dest++ = *source; /* Guess wrong, output char */
|
|
}
|
|
OHASH(*source++);len--;
|
|
}
|
|
*flagdest = flags;
|
|
}
|
|
return(dest - orgdest);
|
|
}
|
|
|
|
static void
|
|
SyncTable(source, dest, len)
|
|
unsigned char *source, *dest;
|
|
int len;
|
|
{
|
|
|
|
while (len--) {
|
|
if (InputGuessTable[iHash] != *source) {
|
|
InputGuessTable[iHash] = *source;
|
|
}
|
|
IHASH(*dest++ = *source++);
|
|
}
|
|
}
|
|
|
|
static int
|
|
decompress(source, dest, len)
|
|
unsigned char *source, *dest;
|
|
int len;
|
|
{
|
|
int i, bitmask;
|
|
unsigned char flags, *orgdest;
|
|
|
|
orgdest = dest;
|
|
while (len) {
|
|
flags = *source++;
|
|
len--;
|
|
for (i=0, bitmask = 1; i < 8; i++, bitmask <<= 1) {
|
|
if (flags & bitmask) {
|
|
*dest = InputGuessTable[iHash]; /* Guess correct */
|
|
} else {
|
|
if (!len)
|
|
break; /* we seem to be really done -- cabo */
|
|
InputGuessTable[iHash] = *source; /* Guess wrong */
|
|
*dest = *source++; /* Read from source */
|
|
len--;
|
|
}
|
|
IHASH(*dest++);
|
|
}
|
|
}
|
|
return(dest - orgdest);
|
|
}
|
|
|
|
#define SIZ1 2048
|
|
|
|
void
|
|
Pred1Init(direction)
|
|
int direction;
|
|
{
|
|
if (direction & 1) { /* Input part */
|
|
iHash = 0;
|
|
bzero(InputGuessTable, sizeof(InputGuessTable));
|
|
}
|
|
if (direction & 2) { /* Output part */
|
|
oHash = 0;
|
|
bzero(OutputGuessTable, sizeof(OutputGuessTable));
|
|
}
|
|
}
|
|
|
|
void
|
|
Pred1Output(pri, proto, bp)
|
|
int pri;
|
|
u_short proto;
|
|
struct mbuf *bp;
|
|
{
|
|
struct mbuf *mwp;
|
|
u_char *cp, *wp, *hp;
|
|
int orglen, len;
|
|
u_char bufp[SIZ1];
|
|
u_short fcs;
|
|
|
|
orglen = plength(bp) + 2; /* add count of proto */
|
|
mwp = mballoc((orglen+2)/8*9+12, MB_HDLCOUT);
|
|
hp = wp = MBUF_CTOP(mwp);
|
|
cp = bufp;
|
|
*wp++ = *cp++ = orglen >> 8;
|
|
*wp++ = *cp++ = orglen & 0377;
|
|
*cp++ = proto >> 8;
|
|
*cp++ = proto & 0377;
|
|
mbread(bp, cp, orglen-2);
|
|
fcs = HdlcFcs(INITFCS, bufp, 2+orglen);
|
|
fcs = ~fcs;
|
|
|
|
len = compress(bufp + 2, wp, orglen);
|
|
#ifdef DEBUG
|
|
logprintf("orglen (%d) --> len (%d)\n", orglen, len);
|
|
#endif
|
|
CcpInfo.orgout += orglen;
|
|
if (len < orglen) {
|
|
*hp |= 0x80;
|
|
wp += len;
|
|
CcpInfo.compout += len;
|
|
} else {
|
|
bcopy(bufp+2, wp, orglen);
|
|
wp += orglen;
|
|
CcpInfo.compout += orglen;
|
|
}
|
|
|
|
*wp++ = fcs & 0377;
|
|
*wp++ = fcs >> 8;
|
|
mwp->cnt = wp - MBUF_CTOP(mwp);
|
|
HdlcOutput(PRI_NORMAL, PROTO_COMPD, mwp);
|
|
}
|
|
|
|
void
|
|
Pred1Input(bp)
|
|
struct mbuf *bp;
|
|
{
|
|
u_char *cp, *pp;
|
|
int len, olen, len1;
|
|
struct mbuf *wp;
|
|
u_char *bufp;
|
|
u_short fcs, proto;
|
|
|
|
wp = mballoc(SIZ1, MB_IPIN);
|
|
cp = MBUF_CTOP(bp);
|
|
olen = plength(bp);
|
|
pp = bufp = MBUF_CTOP(wp);
|
|
*pp++ = *cp & 0177;
|
|
len = *cp++ << 8;
|
|
*pp++ = *cp;
|
|
len += *cp++;
|
|
CcpInfo.orgin += len & 0x7fff;
|
|
if (len & 0x8000) {
|
|
len1 = decompress(cp, pp, olen - 4);
|
|
CcpInfo.compin += olen;
|
|
len &= 0x7fff;
|
|
if (len != len1) { /* Error is detected. Send reset request */
|
|
LogPrintf(LOG_LCP_BIT, "%s: Length Error\n", CcpFsm.name);
|
|
CcpSendResetReq(&CcpFsm);
|
|
pfree(bp);
|
|
pfree(wp);
|
|
return;
|
|
}
|
|
cp += olen - 4;
|
|
pp += len1;
|
|
} else {
|
|
CcpInfo.compin += len;
|
|
SyncTable(cp, pp, len);
|
|
cp += len;
|
|
pp += len;
|
|
}
|
|
*pp++ = *cp++; /* CRC */
|
|
*pp++ = *cp++;
|
|
fcs = HdlcFcs(INITFCS, bufp, wp->cnt = pp - bufp);
|
|
#ifdef DEBUG
|
|
if (fcs != GOODFCS)
|
|
logprintf("fcs = 0x%04x (%s), len = 0x%x, olen = 0x%x\n",
|
|
fcs, (fcs == GOODFCS)? "good" : "bad", len, olen);
|
|
#endif
|
|
if (fcs == GOODFCS) {
|
|
wp->offset += 2; /* skip length */
|
|
wp->cnt -= 4; /* skip length & CRC */
|
|
pp = MBUF_CTOP(wp);
|
|
proto = *pp++;
|
|
if (proto & 1) {
|
|
wp->offset++;
|
|
wp->cnt--;
|
|
} else {
|
|
wp->offset += 2;
|
|
wp->cnt -= 2;
|
|
proto = (proto << 8) | *pp++;
|
|
}
|
|
DecodePacket(proto, wp);
|
|
}
|
|
else
|
|
{
|
|
LogDumpBp(LOG_HDLC, "Bad FCS", wp);
|
|
pfree(wp);
|
|
}
|
|
pfree(bp);
|
|
}
|