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