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