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