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