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 * 2071144dc5SBrian Somers * $Id: fsm.c,v 1.13 1997/06/09 03:27:21 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 /* 4771144dc5SBrian Somers * This timer times the ST_STOPPED state out after the given value 4871144dc5SBrian Somers * (specified via "set stopped ..."). Although this isn't 4971144dc5SBrian Somers * specified in the rfc, the rfc *does* say that "the application 5071144dc5SBrian Somers * may use higher level timers to avoid deadlock". 5171144dc5SBrian Somers * The StoppedTimer takes effect when the other side ABENDs rather 5271144dc5SBrian Somers * than going into ST_ACKSENT (and sending the ACK), causing ppp to 5371144dc5SBrian Somers * time out and drop into ST_STOPPED. At this point, nothing will 5471144dc5SBrian Somers * change this state :-( 5571144dc5SBrian Somers */ 5671144dc5SBrian Somers struct pppTimer StoppedTimer; 5771144dc5SBrian Somers 5871144dc5SBrian Somers static void 5971144dc5SBrian Somers StoppedTimeout(fp) 6071144dc5SBrian Somers struct fsm *fp; 6171144dc5SBrian Somers { 6271144dc5SBrian Somers LogPrintf(LogLCP, "Stopped timer expired\n"); 6371144dc5SBrian Somers if (modem != -1) 6471144dc5SBrian Somers DownConnection(); 6571144dc5SBrian Somers else 6671144dc5SBrian Somers FsmDown(fp); 6771144dc5SBrian Somers } 6871144dc5SBrian Somers 69af57ed9fSAtsushi Murai void 70af57ed9fSAtsushi Murai FsmInit(fp) 71af57ed9fSAtsushi Murai struct fsm *fp; 72af57ed9fSAtsushi Murai { 73927145beSBrian Somers LogPrintf(LogDEBUG, "FsmInit\n"); 74af57ed9fSAtsushi Murai fp->state = ST_INITIAL; 75af57ed9fSAtsushi Murai fp->reqid = 1; 76af57ed9fSAtsushi Murai fp->restart = 1; 77af57ed9fSAtsushi Murai fp->maxconfig = 3; 78af57ed9fSAtsushi Murai } 79af57ed9fSAtsushi Murai 80af57ed9fSAtsushi Murai void 81af57ed9fSAtsushi Murai NewState(fp, new) 82af57ed9fSAtsushi Murai struct fsm *fp; 83af57ed9fSAtsushi Murai int new; 84af57ed9fSAtsushi Murai { 85927145beSBrian Somers LogPrintf(LogLCP, "State change %s --> %s\n", 86927145beSBrian Somers StateNames[fp->state], StateNames[new]); 8771144dc5SBrian Somers if (fp->state == ST_STOPPED && StoppedTimer.state == TIMER_RUNNING) 8871144dc5SBrian Somers StopTimer(&StoppedTimer); 89af57ed9fSAtsushi Murai fp->state = new; 9071144dc5SBrian Somers if ((new >= ST_INITIAL && new <= ST_STOPPED) || (new == ST_OPENED)) { 91af57ed9fSAtsushi Murai StopTimer(&fp->FsmTimer); 9271144dc5SBrian Somers if (new == ST_STOPPED && VarStoppedTimeout) { 9371144dc5SBrian Somers StoppedTimer.state = TIMER_STOPPED; 9471144dc5SBrian Somers StoppedTimer.func = StoppedTimeout; 9571144dc5SBrian Somers StoppedTimer.arg = (void *)fp; 9671144dc5SBrian Somers StoppedTimer.load = VarStoppedTimeout * SECTICKS; 9771144dc5SBrian Somers StartTimer(&StoppedTimer); 9871144dc5SBrian Somers } 9971144dc5SBrian Somers } 100af57ed9fSAtsushi Murai } 101af57ed9fSAtsushi Murai 102af57ed9fSAtsushi Murai void 103af57ed9fSAtsushi Murai FsmOutput(fp, code, id, ptr, count) 104af57ed9fSAtsushi Murai struct fsm *fp; 105af57ed9fSAtsushi Murai u_int code, id; 106af57ed9fSAtsushi Murai u_char *ptr; 107af57ed9fSAtsushi Murai int count; 108af57ed9fSAtsushi Murai { 109af57ed9fSAtsushi Murai int plen; 110af57ed9fSAtsushi Murai struct fsmheader lh; 111af57ed9fSAtsushi Murai struct mbuf *bp; 112af57ed9fSAtsushi Murai 113af57ed9fSAtsushi Murai plen = sizeof(struct fsmheader) + count; 114af57ed9fSAtsushi Murai lh.code = code; 115af57ed9fSAtsushi Murai lh.id = id; 116af57ed9fSAtsushi Murai lh.length = htons(plen); 117af57ed9fSAtsushi Murai bp = mballoc(plen, MB_FSM); 118af57ed9fSAtsushi Murai bcopy(&lh, MBUF_CTOP(bp), sizeof(struct fsmheader)); 119af57ed9fSAtsushi Murai if (count) 120af57ed9fSAtsushi Murai bcopy(ptr, MBUF_CTOP(bp) + sizeof(struct fsmheader), count); 121927145beSBrian Somers LogDumpBp(LogDEBUG, "FsmOutput", bp); 12276bd0c0aSDoug Rabson HdlcOutput(PRI_LINK, fp->proto, bp); 123af57ed9fSAtsushi Murai } 124af57ed9fSAtsushi Murai 125af57ed9fSAtsushi Murai void 126af57ed9fSAtsushi Murai FsmOpen(fp) 127af57ed9fSAtsushi Murai struct fsm *fp; 128af57ed9fSAtsushi Murai { 129af57ed9fSAtsushi Murai switch (fp->state) { 130af57ed9fSAtsushi Murai case ST_INITIAL: 131af57ed9fSAtsushi Murai (fp->LayerStart)(fp); 132af57ed9fSAtsushi Murai NewState(fp, ST_STARTING); 133af57ed9fSAtsushi Murai break; 134af57ed9fSAtsushi Murai case ST_STARTING: 135af57ed9fSAtsushi Murai break; 136af57ed9fSAtsushi Murai case ST_CLOSED: 137af57ed9fSAtsushi Murai if (fp->open_mode == OPEN_PASSIVE) { 138af57ed9fSAtsushi Murai NewState(fp, ST_STOPPED); 139af57ed9fSAtsushi Murai } else { 140af57ed9fSAtsushi Murai FsmInitRestartCounter(fp); 141af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 142af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 143af57ed9fSAtsushi Murai } 144af57ed9fSAtsushi Murai break; 145af57ed9fSAtsushi Murai case ST_STOPPED: /* XXX: restart option */ 146af57ed9fSAtsushi Murai case ST_REQSENT: 147af57ed9fSAtsushi Murai case ST_ACKRCVD: 148af57ed9fSAtsushi Murai case ST_ACKSENT: 149af57ed9fSAtsushi Murai case ST_OPENED: /* XXX: restart option */ 150af57ed9fSAtsushi Murai break; 151af57ed9fSAtsushi Murai case ST_CLOSING: /* XXX: restart option */ 152af57ed9fSAtsushi Murai case ST_STOPPING: /* XXX: restart option */ 153af57ed9fSAtsushi Murai NewState(fp, ST_STOPPING); 154af57ed9fSAtsushi Murai break; 155af57ed9fSAtsushi Murai } 156af57ed9fSAtsushi Murai } 157af57ed9fSAtsushi Murai 158af57ed9fSAtsushi Murai void 159af57ed9fSAtsushi Murai FsmUp(fp) 160af57ed9fSAtsushi Murai struct fsm *fp; 161af57ed9fSAtsushi Murai { 162af57ed9fSAtsushi Murai switch (fp->state) { 163af57ed9fSAtsushi Murai case ST_INITIAL: 164af57ed9fSAtsushi Murai NewState(fp, ST_CLOSED); 165af57ed9fSAtsushi Murai break; 166af57ed9fSAtsushi Murai case ST_STARTING: 167af57ed9fSAtsushi Murai FsmInitRestartCounter(fp); 168af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 169af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 170af57ed9fSAtsushi Murai break; 171af57ed9fSAtsushi Murai default: 172927145beSBrian Somers LogPrintf(LogLCP, "Oops, Up at %s\n", StateNames[fp->state]); 173af57ed9fSAtsushi Murai break; 174af57ed9fSAtsushi Murai } 175af57ed9fSAtsushi Murai } 176af57ed9fSAtsushi Murai 177af57ed9fSAtsushi Murai void 178af57ed9fSAtsushi Murai FsmDown(fp) 179af57ed9fSAtsushi Murai struct fsm *fp; 180af57ed9fSAtsushi Murai { 181af57ed9fSAtsushi Murai switch (fp->state) { 182af57ed9fSAtsushi Murai case ST_CLOSED: 183af57ed9fSAtsushi Murai case ST_CLOSING: 184af57ed9fSAtsushi Murai NewState(fp, ST_INITIAL); 185af57ed9fSAtsushi Murai break; 186af57ed9fSAtsushi Murai case ST_STOPPED: 187af57ed9fSAtsushi Murai (fp->LayerStart)(fp); 188af57ed9fSAtsushi Murai /* Fall into.. */ 189af57ed9fSAtsushi Murai case ST_STOPPING: 190af57ed9fSAtsushi Murai case ST_REQSENT: 191af57ed9fSAtsushi Murai case ST_ACKRCVD: 192af57ed9fSAtsushi Murai case ST_ACKSENT: 193af57ed9fSAtsushi Murai NewState(fp, ST_STARTING); 194af57ed9fSAtsushi Murai break; 195af57ed9fSAtsushi Murai case ST_OPENED: 196af57ed9fSAtsushi Murai (fp->LayerDown)(fp); 197af57ed9fSAtsushi Murai NewState(fp, ST_STARTING); 198af57ed9fSAtsushi Murai break; 199af57ed9fSAtsushi Murai } 200af57ed9fSAtsushi Murai } 201af57ed9fSAtsushi Murai 202af57ed9fSAtsushi Murai void 203af57ed9fSAtsushi Murai FsmClose(fp) 204af57ed9fSAtsushi Murai struct fsm *fp; 205af57ed9fSAtsushi Murai { 206af57ed9fSAtsushi Murai switch (fp->state) { 207af57ed9fSAtsushi Murai case ST_STARTING: 208af57ed9fSAtsushi Murai NewState(fp, ST_INITIAL); 209af57ed9fSAtsushi Murai break; 210af57ed9fSAtsushi Murai case ST_STOPPED: 211af57ed9fSAtsushi Murai NewState(fp, ST_CLOSED); 212af57ed9fSAtsushi Murai break; 213af57ed9fSAtsushi Murai case ST_STOPPING: 214af57ed9fSAtsushi Murai NewState(fp, ST_CLOSING); 215af57ed9fSAtsushi Murai break; 216af57ed9fSAtsushi Murai case ST_OPENED: 217af57ed9fSAtsushi Murai (fp->LayerDown)(fp); 218af57ed9fSAtsushi Murai /* Fall down */ 219af57ed9fSAtsushi Murai case ST_REQSENT: 220af57ed9fSAtsushi Murai case ST_ACKRCVD: 221af57ed9fSAtsushi Murai case ST_ACKSENT: 222af57ed9fSAtsushi Murai FsmInitRestartCounter(fp); 223af57ed9fSAtsushi Murai FsmSendTerminateReq(fp); 224af57ed9fSAtsushi Murai NewState(fp, ST_CLOSING); 225af57ed9fSAtsushi Murai break; 226af57ed9fSAtsushi Murai } 227af57ed9fSAtsushi Murai } 228af57ed9fSAtsushi Murai 229af57ed9fSAtsushi Murai /* 230af57ed9fSAtsushi Murai * Send functions 231af57ed9fSAtsushi Murai */ 232af57ed9fSAtsushi Murai void 233af57ed9fSAtsushi Murai FsmSendConfigReq(fp) 234af57ed9fSAtsushi Murai struct fsm *fp; 235af57ed9fSAtsushi Murai { 236af57ed9fSAtsushi Murai if (--fp->maxconfig > 0) { 237af57ed9fSAtsushi Murai (fp->SendConfigReq)(fp); 238af57ed9fSAtsushi Murai StartTimer(&fp->FsmTimer); /* Start restart timer */ 239af57ed9fSAtsushi Murai fp->restart--; /* Decrement restart counter */ 240af57ed9fSAtsushi Murai } else { 241af57ed9fSAtsushi Murai FsmClose(fp); 242af57ed9fSAtsushi Murai } 243af57ed9fSAtsushi Murai } 244af57ed9fSAtsushi Murai 245af57ed9fSAtsushi Murai void 246af57ed9fSAtsushi Murai FsmSendTerminateReq(fp) 247af57ed9fSAtsushi Murai struct fsm *fp; 248af57ed9fSAtsushi Murai { 249927145beSBrian Somers LogPrintf(LogLCP, "SendTerminateReq.\n"); 250af57ed9fSAtsushi Murai FsmOutput(fp, CODE_TERMREQ, fp->reqid++, NULL, 0); 251af57ed9fSAtsushi Murai (fp->SendTerminateReq)(fp); 252af57ed9fSAtsushi Murai StartTimer(&fp->FsmTimer); /* Start restart timer */ 253af57ed9fSAtsushi Murai fp->restart--; /* Decrement restart counter */ 254af57ed9fSAtsushi Murai } 255af57ed9fSAtsushi Murai 256af57ed9fSAtsushi Murai static void 257af57ed9fSAtsushi Murai FsmSendConfigAck(fp, lhp, option, count) 258af57ed9fSAtsushi Murai struct fsm *fp; 259af57ed9fSAtsushi Murai struct fsmheader *lhp; 260af57ed9fSAtsushi Murai u_char *option; 261af57ed9fSAtsushi Murai int count; 262af57ed9fSAtsushi Murai { 263927145beSBrian Somers LogPrintf(LogLCP, "SendConfigAck(%s)\n", StateNames[fp->state]); 26453c9f6c0SAtsushi Murai (fp->DecodeConfig)(option, count, MODE_NOP); 265af57ed9fSAtsushi Murai FsmOutput(fp, CODE_CONFIGACK, lhp->id, option, count); 266af57ed9fSAtsushi Murai } 267af57ed9fSAtsushi Murai 268af57ed9fSAtsushi Murai static void 269af57ed9fSAtsushi Murai FsmSendConfigRej(fp, lhp, option, count) 270af57ed9fSAtsushi Murai struct fsm *fp; 271af57ed9fSAtsushi Murai struct fsmheader *lhp; 272af57ed9fSAtsushi Murai u_char *option; 273af57ed9fSAtsushi Murai int count; 274af57ed9fSAtsushi Murai { 275927145beSBrian Somers LogPrintf(LogLCP, "SendConfigRej(%s)\n", StateNames[fp->state]); 27653c9f6c0SAtsushi Murai (fp->DecodeConfig)(option, count, MODE_NOP); 277af57ed9fSAtsushi Murai FsmOutput(fp, CODE_CONFIGREJ, lhp->id, option, count); 278af57ed9fSAtsushi Murai } 279af57ed9fSAtsushi Murai 280af57ed9fSAtsushi Murai static void 281af57ed9fSAtsushi Murai FsmSendConfigNak(fp, lhp, option, count) 282af57ed9fSAtsushi Murai struct fsm *fp; 283af57ed9fSAtsushi Murai struct fsmheader *lhp; 284af57ed9fSAtsushi Murai u_char *option; 285af57ed9fSAtsushi Murai int count; 286af57ed9fSAtsushi Murai { 287927145beSBrian Somers LogPrintf(LogLCP, "SendConfigNak(%s)\n", StateNames[fp->state]); 28853c9f6c0SAtsushi Murai (fp->DecodeConfig)(option, count, MODE_NOP); 289af57ed9fSAtsushi Murai FsmOutput(fp, CODE_CONFIGNAK, lhp->id, option, count); 290af57ed9fSAtsushi Murai } 291af57ed9fSAtsushi Murai 292af57ed9fSAtsushi Murai /* 293af57ed9fSAtsushi Murai * Timeout actions 294af57ed9fSAtsushi Murai */ 295af57ed9fSAtsushi Murai void 296af57ed9fSAtsushi Murai FsmTimeout(fp) 297af57ed9fSAtsushi Murai struct fsm *fp; 298af57ed9fSAtsushi Murai { 299af57ed9fSAtsushi Murai if (fp->restart) { 300af57ed9fSAtsushi Murai switch (fp->state) { 301af57ed9fSAtsushi Murai case ST_CLOSING: 302af57ed9fSAtsushi Murai case ST_STOPPING: 303af57ed9fSAtsushi Murai FsmSendTerminateReq(fp); 304af57ed9fSAtsushi Murai break; 305af57ed9fSAtsushi Murai case ST_REQSENT: 306af57ed9fSAtsushi Murai case ST_ACKSENT: 307af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 308af57ed9fSAtsushi Murai break; 309af57ed9fSAtsushi Murai case ST_ACKRCVD: 310af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 311af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 312af57ed9fSAtsushi Murai break; 313af57ed9fSAtsushi Murai } 314af57ed9fSAtsushi Murai StartTimer(&fp->FsmTimer); 315af57ed9fSAtsushi Murai } else { 316af57ed9fSAtsushi Murai switch (fp->state) { 317af57ed9fSAtsushi Murai case ST_CLOSING: 318af57ed9fSAtsushi Murai NewState(fp, ST_CLOSED); 319af57ed9fSAtsushi Murai (fp->LayerFinish)(fp); 320af57ed9fSAtsushi Murai break; 321af57ed9fSAtsushi Murai case ST_STOPPING: 322af57ed9fSAtsushi Murai NewState(fp, ST_STOPPED); 323af57ed9fSAtsushi Murai (fp->LayerFinish)(fp); 324af57ed9fSAtsushi Murai break; 325af57ed9fSAtsushi Murai case ST_REQSENT: /* XXX: 3p */ 326af57ed9fSAtsushi Murai case ST_ACKSENT: 327af57ed9fSAtsushi Murai case ST_ACKRCVD: 328af57ed9fSAtsushi Murai NewState(fp, ST_STOPPED); 329af57ed9fSAtsushi Murai (fp->LayerFinish)(fp); 330af57ed9fSAtsushi Murai break; 331af57ed9fSAtsushi Murai } 332af57ed9fSAtsushi Murai } 333af57ed9fSAtsushi Murai } 334af57ed9fSAtsushi Murai 335af57ed9fSAtsushi Murai void 336af57ed9fSAtsushi Murai FsmInitRestartCounter(fp) 337af57ed9fSAtsushi Murai struct fsm *fp; 338af57ed9fSAtsushi Murai { 339af57ed9fSAtsushi Murai StopTimer(&fp->FsmTimer); 340af57ed9fSAtsushi Murai fp->FsmTimer.state = TIMER_STOPPED; 341af57ed9fSAtsushi Murai fp->FsmTimer.func = FsmTimeout; 342af57ed9fSAtsushi Murai fp->FsmTimer.arg = (void *)fp; 343af57ed9fSAtsushi Murai (fp->InitRestartCounter)(fp); 344af57ed9fSAtsushi Murai } 345af57ed9fSAtsushi Murai 346af57ed9fSAtsushi Murai /* 347af57ed9fSAtsushi Murai * Actions when receive packets 348af57ed9fSAtsushi Murai */ 349af57ed9fSAtsushi Murai void 350af57ed9fSAtsushi Murai FsmRecvConfigReq(fp, lhp, bp) /* RCR */ 351af57ed9fSAtsushi Murai struct fsm *fp; 352af57ed9fSAtsushi Murai struct fsmheader *lhp; 353af57ed9fSAtsushi Murai struct mbuf *bp; 354af57ed9fSAtsushi Murai { 35553c9f6c0SAtsushi Murai int plen, flen; 356af57ed9fSAtsushi Murai int ackaction = 0; 357af57ed9fSAtsushi Murai 358af57ed9fSAtsushi Murai plen = plength(bp); 35953c9f6c0SAtsushi Murai flen = ntohs(lhp->length) - sizeof(*lhp); 36053c9f6c0SAtsushi Murai if (plen < flen) { 361927145beSBrian Somers LogPrintf(LogERROR, "FsmRecvConfigReq: plen (%d) < flen (%d)", plen, flen); 362af57ed9fSAtsushi Murai pfree(bp); 363af57ed9fSAtsushi Murai return; 364af57ed9fSAtsushi Murai } 365af57ed9fSAtsushi Murai 36653c9f6c0SAtsushi Murai 367af57ed9fSAtsushi Murai /* 368af57ed9fSAtsushi Murai * Check and process easy case 369af57ed9fSAtsushi Murai */ 370af57ed9fSAtsushi Murai switch (fp->state) { 371af57ed9fSAtsushi Murai case ST_INITIAL: 372af57ed9fSAtsushi Murai case ST_STARTING: 373927145beSBrian Somers LogPrintf(LogLCP, "Oops, RCR in %s.\n", StateNames[fp->state]); 374af57ed9fSAtsushi Murai pfree(bp); 375af57ed9fSAtsushi Murai return; 376af57ed9fSAtsushi Murai case ST_CLOSED: 377af57ed9fSAtsushi Murai (fp->SendTerminateAck)(fp); 378af57ed9fSAtsushi Murai pfree(bp); 379af57ed9fSAtsushi Murai return; 380af57ed9fSAtsushi Murai case ST_CLOSING: 381af57ed9fSAtsushi Murai case ST_STOPPING: 382927145beSBrian Somers LogPrintf(LogERROR, "Got ConfigReq while state = %d\n", fp->state); 383af57ed9fSAtsushi Murai pfree(bp); 384af57ed9fSAtsushi Murai return; 385af57ed9fSAtsushi Murai } 386af57ed9fSAtsushi Murai 38753c9f6c0SAtsushi Murai (fp->DecodeConfig)(MBUF_CTOP(bp), flen, MODE_REQ); 388af57ed9fSAtsushi Murai 389af57ed9fSAtsushi Murai if (nakp == NakBuff && rejp == RejBuff) 390af57ed9fSAtsushi Murai ackaction = 1; 391af57ed9fSAtsushi Murai 392af57ed9fSAtsushi Murai switch (fp->state) { 393af57ed9fSAtsushi Murai case ST_OPENED: 394af57ed9fSAtsushi Murai (fp->LayerDown)(fp); 395af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 396af57ed9fSAtsushi Murai break; 397af57ed9fSAtsushi Murai case ST_STOPPED: 398af57ed9fSAtsushi Murai FsmInitRestartCounter(fp); 399af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 400af57ed9fSAtsushi Murai break; 401af57ed9fSAtsushi Murai } 402af57ed9fSAtsushi Murai 403af57ed9fSAtsushi Murai if (rejp != RejBuff) 404af57ed9fSAtsushi Murai FsmSendConfigRej(fp, lhp, RejBuff, rejp - RejBuff); 405af57ed9fSAtsushi Murai if (nakp != NakBuff) 406af57ed9fSAtsushi Murai FsmSendConfigNak(fp, lhp, NakBuff, nakp - NakBuff); 407af57ed9fSAtsushi Murai if (ackaction) 408af57ed9fSAtsushi Murai FsmSendConfigAck(fp, lhp, AckBuff, ackp - AckBuff); 409af57ed9fSAtsushi Murai 410af57ed9fSAtsushi Murai switch (fp->state) { 411af57ed9fSAtsushi Murai case ST_STOPPED: 412af57ed9fSAtsushi Murai case ST_OPENED: 413af57ed9fSAtsushi Murai if (ackaction) 414af57ed9fSAtsushi Murai NewState(fp, ST_ACKSENT); 415af57ed9fSAtsushi Murai else 416af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 417af57ed9fSAtsushi Murai break; 418af57ed9fSAtsushi Murai case ST_REQSENT: 419af57ed9fSAtsushi Murai if (ackaction) 420af57ed9fSAtsushi Murai NewState(fp, ST_ACKSENT); 421af57ed9fSAtsushi Murai break; 422af57ed9fSAtsushi Murai case ST_ACKRCVD: 423af57ed9fSAtsushi Murai if (ackaction) { 424af57ed9fSAtsushi Murai NewState(fp, ST_OPENED); 425af57ed9fSAtsushi Murai (fp->LayerUp)(fp); 426af57ed9fSAtsushi Murai } 427af57ed9fSAtsushi Murai break; 428af57ed9fSAtsushi Murai case ST_ACKSENT: 429af57ed9fSAtsushi Murai if (!ackaction) 430af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 431af57ed9fSAtsushi Murai break; 432af57ed9fSAtsushi Murai } 433af57ed9fSAtsushi Murai pfree(bp); 434af57ed9fSAtsushi Murai } 435af57ed9fSAtsushi Murai 436af57ed9fSAtsushi Murai void 437af57ed9fSAtsushi Murai FsmRecvConfigAck(fp, lhp, bp) /* RCA */ 438af57ed9fSAtsushi Murai struct fsm *fp; 439af57ed9fSAtsushi Murai struct fsmheader *lhp; 440af57ed9fSAtsushi Murai struct mbuf *bp; 441af57ed9fSAtsushi Murai { 442af57ed9fSAtsushi Murai switch (fp->state) { 443af57ed9fSAtsushi Murai case ST_CLOSED: 444af57ed9fSAtsushi Murai case ST_STOPPED: 445af57ed9fSAtsushi Murai (fp->SendTerminateAck)(fp); 446af57ed9fSAtsushi Murai break; 447af57ed9fSAtsushi Murai case ST_CLOSING: 448af57ed9fSAtsushi Murai case ST_STOPPING: 449af57ed9fSAtsushi Murai break; 450af57ed9fSAtsushi Murai case ST_REQSENT: 451af57ed9fSAtsushi Murai FsmInitRestartCounter(fp); 452af57ed9fSAtsushi Murai NewState(fp, ST_ACKRCVD); 453af57ed9fSAtsushi Murai break; 454af57ed9fSAtsushi Murai case ST_ACKRCVD: 455af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 456af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 457af57ed9fSAtsushi Murai break; 458af57ed9fSAtsushi Murai case ST_ACKSENT: 459af57ed9fSAtsushi Murai FsmInitRestartCounter(fp); 460af57ed9fSAtsushi Murai NewState(fp, ST_OPENED); 461af57ed9fSAtsushi Murai (fp->LayerUp)(fp); 462af57ed9fSAtsushi Murai break; 463af57ed9fSAtsushi Murai case ST_OPENED: 464af57ed9fSAtsushi Murai (fp->LayerDown)(fp); 465af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 466af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 467af57ed9fSAtsushi Murai break; 468af57ed9fSAtsushi Murai } 469af57ed9fSAtsushi Murai pfree(bp); 470af57ed9fSAtsushi Murai } 471af57ed9fSAtsushi Murai 472af57ed9fSAtsushi Murai void 473af57ed9fSAtsushi Murai FsmRecvConfigNak(fp, lhp, bp) /* RCN */ 474af57ed9fSAtsushi Murai struct fsm *fp; 475af57ed9fSAtsushi Murai struct fsmheader *lhp; 476af57ed9fSAtsushi Murai struct mbuf *bp; 477af57ed9fSAtsushi Murai { 47853c9f6c0SAtsushi Murai int plen, flen; 479af57ed9fSAtsushi Murai 480af57ed9fSAtsushi Murai plen = plength(bp); 48153c9f6c0SAtsushi Murai flen = ntohs(lhp->length) - sizeof(*lhp); 48253c9f6c0SAtsushi Murai if (plen < flen) { 483af57ed9fSAtsushi Murai pfree(bp); 484af57ed9fSAtsushi Murai return; 485af57ed9fSAtsushi Murai } 486af57ed9fSAtsushi Murai 487af57ed9fSAtsushi Murai /* 488af57ed9fSAtsushi Murai * Check and process easy case 489af57ed9fSAtsushi Murai */ 490af57ed9fSAtsushi Murai switch (fp->state) { 491af57ed9fSAtsushi Murai case ST_INITIAL: 492af57ed9fSAtsushi Murai case ST_STARTING: 493927145beSBrian Somers LogPrintf(LogLCP, "Oops, RCN in %s.\n", StateNames[fp->state]); 494af57ed9fSAtsushi Murai pfree(bp); 495af57ed9fSAtsushi Murai return; 496af57ed9fSAtsushi Murai case ST_CLOSED: 497af57ed9fSAtsushi Murai case ST_STOPPED: 498af57ed9fSAtsushi Murai (fp->SendTerminateAck)(fp); 499af57ed9fSAtsushi Murai pfree(bp); 500af57ed9fSAtsushi Murai return; 501af57ed9fSAtsushi Murai case ST_CLOSING: 502af57ed9fSAtsushi Murai case ST_STOPPING: 503af57ed9fSAtsushi Murai pfree(bp); 504af57ed9fSAtsushi Murai return; 505af57ed9fSAtsushi Murai } 506af57ed9fSAtsushi Murai 50753c9f6c0SAtsushi Murai (fp->DecodeConfig)(MBUF_CTOP(bp), flen, MODE_NAK); 508af57ed9fSAtsushi Murai 509af57ed9fSAtsushi Murai switch (fp->state) { 510af57ed9fSAtsushi Murai case ST_REQSENT: 511af57ed9fSAtsushi Murai case ST_ACKSENT: 512af57ed9fSAtsushi Murai FsmInitRestartCounter(fp); 513af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 514af57ed9fSAtsushi Murai break; 515af57ed9fSAtsushi Murai case ST_OPENED: 516af57ed9fSAtsushi Murai (fp->LayerDown)(fp); 517af57ed9fSAtsushi Murai /* Fall down */ 518af57ed9fSAtsushi Murai case ST_ACKRCVD: 519af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 520af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 521af57ed9fSAtsushi Murai break; 522af57ed9fSAtsushi Murai } 523af57ed9fSAtsushi Murai 524af57ed9fSAtsushi Murai pfree(bp); 525af57ed9fSAtsushi Murai } 526af57ed9fSAtsushi Murai 527af57ed9fSAtsushi Murai void 528af57ed9fSAtsushi Murai FsmRecvTermReq(fp, lhp, bp) /* RTR */ 529af57ed9fSAtsushi Murai struct fsm *fp; 530af57ed9fSAtsushi Murai struct fsmheader *lhp; 531af57ed9fSAtsushi Murai struct mbuf *bp; 532af57ed9fSAtsushi Murai { 533af57ed9fSAtsushi Murai switch (fp->state) { 534af57ed9fSAtsushi Murai case ST_INITIAL: 535af57ed9fSAtsushi Murai case ST_STARTING: 536927145beSBrian Somers LogPrintf(LogLCP, "Oops, RTR in %s\n", StateNames[fp->state]); 537af57ed9fSAtsushi Murai break; 538af57ed9fSAtsushi Murai case ST_CLOSED: 539af57ed9fSAtsushi Murai case ST_STOPPED: 540af57ed9fSAtsushi Murai case ST_CLOSING: 541af57ed9fSAtsushi Murai case ST_STOPPING: 542af57ed9fSAtsushi Murai case ST_REQSENT: 543af57ed9fSAtsushi Murai (fp->SendTerminateAck)(fp); 544af57ed9fSAtsushi Murai break; 545af57ed9fSAtsushi Murai case ST_ACKRCVD: 546af57ed9fSAtsushi Murai case ST_ACKSENT: 547af57ed9fSAtsushi Murai (fp->SendTerminateAck)(fp); 548af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 549af57ed9fSAtsushi Murai break; 550af57ed9fSAtsushi Murai case ST_OPENED: 5518f2fa0eeSBrian Somers (fp->LayerDown)(fp); 552af57ed9fSAtsushi Murai (fp->SendTerminateAck)(fp); 5538f2fa0eeSBrian Somers StartTimer(&fp->FsmTimer); /* Start restart timer */ 5548f2fa0eeSBrian Somers fp->restart = 0; 5558f2fa0eeSBrian Somers NewState(fp, ST_STOPPING); 556af57ed9fSAtsushi Murai break; 557af57ed9fSAtsushi Murai } 558af57ed9fSAtsushi Murai pfree(bp); 559af57ed9fSAtsushi Murai } 560af57ed9fSAtsushi Murai 561af57ed9fSAtsushi Murai void 562af57ed9fSAtsushi Murai FsmRecvTermAck(fp, lhp, bp) /* RTA */ 563af57ed9fSAtsushi Murai struct fsm *fp; 564af57ed9fSAtsushi Murai struct fsmheader *lhp; 565af57ed9fSAtsushi Murai struct mbuf *bp; 566af57ed9fSAtsushi Murai { 567af57ed9fSAtsushi Murai switch (fp->state) { 568af57ed9fSAtsushi Murai case ST_CLOSING: 569af57ed9fSAtsushi Murai NewState(fp, ST_CLOSED); 570af57ed9fSAtsushi Murai (fp->LayerFinish)(fp); 571af57ed9fSAtsushi Murai break; 572af57ed9fSAtsushi Murai case ST_STOPPING: 573af57ed9fSAtsushi Murai NewState(fp, ST_STOPPED); 574af57ed9fSAtsushi Murai (fp->LayerFinish)(fp); 575af57ed9fSAtsushi Murai break; 576af57ed9fSAtsushi Murai case ST_ACKRCVD: 577af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 578af57ed9fSAtsushi Murai break; 579af57ed9fSAtsushi Murai case ST_OPENED: 580af57ed9fSAtsushi Murai (fp->LayerDown)(fp); 581af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 582af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 583af57ed9fSAtsushi Murai break; 584af57ed9fSAtsushi Murai } 585af57ed9fSAtsushi Murai pfree(bp); 586af57ed9fSAtsushi Murai } 587af57ed9fSAtsushi Murai 588af57ed9fSAtsushi Murai void 589af57ed9fSAtsushi Murai FsmRecvConfigRej(fp, lhp, bp) /* RCJ */ 590af57ed9fSAtsushi Murai struct fsm *fp; 591af57ed9fSAtsushi Murai struct fsmheader *lhp; 592af57ed9fSAtsushi Murai struct mbuf *bp; 593af57ed9fSAtsushi Murai { 59453c9f6c0SAtsushi Murai int plen, flen; 595af57ed9fSAtsushi Murai 596af57ed9fSAtsushi Murai plen = plength(bp); 59753c9f6c0SAtsushi Murai flen = ntohs(lhp->length) - sizeof(*lhp); 59853c9f6c0SAtsushi Murai if (plen < flen) { 599af57ed9fSAtsushi Murai pfree(bp); 600af57ed9fSAtsushi Murai return; 601af57ed9fSAtsushi Murai } 602927145beSBrian Somers LogPrintf(LogLCP, "RecvConfigRej.\n"); 603af57ed9fSAtsushi Murai 604af57ed9fSAtsushi Murai /* 605af57ed9fSAtsushi Murai * Check and process easy case 606af57ed9fSAtsushi Murai */ 607af57ed9fSAtsushi Murai switch (fp->state) { 608af57ed9fSAtsushi Murai case ST_INITIAL: 609af57ed9fSAtsushi Murai case ST_STARTING: 610927145beSBrian Somers LogPrintf(LogLCP, "Oops, RCJ in %s.\n", StateNames[fp->state]); 611af57ed9fSAtsushi Murai pfree(bp); 612af57ed9fSAtsushi Murai return; 613af57ed9fSAtsushi Murai case ST_CLOSED: 614af57ed9fSAtsushi Murai case ST_STOPPED: 615af57ed9fSAtsushi Murai (fp->SendTerminateAck)(fp); 616af57ed9fSAtsushi Murai pfree(bp); 617af57ed9fSAtsushi Murai return; 618af57ed9fSAtsushi Murai case ST_CLOSING: 619af57ed9fSAtsushi Murai case ST_STOPPING: 620af57ed9fSAtsushi Murai pfree(bp); 621af57ed9fSAtsushi Murai return; 622af57ed9fSAtsushi Murai } 623af57ed9fSAtsushi Murai 62453c9f6c0SAtsushi Murai (fp->DecodeConfig)(MBUF_CTOP(bp), flen, MODE_REJ); 625af57ed9fSAtsushi Murai 626af57ed9fSAtsushi Murai switch (fp->state) { 627af57ed9fSAtsushi Murai case ST_REQSENT: 628af57ed9fSAtsushi Murai case ST_ACKSENT: 629af57ed9fSAtsushi Murai FsmInitRestartCounter(fp); 630af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 631af57ed9fSAtsushi Murai break; 632af57ed9fSAtsushi Murai case ST_OPENED: 633af57ed9fSAtsushi Murai (fp->LayerDown)(fp); 634af57ed9fSAtsushi Murai /* Fall down */ 635af57ed9fSAtsushi Murai case ST_ACKRCVD: 636af57ed9fSAtsushi Murai FsmSendConfigReq(fp); 637af57ed9fSAtsushi Murai NewState(fp, ST_REQSENT); 638af57ed9fSAtsushi Murai break; 639af57ed9fSAtsushi Murai } 640af57ed9fSAtsushi Murai pfree(bp); 641af57ed9fSAtsushi Murai } 642af57ed9fSAtsushi Murai 643af57ed9fSAtsushi Murai void 644af57ed9fSAtsushi Murai FsmRecvCodeRej(fp, lhp, bp) 645af57ed9fSAtsushi Murai struct fsm *fp; 646af57ed9fSAtsushi Murai struct fsmheader *lhp; 647af57ed9fSAtsushi Murai struct mbuf *bp; 648af57ed9fSAtsushi Murai { 649927145beSBrian Somers LogPrintf(LogLCP, "RecvCodeRej\n"); 650af57ed9fSAtsushi Murai pfree(bp); 651af57ed9fSAtsushi Murai } 652af57ed9fSAtsushi Murai 653af57ed9fSAtsushi Murai void 654af57ed9fSAtsushi Murai FsmRecvProtoRej(fp, lhp, bp) 655af57ed9fSAtsushi Murai struct fsm *fp; 656af57ed9fSAtsushi Murai struct fsmheader *lhp; 657af57ed9fSAtsushi Murai struct mbuf *bp; 658af57ed9fSAtsushi Murai { 659af57ed9fSAtsushi Murai u_short *sp, proto; 660af57ed9fSAtsushi Murai 661af57ed9fSAtsushi Murai sp = (u_short *)MBUF_CTOP(bp); 662af57ed9fSAtsushi Murai proto = ntohs(*sp); 663927145beSBrian Somers LogPrintf(LogLCP, "-- Protocol (%04x) was rejected.\n", proto); 664af57ed9fSAtsushi Murai 665af57ed9fSAtsushi Murai switch (proto) { 666af57ed9fSAtsushi Murai case PROTO_LQR: 667af57ed9fSAtsushi Murai StopLqr(LQM_LQR); 668af57ed9fSAtsushi Murai break; 669af57ed9fSAtsushi Murai case PROTO_CCP: 670af57ed9fSAtsushi Murai fp = &CcpFsm; 671af57ed9fSAtsushi Murai (fp->LayerFinish)(fp); 672af57ed9fSAtsushi Murai switch (fp->state) { 673af57ed9fSAtsushi Murai case ST_CLOSED: 674af57ed9fSAtsushi Murai case ST_CLOSING: 675af57ed9fSAtsushi Murai NewState(fp, ST_CLOSED); 676af57ed9fSAtsushi Murai default: 677af57ed9fSAtsushi Murai NewState(fp, ST_STOPPED); 678af57ed9fSAtsushi Murai break; 679af57ed9fSAtsushi Murai } 680af57ed9fSAtsushi Murai break; 681af57ed9fSAtsushi Murai } 682af57ed9fSAtsushi Murai pfree(bp); 683af57ed9fSAtsushi Murai } 684af57ed9fSAtsushi Murai 685af57ed9fSAtsushi Murai void 686af57ed9fSAtsushi Murai FsmRecvEchoReq(fp, lhp, bp) 687af57ed9fSAtsushi Murai struct fsm *fp; 688af57ed9fSAtsushi Murai struct fsmheader *lhp; 689af57ed9fSAtsushi Murai struct mbuf *bp; 690af57ed9fSAtsushi Murai { 691af57ed9fSAtsushi Murai u_char *cp; 692af57ed9fSAtsushi Murai u_long *lp, magic; 693af57ed9fSAtsushi Murai 694af57ed9fSAtsushi Murai cp = MBUF_CTOP(bp); 695af57ed9fSAtsushi Murai lp = (u_long *)cp; 696af57ed9fSAtsushi Murai magic = ntohl(*lp); 697af57ed9fSAtsushi Murai if (magic != LcpInfo.his_magic) { 698927145beSBrian Somers LogPrintf(LogERROR, "RecvEchoReq: his magic is bad!!\n"); 699af57ed9fSAtsushi Murai /* XXX: We should send terminate request */ 700af57ed9fSAtsushi Murai } 701af57ed9fSAtsushi Murai 702af57ed9fSAtsushi Murai if (fp->state == ST_OPENED) { 703af57ed9fSAtsushi Murai *lp = htonl(LcpInfo.want_magic); /* Insert local magic number */ 704927145beSBrian Somers LogPrintf(LogLCP, "SendEchoRep(%s)\n", StateNames[fp->state]); 705af57ed9fSAtsushi Murai FsmOutput(fp, CODE_ECHOREP, lhp->id, cp, plength(bp)); 706af57ed9fSAtsushi Murai } 707af57ed9fSAtsushi Murai pfree(bp); 708af57ed9fSAtsushi Murai } 709af57ed9fSAtsushi Murai 710af57ed9fSAtsushi Murai void 711af57ed9fSAtsushi Murai FsmRecvEchoRep(fp, lhp, bp) 712af57ed9fSAtsushi Murai struct fsm *fp; 713af57ed9fSAtsushi Murai struct fsmheader *lhp; 714af57ed9fSAtsushi Murai struct mbuf *bp; 715af57ed9fSAtsushi Murai { 716af57ed9fSAtsushi Murai u_long *lp, magic; 717af57ed9fSAtsushi Murai 718af57ed9fSAtsushi Murai lp = (u_long *)MBUF_CTOP(bp); 719af57ed9fSAtsushi Murai magic = ntohl(*lp); 72085c59f05SJoerg Wunsch /* 72185c59f05SJoerg Wunsch * Tolerate echo replies with either magic number 72285c59f05SJoerg Wunsch */ 72385c59f05SJoerg Wunsch if (magic != 0 && magic != LcpInfo.his_magic && magic != LcpInfo.want_magic) { 724927145beSBrian Somers LogPrintf(LogERROR, "RecvEchoRep: his magic is wrong! expect: %x got: %x\n", 725af57ed9fSAtsushi Murai LcpInfo.his_magic, magic); 726af57ed9fSAtsushi Murai /* 727af57ed9fSAtsushi Murai * XXX: We should send terminate request. But poor implementation 728af57ed9fSAtsushi Murai * may die as a result. 729af57ed9fSAtsushi Murai */ 730af57ed9fSAtsushi Murai } 731af57ed9fSAtsushi Murai RecvEchoLqr(bp); 732af57ed9fSAtsushi Murai pfree(bp); 733af57ed9fSAtsushi Murai } 734af57ed9fSAtsushi Murai 735af57ed9fSAtsushi Murai void 736af57ed9fSAtsushi Murai FsmRecvDiscReq(fp, lhp, bp) 737af57ed9fSAtsushi Murai struct fsm *fp; 738af57ed9fSAtsushi Murai struct fsmheader *lhp; 739af57ed9fSAtsushi Murai struct mbuf *bp; 740af57ed9fSAtsushi Murai { 741927145beSBrian Somers LogPrintf(LogLCP, "RecvDiscReq\n"); 742af57ed9fSAtsushi Murai pfree(bp); 743af57ed9fSAtsushi Murai } 744af57ed9fSAtsushi Murai 745af57ed9fSAtsushi Murai void 746af57ed9fSAtsushi Murai FsmRecvIdent(fp, lhp, bp) 747af57ed9fSAtsushi Murai struct fsm *fp; 748af57ed9fSAtsushi Murai struct fsmheader *lhp; 749af57ed9fSAtsushi Murai struct mbuf *bp; 750af57ed9fSAtsushi Murai { 751927145beSBrian Somers LogPrintf(LogLCP, "RecvIdent\n"); 752af57ed9fSAtsushi Murai pfree(bp); 753af57ed9fSAtsushi Murai } 754af57ed9fSAtsushi Murai 755af57ed9fSAtsushi Murai void 756af57ed9fSAtsushi Murai FsmRecvTimeRemain(fp, lhp, bp) 757af57ed9fSAtsushi Murai struct fsm *fp; 758af57ed9fSAtsushi Murai struct fsmheader *lhp; 759af57ed9fSAtsushi Murai struct mbuf *bp; 760af57ed9fSAtsushi Murai { 761927145beSBrian Somers LogPrintf(LogLCP, "RecvTimeRemain\n"); 762af57ed9fSAtsushi Murai pfree(bp); 763af57ed9fSAtsushi Murai } 764af57ed9fSAtsushi Murai 765af57ed9fSAtsushi Murai void 766af57ed9fSAtsushi Murai FsmRecvResetReq(fp, lhp, bp) 767af57ed9fSAtsushi Murai struct fsm *fp; 768af57ed9fSAtsushi Murai struct fsmheader *lhp; 769af57ed9fSAtsushi Murai struct mbuf *bp; 770af57ed9fSAtsushi Murai { 771927145beSBrian Somers LogPrintf(LogLCP, "RecvResetReq\n"); 772af57ed9fSAtsushi Murai CcpRecvResetReq(fp); 773927145beSBrian Somers LogPrintf(LogLCP, "SendResetAck\n"); 774af57ed9fSAtsushi Murai FsmOutput(fp, CODE_RESETACK, fp->reqid, NULL, 0); 775af57ed9fSAtsushi Murai pfree(bp); 776af57ed9fSAtsushi Murai } 777af57ed9fSAtsushi Murai 778af57ed9fSAtsushi Murai void 779af57ed9fSAtsushi Murai FsmRecvResetAck(fp, lhp, bp) 780af57ed9fSAtsushi Murai struct fsm *fp; 781af57ed9fSAtsushi Murai struct fsmheader *lhp; 782af57ed9fSAtsushi Murai struct mbuf *bp; 783af57ed9fSAtsushi Murai { 784927145beSBrian Somers LogPrintf(LogLCP, "RecvResetAck\n"); 785af57ed9fSAtsushi Murai fp->reqid++; 786af57ed9fSAtsushi Murai pfree(bp); 787af57ed9fSAtsushi Murai } 788af57ed9fSAtsushi Murai 789af57ed9fSAtsushi Murai struct fsmcodedesc FsmCodes[] = { 790af57ed9fSAtsushi Murai { FsmRecvConfigReq, "Configure Request", }, 791af57ed9fSAtsushi Murai { FsmRecvConfigAck, "Configure Ack", }, 792af57ed9fSAtsushi Murai { FsmRecvConfigNak, "Configure Nak", }, 793af57ed9fSAtsushi Murai { FsmRecvConfigRej, "Configure Reject", }, 794af57ed9fSAtsushi Murai { FsmRecvTermReq, "Terminate Request", }, 795af57ed9fSAtsushi Murai { FsmRecvTermAck, "Terminate Ack", }, 796af57ed9fSAtsushi Murai { FsmRecvCodeRej, "Code Reject", }, 797af57ed9fSAtsushi Murai { FsmRecvProtoRej, "Protocol Reject", }, 798af57ed9fSAtsushi Murai { FsmRecvEchoReq, "Echo Request", }, 799af57ed9fSAtsushi Murai { FsmRecvEchoRep, "Echo Reply", }, 800af57ed9fSAtsushi Murai { FsmRecvDiscReq, "Discard Request", }, 801af57ed9fSAtsushi Murai { FsmRecvIdent, "Ident", }, 802af57ed9fSAtsushi Murai { FsmRecvTimeRemain, "Time Remain", }, 803af57ed9fSAtsushi Murai { FsmRecvResetReq, "Reset Request", }, 804af57ed9fSAtsushi Murai { FsmRecvResetAck, "Reset Ack", }, 805af57ed9fSAtsushi Murai }; 806af57ed9fSAtsushi Murai 807af57ed9fSAtsushi Murai void 808af57ed9fSAtsushi Murai FsmInput(fp, bp) 809af57ed9fSAtsushi Murai struct fsm *fp; 810af57ed9fSAtsushi Murai struct mbuf *bp; 811af57ed9fSAtsushi Murai { 812af57ed9fSAtsushi Murai int len; 813af57ed9fSAtsushi Murai struct fsmheader *lhp; 814af57ed9fSAtsushi Murai struct fsmcodedesc *codep; 815af57ed9fSAtsushi Murai 816af57ed9fSAtsushi Murai len = plength(bp); 817af57ed9fSAtsushi Murai if (len < sizeof(struct fsmheader)) { 818af57ed9fSAtsushi Murai pfree(bp); 819af57ed9fSAtsushi Murai return; 820af57ed9fSAtsushi Murai } 821af57ed9fSAtsushi Murai lhp = (struct fsmheader *)MBUF_CTOP(bp); 822af57ed9fSAtsushi Murai if (lhp->code == 0 || lhp->code > fp->max_code) { 823af57ed9fSAtsushi Murai pfree(bp); /* XXX: Should send code reject */ 824af57ed9fSAtsushi Murai return; 825af57ed9fSAtsushi Murai } 826af57ed9fSAtsushi Murai 827af57ed9fSAtsushi Murai bp->offset += sizeof(struct fsmheader); 828af57ed9fSAtsushi Murai bp->cnt -= sizeof(struct fsmheader); 829af57ed9fSAtsushi Murai 830af57ed9fSAtsushi Murai codep = FsmCodes + lhp->code - 1; 831927145beSBrian Somers LogPrintf(LogLCP, "Received %s (%d) state = %s (%d)\n", 832927145beSBrian Somers codep->name, lhp->id, StateNames[fp->state], fp->state); 833927145beSBrian Somers if (LogIsKept(LogDEBUG)) 834af57ed9fSAtsushi Murai LogMemory(); 835af57ed9fSAtsushi Murai (codep->action)(fp, lhp, bp); 836927145beSBrian Somers if (LogIsKept(LogDEBUG)) 837af57ed9fSAtsushi Murai LogMemory(); 838af57ed9fSAtsushi Murai } 839