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