1706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*-
2706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org>
3706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *          based on work by Toshiharu OHNO <tony-o@iij.ad.jp>
4706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *                           Internet Initiative Japan, Inc (IIJ)
5706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * All rights reserved.
6706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *
7706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Redistribution and use in source and binary forms, with or without
8706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * modification, are permitted provided that the following conditions
9706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * are met:
10706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 1. Redistributions of source code must retain the above copyright
11706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *    notice, this list of conditions and the following disclaimer.
12706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 2. Redistributions in binary form must reproduce the above copyright
13706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *    notice, this list of conditions and the following disclaimer in the
14706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *    documentation and/or other materials provided with the distribution.
15706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *
16706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * SUCH DAMAGE.
27706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *
28706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * $FreeBSD: src/usr.sbin/ppp/lcp.c,v 1.110.14.1 2010/12/21 17:10:29 kensmith Exp $
29706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
30706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
31706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/param.h>
32706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/in.h>
33706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/in_systm.h>
34706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/ip.h>
35706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/socket.h>
36706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/un.h>
37706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
38706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <signal.h>
39706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdarg.h>
40706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdio.h>
41706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdlib.h>
42706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <string.h>
43706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <termios.h>
44706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <unistd.h>
45706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
46706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "layer.h"
47706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ua.h"
48706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "defs.h"
49706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "command.h"
50706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "mbuf.h"
51706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "log.h"
52706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "timer.h"
53706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "fsm.h"
54706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "iplist.h"
55706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "throughput.h"
56706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "proto.h"
57706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "descriptor.h"
58706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "lqr.h"
59706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "hdlc.h"
60706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "lcp.h"
61706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ccp.h"
62706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "async.h"
63706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "link.h"
64706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "physical.h"
65706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "prompt.h"
66706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "slcompress.h"
67706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ncpaddr.h"
68706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ipcp.h"
69706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "filter.h"
70706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "mp.h"
71706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "chat.h"
72706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "auth.h"
73706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "chap.h"
74706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "cbcp.h"
75706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "datalink.h"
76706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NORADIUS
77706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "radius.h"
78706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
79706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ipv6cp.h"
80706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ncp.h"
81706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "bundle.h"
82706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
83706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/* for received LQRs */
84706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct lqrreq {
85706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct fsm_opt_hdr hdr;
86706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_short proto;		/* Quality protocol */
87706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_int32_t period;		/* Reporting interval */
88706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh};
89706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
90706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int LcpLayerUp(struct fsm *);
91706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void LcpLayerDown(struct fsm *);
92706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void LcpLayerStart(struct fsm *);
93706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void LcpLayerFinish(struct fsm *);
94706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void LcpInitRestartCounter(struct fsm *, int);
95706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void LcpSendConfigReq(struct fsm *);
96706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void LcpSentTerminateReq(struct fsm *);
97706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void LcpSendTerminateAck(struct fsm *, u_char);
98706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void LcpDecodeConfig(struct fsm *, u_char *, u_char *, int,
99706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                            struct fsm_decode *);
100706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
101706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic struct fsm_callbacks lcp_Callbacks = {
102706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  LcpLayerUp,
103706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  LcpLayerDown,
104706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  LcpLayerStart,
105706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  LcpLayerFinish,
106706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  LcpInitRestartCounter,
107706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  LcpSendConfigReq,
108706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  LcpSentTerminateReq,
109706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  LcpSendTerminateAck,
110706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  LcpDecodeConfig,
111706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  fsm_NullRecvResetReq,
112706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  fsm_NullRecvResetAck
113706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh};
114706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
115706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic const char * const lcp_TimerNames[] =
116706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  {"LCP restart", "LCP openmode", "LCP stopped"};
117706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
118706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic const char *
119706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehprotoname(unsigned proto)
120706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
121706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  static const char * const cftypes[] = {
122706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* Check out the latest ``Assigned numbers'' rfc (1700) */
123706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    NULL,
124706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "MRU",		/* 1: Maximum-Receive-Unit */
125706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "ACCMAP",		/* 2: Async-Control-Character-Map */
126706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "AUTHPROTO",	/* 3: Authentication-Protocol */
127706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "QUALPROTO",	/* 4: Quality-Protocol */
128706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "MAGICNUM",		/* 5: Magic-Number */
129706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "RESERVED",		/* 6: RESERVED */
130706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "PROTOCOMP",	/* 7: Protocol-Field-Compression */
131706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "ACFCOMP",		/* 8: Address-and-Control-Field-Compression */
132706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "FCSALT",		/* 9: FCS-Alternatives */
133706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "SDP",		/* 10: Self-Describing-Pad */
134706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "NUMMODE",		/* 11: Numbered-Mode */
135706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "MULTIPROC",	/* 12: Multi-Link-Procedure */
136706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "CALLBACK",		/* 13: Callback */
137706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "CONTIME",		/* 14: Connect-Time */
138706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "COMPFRAME",	/* 15: Compound-Frames */
139706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "NDE",		/* 16: Nominal-Data-Encapsulation */
140706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "MRRU",		/* 17: Multilink-MRRU */
141706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "SHORTSEQ",		/* 18: Multilink-Short-Sequence-Number-Header */
142706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "ENDDISC",		/* 19: Multilink-Endpoint-Discriminator */
143706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "PROPRIETRY",	/* 20: Proprietary */
144706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "DCEID",		/* 21: DCE-Identifier */
145706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "MULTIPP",		/* 22: Multi-Link-Plus-Procedure */
146706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "LDBACP",		/* 23: Link Discriminator for BACP */
147706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  };
148706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
149706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (proto > sizeof cftypes / sizeof *cftypes || cftypes[proto] == NULL)
150706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return HexStr(proto, NULL, 0);
151706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
152706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return cftypes[proto];
153706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
154706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
155706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehint
156706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehlcp_ReportStatus(struct cmdargs const *arg)
157706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
158706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct link *l;
159706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct lcp *lcp;
160706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
161706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  l = command_ChooseLink(arg);
162706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp = &l->lcp;
163706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
164706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt, "%s: %s [%s]\n", l->name, lcp->fsm.name,
165706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                State2Nam(lcp->fsm.state));
166706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt,
167706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                " his side: MRU %d, ACCMAP %08lx, PROTOCOMP %s, ACFCOMP %s,\n"
168706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                "           MAGIC %08lx, MRRU %u, SHORTSEQ %s, REJECT %04x\n",
169706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                lcp->his_mru, (u_long)lcp->his_accmap,
170706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                lcp->his_protocomp ? "on" : "off",
171706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                lcp->his_acfcomp ? "on" : "off",
172706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                (u_long)lcp->his_magic, lcp->his_mrru,
173706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                lcp->his_shortseq ? "on" : "off", lcp->his_reject);
174706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt,
175706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                " my  side: MRU %d, ACCMAP %08lx, PROTOCOMP %s, ACFCOMP %s,\n"
176706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                "           MAGIC %08lx, MRRU %u, SHORTSEQ %s, REJECT %04x\n",
177706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                lcp->want_mru, (u_long)lcp->want_accmap,
178706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                lcp->want_protocomp ? "on" : "off",
179706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                lcp->want_acfcomp ? "on" : "off",
180706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                (u_long)lcp->want_magic, lcp->want_mrru,
181706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                lcp->want_shortseq ? "on" : "off", lcp->my_reject);
182706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
183706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (lcp->cfg.mru)
184706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(arg->prompt, "\n Defaults: MRU = %d (max %d), ",
185706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  lcp->cfg.mru, lcp->cfg.max_mru);
186706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  else
187706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(arg->prompt, "\n Defaults: MRU = any (max %d), ",
188706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  lcp->cfg.max_mru);
189706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (lcp->cfg.mtu)
190706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(arg->prompt, "MTU = %d (max %d), ",
191706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  lcp->cfg.mtu, lcp->cfg.max_mtu);
192706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  else
193706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(arg->prompt, "MTU = any (max %d), ", lcp->cfg.max_mtu);
194706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt, "ACCMAP = %08lx\n", (u_long)lcp->cfg.accmap);
195706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt, "           LQR period = %us, ",
196706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                lcp->cfg.lqrperiod);
197706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt, "Open Mode = %s",
198706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                lcp->cfg.openmode == OPEN_PASSIVE ? "passive" : "active");
199706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (lcp->cfg.openmode > 0)
200706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(arg->prompt, " (delay %ds)", lcp->cfg.openmode);
201706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt, "\n           FSM retry = %us, max %u Config"
202706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                " REQ%s, %u Term REQ%s\n", lcp->cfg.fsm.timeout,
203706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                lcp->cfg.fsm.maxreq, lcp->cfg.fsm.maxreq == 1 ? "" : "s",
204706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                lcp->cfg.fsm.maxtrm, lcp->cfg.fsm.maxtrm == 1 ? "" : "s");
205706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt, "    Ident: %s\n", lcp->cfg.ident);
206706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt, "\n Negotiation:\n");
207706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt, "           ACFCOMP =   %s\n",
208706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                command_ShowNegval(lcp->cfg.acfcomp));
209706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt, "           CHAP =      %s\n",
210706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                command_ShowNegval(lcp->cfg.chap05));
211706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
212706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt, "           CHAP80 =    %s\n",
213706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                command_ShowNegval(lcp->cfg.chap80nt));
214706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt, "           LANMan =    %s\n",
215706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                command_ShowNegval(lcp->cfg.chap80lm));
216706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt, "           CHAP81 =    %s\n",
217706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                command_ShowNegval(lcp->cfg.chap81));
218706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
219706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt, "           LQR =       %s\n",
220706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                command_ShowNegval(lcp->cfg.lqr));
221706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt, "           LCP ECHO =  %s\n",
222706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                lcp->cfg.echo ? "enabled" : "disabled");
223706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt, "           PAP =       %s\n",
224706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                command_ShowNegval(lcp->cfg.pap));
225706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt, "           PROTOCOMP = %s\n",
226706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                command_ShowNegval(lcp->cfg.protocomp));
227706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
228706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return 0;
229706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
230706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
231706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic u_int32_t
232706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehGenerateMagic(void)
233706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
234706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* Generate random number which will be used as magic number */
235706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  randinit();
236706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return random();
237706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
238706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
239706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
240706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehlcp_SetupCallbacks(struct lcp *lcp)
241706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
242706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->fsm.fn = &lcp_Callbacks;
243706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->fsm.FsmTimer.name = lcp_TimerNames[0];
244706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->fsm.OpenTimer.name = lcp_TimerNames[1];
245706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->fsm.StoppedTimer.name = lcp_TimerNames[2];
246706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
247706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
248706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
249706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehlcp_Init(struct lcp *lcp, struct bundle *bundle, struct link *l,
250706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh         const struct fsm_parent *parent)
251706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
252706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* Initialise ourselves */
253706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int mincode = parent ? 1 : LCP_MINMPCODE;
254706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
255706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  fsm_Init(&lcp->fsm, "LCP", PROTO_LCP, mincode, LCP_MAXCODE, LogLCP,
256706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh           bundle, l, parent, &lcp_Callbacks, lcp_TimerNames);
257706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
258706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.mru = 0;
259706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.max_mru = MAX_MRU;
260706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.mtu = 0;
261706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.max_mtu = MAX_MTU;
262706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.accmap = 0;
263706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.openmode = 1;
264706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.lqrperiod = DEF_LQRPERIOD;
265706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.fsm.timeout = DEF_FSMRETRY;
266706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.fsm.maxreq = DEF_FSMTRIES;
267706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.fsm.maxtrm = DEF_FSMTRIES;
268706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
269706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.acfcomp = NEG_ENABLED|NEG_ACCEPTED;
270706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.chap05 = NEG_ACCEPTED;
271706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
272706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.chap80nt = NEG_ACCEPTED;
273706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.chap80lm = 0;
274706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.chap81 = NEG_ACCEPTED;
275706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
276706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.lqr = NEG_ACCEPTED;
277706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.echo = 0;
278706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.pap = NEG_ACCEPTED;
279706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->cfg.protocomp = NEG_ENABLED|NEG_ACCEPTED;
280706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  *lcp->cfg.ident = '\0';
281706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
282706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp_Setup(lcp, lcp->cfg.openmode);
283706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
284706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
285706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
286706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehlcp_Setup(struct lcp *lcp, int openmode)
287706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
288706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct physical *p = link2physical(lcp->fsm.link);
289706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
290706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->fsm.open_mode = openmode;
291706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
292706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->his_mru = DEF_MRU;
293706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->his_mrru = 0;
294706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->his_magic = 0;
295706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->his_lqrperiod = 0;
296706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->his_acfcomp = 0;
297706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->his_auth = 0;
298706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->his_authtype = 0;
299706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->his_callback.opmask = 0;
300706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->his_shortseq = 0;
301706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->mru_req = 0;
302706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
303706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if ((lcp->want_mru = lcp->cfg.mru) == 0)
304706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    lcp->want_mru = DEF_MRU;
305706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->want_mrru = lcp->fsm.bundle->ncp.mp.cfg.mrru;
306706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->want_shortseq = IsEnabled(lcp->fsm.bundle->ncp.mp.cfg.shortseq) ? 1 : 0;
307706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->want_acfcomp = IsEnabled(lcp->cfg.acfcomp) ? 1 : 0;
308706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
309706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (lcp->fsm.parent) {
310706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    lcp->his_accmap = 0xffffffff;
311706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    lcp->want_accmap = lcp->cfg.accmap;
312706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    lcp->his_protocomp = 0;
313706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    lcp->want_protocomp = IsEnabled(lcp->cfg.protocomp) ? 1 : 0;
314706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    lcp->want_magic = GenerateMagic();
315706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
316706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (IsEnabled(lcp->cfg.chap05)) {
317706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      lcp->want_auth = PROTO_CHAP;
318706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      lcp->want_authtype = 0x05;
319706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
320706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    } else if (IsEnabled(lcp->cfg.chap80nt) ||
321706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh               IsEnabled(lcp->cfg.chap80lm)) {
322706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      lcp->want_auth = PROTO_CHAP;
323706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      lcp->want_authtype = 0x80;
324706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    } else if (IsEnabled(lcp->cfg.chap81)) {
325706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      lcp->want_auth = PROTO_CHAP;
326706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      lcp->want_authtype = 0x81;
327706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
328706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    } else if (IsEnabled(lcp->cfg.pap)) {
329706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      lcp->want_auth = PROTO_PAP;
330706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      lcp->want_authtype = 0;
331706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    } else {
332706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      lcp->want_auth = 0;
333706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      lcp->want_authtype = 0;
334706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
335706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
336706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (p->type != PHYS_DIRECT)
337706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      memcpy(&lcp->want_callback, &p->dl->cfg.callback,
338706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             sizeof(struct callback));
339706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    else
340706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      lcp->want_callback.opmask = 0;
341706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    lcp->want_lqrperiod = IsEnabled(lcp->cfg.lqr) ?
342706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                          lcp->cfg.lqrperiod * 100 : 0;
343706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else {
344706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    lcp->his_accmap = lcp->want_accmap = 0;
345706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    lcp->his_protocomp = lcp->want_protocomp = 1;
346706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    lcp->want_magic = 0;
347706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    lcp->want_auth = 0;
348706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    lcp->want_authtype = 0;
349706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    lcp->want_callback.opmask = 0;
350706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    lcp->want_lqrperiod = 0;
351706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
352706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
353706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->his_reject = lcp->my_reject = 0;
354706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->auth_iwait = lcp->auth_ineed = 0;
355706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->LcpFailedMagic = 0;
356706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
357706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
358706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
359706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehLcpInitRestartCounter(struct fsm *fp, int what)
360706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
361706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* Set fsm timer load */
362706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct lcp *lcp = fsm2lcp(fp);
363706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
364706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  fp->FsmTimer.load = lcp->cfg.fsm.timeout * SECTICKS;
365706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  switch (what) {
366706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case FSM_REQ_TIMER:
367706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      fp->restart = lcp->cfg.fsm.maxreq;
368706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
369706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case FSM_TRM_TIMER:
370706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      fp->restart = lcp->cfg.fsm.maxtrm;
371706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
372706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    default:
373706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      fp->restart = 1;
374706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
375706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
376706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
377706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
378706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
379706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehLcpSendConfigReq(struct fsm *fp)
380706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
381706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* Send config REQ please */
382706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct physical *p = link2physical(fp->link);
383706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct lcp *lcp = fsm2lcp(fp);
384706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_char buff[200];
385706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct fsm_opt *o;
386706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct mp *mp;
387706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_int16_t proto;
388706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_short maxmru;
389706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
390706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (!p) {
391706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "%s: LcpSendConfigReq: Not a physical link !\n",
392706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              fp->link->name);
393706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return;
394706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
395706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
396706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  o = (struct fsm_opt *)buff;
397706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (!physical_IsSync(p)) {
398706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (lcp->want_acfcomp && !REJECTED(lcp, TY_ACFCOMP))
399706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      INC_FSM_OPT(TY_ACFCOMP, 2, o);
400706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
401706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (lcp->want_protocomp && !REJECTED(lcp, TY_PROTOCOMP))
402706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      INC_FSM_OPT(TY_PROTOCOMP, 2, o);
403706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
404706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (!REJECTED(lcp, TY_ACCMAP)) {
405706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      ua_htonl(&lcp->want_accmap, o->data);
406706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      INC_FSM_OPT(TY_ACCMAP, 6, o);
407706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
408706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
409706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
410706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  maxmru = p ? physical_DeviceMTU(p) : 0;
411706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (lcp->cfg.max_mru && (!maxmru || maxmru > lcp->cfg.max_mru))
412706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    maxmru = lcp->cfg.max_mru;
413706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (maxmru && lcp->want_mru > maxmru) {
414706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogWARN, "%s: Reducing configured MRU from %u to %u\n",
415706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh               fp->link->name, lcp->want_mru, maxmru);
416706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    lcp->want_mru = maxmru;
417706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
418706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (!REJECTED(lcp, TY_MRU)) {
419706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ua_htons(&lcp->want_mru, o->data);
420706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    INC_FSM_OPT(TY_MRU, 4, o);
421706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
422706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
423706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (lcp->want_magic && !REJECTED(lcp, TY_MAGICNUM)) {
424706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ua_htonl(&lcp->want_magic, o->data);
425706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    INC_FSM_OPT(TY_MAGICNUM, 6, o);
426706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
427706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
428706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (lcp->want_lqrperiod && !REJECTED(lcp, TY_QUALPROTO)) {
429706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    proto = PROTO_LQR;
430706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ua_htons(&proto, o->data);
431706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ua_htonl(&lcp->want_lqrperiod, o->data + 2);
432706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    INC_FSM_OPT(TY_QUALPROTO, 8, o);
433706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
434706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
435706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  switch (lcp->want_auth) {
436706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  case PROTO_PAP:
437706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    proto = PROTO_PAP;
438706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ua_htons(&proto, o->data);
439706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    INC_FSM_OPT(TY_AUTHPROTO, 4, o);
440706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    break;
441706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
442706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  case PROTO_CHAP:
443706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    proto = PROTO_CHAP;
444706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ua_htons(&proto, o->data);
445706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    o->data[2] = lcp->want_authtype;
446706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    INC_FSM_OPT(TY_AUTHPROTO, 5, o);
447706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    break;
448706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
449706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
450706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (!REJECTED(lcp, TY_CALLBACK)) {
451706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) {
452706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      *o->data = CALLBACK_AUTH;
453706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      INC_FSM_OPT(TY_CALLBACK, 3, o);
454706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    } else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) {
455706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      *o->data = CALLBACK_CBCP;
456706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      INC_FSM_OPT(TY_CALLBACK, 3, o);
457706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    } else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_E164)) {
458706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      size_t sz = strlen(lcp->want_callback.msg);
459706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
460706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (sz > sizeof o->data - 1) {
461706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        sz = sizeof o->data - 1;
462706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        log_Printf(LogWARN, "Truncating E164 data to %zu octets (oops!)\n",
463706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	    sz);
464706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
465706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      *o->data = CALLBACK_E164;
466706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      memcpy(o->data + 1, lcp->want_callback.msg, sz);
467706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      INC_FSM_OPT(TY_CALLBACK, sz + 3, o);
468706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
469706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
470706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
471706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (lcp->want_mrru && !REJECTED(lcp, TY_MRRU)) {
472706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ua_htons(&lcp->want_mrru, o->data);
473706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    INC_FSM_OPT(TY_MRRU, 4, o);
474706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
475706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (lcp->want_shortseq && !REJECTED(lcp, TY_SHORTSEQ))
476706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      INC_FSM_OPT(TY_SHORTSEQ, 2, o);
477706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
478706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
479706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  mp = &lcp->fsm.bundle->ncp.mp;
480706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (mp->cfg.enddisc.class != 0 && IsEnabled(mp->cfg.negenddisc) &&
481706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      !REJECTED(lcp, TY_ENDDISC)) {
482706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    *o->data = mp->cfg.enddisc.class;
483706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    memcpy(o->data+1, mp->cfg.enddisc.address, mp->cfg.enddisc.len);
484706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    INC_FSM_OPT(TY_ENDDISC, mp->cfg.enddisc.len + 3, o);
485706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
486706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
487706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  fsm_Output(fp, CODE_CONFIGREQ, fp->reqid, buff, (u_char *)o - buff,
488706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             MB_LCPOUT);
489706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
490706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
491706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
492706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehlcp_SendProtoRej(struct lcp *lcp, u_char *option, int count)
493706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
494706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* Don't understand `option' */
495706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  fsm_Output(&lcp->fsm, CODE_PROTOREJ, lcp->fsm.reqid, option, count,
496706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             MB_LCPOUT);
497706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
498706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
499706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehint
500706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehlcp_SendIdentification(struct lcp *lcp)
501706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
502706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  static u_char id;		/* Use a private id */
503706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_char msg[DEF_MRU - 3];
504706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  const char *argv[2];
505706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  char *exp[2];
506706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
507706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (*lcp->cfg.ident == '\0')
508706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return 0;
509706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
510706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  argv[0] = lcp->cfg.ident;
511706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  argv[1] = NULL;
512706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
513706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  command_Expand(exp, 1, argv, lcp->fsm.bundle, 1, getpid());
514706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
515706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  ua_htonl(&lcp->want_magic, msg);
516706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  strncpy(msg + 4, exp[0], sizeof msg - 5);
517706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  msg[sizeof msg - 1] = '\0';
518706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
519706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  fsm_Output(&lcp->fsm, CODE_IDENT, id++, msg, 4 + strlen(msg + 4), MB_LCPOUT);
520706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  log_Printf(LogLCP, " MAGICNUM %08x\n", lcp->want_magic);
521706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  log_Printf(LogLCP, " TEXT %s\n", msg + 4);
522706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
523706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  command_Free(1, exp);
524706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return 1;
525706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
526706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
527706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
528706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehlcp_RecvIdentification(struct lcp *lcp, char *data)
529706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
530706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  log_Printf(LogLCP, " MAGICNUM %08x\n", lcp->his_magic);
531706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  log_Printf(LogLCP, " TEXT %s\n", data);
532706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
533706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
534706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
535706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehLcpSentTerminateReq(struct fsm *fp __unused)
536706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
537706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* Term REQ just sent by FSM */
538706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
539706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
540706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
541706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehLcpSendTerminateAck(struct fsm *fp, u_char id)
542706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
543706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* Send Term ACK please */
544706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct physical *p = link2physical(fp->link);
545706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
546706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (p && p->dl->state == DATALINK_CBCP)
547706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    cbcp_ReceiveTerminateReq(p);
548706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
549706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  fsm_Output(fp, CODE_TERMACK, id, NULL, 0, MB_LCPOUT);
550706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
551706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
552706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
553706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehLcpLayerStart(struct fsm *fp)
554706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
555706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* We're about to start up ! */
556706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct lcp *lcp = fsm2lcp(fp);
557706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
558706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  log_Printf(LogLCP, "%s: LayerStart\n", fp->link->name);
559706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->LcpFailedMagic = 0;
560706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  fp->more.reqs = fp->more.naks = fp->more.rejs = lcp->cfg.fsm.maxreq * 3;
561706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp->mru_req = 0;
562706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
563706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
564706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
565706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehLcpLayerFinish(struct fsm *fp)
566706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
567706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* We're now down */
568706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  log_Printf(LogLCP, "%s: LayerFinish\n", fp->link->name);
569706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
570706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
571706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int
572706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehLcpLayerUp(struct fsm *fp)
573706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
574706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* We're now up */
575706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct physical *p = link2physical(fp->link);
576706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct lcp *lcp = fsm2lcp(fp);
577706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
578706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  log_Printf(LogLCP, "%s: LayerUp\n", fp->link->name);
579706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  physical_SetAsyncParams(p, lcp->want_accmap, lcp->his_accmap);
580706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lqr_Start(lcp);
581706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  hdlc_StartTimer(&p->hdlc);
582706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  fp->more.reqs = fp->more.naks = fp->more.rejs = lcp->cfg.fsm.maxreq * 3;
583706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
584706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp_SendIdentification(lcp);
585706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
586706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return 1;
587706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
588706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
589706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
590706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehLcpLayerDown(struct fsm *fp)
591706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
592706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* About to come down */
593706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct physical *p = link2physical(fp->link);
594706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
595706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  log_Printf(LogLCP, "%s: LayerDown\n", fp->link->name);
596706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  hdlc_StopTimer(&p->hdlc);
597706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lqr_StopTimer(p);
598706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  lcp_Setup(fsm2lcp(fp), 0);
599706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
600706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
601706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int
602706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehE164ok(struct callback *cb, char *req, int sz)
603706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
604706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  char list[sizeof cb->msg], *next;
605706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int len;
606706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
607706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (!strcmp(cb->msg, "*"))
608706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return 1;
609706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
610706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  strncpy(list, cb->msg, sizeof list - 1);
611706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  list[sizeof list - 1] = '\0';
612706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  for (next = strtok(list, ","); next; next = strtok(NULL, ",")) {
613706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    len = strlen(next);
614706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (sz == len && !memcmp(list, req, sz))
615706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return 1;
616706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
617706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return 0;
618706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
619706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
620706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int
621706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehlcp_auth_nak(struct lcp *lcp, struct fsm_decode *dec)
622706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
623706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct fsm_opt nak;
624706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
625706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  nak.hdr.id = TY_AUTHPROTO;
626706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
627706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (IsAccepted(lcp->cfg.pap)) {
628706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    nak.hdr.len = 4;
629706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    nak.data[0] = (unsigned char)(PROTO_PAP >> 8);
630706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    nak.data[1] = (unsigned char)PROTO_PAP;
631706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    fsm_nak(dec, &nak);
632706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return 1;
633706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
634706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
635706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  nak.hdr.len = 5;
636706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  nak.data[0] = (unsigned char)(PROTO_CHAP >> 8);
637706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  nak.data[1] = (unsigned char)PROTO_CHAP;
638706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
639706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (IsAccepted(lcp->cfg.chap05)) {
640706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    nak.data[2] = 0x05;
641706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    fsm_nak(dec, &nak);
642706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
643706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else if (IsAccepted(lcp->cfg.chap80nt) ||
644706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             IsAccepted(lcp->cfg.chap80lm)) {
645706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    nak.data[2] = 0x80;
646706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    fsm_nak(dec, &nak);
647706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else if (IsAccepted(lcp->cfg.chap81)) {
648706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    nak.data[2] = 0x81;
649706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    fsm_nak(dec, &nak);
650706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
651706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else {
652706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    return 0;
653706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
654706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
655706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return 1;
656706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
657706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
658706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void
659706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehLcpDecodeConfig(struct fsm *fp, u_char *cp, u_char *end, int mode_type,
660706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                struct fsm_decode *dec)
661706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
662706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* Deal with incoming PROTO_LCP */
663706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct lcp *lcp = fsm2lcp(fp);
664706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int pos, op, callback_req, chap_type;
665706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  size_t sz;
666706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_int32_t magic, accmap;
667706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_short mru, phmtu, maxmtu, maxmru, wantmtu, wantmru, proto;
668706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct lqrreq req;
669706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  char request[20], desc[22];
670706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct mp *mp;
671706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct physical *p = link2physical(fp->link);
672706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct fsm_opt *opt, nak;
673706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
674706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  sz = 0;
675706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  op = callback_req = 0;
676706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
677706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  while (end - cp >= (int)sizeof(opt->hdr)) {
678706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if ((opt = fsm_readopt(&cp)) == NULL)
679706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
680706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
681706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    snprintf(request, sizeof request, " %s[%d]", protoname(opt->hdr.id),
682706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             opt->hdr.len);
683706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
684706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    switch (opt->hdr.id) {
685706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case TY_MRRU:
686706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      mp = &lcp->fsm.bundle->ncp.mp;
687706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      ua_ntohs(opt->data, &mru);
688706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogLCP, "%s %u\n", request, mru);
689706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
690706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      switch (mode_type) {
691706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REQ:
692706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (mp->cfg.mrru) {
693706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (REJECTED(lcp, TY_MRRU))
694706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            /* Ignore his previous reject so that we REQ next time */
695706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->his_reject &= ~(1 << opt->hdr.id);
696706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
697706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (mru > MAX_MRU) {
698706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            /* Push him down to MAX_MRU */
699706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->his_mrru = MAX_MRU;
700706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            nak.hdr.id = TY_MRRU;
701706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            nak.hdr.len = 4;
702706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            ua_htons(&lcp->his_mrru, nak.data);
703706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            fsm_nak(dec, &nak);
704706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          } else if (mru < MIN_MRU) {
705706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            /* Push him up to MIN_MRU */
706706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->his_mrru = MIN_MRU;
707706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            nak.hdr.id = TY_MRRU;
708706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            nak.hdr.len = 4;
709706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            ua_htons(&lcp->his_mrru, nak.data);
710706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            fsm_nak(dec, &nak);
711706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          } else {
712706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->his_mrru = mru;
713706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            fsm_ack(dec, opt);
714706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          }
715706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          break;
716706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else {
717706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_rej(dec, opt);
718706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->my_reject |= (1 << opt->hdr.id);
719706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
720706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
721706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_NAK:
722706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (mp->cfg.mrru) {
723706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (REJECTED(lcp, TY_MRRU))
724706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            /* Must have changed his mind ! */
725706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->his_reject &= ~(1 << opt->hdr.id);
726706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
727706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (mru > MAX_MRU)
728706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->want_mrru = MAX_MRU;
729706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          else if (mru < MIN_MRU)
730706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->want_mrru = MIN_MRU;
731706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          else
732706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->want_mrru = mru;
733706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
734706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        /* else we honour our config and don't send the suggested REQ */
735706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
736706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REJ:
737706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->his_reject |= (1 << opt->hdr.id);
738706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->want_mrru = 0;		/* Ah well, no multilink :-( */
739706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
740706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
741706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
742706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
743706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case TY_MRU:
744706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      lcp->mru_req = 1;
745706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      ua_ntohs(opt->data, &mru);
746706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogLCP, "%s %d\n", request, mru);
747706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
748706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      switch (mode_type) {
749706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REQ:
750706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        maxmtu = p ? physical_DeviceMTU(p) : 0;
751706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (lcp->cfg.max_mtu && (!maxmtu || maxmtu > lcp->cfg.max_mtu))
752706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          maxmtu = lcp->cfg.max_mtu;
753706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        wantmtu = lcp->cfg.mtu;
754706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (maxmtu && wantmtu > maxmtu) {
755706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogWARN, "%s: Reducing configured MTU from %u to %u\n",
756706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     fp->link->name, wantmtu, maxmtu);
757706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          wantmtu = maxmtu;
758706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
759706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
760706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (maxmtu && mru > maxmtu) {
761706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->his_mru = maxmtu;
762706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          nak.hdr.id = TY_MRU;
763706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          nak.hdr.len = 4;
764706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          ua_htons(&lcp->his_mru, nak.data);
765706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_nak(dec, &nak);
766706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else if (wantmtu && mru < wantmtu) {
767706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          /* Push him up to MTU or MIN_MRU */
768706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->his_mru = wantmtu;
769706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          nak.hdr.id = TY_MRU;
770706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          nak.hdr.len = 4;
771706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          ua_htons(&lcp->his_mru, nak.data);
772706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_nak(dec, &nak);
773706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else {
774706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->his_mru = mru;
775706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_ack(dec, opt);
776706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
777706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
778706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_NAK:
779706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        maxmru = p ? physical_DeviceMTU(p) : 0;
780706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (lcp->cfg.max_mru && (!maxmru || maxmru > lcp->cfg.max_mru))
781706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          maxmru = lcp->cfg.max_mru;
782706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        wantmru = lcp->cfg.mru > maxmru ? maxmru : lcp->cfg.mru;
783706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
784706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (wantmru && mru > wantmru)
785706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->want_mru = wantmru;
786706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        else if (mru > maxmru)
787706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->want_mru = maxmru;
788706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        else if (mru < MIN_MRU)
789706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->want_mru = MIN_MRU;
790706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        else
791706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->want_mru = mru;
792706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
793706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REJ:
794706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->his_reject |= (1 << opt->hdr.id);
795706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        /* Set the MTU to what we want anyway - the peer won't care! */
796706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (lcp->his_mru > lcp->want_mru)
797706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->his_mru = lcp->want_mru;
798706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
799706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
800706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
801706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
802706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case TY_ACCMAP:
803706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      ua_ntohl(opt->data, &accmap);
804706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogLCP, "%s 0x%08lx\n", request, (u_long)accmap);
805706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
806706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      switch (mode_type) {
807706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REQ:
808706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->his_accmap = accmap;
809706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        fsm_ack(dec, opt);
810706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
811706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_NAK:
812706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->want_accmap = accmap;
813706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
814706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REJ:
815706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->his_reject |= (1 << opt->hdr.id);
816706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
817706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
818706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
819706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
820706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case TY_AUTHPROTO:
821706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      ua_ntohs(opt->data, &proto);
822706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      chap_type = opt->hdr.len == 5 ? opt->data[2] : 0;
823706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
824706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogLCP, "%s 0x%04x (%s)\n", request, proto,
825706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 Auth2Nam(proto, chap_type));
826706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
827706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      switch (mode_type) {
828706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REQ:
829706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        switch (proto) {
830706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        case PROTO_PAP:
831706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (opt->hdr.len == 4 && IsAccepted(lcp->cfg.pap)) {
832706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->his_auth = proto;
833706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->his_authtype = 0;
834706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            fsm_ack(dec, opt);
835706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          } else if (!lcp_auth_nak(lcp, dec)) {
836706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->my_reject |= (1 << opt->hdr.id);
837706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            fsm_rej(dec, opt);
838706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          }
839706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          break;
840706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
841706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        case PROTO_CHAP:
842706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if ((chap_type == 0x05 && IsAccepted(lcp->cfg.chap05))
843706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
844706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              || (chap_type == 0x80 && (IsAccepted(lcp->cfg.chap80nt) ||
845706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                                   (IsAccepted(lcp->cfg.chap80lm))))
846706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              || (chap_type == 0x81 && IsAccepted(lcp->cfg.chap81))
847706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
848706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             ) {
849706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->his_auth = proto;
850706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->his_authtype = chap_type;
851706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            fsm_ack(dec, opt);
852706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          } else {
853706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifdef NODES
854706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            if (chap_type == 0x80) {
855706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              log_Printf(LogWARN, "CHAP 0x80 not available without DES\n");
856706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            } else if (chap_type == 0x81) {
857706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              log_Printf(LogWARN, "CHAP 0x81 not available without DES\n");
858706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            } else
859706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
860706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            if (chap_type != 0x05)
861706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              log_Printf(LogWARN, "%s not supported\n",
862706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                         Auth2Nam(PROTO_CHAP, chap_type));
863706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
864706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            if (!lcp_auth_nak(lcp, dec)) {
865706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              lcp->my_reject |= (1 << opt->hdr.id);
866706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              fsm_rej(dec, opt);
867706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            }
868706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          }
869706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          break;
870706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
871706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        default:
872706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogLCP, "%s 0x%04x - not recognised\n",
873706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    request, proto);
874706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (!lcp_auth_nak(lcp, dec)) {
875706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->my_reject |= (1 << opt->hdr.id);
876706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            fsm_rej(dec, opt);
877706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          }
878706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          break;
879706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
880706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
881706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
882706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_NAK:
883706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        switch (proto) {
884706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        case PROTO_PAP:
885706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (IsEnabled(lcp->cfg.pap)) {
886706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->want_auth = PROTO_PAP;
887706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->want_authtype = 0;
888706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          } else {
889706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            log_Printf(LogLCP, "Peer will only send PAP (not enabled)\n");
890706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->his_reject |= (1 << opt->hdr.id);
891706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          }
892706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          break;
893706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        case PROTO_CHAP:
894706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (chap_type == 0x05 && IsEnabled(lcp->cfg.chap05)) {
895706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->want_auth = PROTO_CHAP;
896706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->want_authtype = 0x05;
897706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
898706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          } else if (chap_type == 0x80 && (IsEnabled(lcp->cfg.chap80nt) ||
899706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                                           IsEnabled(lcp->cfg.chap80lm))) {
900706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->want_auth = PROTO_CHAP;
901706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->want_authtype = 0x80;
902706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          } else if (chap_type == 0x81 && IsEnabled(lcp->cfg.chap81)) {
903706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->want_auth = PROTO_CHAP;
904706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->want_authtype = 0x81;
905706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
906706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          } else {
907706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifdef NODES
908706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            if (chap_type == 0x80) {
909706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              log_Printf(LogLCP, "Peer will only send MSCHAP (not available"
910706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                         " without DES)\n");
911706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            } else if (chap_type == 0x81) {
912706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh              log_Printf(LogLCP, "Peer will only send MSCHAPV2 (not available"
913706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                         " without DES)\n");
914706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            } else
915706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
916706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            log_Printf(LogLCP, "Peer will only send %s (not %s)\n",
917706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                       Auth2Nam(PROTO_CHAP, chap_type),
918706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NODES
919706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                       (chap_type == 0x80 || chap_type == 0x81) ? "configured" :
920706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
921706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                       "supported");
922706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->his_reject |= (1 << opt->hdr.id);
923706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          }
924706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          break;
925706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        default:
926706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          /* We've been NAK'd with something we don't understand :-( */
927706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->his_reject |= (1 << opt->hdr.id);
928706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          break;
929706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
930706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
931706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
932706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REJ:
933706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->his_reject |= (1 << opt->hdr.id);
934706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
935706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
936706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
937706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
938706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case TY_QUALPROTO:
939706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      memcpy(&req, opt, sizeof req);
940706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogLCP, "%s proto %x, interval %lums\n",
941706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                request, ntohs(req.proto), (u_long)ntohl(req.period) * 10);
942706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      switch (mode_type) {
943706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REQ:
944706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (ntohs(req.proto) != PROTO_LQR || !IsAccepted(lcp->cfg.lqr)) {
945706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_rej(dec, opt);
946706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->my_reject |= (1 << opt->hdr.id);
947706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else {
948706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->his_lqrperiod = ntohl(req.period);
949706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (lcp->his_lqrperiod < MIN_LQRPERIOD * 100)
950706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->his_lqrperiod = MIN_LQRPERIOD * 100;
951706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          req.period = htonl(lcp->his_lqrperiod);
952706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_ack(dec, opt);
953706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
954706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
955706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_NAK:
956706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->want_lqrperiod = ntohl(req.period);
957706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
958706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REJ:
959706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->his_reject |= (1 << opt->hdr.id);
960706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
961706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
962706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
963706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
964706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case TY_MAGICNUM:
965706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      ua_ntohl(opt->data, &magic);
966706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogLCP, "%s 0x%08lx\n", request, (u_long)magic);
967706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
968706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      switch (mode_type) {
969706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REQ:
970706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (lcp->want_magic) {
971706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          /* Validate magic number */
972706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (magic == lcp->want_magic) {
973706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            sigset_t emptyset;
974706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
975706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            log_Printf(LogLCP, "Magic is same (%08lx) - %d times\n",
976706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                      (u_long)magic, ++lcp->LcpFailedMagic);
977706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->want_magic = GenerateMagic();
978706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            fsm_nak(dec, opt);
979706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            ualarm(TICKUNIT * (4 + 4 * lcp->LcpFailedMagic), 0);
980706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            sigemptyset(&emptyset);
981706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            sigsuspend(&emptyset);
982706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          } else {
983706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->his_magic = magic;
984706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            lcp->LcpFailedMagic = 0;
985706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            fsm_ack(dec, opt);
986706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          }
987706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else {
988706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->my_reject |= (1 << opt->hdr.id);
989706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_rej(dec, opt);
990706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
991706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
992706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_NAK:
993706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        log_Printf(LogLCP, " Magic 0x%08lx is NAKed!\n", (u_long)magic);
994706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->want_magic = GenerateMagic();
995706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
996706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REJ:
997706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        log_Printf(LogLCP, " Magic 0x%08x is REJected!\n", magic);
998706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->want_magic = 0;
999706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->his_reject |= (1 << opt->hdr.id);
1000706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
1001706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
1002706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
1003706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1004706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case TY_PROTOCOMP:
1005706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogLCP, "%s\n", request);
1006706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1007706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      switch (mode_type) {
1008706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REQ:
1009706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (IsAccepted(lcp->cfg.protocomp)) {
1010706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->his_protocomp = 1;
1011706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_ack(dec, opt);
1012706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else {
1013706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifdef OLDMST
1014706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          /* MorningStar before v1.3 needs NAK */
1015706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_nak(dec, opt);
1016706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#else
1017706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_rej(dec, opt);
1018706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->my_reject |= (1 << opt->hdr.id);
1019706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
1020706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
1021706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
1022706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_NAK:
1023706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REJ:
1024706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->want_protocomp = 0;
1025706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->his_reject |= (1 << opt->hdr.id);
1026706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
1027706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
1028706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
1029706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1030706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case TY_ACFCOMP:
1031706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogLCP, "%s\n", request);
1032706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      switch (mode_type) {
1033706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REQ:
1034706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (IsAccepted(lcp->cfg.acfcomp)) {
1035706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->his_acfcomp = 1;
1036706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_ack(dec, opt);
1037706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else {
1038706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifdef OLDMST
1039706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          /* MorningStar before v1.3 needs NAK */
1040706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_nak(dec, opt);
1041706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#else
1042706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_rej(dec, opt);
1043706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->my_reject |= (1 << opt->hdr.id);
1044706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
1045706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
1046706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
1047706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_NAK:
1048706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REJ:
1049706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->want_acfcomp = 0;
1050706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->his_reject |= (1 << opt->hdr.id);
1051706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
1052706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
1053706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
1054706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1055706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case TY_SDP:
1056706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogLCP, "%s\n", request);
1057706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      switch (mode_type) {
1058706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REQ:
1059706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_NAK:
1060706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REJ:
1061706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
1062706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
1063706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
1064706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1065706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case TY_CALLBACK:
1066706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (opt->hdr.len == 2) {
1067706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        op = CALLBACK_NONE;
1068706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        sz = 0;
1069706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      } else {
1070706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        op = (int)opt->data[0];
1071706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        sz = opt->hdr.len - 3;
1072706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
1073706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      switch (op) {
1074706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        case CALLBACK_AUTH:
1075706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogLCP, "%s Auth\n", request);
1076706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          break;
1077706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        case CALLBACK_DIALSTRING:
1078706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		log_Printf(LogLCP, "%s Dialstring %.*s\n", request, (int)sz,
1079706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     opt->data + 1);
1080706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          break;
1081706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        case CALLBACK_LOCATION:
1082706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		log_Printf(LogLCP, "%s Location %.*s\n", request, (int)sz,
1083706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		    opt->data + 1);
1084706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          break;
1085706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        case CALLBACK_E164:
1086706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		log_Printf(LogLCP, "%s E.164 (%.*s)\n", request, (int)sz,
1087706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		    opt->data + 1);
1088706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          break;
1089706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        case CALLBACK_NAME:
1090706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		log_Printf(LogLCP, "%s Name %.*s\n", request, (int)sz,
1091706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh		    opt->data + 1);
1092706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          break;
1093706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        case CALLBACK_CBCP:
1094706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogLCP, "%s CBCP\n", request);
1095706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          break;
1096706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        default:
1097706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogLCP, "%s ???\n", request);
1098706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          break;
1099706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
1100706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1101706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      switch (mode_type) {
1102706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REQ:
1103706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        callback_req = 1;
1104706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (p->type != PHYS_DIRECT) {
1105706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_rej(dec, opt);
1106706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->my_reject |= (1 << opt->hdr.id);
1107706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
1108706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        nak.hdr.id = opt->hdr.id;
1109706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        nak.hdr.len = 3;
1110706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(op)) &&
1111706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            (op != CALLBACK_AUTH || p->link.lcp.want_auth) &&
1112706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            (op != CALLBACK_E164 ||
1113706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh             E164ok(&p->dl->cfg.callback, opt->data + 1, sz))) {
1114706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->his_callback.opmask = CALLBACK_BIT(op);
1115706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (sz > sizeof lcp->his_callback.msg - 1) {
1116706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            sz = sizeof lcp->his_callback.msg - 1;
1117706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            log_Printf(LogWARN, "Truncating option arg to %zu octets\n", sz);
1118706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          }
1119706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          memcpy(lcp->his_callback.msg, opt->data + 1, sz);
1120706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->his_callback.msg[sz] = '\0';
1121706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_ack(dec, opt);
1122706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) &&
1123706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                    p->link.lcp.auth_ineed) {
1124706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          nak.data[0] = CALLBACK_AUTH;
1125706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_nak(dec, &nak);
1126706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) {
1127706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          nak.data[0] = CALLBACK_CBCP;
1128706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_nak(dec, &nak);
1129706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_E164)) {
1130706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          nak.data[0] = CALLBACK_E164;
1131706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_nak(dec, &nak);
1132706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) {
1133706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogWARN, "Cannot insist on auth callback without"
1134706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                     " PAP or CHAP enabled !\n");
1135706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          nak.data[0] = 2;
1136706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_nak(dec, &nak);
1137706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else {
1138706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->my_reject |= (1 << opt->hdr.id);
1139706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_rej(dec, opt);
1140706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
1141706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
1142706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_NAK:
1143706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        /* We don't do what he NAKs with, we do things in our preferred order */
1144706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_AUTH))
1145706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_AUTH);
1146706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_CBCP))
1147706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_CBCP);
1148706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_E164))
1149706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_E164);
1150706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (lcp->want_callback.opmask == CALLBACK_BIT(CALLBACK_NONE)) {
1151706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogPHASE, "Peer NAKd all callbacks, trying none\n");
1152706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->want_callback.opmask = 0;
1153706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else if (!lcp->want_callback.opmask) {
1154706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogPHASE, "Peer NAKd last configured callback\n");
1155706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_Close(&lcp->fsm);
1156706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
1157706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
1158706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REJ:
1159706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_NONE)) {
1160706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->his_reject |= (1 << opt->hdr.id);
1161706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->want_callback.opmask = 0;
1162706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else {
1163706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogPHASE, "Peer rejected *required* callback\n");
1164706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_Close(&lcp->fsm);
1165706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
1166706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
1167706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
1168706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
1169706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1170706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case TY_SHORTSEQ:
1171706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      mp = &lcp->fsm.bundle->ncp.mp;
1172706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogLCP, "%s\n", request);
1173706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1174706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      switch (mode_type) {
1175706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REQ:
1176706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (lcp->want_mrru && IsAccepted(mp->cfg.shortseq)) {
1177706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->his_shortseq = 1;
1178706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_ack(dec, opt);
1179706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else {
1180706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_rej(dec, opt);
1181706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->my_reject |= (1 << opt->hdr.id);
1182706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
1183706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
1184706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_NAK:
1185706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        /*
1186706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh         * He's trying to get us to ask for short sequence numbers.
1187706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh         * We ignore the NAK and honour our configuration file instead.
1188706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh         */
1189706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
1190706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REJ:
1191706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->his_reject |= (1 << opt->hdr.id);
1192706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->want_shortseq = 0;		/* For when we hit MP */
1193706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
1194706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
1195706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
1196706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1197706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    case TY_ENDDISC:
1198706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      mp = &lcp->fsm.bundle->ncp.mp;
1199706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogLCP, "%s %s\n", request,
1200706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 mp_Enddisc(opt->data[0], opt->data + 1, opt->hdr.len - 3));
1201706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      switch (mode_type) {
1202706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REQ:
1203706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        if (!p) {
1204706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          log_Printf(LogLCP, " ENDDISC rejected - not a physical link\n");
1205706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_rej(dec, opt);
1206706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->my_reject |= (1 << opt->hdr.id);
1207706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else if (!IsAccepted(mp->cfg.negenddisc)) {
1208706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->my_reject |= (1 << opt->hdr.id);
1209706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_rej(dec, opt);
1210706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else if (opt->hdr.len < sizeof p->dl->peer.enddisc.address + 3 &&
1211706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                   opt->data[0] <= MAX_ENDDISC_CLASS) {
1212706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          p->dl->peer.enddisc.class = opt->data[0];
1213706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          p->dl->peer.enddisc.len = opt->hdr.len - 3;
1214706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          memcpy(p->dl->peer.enddisc.address, opt->data + 1, opt->hdr.len - 3);
1215706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          p->dl->peer.enddisc.address[opt->hdr.len - 3] = '\0';
1216706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          /* XXX: If mp->active, compare and NAK with mp->peer ? */
1217706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_ack(dec, opt);
1218706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        } else {
1219706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          if (opt->data[0] > MAX_ENDDISC_CLASS)
1220706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            log_Printf(LogLCP, " ENDDISC rejected - unrecognised class %d\n",
1221706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                      opt->data[0]);
1222706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          else
1223706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh            log_Printf(LogLCP, " ENDDISC rejected - local max length is %ld\n",
1224706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                      (long)(sizeof p->dl->peer.enddisc.address - 1));
1225706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          fsm_rej(dec, opt);
1226706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          lcp->my_reject |= (1 << opt->hdr.id);
1227706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        }
1228706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
1229706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1230706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_NAK:	/* Treat this as a REJ, we don't vary our disc (yet) */
1231706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      case MODE_REJ:
1232706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->his_reject |= (1 << opt->hdr.id);
1233706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
1234706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
1235706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
1236706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1237706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    default:
1238706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      sz = (sizeof desc - 2) / 2;
1239706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (sz + 2 > opt->hdr.len)
1240706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        sz = opt->hdr.len - 2;
1241706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      pos = 0;
1242706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      desc[0] = sz ? ' ' : '\0';
1243706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      for (pos = 0; sz--; pos++)
1244706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        sprintf(desc+(pos<<1)+1, "%02x", opt->data[pos]);
1245706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1246706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogLCP, "%s%s\n", request, desc);
1247706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1248706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (mode_type == MODE_REQ) {
1249706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        fsm_rej(dec, opt);
1250706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->my_reject |= (1 << opt->hdr.id);
1251706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
1252706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      break;
1253706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
1254706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
1255706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1256706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (mode_type != MODE_NOP) {
1257706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (mode_type == MODE_REQ && p && p->type == PHYS_DIRECT &&
1258706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        p->dl->cfg.callback.opmask && !callback_req &&
1259706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        !(p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_NONE))) {
1260706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      /* We *REQUIRE* that the peer requests callback */
1261706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      nak.hdr.id = TY_CALLBACK;
1262706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      nak.hdr.len = 3;
1263706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) &&
1264706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh          p->link.lcp.want_auth)
1265706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        nak.data[0] = CALLBACK_AUTH;
1266706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_CBCP))
1267706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        nak.data[0] = CALLBACK_CBCP;
1268706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_E164))
1269706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        nak.data[0] = CALLBACK_E164;
1270706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      else {
1271706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        log_Printf(LogWARN, "Cannot insist on auth callback without"
1272706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                   " PAP or CHAP enabled !\n");
1273706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        nak.hdr.len = 2;	/* XXX: Silly ! */
1274706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
1275706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      fsm_nak(dec, &nak);
1276706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
1277706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (mode_type == MODE_REQ && !lcp->mru_req) {
1278706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      mru = DEF_MRU;
1279706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      phmtu = p ? physical_DeviceMTU(p) : 0;
1280706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (phmtu && mru > phmtu)
1281706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        mru = phmtu;
1282706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (mru > lcp->cfg.max_mtu)
1283706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        mru = lcp->cfg.max_mtu;
1284706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (mru < DEF_MRU) {
1285706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        /* Don't let the peer use the default MRU */
1286706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->his_mru = lcp->cfg.mtu && lcp->cfg.mtu < mru ? lcp->cfg.mtu : mru;
1287706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        nak.hdr.id = TY_MRU;
1288706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        nak.hdr.len = 4;
1289706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        ua_htons(&lcp->his_mru, nak.data);
1290706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        fsm_nak(dec, &nak);
1291706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        lcp->mru_req = 1;	/* Don't keep NAK'ing this */
1292706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
1293706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
1294706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    fsm_opt_normalise(dec);
1295706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
1296706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
1297706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
1298706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehextern struct mbuf *
1299706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehlcp_Input(struct bundle *bundle __unused, struct link *l, struct mbuf *bp)
1300706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
1301706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* Got PROTO_LCP from link */
1302706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  m_settype(bp, MB_LCPIN);
1303706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  fsm_Input(&l->lcp.fsm, bp);
1304706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return NULL;
1305706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
1306