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