From 8f517ba05c9bd73d278c31713cb99d9cbc471e36 Mon Sep 17 00:00:00 2001 From: brian Date: Tue, 16 Apr 2002 23:57:09 +0000 Subject: [PATCH] Make the way FSM options are processed easier to read by using structures instead of u_char *. The changes are cosmetic except: RecvConfigAck() now displays the options that are being ACK'd Huge (bogus) options sent from the peer won't cause an infinite loop SendIdent and ReceiveIdent are displayed consistenlty with other FSM data LCP AUTHPROTO options that aren't understood are NAK'd, not REJ'd --- usr.sbin/ppp/ccp.c | 110 +++---- usr.sbin/ppp/ccp.h | 16 +- usr.sbin/ppp/command.c | 2 +- usr.sbin/ppp/deflate.c | 18 +- usr.sbin/ppp/fsm.c | 156 ++++++++-- usr.sbin/ppp/fsm.h | 58 ++-- usr.sbin/ppp/ipcp.c | 301 +++++++++---------- usr.sbin/ppp/ipv6cp.c | 84 +++--- usr.sbin/ppp/lcp.c | 668 ++++++++++++++++++++--------------------- usr.sbin/ppp/lcp.h | 14 - usr.sbin/ppp/mppe.c | 16 +- usr.sbin/ppp/pred.c | 30 +- 12 files changed, 744 insertions(+), 729 deletions(-) diff --git a/usr.sbin/ppp/ccp.c b/usr.sbin/ppp/ccp.c index 8465c5dee784..caa00fbb0ff3 100644 --- a/usr.sbin/ppp/ccp.c +++ b/usr.sbin/ppp/ccp.c @@ -80,7 +80,7 @@ static void CcpSendConfigReq(struct fsm *); static void CcpSentTerminateReq(struct fsm *); static void CcpSendTerminateAck(struct fsm *, u_char); -static void CcpDecodeConfig(struct fsm *, u_char *, int, int, +static void CcpDecodeConfig(struct fsm *, u_char *, u_char *, int, struct fsm_decode *); static void CcpLayerStart(struct fsm *); static void CcpLayerFinish(struct fsm *); @@ -276,7 +276,7 @@ ccp_Setup(struct ccp *ccp) ccp->reset_sent = ccp->last_reset = -1; ccp->in.algorithm = ccp->out.algorithm = -1; ccp->in.state = ccp->out.state = NULL; - ccp->in.opt.id = -1; + ccp->in.opt.hdr.id = -1; ccp->out.opt = NULL; ccp->his_reject = ccp->my_reject = 0; ccp->uncompout = ccp->compout = 0; @@ -361,26 +361,26 @@ CcpSendConfigReq(struct fsm *fp) if (!alloc) for (o = &ccp->out.opt; *o != NULL; o = &(*o)->next) - if ((*o)->val.id == algorithm[f]->id && (*o)->algorithm == f) + if ((*o)->val.hdr.id == algorithm[f]->id && (*o)->algorithm == f) break; if (alloc || *o == NULL) { *o = (struct ccp_opt *)malloc(sizeof(struct ccp_opt)); - (*o)->val.id = algorithm[f]->id; - (*o)->val.len = 2; + (*o)->val.hdr.id = algorithm[f]->id; + (*o)->val.hdr.len = 2; (*o)->next = NULL; (*o)->algorithm = f; (*algorithm[f]->o.OptInit)(&(*o)->val, &ccp->cfg); } - if (cp + (*o)->val.len > buff + sizeof buff) { + if (cp + (*o)->val.hdr.len > buff + sizeof buff) { log_Printf(LogERROR, "%s: CCP REQ buffer overrun !\n", fp->link->name); break; } - memcpy(cp, &(*o)->val, (*o)->val.len); - cp += (*o)->val.len; + memcpy(cp, &(*o)->val, (*o)->val.hdr.len); + cp += (*o)->val.hdr.len; - ccp->my_proto = (*o)->val.id; + ccp->my_proto = (*o)->val.hdr.id; ccp->out.algorithm = f; if (alloc) @@ -555,93 +555,79 @@ CcpLayerUp(struct fsm *fp) } static void -CcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, +CcpDecodeConfig(struct fsm *fp, u_char *cp, u_char *end, int mode_type, struct fsm_decode *dec) { /* Deal with incoming data */ struct ccp *ccp = fsm2ccp(fp); - int type, length, f; - const char *end; + int f; + const char *disp; + struct fsm_opt *opt; if (mode_type == MODE_REQ) ccp->in.algorithm = -1; /* In case we've received two REQs in a row */ - while (plen >= sizeof(struct fsmconfig)) { - type = *cp; - length = cp[1]; - - if (length == 0) { - log_Printf(LogCCP, "%s: CCP size zero\n", fp->link->name); + while (end - cp >= sizeof(opt->hdr)) { + if ((opt = fsm_readopt(&cp)) == NULL) break; - } - - if (length > sizeof(struct lcp_opt)) { - length = sizeof(struct lcp_opt); - log_Printf(LogCCP, "%s: Warning: Truncating length to %d\n", - fp->link->name, length); - } for (f = NALGORITHMS-1; f > -1; f--) - if (algorithm[f]->id == type) + if (algorithm[f]->id == opt->hdr.id) break; - end = f == -1 ? "" : (*algorithm[f]->Disp)((struct lcp_opt *)cp); - if (end == NULL) - end = ""; + disp = f == -1 ? "" : (*algorithm[f]->Disp)(opt); + if (disp == NULL) + disp = ""; - log_Printf(LogCCP, " %s[%d] %s\n", protoname(type), length, end); + log_Printf(LogCCP, " %s[%d] %s\n", protoname(opt->hdr.id), + opt->hdr.len, disp); if (f == -1) { /* Don't understand that :-( */ if (mode_type == MODE_REQ) { - ccp->my_reject |= (1 << type); - memcpy(dec->rejend, cp, length); - dec->rejend += length; + ccp->my_reject |= (1 << opt->hdr.id); + fsm_rej(dec, opt); } } else { struct ccp_opt *o; switch (mode_type) { case MODE_REQ: - if (IsAccepted(ccp->cfg.neg[algorithm[f]->Neg]) && + if (IsAccepted(ccp->cfg.neg[algorithm[f]->Neg]) && (*algorithm[f]->Usable)(fp) && ccp->in.algorithm == -1) { - memcpy(&ccp->in.opt, cp, length); + memcpy(&ccp->in.opt, opt, opt->hdr.len); switch ((*algorithm[f]->i.Set)(&ccp->in.opt, &ccp->cfg)) { case MODE_REJ: - memcpy(dec->rejend, &ccp->in.opt, ccp->in.opt.len); - dec->rejend += ccp->in.opt.len; + fsm_rej(dec, &ccp->in.opt); break; case MODE_NAK: - memcpy(dec->nakend, &ccp->in.opt, ccp->in.opt.len); - dec->nakend += ccp->in.opt.len; + fsm_nak(dec, &ccp->in.opt); break; case MODE_ACK: - memcpy(dec->ackend, cp, length); - dec->ackend += length; - ccp->his_proto = type; + fsm_ack(dec, &ccp->in.opt); + ccp->his_proto = opt->hdr.id; ccp->in.algorithm = f; /* This one'll do :-) */ break; } - } else { - memcpy(dec->rejend, cp, length); - dec->rejend += length; - } - break; + } else { + fsm_rej(dec, opt); + } + break; case MODE_NAK: for (o = ccp->out.opt; o != NULL; o = o->next) - if (o->val.id == cp[0]) + if (o->val.hdr.id == opt->hdr.id) break; if (o == NULL) log_Printf(LogCCP, "%s: Warning: Ignoring peer NAK of unsent" " option\n", fp->link->name); else { - memcpy(&o->val, cp, length); + memcpy(&o->val, opt, opt->hdr.len); if ((*algorithm[f]->o.Set)(&o->val, &ccp->cfg) == MODE_ACK) ccp->my_proto = algorithm[f]->id; else { - ccp->his_reject |= (1 << type); - ccp->my_proto = -1; + ccp->his_reject |= (1 << opt->hdr.id); + ccp->my_proto = -1; if (algorithm[f]->Required(fp)) { log_Printf(LogWARN, "%s: Cannot understand peers (required)" " %s negotiation\n", fp->link->name, @@ -652,33 +638,21 @@ CcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, } break; case MODE_REJ: - ccp->his_reject |= (1 << type); - ccp->my_proto = -1; + ccp->his_reject |= (1 << opt->hdr.id); + ccp->my_proto = -1; if (algorithm[f]->Required(fp)) { log_Printf(LogWARN, "%s: Peer rejected (required) %s negotiation\n", fp->link->name, protoname(algorithm[f]->id)); fsm_Close(&fp->link->lcp.fsm); } - break; + break; } } - - plen -= cp[1]; - cp += cp[1]; } if (mode_type != MODE_NOP) { - if (dec->rejend != dec->rej) { - /* rejects are preferred */ - dec->ackend = dec->ack; - dec->nakend = dec->nak; - if (ccp->in.state == NULL) { - ccp->his_proto = -1; - ccp->in.algorithm = -1; - } - } else if (dec->nakend != dec->nak) { - /* then NAKs */ - dec->ackend = dec->ack; + fsm_opt_normalise(dec); + if (dec->rejend != dec->rej || dec->nakend != dec->nak) { if (ccp->in.state == NULL) { ccp->his_proto = -1; ccp->in.algorithm = -1; diff --git a/usr.sbin/ppp/ccp.h b/usr.sbin/ppp/ccp.h index d768e759c313..46c96dbfef67 100644 --- a/usr.sbin/ppp/ccp.h +++ b/usr.sbin/ppp/ccp.h @@ -85,7 +85,7 @@ struct ccp_config { struct ccp_opt { struct ccp_opt *next; int algorithm; - struct lcp_opt val; + struct fsm_opt val; }; struct ccp { @@ -100,7 +100,7 @@ struct ccp { struct { int algorithm; /* Algorithm in use */ void *state; /* Returned by implementations Init() */ - struct lcp_opt opt; /* Set by implementation's OptInit() */ + struct fsm_opt opt; /* Set by implementation's OptInit() */ } in; struct { @@ -123,12 +123,12 @@ struct ccp { struct ccp_algorithm { int id; int Neg; /* ccp_config neg array item */ - const char *(*Disp)(struct lcp_opt *); /* Use result immediately ! */ + const char *(*Disp)(struct fsm_opt *); /* Use result immediately ! */ int (*Usable)(struct fsm *); /* Ok to negotiate ? */ int (*Required)(struct fsm *); /* Must negotiate ? */ struct { - int (*Set)(struct lcp_opt *, const struct ccp_config *); - void *(*Init)(struct lcp_opt *); + int (*Set)(struct fsm_opt *, const struct ccp_config *); + void *(*Init)(struct fsm_opt *); void (*Term)(void *); void (*Reset)(void *); struct mbuf *(*Read)(void *, struct ccp *, u_short *, struct mbuf *); @@ -136,9 +136,9 @@ struct ccp_algorithm { } i; struct { int MTUOverhead; - void (*OptInit)(struct lcp_opt *, const struct ccp_config *); - int (*Set)(struct lcp_opt *, const struct ccp_config *); - void *(*Init)(struct lcp_opt *); + void (*OptInit)(struct fsm_opt *, const struct ccp_config *); + int (*Set)(struct fsm_opt *, const struct ccp_config *); + void *(*Init)(struct fsm_opt *); void (*Term)(void *); int (*Reset)(void *); struct mbuf *(*Write)(void *, struct ccp *, struct link *, int, u_short *, diff --git a/usr.sbin/ppp/command.c b/usr.sbin/ppp/command.c index 0931684231d9..ab0f9cb1ce6c 100644 --- a/usr.sbin/ppp/command.c +++ b/usr.sbin/ppp/command.c @@ -164,7 +164,7 @@ #define NEG_MPPE 54 #define NEG_CHAP81 55 -const char Version[] = "3.0.1"; +const char Version[] = "3.0.2"; static int ShowCommand(struct cmdargs const *); static int TerminalCommand(struct cmdargs const *); diff --git a/usr.sbin/ppp/deflate.c b/usr.sbin/ppp/deflate.c index ef04c270bcdd..7e9c77dd7c7d 100644 --- a/usr.sbin/ppp/deflate.c +++ b/usr.sbin/ppp/deflate.c @@ -436,7 +436,7 @@ DeflateDictSetup(void *v, struct ccp *ccp, u_short proto, struct mbuf *mi) } static const char * -DeflateDispOpts(struct lcp_opt *o) +DeflateDispOpts(struct fsm_opt *o) { static char disp[7]; /* Must be used immediately */ @@ -445,17 +445,17 @@ DeflateDispOpts(struct lcp_opt *o) } static void -DeflateInitOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg) +DeflateInitOptsOutput(struct fsm_opt *o, const struct ccp_config *cfg) { - o->len = 4; + o->hdr.len = 4; o->data[0] = ((cfg->deflate.out.winsize - 8) << 4) + 8; o->data[1] = '\0'; } static int -DeflateSetOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg) +DeflateSetOptsOutput(struct fsm_opt *o, const struct ccp_config *cfg) { - if (o->len != 4 || (o->data[0] & 15) != 8 || o->data[1] != '\0') + if (o->hdr.len != 4 || (o->data[0] & 15) != 8 || o->data[1] != '\0') return MODE_REJ; if ((o->data[0] >> 4) + 8 > 15) { @@ -467,11 +467,11 @@ DeflateSetOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg) } static int -DeflateSetOptsInput(struct lcp_opt *o, const struct ccp_config *cfg) +DeflateSetOptsInput(struct fsm_opt *o, const struct ccp_config *cfg) { int want; - if (o->len != 4 || (o->data[0] & 15) != 8 || o->data[1] != '\0') + if (o->hdr.len != 4 || (o->data[0] & 15) != 8 || o->data[1] != '\0') return MODE_REJ; want = (o->data[0] >> 4) + 8; @@ -488,7 +488,7 @@ DeflateSetOptsInput(struct lcp_opt *o, const struct ccp_config *cfg) } static void * -DeflateInitInput(struct lcp_opt *o) +DeflateInitInput(struct fsm_opt *o) { struct deflate_state *state; @@ -511,7 +511,7 @@ DeflateInitInput(struct lcp_opt *o) } static void * -DeflateInitOutput(struct lcp_opt *o) +DeflateInitOutput(struct fsm_opt *o) { struct deflate_state *state; diff --git a/usr.sbin/ppp/fsm.c b/usr.sbin/ppp/fsm.c index d4c89c4470a4..2a108c202f46 100644 --- a/usr.sbin/ppp/fsm.c +++ b/usr.sbin/ppp/fsm.c @@ -170,7 +170,7 @@ static void NewState(struct fsm *fp, int new) { log_Printf(fp->LogLevel, "%s: State change %s --> %s\n", - fp->link->name, State2Nam(fp->state), State2Nam(new)); + fp->link->name, State2Nam(fp->state), State2Nam(new)); if (fp->state == ST_STOPPED && fp->StoppedTimer.state == TIMER_RUNNING) timer_Stop(&fp->StoppedTimer); fp->state = new; @@ -201,8 +201,8 @@ fsm_Output(struct fsm *fp, u_int code, u_int id, u_char *ptr, int count, case CODE_CONFIGACK: case CODE_CONFIGREJ: case CODE_CONFIGNAK: - (*fp->fn->DecodeConfig)(fp, ptr, count, MODE_NOP, NULL); - if (count < sizeof(struct fsmconfig)) + (*fp->fn->DecodeConfig)(fp, ptr, ptr + count, MODE_NOP, NULL); + if (count < sizeof(struct fsm_opt_hdr)) log_Printf(fp->LogLevel, " [EMPTY]\n"); break; } @@ -470,16 +470,29 @@ FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) struct fsm_decode dec; int plen, flen; int ackaction = 0; + u_char *cp; + bp = m_pullup(bp); plen = m_length(bp); flen = ntohs(lhp->length) - sizeof *lhp; if (plen < flen) { log_Printf(LogWARN, "%s: FsmRecvConfigReq: plen (%d) < flen (%d)\n", - fp->link->name, plen, flen); + fp->link->name, plen, flen); m_freem(bp); return; } + dec.ackend = dec.ack; + dec.nakend = dec.nak; + dec.rejend = dec.rej; + cp = MBUF_CTOP(bp); + (*fp->fn->DecodeConfig)(fp, cp, cp + flen, MODE_REQ, &dec); + if (flen < sizeof(struct fsm_opt_hdr)) + log_Printf(fp->LogLevel, " [EMPTY]\n"); + + if (dec.nakend == dec.nak && dec.rejend == dec.rej) + ackaction = 1; + /* Check and process easy case */ switch (fp->state) { case ST_INITIAL: @@ -511,28 +524,12 @@ FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) case ST_STOPPING: m_freem(bp); return; - case ST_OPENED: - (*fp->fn->LayerDown)(fp); - break; - } - - bp = m_pullup(bp); - dec.ackend = dec.ack; - dec.nakend = dec.nak; - dec.rejend = dec.rej; - (*fp->fn->DecodeConfig)(fp, MBUF_CTOP(bp), flen, MODE_REQ, &dec); - if (flen < sizeof(struct fsmconfig)) - log_Printf(fp->LogLevel, " [EMPTY]\n"); - - if (dec.nakend == dec.nak && dec.rejend == dec.rej) - ackaction = 1; - - switch (fp->state) { case ST_STOPPED: FsmInitRestartCounter(fp, FSM_REQ_TIMER); - /* Fall through */ - + FsmSendConfigReq(fp); + break; case ST_OPENED: + (*fp->fn->LayerDown)(fp); FsmSendConfigReq(fp); break; } @@ -609,6 +606,26 @@ static void FsmRecvConfigAck(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) /* RCA */ { + struct fsm_decode dec; + int plen, flen; + u_char *cp; + + plen = m_length(bp); + flen = ntohs(lhp->length) - sizeof *lhp; + if (plen < flen) { + m_freem(bp); + return; + } + + bp = m_pullup(bp); + dec.ackend = dec.ack; + dec.nakend = dec.nak; + dec.rejend = dec.rej; + cp = MBUF_CTOP(bp); + (*fp->fn->DecodeConfig)(fp, cp, cp + flen, MODE_ACK, &dec); + if (flen < sizeof(struct fsm_opt_hdr)) + log_Printf(fp->LogLevel, " [EMPTY]\n"); + switch (fp->state) { case ST_CLOSED: case ST_STOPPED: @@ -654,6 +671,7 @@ FsmRecvConfigNak(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) { struct fsm_decode dec; int plen, flen; + u_char *cp; plen = m_length(bp); flen = ntohs(lhp->length) - sizeof *lhp; @@ -687,8 +705,9 @@ FsmRecvConfigNak(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) dec.ackend = dec.ack; dec.nakend = dec.nak; dec.rejend = dec.rej; - (*fp->fn->DecodeConfig)(fp, MBUF_CTOP(bp), flen, MODE_NAK, &dec); - if (flen < sizeof(struct fsmconfig)) + cp = MBUF_CTOP(bp); + (*fp->fn->DecodeConfig)(fp, cp, cp + flen, MODE_NAK, &dec); + if (flen < sizeof(struct fsm_opt_hdr)) log_Printf(fp->LogLevel, " [EMPTY]\n"); switch (fp->state) { @@ -782,6 +801,7 @@ FsmRecvConfigRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) { struct fsm_decode dec; int plen, flen; + u_char *cp; plen = m_length(bp); flen = ntohs(lhp->length) - sizeof *lhp; @@ -817,8 +837,9 @@ FsmRecvConfigRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) dec.ackend = dec.ack; dec.nakend = dec.nak; dec.rejend = dec.rej; - (*fp->fn->DecodeConfig)(fp, MBUF_CTOP(bp), flen, MODE_REJ, &dec); - if (flen < sizeof(struct fsmconfig)) + cp = MBUF_CTOP(bp); + (*fp->fn->DecodeConfig)(fp, cp, cp + flen, MODE_REJ, &dec); + if (flen < sizeof(struct fsm_opt_hdr)) log_Printf(fp->LogLevel, " [EMPTY]\n"); switch (fp->state) { @@ -1052,12 +1073,12 @@ fsm_Input(struct fsm *fp, struct mbuf *bp) if (lh.id != fp->reqid && codep->check_reqid && Enabled(fp->bundle, OPT_IDCHECK)) { log_Printf(fp->LogLevel, "%s: Recv%s(%d), dropped (expected %d)\n", - fp->link->name, codep->name, lh.id, fp->reqid); + fp->link->name, codep->name, lh.id, fp->reqid); return; } log_Printf(fp->LogLevel, "%s: Recv%s(%d) state = %s\n", - fp->link->name, codep->name, lh.id, State2Nam(fp->state)); + fp->link->name, codep->name, lh.id, State2Nam(fp->state)); if (codep->inc_reqid && (lh.id == fp->reqid || (!Enabled(fp->bundle, OPT_IDCHECK) && codep->check_reqid))) @@ -1106,3 +1127,80 @@ fsm2initial(struct fsm *fp) if (fp->state > ST_INITIAL) fsm_Close(fp); } + +struct fsm_opt * +fsm_readopt(u_char **cp) +{ + struct fsm_opt *o = (struct fsm_opt *)*cp; + + if (o->hdr.len < sizeof(struct fsm_opt_hdr)) { + log_Printf(LogERROR, "Bad option length %d (out of phase?)\n", o->hdr.len); + return NULL; + } + + *cp += o->hdr.len; + + if (o->hdr.len > sizeof(struct fsm_opt)) { + o->hdr.len = sizeof(struct fsm_opt); + log_Printf(LogERROR, "Warning: Truncating option length to %d\n", + o->hdr.len); + } + + return o; +} + +static int +fsm_opt(u_char *opt, int optlen, const struct fsm_opt *o) +{ + int cplen = o->hdr.len; + + if (optlen < sizeof(struct fsm_opt_hdr)) + optlen = 0; + + if (cplen > optlen) { + log_Printf(LogERROR, "Can't REJ length %d - trunating to %d\n", + cplen, optlen); + cplen = optlen; + } + memcpy(opt, o, cplen); + if (cplen) + opt[1] = cplen; + + return cplen; +} + +void +fsm_rej(struct fsm_decode *dec, const struct fsm_opt *o) +{ + if (!dec) + return; + dec->rejend += fsm_opt(dec->rejend, FSM_OPTLEN - (dec->rejend - dec->rej), o); +} + +void +fsm_ack(struct fsm_decode *dec, const struct fsm_opt *o) +{ + if (!dec) + return; + dec->ackend += fsm_opt(dec->ackend, FSM_OPTLEN - (dec->ackend - dec->ack), o); +} + +void +fsm_nak(struct fsm_decode *dec, const struct fsm_opt *o) +{ + if (!dec) + return; + dec->nakend += fsm_opt(dec->nakend, FSM_OPTLEN - (dec->nakend - dec->nak), o); +} + +void +fsm_opt_normalise(struct fsm_decode *dec) +{ + if (dec->rejend != dec->rej) { + /* rejects are preferred */ + dec->ackend = dec->ack; + dec->nakend = dec->nak; + } else if (dec->nakend != dec->nak) + /* then NAKs */ + dec->ackend = dec->ack; +} diff --git a/usr.sbin/ppp/fsm.h b/usr.sbin/ppp/fsm.h index 126c9b78dd80..2e577752ce26 100644 --- a/usr.sbin/ppp/fsm.h +++ b/usr.sbin/ppp/fsm.h @@ -56,6 +56,8 @@ #define FSM_REQ_TIMER 1 #define FSM_TRM_TIMER 2 +#define FSM_OPTLEN 100 + struct fsm; struct fsm_retry { @@ -65,24 +67,24 @@ struct fsm_retry { }; struct fsm_decode { - u_char ack[100], *ackend; - u_char nak[100], *nakend; - u_char rej[100], *rejend; + u_char ack[FSM_OPTLEN], *ackend; + u_char nak[FSM_OPTLEN], *nakend; + u_char rej[FSM_OPTLEN], *rejend; }; struct fsm_callbacks { - int (*LayerUp) (struct fsm *); /* Layer is now up (tlu) */ - void (*LayerDown) (struct fsm *); /* About to come down (tld) */ - void (*LayerStart) (struct fsm *); /* Layer about to start up (tls) */ - void (*LayerFinish) (struct fsm *); /* Layer now down (tlf) */ - void (*InitRestartCounter) (struct fsm *, int); /* Set fsm timer load */ - void (*SendConfigReq) (struct fsm *); /* Send REQ please */ - void (*SentTerminateReq) (struct fsm *); /* Term REQ just sent */ - void (*SendTerminateAck) (struct fsm *, u_char); /* Send Term ACK please */ - void (*DecodeConfig) (struct fsm *, u_char *, int, int, struct fsm_decode *); - /* Deal with incoming data */ - int (*RecvResetReq) (struct fsm *fp); /* Reset output */ - void (*RecvResetAck) (struct fsm *fp, u_char); /* Reset input */ + int (*LayerUp)(struct fsm *); /* Layer is now up (tlu) */ + void (*LayerDown)(struct fsm *); /* About to come down (tld) */ + void (*LayerStart)(struct fsm *); /* Layer about to start (tls) */ + void (*LayerFinish)(struct fsm *); /* Layer now down (tlf) */ + void (*InitRestartCounter)(struct fsm *, int);/* Set fsm timer load */ + void (*SendConfigReq)(struct fsm *); /* Send REQ please */ + void (*SentTerminateReq)(struct fsm *); /* Term REQ just sent */ + void (*SendTerminateAck)(struct fsm *, u_char); /* Send Term ACK please */ + void (*DecodeConfig)(struct fsm *, u_char *, u_char *, int, + struct fsm_decode *); /* Deal with incoming data */ + int (*RecvResetReq)(struct fsm *fp); /* Reset output */ + void (*RecvResetAck)(struct fsm *fp, u_char); /* Reset input */ }; struct fsm_parent { @@ -159,12 +161,25 @@ struct fsmheader { #define CODE_RESETREQ 14 /* Used in CCP */ #define CODE_RESETACK 15 /* Used in CCP */ -/* Minimum config req size. This struct is *only* used for it's size */ -struct fsmconfig { - u_char type; - u_char length; +struct fsm_opt_hdr { + u_char id; + u_char len; }; +#define MAX_FSM_OPT_LEN 20 +struct fsm_opt { + struct fsm_opt_hdr hdr; + u_char data[MAX_FSM_OPT_LEN-2]; +}; + +#define INC_FSM_OPT(ty, length, o) \ + do { \ + (o)->hdr.id = (ty); \ + (o)->hdr.len = (length); \ + (o) = (struct fsm_opt *)((u_char *)(o) + (length)); \ + } while (0) + + extern void fsm_Init(struct fsm *, const char *, u_short, int, int, int, struct bundle *, struct link *, const struct fsm_parent *, struct fsm_callbacks *, const char * const [3]); @@ -179,3 +194,8 @@ extern void fsm_NullRecvResetAck(struct fsm *, u_char); extern void fsm_Reopen(struct fsm *); extern void fsm2initial(struct fsm *); extern const char *State2Nam(u_int); +extern struct fsm_opt *fsm_readopt(u_char **); +extern void fsm_rej(struct fsm_decode *, const struct fsm_opt *); +extern void fsm_ack(struct fsm_decode *, const struct fsm_opt *); +extern void fsm_nak(struct fsm_decode *, const struct fsm_opt *); +extern void fsm_opt_normalise(struct fsm_decode *); diff --git a/usr.sbin/ppp/ipcp.c b/usr.sbin/ppp/ipcp.c index 37446d090512..b92936ca5f6c 100644 --- a/usr.sbin/ppp/ipcp.c +++ b/usr.sbin/ppp/ipcp.c @@ -114,7 +114,7 @@ static void IpcpInitRestartCounter(struct fsm *, int); static void IpcpSendConfigReq(struct fsm *); static void IpcpSentTerminateReq(struct fsm *); static void IpcpSendTerminateAck(struct fsm *, u_char); -static void IpcpDecodeConfig(struct fsm *, u_char *, int, int, +static void IpcpDecodeConfig(struct fsm *, u_char *, u_char *, int, struct fsm_decode *); static struct fsm_callbacks ipcp_Callbacks = { @@ -351,9 +351,9 @@ ipcp_Show(struct cmdargs const *arg) State2Nam(ipcp->fsm.state)); if (ipcp->fsm.state == ST_OPENED) { prompt_Printf(arg->prompt, " His side: %s, %s\n", - inet_ntoa(ipcp->peer_ip), vj2asc(ipcp->peer_compproto)); + inet_ntoa(ipcp->peer_ip), vj2asc(ipcp->peer_compproto)); prompt_Printf(arg->prompt, " My side: %s, %s\n", - inet_ntoa(ipcp->my_ip), vj2asc(ipcp->my_compproto)); + inet_ntoa(ipcp->my_ip), vj2asc(ipcp->my_compproto)); prompt_Printf(arg->prompt, " Queued packets: %lu\n", (unsigned long)ipcp_QueueLen(ipcp)); } @@ -364,7 +364,7 @@ ipcp_Show(struct cmdargs const *arg) ipcp->cfg.fsm.maxreq, ipcp->cfg.fsm.maxreq == 1 ? "" : "s", ipcp->cfg.fsm.maxtrm, ipcp->cfg.fsm.maxtrm == 1 ? "" : "s"); prompt_Printf(arg->prompt, " My Address: %s\n", - ncprange_ntoa(&ipcp->cfg.my_range)); + ncprange_ntoa(&ipcp->cfg.my_range)); if (ipcp->cfg.HaveTriggerAddress) prompt_Printf(arg->prompt, " Trigger address: %s\n", inet_ntoa(ipcp->cfg.TriggerAddress)); @@ -378,7 +378,7 @@ ipcp_Show(struct cmdargs const *arg) ipcp->cfg.peer_list.src); else prompt_Printf(arg->prompt, " His Address: %s\n", - ncprange_ntoa(&ipcp->cfg.peer_range)); + ncprange_ntoa(&ipcp->cfg.peer_range)); prompt_Printf(arg->prompt, " DNS: %s", ipcp->cfg.ns.dns[0].s_addr == INADDR_NONE ? @@ -396,7 +396,7 @@ ipcp_Show(struct cmdargs const *arg) prompt_Printf(arg->prompt, ", %s", inet_ntoa(ipcp->ns.dns[1])); prompt_Printf(arg->prompt, "\n NetBIOS NS: %s, ", - inet_ntoa(ipcp->cfg.ns.nbns[0])); + inet_ntoa(ipcp->cfg.ns.nbns[0])); prompt_Printf(arg->prompt, "%s\n\n", inet_ntoa(ipcp->cfg.ns.nbns[1])); @@ -754,13 +754,13 @@ IpcpSendConfigReq(struct fsm *fp) struct physical *p = link2physical(fp->link); struct ipcp *ipcp = fsm2ipcp(fp); u_char buff[24]; - struct lcp_opt *o; + struct fsm_opt *o; - o = (struct lcp_opt *)buff; + o = (struct fsm_opt *)buff; if ((p && !physical_IsSync(p)) || !REJECTED(ipcp, TY_IPADDR)) { memcpy(o->data, &ipcp->my_ip.s_addr, 4); - INC_LCP_OPT(TY_IPADDR, 6, o); + INC_FSM_OPT(TY_IPADDR, 6, o); } if (ipcp->my_compproto && !REJECTED(ipcp, TY_COMPPROTO)) { @@ -768,7 +768,7 @@ IpcpSendConfigReq(struct fsm *fp) u_int16_t proto = PROTO_VJCOMP; ua_htons(&proto, o->data); - INC_LCP_OPT(TY_COMPPROTO, 4, o); + INC_FSM_OPT(TY_COMPPROTO, 4, o); } else { struct compreq req; @@ -776,19 +776,19 @@ IpcpSendConfigReq(struct fsm *fp) req.slots = (ipcp->my_compproto >> 8) & 255; req.compcid = ipcp->my_compproto & 1; memcpy(o->data, &req, 4); - INC_LCP_OPT(TY_COMPPROTO, 6, o); + INC_FSM_OPT(TY_COMPPROTO, 6, o); } } if (IsEnabled(ipcp->cfg.ns.dns_neg)) { if (!REJECTED(ipcp, TY_PRIMARY_DNS - TY_ADJUST_NS)) { memcpy(o->data, &ipcp->ns.dns[0].s_addr, 4); - INC_LCP_OPT(TY_PRIMARY_DNS, 6, o); + INC_FSM_OPT(TY_PRIMARY_DNS, 6, o); } if (!REJECTED(ipcp, TY_SECONDARY_DNS - TY_ADJUST_NS)) { memcpy(o->data, &ipcp->ns.dns[1].s_addr, 4); - INC_LCP_OPT(TY_SECONDARY_DNS, 6, o); + INC_FSM_OPT(TY_SECONDARY_DNS, 6, o); } } @@ -1033,130 +1033,126 @@ ipcp_ValidateReq(struct ipcp *ipcp, struct in_addr ip, struct fsm_decode *dec) } static void -IpcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, +IpcpDecodeConfig(struct fsm *fp, u_char *cp, u_char *end, int mode_type, struct fsm_decode *dec) { /* Deal with incoming PROTO_IPCP */ struct ncpaddr ncpaddr; struct ipcp *ipcp = fsm2ipcp(fp); - int type, length, gotdnsnak; + int gotdnsnak; u_int32_t compproto; struct compreq *pcomp; struct in_addr ipaddr, dstipaddr, have_ip; char tbuff[100], tbuff2[100]; + struct fsm_opt *opt, nak; gotdnsnak = 0; - while (plen >= sizeof(struct fsmconfig)) { - type = *cp; - length = cp[1]; - - if (length == 0) { - log_Printf(LogIPCP, "%s: IPCP size zero\n", fp->link->name); + while (end - cp >= sizeof(opt->hdr)) { + if ((opt = fsm_readopt(&cp)) == NULL) break; - } - snprintf(tbuff, sizeof tbuff, " %s[%d] ", protoname(type), length); + snprintf(tbuff, sizeof tbuff, " %s[%d]", protoname(opt->hdr.id), + opt->hdr.len); - switch (type) { + switch (opt->hdr.id) { case TY_IPADDR: /* RFC1332 */ - memcpy(&ipaddr.s_addr, cp + 2, 4); + memcpy(&ipaddr.s_addr, opt->data, 4); log_Printf(LogIPCP, "%s %s\n", tbuff, inet_ntoa(ipaddr)); switch (mode_type) { case MODE_REQ: ipcp->peer_req = 1; ipcp_ValidateReq(ipcp, ipaddr, dec); - break; + break; case MODE_NAK: if (ncprange_containsip4(&ipcp->cfg.my_range, ipaddr)) { - /* Use address suggested by peer */ - snprintf(tbuff2, sizeof tbuff2, "%s changing address: %s ", tbuff, - inet_ntoa(ipcp->my_ip)); - log_Printf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); - ipcp->my_ip = ipaddr; + /* Use address suggested by peer */ + snprintf(tbuff2, sizeof tbuff2, "%s changing address: %s ", tbuff, + inet_ntoa(ipcp->my_ip)); + log_Printf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); + ipcp->my_ip = ipaddr; ncpaddr_setip4(&ncpaddr, ipcp->my_ip); bundle_AdjustFilters(fp->bundle, &ncpaddr, NULL); - } else { - log_Printf(log_IsKept(LogIPCP) ? LogIPCP : LogPHASE, + } else { + log_Printf(log_IsKept(LogIPCP) ? LogIPCP : LogPHASE, "%s: Unacceptable address!\n", inet_ntoa(ipaddr)); fsm_Close(&ipcp->fsm); - } - break; + } + break; case MODE_REJ: - ipcp->peer_reject |= (1 << type); - break; + ipcp->peer_reject |= (1 << opt->hdr.id); + break; } break; case TY_COMPPROTO: - pcomp = (struct compreq *)(cp + 2); + pcomp = (struct compreq *)opt->data; compproto = (ntohs(pcomp->proto) << 16) + (pcomp->slots << 8) + pcomp->compcid; log_Printf(LogIPCP, "%s %s\n", tbuff, vj2asc(compproto)); switch (mode_type) { case MODE_REQ: - if (!IsAccepted(ipcp->cfg.vj.neg)) { - memcpy(dec->rejend, cp, length); - dec->rejend += length; - } else { - switch (length) { - case 4: /* RFC1172 */ - if (ntohs(pcomp->proto) == PROTO_VJCOMP) { - log_Printf(LogWARN, "Peer is speaking RFC1172 compression " + if (!IsAccepted(ipcp->cfg.vj.neg)) + fsm_rej(dec, opt); + else { + switch (opt->hdr.len) { + case 4: /* RFC1172 */ + if (ntohs(pcomp->proto) == PROTO_VJCOMP) { + log_Printf(LogWARN, "Peer is speaking RFC1172 compression " "protocol !\n"); - ipcp->heis1172 = 1; - ipcp->peer_compproto = compproto; - memcpy(dec->ackend, cp, length); - dec->ackend += length; - } else { - memcpy(dec->nakend, cp, 2); - pcomp->proto = htons(PROTO_VJCOMP); - memcpy(dec->nakend+2, &pcomp, 2); - dec->nakend += length; - } - break; - case 6: /* RFC1332 */ - if (ntohs(pcomp->proto) == PROTO_VJCOMP) { + ipcp->heis1172 = 1; + ipcp->peer_compproto = compproto; + fsm_ack(dec, opt); + } else { + pcomp->proto = htons(PROTO_VJCOMP); + nak.hdr.id = TY_COMPPROTO; + nak.hdr.len = 4; + memcpy(nak.data, &pcomp, 2); + fsm_nak(dec, &nak); + } + break; + case 6: /* RFC1332 */ + if (ntohs(pcomp->proto) == PROTO_VJCOMP) { if (pcomp->slots <= MAX_VJ_STATES && pcomp->slots >= MIN_VJ_STATES) { /* Ok, we can do that */ - ipcp->peer_compproto = compproto; - ipcp->heis1172 = 0; - memcpy(dec->ackend, cp, length); - dec->ackend += length; - } else { + ipcp->peer_compproto = compproto; + ipcp->heis1172 = 0; + fsm_ack(dec, opt); + } else { /* Get as close as we can to what he wants */ - ipcp->heis1172 = 0; - memcpy(dec->nakend, cp, 2); - pcomp->slots = pcomp->slots < MIN_VJ_STATES ? + ipcp->heis1172 = 0; + pcomp->slots = pcomp->slots < MIN_VJ_STATES ? MIN_VJ_STATES : MAX_VJ_STATES; - memcpy(dec->nakend+2, &pcomp, sizeof pcomp); - dec->nakend += length; + nak.hdr.id = TY_COMPPROTO; + nak.hdr.len = 4; + memcpy(nak.data, &pcomp, 2); + fsm_nak(dec, &nak); } - } else { + } else { /* What we really want */ - memcpy(dec->nakend, cp, 2); - pcomp->proto = htons(PROTO_VJCOMP); - pcomp->slots = DEF_VJ_STATES; - pcomp->compcid = 1; - memcpy(dec->nakend+2, &pcomp, sizeof pcomp); - dec->nakend += length; - } - break; - default: - memcpy(dec->rejend, cp, length); - dec->rejend += length; - break; - } - } - break; + pcomp->proto = htons(PROTO_VJCOMP); + pcomp->slots = DEF_VJ_STATES; + pcomp->compcid = 1; + nak.hdr.id = TY_COMPPROTO; + nak.hdr.len = 6; + memcpy(nak.data, &pcomp, sizeof pcomp); + fsm_nak(dec, &nak); + } + break; + default: + fsm_rej(dec, opt); + break; + } + } + break; case MODE_NAK: - if (ntohs(pcomp->proto) == PROTO_VJCOMP) { + if (ntohs(pcomp->proto) == PROTO_VJCOMP) { if (pcomp->slots > MAX_VJ_STATES) pcomp->slots = MAX_VJ_STATES; else if (pcomp->slots < MIN_VJ_STATES) @@ -1165,51 +1161,49 @@ IpcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, pcomp->compcid; } else compproto = 0; - log_Printf(LogIPCP, "%s changing compproto: %08x --> %08x\n", - tbuff, ipcp->my_compproto, compproto); + log_Printf(LogIPCP, "%s changing compproto: %08x --> %08x\n", + tbuff, ipcp->my_compproto, compproto); ipcp->my_compproto = compproto; - break; + break; case MODE_REJ: - ipcp->peer_reject |= (1 << type); - break; + ipcp->peer_reject |= (1 << opt->hdr.id); + break; } break; case TY_IPADDRS: /* RFC1172 */ - memcpy(&ipaddr.s_addr, cp + 2, 4); - memcpy(&dstipaddr.s_addr, cp + 6, 4); + memcpy(&ipaddr.s_addr, opt->data, 4); + memcpy(&dstipaddr.s_addr, opt->data + 4, 4); snprintf(tbuff2, sizeof tbuff2, "%s %s,", tbuff, inet_ntoa(ipaddr)); log_Printf(LogIPCP, "%s %s\n", tbuff2, inet_ntoa(dstipaddr)); switch (mode_type) { case MODE_REQ: - memcpy(dec->rejend, cp, length); - dec->rejend += length; - break; + fsm_rej(dec, opt); + break; case MODE_NAK: case MODE_REJ: - break; + break; } break; case TY_PRIMARY_DNS: /* DNS negotiation (rfc1877) */ case TY_SECONDARY_DNS: - memcpy(&ipaddr.s_addr, cp + 2, 4); + memcpy(&ipaddr.s_addr, opt->data, 4); log_Printf(LogIPCP, "%s %s\n", tbuff, inet_ntoa(ipaddr)); switch (mode_type) { case MODE_REQ: if (!IsAccepted(ipcp->cfg.ns.dns_neg)) { - ipcp->my_reject |= (1 << (type - TY_ADJUST_NS)); - memcpy(dec->rejend, cp, length); - dec->rejend += length; - break; + ipcp->my_reject |= (1 << (opt->hdr.id - TY_ADJUST_NS)); + fsm_rej(dec, opt); + break; } - have_ip = ipcp->ns.dns[type == TY_PRIMARY_DNS ? 0 : 1]; + have_ip = ipcp->ns.dns[opt->hdr.id == TY_PRIMARY_DNS ? 0 : 1]; - if (type == TY_PRIMARY_DNS && ipaddr.s_addr != have_ip.s_addr && + if (opt->hdr.id == TY_PRIMARY_DNS && ipaddr.s_addr != have_ip.s_addr && ipaddr.s_addr == ipcp->ns.dns[1].s_addr) { /* Swap 'em 'round */ ipcp->ns.dns[0] = ipcp->ns.dns[1]; @@ -1217,86 +1211,81 @@ IpcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, have_ip = ipcp->ns.dns[0]; } - if (ipaddr.s_addr != have_ip.s_addr) { - /* - * The client has got the DNS stuff wrong (first request) so - * we'll tell 'em how it is - */ - memcpy(dec->nakend, cp, 2); /* copy first two (type/length) */ - memcpy(dec->nakend + 2, &have_ip.s_addr, length - 2); - dec->nakend += length; - } else { - /* - * Otherwise they have it right (this time) so we send a ack packet - * back confirming it... end of story - */ - memcpy(dec->ackend, cp, length); - dec->ackend += length; + if (ipaddr.s_addr != have_ip.s_addr) { + /* + * The client has got the DNS stuff wrong (first request) so + * we'll tell 'em how it is + */ + nak.hdr.id = opt->hdr.id; + nak.hdr.len = 6; + memcpy(nak.data, &have_ip.s_addr, 4); + fsm_nak(dec, &nak); + } else { + /* + * Otherwise they have it right (this time) so we send a ack packet + * back confirming it... end of story + */ + fsm_ack(dec, opt); } - break; + break; case MODE_NAK: if (IsEnabled(ipcp->cfg.ns.dns_neg)) { gotdnsnak = 1; - memcpy(&ipcp->ns.dns[type == TY_PRIMARY_DNS ? 0 : 1].s_addr, - cp + 2, 4); - } - break; + memcpy(&ipcp->ns.dns[opt->hdr.id == TY_PRIMARY_DNS ? 0 : 1].s_addr, + opt->data, 4); + } + break; case MODE_REJ: /* Can't do much, stop asking */ - ipcp->peer_reject |= (1 << (type - TY_ADJUST_NS)); - break; + ipcp->peer_reject |= (1 << (opt->hdr.id - TY_ADJUST_NS)); + break; } break; case TY_PRIMARY_NBNS: /* M$ NetBIOS nameserver hack (rfc1877) */ case TY_SECONDARY_NBNS: - memcpy(&ipaddr.s_addr, cp + 2, 4); + memcpy(&ipaddr.s_addr, opt->data, 4); log_Printf(LogIPCP, "%s %s\n", tbuff, inet_ntoa(ipaddr)); switch (mode_type) { case MODE_REQ: - have_ip.s_addr = - ipcp->cfg.ns.nbns[type == TY_PRIMARY_NBNS ? 0 : 1].s_addr; + have_ip.s_addr = + ipcp->cfg.ns.nbns[opt->hdr.id == TY_PRIMARY_NBNS ? 0 : 1].s_addr; if (have_ip.s_addr == INADDR_ANY) { - log_Printf(LogIPCP, "NBNS REQ - rejected - nbns not set\n"); - ipcp->my_reject |= (1 << (type - TY_ADJUST_NS)); - memcpy(dec->rejend, cp, length); - dec->rejend += length; - break; + log_Printf(LogIPCP, "NBNS REQ - rejected - nbns not set\n"); + ipcp->my_reject |= (1 << (opt->hdr.id - TY_ADJUST_NS)); + fsm_rej(dec, opt); + break; } - if (ipaddr.s_addr != have_ip.s_addr) { - memcpy(dec->nakend, cp, 2); - memcpy(dec->nakend+2, &have_ip.s_addr, length); - dec->nakend += length; - } else { - memcpy(dec->ackend, cp, length); - dec->ackend += length; - } - break; + if (ipaddr.s_addr != have_ip.s_addr) { + nak.hdr.id = opt->hdr.id; + nak.hdr.len = 6; + memcpy(nak.data, &have_ip.s_addr, 4); + fsm_nak(dec, &nak); + } else + fsm_ack(dec, opt); + break; case MODE_NAK: - log_Printf(LogIPCP, "MS NBNS req %d - NAK??\n", type); - break; + log_Printf(LogIPCP, "MS NBNS req %d - NAK??\n", opt->hdr.id); + break; case MODE_REJ: - log_Printf(LogIPCP, "MS NBNS req %d - REJ??\n", type); - break; + log_Printf(LogIPCP, "MS NBNS req %d - REJ??\n", opt->hdr.id); + break; } break; default: if (mode_type != MODE_NOP) { - ipcp->my_reject |= (1 << type); - memcpy(dec->rejend, cp, length); - dec->rejend += length; + ipcp->my_reject |= (1 << opt->hdr.id); + fsm_rej(dec, opt); } break; } - plen -= length; - cp += length; } if (gotdnsnak) { @@ -1328,13 +1317,7 @@ IpcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, ipaddr.s_addr = INADDR_ANY; ipcp_ValidateReq(ipcp, ipaddr, dec); } - if (dec->rejend != dec->rej) { - /* rejects are preferred */ - dec->ackend = dec->ack; - dec->nakend = dec->nak; - } else if (dec->nakend != dec->nak) - /* then NAKs */ - dec->ackend = dec->ack; + fsm_opt_normalise(dec); } } diff --git a/usr.sbin/ppp/ipv6cp.c b/usr.sbin/ppp/ipv6cp.c index 229b02e48710..5db92bbdd4da 100644 --- a/usr.sbin/ppp/ipv6cp.c +++ b/usr.sbin/ppp/ipv6cp.c @@ -85,7 +85,7 @@ static void ipv6cp_InitRestartCounter(struct fsm *, int); static void ipv6cp_SendConfigReq(struct fsm *); static void ipv6cp_SentTerminateReq(struct fsm *); static void ipv6cp_SendTerminateAck(struct fsm *, u_char); -static void ipv6cp_DecodeConfig(struct fsm *, u_char *, int, int, +static void ipv6cp_DecodeConfig(struct fsm *, u_char *, u_char *, int, struct fsm_decode *); static struct fsm_callbacks ipv6cp_Callbacks = { @@ -233,9 +233,9 @@ ipv6cp_Show(struct cmdargs const *arg) State2Nam(ipv6cp->fsm.state)); if (ipv6cp->fsm.state == ST_OPENED) { prompt_Printf(arg->prompt, " His side: %s\n", - ncpaddr_ntoa(&ipv6cp->hisaddr)); + ncpaddr_ntoa(&ipv6cp->hisaddr)); prompt_Printf(arg->prompt, " My side: %s\n", - ncpaddr_ntoa(&ipv6cp->myaddr)); + ncpaddr_ntoa(&ipv6cp->myaddr)); prompt_Printf(arg->prompt, " Queued packets: %lu\n", (unsigned long)ipv6cp_QueueLen(ipv6cp)); } @@ -455,13 +455,13 @@ ipv6cp_SendConfigReq(struct fsm *fp) struct physical *p = link2physical(fp->link); struct ipv6cp *ipv6cp = fsm2ipv6cp(fp); u_char buff[6]; - struct lcp_opt *o; + struct fsm_opt *o; - o = (struct lcp_opt *)buff; + o = (struct fsm_opt *)buff; if ((p && !physical_IsSync(p)) || !REJECTED(ipv6cp, TY_TOKEN)) { memcpy(o->data, &ipv6cp->my_token, 4); - INC_LCP_OPT(TY_TOKEN, 6, o); + INC_FSM_OPT(TY_TOKEN, 6, o); } fsm_Output(fp, CODE_CONFIGREQ, fp->reqid, buff, (u_char *)o - buff, @@ -496,61 +496,56 @@ static void ipv6cp_ValidateToken(struct ipv6cp *ipv6cp, u_int32_t token, struct fsm_decode *dec) { + struct fsm_opt opt; + if (token != 0 && token != ipv6cp->my_token) ipv6cp->peer_token = token; - if (token == ipv6cp->peer_token) { - *dec->ackend++ = TY_TOKEN; - *dec->ackend++ = 6; - memcpy(dec->ackend, &ipv6cp->peer_token, 4); - dec->ackend += 4; - } else { - *dec->nakend++ = TY_TOKEN; - *dec->nakend++ = 6; - memcpy(dec->nakend, &ipv6cp->peer_token, 4); - dec->nakend += 4; - } + opt.hdr.id = TY_TOKEN; + opt.hdr.len = 6; + memcpy(opt.data, &ipv6cp->peer_token, 4); + if (token == ipv6cp->peer_token) + fsm_ack(dec, &opt); + else + fsm_nak(dec, &opt); } static void -ipv6cp_DecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, +ipv6cp_DecodeConfig(struct fsm *fp, u_char *cp, u_char *end, int mode_type, struct fsm_decode *dec) { /* Deal with incoming PROTO_IPV6CP */ struct ipv6cp *ipv6cp = fsm2ipv6cp(fp); - int type, length, n; + int n; char tbuff[100]; u_int32_t token; + struct fsm_opt *opt; - while (plen >= sizeof(struct fsmconfig)) { - type = *cp; - length = cp[1]; - - if (length == 0) { - log_Printf(LogIPV6CP, "%s: IPV6CP size zero\n", fp->link->name); + while (end - cp >= sizeof(opt->hdr)) { + if ((opt = fsm_readopt(&cp)) == NULL) break; - } - snprintf(tbuff, sizeof tbuff, " %s[%d] ", protoname(type), length); + snprintf(tbuff, sizeof tbuff, " %s[%d]", protoname(opt->hdr.id), + opt->hdr.len); - switch (type) { + switch (opt->hdr.id) { case TY_TOKEN: - memcpy(&token, cp + 2, 4); + memcpy(&token, opt->data, 4); log_Printf(LogIPV6CP, "%s 0x%08lx\n", tbuff, (unsigned long)token); switch (mode_type) { case MODE_REQ: ipv6cp->peer_tokenreq = 1; ipv6cp_ValidateToken(ipv6cp, token, dec); - break; + break; case MODE_NAK: if (token == 0) { - log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE, + log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE, "0x00000000: Unacceptable token!\n"); fsm_Close(&ipv6cp->fsm); } else if (token == ipv6cp->peer_token) - log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE, + log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE, "0x%08lx: Unacceptable token!\n", (unsigned long)token); else if (token != ipv6cp->my_token) { n = 100; @@ -561,35 +556,32 @@ ipv6cp_DecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, } if (n == 0) { - log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE, + log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE, "0x00000000: Unacceptable token!\n"); fsm_Close(&ipv6cp->fsm); } else { - log_Printf(LogIPV6CP, "%s changing token: 0x%08lx --> 0x%08lx\n", + log_Printf(LogIPV6CP, "%s changing token: 0x%08lx --> 0x%08lx\n", tbuff, (unsigned long)ipv6cp->my_token, (unsigned long)token); ipv6cp->my_token = token; bundle_AdjustFilters(fp->bundle, &ipv6cp->myaddr, NULL); } } - break; + break; case MODE_REJ: - ipv6cp->his_reject |= (1 << type); - break; + ipv6cp->his_reject |= (1 << opt->hdr.id); + break; } break; default: if (mode_type != MODE_NOP) { - ipv6cp->my_reject |= (1 << type); - memcpy(dec->rejend, cp, length); - dec->rejend += length; + ipv6cp->my_reject |= (1 << opt->hdr.id); + fsm_rej(dec, opt); } break; } - plen -= length; - cp += length; } if (mode_type != MODE_NOP) { @@ -606,13 +598,7 @@ ipv6cp_DecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, } ipv6cp_ValidateToken(ipv6cp, 0, dec); } - if (dec->rejend != dec->rej) { - /* rejects are preferred */ - dec->ackend = dec->ack; - dec->nakend = dec->nak; - } else if (dec->nakend != dec->nak) - /* then NAKs */ - dec->ackend = dec->ack; + fsm_opt_normalise(dec); } } #endif diff --git a/usr.sbin/ppp/lcp.c b/usr.sbin/ppp/lcp.c index 1fdfc504e761..5e96a191ab09 100644 --- a/usr.sbin/ppp/lcp.c +++ b/usr.sbin/ppp/lcp.c @@ -82,8 +82,7 @@ /* for received LQRs */ struct lqrreq { - u_char type; - u_char length; + struct fsm_opt_hdr hdr; u_short proto; /* Quality protocol */ u_int32_t period; /* Reporting interval */ }; @@ -96,7 +95,7 @@ static void LcpInitRestartCounter(struct fsm *, int); static void LcpSendConfigReq(struct fsm *); static void LcpSentTerminateReq(struct fsm *); static void LcpSendTerminateAck(struct fsm *, u_char); -static void LcpDecodeConfig(struct fsm *, u_char *, int, int, +static void LcpDecodeConfig(struct fsm *, u_char *, u_char *, int, struct fsm_decode *); static struct fsm_callbacks lcp_Callbacks = { @@ -166,15 +165,15 @@ lcp_ReportStatus(struct cmdargs const *arg) prompt_Printf(arg->prompt, "%s: %s [%s]\n", l->name, lcp->fsm.name, State2Nam(lcp->fsm.state)); prompt_Printf(arg->prompt, - " his side: MRU %d, ACCMAP %08lx, PROTOCOMP %s, ACFCOMP %s,\n" - " MAGIC %08lx, MRRU %u, SHORTSEQ %s, REJECT %04x\n", - lcp->his_mru, (u_long)lcp->his_accmap, + " his side: MRU %d, ACCMAP %08lx, PROTOCOMP %s, ACFCOMP %s,\n" + " MAGIC %08lx, MRRU %u, SHORTSEQ %s, REJECT %04x\n", + lcp->his_mru, (u_long)lcp->his_accmap, lcp->his_protocomp ? "on" : "off", lcp->his_acfcomp ? "on" : "off", (u_long)lcp->his_magic, lcp->his_mrru, lcp->his_shortseq ? "on" : "off", lcp->his_reject); prompt_Printf(arg->prompt, - " my side: MRU %d, ACCMAP %08lx, PROTOCOMP %s, ACFCOMP %s,\n" + " my side: MRU %d, ACCMAP %08lx, PROTOCOMP %s, ACFCOMP %s,\n" " MAGIC %08lx, MRRU %u, SHORTSEQ %s, REJECT %04x\n", lcp->want_mru, (u_long)lcp->want_accmap, lcp->want_protocomp ? "on" : "off", @@ -381,7 +380,7 @@ LcpSendConfigReq(struct fsm *fp) struct physical *p = link2physical(fp->link); struct lcp *lcp = fsm2lcp(fp); u_char buff[200]; - struct lcp_opt *o; + struct fsm_opt *o; struct mp *mp; u_int16_t proto; u_short maxmru; @@ -392,17 +391,17 @@ LcpSendConfigReq(struct fsm *fp) return; } - o = (struct lcp_opt *)buff; + o = (struct fsm_opt *)buff; if (!physical_IsSync(p)) { if (lcp->want_acfcomp && !REJECTED(lcp, TY_ACFCOMP)) - INC_LCP_OPT(TY_ACFCOMP, 2, o); + INC_FSM_OPT(TY_ACFCOMP, 2, o); if (lcp->want_protocomp && !REJECTED(lcp, TY_PROTOCOMP)) - INC_LCP_OPT(TY_PROTOCOMP, 2, o); + INC_FSM_OPT(TY_PROTOCOMP, 2, o); if (!REJECTED(lcp, TY_ACCMAP)) { ua_htonl(&lcp->want_accmap, o->data); - INC_LCP_OPT(TY_ACCMAP, 6, o); + INC_FSM_OPT(TY_ACCMAP, 6, o); } } @@ -416,43 +415,43 @@ LcpSendConfigReq(struct fsm *fp) } if (!REJECTED(lcp, TY_MRU)) { ua_htons(&lcp->want_mru, o->data); - INC_LCP_OPT(TY_MRU, 4, o); + INC_FSM_OPT(TY_MRU, 4, o); } if (lcp->want_magic && !REJECTED(lcp, TY_MAGICNUM)) { ua_htonl(&lcp->want_magic, o->data); - INC_LCP_OPT(TY_MAGICNUM, 6, o); + INC_FSM_OPT(TY_MAGICNUM, 6, o); } if (lcp->want_lqrperiod && !REJECTED(lcp, TY_QUALPROTO)) { proto = PROTO_LQR; ua_htons(&proto, o->data); ua_htonl(&lcp->want_lqrperiod, o->data + 2); - INC_LCP_OPT(TY_QUALPROTO, 8, o); + INC_FSM_OPT(TY_QUALPROTO, 8, o); } switch (lcp->want_auth) { case PROTO_PAP: proto = PROTO_PAP; ua_htons(&proto, o->data); - INC_LCP_OPT(TY_AUTHPROTO, 4, o); + INC_FSM_OPT(TY_AUTHPROTO, 4, o); break; case PROTO_CHAP: proto = PROTO_CHAP; ua_htons(&proto, o->data); o->data[2] = lcp->want_authtype; - INC_LCP_OPT(TY_AUTHPROTO, 5, o); + INC_FSM_OPT(TY_AUTHPROTO, 5, o); break; } if (!REJECTED(lcp, TY_CALLBACK)) { if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) { *o->data = CALLBACK_AUTH; - INC_LCP_OPT(TY_CALLBACK, 3, o); + INC_FSM_OPT(TY_CALLBACK, 3, o); } else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) { *o->data = CALLBACK_CBCP; - INC_LCP_OPT(TY_CALLBACK, 3, o); + INC_FSM_OPT(TY_CALLBACK, 3, o); } else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_E164)) { int sz = strlen(lcp->want_callback.msg); @@ -462,16 +461,16 @@ LcpSendConfigReq(struct fsm *fp) } *o->data = CALLBACK_E164; memcpy(o->data + 1, lcp->want_callback.msg, sz); - INC_LCP_OPT(TY_CALLBACK, sz + 3, o); + INC_FSM_OPT(TY_CALLBACK, sz + 3, o); } } if (lcp->want_mrru && !REJECTED(lcp, TY_MRRU)) { ua_htons(&lcp->want_mrru, o->data); - INC_LCP_OPT(TY_MRRU, 4, o); + INC_FSM_OPT(TY_MRRU, 4, o); if (lcp->want_shortseq && !REJECTED(lcp, TY_SHORTSEQ)) - INC_LCP_OPT(TY_SHORTSEQ, 2, o); + INC_FSM_OPT(TY_SHORTSEQ, 2, o); } mp = &lcp->fsm.bundle->ncp.mp; @@ -479,7 +478,7 @@ LcpSendConfigReq(struct fsm *fp) !REJECTED(lcp, TY_ENDDISC)) { *o->data = mp->cfg.enddisc.class; memcpy(o->data+1, mp->cfg.enddisc.address, mp->cfg.enddisc.len); - INC_LCP_OPT(TY_ENDDISC, mp->cfg.enddisc.len + 3, o); + INC_FSM_OPT(TY_ENDDISC, mp->cfg.enddisc.len + 3, o); } fsm_Output(fp, CODE_CONFIGREQ, fp->reqid, buff, (u_char *)o - buff, @@ -514,9 +513,9 @@ lcp_SendIdentification(struct lcp *lcp) strncpy(msg + 4, exp[0], sizeof msg - 5); msg[sizeof msg - 1] = '\0'; - log_Printf(LogLCP, "Sending ident magic %08x text %s\n", lcp->want_magic, - msg + 4); fsm_Output(&lcp->fsm, CODE_IDENT, id++, msg, 4 + strlen(msg + 4), MB_LCPOUT); + log_Printf(LogLCP, " MAGICNUM %08x\n", lcp->want_magic); + log_Printf(LogLCP, " TEXT %s\n", msg + 4); command_Free(1, exp); return 1; @@ -525,7 +524,8 @@ lcp_SendIdentification(struct lcp *lcp) void lcp_RecvIdentification(struct lcp *lcp, char *data) { - log_Printf(LogLCP, "Received ident: %s\n", data); + log_Printf(LogLCP, " MAGICNUM %08x\n", lcp->his_magic); + log_Printf(LogLCP, " TEXT %s\n", data); } static void @@ -614,37 +614,72 @@ E164ok(struct callback *cb, char *req, int sz) return 0; } +static int +lcp_auth_nak(struct lcp *lcp, struct fsm_decode *dec) +{ + struct fsm_opt nak; + + nak.hdr.id = TY_AUTHPROTO; + + if (IsAccepted(lcp->cfg.pap)) { + nak.hdr.len = 4; + nak.data[0] = (unsigned char)(PROTO_PAP >> 8); + nak.data[1] = (unsigned char)PROTO_PAP; + fsm_nak(dec, &nak); + return 1; + } + + nak.hdr.len = 5; + nak.data[0] = (unsigned char)(PROTO_CHAP >> 8); + nak.data[1] = (unsigned char)PROTO_CHAP; + + if (IsAccepted(lcp->cfg.chap05)) { + nak.data[2] = 0x05; + fsm_nak(dec, &nak); +#ifndef NODES + } else if (IsAccepted(lcp->cfg.chap80nt) || + IsAccepted(lcp->cfg.chap80lm)) { + nak.data[2] = 0x80; + fsm_nak(dec, &nak); + } else if (IsAccepted(lcp->cfg.chap81)) { + nak.data[2] = 0x81; + fsm_nak(dec, &nak); +#endif + } else { + return 0; + } + + return 1; +} + static void -LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, +LcpDecodeConfig(struct fsm *fp, u_char *cp, u_char *end, int mode_type, struct fsm_decode *dec) { /* Deal with incoming PROTO_LCP */ struct lcp *lcp = fsm2lcp(fp); - int type, length, sz, pos, op, callback_req; + int sz, pos, op, callback_req, chap_type; u_int32_t magic, accmap; u_short mru, phmtu, maxmtu, maxmru, wantmtu, wantmru, proto; struct lqrreq *req; char request[20], desc[22]; struct mp *mp; struct physical *p = link2physical(fp->link); + struct fsm_opt *opt, nak; sz = op = callback_req = 0; - while (plen >= sizeof(struct fsmconfig)) { - type = *cp; - length = cp[1]; - - snprintf(request, sizeof request, " %s[%d]", protoname(type), length); - - if (length < 2) { - log_Printf(LogLCP, "%s:%s: Bad LCP length\n", fp->link->name, request); + while (end - cp >= sizeof(opt->hdr)) { + if ((opt = fsm_readopt(&cp)) == NULL) break; - } - switch (type) { + snprintf(request, sizeof request, " %s[%d]", protoname(opt->hdr.id), + opt->hdr.len); + + switch (opt->hdr.id) { case TY_MRRU: mp = &lcp->fsm.bundle->ncp.mp; - ua_ntohs(cp + 2, &mru); + ua_ntohs(opt->data, &mru); log_Printf(LogLCP, "%s %u\n", request, mru); switch (mode_type) { @@ -652,34 +687,37 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, if (mp->cfg.mrru) { if (REJECTED(lcp, TY_MRRU)) /* Ignore his previous reject so that we REQ next time */ - lcp->his_reject &= ~(1 << type); + lcp->his_reject &= ~(1 << opt->hdr.id); if (mru > MAX_MRU) { /* Push him down to MAX_MRU */ lcp->his_mrru = MAX_MRU; - memcpy(dec->nakend, cp, 2); - ua_htons(&lcp->his_mrru, dec->nakend + 2); - dec->nakend += 4; + nak.hdr.id = TY_MRRU; + nak.hdr.len = 4; + ua_htons(&lcp->his_mrru, nak.data); + fsm_nak(dec, &nak); } else if (mru < MIN_MRU) { /* Push him up to MIN_MRU */ lcp->his_mrru = MIN_MRU; - memcpy(dec->nakend, cp, 2); - ua_htons(&lcp->his_mrru, dec->nakend + 2); - dec->nakend += 4; - } else { + nak.hdr.id = TY_MRRU; + nak.hdr.len = 4; + ua_htons(&lcp->his_mrru, nak.data); + fsm_nak(dec, &nak); + } else { lcp->his_mrru = mru; - memcpy(dec->ackend, cp, 4); - dec->ackend += 4; - } - break; - } else - goto reqreject; + fsm_ack(dec, opt); + } + break; + } else { + fsm_rej(dec, opt); + lcp->my_reject |= (1 << opt->hdr.id); + } break; case MODE_NAK: if (mp->cfg.mrru) { if (REJECTED(lcp, TY_MRRU)) /* Must have changed his mind ! */ - lcp->his_reject &= ~(1 << type); + lcp->his_reject &= ~(1 << opt->hdr.id); if (mru > MAX_MRU) lcp->want_mrru = MAX_MRU; @@ -691,15 +729,15 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, /* else we honour our config and don't send the suggested REQ */ break; case MODE_REJ: - lcp->his_reject |= (1 << type); + lcp->his_reject |= (1 << opt->hdr.id); lcp->want_mrru = 0; /* Ah well, no multilink :-( */ - break; + break; } break; case TY_MRU: lcp->mru_req = 1; - ua_ntohs(cp + 2, &mru); + ua_ntohs(opt->data, &mru); log_Printf(LogLCP, "%s %d\n", request, mru); switch (mode_type) { @@ -716,21 +754,22 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, if (maxmtu && mru > maxmtu) { lcp->his_mru = maxmtu; - memcpy(dec->nakend, cp, 2); - ua_htons(&lcp->his_mru, dec->nakend + 2); - dec->nakend += 4; + nak.hdr.id = TY_MRU; + nak.hdr.len = 4; + ua_htons(&lcp->his_mru, nak.data); + fsm_nak(dec, &nak); } else if (wantmtu && mru < wantmtu) { /* Push him up to MTU or MIN_MRU */ lcp->his_mru = wantmtu; - memcpy(dec->nakend, cp, 2); - ua_htons(&lcp->his_mru, dec->nakend + 2); - dec->nakend += 4; + nak.hdr.id = TY_MRU; + nak.hdr.len = 4; + ua_htons(&lcp->his_mru, nak.data); + fsm_nak(dec, &nak); } else { lcp->his_mru = mru; - memcpy(dec->ackend, cp, 4); - dec->ackend += 4; + fsm_ack(dec, opt); } - break; + break; case MODE_NAK: maxmru = p ? physical_DeviceMTU(p) : 0; if (lcp->cfg.max_mru && (!maxmru || maxmru > lcp->cfg.max_mru)) @@ -745,260 +784,211 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, lcp->want_mru = MIN_MRU; else lcp->want_mru = mru; - break; + break; case MODE_REJ: - lcp->his_reject |= (1 << type); - break; + lcp->his_reject |= (1 << opt->hdr.id); + break; } break; case TY_ACCMAP: - ua_ntohl(cp + 2, &accmap); + ua_ntohl(opt->data, &accmap); log_Printf(LogLCP, "%s 0x%08lx\n", request, (u_long)accmap); switch (mode_type) { case MODE_REQ: - lcp->his_accmap = accmap; - memcpy(dec->ackend, cp, 6); - dec->ackend += 6; - break; + lcp->his_accmap = accmap; + fsm_ack(dec, opt); + break; case MODE_NAK: - lcp->want_accmap = accmap; - break; + lcp->want_accmap = accmap; + break; case MODE_REJ: - lcp->his_reject |= (1 << type); - break; + lcp->his_reject |= (1 << opt->hdr.id); + break; } break; case TY_AUTHPROTO: - ua_ntohs(cp + 2, &proto); + ua_ntohs(opt->data, &proto); + chap_type = opt->hdr.len == 5 ? opt->data[2] : 0; + log_Printf(LogLCP, "%s 0x%04x (%s)\n", request, proto, - Auth2Nam(proto, length > 4 ? cp[4] : 0)); + Auth2Nam(proto, chap_type)); switch (mode_type) { case MODE_REQ: - switch (proto) { - case PROTO_PAP: - if (length != 4) { - log_Printf(LogLCP, " Bad length!\n"); - goto reqreject; - } - if (IsAccepted(lcp->cfg.pap)) { - lcp->his_auth = proto; - lcp->his_authtype = 0; - memcpy(dec->ackend, cp, length); - dec->ackend += length; - } else if (IsAccepted(lcp->cfg.chap05)) { - *dec->nakend++ = *cp; - *dec->nakend++ = 5; - *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); - *dec->nakend++ = (unsigned char) PROTO_CHAP; - *dec->nakend++ = 0x05; -#ifndef NODES - } else if (IsAccepted(lcp->cfg.chap80nt) || - IsAccepted(lcp->cfg.chap80lm)) { - *dec->nakend++ = *cp; - *dec->nakend++ = 5; - *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); - *dec->nakend++ = (unsigned char) PROTO_CHAP; - *dec->nakend++ = 0x80; - } else if (IsAccepted(lcp->cfg.chap81)) { - *dec->nakend++ = *cp; - *dec->nakend++ = 5; - *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); - *dec->nakend++ = (unsigned char) PROTO_CHAP; - *dec->nakend++ = 0x81; -#endif - } else - goto reqreject; - break; + switch (proto) { + case PROTO_PAP: + if (opt->hdr.len == 4 && IsAccepted(lcp->cfg.pap)) { + lcp->his_auth = proto; + lcp->his_authtype = 0; + fsm_ack(dec, opt); + } else if (!lcp_auth_nak(lcp, dec)) { + lcp->my_reject |= (1 << opt->hdr.id); + fsm_rej(dec, opt); + } + break; - case PROTO_CHAP: - if (length != 5) { - log_Printf(LogLCP, " Bad length!\n"); - goto reqreject; - } - if ((cp[4] == 0x05 && IsAccepted(lcp->cfg.chap05)) + case PROTO_CHAP: + if ((chap_type == 0x05 && IsAccepted(lcp->cfg.chap05)) #ifndef NODES - || (cp[4] == 0x80 && (IsAccepted(lcp->cfg.chap80nt) || + || (chap_type == 0x80 && (IsAccepted(lcp->cfg.chap80nt) || (IsAccepted(lcp->cfg.chap80lm)))) - || (cp[4] == 0x81 && IsAccepted(lcp->cfg.chap81)) + || (chap_type == 0x81 && IsAccepted(lcp->cfg.chap81)) #endif ) { - lcp->his_auth = proto; - lcp->his_authtype = cp[4]; - memcpy(dec->ackend, cp, length); - dec->ackend += length; - } else { -#ifndef HAVE_DES - if (cp[4] == 0x80) { + lcp->his_auth = proto; + lcp->his_authtype = chap_type; + fsm_ack(dec, opt); + } else { +#ifdef NODES + if (chap_type == 0x80) { log_Printf(LogWARN, "CHAP 0x80 not available without DES\n"); - } else if (cp[4] == 0x81) { + } else if (chap_type == 0x81) { log_Printf(LogWARN, "CHAP 0x81 not available without DES\n"); } else #endif - if (cp[4] != 0x05) + if (chap_type != 0x05) log_Printf(LogWARN, "%s not supported\n", - Auth2Nam(PROTO_CHAP, cp[4])); + Auth2Nam(PROTO_CHAP, chap_type)); - if (IsAccepted(lcp->cfg.chap05)) { - *dec->nakend++ = *cp; - *dec->nakend++ = 5; - *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); - *dec->nakend++ = (unsigned char) PROTO_CHAP; - *dec->nakend++ = 0x05; -#ifndef NODES - } else if (IsAccepted(lcp->cfg.chap80nt) || - IsAccepted(lcp->cfg.chap80lm)) { - *dec->nakend++ = *cp; - *dec->nakend++ = 5; - *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); - *dec->nakend++ = (unsigned char) PROTO_CHAP; - *dec->nakend++ = 0x80; - } else if (IsAccepted(lcp->cfg.chap81)) { - *dec->nakend++ = *cp; - *dec->nakend++ = 5; - *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); - *dec->nakend++ = (unsigned char) PROTO_CHAP; - *dec->nakend++ = 0x81; -#endif - } else if (IsAccepted(lcp->cfg.pap)) { - *dec->nakend++ = *cp; - *dec->nakend++ = 4; - *dec->nakend++ = (unsigned char) (PROTO_PAP >> 8); - *dec->nakend++ = (unsigned char) PROTO_PAP; - } else - goto reqreject; + if (!lcp_auth_nak(lcp, dec)) { + lcp->my_reject |= (1 << opt->hdr.id); + fsm_rej(dec, opt); + } } - break; + break; - default: - log_Printf(LogLCP, "%s 0x%04x - not recognised, NAK\n", + default: + log_Printf(LogLCP, "%s 0x%04x - not recognised\n", request, proto); - memcpy(dec->nakend, cp, length); - dec->nakend += length; - break; - } - break; + if (!lcp_auth_nak(lcp, dec)) { + lcp->my_reject |= (1 << opt->hdr.id); + fsm_rej(dec, opt); + } + break; + } + break; + case MODE_NAK: - switch (proto) { - case PROTO_PAP: + switch (proto) { + case PROTO_PAP: if (IsEnabled(lcp->cfg.pap)) { lcp->want_auth = PROTO_PAP; lcp->want_authtype = 0; } else { log_Printf(LogLCP, "Peer will only send PAP (not enabled)\n"); - lcp->his_reject |= (1 << type); + lcp->his_reject |= (1 << opt->hdr.id); } break; - case PROTO_CHAP: - if (cp[4] == 0x05 && IsEnabled(lcp->cfg.chap05)) { + case PROTO_CHAP: + if (chap_type == 0x05 && IsEnabled(lcp->cfg.chap05)) { lcp->want_auth = PROTO_CHAP; lcp->want_authtype = 0x05; #ifndef NODES - } else if (cp[4] == 0x80 && (IsEnabled(lcp->cfg.chap80nt) || - IsEnabled(lcp->cfg.chap80lm))) { + } else if (chap_type == 0x80 && (IsEnabled(lcp->cfg.chap80nt) || + IsEnabled(lcp->cfg.chap80lm))) { lcp->want_auth = PROTO_CHAP; lcp->want_authtype = 0x80; - } else if (cp[4] == 0x81 && IsEnabled(lcp->cfg.chap81)) { + } else if (chap_type == 0x81 && IsEnabled(lcp->cfg.chap81)) { lcp->want_auth = PROTO_CHAP; lcp->want_authtype = 0x81; #endif } else { -#ifndef HAVE_DES - if (cp[4] == 0x80) { +#ifdef NODES + if (chap_type == 0x80) { log_Printf(LogLCP, "Peer will only send MSCHAP (not available" " without DES)\n"); - } else if (cp[4] == 0x81) { + } else if (chap_type == 0x81) { log_Printf(LogLCP, "Peer will only send MSCHAPV2 (not available" " without DES)\n"); } else #endif log_Printf(LogLCP, "Peer will only send %s (not %s)\n", - Auth2Nam(PROTO_CHAP, cp[4]), + Auth2Nam(PROTO_CHAP, chap_type), #ifndef NODES - (cp[4] == 0x80 || cp[4] == 0x81) ? "configured" : + (chap_type == 0x80 || chap_type == 0x81) ? "configured" : #endif "supported"); - lcp->his_reject |= (1 << type); + lcp->his_reject |= (1 << opt->hdr.id); } break; default: /* We've been NAK'd with something we don't understand :-( */ - lcp->his_reject |= (1 << type); + lcp->his_reject |= (1 << opt->hdr.id); break; } - break; + break; + case MODE_REJ: - lcp->his_reject |= (1 << type); - break; + lcp->his_reject |= (1 << opt->hdr.id); + break; } break; case TY_QUALPROTO: - req = (struct lqrreq *)cp; + req = (struct lqrreq *)opt; log_Printf(LogLCP, "%s proto %x, interval %lums\n", request, ntohs(req->proto), (u_long)ntohl(req->period) * 10); switch (mode_type) { case MODE_REQ: - if (ntohs(req->proto) != PROTO_LQR || !IsAccepted(lcp->cfg.lqr)) - goto reqreject; - else { - lcp->his_lqrperiod = ntohl(req->period); - if (lcp->his_lqrperiod < MIN_LQRPERIOD * 100) - lcp->his_lqrperiod = MIN_LQRPERIOD * 100; - req->period = htonl(lcp->his_lqrperiod); - memcpy(dec->ackend, cp, length); - dec->ackend += length; - } - break; + if (ntohs(req->proto) != PROTO_LQR || !IsAccepted(lcp->cfg.lqr)) { + fsm_rej(dec, opt); + lcp->my_reject |= (1 << opt->hdr.id); + } else { + lcp->his_lqrperiod = ntohl(req->period); + if (lcp->his_lqrperiod < MIN_LQRPERIOD * 100) + lcp->his_lqrperiod = MIN_LQRPERIOD * 100; + req->period = htonl(lcp->his_lqrperiod); + fsm_ack(dec, opt); + } + break; case MODE_NAK: - break; + break; case MODE_REJ: - lcp->his_reject |= (1 << type); - break; + lcp->his_reject |= (1 << opt->hdr.id); + break; } break; case TY_MAGICNUM: - ua_ntohl(cp + 2, &magic); + ua_ntohl(opt->data, &magic); log_Printf(LogLCP, "%s 0x%08lx\n", request, (u_long)magic); switch (mode_type) { case MODE_REQ: - if (lcp->want_magic) { - /* Validate magic number */ - if (magic == lcp->want_magic) { - sigset_t emptyset; + if (lcp->want_magic) { + /* Validate magic number */ + if (magic == lcp->want_magic) { + sigset_t emptyset; - log_Printf(LogLCP, "Magic is same (%08lx) - %d times\n", + log_Printf(LogLCP, "Magic is same (%08lx) - %d times\n", (u_long)magic, ++lcp->LcpFailedMagic); - lcp->want_magic = GenerateMagic(); - memcpy(dec->nakend, cp, 6); - dec->nakend += 6; + lcp->want_magic = GenerateMagic(); + fsm_nak(dec, opt); ualarm(TICKUNIT * (4 + 4 * lcp->LcpFailedMagic), 0); - sigemptyset(&emptyset); - sigsuspend(&emptyset); - } else { - lcp->his_magic = magic; - memcpy(dec->ackend, cp, length); - dec->ackend += length; + sigemptyset(&emptyset); + sigsuspend(&emptyset); + } else { + lcp->his_magic = magic; lcp->LcpFailedMagic = 0; - } - } else { - goto reqreject; - } - break; + fsm_ack(dec, opt); + } + } else { + lcp->my_reject |= (1 << opt->hdr.id); + fsm_rej(dec, opt); + } + break; case MODE_NAK: - log_Printf(LogLCP, " Magic 0x%08lx is NAKed!\n", (u_long)magic); - lcp->want_magic = GenerateMagic(); - break; + log_Printf(LogLCP, " Magic 0x%08lx is NAKed!\n", (u_long)magic); + lcp->want_magic = GenerateMagic(); + break; case MODE_REJ: - log_Printf(LogLCP, " Magic 0x%08x is REJected!\n", magic); - lcp->want_magic = 0; - lcp->his_reject |= (1 << type); - break; + log_Printf(LogLCP, " Magic 0x%08x is REJected!\n", magic); + lcp->want_magic = 0; + lcp->his_reject |= (1 << opt->hdr.id); + break; } break; @@ -1007,25 +997,24 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, switch (mode_type) { case MODE_REQ: - if (IsAccepted(lcp->cfg.protocomp)) { - lcp->his_protocomp = 1; - memcpy(dec->ackend, cp, 2); - dec->ackend += 2; - } else { + if (IsAccepted(lcp->cfg.protocomp)) { + lcp->his_protocomp = 1; + fsm_ack(dec, opt); + } else { #ifdef OLDMST - /* MorningStar before v1.3 needs NAK */ - memcpy(dec->nakend, cp, 2); - dec->nakend += 2; + /* MorningStar before v1.3 needs NAK */ + fsm_nak(dec, opt); #else - goto reqreject; + fsm_rej(dec, opt); + lcp->my_reject |= (1 << opt->hdr.id); #endif - } - break; + } + break; case MODE_NAK: case MODE_REJ: - lcp->want_protocomp = 0; - lcp->his_reject |= (1 << type); - break; + lcp->want_protocomp = 0; + lcp->his_reject |= (1 << opt->hdr.id); + break; } break; @@ -1033,25 +1022,24 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, log_Printf(LogLCP, "%s\n", request); switch (mode_type) { case MODE_REQ: - if (IsAccepted(lcp->cfg.acfcomp)) { - lcp->his_acfcomp = 1; - memcpy(dec->ackend, cp, 2); - dec->ackend += 2; - } else { + if (IsAccepted(lcp->cfg.acfcomp)) { + lcp->his_acfcomp = 1; + fsm_ack(dec, opt); + } else { #ifdef OLDMST - /* MorningStar before v1.3 needs NAK */ - memcpy(dec->nakend, cp, 2); - dec->nakend += 2; + /* MorningStar before v1.3 needs NAK */ + fsm_nak(dec, opt); #else - goto reqreject; + fsm_rej(dec, opt); + lcp->my_reject |= (1 << opt->hdr.id); #endif - } - break; + } + break; case MODE_NAK: case MODE_REJ: - lcp->want_acfcomp = 0; - lcp->his_reject |= (1 << type); - break; + lcp->want_acfcomp = 0; + lcp->his_reject |= (1 << opt->hdr.id); + break; } break; @@ -1061,31 +1049,32 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, case MODE_REQ: case MODE_NAK: case MODE_REJ: - break; + break; } break; case TY_CALLBACK: - if (length == 2) + if (opt->hdr.len == 2) op = CALLBACK_NONE; else - op = (int)cp[2]; - sz = length - 3; + op = (int)opt->data[0]; + sz = opt->hdr.len - 3; switch (op) { case CALLBACK_AUTH: log_Printf(LogLCP, "%s Auth\n", request); break; case CALLBACK_DIALSTRING: - log_Printf(LogLCP, "%s Dialstring %.*s\n", request, sz, cp + 3); + log_Printf(LogLCP, "%s Dialstring %.*s\n", request, sz, + opt->data + 1); break; case CALLBACK_LOCATION: - log_Printf(LogLCP, "%s Location %.*s\n", request, sz, cp + 3); + log_Printf(LogLCP, "%s Location %.*s\n", request, sz, opt->data + 1); break; case CALLBACK_E164: - log_Printf(LogLCP, "%s E.164 (%.*s)\n", request, sz, cp + 3); + log_Printf(LogLCP, "%s E.164 (%.*s)\n", request, sz, opt->data + 1); break; case CALLBACK_NAME: - log_Printf(LogLCP, "%s Name %.*s\n", request, sz, cp + 3); + log_Printf(LogLCP, "%s Name %.*s\n", request, sz, opt->data + 1); break; case CALLBACK_CBCP: log_Printf(LogLCP, "%s CBCP\n", request); @@ -1098,41 +1087,43 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, switch (mode_type) { case MODE_REQ: callback_req = 1; - if (p->type != PHYS_DIRECT) - goto reqreject; + if (p->type != PHYS_DIRECT) { + fsm_rej(dec, opt); + lcp->my_reject |= (1 << opt->hdr.id); + } + nak.hdr.id = opt->hdr.id; + nak.hdr.len = 3; if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(op)) && (op != CALLBACK_AUTH || p->link.lcp.want_auth) && (op != CALLBACK_E164 || - E164ok(&p->dl->cfg.callback, cp + 3, sz))) { - lcp->his_callback.opmask = CALLBACK_BIT(op); + E164ok(&p->dl->cfg.callback, opt->data + 1, sz))) { + lcp->his_callback.opmask = CALLBACK_BIT(op); if (sz > sizeof lcp->his_callback.msg - 1) { sz = sizeof lcp->his_callback.msg - 1; log_Printf(LogWARN, "Truncating option arg to %d octets\n", sz); } - memcpy(lcp->his_callback.msg, cp + 3, sz); - lcp->his_callback.msg[sz] = '\0'; - memcpy(dec->ackend, cp, sz + 3); - dec->ackend += sz + 3; + memcpy(lcp->his_callback.msg, opt->data + 1, sz); + lcp->his_callback.msg[sz] = '\0'; + fsm_ack(dec, opt); } else if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) && p->link.lcp.auth_ineed) { - *dec->nakend++ = *cp; - *dec->nakend++ = 3; - *dec->nakend++ = CALLBACK_AUTH; + nak.data[0] = CALLBACK_AUTH; + fsm_nak(dec, &nak); } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) { - *dec->nakend++ = *cp; - *dec->nakend++ = 3; - *dec->nakend++ = CALLBACK_CBCP; + nak.data[0] = CALLBACK_CBCP; + fsm_nak(dec, &nak); } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_E164)) { - *dec->nakend++ = *cp; - *dec->nakend++ = 3; - *dec->nakend++ = CALLBACK_E164; + nak.data[0] = CALLBACK_E164; + fsm_nak(dec, &nak); } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) { log_Printf(LogWARN, "Cannot insist on auth callback without" " PAP or CHAP enabled !\n"); - *dec->nakend++ = *cp; - *dec->nakend++ = 2; - } else - goto reqreject; + nak.data[0] = 2; + fsm_nak(dec, &nak); + } else { + lcp->my_reject |= (1 << opt->hdr.id); + fsm_rej(dec, opt); + } break; case MODE_NAK: /* We don't do what he NAKs with, we do things in our preferred order */ @@ -1152,13 +1143,13 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, break; case MODE_REJ: if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_NONE)) { - lcp->his_reject |= (1 << type); + lcp->his_reject |= (1 << opt->hdr.id); lcp->want_callback.opmask = 0; } else { log_Printf(LogPHASE, "Peer rejected *required* callback\n"); fsm_Close(&lcp->fsm); } - break; + break; } break; @@ -1170,10 +1161,11 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, case MODE_REQ: if (lcp->want_mrru && IsAccepted(mp->cfg.shortseq)) { lcp->his_shortseq = 1; - memcpy(dec->ackend, cp, length); - dec->ackend += length; - } else - goto reqreject; + fsm_ack(dec, opt); + } else { + fsm_rej(dec, opt); + lcp->my_reject |= (1 << opt->hdr.id); + } break; case MODE_NAK: /* @@ -1182,78 +1174,69 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, */ break; case MODE_REJ: - lcp->his_reject |= (1 << type); + lcp->his_reject |= (1 << opt->hdr.id); lcp->want_shortseq = 0; /* For when we hit MP */ - break; + break; } break; case TY_ENDDISC: mp = &lcp->fsm.bundle->ncp.mp; log_Printf(LogLCP, "%s %s\n", request, - mp_Enddisc(cp[2], cp + 3, length - 3)); + mp_Enddisc(opt->data[0], opt->data + 1, opt->hdr.len - 3)); switch (mode_type) { case MODE_REQ: if (!p) { log_Printf(LogLCP, " ENDDISC rejected - not a physical link\n"); - goto reqreject; - } else if (!IsAccepted(mp->cfg.negenddisc)) - goto reqreject; - else if (length-3 < sizeof p->dl->peer.enddisc.address && - cp[2] <= MAX_ENDDISC_CLASS) { - p->dl->peer.enddisc.class = cp[2]; - p->dl->peer.enddisc.len = length-3; - memcpy(p->dl->peer.enddisc.address, cp + 3, length - 3); - p->dl->peer.enddisc.address[length - 3] = '\0'; + fsm_rej(dec, opt); + lcp->my_reject |= (1 << opt->hdr.id); + } else if (!IsAccepted(mp->cfg.negenddisc)) { + lcp->my_reject |= (1 << opt->hdr.id); + fsm_rej(dec, opt); + } else if (opt->hdr.len - 3 < sizeof p->dl->peer.enddisc.address && + opt->data[0] <= MAX_ENDDISC_CLASS) { + p->dl->peer.enddisc.class = opt->data[0]; + p->dl->peer.enddisc.len = opt->hdr.len - 3; + memcpy(p->dl->peer.enddisc.address, opt->data + 1, opt->hdr.len - 3); + p->dl->peer.enddisc.address[opt->hdr.len - 3] = '\0'; /* XXX: If mp->active, compare and NAK with mp->peer ? */ - memcpy(dec->ackend, cp, length); - dec->ackend += length; + fsm_ack(dec, opt); } else { - if (cp[2] > MAX_ENDDISC_CLASS) + if (opt->data[0] > MAX_ENDDISC_CLASS) log_Printf(LogLCP, " ENDDISC rejected - unrecognised class %d\n", - cp[2]); + opt->data[0]); else log_Printf(LogLCP, " ENDDISC rejected - local max length is %ld\n", (long)(sizeof p->dl->peer.enddisc.address - 1)); - goto reqreject; + fsm_rej(dec, opt); + lcp->my_reject |= (1 << opt->hdr.id); } - break; + break; case MODE_NAK: /* Treat this as a REJ, we don't vary our disc (yet) */ case MODE_REJ: - lcp->his_reject |= (1 << type); - break; + lcp->his_reject |= (1 << opt->hdr.id); + break; } break; default: sz = (sizeof desc - 2) / 2; - if (sz > length - 2) - sz = length - 2; + if (sz > opt->hdr.len - 2) + sz = opt->hdr.len - 2; pos = 0; desc[0] = sz ? ' ' : '\0'; for (pos = 0; sz--; pos++) - sprintf(desc+(pos<<1)+1, "%02x", cp[pos+2]); + sprintf(desc+(pos<<1)+1, "%02x", opt->data[pos]); log_Printf(LogLCP, "%s%s\n", request, desc); if (mode_type == MODE_REQ) { -reqreject: - if (length > sizeof dec->rej - (dec->rejend - dec->rej)) { - length = sizeof dec->rej - (dec->rejend - dec->rej); - log_Printf(LogLCP, "Can't REJ length %d - trunating to %d\n", - cp[1], length); - } - memcpy(dec->rejend, cp, length); - dec->rejend += length; - lcp->my_reject |= (1 << type); - if (length != cp[1]) - length = 0; /* force our way out of the loop */ + fsm_rej(dec, opt); + lcp->my_reject |= (1 << opt->hdr.id); } break; } - plen -= length; - cp += length; } if (mode_type != MODE_NOP) { @@ -1261,20 +1244,21 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, p->dl->cfg.callback.opmask && !callback_req && !(p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_NONE))) { /* We *REQUIRE* that the peer requests callback */ - *dec->nakend++ = TY_CALLBACK; - *dec->nakend++ = 3; + nak.hdr.id = TY_CALLBACK; + nak.hdr.len = 3; if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) && p->link.lcp.want_auth) - *dec->nakend++ = CALLBACK_AUTH; + nak.data[0] = CALLBACK_AUTH; else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) - *dec->nakend++ = CALLBACK_CBCP; + nak.data[0] = CALLBACK_CBCP; else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_E164)) - *dec->nakend++ = CALLBACK_E164; + nak.data[0] = CALLBACK_E164; else { log_Printf(LogWARN, "Cannot insist on auth callback without" " PAP or CHAP enabled !\n"); - dec->nakend[-1] = 2; /* XXX: Silly ! */ + nak.hdr.len = 2; /* XXX: Silly ! */ } + fsm_nak(dec, &nak); } if (mode_type == MODE_REQ && !lcp->mru_req) { mru = DEF_MRU; @@ -1286,20 +1270,14 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, if (mru < DEF_MRU) { /* Don't let the peer use the default MRU */ lcp->his_mru = lcp->cfg.mtu && lcp->cfg.mtu < mru ? lcp->cfg.mtu : mru; - *dec->nakend++ = TY_MRU; - *dec->nakend++ = 4; - ua_htons(&lcp->his_mru, dec->nakend); - dec->nakend += 2; + nak.hdr.id = TY_MRU; + nak.hdr.len = 4; + ua_htons(&lcp->his_mru, nak.data); + fsm_nak(dec, &nak); lcp->mru_req = 1; /* Don't keep NAK'ing this */ } } - if (dec->rejend != dec->rej) { - /* rejects are preferred */ - dec->ackend = dec->ack; - dec->nakend = dec->nak; - } else if (dec->nakend != dec->nak) - /* then NAKs */ - dec->ackend = dec->ack; + fsm_opt_normalise(dec); } } diff --git a/usr.sbin/ppp/lcp.h b/usr.sbin/ppp/lcp.h index 1073c6e6bba9..dca86b72d61c 100644 --- a/usr.sbin/ppp/lcp.h +++ b/usr.sbin/ppp/lcp.h @@ -123,20 +123,6 @@ struct lcp { #define TY_SHORTSEQ 18 /* Want short seqs (12bit) please (see mp.h) */ #define TY_ENDDISC 19 /* Endpoint discriminator */ -#define MAX_LCP_OPT_LEN 20 -struct lcp_opt { - u_char id; - u_char len; - u_char data[MAX_LCP_OPT_LEN-2]; -}; - -#define INC_LCP_OPT(ty, length, o) \ - do { \ - (o)->id = (ty); \ - (o)->len = (length); \ - (o) = (struct lcp_opt *)((char *)(o) + (length)); \ - } while (0) - struct mbuf; struct link; struct bundle; diff --git a/usr.sbin/ppp/mppe.c b/usr.sbin/ppp/mppe.c index 4b75cbf60481..9de16e95b809 100644 --- a/usr.sbin/ppp/mppe.c +++ b/usr.sbin/ppp/mppe.c @@ -364,7 +364,7 @@ MPPEDictSetup(void *v, struct ccp *ccp, u_short proto, struct mbuf *mi) } static const char * -MPPEDispOpts(struct lcp_opt *o) +MPPEDispOpts(struct fsm_opt *o) { static char buf[70]; u_int32_t val; @@ -460,11 +460,11 @@ MPPE_ConfigVal(const struct ccp_config *cfg) * What options should we use for our first configure request */ static void -MPPEInitOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg) +MPPEInitOptsOutput(struct fsm_opt *o, const struct ccp_config *cfg) { u_int32_t mval; - o->len = 6; + o->hdr.len = 6; if (!MPPE_MasterKeyValid) { log_Printf(LogCCP, "MPPE: MasterKey is invalid," @@ -481,7 +481,7 @@ MPPEInitOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg) * Our CCP request was NAK'd with the given options */ static int -MPPESetOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg) +MPPESetOptsOutput(struct fsm_opt *o, const struct ccp_config *cfg) { u_int32_t mval, peer; @@ -519,7 +519,7 @@ MPPESetOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg) * The peer has requested the given options */ static int -MPPESetOptsInput(struct lcp_opt *o, const struct ccp_config *cfg) +MPPESetOptsInput(struct fsm_opt *o, const struct ccp_config *cfg) { u_int32_t mval, peer; int res = MODE_ACK; @@ -588,7 +588,7 @@ MPPESetOptsInput(struct lcp_opt *o, const struct ccp_config *cfg) } static struct mppe_state * -MPPE_InitState(struct lcp_opt *o) +MPPE_InitState(struct fsm_opt *o) { struct mppe_state *mp; u_int32_t val; @@ -622,7 +622,7 @@ MPPE_InitState(struct lcp_opt *o) } static void * -MPPEInitInput(struct lcp_opt *o) +MPPEInitInput(struct fsm_opt *o) { struct mppe_state *mip; @@ -668,7 +668,7 @@ MPPEInitInput(struct lcp_opt *o) } static void * -MPPEInitOutput(struct lcp_opt *o) +MPPEInitOutput(struct fsm_opt *o) { struct mppe_state *mop; diff --git a/usr.sbin/ppp/pred.c b/usr.sbin/ppp/pred.c index d1a5b53f1276..d286a971ae7b 100644 --- a/usr.sbin/ppp/pred.c +++ b/usr.sbin/ppp/pred.c @@ -151,7 +151,7 @@ Pred1ResetOutput(void *v) } static void * -Pred1InitInput(struct lcp_opt *o) +Pred1InitInput(struct fsm_opt *o) { struct pred1_state *state; state = (struct pred1_state *)malloc(sizeof(struct pred1_state)); @@ -161,7 +161,7 @@ Pred1InitInput(struct lcp_opt *o) } static void * -Pred1InitOutput(struct lcp_opt *o) +Pred1InitOutput(struct fsm_opt *o) { struct pred1_state *state; state = (struct pred1_state *)malloc(sizeof(struct pred1_state)); @@ -294,32 +294,22 @@ Pred1DictSetup(void *v, struct ccp *ccp, u_short proto, struct mbuf *bp) } static const char * -Pred1DispOpts(struct lcp_opt *o) +Pred1DispOpts(struct fsm_opt *o) { return NULL; } static void -Pred1InitOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg) +Pred1InitOptsOutput(struct fsm_opt *o, const struct ccp_config *cfg) { - o->len = 2; + o->hdr.len = 2; } static int -Pred1SetOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg) +Pred1SetOpts(struct fsm_opt *o, const struct ccp_config *cfg) { - if (o->len != 2) { - o->len = 2; - return MODE_NAK; - } - return MODE_ACK; -} - -static int -Pred1SetOptsInput(struct lcp_opt *o, const struct ccp_config *cfg) -{ - if (o->len != 2) { - o->len = 2; + if (o->hdr.len != 2) { + o->hdr.len = 2; return MODE_NAK; } return MODE_ACK; @@ -332,7 +322,7 @@ const struct ccp_algorithm Pred1Algorithm = { ccp_DefaultUsable, ccp_DefaultRequired, { - Pred1SetOptsInput, + Pred1SetOpts, Pred1InitInput, Pred1Term, Pred1ResetInput, @@ -342,7 +332,7 @@ const struct ccp_algorithm Pred1Algorithm = { { 0, Pred1InitOptsOutput, - Pred1SetOptsOutput, + Pred1SetOpts, Pred1InitOutput, Pred1Term, Pred1ResetOutput,