diff options
-rw-r--r-- | usr.sbin/ppp/Makefile | 10 | ||||
-rw-r--r-- | usr.sbin/ppp/ccp.c | 214 | ||||
-rw-r--r-- | usr.sbin/ppp/ccp.h | 37 | ||||
-rw-r--r-- | usr.sbin/ppp/deflate.c | 499 | ||||
-rw-r--r-- | usr.sbin/ppp/deflate.h | 5 | ||||
-rw-r--r-- | usr.sbin/ppp/fsm.c | 9 | ||||
-rw-r--r-- | usr.sbin/ppp/fsm.h | 3 | ||||
-rw-r--r-- | usr.sbin/ppp/hdlc.c | 57 | ||||
-rw-r--r-- | usr.sbin/ppp/hdlc.h | 3 | ||||
-rw-r--r-- | usr.sbin/ppp/ipcp.c | 41 | ||||
-rw-r--r-- | usr.sbin/ppp/lcp.c | 228 | ||||
-rw-r--r-- | usr.sbin/ppp/lcp.h | 18 | ||||
-rw-r--r-- | usr.sbin/ppp/main.c | 79 | ||||
-rw-r--r-- | usr.sbin/ppp/mbuf.h | 3 | ||||
-rw-r--r-- | usr.sbin/ppp/os.c | 3 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp.8 | 33 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp.8.m4 | 33 | ||||
-rw-r--r-- | usr.sbin/ppp/pred.c | 147 | ||||
-rw-r--r-- | usr.sbin/ppp/pred.h | 6 | ||||
-rw-r--r-- | usr.sbin/ppp/server.c | 3 | ||||
-rw-r--r-- | usr.sbin/ppp/vars.c | 17 | ||||
-rw-r--r-- | usr.sbin/ppp/vars.h | 24 | ||||
-rw-r--r-- | usr.sbin/ppp/vjcomp.c | 20 | ||||
-rw-r--r-- | usr.sbin/ppp/vjcomp.h | 3 |
24 files changed, 1209 insertions, 286 deletions
diff --git a/usr.sbin/ppp/Makefile b/usr.sbin/ppp/Makefile index d3c5e2d..67cff18 100644 --- a/usr.sbin/ppp/Makefile +++ b/usr.sbin/ppp/Makefile @@ -1,14 +1,14 @@ -# $Id: Makefile,v 1.31 1997/11/18 14:52:03 brian Exp $ +# $Id: Makefile,v 1.32 1997/11/22 03:37:21 brian Exp $ PROG= ppp -SRCS= arp.c async.c auth.c ccp.c chap.c chat.c \ - command.c defs.c filter.c fsm.c hdlc.c id.c ip.c ipcp.c lcp.c \ +SRCS= arp.c async.c auth.c ccp.c chap.c chat.c command.c deflate.c \ + defs.c filter.c fsm.c hdlc.c id.c ip.c ipcp.c lcp.c \ log.c lqr.c main.c mbuf.c modem.c os.c pap.c phase.c \ pred.c route.c server.c sig.c slcompress.c systems.c throughput.c \ timer.c tun.c vars.c vjcomp.c CFLAGS+=-Wall -LDADD+= -lmd -lcrypt -lutil -DPADD+= ${LIBMD} ${LIBCRYPT} ${LIBUTIL} +LDADD+= -lmd -lcrypt -lutil -lz +DPADD+= ${LIBMD} ${LIBCRYPT} ${LIBUTIL} ${LIBZ} MAN8= ppp.8 BINMODE=4550 BINOWN= root diff --git a/usr.sbin/ppp/ccp.c b/usr.sbin/ppp/ccp.c index 6fbee99..a72ad5c 100644 --- a/usr.sbin/ppp/ccp.c +++ b/usr.sbin/ppp/ccp.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ccp.c,v 1.19 1997/11/14 15:39:14 brian Exp $ + * $Id: ccp.c,v 1.20 1997/11/22 03:37:25 brian Exp $ * * TODO: * o Support other compression protocols @@ -41,6 +41,7 @@ #include "loadalias.h" #include "vars.h" #include "pred.h" +#include "deflate.h" struct ccpstate CcpInfo; @@ -54,8 +55,6 @@ static void CcpLayerUp(struct fsm *); static void CcpLayerDown(struct fsm *); static void CcpInitRestartCounter(struct fsm *); -#define REJECTED(p, x) (p->his_reject & (1<<x)) - struct fsm CcpFsm = { "CCP", PROTO_CCP, @@ -92,11 +91,31 @@ static char const *cftypes[] = { "MSPPC", /* 18: Microsoft PPC */ "GAND", /* 19: Gandalf FZA */ "V42BIS", /* 20: ARG->DATA.42bis compression */ - "BSD", /* BSD LZW Compress */ + "BSD", /* 21: BSD LZW Compress */ + "???", + "???", + "DEFLATE", /* 24: PPP Deflate */ }; #define NCFTYPES (sizeof(cftypes)/sizeof(char *)) +static const char * +protoname(int proto) +{ + if (proto < 0 || proto > NCFTYPES) + return "none"; + return cftypes[proto]; +} + +static const struct ccp_algorithm *algorithm[] = { + &Pred1Algorithm, + &DeflateAlgorithm +}; + +static int in_algorithm = -1; +static int out_algorithm = -1; +#define NALGORITHMS (sizeof(algorithm)/sizeof(algorithm[0])) + int ReportCcpStatus(struct cmdargs const *arg) { @@ -105,10 +124,10 @@ ReportCcpStatus(struct cmdargs const *arg) if (VarTerm) { fprintf(VarTerm, "%s [%s]\n", fp->name, StateNames[fp->state]); - fprintf(VarTerm, "myproto = %s, hisproto = %s\n", - cftypes[icp->want_proto], cftypes[icp->his_proto]); - fprintf(VarTerm, "Input: %ld --> %ld, Output: %ld --> %ld\n", - icp->orgin, icp->compin, icp->orgout, icp->compout); + fprintf(VarTerm, "My protocol = %s, His protocol = %s\n", + protoname(icp->my_proto), protoname(icp->his_proto)); + fprintf(VarTerm, "Output: %ld --> %ld, Input: %ld --> %ld\n", + icp->uncompout, icp->compout, icp->compin, icp->uncompin); } return 0; } @@ -120,8 +139,15 @@ CcpInit() FsmInit(&CcpFsm); memset(icp, '\0', sizeof(struct ccpstate)); - if (Enabled(ConfPred1)) - icp->want_proto = TY_PRED1; + icp->his_proto = icp->my_proto = -1; + if (in_algorithm >= 0 && in_algorithm < NALGORITHMS) { + (*algorithm[in_algorithm]->i.Term)(); + in_algorithm = -1; + } + if (out_algorithm >= 0 && out_algorithm < NALGORITHMS) { + (*algorithm[out_algorithm]->o.Term)(); + out_algorithm = -1; + } CcpFsm.maxconfig = 10; } @@ -137,13 +163,22 @@ CcpSendConfigReq(struct fsm *fp) { u_char *cp; struct ccpstate *icp = &CcpInfo; + int f; - cp = ReqBuff; LogPrintf(LogCCP, "CcpSendConfigReq\n"); - if (icp->want_proto && !REJECTED(icp, TY_PRED1)) { - *cp++ = TY_PRED1; - *cp++ = 2; - } + cp = ReqBuff; + CcpInfo.my_proto = -1; + out_algorithm = -1; + for (f = 0; f < NALGORITHMS; f++) + if (Enabled(algorithm[f]->Conf) && !REJECTED(icp, algorithm[f]->id)) { + struct lcp_opt o; + + (*algorithm[f]->o.Get)(&o); + cp += LcpPutConf(LogCCP, cp, &o, cftypes[o.id], + (*algorithm[f]->Disp)(&o)); + CcpInfo.my_proto = o.id; + out_algorithm = f; + } FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); } @@ -170,7 +205,8 @@ CcpSendTerminateAck(struct fsm *fp) void CcpRecvResetReq(struct fsm *fp) { - Pred1Init(2); /* Initialize Output part */ + if (out_algorithm >= 0 && out_algorithm < NALGORITHMS) + (*algorithm[out_algorithm]->o.Reset)(); } static void @@ -183,24 +219,44 @@ static void CcpLayerFinish(struct fsm *fp) { LogPrintf(LogCCP, "CcpLayerFinish.\n"); + if (in_algorithm >= 0 && in_algorithm < NALGORITHMS) { + (*algorithm[in_algorithm]->i.Term)(); + in_algorithm = -1; + } + if (out_algorithm >= 0 && out_algorithm < NALGORITHMS) { + (*algorithm[out_algorithm]->o.Term)(); + out_algorithm = -1; + } } static void CcpLayerDown(struct fsm *fp) { LogPrintf(LogCCP, "CcpLayerDown.\n"); + if (in_algorithm >= 0 && in_algorithm < NALGORITHMS) { + (*algorithm[in_algorithm]->i.Term)(); + in_algorithm = -1; + } + if (out_algorithm >= 0 && out_algorithm < NALGORITHMS) { + (*algorithm[out_algorithm]->o.Term)(); + out_algorithm = -1; + } } /* - * Called when CCP has reached to OPEN state + * Called when CCP has reached the OPEN state */ static void CcpLayerUp(struct fsm *fp) { LogPrintf(LogCCP, "CcpLayerUp(%d).\n", fp->state); - LogPrintf(LogCCP, "myproto = %d, hisproto = %d\n", - CcpInfo.want_proto, CcpInfo.his_proto); - Pred1Init(3); /* Initialize Input and Output */ + LogPrintf(LogCCP, "Out = %s[%d], In = %s[%d]\n", + protoname(CcpInfo.my_proto), CcpInfo.my_proto, + protoname(CcpInfo.his_proto), CcpInfo.his_proto); + if (in_algorithm >= 0 && in_algorithm < NALGORITHMS) + (*algorithm[in_algorithm]->i.Init)(); + if (out_algorithm >= 0 && out_algorithm < NALGORITHMS) + (*algorithm[out_algorithm]->o.Init)(); } void @@ -213,15 +269,29 @@ CcpUp() void CcpOpen() { - if (Enabled(ConfPred1)) - FsmOpen(&CcpFsm); + int f; + + for (f = 0; f < NALGORITHMS; f++) + if (Enabled(algorithm[f]->Conf)) { + CcpFsm.open_mode = OPEN_ACTIVE; + FsmOpen(&CcpFsm); + break; + } + + if (f == NALGORITHMS) + for (f = 0; f < NALGORITHMS; f++) + if (Acceptable(algorithm[f]->Conf)) { + CcpFsm.open_mode = OPEN_PASSIVE; + FsmOpen(&CcpFsm); + break; + } } static void CcpDecodeConfig(u_char *cp, int plen, int mode_type) { int type, length; - char tbuff[100]; + int f; ackp = AckBuff; nakp = NakBuff; @@ -233,42 +303,74 @@ CcpDecodeConfig(u_char *cp, int plen, int mode_type) type = *cp; length = cp[1]; if (type < NCFTYPES) - snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length); + LogPrintf(LogCCP, " %s[%d]\n", cftypes[type], length); else - snprintf(tbuff, sizeof(tbuff), " "); - - LogPrintf(LogCCP, "%s\n", tbuff); + LogPrintf(LogCCP, " ???[%d]\n", length); + + for (f = NALGORITHMS-1; f > -1; f--) + if (algorithm[f]->id == type) + break; + + if (f == -1) { + /* Don't understand that :-( */ + if (mode_type == MODE_REQ) { + CcpInfo.my_reject |= (1 << type); + memcpy(rejp, cp, length); + rejp += length; + } + } else { + struct lcp_opt o; - switch (type) { - case TY_PRED1: switch (mode_type) { case MODE_REQ: - if (Acceptable(ConfPred1)) { - memcpy(ackp, cp, length); - ackp += length; - CcpInfo.his_proto = type; + if (Acceptable(algorithm[f]->Conf) && in_algorithm == -1) { + memcpy(&o, cp, length); + switch ((*algorithm[f]->i.Set)(&o)) { + case MODE_REJ: + memcpy(rejp, &o, o.len); + rejp += o.len; + break; + case MODE_NAK: + memcpy(nakp, &o, o.len); + nakp += o.len; + break; + case MODE_ACK: + memcpy(ackp, cp, length); + ackp += length; + CcpInfo.his_proto = type; + in_algorithm = f; /* This one'll do ! */ + break; + } } else { memcpy(rejp, cp, length); rejp += length; } break; case MODE_NAK: + memcpy(&o, cp, length); + if ((*algorithm[f]->o.Set)(&o) == MODE_ACK) + CcpInfo.my_proto = algorithm[f]->id; + else { + CcpInfo.his_reject |= (1 << type); + CcpInfo.my_proto = -1; + } + break; case MODE_REJ: CcpInfo.his_reject |= (1 << type); - CcpInfo.want_proto = 0; + CcpInfo.my_proto = -1; break; } - break; - case TY_BSD: - default: - CcpInfo.my_reject |= (1 << type); - memcpy(rejp, cp, length); - rejp += length; - break; } + plen -= length; cp += length; } + + if (rejp != RejBuff) { + ackp = AckBuff; /* let's not send both ! */ + CcpInfo.his_proto = -1; + in_algorithm = -1; + } } void @@ -282,3 +384,33 @@ CcpInput(struct mbuf *bp) pfree(bp); } } + +void +CcpResetInput() +{ + if (in_algorithm >= 0 && in_algorithm < NALGORITHMS) + (*algorithm[in_algorithm]->i.Reset)(); +} + +int +CcpOutput(int pri, u_short proto, struct mbuf *m) +{ + if (out_algorithm >= 0 && out_algorithm < NALGORITHMS) + return (*algorithm[out_algorithm]->o.Write)(pri, proto, m); + return 0; +} + +struct mbuf * +CompdInput(u_short *proto, struct mbuf *m) +{ + if (in_algorithm >= 0 && in_algorithm < NALGORITHMS) + return (*algorithm[in_algorithm]->i.Read)(proto, m); + return NULL; +} + +void +CcpDictSetup(u_short proto, struct mbuf *m) +{ + if (in_algorithm >= 0 && in_algorithm < NALGORITHMS) + (*algorithm[in_algorithm]->i.DictSetup)(proto, m); +} diff --git a/usr.sbin/ppp/ccp.h b/usr.sbin/ppp/ccp.h index 8585f17..a9e7e8f 100644 --- a/usr.sbin/ppp/ccp.h +++ b/usr.sbin/ppp/ccp.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ccp.h,v 1.8 1997/10/26 01:02:12 brian Exp $ + * $Id: ccp.h,v 1.9 1997/11/22 03:37:25 brian Exp $ * * TODO: */ @@ -32,19 +32,44 @@ #define TY_GAND 19 /* Gandalf FZA */ #define TY_V42BIS 20 /* V.42bis compression */ #define TY_BSD 21 /* BSD LZW Compress */ +#define TY_DEFLATE 24 /* Deflate (gzip) */ struct ccpstate { u_long his_proto; /* peer's compression protocol */ - u_long want_proto; /* my compression protocol */ + u_long my_proto; /* our compression protocol */ u_long his_reject; /* Request codes rejected by peer */ u_long my_reject; /* Request codes I have rejected */ - u_long orgout, compout; - u_long orgin, compin; + u_long uncompout, compout; + u_long uncompin, compin; }; extern struct ccpstate CcpInfo; + +struct ccp_algorithm { + int id; + int Conf; /* A Conf value from vars.h */ + const char *(*Disp)(struct lcp_opt *); + struct { + void (*Get)(struct lcp_opt *); + int (*Set)(struct lcp_opt *); + int (*Init)(void); + void (*Term)(void); + void (*Reset)(void); + struct mbuf *(*Read)(u_short *, struct mbuf *); + void (*DictSetup)(u_short, struct mbuf *); + } i; + struct { + void (*Get)(struct lcp_opt *); + int (*Set)(struct lcp_opt *); + int (*Init)(void); + void (*Term)(void); + void (*Reset)(void); + int (*Write)(int, u_short, struct mbuf *); + } o; +}; + extern struct fsm CcpFsm; extern void CcpRecvResetReq(struct fsm *); @@ -54,3 +79,7 @@ extern void CcpUp(void); extern void CcpOpen(void); extern void CcpInit(void); extern int ReportCcpStatus(struct cmdargs const *); +extern void CcpResetInput(void); +extern int CcpOutput(int, u_short, struct mbuf *); +extern struct mbuf *CompdInput(u_short *, struct mbuf *); +extern void CcpDictSetup(u_short, struct mbuf *); diff --git a/usr.sbin/ppp/deflate.c b/usr.sbin/ppp/deflate.c new file mode 100644 index 0000000..a759288 --- /dev/null +++ b/usr.sbin/ppp/deflate.c @@ -0,0 +1,499 @@ +/* + * $Id$ + */ + +#include <sys/param.h> +#include <netinet/in.h> + +#include <stdio.h> +#include <stdlib.h> +#include <zlib.h> + +#include "command.h" +#include "mbuf.h" +#include "log.h" +#include "defs.h" +#include "loadalias.h" +#include "vars.h" +#include "hdlc.h" +#include "lcp.h" +#include "ccp.h" +#include "lcpproto.h" +#include "timer.h" +#include "fsm.h" +#include "deflate.h" + +/* Our state */ +struct deflate_state { + u_short seqno; + z_stream cx; +}; + +static int iWindowSize = 15; +static int oWindowSize = 15; +static struct deflate_state InputState, OutputState; +static char garbage[10]; +static u_char EMPTY_BLOCK[4] = { 0x00, 0x00, 0xff, 0xff }; + +#define DEFLATE_CHUNK_LEN 1024 /* Allocate mbufs this size */ + +static void +DeflateResetOutput(void) +{ + OutputState.seqno = 0; + deflateReset(&OutputState.cx); + LogPrintf(LogCCP, "Deflate: Output channel reset\n"); +} + +static int +DeflateOutput(int pri, u_short proto, struct mbuf *mp) +{ + u_char *wp, *rp; + int olen, ilen, len, res, flush; + struct mbuf *mo_head, *mo, *mi_head, *mi; + + ilen = plength(mp); + LogPrintf(LogDEBUG, "DeflateOutput: Proto %02x (%d bytes)\n", proto, ilen); + LogDumpBp(LogDEBUG, "DeflateOutput: Compress packet:", mp); + + /* Stuff the protocol in front of the input */ + mi_head = mi = mballoc(2, MB_HDLCOUT); + mi->next = mp; + rp = MBUF_CTOP(mi); + if (proto < 0x100) { /* Compress the protocol */ + rp[0] = proto & 0377; + mi->cnt = 1; + } else { /* Don't compress the protocol */ + rp[0] = proto >> 8; + rp[1] = proto & 0377; + mi->cnt = 2; + } + + /* Allocate the initial output mbuf */ + mo_head = mo = mballoc(DEFLATE_CHUNK_LEN, MB_HDLCOUT); + mo->cnt = 2; + wp = MBUF_CTOP(mo); + *wp++ = OutputState.seqno >> 8; + *wp++ = OutputState.seqno & 0377; + LogPrintf(LogDEBUG, "DeflateOutput: Seq %d\n", OutputState.seqno); + OutputState.seqno++; + + /* Set up the deflation context */ + OutputState.cx.next_out = wp; + OutputState.cx.avail_out = DEFLATE_CHUNK_LEN - 2; + OutputState.cx.next_in = MBUF_CTOP(mi); + OutputState.cx.avail_in = mi->cnt; + flush = Z_NO_FLUSH; + + olen = 0; + while (1) { + if ((res = deflate(&OutputState.cx, flush)) != Z_OK) { + if (res == Z_STREAM_END) + break; /* Done */ + LogPrintf(LogERROR, "DeflateOutput: deflate returned %d (%s)\n", + res, OutputState.cx.msg ? OutputState.cx.msg : ""); + pfree(mo_head); + mbfree(mi_head); + OutputState.seqno--; + return 1; /* packet dropped */ + } + + if (flush == Z_SYNC_FLUSH && OutputState.cx.avail_out != 0) + break; + + if (OutputState.cx.avail_in == 0 && mi->next != NULL) { + mi = mi->next; + OutputState.cx.next_in = MBUF_CTOP(mi); + OutputState.cx.avail_in = mi->cnt; + if (mi->next == NULL) + flush = Z_SYNC_FLUSH; + } + + if (OutputState.cx.avail_out == 0) { + mo->next = mballoc(DEFLATE_CHUNK_LEN, MB_HDLCOUT); + olen += (mo->cnt = DEFLATE_CHUNK_LEN); + mo = mo->next; + mo->cnt = 0; + OutputState.cx.next_out = MBUF_CTOP(mo); + OutputState.cx.avail_out = DEFLATE_CHUNK_LEN; + } + } + + olen += (mo->cnt = DEFLATE_CHUNK_LEN - OutputState.cx.avail_out); + olen -= 4; /* exclude the trailing EMPTY_BLOCK */ + + /* + * If the output packet (including seqno and excluding the EMPTY_BLOCK) + * got bigger, send the original - returning 0 to HdlcOutput() will + * continue to send ``mp''. + */ + if (olen >= ilen) { + pfree(mo_head); + mbfree(mi_head); + LogPrintf(LogDEBUG, "DeflateOutput: %d => %d: Uncompressible (0x%04x)\n", + ilen, olen, proto); + CcpInfo.uncompout += ilen; + CcpInfo.compout += ilen; /* We measure this stuff too */ + return 0; + } + + pfree(mi_head); + + /* + * Lose the last four bytes of our output. + * XXX: We should probably assert that these are the same as the + * contents of EMPTY_BLOCK. + */ + for (mo = mo_head, len = mo->cnt; len < olen; mo = mo->next, len += mo->cnt) + ; + mo->cnt -= len - olen; + if (mo->next != NULL) { + pfree(mo->next); + mo->next = NULL; + } + + CcpInfo.uncompout += ilen; + CcpInfo.compout += olen; + + LogPrintf(LogDEBUG, "DeflateOutput: %d => %d bytes, proto 0x%04x\n", + ilen, olen, proto); + + HdlcOutput(PRI_NORMAL, PROTO_COMPD, mo_head); + return 1; +} + +static void +DeflateResetInput(void) +{ + InputState.seqno = 0; + inflateReset(&InputState.cx); + LogPrintf(LogCCP, "Deflate: Input channel reset\n"); +} + +static struct mbuf * +DeflateInput(u_short *proto, struct mbuf *mi) +{ + struct mbuf *mo, *mo_head, *mi_head; + u_char *wp; + int ilen, olen; + int seq, flush, res, first; + u_char hdr[2]; + + LogDumpBp(LogDEBUG, "DeflateInput: Decompress packet:", mi); + mi_head = mi = mbread(mi, hdr, 2); + ilen = 2; + + /* Check the sequence number. */ + seq = (hdr[0] << 8) + hdr[1]; + LogPrintf(LogDEBUG, "DeflateInput: Seq %d\n", seq); + if (seq != InputState.seqno) { + LogPrintf(LogERROR, "DeflateInput: Seq error: Got %d, expected %d\n", + seq, InputState.seqno); + pfree(mi_head); + CcpSendResetReq(&CcpFsm); + return NULL; + } + InputState.seqno++; + + /* Allocate an output mbuf */ + mo_head = mo = mballoc(DEFLATE_CHUNK_LEN, MB_IPIN); + + /* Our proto starts with 0 if it's compressed */ + wp = MBUF_CTOP(mo); + wp[0] = '\0'; + + /* + * We set avail_out to 1 initially so we can look at the first + * byte of the output and decide whether we have a compressed + * proto field. + */ + InputState.cx.next_in = MBUF_CTOP(mi); + InputState.cx.avail_in = mi->cnt; + InputState.cx.next_out = wp + 1; + InputState.cx.avail_out = 1; + ilen += mi->cnt; + + flush = mi->next ? Z_NO_FLUSH : Z_SYNC_FLUSH; + first = 1; + olen = 0; + + while (1) { + if ((res = inflate(&InputState.cx, flush)) != Z_OK) { + if (res == Z_STREAM_END) + break; /* Done */ + LogPrintf(LogERROR, "DeflateInput: inflate returned %d (%s)\n", + res, InputState.cx.msg ? InputState.cx.msg : ""); + pfree(mo_head); + pfree(mi); + CcpSendResetReq(&CcpFsm); + return NULL; + } + + if (flush == Z_SYNC_FLUSH && InputState.cx.avail_out != 0) + break; + + if (InputState.cx.avail_in == 0 && mi && (mi = mbfree(mi)) != NULL) { + /* underflow */ + InputState.cx.next_in = MBUF_CTOP(mi); + ilen += (InputState.cx.avail_in = mi->cnt); + if (mi->next == NULL) + flush = Z_SYNC_FLUSH; + } + + if (InputState.cx.avail_out == 0) + /* overflow */ + if (first) { + if (!(wp[1] & 1)) { + /* 2 byte proto, shuffle it back in output */ + wp[0] = wp[1]; + InputState.cx.next_out--; + InputState.cx.avail_out = DEFLATE_CHUNK_LEN-1; + } else + InputState.cx.avail_out = DEFLATE_CHUNK_LEN-2; + first = 0; + } else { + olen += (mo->cnt = DEFLATE_CHUNK_LEN); + mo->next = mballoc(DEFLATE_CHUNK_LEN, MB_IPIN); + mo = mo->next; + InputState.cx.next_out = MBUF_CTOP(mo); + InputState.cx.avail_out = DEFLATE_CHUNK_LEN; + } + } + + if (mi != NULL) + pfree(mi); + + if (first) { + LogPrintf(LogERROR, "DeflateInput: Length error\n"); + pfree(mo_head); + CcpSendResetReq(&CcpFsm); + return NULL; + } + + olen += (mo->cnt = DEFLATE_CHUNK_LEN - InputState.cx.avail_out); + + *proto = ((u_short)wp[0] << 8) | wp[1]; + mo_head->offset += 2; + mo_head->cnt -= 2; + olen -= 2; + + CcpInfo.compin += ilen; + CcpInfo.uncompin += olen; + + LogPrintf(LogDEBUG, "DeflateInput: %d => %d bytes, proto 0x%04x\n", + ilen, olen, *proto); + + /* + * Simulate an EMPTY_BLOCK so that our dictionary stays in sync. + * The peer will have silently removed this! + */ + InputState.cx.next_out = garbage; + InputState.cx.avail_out = sizeof garbage; + InputState.cx.next_in = EMPTY_BLOCK; + InputState.cx.avail_in = sizeof EMPTY_BLOCK; + inflate(&InputState.cx, Z_SYNC_FLUSH); + + return mo_head; +} + +static void +DeflateDictSetup(u_short proto, struct mbuf *mi) +{ + int res, flush; + u_char *rp; + struct mbuf *mi_head; + short len; + + LogPrintf(LogDEBUG, "DeflateDictSetup: Got seq %d\n", InputState.seqno); + + /* + * Stuff an ``uncompressed data'' block header followed by the + * protocol in front of the input + */ + mi_head = mballoc(7, MB_HDLCOUT); + mi_head->next = mi; + len = plength(mi); + mi = mi_head; + rp = MBUF_CTOP(mi); + if (proto < 0x100) { /* Compress the protocol */ + rp[5] = proto & 0377; + mi->cnt = 6; + len++; + } else { /* Don't compress the protocol */ + rp[5] = proto >> 8; + rp[6] = proto & 0377; + mi->cnt = 7; + len += 2; + } + rp[0] = 0x80; /* BITS: 100xxxxx */ + rp[1] = len & 0377; /* The length */ + rp[2] = len >> 8; + rp[3] = (~len) & 0377; /* One's compliment of the length */ + rp[4] = (~len) >> 8; + + InputState.cx.next_in = rp; + InputState.cx.avail_in = mi->cnt; + InputState.cx.next_out = garbage; + InputState.cx.avail_out = sizeof garbage; + flush = Z_NO_FLUSH; + + while (1) { + if ((res = inflate(&InputState.cx, flush)) != Z_OK) { + if (res == Z_STREAM_END) + break; /* Done */ + LogPrintf(LogERROR, "DeflateDictSetup: inflate returned %d (%s)\n", + res, InputState.cx.msg ? InputState.cx.msg : ""); + CcpSendResetReq(&CcpFsm); + mbfree(mi_head); /* lose our allocated ``head'' buf */ + return; + } + + if (flush == Z_SYNC_FLUSH && InputState.cx.avail_out != 0) + break; + + if (InputState.cx.avail_in == 0 && mi && (mi = mi->next) != NULL) { + /* underflow */ + InputState.cx.next_in = MBUF_CTOP(mi); + InputState.cx.avail_in = mi->cnt; + if (mi->next == NULL) + flush = Z_SYNC_FLUSH; + } + + if (InputState.cx.avail_out == 0) { + /* overflow */ + InputState.cx.next_out = garbage; + InputState.cx.avail_out = sizeof garbage; + } + } + + CcpInfo.compin += len; + CcpInfo.uncompin += len; + + InputState.seqno++; + mbfree(mi_head); /* lose our allocated ``head'' buf */ +} + +static const char * +DeflateDispOpts(struct lcp_opt *o) +{ + static char disp[7]; + + sprintf(disp, "win %d", (o->data[0]>>4) + 8); + return disp; +} + +static void +DeflateGetOpts(struct lcp_opt *o) +{ + o->id = TY_DEFLATE; + o->len = 4; + o->data[1] = '\0'; +} + +static void +DeflateGetInputOpts(struct lcp_opt *o) +{ + DeflateGetOpts(o); + o->data[0] = ((iWindowSize-8)<<4)+8; +} + +static void +DeflateGetOutputOpts(struct lcp_opt *o) +{ + DeflateGetOpts(o); + o->data[0] = ((oWindowSize-8)<<4)+8; +} + +static int +DeflateSetOpts(struct lcp_opt *o, int *sz) +{ + if (o->id != TY_DEFLATE || o->len != 4 || + (o->data[0]&15) != 8 || o->data[1] != '\0') { + DeflateGetOpts(o); + return MODE_REJ; + } + *sz = (o->data[0] >> 4) + 8; + if (*sz > 15) { + *sz = 15; + DeflateGetOpts(o); + return MODE_NAK; + } + + return MODE_ACK; +} + +static int +DeflateSetInputOpts(struct lcp_opt *o) +{ + return DeflateSetOpts(o, &iWindowSize); +} + +static int +DeflateSetOutputOpts(struct lcp_opt *o) +{ + return DeflateSetOpts(o, &oWindowSize); +} + +static int +DeflateInitInput(void) +{ + InputState.cx.zalloc = NULL; + InputState.cx.opaque = NULL; + InputState.cx.zfree = NULL; + InputState.cx.next_out = NULL; + if (inflateInit2(&InputState.cx, -iWindowSize) != Z_OK) + return 0; + DeflateResetInput(); + return 1; +} + +static int +DeflateInitOutput(void) +{ + OutputState.cx.zalloc = NULL; + OutputState.cx.opaque = NULL; + OutputState.cx.zfree = NULL; + OutputState.cx.next_in = NULL; + if (deflateInit2(&OutputState.cx, Z_DEFAULT_COMPRESSION, 8, + -oWindowSize, 8, Z_DEFAULT_STRATEGY) != Z_OK) + return 0; + DeflateResetOutput(); + return 1; +} + +static void +DeflateTermInput(void) +{ + iWindowSize = 15; + inflateEnd(&InputState.cx); +} + +static void +DeflateTermOutput(void) +{ + oWindowSize = 15; + deflateEnd(&OutputState.cx); +} + +const struct ccp_algorithm DeflateAlgorithm = { + TY_DEFLATE, + ConfDeflate, + DeflateDispOpts, + { + DeflateGetInputOpts, + DeflateSetInputOpts, + DeflateInitInput, + DeflateTermInput, + DeflateResetInput, + DeflateInput, + DeflateDictSetup + }, + { + DeflateGetOutputOpts, + DeflateSetOutputOpts, + DeflateInitOutput, + DeflateTermOutput, + DeflateResetOutput, + DeflateOutput + }, +}; diff --git a/usr.sbin/ppp/deflate.h b/usr.sbin/ppp/deflate.h new file mode 100644 index 0000000..a879a29 --- /dev/null +++ b/usr.sbin/ppp/deflate.h @@ -0,0 +1,5 @@ +/* + * $Id$ + */ + +extern const struct ccp_algorithm DeflateAlgorithm; diff --git a/usr.sbin/ppp/fsm.c b/usr.sbin/ppp/fsm.c index 7bf11eb..48f9d07 100644 --- a/usr.sbin/ppp/fsm.c +++ b/usr.sbin/ppp/fsm.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: fsm.c,v 1.21 1997/11/11 23:23:11 brian Exp $ + * $Id: fsm.c,v 1.22 1997/11/22 03:37:31 brian Exp $ * * TODO: * o Refer loglevel for log output @@ -44,7 +44,6 @@ #include "modem.h" #include "loadalias.h" #include "vars.h" -#include "pred.h" u_char AckBuff[200]; u_char NakBuff[200]; @@ -735,12 +734,12 @@ static void FsmRecvResetAck(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) { LogPrintf(fp->LogLevel, "RecvResetAck\n"); - Pred1Init(1); /* Initialize Input part */ + CcpResetInput(); fp->reqid++; pfree(bp); } -struct fsmcodedesc FsmCodes[] = { +static const struct fsmcodedesc FsmCodes[] = { {FsmRecvConfigReq, "Configure Request",}, {FsmRecvConfigAck, "Configure Ack",}, {FsmRecvConfigNak, "Configure Nak",}, @@ -763,7 +762,7 @@ FsmInput(struct fsm * fp, struct mbuf * bp) { int len; struct fsmheader *lhp; - struct fsmcodedesc *codep; + const struct fsmcodedesc *codep; len = plength(bp); if (len < sizeof(struct fsmheader)) { diff --git a/usr.sbin/ppp/fsm.h b/usr.sbin/ppp/fsm.h index 3c30f89..d3527af 100644 --- a/usr.sbin/ppp/fsm.h +++ b/usr.sbin/ppp/fsm.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: fsm.h,v 1.11 1997/10/26 01:02:39 brian Exp $ + * $Id: fsm.h,v 1.12 1997/11/22 03:37:32 brian Exp $ * * TODO: */ @@ -41,6 +41,7 @@ #define MODE_NAK 1 #define MODE_REJ 2 #define MODE_NOP 3 +#define MODE_ACK 4 /* pseudo mode for ccp negotiations */ #define OPEN_ACTIVE 0 #define OPEN_PASSIVE 1 diff --git a/usr.sbin/ppp/hdlc.c b/usr.sbin/ppp/hdlc.c index d6fe49a..0c9ef62 100644 --- a/usr.sbin/ppp/hdlc.c +++ b/usr.sbin/ppp/hdlc.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: hdlc.c,v 1.21 1997/10/26 12:42:10 brian Exp $ + * $Id: hdlc.c,v 1.22 1997/11/22 03:37:32 brian Exp $ * * TODO: */ @@ -46,7 +46,6 @@ #include "lqr.h" #include "loadalias.h" #include "vars.h" -#include "pred.h" #include "modem.h" #include "ccp.h" @@ -140,6 +139,26 @@ HdlcFcs(u_short fcs, u_char * cp, int len) return (fcs); } +inline u_short +HdlcFcsBuf(u_short fcs, struct mbuf *m) +{ + int len; + u_char *pos, *end; + + len = plength(m); + pos = MBUF_CTOP(m); + end = pos + m->cnt; + while (len--) { + fcs = (fcs >> 8) ^ fcstab[(fcs ^ *pos++) & 0xff]; + if (pos == end && len) { + m = m->next; + pos = MBUF_CTOP(m); + end = pos + m->cnt; + } + } + return (fcs); +} + void HdlcOutput(int pri, u_short proto, struct mbuf * bp) { @@ -149,18 +168,16 @@ HdlcOutput(int pri, u_short proto, struct mbuf * bp) u_char *cp; u_short fcs; - if ((proto & 0xfff1) == 0x21) { /* Network Layer protocol */ - if (CcpFsm.state == ST_OPENED) { - if (CcpInfo.want_proto == TY_PRED1) { - Pred1Output(pri, proto, bp); + if ((proto & 0xfff1) == 0x21) /* Network Layer protocol */ + if (CcpFsm.state == ST_OPENED) + if (CcpOutput(pri, proto, bp)) return; - } - } - } + if (DEV_IS_SYNC) mfcs = NULLBUFF; else mfcs = mballoc(2, MB_HDLCOUT); + mhp = mballoc(4, MB_HDLCOUT); mhp->cnt = 0; cp = MBUF_CTOP(mhp); @@ -182,7 +199,10 @@ HdlcOutput(int pri, u_short proto, struct mbuf * bp) mhp->cnt += 2; } mhp->next = bp; + while (bp->next != NULL) + bp = bp->next; bp->next = mfcs; + bp = mhp->next; lqr = &MyLqrData; lqr->PeerOutPackets = ifOutPackets++; @@ -216,6 +236,9 @@ HdlcOutput(int pri, u_short proto, struct mbuf * bp) if (statp->number == proto) break; statp->out_count++; + + LogPrintf(LogDEBUG, "HdlcOutput: proto = 0x%04x\n", proto); + if (DEV_IS_SYNC) ModemOutput(pri, mhp); else @@ -227,7 +250,18 @@ DecodePacket(u_short proto, struct mbuf * bp) { u_char *cp; - LogPrintf(LogDEBUG, "DecodePacket: proto = %04x\n", proto); + LogPrintf(LogDEBUG, "DecodePacket: proto = 0x%04x\n", proto); + + /* + * If proto isn't PROTO_COMPD, we still want to pass it to the + * decompression routines so that the dictionary's updated + */ + if (proto == PROTO_COMPD) { + if ((bp = CompdInput(&proto, bp)) == NULL) + return; + } else if ((proto & 0xfff1) == 0x21) /* Network Layer protocol */ + if (CcpFsm.state == ST_OPENED) + CcpDictSetup(proto, bp); switch (proto) { case PROTO_LCP: @@ -259,9 +293,6 @@ DecodePacket(u_short proto, struct mbuf * bp) case PROTO_CCP: CcpInput(bp); break; - case PROTO_COMPD: - Pred1Input(bp); - break; default: LogPrintf(LogPHASE, "Unknown protocol 0x%04x\n", proto); bp->offset -= 2; diff --git a/usr.sbin/ppp/hdlc.h b/usr.sbin/ppp/hdlc.h index 3f14cc1..7cb5234 100644 --- a/usr.sbin/ppp/hdlc.h +++ b/usr.sbin/ppp/hdlc.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: hdlc.h,v 1.11 1997/10/26 01:02:45 brian Exp $ + * $Id: hdlc.h,v 1.12 1997/11/22 03:37:33 brian Exp $ * * TODO: */ @@ -62,6 +62,7 @@ extern void HdlcErrorCheck(void); extern void HdlcInput(struct mbuf *); extern void HdlcOutput(int, u_short, struct mbuf *bp); extern u_short HdlcFcs(u_short, u_char *, int); +extern u_short HdlcFcsBuf(u_short, struct mbuf *); extern void DecodePacket(u_short, struct mbuf *); extern int ReportHdlcStatus(struct cmdargs const *); extern int ReportProtStatus(struct cmdargs const *); diff --git a/usr.sbin/ppp/ipcp.c b/usr.sbin/ppp/ipcp.c index 6e6a4c2..9628112 100644 --- a/usr.sbin/ppp/ipcp.c +++ b/usr.sbin/ppp/ipcp.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ipcp.c,v 1.37 1997/11/18 14:52:04 brian Exp $ + * $Id: ipcp.c,v 1.38 1997/11/22 03:37:34 brian Exp $ * * TODO: * o More RFC1772 backwoard compatibility @@ -145,10 +145,10 @@ ReportIpcpStatus(struct cmdargs const *arg) if (!VarTerm) return 1; fprintf(VarTerm, "%s [%s]\n", fp->name, StateNames[fp->state]); - fprintf(VarTerm, " his side: %s, %lx\n", - inet_ntoa(icp->his_ipaddr), icp->his_compproto); - fprintf(VarTerm, " my side: %s, %lx\n", - inet_ntoa(icp->want_ipaddr), icp->want_compproto); + fprintf(VarTerm, " his side: %s, %s\n", + inet_ntoa(icp->his_ipaddr), vj2asc(icp->his_compproto)); + fprintf(VarTerm, " my side: %s, %s\n", + inet_ntoa(icp->want_ipaddr), vj2asc(icp->want_compproto)); fprintf(VarTerm, "Defaults:\n"); fprintf(VarTerm, " My Address: %s/%d\n", @@ -228,18 +228,31 @@ IpcpSendConfigReq(struct fsm * fp) { u_char *cp; struct ipcpstate *icp = &IpcpInfo; + struct lcp_opt o; cp = ReqBuff; LogPrintf(LogIPCP, "IpcpSendConfigReq\n"); - if (!DEV_IS_SYNC || !REJECTED(icp, TY_IPADDR)) - PutConfValue(LogIPCP, &cp, cftypes, TY_IPADDR, 6, - ntohl(icp->want_ipaddr.s_addr)); + if (!DEV_IS_SYNC || !REJECTED(icp, TY_IPADDR)) { + o.id = TY_IPADDR; + o.len = 6; + *(u_long *)o.data = icp->want_ipaddr.s_addr; + cp += LcpPutConf(LogIPCP, cp, &o, cftypes[o.id], + inet_ntoa(icp->want_ipaddr)); + } + if (icp->want_compproto && !REJECTED(icp, TY_COMPPROTO)) { - if (icp->heis1172) - PutConfValue(LogIPCP, &cp, cftypes, TY_COMPPROTO, 4, - icp->want_compproto >> 16); - else - PutConfValue(LogIPCP, &cp, cftypes, TY_COMPPROTO, 6, icp->want_compproto); + const char *args; + o.id = TY_COMPPROTO; + if (icp->heis1172) { + o.len = 4; + *(u_short *)o.data = htons(PROTO_VJCOMP); + args = ""; + } else { + o.len = 6; + *(u_long *)o.data = htonl(icp->want_compproto); + args = vj2asc(icp->want_compproto); + } + cp += LcpPutConf(LogIPCP, cp, &o, cftypes[o.id], args); } FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); } @@ -403,7 +416,7 @@ IpcpDecodeConfig(u_char * cp, int plen, int mode_type) case TY_COMPPROTO: lp = (u_long *) (cp + 2); compproto = htonl(*lp); - LogPrintf(LogIPCP, "%s %08x\n", tbuff, compproto); + LogPrintf(LogIPCP, "%s %s\n", tbuff, vj2asc(compproto)); switch (mode_type) { case MODE_REQ: diff --git a/usr.sbin/ppp/lcp.c b/usr.sbin/ppp/lcp.c index 5bca853..ac74eed 100644 --- a/usr.sbin/ppp/lcp.c +++ b/usr.sbin/ppp/lcp.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: lcp.c,v 1.47 1997/11/18 14:52:05 brian Exp $ + * $Id: lcp.c,v 1.48 1997/11/22 03:37:35 brian Exp $ * * TODO: * o Validate magic number received from peer. @@ -36,6 +36,7 @@ #include <net/if_tun.h> #include <signal.h> +#include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -68,6 +69,14 @@ #include "modem.h" #include "tun.h" +/* for received LQRs */ +struct lqrreq { + u_char type; + u_char length; + u_short proto; /* Quality protocol */ + u_long period; /* Reporting interval */ +}; + struct lcpstate LcpInfo; static void LcpSendConfigReq(struct fsm *); @@ -80,8 +89,6 @@ static void LcpLayerDown(struct fsm *); static void LcpLayerStart(struct fsm *); static void LcpLayerFinish(struct fsm *); -#define REJECTED(p, x) (p->his_reject & (1<<x)) - static const char *cftypes[] = { /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */ "???", @@ -223,78 +230,122 @@ LcpInitRestartCounter(struct fsm * fp) fp->restart = 5; } -void -PutConfValue(int level, u_char ** cpp, const char **types, u_char type, - int len, u_long val) +int +LcpPutConf(int log, u_char *tgt, const struct lcp_opt *o, const char *nm, + const char *arg, ...) { - u_char *cp; - struct in_addr ina; - - cp = *cpp; - *cp++ = type; - *cp++ = len; - if (len == 6) { - if (type == TY_IPADDR) { - ina.s_addr = htonl(val); - LogPrintf(level, " %s [%d] %s\n", - types[type], len, inet_ntoa(ina)); - } else - LogPrintf(level, " %s [%d] %08x\n", types[type], len, val); - *cp++ = (val >> 24) & 0377; - *cp++ = (val >> 16) & 0377; - } else - LogPrintf(level, " %s [%d] %d\n", types[type], len, val); - *cp++ = (val >> 8) & 0377; - *cp++ = val & 0377; - *cpp = cp; + va_list ap; + char buf[30]; + + va_start(ap, arg); + memcpy(tgt, o, o->len); + if (arg == NULL || *arg == '\0') + LogPrintf(log, " %s[%d]\n", nm, o->len); + else { + vsnprintf(buf, sizeof buf, arg, ap); + LogPrintf(log, " %s[%d] %s\n", nm, o->len, buf); + } + va_end(ap); + + return o->len; } +#define PUTN(ty) \ +do { \ + o.id = ty; \ + o.len = 2; \ + cp += LcpPutConf(LogLCP, cp, &o, cftypes[o.id], NULL); \ +} while (0) + +#define PUTHEXL(ty, arg) \ +do { \ + o.id = ty; \ + o.len = 6; \ + *(u_long *)o.data = htonl(arg); \ + cp += LcpPutConf(LogLCP, cp, &o, cftypes[o.id], "0x%08x", (u_int)arg);\ +} while (0) + +#define PUTACCMAP(arg) PUTHEXL(TY_ACCMAP, arg) +#define PUTMAGIC(arg) PUTHEXL(TY_MAGICNUM, arg) + +#define PUTMRU(arg) \ +do { \ + o.id = TY_MRU; \ + o.len = 4; \ + *(u_short *)o.data = htons(arg); \ + cp += LcpPutConf(LogLCP, cp, &o, cftypes[o.id], "%lu", arg); \ +} while (0) + +#define PUTLQR(period) \ +do { \ + o.id = TY_QUALPROTO; \ + o.len = 8; \ + *(u_short *)o.data = htons(PROTO_LQR); \ + *(u_long *)(o.data+2) = period; \ + cp += LcpPutConf(LogLCP, cp, &o, cftypes[o.id], "period %ld", period);\ +} while (0) + +#define PUTPAP() \ +do { \ + o.id = TY_AUTHPROTO; \ + o.len = 4; \ + *(u_short *)o.data = PROTO_PAP; \ + cp += LcpPutConf(LogLCP, cp, &o, cftypes[o.id], "PAP REQ"); \ +} while (0) + +#define PUTCHAP(val) \ +do { \ + o.id = TY_AUTHPROTO; \ + o.len = 5; \ + *(u_short *)o.data = PROTO_CHAP; \ + o.data[4] = val; \ + cp += LcpPutConf(LogLCP, cp, &o, cftypes[o.id], "CHAP REQ (0x%02x)", val);\ +} while (0) + +#define PUTMD5CHAP() PUTCHAP(0x05) +#define PUTMSCHAP() PUTCHAP(0x80) + static void LcpSendConfigReq(struct fsm * fp) { u_char *cp; struct lcpstate *lcp = &LcpInfo; - struct lqrreq *req; + struct lcp_opt o; LogPrintf(LogLCP, "LcpSendConfigReq\n"); cp = ReqBuff; if (!DEV_IS_SYNC) { - if (lcp->want_acfcomp && !REJECTED(lcp, TY_ACFCOMP)) { - *cp++ = TY_ACFCOMP; - *cp++ = 2; - LogPrintf(LogLCP, " %s\n", cftypes[TY_ACFCOMP]); - } - if (lcp->want_protocomp && !REJECTED(lcp, TY_PROTOCOMP)) { - *cp++ = TY_PROTOCOMP; - *cp++ = 2; - LogPrintf(LogLCP, " %s\n", cftypes[TY_PROTOCOMP]); - } + if (lcp->want_acfcomp && !REJECTED(lcp, TY_ACFCOMP)) + PUTN(TY_ACFCOMP); + + if (lcp->want_protocomp && !REJECTED(lcp, TY_PROTOCOMP)) + PUTN(TY_PROTOCOMP); + if (!REJECTED(lcp, TY_ACCMAP)) - PutConfValue(LogLCP, &cp, cftypes, TY_ACCMAP, 6, lcp->want_accmap); + PUTACCMAP(lcp->want_accmap); } + if (!REJECTED(lcp, TY_MRU)) - PutConfValue(LogLCP, &cp, cftypes, TY_MRU, 4, lcp->want_mru); + PUTMRU(lcp->want_mru); + if (lcp->want_magic && !REJECTED(lcp, TY_MAGICNUM)) - PutConfValue(LogLCP, &cp, cftypes, TY_MAGICNUM, 6, lcp->want_magic); - if (lcp->want_lqrperiod && !REJECTED(lcp, TY_QUALPROTO)) { - req = (struct lqrreq *) cp; - req->type = TY_QUALPROTO; - req->length = sizeof(struct lqrreq); - req->proto = htons(PROTO_LQR); - req->period = htonl(lcp->want_lqrperiod); - cp += sizeof(struct lqrreq); - LogPrintf(LogLCP, " %s (%d)\n", cftypes[TY_QUALPROTO], lcp->want_lqrperiod); - } + PUTMAGIC(lcp->want_magic); + + if (lcp->want_lqrperiod && !REJECTED(lcp, TY_QUALPROTO)) + PUTLQR(lcp->want_lqrperiod); + switch (lcp->want_auth) { case PROTO_PAP: - PutConfValue(LogLCP, &cp, cftypes, TY_AUTHPROTO, 4, lcp->want_auth); + PUTPAP(); break; + case PROTO_CHAP: - PutConfValue(LogLCP, &cp, cftypes, TY_AUTHPROTO, 5, lcp->want_auth); #ifdef HAVE_DES - *cp++ = VarMSChap ? 0x80 : 0x05; /* Use MSChap vs. RFC 1994 (MD5) */ + if (VarMSChap) + PUTMSCHAP(); /* Use MSChap */ + else #else - *cp++ = 0x05; /* Use MD5 */ + PUTMD5CHAP(); /* Use MD5 */ #endif break; } @@ -420,13 +471,13 @@ LcpClose() * XXX: Should validate option length */ static void -LcpDecodeConfig(u_char * cp, int plen, int mode_type) +LcpDecodeConfig(u_char *cp, int plen, int mode_type) { - const char *request; - int type, length, mru, mtu; + int type, length, mru, mtu, sz, pos; u_long *lp, magic, accmap; u_short *sp, proto; struct lqrreq *req; + char request[20], desc[22]; ackp = AckBuff; nakp = NakBuff; @@ -435,16 +486,17 @@ LcpDecodeConfig(u_char * cp, int plen, int mode_type) while (plen >= sizeof(struct fsmconfig)) { type = *cp; length = cp[1]; - if (type < NCFTYPES) - request = cftypes[type]; + + if (type < 0 || type >= NCFTYPES) + snprintf(request, sizeof request, " <%d>[%d]", type, length); else - request = "???"; + snprintf(request, sizeof request, " %s[%d]", cftypes[type], length); switch (type) { case TY_MRU: sp = (u_short *) (cp + 2); mru = htons(*sp); - LogPrintf(LogLCP, " %s %d\n", request, mru); + LogPrintf(LogLCP, "%s %d\n", request, mru); switch (mode_type) { case MODE_REQ: @@ -474,10 +526,11 @@ LcpDecodeConfig(u_char * cp, int plen, int mode_type) break; } break; + case TY_ACCMAP: lp = (u_long *) (cp + 2); accmap = htonl(*lp); - LogPrintf(LogLCP, " %s %08x\n", request, accmap); + LogPrintf(LogLCP, "%s 0x%08x\n", request, accmap); switch (mode_type) { case MODE_REQ: @@ -493,17 +546,18 @@ LcpDecodeConfig(u_char * cp, int plen, int mode_type) break; } break; + case TY_AUTHPROTO: sp = (u_short *) (cp + 2); proto = ntohs(*sp); - LogPrintf(LogLCP, " %s proto = %04x\n", request, proto); + LogPrintf(LogLCP, "%s 0x%04x\n", request, proto); switch (mode_type) { case MODE_REQ: switch (proto) { case PROTO_PAP: if (length != 4) { - LogPrintf(LogLCP, " %s bad length (%d)\n", request, length); + LogPrintf(LogLCP, " Bad length!\n"); goto reqreject; } if (Acceptable(ConfPap)) { @@ -519,9 +573,10 @@ LcpDecodeConfig(u_char * cp, int plen, int mode_type) } else goto reqreject; break; + case PROTO_CHAP: if (length < 5) { - LogPrintf(LogLCP, " %s bad length (%d)\n", request, length); + LogPrintf(LogLCP, " Bad length!\n"); goto reqreject; } #ifdef HAVE_DES @@ -544,8 +599,9 @@ LcpDecodeConfig(u_char * cp, int plen, int mode_type) } else goto reqreject; break; + default: - LogPrintf(LogLCP, " %s not implemented, NAK.\n", request); + LogPrintf(LogLCP, " proto %d not implemented, NAK.\n", proto); memcpy(nakp, cp, length); nakp += length; break; @@ -558,10 +614,11 @@ LcpDecodeConfig(u_char * cp, int plen, int mode_type) break; } break; + case TY_QUALPROTO: req = (struct lqrreq *) cp; - LogPrintf(LogLCP, " %s proto: %x, interval: %dms\n", - request, ntohs(req->proto), ntohl(req->period) * 10); + LogPrintf(LogLCP, "%s proto %x, interval %dms\n", + request, ntohs(req->proto), ntohl(req->period) * 10); switch (mode_type) { case MODE_REQ: if (ntohs(req->proto) != PROTO_LQR || !Acceptable(ConfLqr)) @@ -582,10 +639,11 @@ LcpDecodeConfig(u_char * cp, int plen, int mode_type) break; } break; + case TY_MAGICNUM: lp = (u_long *) (cp + 2); magic = ntohl(*lp); - LogPrintf(LogLCP, " %s %08x\n", request, magic); + LogPrintf(LogLCP, "%s 0x%08x\n", request, magic); switch (mode_type) { case MODE_REQ: @@ -611,18 +669,19 @@ LcpDecodeConfig(u_char * cp, int plen, int mode_type) } break; case MODE_NAK: - LogPrintf(LogLCP, " %s magic %08x has NAKed\n", request, magic); + LogPrintf(LogLCP, " Magic 0x%08x is NAKed!\n", magic); LcpInfo.want_magic = GenerateMagic(); break; case MODE_REJ: - LogPrintf(LogLCP, " %s magic has REJected\n", request); + LogPrintf(LogLCP, " Magic 0x%80x is REJected!\n", magic); LcpInfo.want_magic = 0; LcpInfo.his_reject |= (1 << type); break; } break; + case TY_PROTOCOMP: - LogPrintf(LogLCP, " %s\n", request); + LogPrintf(LogLCP, "%s\n", request); switch (mode_type) { case MODE_REQ: @@ -651,8 +710,9 @@ LcpDecodeConfig(u_char * cp, int plen, int mode_type) break; } break; + case TY_ACFCOMP: - LogPrintf(LogLCP, " %s\n", request); + LogPrintf(LogLCP, "%s\n", request); switch (mode_type) { case MODE_REQ: if (Acceptable(ConfAcfcomp)) { @@ -680,8 +740,9 @@ LcpDecodeConfig(u_char * cp, int plen, int mode_type) break; } break; + case TY_SDP: - LogPrintf(LogLCP, " %s\n", request); + LogPrintf(LogLCP, "%s\n", request); switch (mode_type) { case MODE_REQ: case MODE_NAK: @@ -689,13 +750,30 @@ LcpDecodeConfig(u_char * cp, int plen, int mode_type) break; } break; + default: - LogPrintf(LogLCP, " %s[02x]\n", request, type); + sz = (sizeof(desc)-2)/2; + if (sz > length - 2) + sz = length - 2; + pos = 0; + desc[0] = sz ? ' ' : '\0'; + for (pos = 0; sz--; pos++) + sprintf(desc+(pos<<1)+1, "%02x", cp[pos+2]); + + LogPrintf(LogLCP, "%s%s\n", request, desc); + if (mode_type == MODE_REQ) { - reqreject: +reqreject: + if (length > sizeof(RejBuff) - (rejp - RejBuff)) { + length = sizeof(RejBuff) - (rejp - RejBuff); + LogPrintf(LogLCP, "Can't REJ length %d - trunating to %d\n", + cp[1], length); + } memcpy(rejp, cp, length); rejp += length; LcpInfo.my_reject |= (1 << type); + if (length != cp[1]) + return; } break; } diff --git a/usr.sbin/ppp/lcp.h b/usr.sbin/ppp/lcp.h index ea5388c..9bf9b00 100644 --- a/usr.sbin/ppp/lcp.h +++ b/usr.sbin/ppp/lcp.h @@ -15,11 +15,13 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: lcp.h,v 1.12 1997/11/14 15:39:15 brian Exp $ + * $Id: lcp.h,v 1.13 1997/11/22 03:37:36 brian Exp $ * * TODO: */ +#define REJECTED(p, x) (p->his_reject & (1<<x)) + struct lcpstate { u_long his_mru; u_long his_accmap; @@ -57,13 +59,14 @@ struct lcpstate { #define TY_FCSALT 9 /* FCS-Alternatives */ #define TY_SDP 10 /* Self-Describing-Padding */ -struct lqrreq { - u_char type; - u_char length; - u_short proto; /* Quality protocol */ - u_long period; /* Reporting interval */ +#define MAX_LCP_OPT_LEN 10 +struct lcp_opt { + u_char id; + u_char len; + u_char data[MAX_LCP_OPT_LEN-2]; }; + extern struct lcpstate LcpInfo; extern struct fsm LcpFsm; @@ -73,6 +76,7 @@ extern void LcpSendProtoRej(u_char *, int); extern void LcpOpen(int); extern void LcpClose(void); extern void LcpDown(void); -extern void PutConfValue(int, u_char **, const char **, u_char, int, u_long); +extern int LcpPutConf(int, u_char *, const struct lcp_opt *, const char *, + const char *, ...); extern int ReportLcpStatus(struct cmdargs const *); extern void LcpInput(struct mbuf *); diff --git a/usr.sbin/ppp/main.c b/usr.sbin/ppp/main.c index 10add86..c7baf09 100644 --- a/usr.sbin/ppp/main.c +++ b/usr.sbin/ppp/main.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: main.c,v 1.104 1997/11/18 18:17:25 brian Exp $ + * $Id: main.c,v 1.105 1997/11/22 03:37:39 brian Exp $ * * TODO: * o Add commands for traffic summary, version display, etc. @@ -61,8 +61,8 @@ #include "modem.h" #include "os.h" #include "hdlc.h" -#include "ccp.h" #include "lcp.h" +#include "ccp.h" #include "ipcp.h" #include "loadalias.h" #include "vars.h" @@ -748,12 +748,9 @@ DoLoop(void) int tries; int qlen; int res; - pid_t pgroup; struct tun_data tun; #define rbuff tun.data - pgroup = getpgrp(); - if (mode & MODE_DIRECT) { LogPrintf(LogDEBUG, "Opening modem\n"); if (OpenModem() < 0) @@ -976,48 +973,46 @@ DoLoop(void) IsInteractive(1); Prompt(); } - if (netfd >= 0 && FD_ISSET(netfd, &rfds) && - ((mode & MODE_OUTGOING_DAEMON) || pgroup == tcgetpgrp(0))) { + if (netfd >= 0 && FD_ISSET(netfd, &rfds)) /* something to read from tty */ ReadTty(); + if (modem >= 0 && FD_ISSET(modem, &wfds)) { + /* ready to write into modem */ + ModemStartOutput(modem); + if (modem < 0) + dial_up = 1; } - if (modem >= 0) { - if (FD_ISSET(modem, &wfds)) { /* ready to write into modem */ - ModemStartOutput(modem); - } - if (FD_ISSET(modem, &rfds)) { /* something to read from modem */ - if (LcpFsm.state <= ST_CLOSED) - nointr_usleep(10000); - n = read(modem, rbuff, sizeof(rbuff)); - if ((mode & MODE_DIRECT) && n <= 0) { - DownConnection(); - } else - LogDumpBuff(LogASYNC, "ReadFromModem", rbuff, n); - - if (LcpFsm.state <= ST_CLOSED) { + if (modem >= 0 && FD_ISSET(modem, &rfds)) { + /* something to read from modem */ + if (LcpFsm.state <= ST_CLOSED) + nointr_usleep(10000); + n = read(modem, rbuff, sizeof(rbuff)); + if ((mode & MODE_DIRECT) && n <= 0) { + DownConnection(); + } else + LogDumpBuff(LogASYNC, "ReadFromModem", rbuff, n); - /* - * In dedicated mode, we just discard input until LCP is started. - */ - if (!(mode & MODE_DEDICATED)) { - cp = HdlcDetect(rbuff, n); - if (cp) { - - /* - * LCP packet is detected. Turn ourselves into packet mode. - */ - if (cp != rbuff) { - write(modem, rbuff, cp - rbuff); - write(modem, "\r\n", 2); - } - PacketMode(); - } else - write(fileno(VarTerm), rbuff, n); - } - } else { - if (n > 0) - AsyncInput(rbuff, n); + if (LcpFsm.state <= ST_CLOSED) { + /* + * In dedicated mode, we just discard input until LCP is started. + */ + if (!(mode & MODE_DEDICATED)) { + cp = HdlcDetect(rbuff, n); + if (cp) { + /* + * LCP packet is detected. Turn ourselves into packet mode. + */ + if (cp != rbuff) { + write(modem, rbuff, cp - rbuff); + write(modem, "\r\n", 2); + } + PacketMode(); + } else + write(fileno(VarTerm), rbuff, n); } + } else { + if (n > 0) + AsyncInput(rbuff, n); } } if (tun_in >= 0 && FD_ISSET(tun_in, &rfds)) { /* something to read diff --git a/usr.sbin/ppp/mbuf.h b/usr.sbin/ppp/mbuf.h index cdf38af..6877126 100644 --- a/usr.sbin/ppp/mbuf.h +++ b/usr.sbin/ppp/mbuf.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: mbuf.h,v 1.8 1997/10/26 12:42:13 brian Exp $ + * $Id: mbuf.h,v 1.9 1997/11/22 03:37:40 brian Exp $ * * TODO: */ @@ -58,6 +58,5 @@ extern struct mbuf *mbfree(struct mbuf *); extern void pfree(struct mbuf *); extern void mbwrite(struct mbuf *, u_char *, int); extern struct mbuf *mbread(struct mbuf *, u_char *, int); -extern void DumpBp(struct mbuf *); extern void LogMemory(void); extern int ShowMemMap(struct cmdargs const *); diff --git a/usr.sbin/ppp/os.c b/usr.sbin/ppp/os.c index 025a24e..1f13b34 100644 --- a/usr.sbin/ppp/os.c +++ b/usr.sbin/ppp/os.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: os.c,v 1.34 1997/11/16 22:15:07 brian Exp $ + * $Id: os.c,v 1.35 1997/11/22 03:37:42 brian Exp $ * */ #include <sys/param.h> @@ -55,6 +55,7 @@ #include "arp.h" #include "systems.h" #include "route.h" +#include "lcp.h" #include "ccp.h" #include "modem.h" diff --git a/usr.sbin/ppp/ppp.8 b/usr.sbin/ppp/ppp.8 index 949e5df..a607e55 100644 --- a/usr.sbin/ppp/ppp.8 +++ b/usr.sbin/ppp/ppp.8 @@ -1,4 +1,4 @@ -.\" $Id: ppp.8,v 1.79 1997/11/14 20:07:39 brian Exp $ +.\" $Id: ppp.8,v 1.80 1997/11/18 14:52:06 brian Exp $ .Dd 20 September 1995 .Os FreeBSD .Dt PPP 8 @@ -1061,7 +1061,7 @@ the current IETF-draft specs. As a default behaviour, will attempt to use (or be willing to accept) this capability when the peer agrees (or requests it). -To disable CCP/predictor functionality completely, use the +To disable CCP/predictor1 functionality completely, use the .Dq disable pred1 and .Dq deny pred1 @@ -1587,6 +1587,14 @@ challenge. Refer to the description of the .Dq set encrypt command for further details. +.It deflate +Default: Enabled and Accepted. This option decides if deflate +compression will be used by the Compression Control Protocol (CCP). +This is the same algorithm as used by the +.Xr gzip 1 +program. + + .It lqr Default: Disabled and Accepted. This option decides if Link Quality Requests will be sent. LQR is a protocol that allows @@ -1594,13 +1602,6 @@ Requests will be sent. LQR is a protocol that allows to determine that the link is down without relying on the modems carrier detect. -.It msext -Default: Disabled. This option allows the use of Microsoft's -.Em PPP -extensions, supporting the negotiation of the DNS and the NetBIOS NS. -Enabling this allows us to pass back the values given in "set ns" -and "set nbns". - .It pap Default: Disabled and Accepted. PAP stands for Password Authentication Protocol. Only one of PAP and CHAP (above) may be negotiated. With @@ -1629,7 +1630,7 @@ PAP is accepted by default. .It pred1 Default: Enabled and Accepted. This option decides if Predictor 1 -compression will be used. +compression will be used by the Compression Control Protocol (CCP). .It protocomp Default: Enabled and Accepted. This option is used to negotiate @@ -1646,6 +1647,13 @@ The following options are not actually negotiated with the peer. Therefore, accepting or denying them makes no sense. .Bl -tag -width 20 +.It msext +Default: Disabled. This option allows the use of Microsoft's +.Em PPP +extensions, supporting the negotiation of the DNS and the NetBIOS NS. +Enabling this allows us to pass back the values given in "set ns" +and "set nbns". + .It passwdauth Default: Disabled. Enabling this option will tell the PAP authentication code to use the password file (see @@ -2430,6 +2438,7 @@ Get port number if port number is using service name. .Xr crontab 5 , .Xr ftp 1 , .Xr getty 8 , +.Xr gzip 1 , .Xr hostname 1 , .Xr inetd 8 , .Xr init 8 , @@ -2451,3 +2460,7 @@ Get port number if port number is using service name. This program was originally written by Toshiharu OHNO (tony-o@iij.ad.jp), and was submitted to FreeBSD-2.0.5 by Atsushi Murai (amurai@spec.co.jp). It has since had an enormous face lift and looks substantially different. + +.Pp +The zlib compression algorithms used in the DEFLATE protocol are provided +thanks to Jean-loup Gailly (Copyright 1995). diff --git a/usr.sbin/ppp/ppp.8.m4 b/usr.sbin/ppp/ppp.8.m4 index 949e5df..a607e55 100644 --- a/usr.sbin/ppp/ppp.8.m4 +++ b/usr.sbin/ppp/ppp.8.m4 @@ -1,4 +1,4 @@ -.\" $Id: ppp.8,v 1.79 1997/11/14 20:07:39 brian Exp $ +.\" $Id: ppp.8,v 1.80 1997/11/18 14:52:06 brian Exp $ .Dd 20 September 1995 .Os FreeBSD .Dt PPP 8 @@ -1061,7 +1061,7 @@ the current IETF-draft specs. As a default behaviour, will attempt to use (or be willing to accept) this capability when the peer agrees (or requests it). -To disable CCP/predictor functionality completely, use the +To disable CCP/predictor1 functionality completely, use the .Dq disable pred1 and .Dq deny pred1 @@ -1587,6 +1587,14 @@ challenge. Refer to the description of the .Dq set encrypt command for further details. +.It deflate +Default: Enabled and Accepted. This option decides if deflate +compression will be used by the Compression Control Protocol (CCP). +This is the same algorithm as used by the +.Xr gzip 1 +program. + + .It lqr Default: Disabled and Accepted. This option decides if Link Quality Requests will be sent. LQR is a protocol that allows @@ -1594,13 +1602,6 @@ Requests will be sent. LQR is a protocol that allows to determine that the link is down without relying on the modems carrier detect. -.It msext -Default: Disabled. This option allows the use of Microsoft's -.Em PPP -extensions, supporting the negotiation of the DNS and the NetBIOS NS. -Enabling this allows us to pass back the values given in "set ns" -and "set nbns". - .It pap Default: Disabled and Accepted. PAP stands for Password Authentication Protocol. Only one of PAP and CHAP (above) may be negotiated. With @@ -1629,7 +1630,7 @@ PAP is accepted by default. .It pred1 Default: Enabled and Accepted. This option decides if Predictor 1 -compression will be used. +compression will be used by the Compression Control Protocol (CCP). .It protocomp Default: Enabled and Accepted. This option is used to negotiate @@ -1646,6 +1647,13 @@ The following options are not actually negotiated with the peer. Therefore, accepting or denying them makes no sense. .Bl -tag -width 20 +.It msext +Default: Disabled. This option allows the use of Microsoft's +.Em PPP +extensions, supporting the negotiation of the DNS and the NetBIOS NS. +Enabling this allows us to pass back the values given in "set ns" +and "set nbns". + .It passwdauth Default: Disabled. Enabling this option will tell the PAP authentication code to use the password file (see @@ -2430,6 +2438,7 @@ Get port number if port number is using service name. .Xr crontab 5 , .Xr ftp 1 , .Xr getty 8 , +.Xr gzip 1 , .Xr hostname 1 , .Xr inetd 8 , .Xr init 8 , @@ -2451,3 +2460,7 @@ Get port number if port number is using service name. This program was originally written by Toshiharu OHNO (tony-o@iij.ad.jp), and was submitted to FreeBSD-2.0.5 by Atsushi Murai (amurai@spec.co.jp). It has since had an enormous face lift and looks substantially different. + +.Pp +The zlib compression algorithms used in the DEFLATE protocol are provided +thanks to Jean-loup Gailly (Copyright 1995). diff --git a/usr.sbin/ppp/pred.c b/usr.sbin/ppp/pred.c index 3b4cfff..23b9ec3 100644 --- a/usr.sbin/ppp/pred.c +++ b/usr.sbin/ppp/pred.c @@ -5,24 +5,28 @@ * Updated by: Carsten Bormann <cabo@cs.tu-berlin.de> * Original : Dave Rand <dlr@bungi.com>/<dave_rand@novell.com> * - * $Id: pred.c,v 1.16 1997/11/09 06:22:46 brian Exp $ + * $Id: pred.c,v 1.17 1997/11/22 03:37:44 brian Exp $ * */ -#include <sys/types.h> +#include <sys/param.h> #include <netinet/in.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include "command.h" #include "mbuf.h" #include "log.h" #include "defs.h" +#include "loadalias.h" +#include "vars.h" #include "timer.h" #include "fsm.h" #include "hdlc.h" #include "lcpproto.h" +#include "lcp.h" #include "ccp.h" #include "pred.h" @@ -34,10 +38,11 @@ */ #define IHASH(x) do {iHash = (iHash << 4) ^ (x);} while(0) #define OHASH(x) do {oHash = (oHash << 4) ^ (x);} while(0) +#define GUESS_TABLE_SIZE 65536 static unsigned short int iHash, oHash; -static unsigned char InputGuessTable[65536]; -static unsigned char OutputGuessTable[65536]; +static unsigned char *InputGuessTable; +static unsigned char *OutputGuessTable; static int compress(u_char * source, u_char * dest, int len) @@ -102,20 +107,61 @@ decompress(u_char * source, u_char * dest, int len) return (dest - orgdest); } -void -Pred1Init(int direction) +static void +Pred1TermInput(void) { - if (direction & 1) { /* Input part */ - iHash = 0; - memset(InputGuessTable, '\0', sizeof(InputGuessTable)); + if (InputGuessTable != NULL) { + free(InputGuessTable); + InputGuessTable = NULL; } - if (direction & 2) { /* Output part */ - oHash = 0; - memset(OutputGuessTable, '\0', sizeof(OutputGuessTable)); +} + +static void +Pred1TermOutput(void) +{ + if (OutputGuessTable != NULL) { + free(OutputGuessTable); + OutputGuessTable = NULL; } } -void +static void +Pred1ResetInput(void) +{ + iHash = 0; + memset(InputGuessTable, '\0', GUESS_TABLE_SIZE); + LogPrintf(LogCCP, "Predictor1: Input channel reset\n"); +} + +static void +Pred1ResetOutput(void) +{ + oHash = 0; + memset(OutputGuessTable, '\0', GUESS_TABLE_SIZE); + LogPrintf(LogCCP, "Predictor1: Output channel reset\n"); +} + +static int +Pred1InitInput(void) +{ + if (InputGuessTable == NULL) + if ((InputGuessTable = malloc(GUESS_TABLE_SIZE)) == NULL) + return 0; + Pred1ResetInput(); + return 1; +} + +static int +Pred1InitOutput(void) +{ + if (OutputGuessTable == NULL) + if ((OutputGuessTable = malloc(GUESS_TABLE_SIZE)) == NULL) + return 0; + Pred1ResetOutput(); + return 1; +} + +static int Pred1Output(int pri, u_short proto, struct mbuf * bp) { struct mbuf *mwp; @@ -138,7 +184,7 @@ Pred1Output(int pri, u_short proto, struct mbuf * bp) len = compress(bufp + 2, wp, orglen); LogPrintf(LogDEBUG, "Pred1Output: orglen (%d) --> len (%d)\n", orglen, len); - CcpInfo.orgout += orglen; + CcpInfo.uncompout += orglen; if (len < orglen) { *hp |= 0x80; wp += len; @@ -153,16 +199,17 @@ Pred1Output(int pri, u_short proto, struct mbuf * bp) *wp++ = fcs >> 8; mwp->cnt = wp - MBUF_CTOP(mwp); HdlcOutput(PRI_NORMAL, PROTO_COMPD, mwp); + return 1; } -void -Pred1Input(struct mbuf * bp) +static struct mbuf * +Pred1Input(u_short *proto, struct mbuf *bp) { u_char *cp, *pp; int len, olen, len1; struct mbuf *wp; u_char *bufp; - u_short fcs, proto; + u_short fcs; wp = mballoc(MAX_MTU + 2, MB_IPIN); cp = MBUF_CTOP(bp); @@ -172,17 +219,17 @@ Pred1Input(struct mbuf * bp) len = *cp++ << 8; *pp++ = *cp; len += *cp++; - CcpInfo.orgin += len & 0x7fff; + CcpInfo.uncompin += 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(LogLCP, "%s: Length Error\n", CcpFsm.name); + LogPrintf(LogCCP, "Pred1: Length error\n"); CcpSendResetReq(&CcpFsm); pfree(bp); pfree(wp); - return; + return NULL; } cp += olen - 4; pp += len1; @@ -203,20 +250,72 @@ Pred1Input(struct mbuf * bp) wp->offset += 2; /* skip length */ wp->cnt -= 4; /* skip length & CRC */ pp = MBUF_CTOP(wp); - proto = *pp++; - if (proto & 1) { + *proto = *pp++; + if (*proto & 1) { wp->offset++; wp->cnt--; } else { wp->offset += 2; wp->cnt -= 2; - proto = (proto << 8) | *pp++; + *proto = (*proto << 8) | *pp++; } - DecodePacket(proto, wp); + return wp; } else { LogDumpBp(LogHDLC, "Bad FCS", wp); CcpSendResetReq(&CcpFsm); pfree(wp); } pfree(bp); + return NULL; +} + +static void +Pred1DictSetup(u_short proto, struct mbuf * bp) +{ +} + +static const char * +Pred1DispOpts(struct lcp_opt *o) +{ + return NULL; } + +static void +Pred1GetOpts(struct lcp_opt *o) +{ + o->id = TY_PRED1; + o->len = 2; +} + +static int +Pred1SetOpts(struct lcp_opt *o) +{ + if (o->id != TY_PRED1 || o->len != 2) { + Pred1GetOpts(o); + return MODE_NAK; + } + return MODE_ACK; +} + +const struct ccp_algorithm Pred1Algorithm = { + TY_PRED1, + ConfPred1, + Pred1DispOpts, + { + Pred1GetOpts, + Pred1SetOpts, + Pred1InitInput, + Pred1TermInput, + Pred1ResetInput, + Pred1Input, + Pred1DictSetup + }, + { + Pred1GetOpts, + Pred1SetOpts, + Pred1InitOutput, + Pred1TermOutput, + Pred1ResetOutput, + Pred1Output + }, +}; diff --git a/usr.sbin/ppp/pred.h b/usr.sbin/ppp/pred.h index 9bcc21b..08a0911 100644 --- a/usr.sbin/ppp/pred.h +++ b/usr.sbin/ppp/pred.h @@ -15,11 +15,9 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: pred.h,v 1.5 1997/08/25 00:29:26 brian Exp $ + * $Id: pred.h,v 1.6 1997/10/26 01:03:35 brian Exp $ * * TODO: */ -extern void Pred1Output(int, u_short, struct mbuf *); -extern void Pred1Input(struct mbuf *); -extern void Pred1Init(int); +extern const struct ccp_algorithm Pred1Algorithm; diff --git a/usr.sbin/ppp/server.c b/usr.sbin/ppp/server.c index cb7884b..d55dbb4 100644 --- a/usr.sbin/ppp/server.c +++ b/usr.sbin/ppp/server.c @@ -1,5 +1,5 @@ /* - * $Id: server.c,v 1.10 1997/11/11 22:58:13 brian Exp $ + * $Id: server.c,v 1.11 1997/11/22 03:37:45 brian Exp $ */ #include <sys/param.h> @@ -69,7 +69,6 @@ ServerLocalOpen(const char *name, mode_t mask) if (errno == EADDRINUSE && VarTerm) fprintf(VarTerm, "Wait for a while, then try again.\n"); close(s); - ID0unlink(name); return 4; } if (mask != (mode_t)-1) diff --git a/usr.sbin/ppp/vars.c b/usr.sbin/ppp/vars.c index 8c5b724..fde9089 100644 --- a/usr.sbin/ppp/vars.c +++ b/usr.sbin/ppp/vars.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: vars.c,v 1.36 1997/11/22 03:37:53 brian Exp $ + * $Id: vars.c,v 1.37 1997/11/22 13:47:02 brian Exp $ * */ #include <sys/param.h> @@ -39,7 +39,7 @@ #include "auth.h" char VarVersion[] = "PPP Version 1.5"; -char VarLocalVersion[] = "$Date: 1997/11/22 03:37:53 $"; +char VarLocalVersion[] = "$Date: 1997/11/22 13:47:02 $"; int Utmp = 0; int ipInOctets = 0; int ipOutOctets = 0; @@ -53,18 +53,19 @@ int reconnectCount = 0; * Order of conf option is important. See vars.h. */ struct confdesc pppConfs[] = { - {"vjcomp", CONF_ENABLE, CONF_ACCEPT}, - {"lqr", CONF_DISABLE, CONF_ACCEPT}, + {"acfcomp", CONF_ENABLE, CONF_ACCEPT}, {"chap", CONF_DISABLE, CONF_ACCEPT}, + {"deflate", CONF_ENABLE, CONF_ACCEPT}, + {"lqr", CONF_DISABLE, CONF_ACCEPT}, {"pap", CONF_DISABLE, CONF_ACCEPT}, - {"acfcomp", CONF_ENABLE, CONF_ACCEPT}, - {"protocomp", CONF_ENABLE, CONF_ACCEPT}, {"pred1", CONF_ENABLE, CONF_ACCEPT}, - {"proxy", CONF_DISABLE, CONF_NONE}, + {"protocomp", CONF_ENABLE, CONF_ACCEPT}, + {"vjcomp", CONF_ENABLE, CONF_ACCEPT}, {"msext", CONF_DISABLE, CONF_NONE}, {"passwdauth", CONF_DISABLE, CONF_NONE}, - {"utmp", CONF_ENABLE, CONF_NONE}, + {"proxy", CONF_DISABLE, CONF_NONE}, {"throughput", CONF_DISABLE, CONF_NONE}, + {"utmp", CONF_ENABLE, CONF_NONE}, {NULL}, }; diff --git a/usr.sbin/ppp/vars.h b/usr.sbin/ppp/vars.h index 79f4f82..5f6cf88 100644 --- a/usr.sbin/ppp/vars.h +++ b/usr.sbin/ppp/vars.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: vars.h,v 1.34 1997/11/18 14:52:08 brian Exp $ + * $Id: vars.h,v 1.35 1997/11/22 03:37:54 brian Exp $ * * TODO: */ @@ -32,19 +32,21 @@ struct confdesc { #define CONF_DENY 0 #define CONF_ACCEPT 1 -#define ConfVjcomp 0 -#define ConfLqr 1 -#define ConfChap 2 -#define ConfPap 3 -#define ConfAcfcomp 4 -#define ConfProtocomp 5 -#define ConfPred1 6 -#define ConfProxy 7 +#define ConfAcfcomp 0 +#define ConfChap 1 +#define ConfDeflate 2 +#define ConfLqr 3 +#define ConfPap 4 +#define ConfPred1 5 +#define ConfProtocomp 6 +#define ConfVjcomp 7 + #define ConfMSExt 8 #define ConfPasswdAuth 9 -#define ConfUtmp 10 +#define ConfProxy 10 #define ConfThroughput 11 -#define MAXCONFS 12 +#define ConfUtmp 12 +#define MAXCONFS 13 #define Enabled(x) (pppConfs[x].myside & CONF_ENABLE) #define Acceptable(x) (pppConfs[x].hisside & CONF_ACCEPT) diff --git a/usr.sbin/ppp/vjcomp.c b/usr.sbin/ppp/vjcomp.c index c0fc76f..74e4371 100644 --- a/usr.sbin/ppp/vjcomp.c +++ b/usr.sbin/ppp/vjcomp.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: vjcomp.c,v 1.12 1997/11/09 06:22:49 brian Exp $ + * $Id: vjcomp.c,v 1.13 1997/11/22 03:37:54 brian Exp $ * * TODO: */ @@ -55,14 +55,14 @@ void SendPppFrame(struct mbuf * bp) { int type; - int proto; - int cproto = IpcpInfo.his_compproto >> 16; + u_short proto; + u_short cproto = IpcpInfo.his_compproto >> 16; LogPrintf(LogDEBUG, "SendPppFrame: proto = %x\n", IpcpInfo.his_compproto); if (((struct ip *) MBUF_CTOP(bp))->ip_p == IPPROTO_TCP && cproto == PROTO_VJCOMP) { - type = sl_compress_tcp(bp, (struct ip *) MBUF_CTOP(bp), &cslc, IpcpInfo.his_compproto & 0xff); - + type = sl_compress_tcp(bp, (struct ip *)MBUF_CTOP(bp), &cslc, + IpcpInfo.his_compproto & 0xff); LogPrintf(LogDEBUG, "SendPppFrame: type = %x\n", type); switch (type) { case TYPE_IP: @@ -153,3 +153,13 @@ VjCompInput(struct mbuf * bp, int proto) bp = VjUncompressTcp(bp, type); return (bp); } + +const char * +vj2asc(u_long val) +{ + static char asc[50]; + + sprintf(asc, "%ld VJ slots %s slot compression", + ((val>>8)&15)+1, val & 1 ? "with" : "without"); + return asc; +} diff --git a/usr.sbin/ppp/vjcomp.h b/usr.sbin/ppp/vjcomp.h index 221b591..1589044 100644 --- a/usr.sbin/ppp/vjcomp.h +++ b/usr.sbin/ppp/vjcomp.h @@ -1,7 +1,8 @@ /* - * $Id: vjcomp.h,v 1.1 1997/10/26 01:04:02 brian Exp $ + * $Id: vjcomp.h,v 1.2 1997/10/26 12:42:13 brian Exp $ */ extern void VjInit(int); extern void SendPppFrame(struct mbuf *); extern struct mbuf *VjCompInput(struct mbuf *, int); +extern const char *vj2asc(u_long); |