fsm.c revision 6735
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:$ 21 * 22 * TODO: 23 * o Refer loglevel for log output 24 * o Better option log display 25 */ 26#include "fsm.h" 27#include "hdlc.h" 28#include "lqr.h" 29#include "lcpproto.h" 30#include "lcp.h" 31 32void FsmSendConfigReq(struct fsm *fp); 33void FsmSendTerminateReq(struct fsm *fp); 34void FsmInitRestartCounter(struct fsm *fp); 35void FsmTimeout(struct fsm *fp); 36 37char *StateNames[] = { 38 "Initial", "Starting", "Closed", "Stopped", "Closing", "Stopping", 39 "Req-Sent", "Ack-Rcvd", "Ack-Sent", "Opend", 40}; 41 42void 43FsmInit(fp) 44struct fsm *fp; 45{ 46#ifdef DEBUG 47 logprintf("FsmInit\n"); 48#endif 49 fp->state = ST_INITIAL; 50 fp->reqid = 1; 51 fp->restart = 1; 52 fp->maxconfig = 3; 53} 54 55void 56NewState(fp, new) 57struct fsm *fp; 58int new; 59{ 60 LogPrintf(LOG_LCP, "%s: state change %s --> %s\n", 61 fp->name, StateNames[fp->state], StateNames[new]); 62 fp->state = new; 63 if ((new >= ST_INITIAL && new <= ST_STOPPED) || (new == ST_OPENED)) 64 StopTimer(&fp->FsmTimer); 65} 66 67void 68FsmOutput(fp, code, id, ptr, count) 69struct fsm *fp; 70u_int code, id; 71u_char *ptr; 72int count; 73{ 74 int plen; 75 struct fsmheader lh; 76 struct mbuf *bp; 77 78 plen = sizeof(struct fsmheader) + count; 79 lh.code = code; 80 lh.id = id; 81 lh.length = htons(plen); 82 bp = mballoc(plen, MB_FSM); 83 bcopy(&lh, MBUF_CTOP(bp), sizeof(struct fsmheader)); 84 if (count) 85 bcopy(ptr, MBUF_CTOP(bp) + sizeof(struct fsmheader), count); 86#ifdef DEBUG 87 DumpBp(bp); 88#endif 89 HdlcOutput(PRI_NORMAL, fp->proto, bp); 90} 91 92void 93FsmOpen(fp) 94struct fsm *fp; 95{ 96 switch (fp->state) { 97 case ST_INITIAL: 98 (fp->LayerStart)(fp); 99 NewState(fp, ST_STARTING); 100 break; 101 case ST_STARTING: 102 break; 103 case ST_CLOSED: 104 if (fp->open_mode == OPEN_PASSIVE) { 105 NewState(fp, ST_STOPPED); 106 } else { 107 FsmInitRestartCounter(fp); 108 FsmSendConfigReq(fp); 109 NewState(fp, ST_REQSENT); 110 } 111 break; 112 case ST_STOPPED: /* XXX: restart option */ 113 case ST_REQSENT: 114 case ST_ACKRCVD: 115 case ST_ACKSENT: 116 case ST_OPENED: /* XXX: restart option */ 117 break; 118 case ST_CLOSING: /* XXX: restart option */ 119 case ST_STOPPING: /* XXX: restart option */ 120 NewState(fp, ST_STOPPING); 121 break; 122 } 123} 124 125void 126FsmUp(fp) 127struct fsm *fp; 128{ 129 switch (fp->state) { 130 case ST_INITIAL: 131 NewState(fp, ST_CLOSED); 132 break; 133 case ST_STARTING: 134 FsmInitRestartCounter(fp); 135 FsmSendConfigReq(fp); 136 NewState(fp, ST_REQSENT); 137 break; 138 default: 139 LogPrintf(LOG_LCP, "%s: Oops, Up at %s\n", 140 fp->name, StateNames[fp->state]); 141 break; 142 } 143} 144 145void 146FsmDown(fp) 147struct fsm *fp; 148{ 149 switch (fp->state) { 150 case ST_CLOSED: 151 case ST_CLOSING: 152 NewState(fp, ST_INITIAL); 153 break; 154 case ST_STOPPED: 155 (fp->LayerStart)(fp); 156 /* Fall into.. */ 157 case ST_STOPPING: 158 case ST_REQSENT: 159 case ST_ACKRCVD: 160 case ST_ACKSENT: 161 NewState(fp, ST_STARTING); 162 break; 163 case ST_OPENED: 164 (fp->LayerDown)(fp); 165 NewState(fp, ST_STARTING); 166 break; 167 } 168} 169 170void 171FsmClose(fp) 172struct fsm *fp; 173{ 174 switch (fp->state) { 175 case ST_STARTING: 176 NewState(fp, ST_INITIAL); 177 break; 178 case ST_STOPPED: 179 NewState(fp, ST_CLOSED); 180 break; 181 case ST_STOPPING: 182 NewState(fp, ST_CLOSING); 183 break; 184 case ST_OPENED: 185 (fp->LayerDown)(fp); 186 /* Fall down */ 187 case ST_REQSENT: 188 case ST_ACKRCVD: 189 case ST_ACKSENT: 190 FsmInitRestartCounter(fp); 191 FsmSendTerminateReq(fp); 192 NewState(fp, ST_CLOSING); 193 break; 194 } 195} 196 197/* 198 * Send functions 199 */ 200void 201FsmSendConfigReq(fp) 202struct fsm *fp; 203{ 204 if (--fp->maxconfig > 0) { 205 (fp->SendConfigReq)(fp); 206 StartTimer(&fp->FsmTimer); /* Start restart timer */ 207 fp->restart--; /* Decrement restart counter */ 208 } else { 209 FsmClose(fp); 210 } 211} 212 213void 214FsmSendTerminateReq(fp) 215struct fsm *fp; 216{ 217 LogPrintf(LOG_LCP, "%s: SendTerminateReq.\n", fp->name); 218 FsmOutput(fp, CODE_TERMREQ, fp->reqid++, NULL, 0); 219 (fp->SendTerminateReq)(fp); 220 StartTimer(&fp->FsmTimer); /* Start restart timer */ 221 fp->restart--; /* Decrement restart counter */ 222} 223 224static void 225FsmSendConfigAck(fp, lhp, option, count) 226struct fsm *fp; 227struct fsmheader *lhp; 228u_char *option; 229int count; 230{ 231 LogPrintf(LOG_LCP, "%s: SendConfigAck(%s)\n", fp->name, StateNames[fp->state]); 232 (fp->DecodeConfig)(option, count, MODE_NOP); 233 FsmOutput(fp, CODE_CONFIGACK, lhp->id, option, count); 234} 235 236static void 237FsmSendConfigRej(fp, lhp, option, count) 238struct fsm *fp; 239struct fsmheader *lhp; 240u_char *option; 241int count; 242{ 243 LogPrintf(LOG_LCP, "%s: SendConfigRej(%s)\n", fp->name, StateNames[fp->state]); 244 (fp->DecodeConfig)(option, count, MODE_NOP); 245 FsmOutput(fp, CODE_CONFIGREJ, lhp->id, option, count); 246} 247 248static void 249FsmSendConfigNak(fp, lhp, option, count) 250struct fsm *fp; 251struct fsmheader *lhp; 252u_char *option; 253int count; 254{ 255 LogPrintf(LOG_LCP, "%s: SendConfigNak(%s)\n", 256 fp->name, StateNames[fp->state]); 257 (fp->DecodeConfig)(option, count, MODE_NOP); 258 FsmOutput(fp, CODE_CONFIGNAK, lhp->id, option, count); 259} 260 261/* 262 * Timeout actions 263 */ 264void 265FsmTimeout(fp) 266struct fsm *fp; 267{ 268 if (fp->restart) { 269 switch (fp->state) { 270 case ST_CLOSING: 271 case ST_STOPPING: 272 FsmSendTerminateReq(fp); 273 break; 274 case ST_REQSENT: 275 case ST_ACKSENT: 276 FsmSendConfigReq(fp); 277 break; 278 case ST_ACKRCVD: 279 FsmSendConfigReq(fp); 280 NewState(fp, ST_REQSENT); 281 break; 282 } 283 StartTimer(&fp->FsmTimer); 284 } else { 285 switch (fp->state) { 286 case ST_CLOSING: 287 NewState(fp, ST_CLOSED); 288 (fp->LayerFinish)(fp); 289 break; 290 case ST_STOPPING: 291 NewState(fp, ST_STOPPED); 292 (fp->LayerFinish)(fp); 293 break; 294 case ST_REQSENT: /* XXX: 3p */ 295 case ST_ACKSENT: 296 case ST_ACKRCVD: 297 NewState(fp, ST_STOPPED); 298 (fp->LayerFinish)(fp); 299 break; 300 } 301 } 302} 303 304void 305FsmInitRestartCounter(fp) 306struct fsm *fp; 307{ 308 StopTimer(&fp->FsmTimer); 309 fp->FsmTimer.state = TIMER_STOPPED; 310 fp->FsmTimer.func = FsmTimeout; 311 fp->FsmTimer.arg = (void *)fp; 312 (fp->InitRestartCounter)(fp); 313} 314 315/* 316 * Actions when receive packets 317 */ 318void 319FsmRecvConfigReq(fp, lhp, bp) /* RCR */ 320struct fsm *fp; 321struct fsmheader *lhp; 322struct mbuf *bp; 323{ 324 int plen, flen; 325 int ackaction = 0; 326 327 plen = plength(bp); 328 flen = ntohs(lhp->length) - sizeof(*lhp); 329 if (plen < flen) { 330 logprintf("** plen (%d) < flen (%d)\n", plen, flen); 331 pfree(bp); 332 return; 333 } 334 335 336 /* 337 * Check and process easy case 338 */ 339 switch (fp->state) { 340 case ST_INITIAL: 341 case ST_STARTING: 342 LogPrintf(LOG_LCP, "%s: Oops, RCR in %s.\n", 343 fp->name, StateNames[fp->state]); 344 pfree(bp); 345 return; 346 case ST_CLOSED: 347 (fp->SendTerminateAck)(fp); 348 pfree(bp); 349 return; 350 case ST_CLOSING: 351 case ST_STOPPING: 352logprintf("## state = %d\n", fp->state); 353 pfree(bp); 354 return; 355 } 356 357 (fp->DecodeConfig)(MBUF_CTOP(bp), flen, MODE_REQ); 358 359 if (nakp == NakBuff && rejp == RejBuff) 360 ackaction = 1; 361 362 switch (fp->state) { 363 case ST_OPENED: 364 (fp->LayerDown)(fp); 365 FsmSendConfigReq(fp); 366 break; 367 case ST_STOPPED: 368 FsmInitRestartCounter(fp); 369 FsmSendConfigReq(fp); 370 break; 371 } 372 373 if (rejp != RejBuff) 374 FsmSendConfigRej(fp, lhp, RejBuff, rejp - RejBuff); 375 if (nakp != NakBuff) 376 FsmSendConfigNak(fp, lhp, NakBuff, nakp - NakBuff); 377 if (ackaction) 378 FsmSendConfigAck(fp, lhp, AckBuff, ackp - AckBuff); 379 380 switch (fp->state) { 381 case ST_STOPPED: 382 case ST_OPENED: 383 if (ackaction) 384 NewState(fp, ST_ACKSENT); 385 else 386 NewState(fp, ST_REQSENT); 387 break; 388 case ST_REQSENT: 389 if (ackaction) 390 NewState(fp, ST_ACKSENT); 391 break; 392 case ST_ACKRCVD: 393 if (ackaction) { 394 NewState(fp, ST_OPENED); 395 (fp->LayerUp)(fp); 396 } 397 break; 398 case ST_ACKSENT: 399 if (!ackaction) 400 NewState(fp, ST_REQSENT); 401 break; 402 } 403 pfree(bp); 404} 405 406void 407FsmRecvConfigAck(fp, lhp, bp) /* RCA */ 408struct fsm *fp; 409struct fsmheader *lhp; 410struct mbuf *bp; 411{ 412 switch (fp->state) { 413 case ST_CLOSED: 414 case ST_STOPPED: 415 (fp->SendTerminateAck)(fp); 416 break; 417 case ST_CLOSING: 418 case ST_STOPPING: 419 break; 420 case ST_REQSENT: 421 FsmInitRestartCounter(fp); 422 NewState(fp, ST_ACKRCVD); 423 break; 424 case ST_ACKRCVD: 425 FsmSendConfigReq(fp); 426 NewState(fp, ST_REQSENT); 427 break; 428 case ST_ACKSENT: 429 FsmInitRestartCounter(fp); 430 NewState(fp, ST_OPENED); 431 (fp->LayerUp)(fp); 432 break; 433 case ST_OPENED: 434 (fp->LayerDown)(fp); 435 FsmSendConfigReq(fp); 436 NewState(fp, ST_REQSENT); 437 break; 438 } 439 pfree(bp); 440} 441 442void 443FsmRecvConfigNak(fp, lhp, bp) /* RCN */ 444struct fsm *fp; 445struct fsmheader *lhp; 446struct mbuf *bp; 447{ 448 int plen, flen; 449 450 plen = plength(bp); 451 flen = ntohs(lhp->length) - sizeof(*lhp); 452 if (plen < flen) { 453 pfree(bp); 454 return; 455 } 456 457 /* 458 * Check and process easy case 459 */ 460 switch (fp->state) { 461 case ST_INITIAL: 462 case ST_STARTING: 463 LogPrintf(LOG_LCP, "%s: Oops, RCN in %s.\n", 464 fp->name, StateNames[fp->state]); 465 pfree(bp); 466 return; 467 case ST_CLOSED: 468 case ST_STOPPED: 469 (fp->SendTerminateAck)(fp); 470 pfree(bp); 471 return; 472 case ST_CLOSING: 473 case ST_STOPPING: 474 pfree(bp); 475 return; 476 } 477 478 (fp->DecodeConfig)(MBUF_CTOP(bp), flen, MODE_NAK); 479 480 switch (fp->state) { 481 case ST_REQSENT: 482 case ST_ACKSENT: 483 FsmInitRestartCounter(fp); 484 FsmSendConfigReq(fp); 485 break; 486 case ST_OPENED: 487 (fp->LayerDown)(fp); 488 /* Fall down */ 489 case ST_ACKRCVD: 490 FsmSendConfigReq(fp); 491 NewState(fp, ST_REQSENT); 492 break; 493 } 494 495 pfree(bp); 496} 497 498void 499FsmRecvTermReq(fp, lhp, bp) /* RTR */ 500struct fsm *fp; 501struct fsmheader *lhp; 502struct mbuf *bp; 503{ 504 switch (fp->state) { 505 case ST_INITIAL: 506 case ST_STARTING: 507 LogPrintf(LOG_LCP, "%s: Oops, RTR in %s\n", fp->name, 508 StateNames[fp->state]); 509 break; 510 case ST_CLOSED: 511 case ST_STOPPED: 512 case ST_CLOSING: 513 case ST_STOPPING: 514 case ST_REQSENT: 515 (fp->SendTerminateAck)(fp); 516 break; 517 case ST_ACKRCVD: 518 case ST_ACKSENT: 519 (fp->SendTerminateAck)(fp); 520 NewState(fp, ST_REQSENT); 521 break; 522 case ST_OPENED: 523 (fp->LayerDown)(fp); 524 /* Zero Restart counter */ 525 (fp->SendTerminateAck)(fp); 526 NewState(fp, ST_STOPPING); 527 break; 528 } 529 pfree(bp); 530} 531 532void 533FsmRecvTermAck(fp, lhp, bp) /* RTA */ 534struct fsm *fp; 535struct fsmheader *lhp; 536struct mbuf *bp; 537{ 538 switch (fp->state) { 539 case ST_CLOSING: 540 NewState(fp, ST_CLOSED); 541 (fp->LayerFinish)(fp); 542 break; 543 case ST_STOPPING: 544 NewState(fp, ST_STOPPED); 545 (fp->LayerFinish)(fp); 546 break; 547 case ST_ACKRCVD: 548 NewState(fp, ST_REQSENT); 549 break; 550 case ST_OPENED: 551 (fp->LayerDown)(fp); 552 FsmSendConfigReq(fp); 553 NewState(fp, ST_REQSENT); 554 break; 555 } 556 pfree(bp); 557} 558 559void 560FsmRecvConfigRej(fp, lhp, bp) /* RCJ */ 561struct fsm *fp; 562struct fsmheader *lhp; 563struct mbuf *bp; 564{ 565 int plen, flen; 566 567 plen = plength(bp); 568 flen = ntohs(lhp->length) - sizeof(*lhp); 569 if (plen < flen) { 570 pfree(bp); 571 return; 572 } 573 LogPrintf(LOG_LCP, "%s: RecvConfigRej.\n", fp->name); 574 575 /* 576 * Check and process easy case 577 */ 578 switch (fp->state) { 579 case ST_INITIAL: 580 case ST_STARTING: 581 LogPrintf(LOG_LCP, "%s: Oops, RCJ in %s.\n", 582 fp->name, StateNames[fp->state]); 583 pfree(bp); 584 return; 585 case ST_CLOSED: 586 case ST_STOPPED: 587 (fp->SendTerminateAck)(fp); 588 pfree(bp); 589 return; 590 case ST_CLOSING: 591 case ST_STOPPING: 592 pfree(bp); 593 return; 594 } 595 596 (fp->DecodeConfig)(MBUF_CTOP(bp), flen, MODE_REJ); 597 598 switch (fp->state) { 599 case ST_REQSENT: 600 case ST_ACKSENT: 601 FsmInitRestartCounter(fp); 602 FsmSendConfigReq(fp); 603 break; 604 case ST_OPENED: 605 (fp->LayerDown)(fp); 606 /* Fall down */ 607 case ST_ACKRCVD: 608 FsmSendConfigReq(fp); 609 NewState(fp, ST_REQSENT); 610 break; 611 } 612 pfree(bp); 613} 614 615void 616FsmRecvCodeRej(fp, lhp, bp) 617struct fsm *fp; 618struct fsmheader *lhp; 619struct mbuf *bp; 620{ 621 LogPrintf(LOG_LCP, "%s: RecvCodeRej\n", fp->name); 622 pfree(bp); 623} 624 625void 626FsmRecvProtoRej(fp, lhp, bp) 627struct fsm *fp; 628struct fsmheader *lhp; 629struct mbuf *bp; 630{ 631 u_short *sp, proto; 632 633 sp = (u_short *)MBUF_CTOP(bp); 634 proto = ntohs(*sp); 635 LogPrintf(LOG_LCP, "-- Protocol (%04x) was rejected.\n", proto); 636 637 switch (proto) { 638 case PROTO_LQR: 639 StopLqr(LQM_LQR); 640 break; 641 case PROTO_CCP: 642 fp = &CcpFsm; 643 (fp->LayerFinish)(fp); 644 switch (fp->state) { 645 case ST_CLOSED: 646 case ST_CLOSING: 647 NewState(fp, ST_CLOSED); 648 default: 649 NewState(fp, ST_STOPPED); 650 break; 651 } 652 break; 653 } 654 pfree(bp); 655} 656 657void 658FsmRecvEchoReq(fp, lhp, bp) 659struct fsm *fp; 660struct fsmheader *lhp; 661struct mbuf *bp; 662{ 663 u_char *cp; 664 u_long *lp, magic; 665 666 cp = MBUF_CTOP(bp); 667 lp = (u_long *)cp; 668 magic = ntohl(*lp); 669 if (magic != LcpInfo.his_magic) { 670 logprintf("RecvEchoReq: his magic is bad!!\n"); 671 /* XXX: We should send terminate request */ 672 } 673 674 if (fp->state == ST_OPENED) { 675 *lp = htonl(LcpInfo.want_magic); /* Insert local magic number */ 676 LogPrintf(LOG_LCP, "%s: SendEchoRep(%s)\n", fp->name, StateNames[fp->state]); 677 FsmOutput(fp, CODE_ECHOREP, lhp->id, cp, plength(bp)); 678 } 679 pfree(bp); 680} 681 682void 683FsmRecvEchoRep(fp, lhp, bp) 684struct fsm *fp; 685struct fsmheader *lhp; 686struct mbuf *bp; 687{ 688 u_long *lp, magic; 689 690 lp = (u_long *)MBUF_CTOP(bp); 691 magic = ntohl(*lp); 692 if (magic != 0 && magic != LcpInfo.his_magic) { 693 logprintf("RecvEchoRep: his magic is wrong! expect: %x got: %x\n", 694 LcpInfo.his_magic, magic); 695 /* 696 * XXX: We should send terminate request. But poor implementation 697 * may die as a result. 698 */ 699 } 700 RecvEchoLqr(bp); 701 pfree(bp); 702} 703 704void 705FsmRecvDiscReq(fp, lhp, bp) 706struct fsm *fp; 707struct fsmheader *lhp; 708struct mbuf *bp; 709{ 710 LogPrintf(LOG_LCP, "%s: RecvDiscReq\n", fp->name); 711 pfree(bp); 712} 713 714void 715FsmRecvIdent(fp, lhp, bp) 716struct fsm *fp; 717struct fsmheader *lhp; 718struct mbuf *bp; 719{ 720 LogPrintf(LOG_LCP, "%s: RecvIdent\n", fp->name); 721 pfree(bp); 722} 723 724void 725FsmRecvTimeRemain(fp, lhp, bp) 726struct fsm *fp; 727struct fsmheader *lhp; 728struct mbuf *bp; 729{ 730 LogPrintf(LOG_LCP, "%s: RecvTimeRemain\n", fp->name); 731 pfree(bp); 732} 733 734void 735FsmRecvResetReq(fp, lhp, bp) 736struct fsm *fp; 737struct fsmheader *lhp; 738struct mbuf *bp; 739{ 740 LogPrintf(LOG_LCP, "%s: RecvResetReq\n", fp->name); 741 CcpRecvResetReq(fp); 742 LogPrintf(LOG_LCP, "%s: SendResetAck\n", fp->name); 743 FsmOutput(fp, CODE_RESETACK, fp->reqid, NULL, 0); 744 pfree(bp); 745} 746 747void 748FsmRecvResetAck(fp, lhp, bp) 749struct fsm *fp; 750struct fsmheader *lhp; 751struct mbuf *bp; 752{ 753 LogPrintf(LOG_LCP, "%s: RecvResetAck\n", fp->name); 754 fp->reqid++; 755 pfree(bp); 756} 757 758struct fsmcodedesc FsmCodes[] = { 759 { FsmRecvConfigReq, "Configure Request", }, 760 { FsmRecvConfigAck, "Configure Ack", }, 761 { FsmRecvConfigNak, "Configure Nak", }, 762 { FsmRecvConfigRej, "Configure Reject", }, 763 { FsmRecvTermReq, "Terminate Request", }, 764 { FsmRecvTermAck, "Terminate Ack", }, 765 { FsmRecvCodeRej, "Code Reject", }, 766 { FsmRecvProtoRej, "Protocol Reject", }, 767 { FsmRecvEchoReq, "Echo Request", }, 768 { FsmRecvEchoRep, "Echo Reply", }, 769 { FsmRecvDiscReq, "Discard Request", }, 770 { FsmRecvIdent, "Ident", }, 771 { FsmRecvTimeRemain, "Time Remain", }, 772 { FsmRecvResetReq, "Reset Request", }, 773 { FsmRecvResetAck, "Reset Ack", }, 774}; 775 776void 777FsmInput(fp, bp) 778struct fsm *fp; 779struct mbuf *bp; 780{ 781 int len; 782 struct fsmheader *lhp; 783 struct fsmcodedesc *codep; 784 785 len = plength(bp); 786 if (len < sizeof(struct fsmheader)) { 787 pfree(bp); 788 return; 789 } 790 lhp = (struct fsmheader *)MBUF_CTOP(bp); 791 if (lhp->code == 0 || lhp->code > fp->max_code) { 792 pfree(bp); /* XXX: Should send code reject */ 793 return; 794 } 795 796 bp->offset += sizeof(struct fsmheader); 797 bp->cnt -= sizeof(struct fsmheader); 798 799 codep = FsmCodes + lhp->code - 1; 800 LogPrintf(LOG_LCP, "%s: Received %s (%d) state = %s (%d)\n", 801 fp->name, codep->name, lhp->id, StateNames[fp->state], fp->state); 802#ifdef DEBUG 803 LogMemory(); 804#endif 805 (codep->action)(fp, lhp, bp); 806#ifdef DEBUG 807 LogMemory(); 808#endif 809} 810