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