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.c1305
1 files changed, 0 insertions, 1305 deletions
diff --git a/usr.sbin/ppp/lcp.c b/usr.sbin/ppp/lcp.c
deleted file mode 100644
index cf75718..0000000
--- a/usr.sbin/ppp/lcp.c
+++ /dev/null
@@ -1,1305 +0,0 @@
-/*-
- * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org>
- * based on work by Toshiharu OHNO <tony-o@iij.ad.jp>
- * Internet Initiative Japan, Inc (IIJ)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "layer.h"
-#include "ua.h"
-#include "defs.h"
-#include "command.h"
-#include "mbuf.h"
-#include "log.h"
-#include "timer.h"
-#include "fsm.h"
-#include "iplist.h"
-#include "throughput.h"
-#include "proto.h"
-#include "descriptor.h"
-#include "lqr.h"
-#include "hdlc.h"
-#include "lcp.h"
-#include "ccp.h"
-#include "async.h"
-#include "link.h"
-#include "physical.h"
-#include "prompt.h"
-#include "slcompress.h"
-#include "ncpaddr.h"
-#include "ipcp.h"
-#include "filter.h"
-#include "mp.h"
-#include "chat.h"
-#include "auth.h"
-#include "chap.h"
-#include "cbcp.h"
-#include "datalink.h"
-#ifndef NORADIUS
-#include "radius.h"
-#endif
-#include "ipv6cp.h"
-#include "ncp.h"
-#include "bundle.h"
-
-/* for received LQRs */
-struct lqrreq {
- struct fsm_opt_hdr hdr;
- u_short proto; /* Quality protocol */
- u_int32_t period; /* Reporting interval */
-};
-
-static int LcpLayerUp(struct fsm *);
-static void LcpLayerDown(struct fsm *);
-static void LcpLayerStart(struct fsm *);
-static void LcpLayerFinish(struct fsm *);
-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 *, u_char *, int,
- struct fsm_decode *);
-
-static struct fsm_callbacks lcp_Callbacks = {
- LcpLayerUp,
- LcpLayerDown,
- LcpLayerStart,
- LcpLayerFinish,
- LcpInitRestartCounter,
- LcpSendConfigReq,
- LcpSentTerminateReq,
- LcpSendTerminateAck,
- LcpDecodeConfig,
- fsm_NullRecvResetReq,
- fsm_NullRecvResetAck
-};
-
-static const char * const lcp_TimerNames[] =
- {"LCP restart", "LCP openmode", "LCP stopped"};
-
-static const char *
-protoname(unsigned proto)
-{
- static const char * const cftypes[] = {
- /* Check out the latest ``Assigned numbers'' rfc (1700) */
- NULL,
- "MRU", /* 1: Maximum-Receive-Unit */
- "ACCMAP", /* 2: Async-Control-Character-Map */
- "AUTHPROTO", /* 3: Authentication-Protocol */
- "QUALPROTO", /* 4: Quality-Protocol */
- "MAGICNUM", /* 5: Magic-Number */
- "RESERVED", /* 6: RESERVED */
- "PROTOCOMP", /* 7: Protocol-Field-Compression */
- "ACFCOMP", /* 8: Address-and-Control-Field-Compression */
- "FCSALT", /* 9: FCS-Alternatives */
- "SDP", /* 10: Self-Describing-Pad */
- "NUMMODE", /* 11: Numbered-Mode */
- "MULTIPROC", /* 12: Multi-Link-Procedure */
- "CALLBACK", /* 13: Callback */
- "CONTIME", /* 14: Connect-Time */
- "COMPFRAME", /* 15: Compound-Frames */
- "NDE", /* 16: Nominal-Data-Encapsulation */
- "MRRU", /* 17: Multilink-MRRU */
- "SHORTSEQ", /* 18: Multilink-Short-Sequence-Number-Header */
- "ENDDISC", /* 19: Multilink-Endpoint-Discriminator */
- "PROPRIETRY", /* 20: Proprietary */
- "DCEID", /* 21: DCE-Identifier */
- "MULTIPP", /* 22: Multi-Link-Plus-Procedure */
- "LDBACP", /* 23: Link Discriminator for BACP */
- };
-
- if (proto > sizeof cftypes / sizeof *cftypes || cftypes[proto] == NULL)
- return HexStr(proto, NULL, 0);
-
- return cftypes[proto];
-}
-
-int
-lcp_ReportStatus(struct cmdargs const *arg)
-{
- struct link *l;
- struct lcp *lcp;
-
- l = command_ChooseLink(arg);
- lcp = &l->lcp;
-
- 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,
- 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"
- " MAGIC %08lx, MRRU %u, SHORTSEQ %s, REJECT %04x\n",
- lcp->want_mru, (u_long)lcp->want_accmap,
- lcp->want_protocomp ? "on" : "off",
- lcp->want_acfcomp ? "on" : "off",
- (u_long)lcp->want_magic, lcp->want_mrru,
- lcp->want_shortseq ? "on" : "off", lcp->my_reject);
-
- if (lcp->cfg.mru)
- prompt_Printf(arg->prompt, "\n Defaults: MRU = %d (max %d), ",
- lcp->cfg.mru, lcp->cfg.max_mru);
- else
- prompt_Printf(arg->prompt, "\n Defaults: MRU = any (max %d), ",
- lcp->cfg.max_mru);
- if (lcp->cfg.mtu)
- prompt_Printf(arg->prompt, "MTU = %d (max %d), ",
- lcp->cfg.mtu, lcp->cfg.max_mtu);
- else
- prompt_Printf(arg->prompt, "MTU = any (max %d), ", lcp->cfg.max_mtu);
- prompt_Printf(arg->prompt, "ACCMAP = %08lx\n", (u_long)lcp->cfg.accmap);
- prompt_Printf(arg->prompt, " LQR period = %us, ",
- lcp->cfg.lqrperiod);
- prompt_Printf(arg->prompt, "Open Mode = %s",
- lcp->cfg.openmode == OPEN_PASSIVE ? "passive" : "active");
- if (lcp->cfg.openmode > 0)
- prompt_Printf(arg->prompt, " (delay %ds)", lcp->cfg.openmode);
- prompt_Printf(arg->prompt, "\n FSM retry = %us, max %u Config"
- " REQ%s, %u Term REQ%s\n", lcp->cfg.fsm.timeout,
- lcp->cfg.fsm.maxreq, lcp->cfg.fsm.maxreq == 1 ? "" : "s",
- lcp->cfg.fsm.maxtrm, lcp->cfg.fsm.maxtrm == 1 ? "" : "s");
- prompt_Printf(arg->prompt, " Ident: %s\n", lcp->cfg.ident);
- prompt_Printf(arg->prompt, "\n Negotiation:\n");
- prompt_Printf(arg->prompt, " ACFCOMP = %s\n",
- command_ShowNegval(lcp->cfg.acfcomp));
- prompt_Printf(arg->prompt, " CHAP = %s\n",
- command_ShowNegval(lcp->cfg.chap05));
-#ifndef NODES
- prompt_Printf(arg->prompt, " CHAP80 = %s\n",
- command_ShowNegval(lcp->cfg.chap80nt));
- prompt_Printf(arg->prompt, " LANMan = %s\n",
- command_ShowNegval(lcp->cfg.chap80lm));
- prompt_Printf(arg->prompt, " CHAP81 = %s\n",
- command_ShowNegval(lcp->cfg.chap81));
-#endif
- prompt_Printf(arg->prompt, " LQR = %s\n",
- command_ShowNegval(lcp->cfg.lqr));
- prompt_Printf(arg->prompt, " LCP ECHO = %s\n",
- lcp->cfg.echo ? "enabled" : "disabled");
- prompt_Printf(arg->prompt, " PAP = %s\n",
- command_ShowNegval(lcp->cfg.pap));
- prompt_Printf(arg->prompt, " PROTOCOMP = %s\n",
- command_ShowNegval(lcp->cfg.protocomp));
-
- return 0;
-}
-
-static u_int32_t
-GenerateMagic(void)
-{
- /* Generate random number which will be used as magic number */
- randinit();
- return random();
-}
-
-void
-lcp_SetupCallbacks(struct lcp *lcp)
-{
- lcp->fsm.fn = &lcp_Callbacks;
- lcp->fsm.FsmTimer.name = lcp_TimerNames[0];
- lcp->fsm.OpenTimer.name = lcp_TimerNames[1];
- lcp->fsm.StoppedTimer.name = lcp_TimerNames[2];
-}
-
-void
-lcp_Init(struct lcp *lcp, struct bundle *bundle, struct link *l,
- const struct fsm_parent *parent)
-{
- /* Initialise ourselves */
- int mincode = parent ? 1 : LCP_MINMPCODE;
-
- fsm_Init(&lcp->fsm, "LCP", PROTO_LCP, mincode, LCP_MAXCODE, LogLCP,
- bundle, l, parent, &lcp_Callbacks, lcp_TimerNames);
-
- lcp->cfg.mru = 0;
- lcp->cfg.max_mru = MAX_MRU;
- lcp->cfg.mtu = 0;
- lcp->cfg.max_mtu = MAX_MTU;
- lcp->cfg.accmap = 0;
- lcp->cfg.openmode = 1;
- lcp->cfg.lqrperiod = DEF_LQRPERIOD;
- lcp->cfg.fsm.timeout = DEF_FSMRETRY;
- lcp->cfg.fsm.maxreq = DEF_FSMTRIES;
- lcp->cfg.fsm.maxtrm = DEF_FSMTRIES;
-
- lcp->cfg.acfcomp = NEG_ENABLED|NEG_ACCEPTED;
- lcp->cfg.chap05 = NEG_ACCEPTED;
-#ifndef NODES
- lcp->cfg.chap80nt = NEG_ACCEPTED;
- lcp->cfg.chap80lm = 0;
- lcp->cfg.chap81 = NEG_ACCEPTED;
-#endif
- lcp->cfg.lqr = NEG_ACCEPTED;
- lcp->cfg.echo = 0;
- lcp->cfg.pap = NEG_ACCEPTED;
- lcp->cfg.protocomp = NEG_ENABLED|NEG_ACCEPTED;
- *lcp->cfg.ident = '\0';
-
- lcp_Setup(lcp, lcp->cfg.openmode);
-}
-
-void
-lcp_Setup(struct lcp *lcp, int openmode)
-{
- struct physical *p = link2physical(lcp->fsm.link);
-
- lcp->fsm.open_mode = openmode;
-
- lcp->his_mru = DEF_MRU;
- lcp->his_mrru = 0;
- lcp->his_magic = 0;
- lcp->his_lqrperiod = 0;
- lcp->his_acfcomp = 0;
- lcp->his_auth = 0;
- lcp->his_authtype = 0;
- lcp->his_callback.opmask = 0;
- lcp->his_shortseq = 0;
- lcp->mru_req = 0;
-
- if ((lcp->want_mru = lcp->cfg.mru) == 0)
- lcp->want_mru = DEF_MRU;
- lcp->want_mrru = lcp->fsm.bundle->ncp.mp.cfg.mrru;
- lcp->want_shortseq = IsEnabled(lcp->fsm.bundle->ncp.mp.cfg.shortseq) ? 1 : 0;
- lcp->want_acfcomp = IsEnabled(lcp->cfg.acfcomp) ? 1 : 0;
-
- if (lcp->fsm.parent) {
- lcp->his_accmap = 0xffffffff;
- lcp->want_accmap = lcp->cfg.accmap;
- lcp->his_protocomp = 0;
- lcp->want_protocomp = IsEnabled(lcp->cfg.protocomp) ? 1 : 0;
- lcp->want_magic = GenerateMagic();
-
- if (IsEnabled(lcp->cfg.chap05)) {
- lcp->want_auth = PROTO_CHAP;
- lcp->want_authtype = 0x05;
-#ifndef NODES
- } else if (IsEnabled(lcp->cfg.chap80nt) ||
- IsEnabled(lcp->cfg.chap80lm)) {
- lcp->want_auth = PROTO_CHAP;
- lcp->want_authtype = 0x80;
- } else if (IsEnabled(lcp->cfg.chap81)) {
- lcp->want_auth = PROTO_CHAP;
- lcp->want_authtype = 0x81;
-#endif
- } else if (IsEnabled(lcp->cfg.pap)) {
- lcp->want_auth = PROTO_PAP;
- lcp->want_authtype = 0;
- } else {
- lcp->want_auth = 0;
- lcp->want_authtype = 0;
- }
-
- if (p->type != PHYS_DIRECT)
- memcpy(&lcp->want_callback, &p->dl->cfg.callback,
- sizeof(struct callback));
- else
- lcp->want_callback.opmask = 0;
- lcp->want_lqrperiod = IsEnabled(lcp->cfg.lqr) ?
- lcp->cfg.lqrperiod * 100 : 0;
- } else {
- lcp->his_accmap = lcp->want_accmap = 0;
- lcp->his_protocomp = lcp->want_protocomp = 1;
- lcp->want_magic = 0;
- lcp->want_auth = 0;
- lcp->want_authtype = 0;
- lcp->want_callback.opmask = 0;
- lcp->want_lqrperiod = 0;
- }
-
- lcp->his_reject = lcp->my_reject = 0;
- lcp->auth_iwait = lcp->auth_ineed = 0;
- lcp->LcpFailedMagic = 0;
-}
-
-static void
-LcpInitRestartCounter(struct fsm *fp, int what)
-{
- /* Set fsm timer load */
- struct lcp *lcp = fsm2lcp(fp);
-
- fp->FsmTimer.load = lcp->cfg.fsm.timeout * SECTICKS;
- switch (what) {
- case FSM_REQ_TIMER:
- fp->restart = lcp->cfg.fsm.maxreq;
- break;
- case FSM_TRM_TIMER:
- fp->restart = lcp->cfg.fsm.maxtrm;
- break;
- default:
- fp->restart = 1;
- break;
- }
-}
-
-static void
-LcpSendConfigReq(struct fsm *fp)
-{
- /* Send config REQ please */
- struct physical *p = link2physical(fp->link);
- struct lcp *lcp = fsm2lcp(fp);
- u_char buff[200];
- struct fsm_opt *o;
- struct mp *mp;
- u_int16_t proto;
- u_short maxmru;
-
- if (!p) {
- log_Printf(LogERROR, "%s: LcpSendConfigReq: Not a physical link !\n",
- fp->link->name);
- return;
- }
-
- o = (struct fsm_opt *)buff;
- if (!physical_IsSync(p)) {
- if (lcp->want_acfcomp && !REJECTED(lcp, TY_ACFCOMP))
- INC_FSM_OPT(TY_ACFCOMP, 2, o);
-
- if (lcp->want_protocomp && !REJECTED(lcp, TY_PROTOCOMP))
- INC_FSM_OPT(TY_PROTOCOMP, 2, o);
-
- if (!REJECTED(lcp, TY_ACCMAP)) {
- ua_htonl(&lcp->want_accmap, o->data);
- INC_FSM_OPT(TY_ACCMAP, 6, o);
- }
- }
-
- maxmru = p ? physical_DeviceMTU(p) : 0;
- if (lcp->cfg.max_mru && (!maxmru || maxmru > lcp->cfg.max_mru))
- maxmru = lcp->cfg.max_mru;
- if (maxmru && lcp->want_mru > maxmru) {
- log_Printf(LogWARN, "%s: Reducing configured MRU from %u to %u\n",
- fp->link->name, lcp->want_mru, maxmru);
- lcp->want_mru = maxmru;
- }
- if (!REJECTED(lcp, TY_MRU)) {
- ua_htons(&lcp->want_mru, o->data);
- INC_FSM_OPT(TY_MRU, 4, o);
- }
-
- if (lcp->want_magic && !REJECTED(lcp, TY_MAGICNUM)) {
- ua_htonl(&lcp->want_magic, o->data);
- 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_FSM_OPT(TY_QUALPROTO, 8, o);
- }
-
- switch (lcp->want_auth) {
- case PROTO_PAP:
- proto = PROTO_PAP;
- ua_htons(&proto, o->data);
- 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_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_FSM_OPT(TY_CALLBACK, 3, o);
- } else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) {
- *o->data = CALLBACK_CBCP;
- INC_FSM_OPT(TY_CALLBACK, 3, o);
- } else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_E164)) {
- size_t sz = strlen(lcp->want_callback.msg);
-
- if (sz > sizeof o->data - 1) {
- sz = sizeof o->data - 1;
- log_Printf(LogWARN, "Truncating E164 data to %zu octets (oops!)\n",
- sz);
- }
- *o->data = CALLBACK_E164;
- memcpy(o->data + 1, lcp->want_callback.msg, sz);
- INC_FSM_OPT(TY_CALLBACK, sz + 3, o);
- }
- }
-
- if (lcp->want_mrru && !REJECTED(lcp, TY_MRRU)) {
- ua_htons(&lcp->want_mrru, o->data);
- INC_FSM_OPT(TY_MRRU, 4, o);
-
- if (lcp->want_shortseq && !REJECTED(lcp, TY_SHORTSEQ))
- INC_FSM_OPT(TY_SHORTSEQ, 2, o);
- }
-
- mp = &lcp->fsm.bundle->ncp.mp;
- if (mp->cfg.enddisc.class != 0 && IsEnabled(mp->cfg.negenddisc) &&
- !REJECTED(lcp, TY_ENDDISC)) {
- *o->data = mp->cfg.enddisc.class;
- memcpy(o->data+1, mp->cfg.enddisc.address, mp->cfg.enddisc.len);
- INC_FSM_OPT(TY_ENDDISC, mp->cfg.enddisc.len + 3, o);
- }
-
- fsm_Output(fp, CODE_CONFIGREQ, fp->reqid, buff, (u_char *)o - buff,
- MB_LCPOUT);
-}
-
-void
-lcp_SendProtoRej(struct lcp *lcp, u_char *option, int count)
-{
- /* Don't understand `option' */
- fsm_Output(&lcp->fsm, CODE_PROTOREJ, lcp->fsm.reqid, option, count,
- MB_LCPOUT);
-}
-
-int
-lcp_SendIdentification(struct lcp *lcp)
-{
- static u_char id; /* Use a private id */
- u_char msg[DEF_MRU - 3];
- const char *argv[2];
- char *exp[2];
-
- if (*lcp->cfg.ident == '\0')
- return 0;
-
- argv[0] = lcp->cfg.ident;
- argv[1] = NULL;
-
- command_Expand(exp, 1, argv, lcp->fsm.bundle, 1, getpid());
-
- ua_htonl(&lcp->want_magic, msg);
- strncpy(msg + 4, exp[0], sizeof msg - 5);
- msg[sizeof msg - 1] = '\0';
-
- 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;
-}
-
-void
-lcp_RecvIdentification(struct lcp *lcp, char *data)
-{
- log_Printf(LogLCP, " MAGICNUM %08x\n", lcp->his_magic);
- log_Printf(LogLCP, " TEXT %s\n", data);
-}
-
-static void
-LcpSentTerminateReq(struct fsm *fp __unused)
-{
- /* Term REQ just sent by FSM */
-}
-
-static void
-LcpSendTerminateAck(struct fsm *fp, u_char id)
-{
- /* Send Term ACK please */
- struct physical *p = link2physical(fp->link);
-
- if (p && p->dl->state == DATALINK_CBCP)
- cbcp_ReceiveTerminateReq(p);
-
- fsm_Output(fp, CODE_TERMACK, id, NULL, 0, MB_LCPOUT);
-}
-
-static void
-LcpLayerStart(struct fsm *fp)
-{
- /* We're about to start up ! */
- struct lcp *lcp = fsm2lcp(fp);
-
- log_Printf(LogLCP, "%s: LayerStart\n", fp->link->name);
- lcp->LcpFailedMagic = 0;
- fp->more.reqs = fp->more.naks = fp->more.rejs = lcp->cfg.fsm.maxreq * 3;
- lcp->mru_req = 0;
-}
-
-static void
-LcpLayerFinish(struct fsm *fp)
-{
- /* We're now down */
- log_Printf(LogLCP, "%s: LayerFinish\n", fp->link->name);
-}
-
-static int
-LcpLayerUp(struct fsm *fp)
-{
- /* We're now up */
- struct physical *p = link2physical(fp->link);
- struct lcp *lcp = fsm2lcp(fp);
-
- log_Printf(LogLCP, "%s: LayerUp\n", fp->link->name);
- physical_SetAsyncParams(p, lcp->want_accmap, lcp->his_accmap);
- lqr_Start(lcp);
- hdlc_StartTimer(&p->hdlc);
- fp->more.reqs = fp->more.naks = fp->more.rejs = lcp->cfg.fsm.maxreq * 3;
-
- lcp_SendIdentification(lcp);
-
- return 1;
-}
-
-static void
-LcpLayerDown(struct fsm *fp)
-{
- /* About to come down */
- struct physical *p = link2physical(fp->link);
-
- log_Printf(LogLCP, "%s: LayerDown\n", fp->link->name);
- hdlc_StopTimer(&p->hdlc);
- lqr_StopTimer(p);
- lcp_Setup(fsm2lcp(fp), 0);
-}
-
-static int
-E164ok(struct callback *cb, char *req, int sz)
-{
- char list[sizeof cb->msg], *next;
- int len;
-
- if (!strcmp(cb->msg, "*"))
- return 1;
-
- strncpy(list, cb->msg, sizeof list - 1);
- list[sizeof list - 1] = '\0';
- for (next = strtok(list, ","); next; next = strtok(NULL, ",")) {
- len = strlen(next);
- if (sz == len && !memcmp(list, req, sz))
- return 1;
- }
- 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, u_char *end, int mode_type,
- struct fsm_decode *dec)
-{
- /* Deal with incoming PROTO_LCP */
- struct lcp *lcp = fsm2lcp(fp);
- int pos, op, callback_req, chap_type;
- size_t sz;
- 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 = 0;
- op = callback_req = 0;
-
- while (end - cp >= (int)sizeof(opt->hdr)) {
- if ((opt = fsm_readopt(&cp)) == NULL)
- break;
-
- 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(opt->data, &mru);
- log_Printf(LogLCP, "%s %u\n", request, mru);
-
- switch (mode_type) {
- case MODE_REQ:
- if (mp->cfg.mrru) {
- if (REJECTED(lcp, TY_MRRU))
- /* Ignore his previous reject so that we REQ next time */
- lcp->his_reject &= ~(1 << opt->hdr.id);
-
- if (mru > MAX_MRU) {
- /* Push him down to MAX_MRU */
- lcp->his_mrru = MAX_MRU;
- 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;
- 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;
- 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 << opt->hdr.id);
-
- if (mru > MAX_MRU)
- lcp->want_mrru = MAX_MRU;
- else if (mru < MIN_MRU)
- lcp->want_mrru = MIN_MRU;
- else
- lcp->want_mrru = mru;
- }
- /* else we honour our config and don't send the suggested REQ */
- break;
- case MODE_REJ:
- lcp->his_reject |= (1 << opt->hdr.id);
- lcp->want_mrru = 0; /* Ah well, no multilink :-( */
- break;
- }
- break;
-
- case TY_MRU:
- lcp->mru_req = 1;
- ua_ntohs(opt->data, &mru);
- log_Printf(LogLCP, "%s %d\n", request, mru);
-
- switch (mode_type) {
- case MODE_REQ:
- maxmtu = p ? physical_DeviceMTU(p) : 0;
- if (lcp->cfg.max_mtu && (!maxmtu || maxmtu > lcp->cfg.max_mtu))
- maxmtu = lcp->cfg.max_mtu;
- wantmtu = lcp->cfg.mtu;
- if (maxmtu && wantmtu > maxmtu) {
- log_Printf(LogWARN, "%s: Reducing configured MTU from %u to %u\n",
- fp->link->name, wantmtu, maxmtu);
- wantmtu = maxmtu;
- }
-
- if (maxmtu && mru > maxmtu) {
- lcp->his_mru = maxmtu;
- 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;
- 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;
- fsm_ack(dec, opt);
- }
- break;
- case MODE_NAK:
- maxmru = p ? physical_DeviceMTU(p) : 0;
- if (lcp->cfg.max_mru && (!maxmru || maxmru > lcp->cfg.max_mru))
- maxmru = lcp->cfg.max_mru;
- wantmru = lcp->cfg.mru > maxmru ? maxmru : lcp->cfg.mru;
-
- if (wantmru && mru > wantmru)
- lcp->want_mru = wantmru;
- else if (mru > maxmru)
- lcp->want_mru = maxmru;
- else if (mru < MIN_MRU)
- lcp->want_mru = MIN_MRU;
- else
- lcp->want_mru = mru;
- break;
- case MODE_REJ:
- lcp->his_reject |= (1 << opt->hdr.id);
- /* Set the MTU to what we want anyway - the peer won't care! */
- if (lcp->his_mru > lcp->want_mru)
- lcp->his_mru = lcp->want_mru;
- break;
- }
- break;
-
- case TY_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;
- fsm_ack(dec, opt);
- break;
- case MODE_NAK:
- lcp->want_accmap = accmap;
- break;
- case MODE_REJ:
- lcp->his_reject |= (1 << opt->hdr.id);
- break;
- }
- break;
-
- case TY_AUTHPROTO:
- 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, chap_type));
-
- switch (mode_type) {
- case MODE_REQ:
- 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
- || (chap_type == 0x80 && (IsAccepted(lcp->cfg.chap80nt) ||
- (IsAccepted(lcp->cfg.chap80lm))))
- || (chap_type == 0x81 && IsAccepted(lcp->cfg.chap81))
-#endif
- ) {
- 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 (chap_type == 0x81) {
- log_Printf(LogWARN, "CHAP 0x81 not available without DES\n");
- } else
-#endif
- if (chap_type != 0x05)
- log_Printf(LogWARN, "%s not supported\n",
- Auth2Nam(PROTO_CHAP, chap_type));
-
- if (!lcp_auth_nak(lcp, dec)) {
- lcp->my_reject |= (1 << opt->hdr.id);
- fsm_rej(dec, opt);
- }
- }
- break;
-
- default:
- log_Printf(LogLCP, "%s 0x%04x - not recognised\n",
- request, proto);
- 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:
- 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 << opt->hdr.id);
- }
- break;
- case PROTO_CHAP:
- if (chap_type == 0x05 && IsEnabled(lcp->cfg.chap05)) {
- lcp->want_auth = PROTO_CHAP;
- lcp->want_authtype = 0x05;
-#ifndef NODES
- } else if (chap_type == 0x80 && (IsEnabled(lcp->cfg.chap80nt) ||
- IsEnabled(lcp->cfg.chap80lm))) {
- lcp->want_auth = PROTO_CHAP;
- lcp->want_authtype = 0x80;
- } else if (chap_type == 0x81 && IsEnabled(lcp->cfg.chap81)) {
- lcp->want_auth = PROTO_CHAP;
- lcp->want_authtype = 0x81;
-#endif
- } else {
-#ifdef NODES
- if (chap_type == 0x80) {
- log_Printf(LogLCP, "Peer will only send MSCHAP (not available"
- " without DES)\n");
- } 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, chap_type),
-#ifndef NODES
- (chap_type == 0x80 || chap_type == 0x81) ? "configured" :
-#endif
- "supported");
- lcp->his_reject |= (1 << opt->hdr.id);
- }
- break;
- default:
- /* We've been NAK'd with something we don't understand :-( */
- lcp->his_reject |= (1 << opt->hdr.id);
- break;
- }
- break;
-
- case MODE_REJ:
- lcp->his_reject |= (1 << opt->hdr.id);
- break;
- }
- break;
-
- case TY_QUALPROTO:
- memcpy(&req, opt, sizeof req);
- 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)) {
- 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:
- lcp->want_lqrperiod = ntohl(req.period);
- break;
- case MODE_REJ:
- lcp->his_reject |= (1 << opt->hdr.id);
- break;
- }
- break;
-
- case TY_MAGICNUM:
- 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;
-
- log_Printf(LogLCP, "Magic is same (%08lx) - %d times\n",
- (u_long)magic, ++lcp->LcpFailedMagic);
- lcp->want_magic = GenerateMagic();
- fsm_nak(dec, opt);
- ualarm(TICKUNIT * (4 + 4 * lcp->LcpFailedMagic), 0);
- sigemptyset(&emptyset);
- sigsuspend(&emptyset);
- } else {
- lcp->his_magic = magic;
- lcp->LcpFailedMagic = 0;
- 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;
- case MODE_REJ:
- log_Printf(LogLCP, " Magic 0x%08x is REJected!\n", magic);
- lcp->want_magic = 0;
- lcp->his_reject |= (1 << opt->hdr.id);
- break;
- }
- break;
-
- case TY_PROTOCOMP:
- log_Printf(LogLCP, "%s\n", request);
-
- switch (mode_type) {
- case MODE_REQ:
- if (IsAccepted(lcp->cfg.protocomp)) {
- lcp->his_protocomp = 1;
- fsm_ack(dec, opt);
- } else {
-#ifdef OLDMST
- /* MorningStar before v1.3 needs NAK */
- fsm_nak(dec, opt);
-#else
- fsm_rej(dec, opt);
- lcp->my_reject |= (1 << opt->hdr.id);
-#endif
- }
- break;
- case MODE_NAK:
- case MODE_REJ:
- lcp->want_protocomp = 0;
- lcp->his_reject |= (1 << opt->hdr.id);
- break;
- }
- break;
-
- case TY_ACFCOMP:
- log_Printf(LogLCP, "%s\n", request);
- switch (mode_type) {
- case MODE_REQ:
- if (IsAccepted(lcp->cfg.acfcomp)) {
- lcp->his_acfcomp = 1;
- fsm_ack(dec, opt);
- } else {
-#ifdef OLDMST
- /* MorningStar before v1.3 needs NAK */
- fsm_nak(dec, opt);
-#else
- fsm_rej(dec, opt);
- lcp->my_reject |= (1 << opt->hdr.id);
-#endif
- }
- break;
- case MODE_NAK:
- case MODE_REJ:
- lcp->want_acfcomp = 0;
- lcp->his_reject |= (1 << opt->hdr.id);
- break;
- }
- break;
-
- case TY_SDP:
- log_Printf(LogLCP, "%s\n", request);
- switch (mode_type) {
- case MODE_REQ:
- case MODE_NAK:
- case MODE_REJ:
- break;
- }
- break;
-
- case TY_CALLBACK:
- if (opt->hdr.len == 2) {
- op = CALLBACK_NONE;
- sz = 0;
- } else {
- 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, (int)sz,
- opt->data + 1);
- break;
- case CALLBACK_LOCATION:
- log_Printf(LogLCP, "%s Location %.*s\n", request, (int)sz,
- opt->data + 1);
- break;
- case CALLBACK_E164:
- log_Printf(LogLCP, "%s E.164 (%.*s)\n", request, (int)sz,
- opt->data + 1);
- break;
- case CALLBACK_NAME:
- log_Printf(LogLCP, "%s Name %.*s\n", request, (int)sz,
- opt->data + 1);
- break;
- case CALLBACK_CBCP:
- log_Printf(LogLCP, "%s CBCP\n", request);
- break;
- default:
- log_Printf(LogLCP, "%s ???\n", request);
- break;
- }
-
- switch (mode_type) {
- case MODE_REQ:
- callback_req = 1;
- 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, 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 %zu octets\n", sz);
- }
- 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) {
- nak.data[0] = CALLBACK_AUTH;
- fsm_nak(dec, &nak);
- } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) {
- nak.data[0] = CALLBACK_CBCP;
- fsm_nak(dec, &nak);
- } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(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");
- 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 */
- if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_AUTH))
- lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_AUTH);
- else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_CBCP))
- lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_CBCP);
- else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_E164))
- lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_E164);
- if (lcp->want_callback.opmask == CALLBACK_BIT(CALLBACK_NONE)) {
- log_Printf(LogPHASE, "Peer NAKd all callbacks, trying none\n");
- lcp->want_callback.opmask = 0;
- } else if (!lcp->want_callback.opmask) {
- log_Printf(LogPHASE, "Peer NAKd last configured callback\n");
- fsm_Close(&lcp->fsm);
- }
- break;
- case MODE_REJ:
- if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_NONE)) {
- 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;
-
- case TY_SHORTSEQ:
- mp = &lcp->fsm.bundle->ncp.mp;
- log_Printf(LogLCP, "%s\n", request);
-
- switch (mode_type) {
- case MODE_REQ:
- if (lcp->want_mrru && IsAccepted(mp->cfg.shortseq)) {
- lcp->his_shortseq = 1;
- fsm_ack(dec, opt);
- } else {
- fsm_rej(dec, opt);
- lcp->my_reject |= (1 << opt->hdr.id);
- }
- break;
- case MODE_NAK:
- /*
- * He's trying to get us to ask for short sequence numbers.
- * We ignore the NAK and honour our configuration file instead.
- */
- break;
- case MODE_REJ:
- lcp->his_reject |= (1 << opt->hdr.id);
- lcp->want_shortseq = 0; /* For when we hit MP */
- break;
- }
- break;
-
- case TY_ENDDISC:
- mp = &lcp->fsm.bundle->ncp.mp;
- log_Printf(LogLCP, "%s %s\n", request,
- 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");
- 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 < sizeof p->dl->peer.enddisc.address + 3 &&
- 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 ? */
- fsm_ack(dec, opt);
- } else {
- if (opt->data[0] > MAX_ENDDISC_CLASS)
- log_Printf(LogLCP, " ENDDISC rejected - unrecognised class %d\n",
- opt->data[0]);
- else
- log_Printf(LogLCP, " ENDDISC rejected - local max length is %ld\n",
- (long)(sizeof p->dl->peer.enddisc.address - 1));
- fsm_rej(dec, opt);
- lcp->my_reject |= (1 << opt->hdr.id);
- }
- break;
-
- case MODE_NAK: /* Treat this as a REJ, we don't vary our disc (yet) */
- case MODE_REJ:
- lcp->his_reject |= (1 << opt->hdr.id);
- break;
- }
- break;
-
- default:
- sz = (sizeof desc - 2) / 2;
- if (sz + 2 > opt->hdr.len)
- sz = opt->hdr.len - 2;
- pos = 0;
- desc[0] = sz ? ' ' : '\0';
- for (pos = 0; sz--; pos++)
- sprintf(desc+(pos<<1)+1, "%02x", opt->data[pos]);
-
- log_Printf(LogLCP, "%s%s\n", request, desc);
-
- if (mode_type == MODE_REQ) {
- fsm_rej(dec, opt);
- lcp->my_reject |= (1 << opt->hdr.id);
- }
- break;
- }
- }
-
- if (mode_type != MODE_NOP) {
- if (mode_type == MODE_REQ && p && p->type == PHYS_DIRECT &&
- p->dl->cfg.callback.opmask && !callback_req &&
- !(p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_NONE))) {
- /* We *REQUIRE* that the peer requests callback */
- nak.hdr.id = TY_CALLBACK;
- nak.hdr.len = 3;
- if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) &&
- p->link.lcp.want_auth)
- nak.data[0] = CALLBACK_AUTH;
- else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_CBCP))
- nak.data[0] = CALLBACK_CBCP;
- else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_E164))
- nak.data[0] = CALLBACK_E164;
- else {
- log_Printf(LogWARN, "Cannot insist on auth callback without"
- " PAP or CHAP enabled !\n");
- nak.hdr.len = 2; /* XXX: Silly ! */
- }
- fsm_nak(dec, &nak);
- }
- if (mode_type == MODE_REQ && !lcp->mru_req) {
- mru = DEF_MRU;
- phmtu = p ? physical_DeviceMTU(p) : 0;
- if (phmtu && mru > phmtu)
- mru = phmtu;
- if (mru > lcp->cfg.max_mtu)
- mru = lcp->cfg.max_mtu;
- 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;
- 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 */
- }
- }
- fsm_opt_normalise(dec);
- }
-}
-
-extern struct mbuf *
-lcp_Input(struct bundle *bundle __unused, struct link *l, struct mbuf *bp)
-{
- /* Got PROTO_LCP from link */
- m_settype(bp, MB_LCPIN);
- fsm_Input(&l->lcp.fsm, bp);
- return NULL;
-}
OpenPOWER on IntegriCloud