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