summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ppp/lcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/ppp/lcp.c')
-rw-r--r--usr.sbin/ppp/lcp.c672
1 files changed, 325 insertions, 347 deletions
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);
}
}
OpenPOWER on IntegriCloud