summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>2002-04-16 23:57:09 +0000
committerbrian <brian@FreeBSD.org>2002-04-16 23:57:09 +0000
commitb86a2d03f8a98e438b3c78ca9fb2a04a1565f133 (patch)
tree5b0847031a0b3f8cbd6098a3ecd67ce4673d2eca
parenta9db9e22216eec27a36b64873a2eeb434586b0dd (diff)
downloadFreeBSD-src-b86a2d03f8a98e438b3c78ca9fb2a04a1565f133.zip
FreeBSD-src-b86a2d03f8a98e438b3c78ca9fb2a04a1565f133.tar.gz
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
-rw-r--r--usr.sbin/ppp/ccp.c110
-rw-r--r--usr.sbin/ppp/ccp.h16
-rw-r--r--usr.sbin/ppp/command.c2
-rw-r--r--usr.sbin/ppp/deflate.c18
-rw-r--r--usr.sbin/ppp/fsm.c156
-rw-r--r--usr.sbin/ppp/fsm.h58
-rw-r--r--usr.sbin/ppp/ipcp.c301
-rw-r--r--usr.sbin/ppp/ipv6cp.c84
-rw-r--r--usr.sbin/ppp/lcp.c672
-rw-r--r--usr.sbin/ppp/lcp.h14
-rw-r--r--usr.sbin/ppp/mppe.c16
-rw-r--r--usr.sbin/ppp/pred.c30
12 files changed, 746 insertions, 731 deletions
diff --git a/usr.sbin/ppp/ccp.c b/usr.sbin/ppp/ccp.c
index 8465c5d..caa00fb 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 d768e75..46c96db 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 0931684..ab0f9cb 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 ef04c27..7e9c77d 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 d4c89c4..2a108c2 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 126c9b7..2e57775 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 37446d0..b92936c 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 229b02e..5db92bb 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 1fdfc50..5e96a19 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;
-
- case PROTO_CHAP:
- if (length != 5) {
- log_Printf(LogLCP, " Bad length!\n");
- goto reqreject;
- }
- if ((cp[4] == 0x05 && IsAccepted(lcp->cfg.chap05))
+ 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 ((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]));
-
- 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;
+ Auth2Nam(PROTO_CHAP, chap_type));
+
+ 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 @@ reqreject:
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 @@ reqreject:
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 1073c6e..dca86b7 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 4b75cbf..9de16e9 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 d1a5b53..d286a97 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,
OpenPOWER on IntegriCloud