summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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