1af57ed9fSAtsushi Murai /* 2af57ed9fSAtsushi Murai * PPP Finite State Machine for LCP/IPCP 3af57ed9fSAtsushi Murai * 4af57ed9fSAtsushi Murai * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5af57ed9fSAtsushi Murai * 6af57ed9fSAtsushi Murai * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 7af57ed9fSAtsushi Murai * 8af57ed9fSAtsushi Murai * Redistribution and use in source and binary forms are permitted 9af57ed9fSAtsushi Murai * provided that the above copyright notice and this paragraph are 10af57ed9fSAtsushi Murai * duplicated in all such forms and that any documentation, 11af57ed9fSAtsushi Murai * advertising materials, and other materials related to such 12af57ed9fSAtsushi Murai * distribution and use acknowledge that the software was developed 13af57ed9fSAtsushi Murai * by the Internet Initiative Japan, Inc. The name of the 14af57ed9fSAtsushi Murai * IIJ may not be used to endorse or promote products derived 15af57ed9fSAtsushi Murai * from this software without specific prior written permission. 16af57ed9fSAtsushi Murai * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17af57ed9fSAtsushi Murai * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18af57ed9fSAtsushi Murai * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19af57ed9fSAtsushi Murai * 20944f7098SBrian Somers * $Id: fsm.c,v 1.15 1997/08/20 23:47:42 brian Exp $ 21af57ed9fSAtsushi Murai * 22af57ed9fSAtsushi Murai * TODO: 23af57ed9fSAtsushi Murai * o Refer loglevel for log output 24af57ed9fSAtsushi Murai * o Better option log display 25af57ed9fSAtsushi Murai */ 26af57ed9fSAtsushi Murai #include "fsm.h" 27af57ed9fSAtsushi Murai #include "hdlc.h" 28af57ed9fSAtsushi Murai #include "lqr.h" 29af57ed9fSAtsushi Murai #include "lcpproto.h" 30af57ed9fSAtsushi Murai #include "lcp.h" 31ed6a16c1SPoul-Henning Kamp #include "ccp.h" 3271144dc5SBrian Somers #include "modem.h" 3371144dc5SBrian Somers #include "loadalias.h" 3471144dc5SBrian Somers #include "vars.h" 35af57ed9fSAtsushi Murai 36af57ed9fSAtsushi Murai void FsmSendConfigReq(struct fsm * fp); 37af57ed9fSAtsushi Murai void FsmSendTerminateReq(struct fsm * fp); 38af57ed9fSAtsushi Murai void FsmInitRestartCounter(struct fsm * fp); 39af57ed9fSAtsushi Murai void FsmTimeout(struct fsm * fp); 40af57ed9fSAtsushi Murai 41ed6a16c1SPoul-Henning Kamp char const *StateNames[] = { 42af57ed9fSAtsushi Murai "Initial", "Starting", "Closed", "Stopped", "Closing", "Stopping", 43927145beSBrian Somers "Req-Sent", "Ack-Rcvd", "Ack-Sent", "Opened", 44af57ed9fSAtsushi Murai }; 45af57ed9fSAtsushi Murai 4671144dc5SBrian Somers static void 47944f7098SBrian Somers StoppedTimeout(struct fsm * fp) 4871144dc5SBrian Somers { 49cb611434SBrian Somers LogPrintf(fp->LogLevel, "Stopped timer expired\n"); 5071144dc5SBrian Somers if (modem != -1) 5171144dc5SBrian Somers DownConnection(); 5271144dc5SBrian Somers else 5371144dc5SBrian Somers FsmDown(fp); 5471144dc5SBrian Somers } 5571144dc5SBrian Somers 56af57ed9fSAtsushi Murai void 57944f7098SBrian Somers FsmInit(struct fsm * fp) 58af57ed9fSAtsushi Murai { 59927145beSBrian Somers LogPrintf(LogDEBUG, "FsmInit\n"); 60af57ed9fSAtsushi Murai fp->state = ST_INITIAL; 61af57ed9fSAtsushi Murai fp->reqid = 1; 62af57ed9fSAtsushi Murai fp->restart = 1; 63af57ed9fSAtsushi Murai fp->maxconfig = 3; 64af57ed9fSAtsushi Murai } 65af57ed9fSAtsushi Murai 66af57ed9fSAtsushi Murai void 67944f7098SBrian Somers NewState(struct fsm * fp, int new) 68af57ed9fSAtsushi Murai { 69cb611434SBrian Somers LogPrintf(fp->LogLevel, "State change %s --> %s\n", 70927145beSBrian Somers StateNames[fp->state], StateNames[new]); 71cb611434SBrian Somers if (fp->state == ST_STOPPED && fp->StoppedTimer.state == TIMER_RUNNING) 72cb611434SBrian Somers StopTimer(&fp->StoppedTimer); 73af57ed9fSAtsushi Murai fp->state = new; 7471144dc5SBrian Somers if ((new >= ST_INITIAL && new <= ST_STOPPED) || (new == ST_OPENED)) { 75af57ed9fSAtsushi Murai StopTimer(&fp->FsmTimer); 76cb611434SBrian Somers if (new == ST_STOPPED && fp->StoppedTimer.load) { 77cb611434SBrian Somers fp->StoppedTimer.state = TIMER_STOPPED; 78cb611434SBrian Somers fp->StoppedTimer.func = StoppedTimeout; 79cb611434SBrian Somers fp->StoppedTimer.arg = (void *) fp; 80cb611434SBrian Somers StartTimer(&fp->StoppedTimer); 8171144dc5SBrian Somers } 8271144dc5SBrian Somers } 83af57ed9fSAtsushi Murai } 84af57ed9fSAtsushi Murai 85af57ed9fSAtsushi Murai void 86944f7098SBrian Somers FsmOutput(struct fsm * fp, u_int code, u_int id, u_char * ptr, int count) 87af57ed9fSAtsushi Murai { 88af57ed9fSAtsushi Murai int plen; 89af57ed9fSAtsushi Murai struct fsmheader lh; 90af57ed9fSAtsushi Murai struct mbuf *bp; 91af57ed9fSAtsushi Murai 92af57ed9fSAtsushi Murai plen = sizeof(struct fsmheader) + count; 93af57ed9fSAtsushi Murai lh.code = code; 94af57ed9fSAtsushi Murai lh.id = id; 95af57ed9fSAtsushi Murai lh.length = htons(plen); 96af57ed9fSAtsushi Murai bp = mballoc(plen, MB_FSM); 97af57ed9fSAtsushi Murai bcopy(&lh, MBUF_CTOP(bp), sizeof(struct fsmheader)); 98af57ed9fSAtsushi Murai if (count) 99af57ed9fSAtsushi Murai bcopy(ptr, MBUF_CTOP(bp) + sizeof(struct fsmheader), count); 100927145beSBrian Somers LogDumpBp(LogDEBUG, "FsmOutput", bp); 10176bd0c0aSDoug Rabson HdlcOutput(PRI_LINK, fp->proto, bp); 102af57ed9fSAtsushi Murai } 103af57ed9fSAtsushi Murai 104af57ed9fSAtsushi Murai void 105944f7098SBrian Somers FsmOpen(struct fsm * fp) 106af57ed9fSAtsushi Murai { 107af57ed9fSAtsushi Murai switch (fp->state) { 108af57ed9fSAtsushi Murai case ST_INITIAL: 109af57ed9fSAtsushi Murai (fp->LayerStart) (fp); 110af57ed9fSAtsushi Murai NewState(fp, ST_STARTING); 111af57ed9fSAtsushi Murai break; 112af57ed9fSAtsushi Murai case ST_STARTING: 113af57ed9fSAtsushi Murai break; 114af57ed9fSAtsushi Murai case ST_CLOSED: 115af57ed9fSAtsushi Murai if (fp->open_mode == OPEN_PASSIVE) { 116af57ed9fSAtsushi Murai NewState(fp, ST_STOPPED); 117af57ed9fSAtsushi Murai } else { 118af57ed9fSAtsushi Murai FsmInitRestartCounter(fp); 119af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 120af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 121af57ed9fSAtsushi Murai } 122af57ed9fSAtsushi Murai break; 123af57ed9fSAtsushi Murai case ST_STOPPED: /* XXX: restart option */ 124af57ed9fSAtsushi Murai case ST_REQSENT: 125af57ed9fSAtsushi Murai case ST_ACKRCVD: 126af57ed9fSAtsushi Murai case ST_ACKSENT: 127af57ed9fSAtsushi Murai case ST_OPENED: /* XXX: restart option */ 128af57ed9fSAtsushi Murai break; 129af57ed9fSAtsushi Murai case ST_CLOSING: /* XXX: restart option */ 130af57ed9fSAtsushi Murai case ST_STOPPING: /* XXX: restart option */ 131af57ed9fSAtsushi Murai NewState(fp, ST_STOPPING); 132af57ed9fSAtsushi Murai break; 133af57ed9fSAtsushi Murai } 134af57ed9fSAtsushi Murai } 135af57ed9fSAtsushi Murai 136af57ed9fSAtsushi Murai void 137944f7098SBrian Somers FsmUp(struct fsm * fp) 138af57ed9fSAtsushi Murai { 139af57ed9fSAtsushi Murai switch (fp->state) { 140af57ed9fSAtsushi Murai case ST_INITIAL: 141af57ed9fSAtsushi Murai NewState(fp, ST_CLOSED); 142af57ed9fSAtsushi Murai break; 143af57ed9fSAtsushi Murai case ST_STARTING: 144af57ed9fSAtsushi Murai FsmInitRestartCounter(fp); 145af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 146af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 147af57ed9fSAtsushi Murai break; 148af57ed9fSAtsushi Murai default: 149cb611434SBrian Somers LogPrintf(fp->LogLevel, "Oops, Up at %s\n", StateNames[fp->state]); 150af57ed9fSAtsushi Murai break; 151af57ed9fSAtsushi Murai } 152af57ed9fSAtsushi Murai } 153af57ed9fSAtsushi Murai 154af57ed9fSAtsushi Murai void 155944f7098SBrian Somers FsmDown(struct fsm * fp) 156af57ed9fSAtsushi Murai { 157af57ed9fSAtsushi Murai switch (fp->state) { 158af57ed9fSAtsushi Murai case ST_CLOSED: 159af57ed9fSAtsushi Murai case ST_CLOSING: 160af57ed9fSAtsushi Murai NewState(fp, ST_INITIAL); 161af57ed9fSAtsushi Murai break; 162af57ed9fSAtsushi Murai case ST_STOPPED: 163af57ed9fSAtsushi Murai (fp->LayerStart) (fp); 164af57ed9fSAtsushi Murai /* Fall into.. */ 165af57ed9fSAtsushi Murai case ST_STOPPING: 166af57ed9fSAtsushi Murai case ST_REQSENT: 167af57ed9fSAtsushi Murai case ST_ACKRCVD: 168af57ed9fSAtsushi Murai case ST_ACKSENT: 169af57ed9fSAtsushi Murai NewState(fp, ST_STARTING); 170af57ed9fSAtsushi Murai break; 171af57ed9fSAtsushi Murai case ST_OPENED: 172af57ed9fSAtsushi Murai (fp->LayerDown) (fp); 173af57ed9fSAtsushi Murai NewState(fp, ST_STARTING); 174af57ed9fSAtsushi Murai break; 175af57ed9fSAtsushi Murai } 176af57ed9fSAtsushi Murai } 177af57ed9fSAtsushi Murai 178af57ed9fSAtsushi Murai void 179944f7098SBrian Somers FsmClose(struct fsm * fp) 180af57ed9fSAtsushi Murai { 181af57ed9fSAtsushi Murai switch (fp->state) { 182af57ed9fSAtsushi Murai case ST_STARTING: 183af57ed9fSAtsushi Murai NewState(fp, ST_INITIAL); 184af57ed9fSAtsushi Murai break; 185af57ed9fSAtsushi Murai case ST_STOPPED: 186af57ed9fSAtsushi Murai NewState(fp, ST_CLOSED); 187af57ed9fSAtsushi Murai break; 188af57ed9fSAtsushi Murai case ST_STOPPING: 189af57ed9fSAtsushi Murai NewState(fp, ST_CLOSING); 190af57ed9fSAtsushi Murai break; 191af57ed9fSAtsushi Murai case ST_OPENED: 192af57ed9fSAtsushi Murai (fp->LayerDown) (fp); 193af57ed9fSAtsushi Murai /* Fall down */ 194af57ed9fSAtsushi Murai case ST_REQSENT: 195af57ed9fSAtsushi Murai case ST_ACKRCVD: 196af57ed9fSAtsushi Murai case ST_ACKSENT: 197af57ed9fSAtsushi Murai FsmInitRestartCounter(fp); 198af57ed9fSAtsushi Murai FsmSendTerminateReq(fp); 199af57ed9fSAtsushi Murai NewState(fp, ST_CLOSING); 200af57ed9fSAtsushi Murai break; 201af57ed9fSAtsushi Murai } 202af57ed9fSAtsushi Murai } 203af57ed9fSAtsushi Murai 204af57ed9fSAtsushi Murai /* 205af57ed9fSAtsushi Murai * Send functions 206af57ed9fSAtsushi Murai */ 207af57ed9fSAtsushi Murai void 208944f7098SBrian Somers FsmSendConfigReq(struct fsm * fp) 209af57ed9fSAtsushi Murai { 210af57ed9fSAtsushi Murai if (--fp->maxconfig > 0) { 211af57ed9fSAtsushi Murai (fp->SendConfigReq) (fp); 212af57ed9fSAtsushi Murai StartTimer(&fp->FsmTimer); /* Start restart timer */ 213af57ed9fSAtsushi Murai fp->restart--; /* Decrement restart counter */ 214af57ed9fSAtsushi Murai } else { 215af57ed9fSAtsushi Murai FsmClose(fp); 216af57ed9fSAtsushi Murai } 217af57ed9fSAtsushi Murai } 218af57ed9fSAtsushi Murai 219af57ed9fSAtsushi Murai void 220944f7098SBrian Somers FsmSendTerminateReq(struct fsm * fp) 221af57ed9fSAtsushi Murai { 222cb611434SBrian Somers LogPrintf(fp->LogLevel, "SendTerminateReq.\n"); 223af57ed9fSAtsushi Murai FsmOutput(fp, CODE_TERMREQ, fp->reqid++, NULL, 0); 224af57ed9fSAtsushi Murai (fp->SendTerminateReq) (fp); 225af57ed9fSAtsushi Murai StartTimer(&fp->FsmTimer); /* Start restart timer */ 226af57ed9fSAtsushi Murai fp->restart--; /* Decrement restart counter */ 227af57ed9fSAtsushi Murai } 228af57ed9fSAtsushi Murai 229af57ed9fSAtsushi Murai static void 230944f7098SBrian Somers FsmSendConfigAck(struct fsm * fp, 231944f7098SBrian Somers struct fsmheader * lhp, 232944f7098SBrian Somers u_char * option, 233944f7098SBrian Somers int count) 234af57ed9fSAtsushi Murai { 235cb611434SBrian Somers LogPrintf(fp->LogLevel, "SendConfigAck(%s)\n", StateNames[fp->state]); 23653c9f6c0SAtsushi Murai (fp->DecodeConfig) (option, count, MODE_NOP); 237af57ed9fSAtsushi Murai FsmOutput(fp, CODE_CONFIGACK, lhp->id, option, count); 238af57ed9fSAtsushi Murai } 239af57ed9fSAtsushi Murai 240af57ed9fSAtsushi Murai static void 241944f7098SBrian Somers FsmSendConfigRej(struct fsm * fp, 242944f7098SBrian Somers struct fsmheader * lhp, 243944f7098SBrian Somers u_char * option, 244944f7098SBrian Somers int count) 245af57ed9fSAtsushi Murai { 246cb611434SBrian Somers LogPrintf(fp->LogLevel, "SendConfigRej(%s)\n", StateNames[fp->state]); 24753c9f6c0SAtsushi Murai (fp->DecodeConfig) (option, count, MODE_NOP); 248af57ed9fSAtsushi Murai FsmOutput(fp, CODE_CONFIGREJ, lhp->id, option, count); 249af57ed9fSAtsushi Murai } 250af57ed9fSAtsushi Murai 251af57ed9fSAtsushi Murai static void 252944f7098SBrian Somers FsmSendConfigNak(struct fsm * fp, 253944f7098SBrian Somers struct fsmheader * lhp, 254944f7098SBrian Somers u_char * option, 255944f7098SBrian Somers int count) 256af57ed9fSAtsushi Murai { 257cb611434SBrian Somers LogPrintf(fp->LogLevel, "SendConfigNak(%s)\n", StateNames[fp->state]); 25853c9f6c0SAtsushi Murai (fp->DecodeConfig) (option, count, MODE_NOP); 259af57ed9fSAtsushi Murai FsmOutput(fp, CODE_CONFIGNAK, lhp->id, option, count); 260af57ed9fSAtsushi Murai } 261af57ed9fSAtsushi Murai 262af57ed9fSAtsushi Murai /* 263af57ed9fSAtsushi Murai * Timeout actions 264af57ed9fSAtsushi Murai */ 265af57ed9fSAtsushi Murai void 266944f7098SBrian Somers FsmTimeout(struct fsm * fp) 267af57ed9fSAtsushi Murai { 268af57ed9fSAtsushi Murai if (fp->restart) { 269af57ed9fSAtsushi Murai switch (fp->state) { 270af57ed9fSAtsushi Murai case ST_CLOSING: 271af57ed9fSAtsushi Murai case ST_STOPPING: 272af57ed9fSAtsushi Murai FsmSendTerminateReq(fp); 273af57ed9fSAtsushi Murai break; 274af57ed9fSAtsushi Murai case ST_REQSENT: 275af57ed9fSAtsushi Murai case ST_ACKSENT: 276af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 277af57ed9fSAtsushi Murai break; 278af57ed9fSAtsushi Murai case ST_ACKRCVD: 279af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 280af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 281af57ed9fSAtsushi Murai break; 282af57ed9fSAtsushi Murai } 283af57ed9fSAtsushi Murai StartTimer(&fp->FsmTimer); 284af57ed9fSAtsushi Murai } else { 285af57ed9fSAtsushi Murai switch (fp->state) { 286af57ed9fSAtsushi Murai case ST_CLOSING: 287af57ed9fSAtsushi Murai NewState(fp, ST_CLOSED); 288af57ed9fSAtsushi Murai (fp->LayerFinish) (fp); 289af57ed9fSAtsushi Murai break; 290af57ed9fSAtsushi Murai case ST_STOPPING: 291af57ed9fSAtsushi Murai NewState(fp, ST_STOPPED); 292af57ed9fSAtsushi Murai (fp->LayerFinish) (fp); 293af57ed9fSAtsushi Murai break; 294af57ed9fSAtsushi Murai case ST_REQSENT: /* XXX: 3p */ 295af57ed9fSAtsushi Murai case ST_ACKSENT: 296af57ed9fSAtsushi Murai case ST_ACKRCVD: 297af57ed9fSAtsushi Murai NewState(fp, ST_STOPPED); 298af57ed9fSAtsushi Murai (fp->LayerFinish) (fp); 299af57ed9fSAtsushi Murai break; 300af57ed9fSAtsushi Murai } 301af57ed9fSAtsushi Murai } 302af57ed9fSAtsushi Murai } 303af57ed9fSAtsushi Murai 304af57ed9fSAtsushi Murai void 305944f7098SBrian Somers FsmInitRestartCounter(struct fsm * fp) 306af57ed9fSAtsushi Murai { 307af57ed9fSAtsushi Murai StopTimer(&fp->FsmTimer); 308af57ed9fSAtsushi Murai fp->FsmTimer.state = TIMER_STOPPED; 309af57ed9fSAtsushi Murai fp->FsmTimer.func = FsmTimeout; 310af57ed9fSAtsushi Murai fp->FsmTimer.arg = (void *) fp; 311af57ed9fSAtsushi Murai (fp->InitRestartCounter) (fp); 312af57ed9fSAtsushi Murai } 313af57ed9fSAtsushi Murai 314af57ed9fSAtsushi Murai /* 315af57ed9fSAtsushi Murai * Actions when receive packets 316af57ed9fSAtsushi Murai */ 317af57ed9fSAtsushi Murai void 318944f7098SBrian Somers FsmRecvConfigReq(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 319944f7098SBrian Somers /* RCR */ 320af57ed9fSAtsushi Murai { 32153c9f6c0SAtsushi Murai int plen, flen; 322af57ed9fSAtsushi Murai int ackaction = 0; 323af57ed9fSAtsushi Murai 324af57ed9fSAtsushi Murai plen = plength(bp); 32553c9f6c0SAtsushi Murai flen = ntohs(lhp->length) - sizeof(*lhp); 32653c9f6c0SAtsushi Murai if (plen < flen) { 327927145beSBrian Somers LogPrintf(LogERROR, "FsmRecvConfigReq: plen (%d) < flen (%d)", plen, flen); 328af57ed9fSAtsushi Murai pfree(bp); 329af57ed9fSAtsushi Murai return; 330af57ed9fSAtsushi Murai } 331af57ed9fSAtsushi Murai 332af57ed9fSAtsushi Murai /* 333af57ed9fSAtsushi Murai * Check and process easy case 334af57ed9fSAtsushi Murai */ 335af57ed9fSAtsushi Murai switch (fp->state) { 336af57ed9fSAtsushi Murai case ST_INITIAL: 337af57ed9fSAtsushi Murai case ST_STARTING: 338cb611434SBrian Somers LogPrintf(fp->LogLevel, "Oops, RCR in %s.\n", StateNames[fp->state]); 339af57ed9fSAtsushi Murai pfree(bp); 340af57ed9fSAtsushi Murai return; 341af57ed9fSAtsushi Murai case ST_CLOSED: 342af57ed9fSAtsushi Murai (fp->SendTerminateAck) (fp); 343af57ed9fSAtsushi Murai pfree(bp); 344af57ed9fSAtsushi Murai return; 345af57ed9fSAtsushi Murai case ST_CLOSING: 346af57ed9fSAtsushi Murai case ST_STOPPING: 347927145beSBrian Somers LogPrintf(LogERROR, "Got ConfigReq while state = %d\n", fp->state); 348af57ed9fSAtsushi Murai pfree(bp); 349af57ed9fSAtsushi Murai return; 350af57ed9fSAtsushi Murai } 351af57ed9fSAtsushi Murai 35253c9f6c0SAtsushi Murai (fp->DecodeConfig) (MBUF_CTOP(bp), flen, MODE_REQ); 353af57ed9fSAtsushi Murai 354af57ed9fSAtsushi Murai if (nakp == NakBuff && rejp == RejBuff) 355af57ed9fSAtsushi Murai ackaction = 1; 356af57ed9fSAtsushi Murai 357af57ed9fSAtsushi Murai switch (fp->state) { 358af57ed9fSAtsushi Murai case ST_OPENED: 359af57ed9fSAtsushi Murai (fp->LayerDown) (fp); 360af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 361af57ed9fSAtsushi Murai break; 362af57ed9fSAtsushi Murai case ST_STOPPED: 363af57ed9fSAtsushi Murai FsmInitRestartCounter(fp); 364af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 365af57ed9fSAtsushi Murai break; 366af57ed9fSAtsushi Murai } 367af57ed9fSAtsushi Murai 368af57ed9fSAtsushi Murai if (rejp != RejBuff) 369af57ed9fSAtsushi Murai FsmSendConfigRej(fp, lhp, RejBuff, rejp - RejBuff); 370af57ed9fSAtsushi Murai if (nakp != NakBuff) 371af57ed9fSAtsushi Murai FsmSendConfigNak(fp, lhp, NakBuff, nakp - NakBuff); 372af57ed9fSAtsushi Murai if (ackaction) 373af57ed9fSAtsushi Murai FsmSendConfigAck(fp, lhp, AckBuff, ackp - AckBuff); 374af57ed9fSAtsushi Murai 375af57ed9fSAtsushi Murai switch (fp->state) { 376af57ed9fSAtsushi Murai case ST_STOPPED: 377af57ed9fSAtsushi Murai case ST_OPENED: 378af57ed9fSAtsushi Murai if (ackaction) 379af57ed9fSAtsushi Murai NewState(fp, ST_ACKSENT); 380af57ed9fSAtsushi Murai else 381af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 382af57ed9fSAtsushi Murai break; 383af57ed9fSAtsushi Murai case ST_REQSENT: 384af57ed9fSAtsushi Murai if (ackaction) 385af57ed9fSAtsushi Murai NewState(fp, ST_ACKSENT); 386af57ed9fSAtsushi Murai break; 387af57ed9fSAtsushi Murai case ST_ACKRCVD: 388af57ed9fSAtsushi Murai if (ackaction) { 389af57ed9fSAtsushi Murai NewState(fp, ST_OPENED); 390af57ed9fSAtsushi Murai (fp->LayerUp) (fp); 391af57ed9fSAtsushi Murai } 392af57ed9fSAtsushi Murai break; 393af57ed9fSAtsushi Murai case ST_ACKSENT: 394af57ed9fSAtsushi Murai if (!ackaction) 395af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 396af57ed9fSAtsushi Murai break; 397af57ed9fSAtsushi Murai } 398af57ed9fSAtsushi Murai pfree(bp); 399af57ed9fSAtsushi Murai } 400af57ed9fSAtsushi Murai 401af57ed9fSAtsushi Murai void 402944f7098SBrian Somers FsmRecvConfigAck(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 403944f7098SBrian Somers /* RCA */ 404af57ed9fSAtsushi Murai { 405af57ed9fSAtsushi Murai switch (fp->state) { 406af57ed9fSAtsushi Murai case ST_CLOSED: 407af57ed9fSAtsushi Murai case ST_STOPPED: 408af57ed9fSAtsushi Murai (fp->SendTerminateAck) (fp); 409af57ed9fSAtsushi Murai break; 410af57ed9fSAtsushi Murai case ST_CLOSING: 411af57ed9fSAtsushi Murai case ST_STOPPING: 412af57ed9fSAtsushi Murai break; 413af57ed9fSAtsushi Murai case ST_REQSENT: 414af57ed9fSAtsushi Murai FsmInitRestartCounter(fp); 415af57ed9fSAtsushi Murai NewState(fp, ST_ACKRCVD); 416af57ed9fSAtsushi Murai break; 417af57ed9fSAtsushi Murai case ST_ACKRCVD: 418af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 419af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 420af57ed9fSAtsushi Murai break; 421af57ed9fSAtsushi Murai case ST_ACKSENT: 422af57ed9fSAtsushi Murai FsmInitRestartCounter(fp); 423af57ed9fSAtsushi Murai NewState(fp, ST_OPENED); 424af57ed9fSAtsushi Murai (fp->LayerUp) (fp); 425af57ed9fSAtsushi Murai break; 426af57ed9fSAtsushi Murai case ST_OPENED: 427af57ed9fSAtsushi Murai (fp->LayerDown) (fp); 428af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 429af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 430af57ed9fSAtsushi Murai break; 431af57ed9fSAtsushi Murai } 432af57ed9fSAtsushi Murai pfree(bp); 433af57ed9fSAtsushi Murai } 434af57ed9fSAtsushi Murai 435af57ed9fSAtsushi Murai void 436944f7098SBrian Somers FsmRecvConfigNak(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 437944f7098SBrian Somers /* RCN */ 438af57ed9fSAtsushi Murai { 43953c9f6c0SAtsushi Murai int plen, flen; 440af57ed9fSAtsushi Murai 441af57ed9fSAtsushi Murai plen = plength(bp); 44253c9f6c0SAtsushi Murai flen = ntohs(lhp->length) - sizeof(*lhp); 44353c9f6c0SAtsushi Murai if (plen < flen) { 444af57ed9fSAtsushi Murai pfree(bp); 445af57ed9fSAtsushi Murai return; 446af57ed9fSAtsushi Murai } 447af57ed9fSAtsushi Murai 448af57ed9fSAtsushi Murai /* 449af57ed9fSAtsushi Murai * Check and process easy case 450af57ed9fSAtsushi Murai */ 451af57ed9fSAtsushi Murai switch (fp->state) { 452af57ed9fSAtsushi Murai case ST_INITIAL: 453af57ed9fSAtsushi Murai case ST_STARTING: 454cb611434SBrian Somers LogPrintf(fp->LogLevel, "Oops, RCN in %s.\n", StateNames[fp->state]); 455af57ed9fSAtsushi Murai pfree(bp); 456af57ed9fSAtsushi Murai return; 457af57ed9fSAtsushi Murai case ST_CLOSED: 458af57ed9fSAtsushi Murai case ST_STOPPED: 459af57ed9fSAtsushi Murai (fp->SendTerminateAck) (fp); 460af57ed9fSAtsushi Murai pfree(bp); 461af57ed9fSAtsushi Murai return; 462af57ed9fSAtsushi Murai case ST_CLOSING: 463af57ed9fSAtsushi Murai case ST_STOPPING: 464af57ed9fSAtsushi Murai pfree(bp); 465af57ed9fSAtsushi Murai return; 466af57ed9fSAtsushi Murai } 467af57ed9fSAtsushi Murai 46853c9f6c0SAtsushi Murai (fp->DecodeConfig) (MBUF_CTOP(bp), flen, MODE_NAK); 469af57ed9fSAtsushi Murai 470af57ed9fSAtsushi Murai switch (fp->state) { 471af57ed9fSAtsushi Murai case ST_REQSENT: 472af57ed9fSAtsushi Murai case ST_ACKSENT: 473af57ed9fSAtsushi Murai FsmInitRestartCounter(fp); 474af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 475af57ed9fSAtsushi Murai break; 476af57ed9fSAtsushi Murai case ST_OPENED: 477af57ed9fSAtsushi Murai (fp->LayerDown) (fp); 478af57ed9fSAtsushi Murai /* Fall down */ 479af57ed9fSAtsushi Murai case ST_ACKRCVD: 480af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 481af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 482af57ed9fSAtsushi Murai break; 483af57ed9fSAtsushi Murai } 484af57ed9fSAtsushi Murai 485af57ed9fSAtsushi Murai pfree(bp); 486af57ed9fSAtsushi Murai } 487af57ed9fSAtsushi Murai 488af57ed9fSAtsushi Murai void 489944f7098SBrian Somers FsmRecvTermReq(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 490944f7098SBrian Somers /* RTR */ 491af57ed9fSAtsushi Murai { 492af57ed9fSAtsushi Murai switch (fp->state) { 493af57ed9fSAtsushi Murai case ST_INITIAL: 494af57ed9fSAtsushi Murai case ST_STARTING: 495cb611434SBrian Somers LogPrintf(fp->LogLevel, "Oops, RTR in %s\n", StateNames[fp->state]); 496af57ed9fSAtsushi Murai break; 497af57ed9fSAtsushi Murai case ST_CLOSED: 498af57ed9fSAtsushi Murai case ST_STOPPED: 499af57ed9fSAtsushi Murai case ST_CLOSING: 500af57ed9fSAtsushi Murai case ST_STOPPING: 501af57ed9fSAtsushi Murai case ST_REQSENT: 502af57ed9fSAtsushi Murai (fp->SendTerminateAck) (fp); 503af57ed9fSAtsushi Murai break; 504af57ed9fSAtsushi Murai case ST_ACKRCVD: 505af57ed9fSAtsushi Murai case ST_ACKSENT: 506af57ed9fSAtsushi Murai (fp->SendTerminateAck) (fp); 507af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 508af57ed9fSAtsushi Murai break; 509af57ed9fSAtsushi Murai case ST_OPENED: 5108f2fa0eeSBrian Somers (fp->LayerDown) (fp); 511af57ed9fSAtsushi Murai (fp->SendTerminateAck) (fp); 5128f2fa0eeSBrian Somers StartTimer(&fp->FsmTimer); /* Start restart timer */ 5138f2fa0eeSBrian Somers fp->restart = 0; 5148f2fa0eeSBrian Somers NewState(fp, ST_STOPPING); 515af57ed9fSAtsushi Murai break; 516af57ed9fSAtsushi Murai } 517af57ed9fSAtsushi Murai pfree(bp); 518af57ed9fSAtsushi Murai } 519af57ed9fSAtsushi Murai 520af57ed9fSAtsushi Murai void 521944f7098SBrian Somers FsmRecvTermAck(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 522944f7098SBrian Somers /* RTA */ 523af57ed9fSAtsushi Murai { 524af57ed9fSAtsushi Murai switch (fp->state) { 525af57ed9fSAtsushi Murai case ST_CLOSING: 526af57ed9fSAtsushi Murai NewState(fp, ST_CLOSED); 527af57ed9fSAtsushi Murai (fp->LayerFinish) (fp); 528af57ed9fSAtsushi Murai break; 529af57ed9fSAtsushi Murai case ST_STOPPING: 530af57ed9fSAtsushi Murai NewState(fp, ST_STOPPED); 531af57ed9fSAtsushi Murai (fp->LayerFinish) (fp); 532af57ed9fSAtsushi Murai break; 533af57ed9fSAtsushi Murai case ST_ACKRCVD: 534af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 535af57ed9fSAtsushi Murai break; 536af57ed9fSAtsushi Murai case ST_OPENED: 537af57ed9fSAtsushi Murai (fp->LayerDown) (fp); 538af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 539af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 540af57ed9fSAtsushi Murai break; 541af57ed9fSAtsushi Murai } 542af57ed9fSAtsushi Murai pfree(bp); 543af57ed9fSAtsushi Murai } 544af57ed9fSAtsushi Murai 545af57ed9fSAtsushi Murai void 546944f7098SBrian Somers FsmRecvConfigRej(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 547944f7098SBrian Somers /* RCJ */ 548af57ed9fSAtsushi Murai { 54953c9f6c0SAtsushi Murai int plen, flen; 550af57ed9fSAtsushi Murai 551af57ed9fSAtsushi Murai plen = plength(bp); 55253c9f6c0SAtsushi Murai flen = ntohs(lhp->length) - sizeof(*lhp); 55353c9f6c0SAtsushi Murai if (plen < flen) { 554af57ed9fSAtsushi Murai pfree(bp); 555af57ed9fSAtsushi Murai return; 556af57ed9fSAtsushi Murai } 557cb611434SBrian Somers LogPrintf(fp->LogLevel, "RecvConfigRej.\n"); 558af57ed9fSAtsushi Murai 559af57ed9fSAtsushi Murai /* 560af57ed9fSAtsushi Murai * Check and process easy case 561af57ed9fSAtsushi Murai */ 562af57ed9fSAtsushi Murai switch (fp->state) { 563af57ed9fSAtsushi Murai case ST_INITIAL: 564af57ed9fSAtsushi Murai case ST_STARTING: 565cb611434SBrian Somers LogPrintf(fp->LogLevel, "Oops, RCJ in %s.\n", StateNames[fp->state]); 566af57ed9fSAtsushi Murai pfree(bp); 567af57ed9fSAtsushi Murai return; 568af57ed9fSAtsushi Murai case ST_CLOSED: 569af57ed9fSAtsushi Murai case ST_STOPPED: 570af57ed9fSAtsushi Murai (fp->SendTerminateAck) (fp); 571af57ed9fSAtsushi Murai pfree(bp); 572af57ed9fSAtsushi Murai return; 573af57ed9fSAtsushi Murai case ST_CLOSING: 574af57ed9fSAtsushi Murai case ST_STOPPING: 575af57ed9fSAtsushi Murai pfree(bp); 576af57ed9fSAtsushi Murai return; 577af57ed9fSAtsushi Murai } 578af57ed9fSAtsushi Murai 57953c9f6c0SAtsushi Murai (fp->DecodeConfig) (MBUF_CTOP(bp), flen, MODE_REJ); 580af57ed9fSAtsushi Murai 581af57ed9fSAtsushi Murai switch (fp->state) { 582af57ed9fSAtsushi Murai case ST_REQSENT: 583af57ed9fSAtsushi Murai case ST_ACKSENT: 584af57ed9fSAtsushi Murai FsmInitRestartCounter(fp); 585af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 586af57ed9fSAtsushi Murai break; 587af57ed9fSAtsushi Murai case ST_OPENED: 588af57ed9fSAtsushi Murai (fp->LayerDown) (fp); 589af57ed9fSAtsushi Murai /* Fall down */ 590af57ed9fSAtsushi Murai case ST_ACKRCVD: 591af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 592af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 593af57ed9fSAtsushi Murai break; 594af57ed9fSAtsushi Murai } 595af57ed9fSAtsushi Murai pfree(bp); 596af57ed9fSAtsushi Murai } 597af57ed9fSAtsushi Murai 598af57ed9fSAtsushi Murai void 599944f7098SBrian Somers FsmRecvCodeRej(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 600af57ed9fSAtsushi Murai { 601cb611434SBrian Somers LogPrintf(fp->LogLevel, "RecvCodeRej\n"); 602af57ed9fSAtsushi Murai pfree(bp); 603af57ed9fSAtsushi Murai } 604af57ed9fSAtsushi Murai 605af57ed9fSAtsushi Murai void 606944f7098SBrian Somers FsmRecvProtoRej(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 607af57ed9fSAtsushi Murai { 608af57ed9fSAtsushi Murai u_short *sp, proto; 609af57ed9fSAtsushi Murai 610af57ed9fSAtsushi Murai sp = (u_short *) MBUF_CTOP(bp); 611af57ed9fSAtsushi Murai proto = ntohs(*sp); 612cb611434SBrian Somers LogPrintf(fp->LogLevel, "-- Protocol (%04x) was rejected.\n", proto); 613af57ed9fSAtsushi Murai 614af57ed9fSAtsushi Murai switch (proto) { 615af57ed9fSAtsushi Murai case PROTO_LQR: 616af57ed9fSAtsushi Murai StopLqr(LQM_LQR); 617af57ed9fSAtsushi Murai break; 618af57ed9fSAtsushi Murai case PROTO_CCP: 619af57ed9fSAtsushi Murai fp = &CcpFsm; 620af57ed9fSAtsushi Murai (fp->LayerFinish) (fp); 621af57ed9fSAtsushi Murai switch (fp->state) { 622af57ed9fSAtsushi Murai case ST_CLOSED: 623af57ed9fSAtsushi Murai case ST_CLOSING: 624af57ed9fSAtsushi Murai NewState(fp, ST_CLOSED); 625af57ed9fSAtsushi Murai default: 626af57ed9fSAtsushi Murai NewState(fp, ST_STOPPED); 627af57ed9fSAtsushi Murai break; 628af57ed9fSAtsushi Murai } 629af57ed9fSAtsushi Murai break; 630af57ed9fSAtsushi Murai } 631af57ed9fSAtsushi Murai pfree(bp); 632af57ed9fSAtsushi Murai } 633af57ed9fSAtsushi Murai 634af57ed9fSAtsushi Murai void 635944f7098SBrian Somers FsmRecvEchoReq(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 636af57ed9fSAtsushi Murai { 637af57ed9fSAtsushi Murai u_char *cp; 638af57ed9fSAtsushi Murai u_long *lp, magic; 639af57ed9fSAtsushi Murai 640af57ed9fSAtsushi Murai cp = MBUF_CTOP(bp); 641af57ed9fSAtsushi Murai lp = (u_long *) cp; 642af57ed9fSAtsushi Murai magic = ntohl(*lp); 643af57ed9fSAtsushi Murai if (magic != LcpInfo.his_magic) { 644927145beSBrian Somers LogPrintf(LogERROR, "RecvEchoReq: his magic is bad!!\n"); 645af57ed9fSAtsushi Murai /* XXX: We should send terminate request */ 646af57ed9fSAtsushi Murai } 647af57ed9fSAtsushi Murai if (fp->state == ST_OPENED) { 648af57ed9fSAtsushi Murai *lp = htonl(LcpInfo.want_magic); /* Insert local magic number */ 649cb611434SBrian Somers LogPrintf(fp->LogLevel, "SendEchoRep(%s)\n", StateNames[fp->state]); 650af57ed9fSAtsushi Murai FsmOutput(fp, CODE_ECHOREP, lhp->id, cp, plength(bp)); 651af57ed9fSAtsushi Murai } 652af57ed9fSAtsushi Murai pfree(bp); 653af57ed9fSAtsushi Murai } 654af57ed9fSAtsushi Murai 655af57ed9fSAtsushi Murai void 656944f7098SBrian Somers FsmRecvEchoRep(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 657af57ed9fSAtsushi Murai { 658af57ed9fSAtsushi Murai u_long *lp, magic; 659af57ed9fSAtsushi Murai 660af57ed9fSAtsushi Murai lp = (u_long *) MBUF_CTOP(bp); 661af57ed9fSAtsushi Murai magic = ntohl(*lp); 66285c59f05SJoerg Wunsch /* 66385c59f05SJoerg Wunsch * Tolerate echo replies with either magic number 66485c59f05SJoerg Wunsch */ 66585c59f05SJoerg Wunsch if (magic != 0 && magic != LcpInfo.his_magic && magic != LcpInfo.want_magic) { 666927145beSBrian Somers LogPrintf(LogERROR, "RecvEchoRep: his magic is wrong! expect: %x got: %x\n", 667af57ed9fSAtsushi Murai LcpInfo.his_magic, magic); 668944f7098SBrian Somers 669af57ed9fSAtsushi Murai /* 670944f7098SBrian Somers * XXX: We should send terminate request. But poor implementation may die 671944f7098SBrian Somers * as a result. 672af57ed9fSAtsushi Murai */ 673af57ed9fSAtsushi Murai } 674af57ed9fSAtsushi Murai RecvEchoLqr(bp); 675af57ed9fSAtsushi Murai pfree(bp); 676af57ed9fSAtsushi Murai } 677af57ed9fSAtsushi Murai 678af57ed9fSAtsushi Murai void 679944f7098SBrian Somers FsmRecvDiscReq(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 680af57ed9fSAtsushi Murai { 681cb611434SBrian Somers LogPrintf(fp->LogLevel, "RecvDiscReq\n"); 682af57ed9fSAtsushi Murai pfree(bp); 683af57ed9fSAtsushi Murai } 684af57ed9fSAtsushi Murai 685af57ed9fSAtsushi Murai void 686944f7098SBrian Somers FsmRecvIdent(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 687af57ed9fSAtsushi Murai { 688cb611434SBrian Somers LogPrintf(fp->LogLevel, "RecvIdent\n"); 689af57ed9fSAtsushi Murai pfree(bp); 690af57ed9fSAtsushi Murai } 691af57ed9fSAtsushi Murai 692af57ed9fSAtsushi Murai void 693944f7098SBrian Somers FsmRecvTimeRemain(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 694af57ed9fSAtsushi Murai { 695cb611434SBrian Somers LogPrintf(fp->LogLevel, "RecvTimeRemain\n"); 696af57ed9fSAtsushi Murai pfree(bp); 697af57ed9fSAtsushi Murai } 698af57ed9fSAtsushi Murai 699af57ed9fSAtsushi Murai void 700944f7098SBrian Somers FsmRecvResetReq(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 701af57ed9fSAtsushi Murai { 702cb611434SBrian Somers LogPrintf(fp->LogLevel, "RecvResetReq\n"); 703af57ed9fSAtsushi Murai CcpRecvResetReq(fp); 704cb611434SBrian Somers LogPrintf(fp->LogLevel, "SendResetAck\n"); 705af57ed9fSAtsushi Murai FsmOutput(fp, CODE_RESETACK, fp->reqid, NULL, 0); 706af57ed9fSAtsushi Murai pfree(bp); 707af57ed9fSAtsushi Murai } 708af57ed9fSAtsushi Murai 709af57ed9fSAtsushi Murai void 710944f7098SBrian Somers FsmRecvResetAck(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) 711af57ed9fSAtsushi Murai { 712cb611434SBrian Somers LogPrintf(fp->LogLevel, "RecvResetAck\n"); 713af57ed9fSAtsushi Murai fp->reqid++; 714af57ed9fSAtsushi Murai pfree(bp); 715af57ed9fSAtsushi Murai } 716af57ed9fSAtsushi Murai 717af57ed9fSAtsushi Murai struct fsmcodedesc FsmCodes[] = { 718af57ed9fSAtsushi Murai {FsmRecvConfigReq, "Configure Request",}, 719af57ed9fSAtsushi Murai {FsmRecvConfigAck, "Configure Ack",}, 720af57ed9fSAtsushi Murai {FsmRecvConfigNak, "Configure Nak",}, 721af57ed9fSAtsushi Murai {FsmRecvConfigRej, "Configure Reject",}, 722af57ed9fSAtsushi Murai {FsmRecvTermReq, "Terminate Request",}, 723af57ed9fSAtsushi Murai {FsmRecvTermAck, "Terminate Ack",}, 724af57ed9fSAtsushi Murai {FsmRecvCodeRej, "Code Reject",}, 725af57ed9fSAtsushi Murai {FsmRecvProtoRej, "Protocol Reject",}, 726af57ed9fSAtsushi Murai {FsmRecvEchoReq, "Echo Request",}, 727af57ed9fSAtsushi Murai {FsmRecvEchoRep, "Echo Reply",}, 728af57ed9fSAtsushi Murai {FsmRecvDiscReq, "Discard Request",}, 729af57ed9fSAtsushi Murai {FsmRecvIdent, "Ident",}, 730af57ed9fSAtsushi Murai {FsmRecvTimeRemain, "Time Remain",}, 731af57ed9fSAtsushi Murai {FsmRecvResetReq, "Reset Request",}, 732af57ed9fSAtsushi Murai {FsmRecvResetAck, "Reset Ack",}, 733af57ed9fSAtsushi Murai }; 734af57ed9fSAtsushi Murai 735af57ed9fSAtsushi Murai void 736944f7098SBrian Somers FsmInput(struct fsm * fp, struct mbuf * bp) 737af57ed9fSAtsushi Murai { 738af57ed9fSAtsushi Murai int len; 739af57ed9fSAtsushi Murai struct fsmheader *lhp; 740af57ed9fSAtsushi Murai struct fsmcodedesc *codep; 741af57ed9fSAtsushi Murai 742af57ed9fSAtsushi Murai len = plength(bp); 743af57ed9fSAtsushi Murai if (len < sizeof(struct fsmheader)) { 744af57ed9fSAtsushi Murai pfree(bp); 745af57ed9fSAtsushi Murai return; 746af57ed9fSAtsushi Murai } 747af57ed9fSAtsushi Murai lhp = (struct fsmheader *) MBUF_CTOP(bp); 748af57ed9fSAtsushi Murai if (lhp->code == 0 || lhp->code > fp->max_code) { 749af57ed9fSAtsushi Murai pfree(bp); /* XXX: Should send code reject */ 750af57ed9fSAtsushi Murai return; 751af57ed9fSAtsushi Murai } 752af57ed9fSAtsushi Murai bp->offset += sizeof(struct fsmheader); 753af57ed9fSAtsushi Murai bp->cnt -= sizeof(struct fsmheader); 754af57ed9fSAtsushi Murai 755af57ed9fSAtsushi Murai codep = FsmCodes + lhp->code - 1; 756cb611434SBrian Somers LogPrintf(fp->LogLevel, "Received %s (%d) state = %s (%d)\n", 757927145beSBrian Somers codep->name, lhp->id, StateNames[fp->state], fp->state); 758927145beSBrian Somers if (LogIsKept(LogDEBUG)) 759af57ed9fSAtsushi Murai LogMemory(); 760af57ed9fSAtsushi Murai (codep->action) (fp, lhp, bp); 761927145beSBrian Somers if (LogIsKept(LogDEBUG)) 762af57ed9fSAtsushi Murai LogMemory(); 763af57ed9fSAtsushi Murai } 764