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