1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org> 5 * based on work by Toshiharu OHNO <tony-o@iij.ad.jp> 6 * Internet Initiative Japan, Inc (IIJ) 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * $FreeBSD$ 31 */ 32 33 #include <sys/param.h> 34 #include <netinet/in.h> 35 #include <netinet/in_systm.h> 36 #include <netinet/ip.h> 37 #include <sys/socket.h> 38 #include <sys/un.h> 39 40 #include <string.h> 41 #include <termios.h> 42 43 #include "layer.h" 44 #include "ua.h" 45 #include "mbuf.h" 46 #include "log.h" 47 #include "defs.h" 48 #include "timer.h" 49 #include "fsm.h" 50 #include "iplist.h" 51 #include "lqr.h" 52 #include "hdlc.h" 53 #include "throughput.h" 54 #include "slcompress.h" 55 #include "ncpaddr.h" 56 #include "ipcp.h" 57 #include "filter.h" 58 #include "descriptor.h" 59 #include "lcp.h" 60 #include "ccp.h" 61 #include "link.h" 62 #include "mp.h" 63 #ifndef NORADIUS 64 #include "radius.h" 65 #endif 66 #include "ipv6cp.h" 67 #include "ncp.h" 68 #include "bundle.h" 69 #include "async.h" 70 #include "physical.h" 71 #include "proto.h" 72 73 static void FsmSendConfigReq(struct fsm *); 74 static void FsmSendTerminateReq(struct fsm *); 75 static void FsmInitRestartCounter(struct fsm *, int); 76 77 typedef void (recvfn)(struct fsm *, struct fsmheader *, struct mbuf *); 78 static recvfn FsmRecvConfigReq, FsmRecvConfigAck, FsmRecvConfigNak, 79 FsmRecvConfigRej, FsmRecvTermReq, FsmRecvTermAck, 80 FsmRecvCodeRej, FsmRecvProtoRej, FsmRecvEchoReq, 81 FsmRecvEchoRep, FsmRecvDiscReq, FsmRecvIdent, 82 FsmRecvTimeRemain, FsmRecvResetReq, FsmRecvResetAck; 83 84 static const struct fsmcodedesc { 85 recvfn *recv; 86 unsigned check_reqid : 1; 87 unsigned inc_reqid : 1; 88 const char *name; 89 } FsmCodes[] = { 90 { FsmRecvConfigReq, 0, 0, "ConfigReq" }, 91 { FsmRecvConfigAck, 1, 1, "ConfigAck" }, 92 { FsmRecvConfigNak, 1, 1, "ConfigNak" }, 93 { FsmRecvConfigRej, 1, 1, "ConfigRej" }, 94 { FsmRecvTermReq, 0, 0, "TerminateReq" }, 95 { FsmRecvTermAck, 1, 1, "TerminateAck" }, 96 { FsmRecvCodeRej, 0, 0, "CodeRej" }, 97 { FsmRecvProtoRej, 0, 0, "ProtocolRej" }, 98 { FsmRecvEchoReq, 0, 0, "EchoRequest" }, 99 { FsmRecvEchoRep, 0, 0, "EchoReply" }, 100 { FsmRecvDiscReq, 0, 0, "DiscardReq" }, 101 { FsmRecvIdent, 0, 1, "Ident" }, 102 { FsmRecvTimeRemain,0, 0, "TimeRemain" }, 103 { FsmRecvResetReq, 0, 0, "ResetReq" }, 104 { FsmRecvResetAck, 0, 1, "ResetAck" } 105 }; 106 107 static const char * 108 Code2Nam(u_int code) 109 { 110 if (code == 0 || code > sizeof FsmCodes / sizeof FsmCodes[0]) 111 return "Unknown"; 112 return FsmCodes[code-1].name; 113 } 114 115 const char * 116 State2Nam(u_int state) 117 { 118 static const char * const StateNames[] = { 119 "Initial", "Starting", "Closed", "Stopped", "Closing", "Stopping", 120 "Req-Sent", "Ack-Rcvd", "Ack-Sent", "Opened", 121 }; 122 123 if (state >= sizeof StateNames / sizeof StateNames[0]) 124 return "unknown"; 125 return StateNames[state]; 126 } 127 128 static void 129 StoppedTimeout(void *v) 130 { 131 struct fsm *fp = (struct fsm *)v; 132 133 log_Printf(fp->LogLevel, "%s: Stopped timer expired\n", fp->link->name); 134 if (fp->OpenTimer.state == TIMER_RUNNING) { 135 log_Printf(LogWARN, "%s: %s: aborting open delay due to stopped timer\n", 136 fp->link->name, fp->name); 137 timer_Stop(&fp->OpenTimer); 138 } 139 if (fp->state == ST_STOPPED) 140 fsm2initial(fp); 141 } 142 143 void 144 fsm_Init(struct fsm *fp, const char *name, u_short proto, int mincode, 145 int maxcode, int LogLevel, struct bundle *bundle, 146 struct link *l, const struct fsm_parent *parent, 147 struct fsm_callbacks *fn, const char * const timer_names[3]) 148 { 149 fp->name = name; 150 fp->proto = proto; 151 fp->min_code = mincode; 152 fp->max_code = maxcode; 153 fp->state = fp->min_code > CODE_TERMACK ? ST_OPENED : ST_INITIAL; 154 fp->reqid = 1; 155 fp->restart = 1; 156 fp->more.reqs = fp->more.naks = fp->more.rejs = 3; 157 memset(&fp->FsmTimer, '\0', sizeof fp->FsmTimer); 158 memset(&fp->OpenTimer, '\0', sizeof fp->OpenTimer); 159 memset(&fp->StoppedTimer, '\0', sizeof fp->StoppedTimer); 160 fp->LogLevel = LogLevel; 161 fp->link = l; 162 fp->bundle = bundle; 163 fp->parent = parent; 164 fp->fn = fn; 165 fp->FsmTimer.name = timer_names[0]; 166 fp->OpenTimer.name = timer_names[1]; 167 fp->StoppedTimer.name = timer_names[2]; 168 } 169 170 static void 171 NewState(struct fsm *fp, int new) 172 { 173 log_Printf(fp->LogLevel, "%s: State change %s --> %s\n", 174 fp->link->name, State2Nam(fp->state), State2Nam(new)); 175 if (fp->state == ST_STOPPED && fp->StoppedTimer.state == TIMER_RUNNING) 176 timer_Stop(&fp->StoppedTimer); 177 fp->state = new; 178 if ((new >= ST_INITIAL && new <= ST_STOPPED) || (new == ST_OPENED)) { 179 timer_Stop(&fp->FsmTimer); 180 if (new == ST_STOPPED && fp->StoppedTimer.load) { 181 timer_Stop(&fp->StoppedTimer); 182 fp->StoppedTimer.func = StoppedTimeout; 183 fp->StoppedTimer.arg = (void *) fp; 184 timer_Start(&fp->StoppedTimer); 185 } 186 } 187 } 188 189 void 190 fsm_Output(struct fsm *fp, u_int code, u_int id, u_char *ptr, unsigned count, 191 int mtype) 192 { 193 int plen; 194 struct fsmheader lh; 195 struct mbuf *bp; 196 197 if (log_IsKept(fp->LogLevel)) { 198 log_Printf(fp->LogLevel, "%s: Send%s(%d) state = %s\n", 199 fp->link->name, Code2Nam(code), id, State2Nam(fp->state)); 200 switch (code) { 201 case CODE_CONFIGREQ: 202 case CODE_CONFIGACK: 203 case CODE_CONFIGREJ: 204 case CODE_CONFIGNAK: 205 (*fp->fn->DecodeConfig)(fp, ptr, ptr + count, MODE_NOP, NULL); 206 if (count < sizeof(struct fsm_opt_hdr)) 207 log_Printf(fp->LogLevel, " [EMPTY]\n"); 208 break; 209 } 210 } 211 212 plen = sizeof(struct fsmheader) + count; 213 lh.code = code; 214 lh.id = id; 215 lh.length = htons(plen); 216 bp = m_get(plen, mtype); 217 memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader)); 218 if (count) 219 memcpy(MBUF_CTOP(bp) + sizeof(struct fsmheader), ptr, count); 220 log_DumpBp(LogDEBUG, "fsm_Output", bp); 221 link_PushPacket(fp->link, bp, fp->bundle, LINK_QUEUES(fp->link) - 1, 222 fp->proto); 223 224 if (code == CODE_CONFIGREJ) 225 lcp_SendIdentification(&fp->link->lcp); 226 } 227 228 static void 229 FsmOpenNow(void *v) 230 { 231 struct fsm *fp = (struct fsm *)v; 232 233 timer_Stop(&fp->OpenTimer); 234 if (fp->state <= ST_STOPPED) { 235 if (fp->state != ST_STARTING) { 236 /* 237 * In practice, we're only here in ST_STOPPED (when delaying the 238 * first config request) or ST_CLOSED (when openmode == 0). 239 * 240 * The ST_STOPPED bit is breaking the RFC already :-( 241 * 242 * According to the RFC (1661) state transition table, a TLS isn't 243 * required for an Open event when state == Closed, but the RFC 244 * must be wrong as TLS hasn't yet been called (since the last TLF) 245 * ie, Initial gets an `Up' event, Closing gets a RTA etc. 246 */ 247 (*fp->fn->LayerStart)(fp); 248 (*fp->parent->LayerStart)(fp->parent->object, fp); 249 } 250 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 251 FsmSendConfigReq(fp); 252 NewState(fp, ST_REQSENT); 253 } 254 } 255 256 void 257 fsm_Open(struct fsm *fp) 258 { 259 switch (fp->state) { 260 case ST_INITIAL: 261 NewState(fp, ST_STARTING); 262 (*fp->fn->LayerStart)(fp); 263 (*fp->parent->LayerStart)(fp->parent->object, fp); 264 break; 265 case ST_CLOSED: 266 if (fp->open_mode == OPEN_PASSIVE) { 267 NewState(fp, ST_STOPPED); /* XXX: This is a hack ! */ 268 } else if (fp->open_mode > 0) { 269 if (fp->open_mode > 1) 270 log_Printf(LogPHASE, "%s: Entering STOPPED state for %d seconds\n", 271 fp->link->name, fp->open_mode); 272 NewState(fp, ST_STOPPED); /* XXX: This is a not-so-bad hack ! */ 273 timer_Stop(&fp->OpenTimer); 274 fp->OpenTimer.load = fp->open_mode * SECTICKS; 275 fp->OpenTimer.func = FsmOpenNow; 276 fp->OpenTimer.arg = (void *)fp; 277 timer_Start(&fp->OpenTimer); 278 } else 279 FsmOpenNow(fp); 280 break; 281 case ST_STOPPED: /* XXX: restart option */ 282 case ST_REQSENT: 283 case ST_ACKRCVD: 284 case ST_ACKSENT: 285 case ST_OPENED: /* XXX: restart option */ 286 break; 287 case ST_CLOSING: /* XXX: restart option */ 288 case ST_STOPPING: /* XXX: restart option */ 289 NewState(fp, ST_STOPPING); 290 break; 291 } 292 } 293 294 void 295 fsm_Up(struct fsm *fp) 296 { 297 switch (fp->state) { 298 case ST_INITIAL: 299 log_Printf(fp->LogLevel, "FSM: Using \"%s\" as a transport\n", 300 fp->link->name); 301 NewState(fp, ST_CLOSED); 302 break; 303 case ST_STARTING: 304 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 305 FsmSendConfigReq(fp); 306 NewState(fp, ST_REQSENT); 307 break; 308 default: 309 log_Printf(fp->LogLevel, "%s: Oops, Up at %s\n", 310 fp->link->name, State2Nam(fp->state)); 311 break; 312 } 313 } 314 315 void 316 fsm_Down(struct fsm *fp) 317 { 318 switch (fp->state) { 319 case ST_CLOSED: 320 NewState(fp, ST_INITIAL); 321 break; 322 case ST_CLOSING: 323 /* This TLF contradicts the RFC (1661), which ``misses it out'' ! */ 324 (*fp->fn->LayerFinish)(fp); 325 NewState(fp, ST_INITIAL); 326 (*fp->parent->LayerFinish)(fp->parent->object, fp); 327 break; 328 case ST_STOPPED: 329 NewState(fp, ST_STARTING); 330 (*fp->fn->LayerStart)(fp); 331 (*fp->parent->LayerStart)(fp->parent->object, fp); 332 break; 333 case ST_STOPPING: 334 case ST_REQSENT: 335 case ST_ACKRCVD: 336 case ST_ACKSENT: 337 NewState(fp, ST_STARTING); 338 break; 339 case ST_OPENED: 340 (*fp->fn->LayerDown)(fp); 341 NewState(fp, ST_STARTING); 342 (*fp->parent->LayerDown)(fp->parent->object, fp); 343 break; 344 } 345 } 346 347 void 348 fsm_Close(struct fsm *fp) 349 { 350 switch (fp->state) { 351 case ST_STARTING: 352 (*fp->fn->LayerFinish)(fp); 353 NewState(fp, ST_INITIAL); 354 (*fp->parent->LayerFinish)(fp->parent->object, fp); 355 break; 356 case ST_STOPPED: 357 NewState(fp, ST_CLOSED); 358 break; 359 case ST_STOPPING: 360 NewState(fp, ST_CLOSING); 361 break; 362 case ST_OPENED: 363 (*fp->fn->LayerDown)(fp); 364 if (fp->state == ST_OPENED) { 365 FsmInitRestartCounter(fp, FSM_TRM_TIMER); 366 FsmSendTerminateReq(fp); 367 NewState(fp, ST_CLOSING); 368 (*fp->parent->LayerDown)(fp->parent->object, fp); 369 } 370 break; 371 case ST_REQSENT: 372 case ST_ACKRCVD: 373 case ST_ACKSENT: 374 FsmInitRestartCounter(fp, FSM_TRM_TIMER); 375 FsmSendTerminateReq(fp); 376 NewState(fp, ST_CLOSING); 377 break; 378 } 379 } 380 381 /* 382 * Send functions 383 */ 384 static void 385 FsmSendConfigReq(struct fsm *fp) 386 { 387 if (fp->more.reqs-- > 0 && fp->restart-- > 0) { 388 (*fp->fn->SendConfigReq)(fp); 389 timer_Start(&fp->FsmTimer); /* Start restart timer */ 390 } else { 391 if (fp->more.reqs < 0) 392 log_Printf(LogPHASE, "%s: Too many %s REQs sent - abandoning " 393 "negotiation\n", fp->link->name, fp->name); 394 lcp_SendIdentification(&fp->link->lcp); 395 fsm_Close(fp); 396 } 397 } 398 399 static void 400 FsmSendTerminateReq(struct fsm *fp) 401 { 402 fsm_Output(fp, CODE_TERMREQ, fp->reqid, NULL, 0, MB_UNKNOWN); 403 (*fp->fn->SentTerminateReq)(fp); 404 timer_Start(&fp->FsmTimer); /* Start restart timer */ 405 fp->restart--; /* Decrement restart counter */ 406 } 407 408 /* 409 * Timeout actions 410 */ 411 static void 412 FsmTimeout(void *v) 413 { 414 struct fsm *fp = (struct fsm *)v; 415 416 if (fp->restart) { 417 switch (fp->state) { 418 case ST_CLOSING: 419 case ST_STOPPING: 420 FsmSendTerminateReq(fp); 421 break; 422 case ST_REQSENT: 423 case ST_ACKSENT: 424 FsmSendConfigReq(fp); 425 break; 426 case ST_ACKRCVD: 427 FsmSendConfigReq(fp); 428 NewState(fp, ST_REQSENT); 429 break; 430 } 431 timer_Start(&fp->FsmTimer); 432 } else { 433 switch (fp->state) { 434 case ST_CLOSING: 435 (*fp->fn->LayerFinish)(fp); 436 NewState(fp, ST_CLOSED); 437 (*fp->parent->LayerFinish)(fp->parent->object, fp); 438 break; 439 case ST_STOPPING: 440 (*fp->fn->LayerFinish)(fp); 441 NewState(fp, ST_STOPPED); 442 (*fp->parent->LayerFinish)(fp->parent->object, fp); 443 break; 444 case ST_REQSENT: /* XXX: 3p */ 445 case ST_ACKSENT: 446 case ST_ACKRCVD: 447 (*fp->fn->LayerFinish)(fp); 448 NewState(fp, ST_STOPPED); 449 (*fp->parent->LayerFinish)(fp->parent->object, fp); 450 break; 451 } 452 } 453 } 454 455 static void 456 FsmInitRestartCounter(struct fsm *fp, int what) 457 { 458 timer_Stop(&fp->FsmTimer); 459 fp->FsmTimer.func = FsmTimeout; 460 fp->FsmTimer.arg = (void *)fp; 461 (*fp->fn->InitRestartCounter)(fp, what); 462 } 463 464 /* 465 * Actions when receive packets 466 */ 467 static void 468 FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 469 /* RCR */ 470 { 471 struct fsm_decode dec; 472 int plen, flen; 473 int ackaction = 0; 474 u_char *cp; 475 476 bp = m_pullup(bp); 477 plen = m_length(bp); 478 flen = ntohs(lhp->length) - sizeof *lhp; 479 if (plen < flen) { 480 log_Printf(LogWARN, "%s: FsmRecvConfigReq: plen (%d) < flen (%d)\n", 481 fp->link->name, plen, flen); 482 m_freem(bp); 483 return; 484 } 485 486 /* Some things must be done before we Decode the packet */ 487 switch (fp->state) { 488 case ST_OPENED: 489 (*fp->fn->LayerDown)(fp); 490 } 491 492 dec.ackend = dec.ack; 493 dec.nakend = dec.nak; 494 dec.rejend = dec.rej; 495 cp = MBUF_CTOP(bp); 496 (*fp->fn->DecodeConfig)(fp, cp, cp + flen, MODE_REQ, &dec); 497 if (flen < (int)sizeof(struct fsm_opt_hdr)) 498 log_Printf(fp->LogLevel, " [EMPTY]\n"); 499 500 if (dec.nakend == dec.nak && dec.rejend == dec.rej) 501 ackaction = 1; 502 503 /* Check and process easy case */ 504 switch (fp->state) { 505 case ST_INITIAL: 506 if (fp->proto == PROTO_CCP && fp->link->lcp.fsm.state == ST_OPENED) { 507 /* 508 * ccp_SetOpenMode() leaves us in initial if we're disabling 509 * & denying everything. 510 */ 511 bp = m_prepend(bp, lhp, sizeof *lhp, 2); 512 bp = proto_Prepend(bp, fp->proto, 0, 0); 513 bp = m_pullup(bp); 514 lcp_SendProtoRej(&fp->link->lcp, MBUF_CTOP(bp), bp->m_len); 515 m_freem(bp); 516 return; 517 } 518 /* Drop through */ 519 case ST_STARTING: 520 log_Printf(fp->LogLevel, "%s: Oops, RCR in %s.\n", 521 fp->link->name, State2Nam(fp->state)); 522 m_freem(bp); 523 return; 524 case ST_CLOSED: 525 (*fp->fn->SendTerminateAck)(fp, lhp->id); 526 m_freem(bp); 527 return; 528 case ST_CLOSING: 529 log_Printf(fp->LogLevel, "%s: Error: Got ConfigReq while state = %s\n", 530 fp->link->name, State2Nam(fp->state)); 531 case ST_STOPPING: 532 m_freem(bp); 533 return; 534 case ST_STOPPED: 535 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 536 /* Drop through */ 537 case ST_OPENED: 538 FsmSendConfigReq(fp); 539 break; 540 } 541 542 if (dec.rejend != dec.rej) 543 fsm_Output(fp, CODE_CONFIGREJ, lhp->id, dec.rej, dec.rejend - dec.rej, 544 MB_UNKNOWN); 545 if (dec.nakend != dec.nak) 546 fsm_Output(fp, CODE_CONFIGNAK, lhp->id, dec.nak, dec.nakend - dec.nak, 547 MB_UNKNOWN); 548 if (ackaction) 549 fsm_Output(fp, CODE_CONFIGACK, lhp->id, dec.ack, dec.ackend - dec.ack, 550 MB_UNKNOWN); 551 552 switch (fp->state) { 553 case ST_STOPPED: 554 /* 555 * According to the RFC (1661) state transition table, a TLS isn't 556 * required for a RCR when state == ST_STOPPED, but the RFC 557 * must be wrong as TLS hasn't yet been called (since the last TLF) 558 */ 559 (*fp->fn->LayerStart)(fp); 560 (*fp->parent->LayerStart)(fp->parent->object, fp); 561 /* FALLTHROUGH */ 562 563 case ST_OPENED: 564 if (ackaction) 565 NewState(fp, ST_ACKSENT); 566 else 567 NewState(fp, ST_REQSENT); 568 (*fp->parent->LayerDown)(fp->parent->object, fp); 569 break; 570 case ST_REQSENT: 571 if (ackaction) 572 NewState(fp, ST_ACKSENT); 573 break; 574 case ST_ACKRCVD: 575 if (ackaction) { 576 NewState(fp, ST_OPENED); 577 if ((*fp->fn->LayerUp)(fp)) 578 (*fp->parent->LayerUp)(fp->parent->object, fp); 579 else { 580 (*fp->fn->LayerDown)(fp); 581 FsmInitRestartCounter(fp, FSM_TRM_TIMER); 582 FsmSendTerminateReq(fp); 583 NewState(fp, ST_CLOSING); 584 lcp_SendIdentification(&fp->link->lcp); 585 } 586 } 587 break; 588 case ST_ACKSENT: 589 if (!ackaction) 590 NewState(fp, ST_REQSENT); 591 break; 592 } 593 m_freem(bp); 594 595 if (dec.rejend != dec.rej && --fp->more.rejs <= 0) { 596 log_Printf(LogPHASE, "%s: Too many %s REJs sent - abandoning negotiation\n", 597 fp->link->name, fp->name); 598 lcp_SendIdentification(&fp->link->lcp); 599 fsm_Close(fp); 600 } 601 602 if (dec.nakend != dec.nak && --fp->more.naks <= 0) { 603 log_Printf(LogPHASE, "%s: Too many %s NAKs sent - abandoning negotiation\n", 604 fp->link->name, fp->name); 605 lcp_SendIdentification(&fp->link->lcp); 606 fsm_Close(fp); 607 } 608 } 609 610 static void 611 FsmRecvConfigAck(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 612 /* RCA */ 613 { 614 struct fsm_decode dec; 615 int plen, flen; 616 u_char *cp; 617 618 plen = m_length(bp); 619 flen = ntohs(lhp->length) - sizeof *lhp; 620 if (plen < flen) { 621 m_freem(bp); 622 return; 623 } 624 625 bp = m_pullup(bp); 626 dec.ackend = dec.ack; 627 dec.nakend = dec.nak; 628 dec.rejend = dec.rej; 629 cp = MBUF_CTOP(bp); 630 (*fp->fn->DecodeConfig)(fp, cp, cp + flen, MODE_ACK, &dec); 631 if (flen < (int)sizeof(struct fsm_opt_hdr)) 632 log_Printf(fp->LogLevel, " [EMPTY]\n"); 633 634 switch (fp->state) { 635 case ST_CLOSED: 636 case ST_STOPPED: 637 (*fp->fn->SendTerminateAck)(fp, lhp->id); 638 break; 639 case ST_CLOSING: 640 case ST_STOPPING: 641 break; 642 case ST_REQSENT: 643 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 644 NewState(fp, ST_ACKRCVD); 645 break; 646 case ST_ACKRCVD: 647 FsmSendConfigReq(fp); 648 NewState(fp, ST_REQSENT); 649 break; 650 case ST_ACKSENT: 651 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 652 NewState(fp, ST_OPENED); 653 if ((*fp->fn->LayerUp)(fp)) 654 (*fp->parent->LayerUp)(fp->parent->object, fp); 655 else { 656 (*fp->fn->LayerDown)(fp); 657 FsmInitRestartCounter(fp, FSM_TRM_TIMER); 658 FsmSendTerminateReq(fp); 659 NewState(fp, ST_CLOSING); 660 lcp_SendIdentification(&fp->link->lcp); 661 } 662 break; 663 case ST_OPENED: 664 (*fp->fn->LayerDown)(fp); 665 FsmSendConfigReq(fp); 666 NewState(fp, ST_REQSENT); 667 (*fp->parent->LayerDown)(fp->parent->object, fp); 668 break; 669 } 670 m_freem(bp); 671 } 672 673 static void 674 FsmRecvConfigNak(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 675 /* RCN */ 676 { 677 struct fsm_decode dec; 678 int plen, flen; 679 u_char *cp; 680 681 plen = m_length(bp); 682 flen = ntohs(lhp->length) - sizeof *lhp; 683 if (plen < flen) { 684 m_freem(bp); 685 return; 686 } 687 688 /* 689 * Check and process easy case 690 */ 691 switch (fp->state) { 692 case ST_INITIAL: 693 case ST_STARTING: 694 log_Printf(fp->LogLevel, "%s: Oops, RCN in %s.\n", 695 fp->link->name, State2Nam(fp->state)); 696 m_freem(bp); 697 return; 698 case ST_CLOSED: 699 case ST_STOPPED: 700 (*fp->fn->SendTerminateAck)(fp, lhp->id); 701 m_freem(bp); 702 return; 703 case ST_CLOSING: 704 case ST_STOPPING: 705 m_freem(bp); 706 return; 707 } 708 709 bp = m_pullup(bp); 710 dec.ackend = dec.ack; 711 dec.nakend = dec.nak; 712 dec.rejend = dec.rej; 713 cp = MBUF_CTOP(bp); 714 (*fp->fn->DecodeConfig)(fp, cp, cp + flen, MODE_NAK, &dec); 715 if (flen < (int)sizeof(struct fsm_opt_hdr)) 716 log_Printf(fp->LogLevel, " [EMPTY]\n"); 717 718 switch (fp->state) { 719 case ST_REQSENT: 720 case ST_ACKSENT: 721 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 722 FsmSendConfigReq(fp); 723 break; 724 case ST_OPENED: 725 (*fp->fn->LayerDown)(fp); 726 FsmSendConfigReq(fp); 727 NewState(fp, ST_REQSENT); 728 (*fp->parent->LayerDown)(fp->parent->object, fp); 729 break; 730 case ST_ACKRCVD: 731 FsmSendConfigReq(fp); 732 NewState(fp, ST_REQSENT); 733 break; 734 } 735 736 m_freem(bp); 737 } 738 739 static void 740 FsmRecvTermReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 741 /* RTR */ 742 { 743 switch (fp->state) { 744 case ST_INITIAL: 745 case ST_STARTING: 746 log_Printf(fp->LogLevel, "%s: Oops, RTR in %s\n", 747 fp->link->name, State2Nam(fp->state)); 748 break; 749 case ST_CLOSED: 750 case ST_STOPPED: 751 case ST_CLOSING: 752 case ST_STOPPING: 753 case ST_REQSENT: 754 (*fp->fn->SendTerminateAck)(fp, lhp->id); 755 break; 756 case ST_ACKRCVD: 757 case ST_ACKSENT: 758 (*fp->fn->SendTerminateAck)(fp, lhp->id); 759 NewState(fp, ST_REQSENT); 760 break; 761 case ST_OPENED: 762 (*fp->fn->LayerDown)(fp); 763 (*fp->fn->SendTerminateAck)(fp, lhp->id); 764 FsmInitRestartCounter(fp, FSM_TRM_TIMER); 765 timer_Start(&fp->FsmTimer); /* Start restart timer */ 766 fp->restart = 0; 767 NewState(fp, ST_STOPPING); 768 (*fp->parent->LayerDown)(fp->parent->object, fp); 769 /* A delayed ST_STOPPED is now scheduled */ 770 break; 771 } 772 m_freem(bp); 773 } 774 775 static void 776 FsmRecvTermAck(struct fsm *fp, struct fsmheader *lhp __unused, struct mbuf *bp) 777 /* RTA */ 778 { 779 switch (fp->state) { 780 case ST_CLOSING: 781 (*fp->fn->LayerFinish)(fp); 782 NewState(fp, ST_CLOSED); 783 (*fp->parent->LayerFinish)(fp->parent->object, fp); 784 break; 785 case ST_STOPPING: 786 (*fp->fn->LayerFinish)(fp); 787 NewState(fp, ST_STOPPED); 788 (*fp->parent->LayerFinish)(fp->parent->object, fp); 789 break; 790 case ST_ACKRCVD: 791 NewState(fp, ST_REQSENT); 792 break; 793 case ST_OPENED: 794 (*fp->fn->LayerDown)(fp); 795 FsmSendConfigReq(fp); 796 NewState(fp, ST_REQSENT); 797 (*fp->parent->LayerDown)(fp->parent->object, fp); 798 break; 799 } 800 m_freem(bp); 801 } 802 803 static void 804 FsmRecvConfigRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 805 /* RCJ */ 806 { 807 struct fsm_decode dec; 808 size_t plen; 809 int flen; 810 u_char *cp; 811 812 plen = m_length(bp); 813 flen = ntohs(lhp->length) - sizeof *lhp; 814 if ((int)plen < flen) { 815 m_freem(bp); 816 return; 817 } 818 819 lcp_SendIdentification(&fp->link->lcp); 820 821 /* 822 * Check and process easy case 823 */ 824 switch (fp->state) { 825 case ST_INITIAL: 826 case ST_STARTING: 827 log_Printf(fp->LogLevel, "%s: Oops, RCJ in %s.\n", 828 fp->link->name, State2Nam(fp->state)); 829 m_freem(bp); 830 return; 831 case ST_CLOSED: 832 case ST_STOPPED: 833 (*fp->fn->SendTerminateAck)(fp, lhp->id); 834 m_freem(bp); 835 return; 836 case ST_CLOSING: 837 case ST_STOPPING: 838 m_freem(bp); 839 return; 840 } 841 842 bp = m_pullup(bp); 843 dec.ackend = dec.ack; 844 dec.nakend = dec.nak; 845 dec.rejend = dec.rej; 846 cp = MBUF_CTOP(bp); 847 (*fp->fn->DecodeConfig)(fp, cp, cp + flen, MODE_REJ, &dec); 848 if (flen < (int)sizeof(struct fsm_opt_hdr)) 849 log_Printf(fp->LogLevel, " [EMPTY]\n"); 850 851 switch (fp->state) { 852 case ST_REQSENT: 853 case ST_ACKSENT: 854 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 855 FsmSendConfigReq(fp); 856 break; 857 case ST_OPENED: 858 (*fp->fn->LayerDown)(fp); 859 FsmSendConfigReq(fp); 860 NewState(fp, ST_REQSENT); 861 (*fp->parent->LayerDown)(fp->parent->object, fp); 862 break; 863 case ST_ACKRCVD: 864 FsmSendConfigReq(fp); 865 NewState(fp, ST_REQSENT); 866 break; 867 } 868 m_freem(bp); 869 } 870 871 static void 872 FsmRecvCodeRej(struct fsm *fp __unused, struct fsmheader *lhp __unused, 873 struct mbuf *bp) 874 { 875 m_freem(bp); 876 } 877 878 static void 879 FsmRecvProtoRej(struct fsm *fp, struct fsmheader *lhp __unused, struct mbuf *bp) 880 { 881 struct physical *p = link2physical(fp->link); 882 u_short proto; 883 884 if (m_length(bp) < 2) { 885 m_freem(bp); 886 return; 887 } 888 bp = mbuf_Read(bp, &proto, 2); 889 proto = ntohs(proto); 890 log_Printf(fp->LogLevel, "%s: -- Protocol 0x%04x (%s) was rejected!\n", 891 fp->link->name, proto, hdlc_Protocol2Nam(proto)); 892 893 switch (proto) { 894 case PROTO_LQR: 895 if (p) 896 lqr_Stop(p, LQM_LQR); 897 else 898 log_Printf(LogERROR, "%s: FsmRecvProtoRej: Not a physical link !\n", 899 fp->link->name); 900 break; 901 case PROTO_CCP: 902 if (fp->proto == PROTO_LCP) { 903 fp = &fp->link->ccp.fsm; 904 /* Despite the RFC (1661), don't do an out-of-place TLF */ 905 /* (*fp->fn->LayerFinish)(fp); */ 906 switch (fp->state) { 907 case ST_CLOSED: 908 case ST_CLOSING: 909 NewState(fp, ST_CLOSED); 910 break; 911 default: 912 NewState(fp, ST_STOPPED); 913 break; 914 } 915 /* See above */ 916 /* (*fp->parent->LayerFinish)(fp->parent->object, fp); */ 917 } 918 break; 919 case PROTO_IPCP: 920 if (fp->proto == PROTO_LCP) { 921 log_Printf(LogPHASE, "%s: IPCP protocol reject closes IPCP !\n", 922 fp->link->name); 923 fsm_Close(&fp->bundle->ncp.ipcp.fsm); 924 } 925 break; 926 #ifndef NOINET6 927 case PROTO_IPV6CP: 928 if (fp->proto == PROTO_LCP) { 929 log_Printf(LogPHASE, "%s: IPV6CP protocol reject closes IPV6CP !\n", 930 fp->link->name); 931 fsm_Close(&fp->bundle->ncp.ipv6cp.fsm); 932 } 933 break; 934 #endif 935 case PROTO_MP: 936 if (fp->proto == PROTO_LCP) { 937 struct lcp *lcp = fsm2lcp(fp); 938 939 if (lcp->want_mrru && lcp->his_mrru) { 940 log_Printf(LogPHASE, "%s: MP protocol reject is fatal !\n", 941 fp->link->name); 942 fsm_Close(fp); 943 } 944 } 945 break; 946 } 947 m_freem(bp); 948 } 949 950 static void 951 FsmRecvEchoReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 952 { 953 struct lcp *lcp = fsm2lcp(fp); 954 u_char *cp; 955 u_int32_t magic; 956 957 bp = m_pullup(bp); 958 m_settype(bp, MB_ECHOIN); 959 960 if (lcp && ntohs(lhp->length) - sizeof *lhp >= 4) { 961 cp = MBUF_CTOP(bp); 962 ua_ntohl(cp, &magic); 963 if (magic != lcp->his_magic) { 964 log_Printf(fp->LogLevel, "%s: RecvEchoReq: magic 0x%08lx is wrong," 965 " expecting 0x%08lx\n", fp->link->name, (u_long)magic, 966 (u_long)lcp->his_magic); 967 /* XXX: We should send terminate request */ 968 } 969 if (fp->state == ST_OPENED) { 970 ua_htonl(&lcp->want_magic, cp); /* local magic */ 971 fsm_Output(fp, CODE_ECHOREP, lhp->id, cp, 972 ntohs(lhp->length) - sizeof *lhp, MB_ECHOOUT); 973 } 974 } 975 m_freem(bp); 976 } 977 978 static void 979 FsmRecvEchoRep(struct fsm *fp, struct fsmheader *lhp __unused, struct mbuf *bp) 980 { 981 if (fsm2lcp(fp)) 982 bp = lqr_RecvEcho(fp, bp); 983 984 m_freem(bp); 985 } 986 987 static void 988 FsmRecvDiscReq(struct fsm *fp __unused, struct fsmheader *lhp __unused, 989 struct mbuf *bp) 990 { 991 m_freem(bp); 992 } 993 994 static void 995 FsmRecvIdent(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 996 { 997 u_int32_t magic; 998 u_short len; 999 u_char *cp; 1000 1001 len = ntohs(lhp->length) - sizeof *lhp; 1002 if (len >= 4) { 1003 bp = m_pullup(m_append(bp, "", 1)); 1004 cp = MBUF_CTOP(bp); 1005 ua_ntohl(cp, &magic); 1006 if (magic != fp->link->lcp.his_magic) 1007 log_Printf(fp->LogLevel, "%s: RecvIdent: magic 0x%08lx is wrong," 1008 " expecting 0x%08lx\n", fp->link->name, (u_long)magic, 1009 (u_long)fp->link->lcp.his_magic); 1010 cp[len] = '\0'; 1011 lcp_RecvIdentification(&fp->link->lcp, cp + 4); 1012 } 1013 m_freem(bp); 1014 } 1015 1016 static void 1017 FsmRecvTimeRemain(struct fsm *fp __unused, struct fsmheader *lhp __unused, 1018 struct mbuf *bp) 1019 { 1020 m_freem(bp); 1021 } 1022 1023 static void 1024 FsmRecvResetReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 1025 { 1026 if ((*fp->fn->RecvResetReq)(fp)) { 1027 /* 1028 * All sendable compressed packets are queued in the first (lowest 1029 * priority) modem output queue.... dump 'em to the priority queue 1030 * so that they arrive at the peer before our ResetAck. 1031 */ 1032 link_SequenceQueue(fp->link); 1033 fsm_Output(fp, CODE_RESETACK, lhp->id, NULL, 0, MB_CCPOUT); 1034 } 1035 m_freem(bp); 1036 } 1037 1038 static void 1039 FsmRecvResetAck(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 1040 { 1041 (*fp->fn->RecvResetAck)(fp, lhp->id); 1042 m_freem(bp); 1043 } 1044 1045 void 1046 fsm_Input(struct fsm *fp, struct mbuf *bp) 1047 { 1048 size_t len; 1049 struct fsmheader lh; 1050 const struct fsmcodedesc *codep; 1051 1052 len = m_length(bp); 1053 if (len < sizeof(struct fsmheader)) { 1054 m_freem(bp); 1055 return; 1056 } 1057 bp = mbuf_Read(bp, &lh, sizeof lh); 1058 1059 if (ntohs(lh.length) > len) { 1060 log_Printf(LogWARN, "%s: Oops: Got %zu bytes but %d byte payload " 1061 "- dropped\n", fp->link->name, len, (int)ntohs(lh.length)); 1062 m_freem(bp); 1063 return; 1064 } 1065 1066 if (lh.code < fp->min_code || lh.code > fp->max_code || 1067 lh.code > sizeof FsmCodes / sizeof *FsmCodes) { 1068 /* 1069 * Use a private id. This is really a response-type packet, but we 1070 * MUST send a unique id for each REQ.... 1071 */ 1072 static u_char id; 1073 1074 bp = m_prepend(bp, &lh, sizeof lh, 0); 1075 bp = m_pullup(bp); 1076 fsm_Output(fp, CODE_CODEREJ, id++, MBUF_CTOP(bp), bp->m_len, MB_UNKNOWN); 1077 m_freem(bp); 1078 return; 1079 } 1080 1081 codep = FsmCodes + lh.code - 1; 1082 if (lh.id != fp->reqid && codep->check_reqid && 1083 Enabled(fp->bundle, OPT_IDCHECK)) { 1084 log_Printf(fp->LogLevel, "%s: Recv%s(%d), dropped (expected %d)\n", 1085 fp->link->name, codep->name, lh.id, fp->reqid); 1086 return; 1087 } 1088 1089 log_Printf(fp->LogLevel, "%s: Recv%s(%d) state = %s\n", 1090 fp->link->name, codep->name, lh.id, State2Nam(fp->state)); 1091 1092 if (codep->inc_reqid && (lh.id == fp->reqid || 1093 (!Enabled(fp->bundle, OPT_IDCHECK) && codep->check_reqid))) 1094 fp->reqid++; /* That's the end of that ``exchange''.... */ 1095 1096 (*codep->recv)(fp, &lh, bp); 1097 } 1098 1099 int 1100 fsm_NullRecvResetReq(struct fsm *fp) 1101 { 1102 log_Printf(fp->LogLevel, "%s: Oops - received unexpected reset req\n", 1103 fp->link->name); 1104 return 1; 1105 } 1106 1107 void 1108 fsm_NullRecvResetAck(struct fsm *fp, u_char id __unused) 1109 { 1110 log_Printf(fp->LogLevel, "%s: Oops - received unexpected reset ack\n", 1111 fp->link->name); 1112 } 1113 1114 void 1115 fsm_Reopen(struct fsm *fp) 1116 { 1117 if (fp->state == ST_OPENED) { 1118 (*fp->fn->LayerDown)(fp); 1119 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 1120 FsmSendConfigReq(fp); 1121 NewState(fp, ST_REQSENT); 1122 (*fp->parent->LayerDown)(fp->parent->object, fp); 1123 } 1124 } 1125 1126 void 1127 fsm2initial(struct fsm *fp) 1128 { 1129 timer_Stop(&fp->FsmTimer); 1130 timer_Stop(&fp->OpenTimer); 1131 timer_Stop(&fp->StoppedTimer); 1132 if (fp->state == ST_STOPPED) 1133 fsm_Close(fp); 1134 if (fp->state > ST_INITIAL) 1135 fsm_Down(fp); 1136 if (fp->state > ST_INITIAL) 1137 fsm_Close(fp); 1138 } 1139 1140 struct fsm_opt * 1141 fsm_readopt(u_char **cp) 1142 { 1143 struct fsm_opt *o = (struct fsm_opt *)*cp; 1144 1145 if (o->hdr.len < sizeof(struct fsm_opt_hdr)) { 1146 log_Printf(LogERROR, "Bad option length %d (out of phase?)\n", o->hdr.len); 1147 return NULL; 1148 } 1149 1150 *cp += o->hdr.len; 1151 1152 if (o->hdr.len > sizeof(struct fsm_opt)) { 1153 log_Printf(LogERROR, "Warning: Truncating option length from %d to %d\n", 1154 o->hdr.len, (int)sizeof(struct fsm_opt)); 1155 o->hdr.len = sizeof(struct fsm_opt); 1156 } 1157 1158 return o; 1159 } 1160 1161 static int 1162 fsm_opt(u_char *opt, int optlen, const struct fsm_opt *o) 1163 { 1164 unsigned cplen = o->hdr.len; 1165 1166 if (optlen < (int)sizeof(struct fsm_opt_hdr)) 1167 optlen = 0; 1168 1169 if ((int)cplen > optlen) { 1170 log_Printf(LogERROR, "Can't REJ length %d - trunating to %d\n", 1171 cplen, optlen); 1172 cplen = optlen; 1173 } 1174 memcpy(opt, o, cplen); 1175 if (cplen) 1176 opt[1] = cplen; 1177 1178 return cplen; 1179 } 1180 1181 void 1182 fsm_rej(struct fsm_decode *dec, const struct fsm_opt *o) 1183 { 1184 if (!dec) 1185 return; 1186 dec->rejend += fsm_opt(dec->rejend, FSM_OPTLEN - (dec->rejend - dec->rej), o); 1187 } 1188 1189 void 1190 fsm_ack(struct fsm_decode *dec, const struct fsm_opt *o) 1191 { 1192 if (!dec) 1193 return; 1194 dec->ackend += fsm_opt(dec->ackend, FSM_OPTLEN - (dec->ackend - dec->ack), o); 1195 } 1196 1197 void 1198 fsm_nak(struct fsm_decode *dec, const struct fsm_opt *o) 1199 { 1200 if (!dec) 1201 return; 1202 dec->nakend += fsm_opt(dec->nakend, FSM_OPTLEN - (dec->nakend - dec->nak), o); 1203 } 1204 1205 void 1206 fsm_opt_normalise(struct fsm_decode *dec) 1207 { 1208 if (dec->rejend != dec->rej) { 1209 /* rejects are preferred */ 1210 dec->ackend = dec->ack; 1211 dec->nakend = dec->nak; 1212 } else if (dec->nakend != dec->nak) 1213 /* then NAKs */ 1214 dec->ackend = dec->ack; 1215 } 1216