1 /* 2 * PPP Finite State Machine for LCP/IPCP 3 * 4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5 * 6 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 7 * 8 * Redistribution and use in source and binary forms are permitted 9 * provided that the above copyright notice and this paragraph are 10 * duplicated in all such forms and that any documentation, 11 * advertising materials, and other materials related to such 12 * distribution and use acknowledge that the software was developed 13 * by the Internet Initiative Japan, Inc. The name of the 14 * IIJ may not be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 * 20 * $Id: fsm.c,v 1.36 1998/08/01 01:02:41 brian Exp $ 21 * 22 * TODO: 23 */ 24 25 #include <sys/types.h> 26 #include <netinet/in.h> 27 #include <netinet/in_systm.h> 28 #include <netinet/ip.h> 29 #include <sys/un.h> 30 31 #include <string.h> 32 #include <termios.h> 33 34 #include "ua.h" 35 #include "mbuf.h" 36 #include "log.h" 37 #include "defs.h" 38 #include "timer.h" 39 #include "fsm.h" 40 #include "iplist.h" 41 #include "lqr.h" 42 #include "hdlc.h" 43 #include "throughput.h" 44 #include "slcompress.h" 45 #include "ipcp.h" 46 #include "filter.h" 47 #include "descriptor.h" 48 #include "lcp.h" 49 #include "ccp.h" 50 #include "link.h" 51 #include "mp.h" 52 #include "bundle.h" 53 #include "async.h" 54 #include "physical.h" 55 #include "lcpproto.h" 56 57 static void FsmSendConfigReq(struct fsm *); 58 static void FsmSendTerminateReq(struct fsm *); 59 static void FsmInitRestartCounter(struct fsm *); 60 61 typedef void (recvfn)(struct fsm *, struct fsmheader *, struct mbuf *); 62 static recvfn FsmRecvConfigReq, FsmRecvConfigAck, FsmRecvConfigNak, 63 FsmRecvConfigRej, FsmRecvTermReq, FsmRecvTermAck, 64 FsmRecvCodeRej, FsmRecvProtoRej, FsmRecvEchoReq, 65 FsmRecvEchoRep, FsmRecvDiscReq, FsmRecvIdent, 66 FsmRecvTimeRemain, FsmRecvResetReq, FsmRecvResetAck; 67 68 static const struct fsmcodedesc { 69 recvfn *recv; 70 unsigned check_reqid : 1; 71 unsigned inc_reqid : 1; 72 const char *name; 73 } FsmCodes[] = { 74 { FsmRecvConfigReq, 0, 0, "ConfigReq" }, 75 { FsmRecvConfigAck, 1, 1, "ConfigAck" }, 76 { FsmRecvConfigNak, 1, 1, "ConfigNak" }, 77 { FsmRecvConfigRej, 1, 1, "ConfigRej" }, 78 { FsmRecvTermReq, 0, 0, "TerminateReq" }, 79 { FsmRecvTermAck, 1, 1, "TerminateAck" }, 80 { FsmRecvCodeRej, 0, 0, "CodeRej" }, 81 { FsmRecvProtoRej, 0, 0, "ProtocolRej" }, 82 { FsmRecvEchoReq, 0, 0, "EchoRequest" }, 83 { FsmRecvEchoRep, 0, 0, "EchoReply" }, 84 { FsmRecvDiscReq, 0, 0, "DiscardReq" }, 85 { FsmRecvIdent, 0, 0, "Ident" }, 86 { FsmRecvTimeRemain,0, 0, "TimeRemain" }, 87 { FsmRecvResetReq, 0, 0, "ResetReqt" }, 88 { FsmRecvResetAck, 0, 1, "ResetAck" } 89 }; 90 91 static const char * 92 Code2Nam(u_int code) 93 { 94 if (code == 0 || code > sizeof FsmCodes / sizeof FsmCodes[0]) 95 return "Unknown"; 96 return FsmCodes[code-1].name; 97 } 98 99 const char * 100 State2Nam(u_int state) 101 { 102 static const char *StateNames[] = { 103 "Initial", "Starting", "Closed", "Stopped", "Closing", "Stopping", 104 "Req-Sent", "Ack-Rcvd", "Ack-Sent", "Opened", 105 }; 106 107 if (state >= sizeof StateNames / sizeof StateNames[0]) 108 return "unknown"; 109 return StateNames[state]; 110 } 111 112 static void 113 StoppedTimeout(void *v) 114 { 115 struct fsm *fp = (struct fsm *)v; 116 117 log_Printf(fp->LogLevel, "%s: Stopped timer expired\n", fp->link->name); 118 if (fp->OpenTimer.state == TIMER_RUNNING) { 119 log_Printf(LogWARN, "%s: %s: aborting open delay due to stopped timer\n", 120 fp->link->name, fp->name); 121 timer_Stop(&fp->OpenTimer); 122 } 123 if (fp->state == ST_STOPPED) 124 fsm2initial(fp); 125 } 126 127 void 128 fsm_Init(struct fsm *fp, const char *name, u_short proto, int mincode, 129 int maxcode, int maxcfg, int LogLevel, struct bundle *bundle, 130 struct link *l, const struct fsm_parent *parent, 131 struct fsm_callbacks *fn, const char *timer_names[3]) 132 { 133 fp->name = name; 134 fp->proto = proto; 135 fp->min_code = mincode; 136 fp->max_code = maxcode; 137 fp->state = fp->min_code > CODE_TERMACK ? ST_OPENED : ST_INITIAL; 138 fp->reqid = 1; 139 fp->restart = 1; 140 fp->maxconfig = maxcfg; 141 memset(&fp->FsmTimer, '\0', sizeof fp->FsmTimer); 142 memset(&fp->OpenTimer, '\0', sizeof fp->OpenTimer); 143 memset(&fp->StoppedTimer, '\0', sizeof fp->StoppedTimer); 144 fp->LogLevel = LogLevel; 145 fp->link = l; 146 fp->bundle = bundle; 147 fp->parent = parent; 148 fp->fn = fn; 149 fp->FsmTimer.name = timer_names[0]; 150 fp->OpenTimer.name = timer_names[1]; 151 fp->StoppedTimer.name = timer_names[2]; 152 } 153 154 static void 155 NewState(struct fsm * fp, int new) 156 { 157 log_Printf(fp->LogLevel, "%s: State change %s --> %s\n", 158 fp->link->name, State2Nam(fp->state), State2Nam(new)); 159 if (fp->state == ST_STOPPED && fp->StoppedTimer.state == TIMER_RUNNING) 160 timer_Stop(&fp->StoppedTimer); 161 fp->state = new; 162 if ((new >= ST_INITIAL && new <= ST_STOPPED) || (new == ST_OPENED)) { 163 timer_Stop(&fp->FsmTimer); 164 if (new == ST_STOPPED && fp->StoppedTimer.load) { 165 timer_Stop(&fp->StoppedTimer); 166 fp->StoppedTimer.func = StoppedTimeout; 167 fp->StoppedTimer.arg = (void *) fp; 168 timer_Start(&fp->StoppedTimer); 169 } 170 } 171 } 172 173 void 174 fsm_Output(struct fsm *fp, u_int code, u_int id, u_char *ptr, int count) 175 { 176 int plen; 177 struct fsmheader lh; 178 struct mbuf *bp; 179 180 if (log_IsKept(fp->LogLevel)) { 181 log_Printf(fp->LogLevel, "%s: Send%s(%d) state = %s\n", 182 fp->link->name, Code2Nam(code), id, State2Nam(fp->state)); 183 switch (code) { 184 case CODE_CONFIGREQ: 185 case CODE_CONFIGACK: 186 case CODE_CONFIGREJ: 187 case CODE_CONFIGNAK: 188 (*fp->fn->DecodeConfig)(fp, ptr, count, MODE_NOP, NULL); 189 if (count < sizeof(struct fsmconfig)) 190 log_Printf(fp->LogLevel, " [EMPTY]\n"); 191 break; 192 } 193 } 194 195 plen = sizeof(struct fsmheader) + count; 196 lh.code = code; 197 lh.id = id; 198 lh.length = htons(plen); 199 bp = mbuf_Alloc(plen, MB_FSM); 200 memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader)); 201 if (count) 202 memcpy(MBUF_CTOP(bp) + sizeof(struct fsmheader), ptr, count); 203 log_DumpBp(LogDEBUG, "fsm_Output", bp); 204 hdlc_Output(fp->link, PRI_LINK, fp->proto, bp); 205 } 206 207 static void 208 FsmOpenNow(void *v) 209 { 210 struct fsm *fp = (struct fsm *)v; 211 212 timer_Stop(&fp->OpenTimer); 213 if (fp->state <= ST_STOPPED) { 214 if (fp->state != ST_STARTING) { 215 /* 216 * In practice, we're only here in ST_STOPPED (when delaying the 217 * first config request) or ST_CLOSED (when openmode == 0). 218 * 219 * The ST_STOPPED bit is breaking the RFC already :-( 220 * 221 * According to the RFC (1661) state transition table, a TLS isn't 222 * required for an Open event when state == Closed, but the RFC 223 * must be wrong as TLS hasn't yet been called (since the last TLF) 224 * ie, Initial gets an `Up' event, Closing gets a RTA etc. 225 */ 226 (*fp->fn->LayerStart)(fp); 227 (*fp->parent->LayerStart)(fp->parent->object, fp); 228 } 229 FsmInitRestartCounter(fp); 230 FsmSendConfigReq(fp); 231 NewState(fp, ST_REQSENT); 232 } 233 } 234 235 void 236 fsm_Open(struct fsm * fp) 237 { 238 switch (fp->state) { 239 case ST_INITIAL: 240 NewState(fp, ST_STARTING); 241 (*fp->fn->LayerStart)(fp); 242 (*fp->parent->LayerStart)(fp->parent->object, fp); 243 break; 244 case ST_CLOSED: 245 if (fp->open_mode == OPEN_PASSIVE) { 246 NewState(fp, ST_STOPPED); /* XXX: This is a hack ! */ 247 } else if (fp->open_mode > 0) { 248 if (fp->open_mode > 1) 249 log_Printf(LogPHASE, "%s: Entering STOPPED state for %d seconds\n", 250 fp->link->name, fp->open_mode); 251 NewState(fp, ST_STOPPED); /* XXX: This is a not-so-bad hack ! */ 252 timer_Stop(&fp->OpenTimer); 253 fp->OpenTimer.load = fp->open_mode * SECTICKS; 254 fp->OpenTimer.func = FsmOpenNow; 255 fp->OpenTimer.arg = (void *)fp; 256 timer_Start(&fp->OpenTimer); 257 } else 258 FsmOpenNow(fp); 259 break; 260 case ST_STOPPED: /* XXX: restart option */ 261 case ST_REQSENT: 262 case ST_ACKRCVD: 263 case ST_ACKSENT: 264 case ST_OPENED: /* XXX: restart option */ 265 break; 266 case ST_CLOSING: /* XXX: restart option */ 267 case ST_STOPPING: /* XXX: restart option */ 268 NewState(fp, ST_STOPPING); 269 break; 270 } 271 } 272 273 void 274 fsm_Up(struct fsm * fp) 275 { 276 switch (fp->state) { 277 case ST_INITIAL: 278 log_Printf(fp->LogLevel, "FSM: Using \"%s\" as a transport\n", 279 fp->link->name); 280 NewState(fp, ST_CLOSED); 281 break; 282 case ST_STARTING: 283 FsmInitRestartCounter(fp); 284 FsmSendConfigReq(fp); 285 NewState(fp, ST_REQSENT); 286 break; 287 default: 288 log_Printf(fp->LogLevel, "%s: Oops, Up at %s\n", 289 fp->link->name, State2Nam(fp->state)); 290 break; 291 } 292 } 293 294 void 295 fsm_Down(struct fsm *fp) 296 { 297 switch (fp->state) { 298 case ST_CLOSED: 299 NewState(fp, ST_INITIAL); 300 break; 301 case ST_CLOSING: 302 (*fp->fn->LayerFinish)(fp); 303 NewState(fp, ST_INITIAL); 304 (*fp->parent->LayerFinish)(fp->parent->object, fp); 305 break; 306 case ST_STOPPED: 307 NewState(fp, ST_STARTING); 308 (*fp->fn->LayerStart)(fp); 309 (*fp->parent->LayerStart)(fp->parent->object, fp); 310 break; 311 case ST_STOPPING: 312 case ST_REQSENT: 313 case ST_ACKRCVD: 314 case ST_ACKSENT: 315 NewState(fp, ST_STARTING); 316 break; 317 case ST_OPENED: 318 (*fp->fn->LayerDown)(fp); 319 NewState(fp, ST_STARTING); 320 (*fp->parent->LayerDown)(fp->parent->object, fp); 321 break; 322 } 323 } 324 325 void 326 fsm_Close(struct fsm *fp) 327 { 328 switch (fp->state) { 329 case ST_STARTING: 330 (*fp->fn->LayerFinish)(fp); 331 NewState(fp, ST_INITIAL); 332 (*fp->parent->LayerFinish)(fp->parent->object, fp); 333 break; 334 case ST_STOPPED: 335 NewState(fp, ST_CLOSED); 336 break; 337 case ST_STOPPING: 338 NewState(fp, ST_CLOSING); 339 break; 340 case ST_OPENED: 341 (*fp->fn->LayerDown)(fp); 342 FsmInitRestartCounter(fp); 343 FsmSendTerminateReq(fp); 344 NewState(fp, ST_CLOSING); 345 (*fp->parent->LayerDown)(fp->parent->object, fp); 346 break; 347 case ST_REQSENT: 348 case ST_ACKRCVD: 349 case ST_ACKSENT: 350 FsmInitRestartCounter(fp); 351 FsmSendTerminateReq(fp); 352 NewState(fp, ST_CLOSING); 353 break; 354 } 355 } 356 357 /* 358 * Send functions 359 */ 360 static void 361 FsmSendConfigReq(struct fsm * fp) 362 { 363 if (--fp->maxconfig > 0) { 364 (*fp->fn->SendConfigReq)(fp); 365 timer_Start(&fp->FsmTimer); /* Start restart timer */ 366 fp->restart--; /* Decrement restart counter */ 367 } else { 368 fsm_Close(fp); 369 } 370 } 371 372 static void 373 FsmSendTerminateReq(struct fsm *fp) 374 { 375 fsm_Output(fp, CODE_TERMREQ, fp->reqid, NULL, 0); 376 (*fp->fn->SentTerminateReq)(fp); 377 timer_Start(&fp->FsmTimer); /* Start restart timer */ 378 fp->restart--; /* Decrement restart counter */ 379 } 380 381 /* 382 * Timeout actions 383 */ 384 static void 385 FsmTimeout(void *v) 386 { 387 struct fsm *fp = (struct fsm *)v; 388 389 if (fp->restart) { 390 switch (fp->state) { 391 case ST_CLOSING: 392 case ST_STOPPING: 393 FsmSendTerminateReq(fp); 394 break; 395 case ST_REQSENT: 396 case ST_ACKSENT: 397 FsmSendConfigReq(fp); 398 break; 399 case ST_ACKRCVD: 400 FsmSendConfigReq(fp); 401 NewState(fp, ST_REQSENT); 402 break; 403 } 404 timer_Start(&fp->FsmTimer); 405 } else { 406 switch (fp->state) { 407 case ST_CLOSING: 408 (*fp->fn->LayerFinish)(fp); 409 NewState(fp, ST_CLOSED); 410 (*fp->parent->LayerFinish)(fp->parent->object, fp); 411 break; 412 case ST_STOPPING: 413 (*fp->fn->LayerFinish)(fp); 414 NewState(fp, ST_STOPPED); 415 (*fp->parent->LayerFinish)(fp->parent->object, fp); 416 break; 417 case ST_REQSENT: /* XXX: 3p */ 418 case ST_ACKSENT: 419 case ST_ACKRCVD: 420 (*fp->fn->LayerFinish)(fp); 421 NewState(fp, ST_STOPPED); 422 (*fp->parent->LayerFinish)(fp->parent->object, fp); 423 break; 424 } 425 } 426 } 427 428 static void 429 FsmInitRestartCounter(struct fsm * fp) 430 { 431 timer_Stop(&fp->FsmTimer); 432 fp->FsmTimer.func = FsmTimeout; 433 fp->FsmTimer.arg = (void *) fp; 434 (*fp->fn->InitRestartCounter)(fp); 435 } 436 437 /* 438 * Actions when receive packets 439 */ 440 static void 441 FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 442 /* RCR */ 443 { 444 struct fsm_decode dec; 445 int plen, flen; 446 int ackaction = 0; 447 448 plen = mbuf_Length(bp); 449 flen = ntohs(lhp->length) - sizeof *lhp; 450 if (plen < flen) { 451 log_Printf(LogWARN, "%s: FsmRecvConfigReq: plen (%d) < flen (%d)\n", 452 fp->link->name, plen, flen); 453 mbuf_Free(bp); 454 return; 455 } 456 457 /* 458 * Check and process easy case 459 */ 460 switch (fp->state) { 461 case ST_INITIAL: 462 if (fp->proto == PROTO_CCP && fp->link->lcp.fsm.state == ST_OPENED) { 463 /* 464 * ccp_SetOpenMode() leaves us in initial if we're disabling 465 * & denying everything. This is a bit smelly, we know that 466 * ``bp'' really has ``fsmheader'' in front of it, and CCP_PROTO 467 * in front of that. CCP_PROTO isn't compressed either 'cos it 468 * doesn't begin with 0x00.... 469 */ 470 bp->offset -= sizeof(struct fsmheader) + 2; 471 bp->cnt += sizeof(struct fsmheader) + 2; 472 lcp_SendProtoRej(&fp->link->lcp, MBUF_CTOP(bp), bp->cnt); 473 mbuf_Free(bp); 474 return; 475 } 476 /* Drop through */ 477 case ST_STARTING: 478 log_Printf(fp->LogLevel, "%s: Oops, RCR in %s.\n", 479 fp->link->name, State2Nam(fp->state)); 480 mbuf_Free(bp); 481 return; 482 case ST_CLOSED: 483 (*fp->fn->SendTerminateAck)(fp, lhp->id); 484 mbuf_Free(bp); 485 return; 486 case ST_CLOSING: 487 log_Printf(fp->LogLevel, "%s: Error: Got ConfigReq while state = %s\n", 488 fp->link->name, State2Nam(fp->state)); 489 case ST_STOPPING: 490 mbuf_Free(bp); 491 return; 492 case ST_OPENED: 493 (*fp->fn->LayerDown)(fp); 494 (*fp->parent->LayerDown)(fp->parent->object, fp); 495 break; 496 } 497 498 dec.ackend = dec.ack; 499 dec.nakend = dec.nak; 500 dec.rejend = dec.rej; 501 (*fp->fn->DecodeConfig)(fp, MBUF_CTOP(bp), flen, MODE_REQ, &dec); 502 if (flen < sizeof(struct fsmconfig)) 503 log_Printf(fp->LogLevel, " [EMPTY]\n"); 504 505 if (dec.nakend == dec.nak && dec.rejend == dec.rej) 506 ackaction = 1; 507 508 switch (fp->state) { 509 case ST_STOPPED: 510 FsmInitRestartCounter(fp); 511 /* Fall through */ 512 513 case ST_OPENED: 514 FsmSendConfigReq(fp); 515 break; 516 } 517 518 if (dec.rejend != dec.rej) 519 fsm_Output(fp, CODE_CONFIGREJ, lhp->id, dec.rej, dec.rejend - dec.rej); 520 if (dec.nakend != dec.nak) 521 fsm_Output(fp, CODE_CONFIGNAK, lhp->id, dec.nak, dec.nakend - dec.nak); 522 if (ackaction) 523 fsm_Output(fp, CODE_CONFIGACK, lhp->id, dec.ack, dec.ackend - dec.ack); 524 525 switch (fp->state) { 526 case ST_OPENED: 527 case ST_STOPPED: 528 if (ackaction) 529 NewState(fp, ST_ACKSENT); 530 else 531 NewState(fp, ST_REQSENT); 532 break; 533 case ST_REQSENT: 534 if (ackaction) 535 NewState(fp, ST_ACKSENT); 536 break; 537 case ST_ACKRCVD: 538 if (ackaction) { 539 NewState(fp, ST_OPENED); 540 if ((*fp->fn->LayerUp)(fp)) 541 (*fp->parent->LayerUp)(fp->parent->object, fp); 542 else { 543 (*fp->fn->LayerDown)(fp); 544 FsmInitRestartCounter(fp); 545 FsmSendTerminateReq(fp); 546 NewState(fp, ST_CLOSING); 547 } 548 } 549 break; 550 case ST_ACKSENT: 551 if (!ackaction) 552 NewState(fp, ST_REQSENT); 553 break; 554 } 555 mbuf_Free(bp); 556 } 557 558 static void 559 FsmRecvConfigAck(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 560 /* RCA */ 561 { 562 switch (fp->state) { 563 case ST_CLOSED: 564 case ST_STOPPED: 565 (*fp->fn->SendTerminateAck)(fp, lhp->id); 566 break; 567 case ST_CLOSING: 568 case ST_STOPPING: 569 break; 570 case ST_REQSENT: 571 FsmInitRestartCounter(fp); 572 NewState(fp, ST_ACKRCVD); 573 break; 574 case ST_ACKRCVD: 575 FsmSendConfigReq(fp); 576 NewState(fp, ST_REQSENT); 577 break; 578 case ST_ACKSENT: 579 FsmInitRestartCounter(fp); 580 NewState(fp, ST_OPENED); 581 if ((*fp->fn->LayerUp)(fp)) 582 (*fp->parent->LayerUp)(fp->parent->object, fp); 583 else { 584 (*fp->fn->LayerDown)(fp); 585 FsmInitRestartCounter(fp); 586 FsmSendTerminateReq(fp); 587 NewState(fp, ST_CLOSING); 588 } 589 break; 590 case ST_OPENED: 591 (*fp->fn->LayerDown)(fp); 592 FsmSendConfigReq(fp); 593 NewState(fp, ST_REQSENT); 594 (*fp->parent->LayerDown)(fp->parent->object, fp); 595 break; 596 } 597 mbuf_Free(bp); 598 } 599 600 static void 601 FsmRecvConfigNak(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 602 /* RCN */ 603 { 604 struct fsm_decode dec; 605 int plen, flen; 606 607 plen = mbuf_Length(bp); 608 flen = ntohs(lhp->length) - sizeof *lhp; 609 if (plen < flen) { 610 mbuf_Free(bp); 611 return; 612 } 613 614 /* 615 * Check and process easy case 616 */ 617 switch (fp->state) { 618 case ST_INITIAL: 619 case ST_STARTING: 620 log_Printf(fp->LogLevel, "%s: Oops, RCN in %s.\n", 621 fp->link->name, State2Nam(fp->state)); 622 mbuf_Free(bp); 623 return; 624 case ST_CLOSED: 625 case ST_STOPPED: 626 (*fp->fn->SendTerminateAck)(fp, lhp->id); 627 mbuf_Free(bp); 628 return; 629 case ST_CLOSING: 630 case ST_STOPPING: 631 mbuf_Free(bp); 632 return; 633 } 634 635 dec.ackend = dec.ack; 636 dec.nakend = dec.nak; 637 dec.rejend = dec.rej; 638 (*fp->fn->DecodeConfig)(fp, MBUF_CTOP(bp), flen, MODE_NAK, &dec); 639 if (flen < sizeof(struct fsmconfig)) 640 log_Printf(fp->LogLevel, " [EMPTY]\n"); 641 642 switch (fp->state) { 643 case ST_REQSENT: 644 case ST_ACKSENT: 645 FsmInitRestartCounter(fp); 646 FsmSendConfigReq(fp); 647 break; 648 case ST_OPENED: 649 (*fp->fn->LayerDown)(fp); 650 FsmSendConfigReq(fp); 651 NewState(fp, ST_REQSENT); 652 (*fp->parent->LayerDown)(fp->parent->object, fp); 653 break; 654 case ST_ACKRCVD: 655 FsmSendConfigReq(fp); 656 NewState(fp, ST_REQSENT); 657 break; 658 } 659 660 mbuf_Free(bp); 661 } 662 663 static void 664 FsmRecvTermReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 665 /* RTR */ 666 { 667 switch (fp->state) { 668 case ST_INITIAL: 669 case ST_STARTING: 670 log_Printf(fp->LogLevel, "%s: Oops, RTR in %s\n", 671 fp->link->name, State2Nam(fp->state)); 672 break; 673 case ST_CLOSED: 674 case ST_STOPPED: 675 case ST_CLOSING: 676 case ST_STOPPING: 677 case ST_REQSENT: 678 (*fp->fn->SendTerminateAck)(fp, lhp->id); 679 break; 680 case ST_ACKRCVD: 681 case ST_ACKSENT: 682 (*fp->fn->SendTerminateAck)(fp, lhp->id); 683 NewState(fp, ST_REQSENT); 684 break; 685 case ST_OPENED: 686 (*fp->fn->LayerDown)(fp); 687 (*fp->fn->SendTerminateAck)(fp, lhp->id); 688 FsmInitRestartCounter(fp); 689 timer_Start(&fp->FsmTimer); /* Start restart timer */ 690 fp->restart = 0; 691 NewState(fp, ST_STOPPING); 692 (*fp->parent->LayerDown)(fp->parent->object, fp); 693 break; 694 } 695 mbuf_Free(bp); 696 } 697 698 static void 699 FsmRecvTermAck(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 700 /* RTA */ 701 { 702 switch (fp->state) { 703 case ST_CLOSING: 704 (*fp->fn->LayerFinish)(fp); 705 NewState(fp, ST_CLOSED); 706 (*fp->parent->LayerFinish)(fp->parent->object, fp); 707 break; 708 case ST_STOPPING: 709 (*fp->fn->LayerFinish)(fp); 710 NewState(fp, ST_STOPPED); 711 (*fp->parent->LayerFinish)(fp->parent->object, fp); 712 break; 713 case ST_ACKRCVD: 714 NewState(fp, ST_REQSENT); 715 break; 716 case ST_OPENED: 717 (*fp->fn->LayerDown)(fp); 718 FsmSendConfigReq(fp); 719 NewState(fp, ST_REQSENT); 720 (*fp->parent->LayerDown)(fp->parent->object, fp); 721 break; 722 } 723 mbuf_Free(bp); 724 } 725 726 static void 727 FsmRecvConfigRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 728 /* RCJ */ 729 { 730 struct fsm_decode dec; 731 int plen, flen; 732 733 plen = mbuf_Length(bp); 734 flen = ntohs(lhp->length) - sizeof *lhp; 735 if (plen < flen) { 736 mbuf_Free(bp); 737 return; 738 } 739 740 /* 741 * Check and process easy case 742 */ 743 switch (fp->state) { 744 case ST_INITIAL: 745 case ST_STARTING: 746 log_Printf(fp->LogLevel, "%s: Oops, RCJ in %s.\n", 747 fp->link->name, State2Nam(fp->state)); 748 mbuf_Free(bp); 749 return; 750 case ST_CLOSED: 751 case ST_STOPPED: 752 (*fp->fn->SendTerminateAck)(fp, lhp->id); 753 mbuf_Free(bp); 754 return; 755 case ST_CLOSING: 756 case ST_STOPPING: 757 mbuf_Free(bp); 758 return; 759 } 760 761 dec.ackend = dec.ack; 762 dec.nakend = dec.nak; 763 dec.rejend = dec.rej; 764 (*fp->fn->DecodeConfig)(fp, MBUF_CTOP(bp), flen, MODE_REJ, &dec); 765 if (flen < sizeof(struct fsmconfig)) 766 log_Printf(fp->LogLevel, " [EMPTY]\n"); 767 768 switch (fp->state) { 769 case ST_REQSENT: 770 case ST_ACKSENT: 771 FsmInitRestartCounter(fp); 772 FsmSendConfigReq(fp); 773 break; 774 case ST_OPENED: 775 (*fp->fn->LayerDown)(fp); 776 FsmSendConfigReq(fp); 777 NewState(fp, ST_REQSENT); 778 (*fp->parent->LayerDown)(fp->parent->object, fp); 779 break; 780 case ST_ACKRCVD: 781 FsmSendConfigReq(fp); 782 NewState(fp, ST_REQSENT); 783 break; 784 } 785 mbuf_Free(bp); 786 } 787 788 static void 789 FsmRecvCodeRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 790 { 791 mbuf_Free(bp); 792 } 793 794 static void 795 FsmRecvProtoRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 796 { 797 struct physical *p = link2physical(fp->link); 798 u_short *sp, proto; 799 800 sp = (u_short *)MBUF_CTOP(bp); 801 proto = ntohs(*sp); 802 log_Printf(fp->LogLevel, "%s: -- Protocol 0x%04x (%s) was rejected!\n", 803 fp->link->name, proto, hdlc_Protocol2Nam(proto)); 804 805 switch (proto) { 806 case PROTO_LQR: 807 if (p) 808 lqr_Stop(p, LQM_LQR); 809 else 810 log_Printf(LogERROR, "%s: FsmRecvProtoRej: Not a physical link !\n", 811 fp->link->name); 812 break; 813 case PROTO_CCP: 814 if (fp->proto == PROTO_LCP) { 815 fp = &fp->link->ccp.fsm; 816 (*fp->fn->LayerFinish)(fp); 817 switch (fp->state) { 818 case ST_CLOSED: 819 case ST_CLOSING: 820 NewState(fp, ST_CLOSED); 821 default: 822 NewState(fp, ST_STOPPED); 823 break; 824 } 825 (*fp->parent->LayerFinish)(fp->parent->object, fp); 826 } 827 break; 828 case PROTO_MP: 829 if (fp->proto == PROTO_LCP) { 830 struct lcp *lcp = fsm2lcp(fp); 831 832 if (lcp->want_mrru && lcp->his_mrru) { 833 log_Printf(LogPHASE, "%s: MP protocol reject is fatal !\n", 834 fp->link->name); 835 fsm_Close(fp); 836 } 837 } 838 break; 839 } 840 mbuf_Free(bp); 841 } 842 843 static void 844 FsmRecvEchoReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 845 { 846 struct lcp *lcp = fsm2lcp(fp); 847 u_char *cp; 848 u_int32_t magic; 849 850 if (lcp) { 851 cp = MBUF_CTOP(bp); 852 ua_ntohl(cp, &magic); 853 if (magic != lcp->his_magic) { 854 log_Printf(fp->LogLevel, "%s: RecvEchoReq: Error: His magic is bad!!\n", 855 fp->link->name); 856 /* XXX: We should send terminate request */ 857 } 858 if (fp->state == ST_OPENED) { 859 ua_htonl(&lcp->want_magic, cp); /* local magic */ 860 fsm_Output(fp, CODE_ECHOREP, lhp->id, cp, mbuf_Length(bp)); 861 } 862 } 863 mbuf_Free(bp); 864 } 865 866 static void 867 FsmRecvEchoRep(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 868 { 869 struct lcp *lcp = fsm2lcp(fp); 870 u_int32_t magic; 871 872 if (lcp) { 873 ua_ntohl(MBUF_CTOP(bp), &magic); 874 /* Tolerate echo replies with either magic number */ 875 if (magic != 0 && magic != lcp->his_magic && magic != lcp->want_magic) { 876 log_Printf(LogWARN, 877 "%s: RecvEchoRep: Bad magic: expected 0x%08x, got: 0x%08x\n", 878 fp->link->name, lcp->his_magic, magic); 879 /* 880 * XXX: We should send terminate request. But poor implementations may 881 * die as a result. 882 */ 883 } 884 lqr_RecvEcho(fp, bp); 885 } 886 mbuf_Free(bp); 887 } 888 889 static void 890 FsmRecvDiscReq(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 891 { 892 mbuf_Free(bp); 893 } 894 895 static void 896 FsmRecvIdent(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 897 { 898 mbuf_Free(bp); 899 } 900 901 static void 902 FsmRecvTimeRemain(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 903 { 904 mbuf_Free(bp); 905 } 906 907 static void 908 FsmRecvResetReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 909 { 910 (*fp->fn->RecvResetReq)(fp); 911 /* 912 * All sendable compressed packets are queued in the PRI_NORMAL modem 913 * output queue.... dump 'em to the priority queue so that they arrive 914 * at the peer before our ResetAck. 915 */ 916 link_SequenceQueue(fp->link); 917 fsm_Output(fp, CODE_RESETACK, lhp->id, NULL, 0); 918 mbuf_Free(bp); 919 } 920 921 static void 922 FsmRecvResetAck(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 923 { 924 (*fp->fn->RecvResetAck)(fp, lhp->id); 925 mbuf_Free(bp); 926 } 927 928 void 929 fsm_Input(struct fsm *fp, struct mbuf *bp) 930 { 931 int len; 932 struct fsmheader *lhp; 933 const struct fsmcodedesc *codep; 934 935 len = mbuf_Length(bp); 936 if (len < sizeof(struct fsmheader)) { 937 mbuf_Free(bp); 938 return; 939 } 940 lhp = (struct fsmheader *) MBUF_CTOP(bp); 941 if (lhp->code < fp->min_code || lhp->code > fp->max_code || 942 lhp->code > sizeof FsmCodes / sizeof *FsmCodes) { 943 /* 944 * Use a private id. This is really a response-type packet, but we 945 * MUST send a unique id for each REQ.... 946 */ 947 static u_char id; 948 949 fsm_Output(fp, CODE_CODEREJ, id++, MBUF_CTOP(bp), bp->cnt); 950 mbuf_Free(bp); 951 return; 952 } 953 bp->offset += sizeof(struct fsmheader); 954 bp->cnt -= sizeof(struct fsmheader); 955 956 codep = FsmCodes + lhp->code - 1; 957 if (lhp->id != fp->reqid && codep->check_reqid && 958 Enabled(fp->bundle, OPT_IDCHECK)) { 959 log_Printf(fp->LogLevel, "%s: Recv%s(%d), dropped (expected %d)\n", 960 fp->link->name, codep->name, lhp->id, fp->reqid); 961 return; 962 } 963 964 log_Printf(fp->LogLevel, "%s: Recv%s(%d) state = %s\n", 965 fp->link->name, codep->name, lhp->id, State2Nam(fp->state)); 966 967 if (log_IsKept(LogDEBUG)) 968 mbuf_Log(); 969 970 if (codep->inc_reqid && (lhp->id == fp->reqid || 971 (!Enabled(fp->bundle, OPT_IDCHECK) && codep->check_reqid))) 972 fp->reqid++; /* That's the end of that ``exchange''.... */ 973 974 (*codep->recv)(fp, lhp, bp); 975 976 if (log_IsKept(LogDEBUG)) 977 mbuf_Log(); 978 } 979 980 void 981 fsm_NullRecvResetReq(struct fsm *fp) 982 { 983 log_Printf(fp->LogLevel, "%s: Oops - received unexpected reset req\n", 984 fp->link->name); 985 } 986 987 void 988 fsm_NullRecvResetAck(struct fsm *fp, u_char id) 989 { 990 log_Printf(fp->LogLevel, "%s: Oops - received unexpected reset ack\n", 991 fp->link->name); 992 } 993 994 void 995 fsm_Reopen(struct fsm *fp) 996 { 997 if (fp->state == ST_OPENED) { 998 (*fp->fn->LayerDown)(fp); 999 FsmInitRestartCounter(fp); 1000 FsmSendConfigReq(fp); 1001 NewState(fp, ST_REQSENT); 1002 (*fp->parent->LayerDown)(fp->parent->object, fp); 1003 } 1004 } 1005 1006 void 1007 fsm2initial(struct fsm *fp) 1008 { 1009 if (fp->state == ST_STOPPED) 1010 fsm_Close(fp); 1011 if (fp->state > ST_INITIAL) 1012 fsm_Down(fp); 1013 if (fp->state > ST_INITIAL) 1014 fsm_Close(fp); 1015 } 1016