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