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