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