1/*- 2 * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org> 3 * based on work by Toshiharu OHNO <tony-o@iij.ad.jp> 4 * Internet Initiative Japan, Inc (IIJ) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 *
| 1/*- 2 * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org> 3 * based on work by Toshiharu OHNO <tony-o@iij.ad.jp> 4 * Internet Initiative Japan, Inc (IIJ) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 *
|
28 * $FreeBSD: head/usr.sbin/ppp/lcp.c 78189 2001-06-13 21:52:19Z brian $
| 28 * $FreeBSD: head/usr.sbin/ppp/lcp.c 78410 2001-06-18 14:59:36Z brian $
|
29 */ 30 31#include <sys/param.h> 32#include <netinet/in.h> 33#include <netinet/in_systm.h> 34#include <netinet/ip.h> 35#include <sys/un.h> 36 37#include <signal.h> 38#include <stdio.h> 39#include <stdlib.h> 40#include <string.h> 41#include <termios.h> 42#include <unistd.h> 43 44#include "layer.h" 45#include "ua.h" 46#include "defs.h" 47#include "command.h" 48#include "mbuf.h" 49#include "log.h" 50#include "timer.h" 51#include "fsm.h" 52#include "iplist.h" 53#include "throughput.h" 54#include "proto.h" 55#include "descriptor.h" 56#include "lqr.h" 57#include "hdlc.h" 58#include "lcp.h" 59#include "ccp.h" 60#include "async.h" 61#include "link.h" 62#include "physical.h" 63#include "prompt.h" 64#include "slcompress.h" 65#include "ipcp.h" 66#include "filter.h" 67#include "mp.h" 68#include "chat.h" 69#include "auth.h" 70#include "chap.h" 71#include "cbcp.h" 72#include "datalink.h" 73#ifndef NORADIUS 74#include "radius.h" 75#endif 76#include "bundle.h" 77 78/* for received LQRs */ 79struct lqrreq { 80 u_char type; 81 u_char length; 82 u_short proto; /* Quality protocol */ 83 u_int32_t period; /* Reporting interval */ 84}; 85 86static int LcpLayerUp(struct fsm *); 87static void LcpLayerDown(struct fsm *); 88static void LcpLayerStart(struct fsm *); 89static void LcpLayerFinish(struct fsm *); 90static void LcpInitRestartCounter(struct fsm *, int); 91static void LcpSendConfigReq(struct fsm *); 92static void LcpSentTerminateReq(struct fsm *); 93static void LcpSendTerminateAck(struct fsm *, u_char); 94static void LcpDecodeConfig(struct fsm *, u_char *, int, int, 95 struct fsm_decode *); 96 97static struct fsm_callbacks lcp_Callbacks = { 98 LcpLayerUp, 99 LcpLayerDown, 100 LcpLayerStart, 101 LcpLayerFinish, 102 LcpInitRestartCounter, 103 LcpSendConfigReq, 104 LcpSentTerminateReq, 105 LcpSendTerminateAck, 106 LcpDecodeConfig, 107 fsm_NullRecvResetReq, 108 fsm_NullRecvResetAck 109}; 110 111static const char * const lcp_TimerNames[] = 112 {"LCP restart", "LCP openmode", "LCP stopped"}; 113 114static const char * 115protoname(int proto) 116{ 117 static const char * const cftypes[] = { 118 /* Check out the latest ``Assigned numbers'' rfc (1700) */ 119 NULL, 120 "MRU", /* 1: Maximum-Receive-Unit */ 121 "ACCMAP", /* 2: Async-Control-Character-Map */ 122 "AUTHPROTO", /* 3: Authentication-Protocol */ 123 "QUALPROTO", /* 4: Quality-Protocol */ 124 "MAGICNUM", /* 5: Magic-Number */ 125 "RESERVED", /* 6: RESERVED */ 126 "PROTOCOMP", /* 7: Protocol-Field-Compression */ 127 "ACFCOMP", /* 8: Address-and-Control-Field-Compression */ 128 "FCSALT", /* 9: FCS-Alternatives */ 129 "SDP", /* 10: Self-Describing-Pad */ 130 "NUMMODE", /* 11: Numbered-Mode */ 131 "MULTIPROC", /* 12: Multi-Link-Procedure */ 132 "CALLBACK", /* 13: Callback */ 133 "CONTIME", /* 14: Connect-Time */ 134 "COMPFRAME", /* 15: Compound-Frames */ 135 "NDE", /* 16: Nominal-Data-Encapsulation */ 136 "MRRU", /* 17: Multilink-MRRU */ 137 "SHORTSEQ", /* 18: Multilink-Short-Sequence-Number-Header */ 138 "ENDDISC", /* 19: Multilink-Endpoint-Discriminator */ 139 "PROPRIETRY", /* 20: Proprietary */ 140 "DCEID", /* 21: DCE-Identifier */ 141 "MULTIPP", /* 22: Multi-Link-Plus-Procedure */ 142 "LDBACP", /* 23: Link Discriminator for BACP */ 143 }; 144 145 if (proto < 0 || proto > sizeof cftypes / sizeof *cftypes || 146 cftypes[proto] == NULL) 147 return HexStr(proto, NULL, 0); 148 149 return cftypes[proto]; 150} 151 152int 153lcp_ReportStatus(struct cmdargs const *arg) 154{ 155 struct link *l; 156 struct lcp *lcp; 157 158 l = command_ChooseLink(arg); 159 lcp = &l->lcp; 160 161 prompt_Printf(arg->prompt, "%s: %s [%s]\n", l->name, lcp->fsm.name, 162 State2Nam(lcp->fsm.state)); 163 prompt_Printf(arg->prompt, 164 " his side: MRU %d, ACCMAP %08lx, PROTOCOMP %s, ACFCOMP %s,\n" 165 " MAGIC %08lx, MRRU %u, SHORTSEQ %s, REJECT %04x\n", 166 lcp->his_mru, (u_long)lcp->his_accmap, 167 lcp->his_protocomp ? "on" : "off", 168 lcp->his_acfcomp ? "on" : "off", 169 (u_long)lcp->his_magic, lcp->his_mrru, 170 lcp->his_shortseq ? "on" : "off", lcp->his_reject); 171 prompt_Printf(arg->prompt, 172 " my side: MRU %d, ACCMAP %08lx, PROTOCOMP %s, ACFCOMP %s,\n" 173 " MAGIC %08lx, MRRU %u, SHORTSEQ %s, REJECT %04x\n", 174 lcp->want_mru, (u_long)lcp->want_accmap, 175 lcp->want_protocomp ? "on" : "off", 176 lcp->want_acfcomp ? "on" : "off", 177 (u_long)lcp->want_magic, lcp->want_mrru, 178 lcp->want_shortseq ? "on" : "off", lcp->my_reject); 179
| 29 */ 30 31#include <sys/param.h> 32#include <netinet/in.h> 33#include <netinet/in_systm.h> 34#include <netinet/ip.h> 35#include <sys/un.h> 36 37#include <signal.h> 38#include <stdio.h> 39#include <stdlib.h> 40#include <string.h> 41#include <termios.h> 42#include <unistd.h> 43 44#include "layer.h" 45#include "ua.h" 46#include "defs.h" 47#include "command.h" 48#include "mbuf.h" 49#include "log.h" 50#include "timer.h" 51#include "fsm.h" 52#include "iplist.h" 53#include "throughput.h" 54#include "proto.h" 55#include "descriptor.h" 56#include "lqr.h" 57#include "hdlc.h" 58#include "lcp.h" 59#include "ccp.h" 60#include "async.h" 61#include "link.h" 62#include "physical.h" 63#include "prompt.h" 64#include "slcompress.h" 65#include "ipcp.h" 66#include "filter.h" 67#include "mp.h" 68#include "chat.h" 69#include "auth.h" 70#include "chap.h" 71#include "cbcp.h" 72#include "datalink.h" 73#ifndef NORADIUS 74#include "radius.h" 75#endif 76#include "bundle.h" 77 78/* for received LQRs */ 79struct lqrreq { 80 u_char type; 81 u_char length; 82 u_short proto; /* Quality protocol */ 83 u_int32_t period; /* Reporting interval */ 84}; 85 86static int LcpLayerUp(struct fsm *); 87static void LcpLayerDown(struct fsm *); 88static void LcpLayerStart(struct fsm *); 89static void LcpLayerFinish(struct fsm *); 90static void LcpInitRestartCounter(struct fsm *, int); 91static void LcpSendConfigReq(struct fsm *); 92static void LcpSentTerminateReq(struct fsm *); 93static void LcpSendTerminateAck(struct fsm *, u_char); 94static void LcpDecodeConfig(struct fsm *, u_char *, int, int, 95 struct fsm_decode *); 96 97static struct fsm_callbacks lcp_Callbacks = { 98 LcpLayerUp, 99 LcpLayerDown, 100 LcpLayerStart, 101 LcpLayerFinish, 102 LcpInitRestartCounter, 103 LcpSendConfigReq, 104 LcpSentTerminateReq, 105 LcpSendTerminateAck, 106 LcpDecodeConfig, 107 fsm_NullRecvResetReq, 108 fsm_NullRecvResetAck 109}; 110 111static const char * const lcp_TimerNames[] = 112 {"LCP restart", "LCP openmode", "LCP stopped"}; 113 114static const char * 115protoname(int proto) 116{ 117 static const char * const cftypes[] = { 118 /* Check out the latest ``Assigned numbers'' rfc (1700) */ 119 NULL, 120 "MRU", /* 1: Maximum-Receive-Unit */ 121 "ACCMAP", /* 2: Async-Control-Character-Map */ 122 "AUTHPROTO", /* 3: Authentication-Protocol */ 123 "QUALPROTO", /* 4: Quality-Protocol */ 124 "MAGICNUM", /* 5: Magic-Number */ 125 "RESERVED", /* 6: RESERVED */ 126 "PROTOCOMP", /* 7: Protocol-Field-Compression */ 127 "ACFCOMP", /* 8: Address-and-Control-Field-Compression */ 128 "FCSALT", /* 9: FCS-Alternatives */ 129 "SDP", /* 10: Self-Describing-Pad */ 130 "NUMMODE", /* 11: Numbered-Mode */ 131 "MULTIPROC", /* 12: Multi-Link-Procedure */ 132 "CALLBACK", /* 13: Callback */ 133 "CONTIME", /* 14: Connect-Time */ 134 "COMPFRAME", /* 15: Compound-Frames */ 135 "NDE", /* 16: Nominal-Data-Encapsulation */ 136 "MRRU", /* 17: Multilink-MRRU */ 137 "SHORTSEQ", /* 18: Multilink-Short-Sequence-Number-Header */ 138 "ENDDISC", /* 19: Multilink-Endpoint-Discriminator */ 139 "PROPRIETRY", /* 20: Proprietary */ 140 "DCEID", /* 21: DCE-Identifier */ 141 "MULTIPP", /* 22: Multi-Link-Plus-Procedure */ 142 "LDBACP", /* 23: Link Discriminator for BACP */ 143 }; 144 145 if (proto < 0 || proto > sizeof cftypes / sizeof *cftypes || 146 cftypes[proto] == NULL) 147 return HexStr(proto, NULL, 0); 148 149 return cftypes[proto]; 150} 151 152int 153lcp_ReportStatus(struct cmdargs const *arg) 154{ 155 struct link *l; 156 struct lcp *lcp; 157 158 l = command_ChooseLink(arg); 159 lcp = &l->lcp; 160 161 prompt_Printf(arg->prompt, "%s: %s [%s]\n", l->name, lcp->fsm.name, 162 State2Nam(lcp->fsm.state)); 163 prompt_Printf(arg->prompt, 164 " his side: MRU %d, ACCMAP %08lx, PROTOCOMP %s, ACFCOMP %s,\n" 165 " MAGIC %08lx, MRRU %u, SHORTSEQ %s, REJECT %04x\n", 166 lcp->his_mru, (u_long)lcp->his_accmap, 167 lcp->his_protocomp ? "on" : "off", 168 lcp->his_acfcomp ? "on" : "off", 169 (u_long)lcp->his_magic, lcp->his_mrru, 170 lcp->his_shortseq ? "on" : "off", lcp->his_reject); 171 prompt_Printf(arg->prompt, 172 " my side: MRU %d, ACCMAP %08lx, PROTOCOMP %s, ACFCOMP %s,\n" 173 " MAGIC %08lx, MRRU %u, SHORTSEQ %s, REJECT %04x\n", 174 lcp->want_mru, (u_long)lcp->want_accmap, 175 lcp->want_protocomp ? "on" : "off", 176 lcp->want_acfcomp ? "on" : "off", 177 (u_long)lcp->want_magic, lcp->want_mrru, 178 lcp->want_shortseq ? "on" : "off", lcp->my_reject); 179
|
180 prompt_Printf(arg->prompt, "\n Defaults: MRU = %d, ", lcp->cfg.mru);
| 180 prompt_Printf(arg->prompt, "\n Defaults: MRU = %d (max %d), ", 181 lcp->cfg.mru, lcp->cfg.max_mru); 182 if (lcp->cfg.mtu) 183 prompt_Printf(arg->prompt, "MTU = %d (max %d), ", 184 lcp->cfg.mtu, lcp->cfg.max_mtu); 185 else 186 prompt_Printf(arg->prompt, "MTU = any (max %d), ", lcp->cfg.max_mtu);
|
181 prompt_Printf(arg->prompt, "ACCMAP = %08lx\n", (u_long)lcp->cfg.accmap); 182 prompt_Printf(arg->prompt, " LQR period = %us, ", 183 lcp->cfg.lqrperiod); 184 prompt_Printf(arg->prompt, "Open Mode = %s", 185 lcp->cfg.openmode == OPEN_PASSIVE ? "passive" : "active"); 186 if (lcp->cfg.openmode > 0) 187 prompt_Printf(arg->prompt, " (delay %ds)", lcp->cfg.openmode); 188 prompt_Printf(arg->prompt, "\n FSM retry = %us, max %u Config" 189 " REQ%s, %u Term REQ%s\n", lcp->cfg.fsm.timeout, 190 lcp->cfg.fsm.maxreq, lcp->cfg.fsm.maxreq == 1 ? "" : "s", 191 lcp->cfg.fsm.maxtrm, lcp->cfg.fsm.maxtrm == 1 ? "" : "s"); 192 prompt_Printf(arg->prompt, " Ident: %s\n", lcp->cfg.ident); 193 prompt_Printf(arg->prompt, "\n Negotiation:\n"); 194 prompt_Printf(arg->prompt, " ACFCOMP = %s\n", 195 command_ShowNegval(lcp->cfg.acfcomp)); 196 prompt_Printf(arg->prompt, " CHAP = %s\n", 197 command_ShowNegval(lcp->cfg.chap05)); 198#ifdef HAVE_DES 199 prompt_Printf(arg->prompt, " CHAP80 = %s\n", 200 command_ShowNegval(lcp->cfg.chap80nt)); 201 prompt_Printf(arg->prompt, " LANMan = %s\n", 202 command_ShowNegval(lcp->cfg.chap80lm)); 203 prompt_Printf(arg->prompt, " CHAP81 = %s\n", 204 command_ShowNegval(lcp->cfg.chap81)); 205#endif 206 prompt_Printf(arg->prompt, " LQR = %s\n", 207 command_ShowNegval(lcp->cfg.lqr)); 208 prompt_Printf(arg->prompt, " PAP = %s\n", 209 command_ShowNegval(lcp->cfg.pap)); 210 prompt_Printf(arg->prompt, " PROTOCOMP = %s\n", 211 command_ShowNegval(lcp->cfg.protocomp)); 212 213 return 0; 214} 215 216static u_int32_t 217GenerateMagic(void) 218{ 219 /* Generate random number which will be used as magic number */ 220 randinit(); 221 return random(); 222} 223 224void 225lcp_SetupCallbacks(struct lcp *lcp) 226{ 227 lcp->fsm.fn = &lcp_Callbacks; 228 lcp->fsm.FsmTimer.name = lcp_TimerNames[0]; 229 lcp->fsm.OpenTimer.name = lcp_TimerNames[1]; 230 lcp->fsm.StoppedTimer.name = lcp_TimerNames[2]; 231} 232 233void 234lcp_Init(struct lcp *lcp, struct bundle *bundle, struct link *l, 235 const struct fsm_parent *parent) 236{ 237 /* Initialise ourselves */ 238 int mincode = parent ? 1 : LCP_MINMPCODE; 239 240 fsm_Init(&lcp->fsm, "LCP", PROTO_LCP, mincode, LCP_MAXCODE, LogLCP, 241 bundle, l, parent, &lcp_Callbacks, lcp_TimerNames); 242 243 lcp->cfg.mru = DEF_MRU;
| 187 prompt_Printf(arg->prompt, "ACCMAP = %08lx\n", (u_long)lcp->cfg.accmap); 188 prompt_Printf(arg->prompt, " LQR period = %us, ", 189 lcp->cfg.lqrperiod); 190 prompt_Printf(arg->prompt, "Open Mode = %s", 191 lcp->cfg.openmode == OPEN_PASSIVE ? "passive" : "active"); 192 if (lcp->cfg.openmode > 0) 193 prompt_Printf(arg->prompt, " (delay %ds)", lcp->cfg.openmode); 194 prompt_Printf(arg->prompt, "\n FSM retry = %us, max %u Config" 195 " REQ%s, %u Term REQ%s\n", lcp->cfg.fsm.timeout, 196 lcp->cfg.fsm.maxreq, lcp->cfg.fsm.maxreq == 1 ? "" : "s", 197 lcp->cfg.fsm.maxtrm, lcp->cfg.fsm.maxtrm == 1 ? "" : "s"); 198 prompt_Printf(arg->prompt, " Ident: %s\n", lcp->cfg.ident); 199 prompt_Printf(arg->prompt, "\n Negotiation:\n"); 200 prompt_Printf(arg->prompt, " ACFCOMP = %s\n", 201 command_ShowNegval(lcp->cfg.acfcomp)); 202 prompt_Printf(arg->prompt, " CHAP = %s\n", 203 command_ShowNegval(lcp->cfg.chap05)); 204#ifdef HAVE_DES 205 prompt_Printf(arg->prompt, " CHAP80 = %s\n", 206 command_ShowNegval(lcp->cfg.chap80nt)); 207 prompt_Printf(arg->prompt, " LANMan = %s\n", 208 command_ShowNegval(lcp->cfg.chap80lm)); 209 prompt_Printf(arg->prompt, " CHAP81 = %s\n", 210 command_ShowNegval(lcp->cfg.chap81)); 211#endif 212 prompt_Printf(arg->prompt, " LQR = %s\n", 213 command_ShowNegval(lcp->cfg.lqr)); 214 prompt_Printf(arg->prompt, " PAP = %s\n", 215 command_ShowNegval(lcp->cfg.pap)); 216 prompt_Printf(arg->prompt, " PROTOCOMP = %s\n", 217 command_ShowNegval(lcp->cfg.protocomp)); 218 219 return 0; 220} 221 222static u_int32_t 223GenerateMagic(void) 224{ 225 /* Generate random number which will be used as magic number */ 226 randinit(); 227 return random(); 228} 229 230void 231lcp_SetupCallbacks(struct lcp *lcp) 232{ 233 lcp->fsm.fn = &lcp_Callbacks; 234 lcp->fsm.FsmTimer.name = lcp_TimerNames[0]; 235 lcp->fsm.OpenTimer.name = lcp_TimerNames[1]; 236 lcp->fsm.StoppedTimer.name = lcp_TimerNames[2]; 237} 238 239void 240lcp_Init(struct lcp *lcp, struct bundle *bundle, struct link *l, 241 const struct fsm_parent *parent) 242{ 243 /* Initialise ourselves */ 244 int mincode = parent ? 1 : LCP_MINMPCODE; 245 246 fsm_Init(&lcp->fsm, "LCP", PROTO_LCP, mincode, LCP_MAXCODE, LogLCP, 247 bundle, l, parent, &lcp_Callbacks, lcp_TimerNames); 248 249 lcp->cfg.mru = DEF_MRU;
|
| 250 lcp->cfg.max_mru = MAX_MRU; 251 lcp->cfg.mtu = 0; 252 lcp->cfg.max_mtu = MAX_MTU;
|
244 lcp->cfg.accmap = 0; 245 lcp->cfg.openmode = 1; 246 lcp->cfg.lqrperiod = DEF_LQRPERIOD; 247 lcp->cfg.fsm.timeout = DEF_FSMRETRY; 248 lcp->cfg.fsm.maxreq = DEF_FSMTRIES; 249 lcp->cfg.fsm.maxtrm = DEF_FSMTRIES; 250 251 lcp->cfg.acfcomp = NEG_ENABLED|NEG_ACCEPTED; 252 lcp->cfg.chap05 = NEG_ACCEPTED; 253#ifdef HAVE_DES 254 lcp->cfg.chap80nt = NEG_ACCEPTED; 255 lcp->cfg.chap80lm = NEG_ACCEPTED; 256 lcp->cfg.chap81 = NEG_ACCEPTED; 257#endif 258 lcp->cfg.lqr = NEG_ACCEPTED; 259 lcp->cfg.pap = NEG_ACCEPTED; 260 lcp->cfg.protocomp = NEG_ENABLED|NEG_ACCEPTED; 261 *lcp->cfg.ident = '\0'; 262 263 lcp_Setup(lcp, lcp->cfg.openmode); 264} 265 266void 267lcp_Setup(struct lcp *lcp, int openmode) 268{
| 253 lcp->cfg.accmap = 0; 254 lcp->cfg.openmode = 1; 255 lcp->cfg.lqrperiod = DEF_LQRPERIOD; 256 lcp->cfg.fsm.timeout = DEF_FSMRETRY; 257 lcp->cfg.fsm.maxreq = DEF_FSMTRIES; 258 lcp->cfg.fsm.maxtrm = DEF_FSMTRIES; 259 260 lcp->cfg.acfcomp = NEG_ENABLED|NEG_ACCEPTED; 261 lcp->cfg.chap05 = NEG_ACCEPTED; 262#ifdef HAVE_DES 263 lcp->cfg.chap80nt = NEG_ACCEPTED; 264 lcp->cfg.chap80lm = NEG_ACCEPTED; 265 lcp->cfg.chap81 = NEG_ACCEPTED; 266#endif 267 lcp->cfg.lqr = NEG_ACCEPTED; 268 lcp->cfg.pap = NEG_ACCEPTED; 269 lcp->cfg.protocomp = NEG_ENABLED|NEG_ACCEPTED; 270 *lcp->cfg.ident = '\0'; 271 272 lcp_Setup(lcp, lcp->cfg.openmode); 273} 274 275void 276lcp_Setup(struct lcp *lcp, int openmode) 277{
|
| 278 struct physical *p = link2physical(lcp->fsm.link); 279 int phmtu = p ? physical_DeviceMTU(p) : 0; 280
|
269 lcp->fsm.open_mode = openmode; 270
| 281 lcp->fsm.open_mode = openmode; 282
|
271 lcp->his_mru = lcp->fsm.bundle->cfg.mtu; 272 if (!lcp->his_mru || lcp->his_mru > DEF_MRU) 273 lcp->his_mru = DEF_MRU;
| 283 lcp->his_mru = DEF_MRU;
|
274 lcp->his_mrru = 0; 275 lcp->his_magic = 0; 276 lcp->his_lqrperiod = 0; 277 lcp->his_acfcomp = 0; 278 lcp->his_auth = 0; 279 lcp->his_authtype = 0; 280 lcp->his_callback.opmask = 0; 281 lcp->his_shortseq = 0; 282 283 lcp->want_mru = lcp->cfg.mru;
| 284 lcp->his_mrru = 0; 285 lcp->his_magic = 0; 286 lcp->his_lqrperiod = 0; 287 lcp->his_acfcomp = 0; 288 lcp->his_auth = 0; 289 lcp->his_authtype = 0; 290 lcp->his_callback.opmask = 0; 291 lcp->his_shortseq = 0; 292 293 lcp->want_mru = lcp->cfg.mru;
|
| 294 if (phmtu && lcp->want_mru > phmtu) 295 lcp->want_mru = phmtu;
|
284 lcp->want_mrru = lcp->fsm.bundle->ncp.mp.cfg.mrru; 285 lcp->want_shortseq = IsEnabled(lcp->fsm.bundle->ncp.mp.cfg.shortseq) ? 1 : 0; 286 lcp->want_acfcomp = IsEnabled(lcp->cfg.acfcomp) ? 1 : 0; 287 288 if (lcp->fsm.parent) {
| 296 lcp->want_mrru = lcp->fsm.bundle->ncp.mp.cfg.mrru; 297 lcp->want_shortseq = IsEnabled(lcp->fsm.bundle->ncp.mp.cfg.shortseq) ? 1 : 0; 298 lcp->want_acfcomp = IsEnabled(lcp->cfg.acfcomp) ? 1 : 0; 299 300 if (lcp->fsm.parent) {
|
289 struct physical *p = link2physical(lcp->fsm.link); 290
| |
291 lcp->his_accmap = 0xffffffff; 292 lcp->want_accmap = lcp->cfg.accmap; 293 lcp->his_protocomp = 0; 294 lcp->want_protocomp = IsEnabled(lcp->cfg.protocomp) ? 1 : 0; 295 lcp->want_magic = GenerateMagic(); 296 297 if (IsEnabled(lcp->cfg.chap05)) { 298 lcp->want_auth = PROTO_CHAP; 299 lcp->want_authtype = 0x05; 300#ifdef HAVE_DES 301 } else if (IsEnabled(lcp->cfg.chap80nt) || 302 IsEnabled(lcp->cfg.chap80lm)) { 303 lcp->want_auth = PROTO_CHAP; 304 lcp->want_authtype = 0x80; 305 } else if (IsEnabled(lcp->cfg.chap81)) { 306 lcp->want_auth = PROTO_CHAP; 307 lcp->want_authtype = 0x81; 308#endif 309 } else if (IsEnabled(lcp->cfg.pap)) { 310 lcp->want_auth = PROTO_PAP; 311 lcp->want_authtype = 0; 312 } else { 313 lcp->want_auth = 0; 314 lcp->want_authtype = 0; 315 } 316 317 if (p->type != PHYS_DIRECT) 318 memcpy(&lcp->want_callback, &p->dl->cfg.callback, 319 sizeof(struct callback)); 320 else 321 lcp->want_callback.opmask = 0; 322 lcp->want_lqrperiod = IsEnabled(lcp->cfg.lqr) ? 323 lcp->cfg.lqrperiod * 100 : 0; 324 } else { 325 lcp->his_accmap = lcp->want_accmap = 0; 326 lcp->his_protocomp = lcp->want_protocomp = 1; 327 lcp->want_magic = 0; 328 lcp->want_auth = 0; 329 lcp->want_authtype = 0; 330 lcp->want_callback.opmask = 0; 331 lcp->want_lqrperiod = 0; 332 } 333 334 lcp->his_reject = lcp->my_reject = 0; 335 lcp->auth_iwait = lcp->auth_ineed = 0; 336 lcp->LcpFailedMagic = 0; 337} 338 339static void 340LcpInitRestartCounter(struct fsm *fp, int what) 341{ 342 /* Set fsm timer load */ 343 struct lcp *lcp = fsm2lcp(fp); 344 345 fp->FsmTimer.load = lcp->cfg.fsm.timeout * SECTICKS; 346 switch (what) { 347 case FSM_REQ_TIMER: 348 fp->restart = lcp->cfg.fsm.maxreq; 349 break; 350 case FSM_TRM_TIMER: 351 fp->restart = lcp->cfg.fsm.maxtrm; 352 break; 353 default: 354 fp->restart = 1; 355 break; 356 } 357} 358 359static void 360LcpSendConfigReq(struct fsm *fp) 361{ 362 /* Send config REQ please */ 363 struct physical *p = link2physical(fp->link); 364 struct lcp *lcp = fsm2lcp(fp); 365 u_char buff[200]; 366 struct lcp_opt *o; 367 struct mp *mp; 368 u_int16_t proto; 369 370 if (!p) { 371 log_Printf(LogERROR, "%s: LcpSendConfigReq: Not a physical link !\n", 372 fp->link->name); 373 return; 374 } 375 376 o = (struct lcp_opt *)buff; 377 if (!physical_IsSync(p)) { 378 if (lcp->want_acfcomp && !REJECTED(lcp, TY_ACFCOMP)) 379 INC_LCP_OPT(TY_ACFCOMP, 2, o); 380 381 if (lcp->want_protocomp && !REJECTED(lcp, TY_PROTOCOMP)) 382 INC_LCP_OPT(TY_PROTOCOMP, 2, o); 383 384 if (!REJECTED(lcp, TY_ACCMAP)) { 385 ua_htonl(&lcp->want_accmap, o->data); 386 INC_LCP_OPT(TY_ACCMAP, 6, o); 387 } 388 } 389 390 if (!REJECTED(lcp, TY_MRU)) { 391 ua_htons(&lcp->want_mru, o->data); 392 INC_LCP_OPT(TY_MRU, 4, o); 393 } 394 395 if (lcp->want_magic && !REJECTED(lcp, TY_MAGICNUM)) { 396 ua_htonl(&lcp->want_magic, o->data); 397 INC_LCP_OPT(TY_MAGICNUM, 6, o); 398 } 399 400 if (lcp->want_lqrperiod && !REJECTED(lcp, TY_QUALPROTO)) { 401 proto = PROTO_LQR; 402 ua_htons(&proto, o->data); 403 ua_htonl(&lcp->want_lqrperiod, o->data + 2); 404 INC_LCP_OPT(TY_QUALPROTO, 8, o); 405 } 406 407 switch (lcp->want_auth) { 408 case PROTO_PAP: 409 proto = PROTO_PAP; 410 ua_htons(&proto, o->data); 411 INC_LCP_OPT(TY_AUTHPROTO, 4, o); 412 break; 413 414 case PROTO_CHAP: 415 proto = PROTO_CHAP; 416 ua_htons(&proto, o->data); 417 o->data[2] = lcp->want_authtype; 418 INC_LCP_OPT(TY_AUTHPROTO, 5, o); 419 break; 420 } 421 422 if (!REJECTED(lcp, TY_CALLBACK)) { 423 if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) { 424 *o->data = CALLBACK_AUTH; 425 INC_LCP_OPT(TY_CALLBACK, 3, o); 426 } else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) { 427 *o->data = CALLBACK_CBCP; 428 INC_LCP_OPT(TY_CALLBACK, 3, o); 429 } else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_E164)) { 430 int sz = strlen(lcp->want_callback.msg); 431 432 if (sz > sizeof o->data - 1) { 433 sz = sizeof o->data - 1; 434 log_Printf(LogWARN, "Truncating E164 data to %d octets (oops!)\n", sz); 435 } 436 *o->data = CALLBACK_E164; 437 memcpy(o->data + 1, lcp->want_callback.msg, sz); 438 INC_LCP_OPT(TY_CALLBACK, sz + 3, o); 439 } 440 } 441 442 if (lcp->want_mrru && !REJECTED(lcp, TY_MRRU)) { 443 ua_htons(&lcp->want_mrru, o->data); 444 INC_LCP_OPT(TY_MRRU, 4, o); 445 446 if (lcp->want_shortseq && !REJECTED(lcp, TY_SHORTSEQ)) 447 INC_LCP_OPT(TY_SHORTSEQ, 2, o); 448 } 449 450 mp = &lcp->fsm.bundle->ncp.mp; 451 if (mp->cfg.enddisc.class != 0 && IsEnabled(mp->cfg.negenddisc) && 452 !REJECTED(lcp, TY_ENDDISC)) { 453 *o->data = mp->cfg.enddisc.class; 454 memcpy(o->data+1, mp->cfg.enddisc.address, mp->cfg.enddisc.len); 455 INC_LCP_OPT(TY_ENDDISC, mp->cfg.enddisc.len + 3, o); 456 } 457 458 fsm_Output(fp, CODE_CONFIGREQ, fp->reqid, buff, (u_char *)o - buff, 459 MB_LCPOUT); 460} 461 462void 463lcp_SendProtoRej(struct lcp *lcp, u_char *option, int count) 464{ 465 /* Don't understand `option' */ 466 fsm_Output(&lcp->fsm, CODE_PROTOREJ, lcp->fsm.reqid, option, count, 467 MB_LCPOUT); 468} 469 470int 471lcp_SendIdentification(struct lcp *lcp) 472{ 473 static u_char id; /* Use a private id */ 474 u_char msg[DEF_MRU - 3]; 475 const char *argv[2]; 476 char *exp[2]; 477 478 if (*lcp->cfg.ident == '\0') 479 return 0; 480 481 argv[0] = lcp->cfg.ident; 482 argv[1] = NULL; 483 484 command_Expand(exp, 1, argv, lcp->fsm.bundle, 1, getpid()); 485 486 ua_htonl(&lcp->want_magic, msg); 487 strncpy(msg + 4, exp[0], sizeof msg - 5); 488 msg[sizeof msg - 1] = '\0'; 489 490 log_Printf(LogLCP, "Sending ident magic %08x text %s\n", lcp->want_magic, 491 msg + 4); 492 fsm_Output(&lcp->fsm, CODE_IDENT, id++, msg, 4 + strlen(msg + 4), MB_LCPOUT); 493 494 free(exp[0]); 495 return 1; 496} 497 498void 499lcp_RecvIdentification(struct lcp *lcp, char *data) 500{ 501 log_Printf(LogLCP, "Received ident: %s\n", data); 502} 503 504static void 505LcpSentTerminateReq(struct fsm *fp) 506{ 507 /* Term REQ just sent by FSM */ 508} 509 510static void 511LcpSendTerminateAck(struct fsm *fp, u_char id) 512{ 513 /* Send Term ACK please */ 514 struct physical *p = link2physical(fp->link); 515 516 if (p && p->dl->state == DATALINK_CBCP) 517 cbcp_ReceiveTerminateReq(p); 518 519 fsm_Output(fp, CODE_TERMACK, id, NULL, 0, MB_LCPOUT); 520} 521 522static void 523LcpLayerStart(struct fsm *fp) 524{ 525 /* We're about to start up ! */ 526 struct lcp *lcp = fsm2lcp(fp); 527 528 log_Printf(LogLCP, "%s: LayerStart\n", fp->link->name); 529 lcp->LcpFailedMagic = 0; 530 fp->more.reqs = fp->more.naks = fp->more.rejs = lcp->cfg.fsm.maxreq * 3; 531} 532 533static void 534LcpLayerFinish(struct fsm *fp) 535{ 536 /* We're now down */ 537 log_Printf(LogLCP, "%s: LayerFinish\n", fp->link->name); 538} 539 540static int 541LcpLayerUp(struct fsm *fp) 542{ 543 /* We're now up */ 544 struct physical *p = link2physical(fp->link); 545 struct lcp *lcp = fsm2lcp(fp); 546 547 log_Printf(LogLCP, "%s: LayerUp\n", fp->link->name); 548 async_SetLinkParams(&p->async, lcp); 549 lqr_Start(lcp); 550 hdlc_StartTimer(&p->hdlc); 551 fp->more.reqs = fp->more.naks = fp->more.rejs = lcp->cfg.fsm.maxreq * 3; 552 553 lcp_SendIdentification(lcp); 554 555 return 1; 556} 557 558static void 559LcpLayerDown(struct fsm *fp) 560{ 561 /* About to come down */ 562 struct physical *p = link2physical(fp->link); 563 564 log_Printf(LogLCP, "%s: LayerDown\n", fp->link->name); 565 hdlc_StopTimer(&p->hdlc); 566 lqr_StopTimer(p); 567 lcp_Setup(fsm2lcp(fp), 0); 568} 569 570static int 571E164ok(struct callback *cb, char *req, int sz) 572{ 573 char list[sizeof cb->msg], *next; 574 int len; 575 576 if (!strcmp(cb->msg, "*")) 577 return 1; 578 579 strncpy(list, cb->msg, sizeof list - 1); 580 list[sizeof list - 1] = '\0'; 581 for (next = strtok(list, ","); next; next = strtok(NULL, ",")) { 582 len = strlen(next); 583 if (sz == len && !memcmp(list, req, sz)) 584 return 1; 585 } 586 return 0; 587} 588 589static void 590LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, 591 struct fsm_decode *dec) 592{ 593 /* Deal with incoming PROTO_LCP */ 594 struct lcp *lcp = fsm2lcp(fp);
| 301 lcp->his_accmap = 0xffffffff; 302 lcp->want_accmap = lcp->cfg.accmap; 303 lcp->his_protocomp = 0; 304 lcp->want_protocomp = IsEnabled(lcp->cfg.protocomp) ? 1 : 0; 305 lcp->want_magic = GenerateMagic(); 306 307 if (IsEnabled(lcp->cfg.chap05)) { 308 lcp->want_auth = PROTO_CHAP; 309 lcp->want_authtype = 0x05; 310#ifdef HAVE_DES 311 } else if (IsEnabled(lcp->cfg.chap80nt) || 312 IsEnabled(lcp->cfg.chap80lm)) { 313 lcp->want_auth = PROTO_CHAP; 314 lcp->want_authtype = 0x80; 315 } else if (IsEnabled(lcp->cfg.chap81)) { 316 lcp->want_auth = PROTO_CHAP; 317 lcp->want_authtype = 0x81; 318#endif 319 } else if (IsEnabled(lcp->cfg.pap)) { 320 lcp->want_auth = PROTO_PAP; 321 lcp->want_authtype = 0; 322 } else { 323 lcp->want_auth = 0; 324 lcp->want_authtype = 0; 325 } 326 327 if (p->type != PHYS_DIRECT) 328 memcpy(&lcp->want_callback, &p->dl->cfg.callback, 329 sizeof(struct callback)); 330 else 331 lcp->want_callback.opmask = 0; 332 lcp->want_lqrperiod = IsEnabled(lcp->cfg.lqr) ? 333 lcp->cfg.lqrperiod * 100 : 0; 334 } else { 335 lcp->his_accmap = lcp->want_accmap = 0; 336 lcp->his_protocomp = lcp->want_protocomp = 1; 337 lcp->want_magic = 0; 338 lcp->want_auth = 0; 339 lcp->want_authtype = 0; 340 lcp->want_callback.opmask = 0; 341 lcp->want_lqrperiod = 0; 342 } 343 344 lcp->his_reject = lcp->my_reject = 0; 345 lcp->auth_iwait = lcp->auth_ineed = 0; 346 lcp->LcpFailedMagic = 0; 347} 348 349static void 350LcpInitRestartCounter(struct fsm *fp, int what) 351{ 352 /* Set fsm timer load */ 353 struct lcp *lcp = fsm2lcp(fp); 354 355 fp->FsmTimer.load = lcp->cfg.fsm.timeout * SECTICKS; 356 switch (what) { 357 case FSM_REQ_TIMER: 358 fp->restart = lcp->cfg.fsm.maxreq; 359 break; 360 case FSM_TRM_TIMER: 361 fp->restart = lcp->cfg.fsm.maxtrm; 362 break; 363 default: 364 fp->restart = 1; 365 break; 366 } 367} 368 369static void 370LcpSendConfigReq(struct fsm *fp) 371{ 372 /* Send config REQ please */ 373 struct physical *p = link2physical(fp->link); 374 struct lcp *lcp = fsm2lcp(fp); 375 u_char buff[200]; 376 struct lcp_opt *o; 377 struct mp *mp; 378 u_int16_t proto; 379 380 if (!p) { 381 log_Printf(LogERROR, "%s: LcpSendConfigReq: Not a physical link !\n", 382 fp->link->name); 383 return; 384 } 385 386 o = (struct lcp_opt *)buff; 387 if (!physical_IsSync(p)) { 388 if (lcp->want_acfcomp && !REJECTED(lcp, TY_ACFCOMP)) 389 INC_LCP_OPT(TY_ACFCOMP, 2, o); 390 391 if (lcp->want_protocomp && !REJECTED(lcp, TY_PROTOCOMP)) 392 INC_LCP_OPT(TY_PROTOCOMP, 2, o); 393 394 if (!REJECTED(lcp, TY_ACCMAP)) { 395 ua_htonl(&lcp->want_accmap, o->data); 396 INC_LCP_OPT(TY_ACCMAP, 6, o); 397 } 398 } 399 400 if (!REJECTED(lcp, TY_MRU)) { 401 ua_htons(&lcp->want_mru, o->data); 402 INC_LCP_OPT(TY_MRU, 4, o); 403 } 404 405 if (lcp->want_magic && !REJECTED(lcp, TY_MAGICNUM)) { 406 ua_htonl(&lcp->want_magic, o->data); 407 INC_LCP_OPT(TY_MAGICNUM, 6, o); 408 } 409 410 if (lcp->want_lqrperiod && !REJECTED(lcp, TY_QUALPROTO)) { 411 proto = PROTO_LQR; 412 ua_htons(&proto, o->data); 413 ua_htonl(&lcp->want_lqrperiod, o->data + 2); 414 INC_LCP_OPT(TY_QUALPROTO, 8, o); 415 } 416 417 switch (lcp->want_auth) { 418 case PROTO_PAP: 419 proto = PROTO_PAP; 420 ua_htons(&proto, o->data); 421 INC_LCP_OPT(TY_AUTHPROTO, 4, o); 422 break; 423 424 case PROTO_CHAP: 425 proto = PROTO_CHAP; 426 ua_htons(&proto, o->data); 427 o->data[2] = lcp->want_authtype; 428 INC_LCP_OPT(TY_AUTHPROTO, 5, o); 429 break; 430 } 431 432 if (!REJECTED(lcp, TY_CALLBACK)) { 433 if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) { 434 *o->data = CALLBACK_AUTH; 435 INC_LCP_OPT(TY_CALLBACK, 3, o); 436 } else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) { 437 *o->data = CALLBACK_CBCP; 438 INC_LCP_OPT(TY_CALLBACK, 3, o); 439 } else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_E164)) { 440 int sz = strlen(lcp->want_callback.msg); 441 442 if (sz > sizeof o->data - 1) { 443 sz = sizeof o->data - 1; 444 log_Printf(LogWARN, "Truncating E164 data to %d octets (oops!)\n", sz); 445 } 446 *o->data = CALLBACK_E164; 447 memcpy(o->data + 1, lcp->want_callback.msg, sz); 448 INC_LCP_OPT(TY_CALLBACK, sz + 3, o); 449 } 450 } 451 452 if (lcp->want_mrru && !REJECTED(lcp, TY_MRRU)) { 453 ua_htons(&lcp->want_mrru, o->data); 454 INC_LCP_OPT(TY_MRRU, 4, o); 455 456 if (lcp->want_shortseq && !REJECTED(lcp, TY_SHORTSEQ)) 457 INC_LCP_OPT(TY_SHORTSEQ, 2, o); 458 } 459 460 mp = &lcp->fsm.bundle->ncp.mp; 461 if (mp->cfg.enddisc.class != 0 && IsEnabled(mp->cfg.negenddisc) && 462 !REJECTED(lcp, TY_ENDDISC)) { 463 *o->data = mp->cfg.enddisc.class; 464 memcpy(o->data+1, mp->cfg.enddisc.address, mp->cfg.enddisc.len); 465 INC_LCP_OPT(TY_ENDDISC, mp->cfg.enddisc.len + 3, o); 466 } 467 468 fsm_Output(fp, CODE_CONFIGREQ, fp->reqid, buff, (u_char *)o - buff, 469 MB_LCPOUT); 470} 471 472void 473lcp_SendProtoRej(struct lcp *lcp, u_char *option, int count) 474{ 475 /* Don't understand `option' */ 476 fsm_Output(&lcp->fsm, CODE_PROTOREJ, lcp->fsm.reqid, option, count, 477 MB_LCPOUT); 478} 479 480int 481lcp_SendIdentification(struct lcp *lcp) 482{ 483 static u_char id; /* Use a private id */ 484 u_char msg[DEF_MRU - 3]; 485 const char *argv[2]; 486 char *exp[2]; 487 488 if (*lcp->cfg.ident == '\0') 489 return 0; 490 491 argv[0] = lcp->cfg.ident; 492 argv[1] = NULL; 493 494 command_Expand(exp, 1, argv, lcp->fsm.bundle, 1, getpid()); 495 496 ua_htonl(&lcp->want_magic, msg); 497 strncpy(msg + 4, exp[0], sizeof msg - 5); 498 msg[sizeof msg - 1] = '\0'; 499 500 log_Printf(LogLCP, "Sending ident magic %08x text %s\n", lcp->want_magic, 501 msg + 4); 502 fsm_Output(&lcp->fsm, CODE_IDENT, id++, msg, 4 + strlen(msg + 4), MB_LCPOUT); 503 504 free(exp[0]); 505 return 1; 506} 507 508void 509lcp_RecvIdentification(struct lcp *lcp, char *data) 510{ 511 log_Printf(LogLCP, "Received ident: %s\n", data); 512} 513 514static void 515LcpSentTerminateReq(struct fsm *fp) 516{ 517 /* Term REQ just sent by FSM */ 518} 519 520static void 521LcpSendTerminateAck(struct fsm *fp, u_char id) 522{ 523 /* Send Term ACK please */ 524 struct physical *p = link2physical(fp->link); 525 526 if (p && p->dl->state == DATALINK_CBCP) 527 cbcp_ReceiveTerminateReq(p); 528 529 fsm_Output(fp, CODE_TERMACK, id, NULL, 0, MB_LCPOUT); 530} 531 532static void 533LcpLayerStart(struct fsm *fp) 534{ 535 /* We're about to start up ! */ 536 struct lcp *lcp = fsm2lcp(fp); 537 538 log_Printf(LogLCP, "%s: LayerStart\n", fp->link->name); 539 lcp->LcpFailedMagic = 0; 540 fp->more.reqs = fp->more.naks = fp->more.rejs = lcp->cfg.fsm.maxreq * 3; 541} 542 543static void 544LcpLayerFinish(struct fsm *fp) 545{ 546 /* We're now down */ 547 log_Printf(LogLCP, "%s: LayerFinish\n", fp->link->name); 548} 549 550static int 551LcpLayerUp(struct fsm *fp) 552{ 553 /* We're now up */ 554 struct physical *p = link2physical(fp->link); 555 struct lcp *lcp = fsm2lcp(fp); 556 557 log_Printf(LogLCP, "%s: LayerUp\n", fp->link->name); 558 async_SetLinkParams(&p->async, lcp); 559 lqr_Start(lcp); 560 hdlc_StartTimer(&p->hdlc); 561 fp->more.reqs = fp->more.naks = fp->more.rejs = lcp->cfg.fsm.maxreq * 3; 562 563 lcp_SendIdentification(lcp); 564 565 return 1; 566} 567 568static void 569LcpLayerDown(struct fsm *fp) 570{ 571 /* About to come down */ 572 struct physical *p = link2physical(fp->link); 573 574 log_Printf(LogLCP, "%s: LayerDown\n", fp->link->name); 575 hdlc_StopTimer(&p->hdlc); 576 lqr_StopTimer(p); 577 lcp_Setup(fsm2lcp(fp), 0); 578} 579 580static int 581E164ok(struct callback *cb, char *req, int sz) 582{ 583 char list[sizeof cb->msg], *next; 584 int len; 585 586 if (!strcmp(cb->msg, "*")) 587 return 1; 588 589 strncpy(list, cb->msg, sizeof list - 1); 590 list[sizeof list - 1] = '\0'; 591 for (next = strtok(list, ","); next; next = strtok(NULL, ",")) { 592 len = strlen(next); 593 if (sz == len && !memcmp(list, req, sz)) 594 return 1; 595 } 596 return 0; 597} 598 599static void 600LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, 601 struct fsm_decode *dec) 602{ 603 /* Deal with incoming PROTO_LCP */ 604 struct lcp *lcp = fsm2lcp(fp);
|
595 int type, length, sz, pos, op, callback_req;
| 605 int type, length, sz, pos, op, callback_req, mru_req;
|
596 u_int32_t magic, accmap;
| 606 u_int32_t magic, accmap;
|
597 u_short mtu, mru, proto;
| 607 u_short mru, phmtu, proto;
|
598 struct lqrreq *req; 599 char request[20], desc[22]; 600 struct mp *mp; 601 struct physical *p = link2physical(fp->link); 602
| 608 struct lqrreq *req; 609 char request[20], desc[22]; 610 struct mp *mp; 611 struct physical *p = link2physical(fp->link); 612
|
603 sz = op = callback_req = 0;
| 613 sz = op = callback_req = mru_req = 0;
|
604 605 while (plen >= sizeof(struct fsmconfig)) { 606 type = *cp; 607 length = cp[1]; 608 609 snprintf(request, sizeof request, " %s[%d]", protoname(type), length); 610 611 if (length < 2) { 612 log_Printf(LogLCP, "%s:%s: Bad LCP length\n", fp->link->name, request); 613 break; 614 } 615 616 switch (type) { 617 case TY_MRRU: 618 mp = &lcp->fsm.bundle->ncp.mp; 619 ua_ntohs(cp + 2, &mru); 620 log_Printf(LogLCP, "%s %u\n", request, mru); 621 622 switch (mode_type) { 623 case MODE_REQ: 624 if (mp->cfg.mrru) { 625 if (REJECTED(lcp, TY_MRRU)) 626 /* Ignore his previous reject so that we REQ next time */ 627 lcp->his_reject &= ~(1 << type); 628
| 614 615 while (plen >= sizeof(struct fsmconfig)) { 616 type = *cp; 617 length = cp[1]; 618 619 snprintf(request, sizeof request, " %s[%d]", protoname(type), length); 620 621 if (length < 2) { 622 log_Printf(LogLCP, "%s:%s: Bad LCP length\n", fp->link->name, request); 623 break; 624 } 625 626 switch (type) { 627 case TY_MRRU: 628 mp = &lcp->fsm.bundle->ncp.mp; 629 ua_ntohs(cp + 2, &mru); 630 log_Printf(LogLCP, "%s %u\n", request, mru); 631 632 switch (mode_type) { 633 case MODE_REQ: 634 if (mp->cfg.mrru) { 635 if (REJECTED(lcp, TY_MRRU)) 636 /* Ignore his previous reject so that we REQ next time */ 637 lcp->his_reject &= ~(1 << type); 638
|
629 if (mru < MIN_MRU) {
| 639 if (mru > MAX_MRU) { 640 /* Push him down to MAX_MRU */ 641 lcp->his_mrru = MAX_MRU; 642 memcpy(dec->nakend, cp, 2); 643 ua_htons(&lcp->his_mrru, dec->nakend + 2); 644 dec->nakend += 4; 645 } else if (mru < MIN_MRU) {
|
630 /* Push him up to MIN_MRU */ 631 lcp->his_mrru = MIN_MRU; 632 memcpy(dec->nakend, cp, 2); 633 ua_htons(&lcp->his_mrru, dec->nakend + 2); 634 dec->nakend += 4; 635 } else { 636 lcp->his_mrru = mru; 637 memcpy(dec->ackend, cp, 4); 638 dec->ackend += 4; 639 } 640 break; 641 } else 642 goto reqreject; 643 break; 644 case MODE_NAK: 645 if (mp->cfg.mrru) { 646 if (REJECTED(lcp, TY_MRRU)) 647 /* Must have changed his mind ! */ 648 lcp->his_reject &= ~(1 << type); 649 650 if (mru > MAX_MRU) 651 lcp->want_mrru = MAX_MRU; 652 else if (mru < MIN_MRU) 653 lcp->want_mrru = MIN_MRU; 654 else 655 lcp->want_mrru = mru; 656 } 657 /* else we honour our config and don't send the suggested REQ */ 658 break; 659 case MODE_REJ: 660 lcp->his_reject |= (1 << type); 661 lcp->want_mrru = 0; /* Ah well, no multilink :-( */ 662 break; 663 } 664 break; 665 666 case TY_MRU:
| 646 /* Push him up to MIN_MRU */ 647 lcp->his_mrru = MIN_MRU; 648 memcpy(dec->nakend, cp, 2); 649 ua_htons(&lcp->his_mrru, dec->nakend + 2); 650 dec->nakend += 4; 651 } else { 652 lcp->his_mrru = mru; 653 memcpy(dec->ackend, cp, 4); 654 dec->ackend += 4; 655 } 656 break; 657 } else 658 goto reqreject; 659 break; 660 case MODE_NAK: 661 if (mp->cfg.mrru) { 662 if (REJECTED(lcp, TY_MRRU)) 663 /* Must have changed his mind ! */ 664 lcp->his_reject &= ~(1 << type); 665 666 if (mru > MAX_MRU) 667 lcp->want_mrru = MAX_MRU; 668 else if (mru < MIN_MRU) 669 lcp->want_mrru = MIN_MRU; 670 else 671 lcp->want_mrru = mru; 672 } 673 /* else we honour our config and don't send the suggested REQ */ 674 break; 675 case MODE_REJ: 676 lcp->his_reject |= (1 << type); 677 lcp->want_mrru = 0; /* Ah well, no multilink :-( */ 678 break; 679 } 680 break; 681 682 case TY_MRU:
|
| 683 mru_req = 1;
|
667 ua_ntohs(cp + 2, &mru); 668 log_Printf(LogLCP, "%s %d\n", request, mru); 669 670 switch (mode_type) { 671 case MODE_REQ:
| 684 ua_ntohs(cp + 2, &mru); 685 log_Printf(LogLCP, "%s %d\n", request, mru); 686 687 switch (mode_type) { 688 case MODE_REQ:
|
672 mtu = lcp->fsm.bundle->cfg.mtu; 673 if (mru < MIN_MRU || (!lcp->want_mrru && mru < mtu)) {
| 689 phmtu = p ? physical_DeviceMTU(p) : 0; 690 if (phmtu && mru > phmtu) { 691 lcp->his_mru = lcp->cfg.mtu ? lcp->cfg.mtu : phmtu; 692 memcpy(dec->nakend, cp, 2); 693 ua_htons(&lcp->his_mru, dec->nakend + 2); 694 dec->nakend += 4; 695 } if (mru > lcp->cfg.max_mtu) { 696 lcp->his_mru = lcp->cfg.mtu ? lcp->cfg.mtu : lcp->cfg.max_mtu; 697 memcpy(dec->nakend, cp, 2); 698 ua_htons(&lcp->his_mru, dec->nakend + 2); 699 dec->nakend += 4; 700 } else if (mru < MIN_MRU || mru < lcp->cfg.mtu) {
|
674 /* Push him up to MTU or MIN_MRU */
| 701 /* Push him up to MTU or MIN_MRU */
|
675 lcp->his_mru = mru < mtu ? mtu : MIN_MRU;
| 702 lcp->his_mru = mru < lcp->cfg.mtu ? lcp->cfg.mtu : MIN_MRU;
|
676 memcpy(dec->nakend, cp, 2); 677 ua_htons(&lcp->his_mru, dec->nakend + 2); 678 dec->nakend += 4; 679 } else {
| 703 memcpy(dec->nakend, cp, 2); 704 ua_htons(&lcp->his_mru, dec->nakend + 2); 705 dec->nakend += 4; 706 } else {
|
680 lcp->his_mru = mtu ? mtu : mru;
| 707 lcp->his_mru = lcp->cfg.mtu ? lcp->cfg.mtu : mru;
|
681 memcpy(dec->ackend, cp, 4); 682 dec->ackend += 4; 683 } 684 break; 685 case MODE_NAK:
| 708 memcpy(dec->ackend, cp, 4); 709 dec->ackend += 4; 710 } 711 break; 712 case MODE_NAK:
|
686 if (mru > MAX_MRU) 687 lcp->want_mru = MAX_MRU; 688 else if (mru < MIN_MRU)
| 713 if (mru > lcp->cfg.max_mru) { 714 lcp->want_mru = lcp->cfg.max_mru; 715 if (p && lcp->want_mru > physical_DeviceMTU(p)) 716 lcp->want_mru = physical_DeviceMTU(p); 717 } else if (mru < MIN_MRU)
|
689 lcp->want_mru = MIN_MRU; 690 else 691 lcp->want_mru = mru; 692 break; 693 case MODE_REJ: 694 lcp->his_reject |= (1 << type); 695 break; 696 } 697 break; 698 699 case TY_ACCMAP: 700 ua_ntohl(cp + 2, &accmap); 701 log_Printf(LogLCP, "%s 0x%08lx\n", request, (u_long)accmap); 702 703 switch (mode_type) { 704 case MODE_REQ: 705 lcp->his_accmap = accmap; 706 memcpy(dec->ackend, cp, 6); 707 dec->ackend += 6; 708 break; 709 case MODE_NAK: 710 lcp->want_accmap = accmap; 711 break; 712 case MODE_REJ: 713 lcp->his_reject |= (1 << type); 714 break; 715 } 716 break; 717 718 case TY_AUTHPROTO: 719 ua_ntohs(cp + 2, &proto); 720 log_Printf(LogLCP, "%s 0x%04x (%s)\n", request, proto, 721 Auth2Nam(proto, length > 4 ? cp[4] : 0)); 722 723 switch (mode_type) { 724 case MODE_REQ: 725 switch (proto) { 726 case PROTO_PAP: 727 if (length != 4) { 728 log_Printf(LogLCP, " Bad length!\n"); 729 goto reqreject; 730 } 731 if (IsAccepted(lcp->cfg.pap)) { 732 lcp->his_auth = proto; 733 lcp->his_authtype = 0; 734 memcpy(dec->ackend, cp, length); 735 dec->ackend += length; 736 } else if (IsAccepted(lcp->cfg.chap05)) { 737 *dec->nakend++ = *cp; 738 *dec->nakend++ = 5; 739 *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); 740 *dec->nakend++ = (unsigned char) PROTO_CHAP; 741 *dec->nakend++ = 0x05; 742#ifdef HAVE_DES 743 } else if (IsAccepted(lcp->cfg.chap80nt) || 744 IsAccepted(lcp->cfg.chap80lm)) { 745 *dec->nakend++ = *cp; 746 *dec->nakend++ = 5; 747 *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); 748 *dec->nakend++ = (unsigned char) PROTO_CHAP; 749 *dec->nakend++ = 0x80; 750 } else if (IsAccepted(lcp->cfg.chap81)) { 751 *dec->nakend++ = *cp; 752 *dec->nakend++ = 5; 753 *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); 754 *dec->nakend++ = (unsigned char) PROTO_CHAP; 755 *dec->nakend++ = 0x81; 756#endif 757 } else 758 goto reqreject; 759 break; 760 761 case PROTO_CHAP: 762 if (length != 5) { 763 log_Printf(LogLCP, " Bad length!\n"); 764 goto reqreject; 765 } 766 if ((cp[4] == 0x05 && IsAccepted(lcp->cfg.chap05)) 767#ifdef HAVE_DES 768 || (cp[4] == 0x80 && (IsAccepted(lcp->cfg.chap80nt) || 769 (IsAccepted(lcp->cfg.chap80lm)))) 770 || (cp[4] == 0x81 && IsAccepted(lcp->cfg.chap81)) 771#endif 772 ) { 773 lcp->his_auth = proto; 774 lcp->his_authtype = cp[4]; 775 memcpy(dec->ackend, cp, length); 776 dec->ackend += length; 777 } else { 778#ifndef HAVE_DES 779 if (cp[4] == 0x80) { 780 log_Printf(LogWARN, "CHAP 0x80 not available without DES\n"); 781 } else if (cp[4] == 0x81) { 782 log_Printf(LogWARN, "CHAP 0x81 not available without DES\n"); 783 } else 784#endif 785 if (cp[4] != 0x05) 786 log_Printf(LogWARN, "%s not supported\n", 787 Auth2Nam(PROTO_CHAP, cp[4])); 788 789 if (IsAccepted(lcp->cfg.chap05)) { 790 *dec->nakend++ = *cp; 791 *dec->nakend++ = 5; 792 *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); 793 *dec->nakend++ = (unsigned char) PROTO_CHAP; 794 *dec->nakend++ = 0x05; 795#ifdef HAVE_DES 796 } else if (IsAccepted(lcp->cfg.chap80nt) || 797 IsAccepted(lcp->cfg.chap80lm)) { 798 *dec->nakend++ = *cp; 799 *dec->nakend++ = 5; 800 *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); 801 *dec->nakend++ = (unsigned char) PROTO_CHAP; 802 *dec->nakend++ = 0x80; 803 } else if (IsAccepted(lcp->cfg.chap81)) { 804 *dec->nakend++ = *cp; 805 *dec->nakend++ = 5; 806 *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); 807 *dec->nakend++ = (unsigned char) PROTO_CHAP; 808 *dec->nakend++ = 0x81; 809#endif 810 } else if (IsAccepted(lcp->cfg.pap)) { 811 *dec->nakend++ = *cp; 812 *dec->nakend++ = 4; 813 *dec->nakend++ = (unsigned char) (PROTO_PAP >> 8); 814 *dec->nakend++ = (unsigned char) PROTO_PAP; 815 } else 816 goto reqreject; 817 } 818 break; 819 820 default: 821 log_Printf(LogLCP, "%s 0x%04x - not recognised, NAK\n", 822 request, proto); 823 memcpy(dec->nakend, cp, length); 824 dec->nakend += length; 825 break; 826 } 827 break; 828 case MODE_NAK: 829 switch (proto) { 830 case PROTO_PAP: 831 if (IsEnabled(lcp->cfg.pap)) { 832 lcp->want_auth = PROTO_PAP; 833 lcp->want_authtype = 0; 834 } else { 835 log_Printf(LogLCP, "Peer will only send PAP (not enabled)\n"); 836 lcp->his_reject |= (1 << type); 837 } 838 break; 839 case PROTO_CHAP: 840 if (cp[4] == 0x05 && IsEnabled(lcp->cfg.chap05)) { 841 lcp->want_auth = PROTO_CHAP; 842 lcp->want_authtype = 0x05; 843#ifdef HAVE_DES 844 } else if (cp[4] == 0x80 && (IsEnabled(lcp->cfg.chap80nt) || 845 IsEnabled(lcp->cfg.chap80lm))) { 846 lcp->want_auth = PROTO_CHAP; 847 lcp->want_authtype = 0x80; 848 } else if (cp[4] == 0x81 && IsEnabled(lcp->cfg.chap81)) { 849 lcp->want_auth = PROTO_CHAP; 850 lcp->want_authtype = 0x81; 851#endif 852 } else { 853#ifndef HAVE_DES 854 if (cp[4] == 0x80) { 855 log_Printf(LogLCP, "Peer will only send MSCHAP (not available" 856 " without DES)\n"); 857 } else if (cp[4] == 0x81) { 858 log_Printf(LogLCP, "Peer will only send MSCHAPV2 (not available" 859 " without DES)\n"); 860 } else 861#endif 862 log_Printf(LogLCP, "Peer will only send %s (not %s)\n", 863 Auth2Nam(PROTO_CHAP, cp[4]), 864#ifdef HAVE_DES 865 (cp[4] == 0x80 || cp[4] == 0x81) ? "configured" : 866#endif 867 "supported"); 868 lcp->his_reject |= (1 << type); 869 } 870 break; 871 default: 872 /* We've been NAK'd with something we don't understand :-( */ 873 lcp->his_reject |= (1 << type); 874 break; 875 } 876 break; 877 case MODE_REJ: 878 lcp->his_reject |= (1 << type); 879 break; 880 } 881 break; 882 883 case TY_QUALPROTO: 884 req = (struct lqrreq *)cp; 885 log_Printf(LogLCP, "%s proto %x, interval %lums\n", 886 request, ntohs(req->proto), (u_long)ntohl(req->period) * 10); 887 switch (mode_type) { 888 case MODE_REQ: 889 if (ntohs(req->proto) != PROTO_LQR || !IsAccepted(lcp->cfg.lqr)) 890 goto reqreject; 891 else { 892 lcp->his_lqrperiod = ntohl(req->period); 893 if (lcp->his_lqrperiod < MIN_LQRPERIOD * 100) 894 lcp->his_lqrperiod = MIN_LQRPERIOD * 100; 895 req->period = htonl(lcp->his_lqrperiod); 896 memcpy(dec->ackend, cp, length); 897 dec->ackend += length; 898 } 899 break; 900 case MODE_NAK: 901 break; 902 case MODE_REJ: 903 lcp->his_reject |= (1 << type); 904 break; 905 } 906 break; 907 908 case TY_MAGICNUM: 909 ua_ntohl(cp + 2, &magic); 910 log_Printf(LogLCP, "%s 0x%08lx\n", request, (u_long)magic); 911 912 switch (mode_type) { 913 case MODE_REQ: 914 if (lcp->want_magic) { 915 /* Validate magic number */ 916 if (magic == lcp->want_magic) { 917 log_Printf(LogLCP, "Magic is same (%08lx) - %d times\n", 918 (u_long)magic, ++lcp->LcpFailedMagic); 919 lcp->want_magic = GenerateMagic(); 920 memcpy(dec->nakend, cp, 6); 921 dec->nakend += 6; 922 ualarm(TICKUNIT * (4 + 4 * lcp->LcpFailedMagic), 0); 923 sigpause(0); 924 } else { 925 lcp->his_magic = magic; 926 memcpy(dec->ackend, cp, length); 927 dec->ackend += length; 928 lcp->LcpFailedMagic = 0; 929 } 930 } else { 931 goto reqreject; 932 } 933 break; 934 case MODE_NAK: 935 log_Printf(LogLCP, " Magic 0x%08lx is NAKed!\n", (u_long)magic); 936 lcp->want_magic = GenerateMagic(); 937 break; 938 case MODE_REJ: 939 log_Printf(LogLCP, " Magic 0x%08x is REJected!\n", magic); 940 lcp->want_magic = 0; 941 lcp->his_reject |= (1 << type); 942 break; 943 } 944 break; 945 946 case TY_PROTOCOMP: 947 log_Printf(LogLCP, "%s\n", request); 948 949 switch (mode_type) { 950 case MODE_REQ: 951 if (IsAccepted(lcp->cfg.protocomp)) { 952 lcp->his_protocomp = 1; 953 memcpy(dec->ackend, cp, 2); 954 dec->ackend += 2; 955 } else { 956#ifdef OLDMST 957 /* MorningStar before v1.3 needs NAK */ 958 memcpy(dec->nakend, cp, 2); 959 dec->nakend += 2; 960#else 961 goto reqreject; 962#endif 963 } 964 break; 965 case MODE_NAK: 966 case MODE_REJ: 967 lcp->want_protocomp = 0; 968 lcp->his_reject |= (1 << type); 969 break; 970 } 971 break; 972 973 case TY_ACFCOMP: 974 log_Printf(LogLCP, "%s\n", request); 975 switch (mode_type) { 976 case MODE_REQ: 977 if (IsAccepted(lcp->cfg.acfcomp)) { 978 lcp->his_acfcomp = 1; 979 memcpy(dec->ackend, cp, 2); 980 dec->ackend += 2; 981 } else { 982#ifdef OLDMST 983 /* MorningStar before v1.3 needs NAK */ 984 memcpy(dec->nakend, cp, 2); 985 dec->nakend += 2; 986#else 987 goto reqreject; 988#endif 989 } 990 break; 991 case MODE_NAK: 992 case MODE_REJ: 993 lcp->want_acfcomp = 0; 994 lcp->his_reject |= (1 << type); 995 break; 996 } 997 break; 998 999 case TY_SDP: 1000 log_Printf(LogLCP, "%s\n", request); 1001 switch (mode_type) { 1002 case MODE_REQ: 1003 case MODE_NAK: 1004 case MODE_REJ: 1005 break; 1006 } 1007 break; 1008 1009 case TY_CALLBACK: 1010 if (length == 2) 1011 op = CALLBACK_NONE; 1012 else 1013 op = (int)cp[2]; 1014 sz = length - 3; 1015 switch (op) { 1016 case CALLBACK_AUTH: 1017 log_Printf(LogLCP, "%s Auth\n", request); 1018 break; 1019 case CALLBACK_DIALSTRING: 1020 log_Printf(LogLCP, "%s Dialstring %.*s\n", request, sz, cp + 3); 1021 break; 1022 case CALLBACK_LOCATION: 1023 log_Printf(LogLCP, "%s Location %.*s\n", request, sz, cp + 3); 1024 break; 1025 case CALLBACK_E164: 1026 log_Printf(LogLCP, "%s E.164 (%.*s)\n", request, sz, cp + 3); 1027 break; 1028 case CALLBACK_NAME: 1029 log_Printf(LogLCP, "%s Name %.*s\n", request, sz, cp + 3); 1030 break; 1031 case CALLBACK_CBCP: 1032 log_Printf(LogLCP, "%s CBCP\n", request); 1033 break; 1034 default: 1035 log_Printf(LogLCP, "%s ???\n", request); 1036 break; 1037 } 1038 1039 switch (mode_type) { 1040 case MODE_REQ: 1041 callback_req = 1; 1042 if (p->type != PHYS_DIRECT) 1043 goto reqreject; 1044 if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(op)) && 1045 (op != CALLBACK_AUTH || p->link.lcp.auth_ineed) && 1046 (op != CALLBACK_E164 || 1047 E164ok(&p->dl->cfg.callback, cp + 3, sz))) { 1048 lcp->his_callback.opmask = CALLBACK_BIT(op); 1049 if (sz > sizeof lcp->his_callback.msg - 1) { 1050 sz = sizeof lcp->his_callback.msg - 1; 1051 log_Printf(LogWARN, "Truncating option arg to %d octets\n", sz); 1052 } 1053 memcpy(lcp->his_callback.msg, cp + 3, sz); 1054 lcp->his_callback.msg[sz] = '\0'; 1055 memcpy(dec->ackend, cp, sz + 3); 1056 dec->ackend += sz + 3; 1057 } else if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) && 1058 p->link.lcp.auth_ineed) { 1059 *dec->nakend++ = *cp; 1060 *dec->nakend++ = 3; 1061 *dec->nakend++ = CALLBACK_AUTH; 1062 } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) { 1063 *dec->nakend++ = *cp; 1064 *dec->nakend++ = 3; 1065 *dec->nakend++ = CALLBACK_CBCP; 1066 } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_E164)) { 1067 *dec->nakend++ = *cp; 1068 *dec->nakend++ = 3; 1069 *dec->nakend++ = CALLBACK_E164; 1070 } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) { 1071 log_Printf(LogWARN, "Cannot insist on auth callback without" 1072 " PAP or CHAP enabled !\n"); 1073 *dec->nakend++ = *cp; 1074 *dec->nakend++ = 2; 1075 } else 1076 goto reqreject; 1077 break; 1078 case MODE_NAK: 1079 /* We don't do what he NAKs with, we do things in our preferred order */ 1080 if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) 1081 lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_AUTH); 1082 else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) 1083 lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_CBCP); 1084 else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_E164)) 1085 lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_E164); 1086 if (lcp->want_callback.opmask == CALLBACK_BIT(CALLBACK_NONE)) { 1087 log_Printf(LogPHASE, "Peer NAKd all callbacks, trying none\n"); 1088 lcp->want_callback.opmask = 0; 1089 } else if (!lcp->want_callback.opmask) { 1090 log_Printf(LogPHASE, "Peer NAKd last configured callback\n"); 1091 fsm_Close(&lcp->fsm); 1092 } 1093 break; 1094 case MODE_REJ: 1095 if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_NONE)) { 1096 lcp->his_reject |= (1 << type); 1097 lcp->want_callback.opmask = 0; 1098 } else { 1099 log_Printf(LogPHASE, "Peer rejected *required* callback\n"); 1100 fsm_Close(&lcp->fsm); 1101 } 1102 break; 1103 } 1104 break; 1105 1106 case TY_SHORTSEQ: 1107 mp = &lcp->fsm.bundle->ncp.mp; 1108 log_Printf(LogLCP, "%s\n", request); 1109 1110 switch (mode_type) { 1111 case MODE_REQ: 1112 if (lcp->want_mrru && IsAccepted(mp->cfg.shortseq)) { 1113 lcp->his_shortseq = 1; 1114 memcpy(dec->ackend, cp, length); 1115 dec->ackend += length; 1116 } else 1117 goto reqreject; 1118 break; 1119 case MODE_NAK: 1120 /* 1121 * He's trying to get us to ask for short sequence numbers. 1122 * We ignore the NAK and honour our configuration file instead. 1123 */ 1124 break; 1125 case MODE_REJ: 1126 lcp->his_reject |= (1 << type); 1127 lcp->want_shortseq = 0; /* For when we hit MP */ 1128 break; 1129 } 1130 break; 1131 1132 case TY_ENDDISC: 1133 mp = &lcp->fsm.bundle->ncp.mp; 1134 log_Printf(LogLCP, "%s %s\n", request, 1135 mp_Enddisc(cp[2], cp + 3, length - 3)); 1136 switch (mode_type) { 1137 case MODE_REQ: 1138 if (!p) { 1139 log_Printf(LogLCP, " ENDDISC rejected - not a physical link\n"); 1140 goto reqreject; 1141 } else if (!IsAccepted(mp->cfg.negenddisc)) 1142 goto reqreject; 1143 else if (length-3 < sizeof p->dl->peer.enddisc.address && 1144 cp[2] <= MAX_ENDDISC_CLASS) { 1145 p->dl->peer.enddisc.class = cp[2]; 1146 p->dl->peer.enddisc.len = length-3; 1147 memcpy(p->dl->peer.enddisc.address, cp + 3, length - 3); 1148 p->dl->peer.enddisc.address[length - 3] = '\0'; 1149 /* XXX: If mp->active, compare and NAK with mp->peer ? */ 1150 memcpy(dec->ackend, cp, length); 1151 dec->ackend += length; 1152 } else { 1153 if (cp[2] > MAX_ENDDISC_CLASS) 1154 log_Printf(LogLCP, " ENDDISC rejected - unrecognised class %d\n", 1155 cp[2]); 1156 else 1157 log_Printf(LogLCP, " ENDDISC rejected - local max length is %ld\n", 1158 (long)(sizeof p->dl->peer.enddisc.address - 1)); 1159 goto reqreject; 1160 } 1161 break; 1162 1163 case MODE_NAK: /* Treat this as a REJ, we don't vary our disc (yet) */ 1164 case MODE_REJ: 1165 lcp->his_reject |= (1 << type); 1166 break; 1167 } 1168 break; 1169 1170 default: 1171 sz = (sizeof desc - 2) / 2; 1172 if (sz > length - 2) 1173 sz = length - 2; 1174 pos = 0; 1175 desc[0] = sz ? ' ' : '\0'; 1176 for (pos = 0; sz--; pos++) 1177 sprintf(desc+(pos<<1)+1, "%02x", cp[pos+2]); 1178 1179 log_Printf(LogLCP, "%s%s\n", request, desc); 1180 1181 if (mode_type == MODE_REQ) { 1182reqreject: 1183 if (length > sizeof dec->rej - (dec->rejend - dec->rej)) { 1184 length = sizeof dec->rej - (dec->rejend - dec->rej); 1185 log_Printf(LogLCP, "Can't REJ length %d - trunating to %d\n", 1186 cp[1], length); 1187 } 1188 memcpy(dec->rejend, cp, length); 1189 dec->rejend += length; 1190 lcp->my_reject |= (1 << type); 1191 if (length != cp[1]) 1192 length = 0; /* force our way out of the loop */ 1193 } 1194 break; 1195 } 1196 plen -= length; 1197 cp += length; 1198 } 1199 1200 if (mode_type != MODE_NOP) { 1201 if (mode_type == MODE_REQ && p && p->type == PHYS_DIRECT && 1202 p->dl->cfg.callback.opmask && !callback_req && 1203 !(p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_NONE))) { 1204 /* We *REQUIRE* that the peer requests callback */ 1205 *dec->nakend++ = TY_CALLBACK; 1206 *dec->nakend++ = 3; 1207 if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) && 1208 p->link.lcp.auth_ineed) 1209 *dec->nakend++ = CALLBACK_AUTH; 1210 else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) 1211 *dec->nakend++ = CALLBACK_CBCP; 1212 else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_E164)) 1213 *dec->nakend++ = CALLBACK_E164; 1214 else { 1215 log_Printf(LogWARN, "Cannot insist on auth callback without" 1216 " PAP or CHAP enabled !\n"); 1217 dec->nakend[-1] = 2; /* XXX: Silly ! */ 1218 } 1219 }
| 718 lcp->want_mru = MIN_MRU; 719 else 720 lcp->want_mru = mru; 721 break; 722 case MODE_REJ: 723 lcp->his_reject |= (1 << type); 724 break; 725 } 726 break; 727 728 case TY_ACCMAP: 729 ua_ntohl(cp + 2, &accmap); 730 log_Printf(LogLCP, "%s 0x%08lx\n", request, (u_long)accmap); 731 732 switch (mode_type) { 733 case MODE_REQ: 734 lcp->his_accmap = accmap; 735 memcpy(dec->ackend, cp, 6); 736 dec->ackend += 6; 737 break; 738 case MODE_NAK: 739 lcp->want_accmap = accmap; 740 break; 741 case MODE_REJ: 742 lcp->his_reject |= (1 << type); 743 break; 744 } 745 break; 746 747 case TY_AUTHPROTO: 748 ua_ntohs(cp + 2, &proto); 749 log_Printf(LogLCP, "%s 0x%04x (%s)\n", request, proto, 750 Auth2Nam(proto, length > 4 ? cp[4] : 0)); 751 752 switch (mode_type) { 753 case MODE_REQ: 754 switch (proto) { 755 case PROTO_PAP: 756 if (length != 4) { 757 log_Printf(LogLCP, " Bad length!\n"); 758 goto reqreject; 759 } 760 if (IsAccepted(lcp->cfg.pap)) { 761 lcp->his_auth = proto; 762 lcp->his_authtype = 0; 763 memcpy(dec->ackend, cp, length); 764 dec->ackend += length; 765 } else if (IsAccepted(lcp->cfg.chap05)) { 766 *dec->nakend++ = *cp; 767 *dec->nakend++ = 5; 768 *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); 769 *dec->nakend++ = (unsigned char) PROTO_CHAP; 770 *dec->nakend++ = 0x05; 771#ifdef HAVE_DES 772 } else if (IsAccepted(lcp->cfg.chap80nt) || 773 IsAccepted(lcp->cfg.chap80lm)) { 774 *dec->nakend++ = *cp; 775 *dec->nakend++ = 5; 776 *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); 777 *dec->nakend++ = (unsigned char) PROTO_CHAP; 778 *dec->nakend++ = 0x80; 779 } else if (IsAccepted(lcp->cfg.chap81)) { 780 *dec->nakend++ = *cp; 781 *dec->nakend++ = 5; 782 *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); 783 *dec->nakend++ = (unsigned char) PROTO_CHAP; 784 *dec->nakend++ = 0x81; 785#endif 786 } else 787 goto reqreject; 788 break; 789 790 case PROTO_CHAP: 791 if (length != 5) { 792 log_Printf(LogLCP, " Bad length!\n"); 793 goto reqreject; 794 } 795 if ((cp[4] == 0x05 && IsAccepted(lcp->cfg.chap05)) 796#ifdef HAVE_DES 797 || (cp[4] == 0x80 && (IsAccepted(lcp->cfg.chap80nt) || 798 (IsAccepted(lcp->cfg.chap80lm)))) 799 || (cp[4] == 0x81 && IsAccepted(lcp->cfg.chap81)) 800#endif 801 ) { 802 lcp->his_auth = proto; 803 lcp->his_authtype = cp[4]; 804 memcpy(dec->ackend, cp, length); 805 dec->ackend += length; 806 } else { 807#ifndef HAVE_DES 808 if (cp[4] == 0x80) { 809 log_Printf(LogWARN, "CHAP 0x80 not available without DES\n"); 810 } else if (cp[4] == 0x81) { 811 log_Printf(LogWARN, "CHAP 0x81 not available without DES\n"); 812 } else 813#endif 814 if (cp[4] != 0x05) 815 log_Printf(LogWARN, "%s not supported\n", 816 Auth2Nam(PROTO_CHAP, cp[4])); 817 818 if (IsAccepted(lcp->cfg.chap05)) { 819 *dec->nakend++ = *cp; 820 *dec->nakend++ = 5; 821 *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); 822 *dec->nakend++ = (unsigned char) PROTO_CHAP; 823 *dec->nakend++ = 0x05; 824#ifdef HAVE_DES 825 } else if (IsAccepted(lcp->cfg.chap80nt) || 826 IsAccepted(lcp->cfg.chap80lm)) { 827 *dec->nakend++ = *cp; 828 *dec->nakend++ = 5; 829 *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); 830 *dec->nakend++ = (unsigned char) PROTO_CHAP; 831 *dec->nakend++ = 0x80; 832 } else if (IsAccepted(lcp->cfg.chap81)) { 833 *dec->nakend++ = *cp; 834 *dec->nakend++ = 5; 835 *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); 836 *dec->nakend++ = (unsigned char) PROTO_CHAP; 837 *dec->nakend++ = 0x81; 838#endif 839 } else if (IsAccepted(lcp->cfg.pap)) { 840 *dec->nakend++ = *cp; 841 *dec->nakend++ = 4; 842 *dec->nakend++ = (unsigned char) (PROTO_PAP >> 8); 843 *dec->nakend++ = (unsigned char) PROTO_PAP; 844 } else 845 goto reqreject; 846 } 847 break; 848 849 default: 850 log_Printf(LogLCP, "%s 0x%04x - not recognised, NAK\n", 851 request, proto); 852 memcpy(dec->nakend, cp, length); 853 dec->nakend += length; 854 break; 855 } 856 break; 857 case MODE_NAK: 858 switch (proto) { 859 case PROTO_PAP: 860 if (IsEnabled(lcp->cfg.pap)) { 861 lcp->want_auth = PROTO_PAP; 862 lcp->want_authtype = 0; 863 } else { 864 log_Printf(LogLCP, "Peer will only send PAP (not enabled)\n"); 865 lcp->his_reject |= (1 << type); 866 } 867 break; 868 case PROTO_CHAP: 869 if (cp[4] == 0x05 && IsEnabled(lcp->cfg.chap05)) { 870 lcp->want_auth = PROTO_CHAP; 871 lcp->want_authtype = 0x05; 872#ifdef HAVE_DES 873 } else if (cp[4] == 0x80 && (IsEnabled(lcp->cfg.chap80nt) || 874 IsEnabled(lcp->cfg.chap80lm))) { 875 lcp->want_auth = PROTO_CHAP; 876 lcp->want_authtype = 0x80; 877 } else if (cp[4] == 0x81 && IsEnabled(lcp->cfg.chap81)) { 878 lcp->want_auth = PROTO_CHAP; 879 lcp->want_authtype = 0x81; 880#endif 881 } else { 882#ifndef HAVE_DES 883 if (cp[4] == 0x80) { 884 log_Printf(LogLCP, "Peer will only send MSCHAP (not available" 885 " without DES)\n"); 886 } else if (cp[4] == 0x81) { 887 log_Printf(LogLCP, "Peer will only send MSCHAPV2 (not available" 888 " without DES)\n"); 889 } else 890#endif 891 log_Printf(LogLCP, "Peer will only send %s (not %s)\n", 892 Auth2Nam(PROTO_CHAP, cp[4]), 893#ifdef HAVE_DES 894 (cp[4] == 0x80 || cp[4] == 0x81) ? "configured" : 895#endif 896 "supported"); 897 lcp->his_reject |= (1 << type); 898 } 899 break; 900 default: 901 /* We've been NAK'd with something we don't understand :-( */ 902 lcp->his_reject |= (1 << type); 903 break; 904 } 905 break; 906 case MODE_REJ: 907 lcp->his_reject |= (1 << type); 908 break; 909 } 910 break; 911 912 case TY_QUALPROTO: 913 req = (struct lqrreq *)cp; 914 log_Printf(LogLCP, "%s proto %x, interval %lums\n", 915 request, ntohs(req->proto), (u_long)ntohl(req->period) * 10); 916 switch (mode_type) { 917 case MODE_REQ: 918 if (ntohs(req->proto) != PROTO_LQR || !IsAccepted(lcp->cfg.lqr)) 919 goto reqreject; 920 else { 921 lcp->his_lqrperiod = ntohl(req->period); 922 if (lcp->his_lqrperiod < MIN_LQRPERIOD * 100) 923 lcp->his_lqrperiod = MIN_LQRPERIOD * 100; 924 req->period = htonl(lcp->his_lqrperiod); 925 memcpy(dec->ackend, cp, length); 926 dec->ackend += length; 927 } 928 break; 929 case MODE_NAK: 930 break; 931 case MODE_REJ: 932 lcp->his_reject |= (1 << type); 933 break; 934 } 935 break; 936 937 case TY_MAGICNUM: 938 ua_ntohl(cp + 2, &magic); 939 log_Printf(LogLCP, "%s 0x%08lx\n", request, (u_long)magic); 940 941 switch (mode_type) { 942 case MODE_REQ: 943 if (lcp->want_magic) { 944 /* Validate magic number */ 945 if (magic == lcp->want_magic) { 946 log_Printf(LogLCP, "Magic is same (%08lx) - %d times\n", 947 (u_long)magic, ++lcp->LcpFailedMagic); 948 lcp->want_magic = GenerateMagic(); 949 memcpy(dec->nakend, cp, 6); 950 dec->nakend += 6; 951 ualarm(TICKUNIT * (4 + 4 * lcp->LcpFailedMagic), 0); 952 sigpause(0); 953 } else { 954 lcp->his_magic = magic; 955 memcpy(dec->ackend, cp, length); 956 dec->ackend += length; 957 lcp->LcpFailedMagic = 0; 958 } 959 } else { 960 goto reqreject; 961 } 962 break; 963 case MODE_NAK: 964 log_Printf(LogLCP, " Magic 0x%08lx is NAKed!\n", (u_long)magic); 965 lcp->want_magic = GenerateMagic(); 966 break; 967 case MODE_REJ: 968 log_Printf(LogLCP, " Magic 0x%08x is REJected!\n", magic); 969 lcp->want_magic = 0; 970 lcp->his_reject |= (1 << type); 971 break; 972 } 973 break; 974 975 case TY_PROTOCOMP: 976 log_Printf(LogLCP, "%s\n", request); 977 978 switch (mode_type) { 979 case MODE_REQ: 980 if (IsAccepted(lcp->cfg.protocomp)) { 981 lcp->his_protocomp = 1; 982 memcpy(dec->ackend, cp, 2); 983 dec->ackend += 2; 984 } else { 985#ifdef OLDMST 986 /* MorningStar before v1.3 needs NAK */ 987 memcpy(dec->nakend, cp, 2); 988 dec->nakend += 2; 989#else 990 goto reqreject; 991#endif 992 } 993 break; 994 case MODE_NAK: 995 case MODE_REJ: 996 lcp->want_protocomp = 0; 997 lcp->his_reject |= (1 << type); 998 break; 999 } 1000 break; 1001 1002 case TY_ACFCOMP: 1003 log_Printf(LogLCP, "%s\n", request); 1004 switch (mode_type) { 1005 case MODE_REQ: 1006 if (IsAccepted(lcp->cfg.acfcomp)) { 1007 lcp->his_acfcomp = 1; 1008 memcpy(dec->ackend, cp, 2); 1009 dec->ackend += 2; 1010 } else { 1011#ifdef OLDMST 1012 /* MorningStar before v1.3 needs NAK */ 1013 memcpy(dec->nakend, cp, 2); 1014 dec->nakend += 2; 1015#else 1016 goto reqreject; 1017#endif 1018 } 1019 break; 1020 case MODE_NAK: 1021 case MODE_REJ: 1022 lcp->want_acfcomp = 0; 1023 lcp->his_reject |= (1 << type); 1024 break; 1025 } 1026 break; 1027 1028 case TY_SDP: 1029 log_Printf(LogLCP, "%s\n", request); 1030 switch (mode_type) { 1031 case MODE_REQ: 1032 case MODE_NAK: 1033 case MODE_REJ: 1034 break; 1035 } 1036 break; 1037 1038 case TY_CALLBACK: 1039 if (length == 2) 1040 op = CALLBACK_NONE; 1041 else 1042 op = (int)cp[2]; 1043 sz = length - 3; 1044 switch (op) { 1045 case CALLBACK_AUTH: 1046 log_Printf(LogLCP, "%s Auth\n", request); 1047 break; 1048 case CALLBACK_DIALSTRING: 1049 log_Printf(LogLCP, "%s Dialstring %.*s\n", request, sz, cp + 3); 1050 break; 1051 case CALLBACK_LOCATION: 1052 log_Printf(LogLCP, "%s Location %.*s\n", request, sz, cp + 3); 1053 break; 1054 case CALLBACK_E164: 1055 log_Printf(LogLCP, "%s E.164 (%.*s)\n", request, sz, cp + 3); 1056 break; 1057 case CALLBACK_NAME: 1058 log_Printf(LogLCP, "%s Name %.*s\n", request, sz, cp + 3); 1059 break; 1060 case CALLBACK_CBCP: 1061 log_Printf(LogLCP, "%s CBCP\n", request); 1062 break; 1063 default: 1064 log_Printf(LogLCP, "%s ???\n", request); 1065 break; 1066 } 1067 1068 switch (mode_type) { 1069 case MODE_REQ: 1070 callback_req = 1; 1071 if (p->type != PHYS_DIRECT) 1072 goto reqreject; 1073 if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(op)) && 1074 (op != CALLBACK_AUTH || p->link.lcp.auth_ineed) && 1075 (op != CALLBACK_E164 || 1076 E164ok(&p->dl->cfg.callback, cp + 3, sz))) { 1077 lcp->his_callback.opmask = CALLBACK_BIT(op); 1078 if (sz > sizeof lcp->his_callback.msg - 1) { 1079 sz = sizeof lcp->his_callback.msg - 1; 1080 log_Printf(LogWARN, "Truncating option arg to %d octets\n", sz); 1081 } 1082 memcpy(lcp->his_callback.msg, cp + 3, sz); 1083 lcp->his_callback.msg[sz] = '\0'; 1084 memcpy(dec->ackend, cp, sz + 3); 1085 dec->ackend += sz + 3; 1086 } else if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) && 1087 p->link.lcp.auth_ineed) { 1088 *dec->nakend++ = *cp; 1089 *dec->nakend++ = 3; 1090 *dec->nakend++ = CALLBACK_AUTH; 1091 } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) { 1092 *dec->nakend++ = *cp; 1093 *dec->nakend++ = 3; 1094 *dec->nakend++ = CALLBACK_CBCP; 1095 } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_E164)) { 1096 *dec->nakend++ = *cp; 1097 *dec->nakend++ = 3; 1098 *dec->nakend++ = CALLBACK_E164; 1099 } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) { 1100 log_Printf(LogWARN, "Cannot insist on auth callback without" 1101 " PAP or CHAP enabled !\n"); 1102 *dec->nakend++ = *cp; 1103 *dec->nakend++ = 2; 1104 } else 1105 goto reqreject; 1106 break; 1107 case MODE_NAK: 1108 /* We don't do what he NAKs with, we do things in our preferred order */ 1109 if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) 1110 lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_AUTH); 1111 else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) 1112 lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_CBCP); 1113 else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_E164)) 1114 lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_E164); 1115 if (lcp->want_callback.opmask == CALLBACK_BIT(CALLBACK_NONE)) { 1116 log_Printf(LogPHASE, "Peer NAKd all callbacks, trying none\n"); 1117 lcp->want_callback.opmask = 0; 1118 } else if (!lcp->want_callback.opmask) { 1119 log_Printf(LogPHASE, "Peer NAKd last configured callback\n"); 1120 fsm_Close(&lcp->fsm); 1121 } 1122 break; 1123 case MODE_REJ: 1124 if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_NONE)) { 1125 lcp->his_reject |= (1 << type); 1126 lcp->want_callback.opmask = 0; 1127 } else { 1128 log_Printf(LogPHASE, "Peer rejected *required* callback\n"); 1129 fsm_Close(&lcp->fsm); 1130 } 1131 break; 1132 } 1133 break; 1134 1135 case TY_SHORTSEQ: 1136 mp = &lcp->fsm.bundle->ncp.mp; 1137 log_Printf(LogLCP, "%s\n", request); 1138 1139 switch (mode_type) { 1140 case MODE_REQ: 1141 if (lcp->want_mrru && IsAccepted(mp->cfg.shortseq)) { 1142 lcp->his_shortseq = 1; 1143 memcpy(dec->ackend, cp, length); 1144 dec->ackend += length; 1145 } else 1146 goto reqreject; 1147 break; 1148 case MODE_NAK: 1149 /* 1150 * He's trying to get us to ask for short sequence numbers. 1151 * We ignore the NAK and honour our configuration file instead. 1152 */ 1153 break; 1154 case MODE_REJ: 1155 lcp->his_reject |= (1 << type); 1156 lcp->want_shortseq = 0; /* For when we hit MP */ 1157 break; 1158 } 1159 break; 1160 1161 case TY_ENDDISC: 1162 mp = &lcp->fsm.bundle->ncp.mp; 1163 log_Printf(LogLCP, "%s %s\n", request, 1164 mp_Enddisc(cp[2], cp + 3, length - 3)); 1165 switch (mode_type) { 1166 case MODE_REQ: 1167 if (!p) { 1168 log_Printf(LogLCP, " ENDDISC rejected - not a physical link\n"); 1169 goto reqreject; 1170 } else if (!IsAccepted(mp->cfg.negenddisc)) 1171 goto reqreject; 1172 else if (length-3 < sizeof p->dl->peer.enddisc.address && 1173 cp[2] <= MAX_ENDDISC_CLASS) { 1174 p->dl->peer.enddisc.class = cp[2]; 1175 p->dl->peer.enddisc.len = length-3; 1176 memcpy(p->dl->peer.enddisc.address, cp + 3, length - 3); 1177 p->dl->peer.enddisc.address[length - 3] = '\0'; 1178 /* XXX: If mp->active, compare and NAK with mp->peer ? */ 1179 memcpy(dec->ackend, cp, length); 1180 dec->ackend += length; 1181 } else { 1182 if (cp[2] > MAX_ENDDISC_CLASS) 1183 log_Printf(LogLCP, " ENDDISC rejected - unrecognised class %d\n", 1184 cp[2]); 1185 else 1186 log_Printf(LogLCP, " ENDDISC rejected - local max length is %ld\n", 1187 (long)(sizeof p->dl->peer.enddisc.address - 1)); 1188 goto reqreject; 1189 } 1190 break; 1191 1192 case MODE_NAK: /* Treat this as a REJ, we don't vary our disc (yet) */ 1193 case MODE_REJ: 1194 lcp->his_reject |= (1 << type); 1195 break; 1196 } 1197 break; 1198 1199 default: 1200 sz = (sizeof desc - 2) / 2; 1201 if (sz > length - 2) 1202 sz = length - 2; 1203 pos = 0; 1204 desc[0] = sz ? ' ' : '\0'; 1205 for (pos = 0; sz--; pos++) 1206 sprintf(desc+(pos<<1)+1, "%02x", cp[pos+2]); 1207 1208 log_Printf(LogLCP, "%s%s\n", request, desc); 1209 1210 if (mode_type == MODE_REQ) { 1211reqreject: 1212 if (length > sizeof dec->rej - (dec->rejend - dec->rej)) { 1213 length = sizeof dec->rej - (dec->rejend - dec->rej); 1214 log_Printf(LogLCP, "Can't REJ length %d - trunating to %d\n", 1215 cp[1], length); 1216 } 1217 memcpy(dec->rejend, cp, length); 1218 dec->rejend += length; 1219 lcp->my_reject |= (1 << type); 1220 if (length != cp[1]) 1221 length = 0; /* force our way out of the loop */ 1222 } 1223 break; 1224 } 1225 plen -= length; 1226 cp += length; 1227 } 1228 1229 if (mode_type != MODE_NOP) { 1230 if (mode_type == MODE_REQ && p && p->type == PHYS_DIRECT && 1231 p->dl->cfg.callback.opmask && !callback_req && 1232 !(p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_NONE))) { 1233 /* We *REQUIRE* that the peer requests callback */ 1234 *dec->nakend++ = TY_CALLBACK; 1235 *dec->nakend++ = 3; 1236 if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) && 1237 p->link.lcp.auth_ineed) 1238 *dec->nakend++ = CALLBACK_AUTH; 1239 else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) 1240 *dec->nakend++ = CALLBACK_CBCP; 1241 else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_E164)) 1242 *dec->nakend++ = CALLBACK_E164; 1243 else { 1244 log_Printf(LogWARN, "Cannot insist on auth callback without" 1245 " PAP or CHAP enabled !\n"); 1246 dec->nakend[-1] = 2; /* XXX: Silly ! */ 1247 } 1248 }
|
| 1249 if (mode_type == MODE_REQ && !mru_req) { 1250 mru = DEF_MRU; 1251 phmtu = p ? physical_DeviceMTU(p) : 0; 1252 if (phmtu && mru > phmtu) 1253 mru = phmtu; 1254 if (mru > lcp->cfg.max_mtu) 1255 mru = lcp->cfg.max_mtu; 1256 if (mru < DEF_MRU) { 1257 /* Don't let the peer use the default MRU */ 1258 lcp->his_mru = lcp->cfg.mtu && lcp->cfg.mtu < mru ? lcp->cfg.mtu : mru; 1259 *dec->nakend++ = TY_MRU; 1260 *dec->nakend++ = 4; 1261 ua_htons(&lcp->his_mru, dec->nakend); 1262 dec->nakend += 2; 1263 } 1264 }
|
1220 if (dec->rejend != dec->rej) { 1221 /* rejects are preferred */ 1222 dec->ackend = dec->ack; 1223 dec->nakend = dec->nak; 1224 } else if (dec->nakend != dec->nak) 1225 /* then NAKs */ 1226 dec->ackend = dec->ack; 1227 } 1228} 1229 1230extern struct mbuf * 1231lcp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) 1232{ 1233 /* Got PROTO_LCP from link */ 1234 m_settype(bp, MB_LCPIN); 1235 fsm_Input(&l->lcp.fsm, bp); 1236 return NULL; 1237}
| 1265 if (dec->rejend != dec->rej) { 1266 /* rejects are preferred */ 1267 dec->ackend = dec->ack; 1268 dec->nakend = dec->nak; 1269 } else if (dec->nakend != dec->nak) 1270 /* then NAKs */ 1271 dec->ackend = dec->ack; 1272 } 1273} 1274 1275extern struct mbuf * 1276lcp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) 1277{ 1278 /* Got PROTO_LCP from link */ 1279 m_settype(bp, MB_LCPIN); 1280 fsm_Input(&l->lcp.fsm, bp); 1281 return NULL; 1282}
|