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