1706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*- 2706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org> 3706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * based on work by Toshiharu OHNO <tony-o@iij.ad.jp> 4706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Internet Initiative Japan, Inc (IIJ) 5706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * All rights reserved. 6706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 7706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Redistribution and use in source and binary forms, with or without 8706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * modification, are permitted provided that the following conditions 9706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * are met: 10706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 1. Redistributions of source code must retain the above copyright 11706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * notice, this list of conditions and the following disclaimer. 12706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 2. Redistributions in binary form must reproduce the above copyright 13706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * notice, this list of conditions and the following disclaimer in the 14706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * documentation and/or other materials provided with the distribution. 15706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 16706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * SUCH DAMAGE. 27706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 28706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * $FreeBSD: src/usr.sbin/ppp/fsm.c,v 1.71.26.1 2010/12/21 17:10:29 kensmith Exp $ 29706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 30706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 31706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/param.h> 32706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/in.h> 33706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/in_systm.h> 34706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/ip.h> 35706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/socket.h> 36706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/un.h> 37706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 38706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <string.h> 39706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <termios.h> 40706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 41706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "layer.h" 42706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ua.h" 43706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "mbuf.h" 44706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "log.h" 45706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "defs.h" 46706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "timer.h" 47706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "fsm.h" 48706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "iplist.h" 49706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "lqr.h" 50706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "hdlc.h" 51706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "throughput.h" 52706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "slcompress.h" 53706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ncpaddr.h" 54706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ipcp.h" 55706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "filter.h" 56706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "descriptor.h" 57706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "lcp.h" 58706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ccp.h" 59706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "link.h" 60706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "mp.h" 61706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NORADIUS 62706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "radius.h" 63706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif 64706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ipv6cp.h" 65706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ncp.h" 66706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "bundle.h" 67706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "async.h" 68706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "physical.h" 69706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "proto.h" 70706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 71706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void FsmSendConfigReq(struct fsm *); 72706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void FsmSendTerminateReq(struct fsm *); 73706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void FsmInitRestartCounter(struct fsm *, int); 74706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 75706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehtypedef void (recvfn)(struct fsm *, struct fsmheader *, struct mbuf *); 76706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic recvfn FsmRecvConfigReq, FsmRecvConfigAck, FsmRecvConfigNak, 77706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmRecvConfigRej, FsmRecvTermReq, FsmRecvTermAck, 78706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmRecvCodeRej, FsmRecvProtoRej, FsmRecvEchoReq, 79706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmRecvEchoRep, FsmRecvDiscReq, FsmRecvIdent, 80706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmRecvTimeRemain, FsmRecvResetReq, FsmRecvResetAck; 81706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 82706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic const struct fsmcodedesc { 83706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh recvfn *recv; 84706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh unsigned check_reqid : 1; 85706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh unsigned inc_reqid : 1; 86706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh const char *name; 87706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} FsmCodes[] = { 88706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh { FsmRecvConfigReq, 0, 0, "ConfigReq" }, 89706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh { FsmRecvConfigAck, 1, 1, "ConfigAck" }, 90706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh { FsmRecvConfigNak, 1, 1, "ConfigNak" }, 91706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh { FsmRecvConfigRej, 1, 1, "ConfigRej" }, 92706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh { FsmRecvTermReq, 0, 0, "TerminateReq" }, 93706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh { FsmRecvTermAck, 1, 1, "TerminateAck" }, 94706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh { FsmRecvCodeRej, 0, 0, "CodeRej" }, 95706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh { FsmRecvProtoRej, 0, 0, "ProtocolRej" }, 96706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh { FsmRecvEchoReq, 0, 0, "EchoRequest" }, 97706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh { FsmRecvEchoRep, 0, 0, "EchoReply" }, 98706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh { FsmRecvDiscReq, 0, 0, "DiscardReq" }, 99706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh { FsmRecvIdent, 0, 1, "Ident" }, 100706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh { FsmRecvTimeRemain,0, 0, "TimeRemain" }, 101706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh { FsmRecvResetReq, 0, 0, "ResetReq" }, 102706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh { FsmRecvResetAck, 0, 1, "ResetAck" } 103706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}; 104706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 105706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic const char * 106706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehCode2Nam(u_int code) 107706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 108706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (code == 0 || code > sizeof FsmCodes / sizeof FsmCodes[0]) 109706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return "Unknown"; 110706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return FsmCodes[code-1].name; 111706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 112706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 113706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehconst char * 114706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehState2Nam(u_int state) 115706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 116706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh static const char * const StateNames[] = { 117706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh "Initial", "Starting", "Closed", "Stopped", "Closing", "Stopping", 118706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh "Req-Sent", "Ack-Rcvd", "Ack-Sent", "Opened", 119706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh }; 120706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 121706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (state >= sizeof StateNames / sizeof StateNames[0]) 122706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return "unknown"; 123706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return StateNames[state]; 124706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 125706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 126706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 127706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehStoppedTimeout(void *v) 128706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 129706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct fsm *fp = (struct fsm *)v; 130706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 131706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, "%s: Stopped timer expired\n", fp->link->name); 132706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->OpenTimer.state == TIMER_RUNNING) { 133706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogWARN, "%s: %s: aborting open delay due to stopped timer\n", 134706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name, fp->name); 135706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh timer_Stop(&fp->OpenTimer); 136706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 137706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->state == ST_STOPPED) 138706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm2initial(fp); 139706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 140706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 141706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 142706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehfsm_Init(struct fsm *fp, const char *name, u_short proto, int mincode, 143706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int maxcode, int LogLevel, struct bundle *bundle, 144706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct link *l, const struct fsm_parent *parent, 145706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct fsm_callbacks *fn, const char * const timer_names[3]) 146706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 147706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->name = name; 148706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->proto = proto; 149706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->min_code = mincode; 150706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->max_code = maxcode; 151706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->state = fp->min_code > CODE_TERMACK ? ST_OPENED : ST_INITIAL; 152706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->reqid = 1; 153706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->restart = 1; 154706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->more.reqs = fp->more.naks = fp->more.rejs = 3; 155706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(&fp->FsmTimer, '\0', sizeof fp->FsmTimer); 156706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(&fp->OpenTimer, '\0', sizeof fp->OpenTimer); 157706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(&fp->StoppedTimer, '\0', sizeof fp->StoppedTimer); 158706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->LogLevel = LogLevel; 159706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link = l; 160706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->bundle = bundle; 161706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->parent = parent; 162706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->fn = fn; 163706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->FsmTimer.name = timer_names[0]; 164706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->OpenTimer.name = timer_names[1]; 165706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->StoppedTimer.name = timer_names[2]; 166706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 167706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 168706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 169706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehNewState(struct fsm *fp, int new) 170706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 171706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, "%s: State change %s --> %s\n", 172706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name, State2Nam(fp->state), State2Nam(new)); 173706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->state == ST_STOPPED && fp->StoppedTimer.state == TIMER_RUNNING) 174706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh timer_Stop(&fp->StoppedTimer); 175706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->state = new; 176706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if ((new >= ST_INITIAL && new <= ST_STOPPED) || (new == ST_OPENED)) { 177706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh timer_Stop(&fp->FsmTimer); 178706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (new == ST_STOPPED && fp->StoppedTimer.load) { 179706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh timer_Stop(&fp->StoppedTimer); 180706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->StoppedTimer.func = StoppedTimeout; 181706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->StoppedTimer.arg = (void *) fp; 182706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh timer_Start(&fp->StoppedTimer); 183706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 184706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 185706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 186706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 187706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 188706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehfsm_Output(struct fsm *fp, u_int code, u_int id, u_char *ptr, unsigned count, 189706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int mtype) 190706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 191706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int plen; 192706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct fsmheader lh; 193706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mbuf *bp; 194706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 195706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (log_IsKept(fp->LogLevel)) { 196706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, "%s: Send%s(%d) state = %s\n", 197706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name, Code2Nam(code), id, State2Nam(fp->state)); 198706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (code) { 199706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case CODE_CONFIGREQ: 200706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case CODE_CONFIGACK: 201706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case CODE_CONFIGREJ: 202706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case CODE_CONFIGNAK: 203706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->DecodeConfig)(fp, ptr, ptr + count, MODE_NOP, NULL); 204706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (count < sizeof(struct fsm_opt_hdr)) 205706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, " [EMPTY]\n"); 206706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 207706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 208706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 209706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 210706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh plen = sizeof(struct fsmheader) + count; 211706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lh.code = code; 212706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lh.id = id; 213706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lh.length = htons(plen); 214706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = m_get(plen, mtype); 215706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader)); 216706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (count) 217706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(MBUF_CTOP(bp) + sizeof(struct fsmheader), ptr, count); 218706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_DumpBp(LogDEBUG, "fsm_Output", bp); 219706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh link_PushPacket(fp->link, bp, fp->bundle, LINK_QUEUES(fp->link) - 1, 220706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->proto); 221706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 222706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (code == CODE_CONFIGREJ) 223706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lcp_SendIdentification(&fp->link->lcp); 224706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 225706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 226706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 227706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmOpenNow(void *v) 228706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 229706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct fsm *fp = (struct fsm *)v; 230706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 231706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh timer_Stop(&fp->OpenTimer); 232706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->state <= ST_STOPPED) { 233706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->state != ST_STARTING) { 234706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 235706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * In practice, we're only here in ST_STOPPED (when delaying the 236706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * first config request) or ST_CLOSED (when openmode == 0). 237706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 238706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * The ST_STOPPED bit is breaking the RFC already :-( 239706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 240706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * According to the RFC (1661) state transition table, a TLS isn't 241706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * required for an Open event when state == Closed, but the RFC 242706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * must be wrong as TLS hasn't yet been called (since the last TLF) 243706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * ie, Initial gets an `Up' event, Closing gets a RTA etc. 244706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 245706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerStart)(fp); 246706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerStart)(fp->parent->object, fp); 247706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 248706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmInitRestartCounter(fp, FSM_REQ_TIMER); 249706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendConfigReq(fp); 250706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_REQSENT); 251706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 252706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 253706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 254706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 255706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehfsm_Open(struct fsm *fp) 256706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 257706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (fp->state) { 258706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_INITIAL: 259706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_STARTING); 260706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerStart)(fp); 261706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerStart)(fp->parent->object, fp); 262706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 263706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSED: 264706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->open_mode == OPEN_PASSIVE) { 265706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_STOPPED); /* XXX: This is a hack ! */ 266706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else if (fp->open_mode > 0) { 267706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->open_mode > 1) 268706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, "%s: Entering STOPPED state for %d seconds\n", 269706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name, fp->open_mode); 270706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_STOPPED); /* XXX: This is a not-so-bad hack ! */ 271706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh timer_Stop(&fp->OpenTimer); 272706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->OpenTimer.load = fp->open_mode * SECTICKS; 273706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->OpenTimer.func = FsmOpenNow; 274706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->OpenTimer.arg = (void *)fp; 275706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh timer_Start(&fp->OpenTimer); 276706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else 277706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmOpenNow(fp); 278706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 279706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPED: /* XXX: restart option */ 280706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_REQSENT: 281706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKRCVD: 282706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKSENT: 283706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_OPENED: /* XXX: restart option */ 284706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 285706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSING: /* XXX: restart option */ 286706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPING: /* XXX: restart option */ 287706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_STOPPING); 288706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 289706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 290706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 291706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 292706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 293706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehfsm_Up(struct fsm *fp) 294706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 295706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (fp->state) { 296706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_INITIAL: 297706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, "FSM: Using \"%s\" as a transport\n", 298706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name); 299706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_CLOSED); 300706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 301706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STARTING: 302706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmInitRestartCounter(fp, FSM_REQ_TIMER); 303706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendConfigReq(fp); 304706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_REQSENT); 305706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 306706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh default: 307706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, "%s: Oops, Up at %s\n", 308706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name, State2Nam(fp->state)); 309706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 310706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 311706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 312706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 313706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 314706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehfsm_Down(struct fsm *fp) 315706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 316706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (fp->state) { 317706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSED: 318706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_INITIAL); 319706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 320706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSING: 321706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* This TLF contradicts the RFC (1661), which ``misses it out'' ! */ 322706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerFinish)(fp); 323706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_INITIAL); 324706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerFinish)(fp->parent->object, fp); 325706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 326706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPED: 327706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_STARTING); 328706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerStart)(fp); 329706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerStart)(fp->parent->object, fp); 330706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 331706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPING: 332706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_REQSENT: 333706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKRCVD: 334706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKSENT: 335706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_STARTING); 336706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 337706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_OPENED: 338706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerDown)(fp); 339706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_STARTING); 340706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerDown)(fp->parent->object, fp); 341706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 342706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 343706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 344706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 345706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 346706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehfsm_Close(struct fsm *fp) 347706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 348706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (fp->state) { 349706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STARTING: 350706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerFinish)(fp); 351706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_INITIAL); 352706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerFinish)(fp->parent->object, fp); 353706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 354706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPED: 355706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_CLOSED); 356706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 357706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPING: 358706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_CLOSING); 359706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 360706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_OPENED: 361706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerDown)(fp); 362706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->state == ST_OPENED) { 363706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmInitRestartCounter(fp, FSM_TRM_TIMER); 364706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendTerminateReq(fp); 365706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_CLOSING); 366706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerDown)(fp->parent->object, fp); 367706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 368706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 369706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_REQSENT: 370706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKRCVD: 371706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKSENT: 372706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmInitRestartCounter(fp, FSM_TRM_TIMER); 373706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendTerminateReq(fp); 374706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_CLOSING); 375706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 376706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 377706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 378706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 379706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/* 380706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Send functions 381706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 382706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 383706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmSendConfigReq(struct fsm *fp) 384706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 385706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->more.reqs-- > 0 && fp->restart-- > 0) { 386706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->SendConfigReq)(fp); 387706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh timer_Start(&fp->FsmTimer); /* Start restart timer */ 388706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { 389706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->more.reqs < 0) 390706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, "%s: Too many %s REQs sent - abandoning " 391706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh "negotiation\n", fp->link->name, fp->name); 392706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lcp_SendIdentification(&fp->link->lcp); 393706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Close(fp); 394706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 395706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 396706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 397706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 398706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmSendTerminateReq(struct fsm *fp) 399706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 400706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Output(fp, CODE_TERMREQ, fp->reqid, NULL, 0, MB_UNKNOWN); 401706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->SentTerminateReq)(fp); 402706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh timer_Start(&fp->FsmTimer); /* Start restart timer */ 403706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->restart--; /* Decrement restart counter */ 404706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 405706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 406706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/* 407706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Timeout actions 408706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 409706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 410706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmTimeout(void *v) 411706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 412706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct fsm *fp = (struct fsm *)v; 413706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 414706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->restart) { 415706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (fp->state) { 416706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSING: 417706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPING: 418706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendTerminateReq(fp); 419706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 420706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_REQSENT: 421706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKSENT: 422706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendConfigReq(fp); 423706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 424706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKRCVD: 425706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendConfigReq(fp); 426706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_REQSENT); 427706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 428706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 429706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh timer_Start(&fp->FsmTimer); 430706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { 431706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (fp->state) { 432706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSING: 433706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerFinish)(fp); 434706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_CLOSED); 435706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerFinish)(fp->parent->object, fp); 436706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 437706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPING: 438706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerFinish)(fp); 439706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_STOPPED); 440706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerFinish)(fp->parent->object, fp); 441706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 442706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_REQSENT: /* XXX: 3p */ 443706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKSENT: 444706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKRCVD: 445706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerFinish)(fp); 446706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_STOPPED); 447706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerFinish)(fp->parent->object, fp); 448706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 449706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 450706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 451706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 452706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 453706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 454706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmInitRestartCounter(struct fsm *fp, int what) 455706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 456706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh timer_Stop(&fp->FsmTimer); 457706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->FsmTimer.func = FsmTimeout; 458706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->FsmTimer.arg = (void *)fp; 459706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->InitRestartCounter)(fp, what); 460706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 461706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 462706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/* 463706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Actions when receive packets 464706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 465706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 466706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 467706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/* RCR */ 468706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 469706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct fsm_decode dec; 470706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int plen, flen; 471706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int ackaction = 0; 472706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_char *cp; 473706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 474706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = m_pullup(bp); 475706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh plen = m_length(bp); 476706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh flen = ntohs(lhp->length) - sizeof *lhp; 477706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (plen < flen) { 478706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogWARN, "%s: FsmRecvConfigReq: plen (%d) < flen (%d)\n", 479706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name, plen, flen); 480706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 481706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 482706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 483706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 484706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Some things must be done before we Decode the packet */ 485706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (fp->state) { 486706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_OPENED: 487706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerDown)(fp); 488706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 489706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 490706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dec.ackend = dec.ack; 491706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dec.nakend = dec.nak; 492706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dec.rejend = dec.rej; 493706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp = MBUF_CTOP(bp); 494706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->DecodeConfig)(fp, cp, cp + flen, MODE_REQ, &dec); 495706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (flen < (int)sizeof(struct fsm_opt_hdr)) 496706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, " [EMPTY]\n"); 497706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 498706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (dec.nakend == dec.nak && dec.rejend == dec.rej) 499706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ackaction = 1; 500706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 501706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Check and process easy case */ 502706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (fp->state) { 503706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_INITIAL: 504706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->proto == PROTO_CCP && fp->link->lcp.fsm.state == ST_OPENED) { 505706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 506706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * ccp_SetOpenMode() leaves us in initial if we're disabling 507706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * & denying everything. 508706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 509706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = m_prepend(bp, lhp, sizeof *lhp, 2); 510706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = proto_Prepend(bp, fp->proto, 0, 0); 511706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = m_pullup(bp); 512706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lcp_SendProtoRej(&fp->link->lcp, MBUF_CTOP(bp), bp->m_len); 513706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 514706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 515706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 516706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Drop through */ 517706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STARTING: 518706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, "%s: Oops, RCR in %s.\n", 519706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name, State2Nam(fp->state)); 520706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 521706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 522706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSED: 523706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->SendTerminateAck)(fp, lhp->id); 524706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 525706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 526706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSING: 527706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, "%s: Error: Got ConfigReq while state = %s\n", 528706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name, State2Nam(fp->state)); 529706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPING: 530706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 531706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 532706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPED: 533706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmInitRestartCounter(fp, FSM_REQ_TIMER); 534706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Drop through */ 535706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_OPENED: 536706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendConfigReq(fp); 537706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 538706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 539706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 540706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (dec.rejend != dec.rej) 541706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Output(fp, CODE_CONFIGREJ, lhp->id, dec.rej, dec.rejend - dec.rej, 542706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh MB_UNKNOWN); 543706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (dec.nakend != dec.nak) 544706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Output(fp, CODE_CONFIGNAK, lhp->id, dec.nak, dec.nakend - dec.nak, 545706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh MB_UNKNOWN); 546706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (ackaction) 547706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Output(fp, CODE_CONFIGACK, lhp->id, dec.ack, dec.ackend - dec.ack, 548706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh MB_UNKNOWN); 549706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 550706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (fp->state) { 551706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPED: 552706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 553706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * According to the RFC (1661) state transition table, a TLS isn't 554706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * required for a RCR when state == ST_STOPPED, but the RFC 555706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * must be wrong as TLS hasn't yet been called (since the last TLF) 556706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 557706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerStart)(fp); 558706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerStart)(fp->parent->object, fp); 559706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* FALLTHROUGH */ 560706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 561706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_OPENED: 562706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (ackaction) 563706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_ACKSENT); 564706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else 565706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_REQSENT); 566706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerDown)(fp->parent->object, fp); 567706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 568706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_REQSENT: 569706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (ackaction) 570706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_ACKSENT); 571706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 572706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKRCVD: 573706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (ackaction) { 574706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_OPENED); 575706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if ((*fp->fn->LayerUp)(fp)) 576706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerUp)(fp->parent->object, fp); 577706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else { 578706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerDown)(fp); 579706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmInitRestartCounter(fp, FSM_TRM_TIMER); 580706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendTerminateReq(fp); 581706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_CLOSING); 582706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lcp_SendIdentification(&fp->link->lcp); 583706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 584706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 585706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 586706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKSENT: 587706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!ackaction) 588706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_REQSENT); 589706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 590706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 591706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 592706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 593706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (dec.rejend != dec.rej && --fp->more.rejs <= 0) { 594706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, "%s: Too many %s REJs sent - abandoning negotiation\n", 595706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name, fp->name); 596706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lcp_SendIdentification(&fp->link->lcp); 597706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Close(fp); 598706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 599706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 600706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (dec.nakend != dec.nak && --fp->more.naks <= 0) { 601706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, "%s: Too many %s NAKs sent - abandoning negotiation\n", 602706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name, fp->name); 603706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lcp_SendIdentification(&fp->link->lcp); 604706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Close(fp); 605706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 606706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 607706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 608706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 609706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmRecvConfigAck(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 610706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/* RCA */ 611706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 612706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct fsm_decode dec; 613706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int plen, flen; 614706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_char *cp; 615706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 616706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh plen = m_length(bp); 617706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh flen = ntohs(lhp->length) - sizeof *lhp; 618706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (plen < flen) { 619706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 620706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 621706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 622706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 623706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = m_pullup(bp); 624706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dec.ackend = dec.ack; 625706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dec.nakend = dec.nak; 626706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dec.rejend = dec.rej; 627706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp = MBUF_CTOP(bp); 628706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->DecodeConfig)(fp, cp, cp + flen, MODE_ACK, &dec); 629706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (flen < (int)sizeof(struct fsm_opt_hdr)) 630706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, " [EMPTY]\n"); 631706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 632706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (fp->state) { 633706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSED: 634706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPED: 635706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->SendTerminateAck)(fp, lhp->id); 636706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 637706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSING: 638706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPING: 639706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 640706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_REQSENT: 641706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmInitRestartCounter(fp, FSM_REQ_TIMER); 642706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_ACKRCVD); 643706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 644706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKRCVD: 645706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendConfigReq(fp); 646706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_REQSENT); 647706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 648706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKSENT: 649706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmInitRestartCounter(fp, FSM_REQ_TIMER); 650706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_OPENED); 651706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if ((*fp->fn->LayerUp)(fp)) 652706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerUp)(fp->parent->object, fp); 653706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else { 654706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerDown)(fp); 655706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmInitRestartCounter(fp, FSM_TRM_TIMER); 656706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendTerminateReq(fp); 657706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_CLOSING); 658706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lcp_SendIdentification(&fp->link->lcp); 659706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 660706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 661706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_OPENED: 662706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerDown)(fp); 663706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendConfigReq(fp); 664706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_REQSENT); 665706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerDown)(fp->parent->object, fp); 666706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 667706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 668706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 669706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 670706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 671706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 672706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmRecvConfigNak(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 673706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/* RCN */ 674706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 675706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct fsm_decode dec; 676706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int plen, flen; 677706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_char *cp; 678706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 679706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh plen = m_length(bp); 680706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh flen = ntohs(lhp->length) - sizeof *lhp; 681706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (plen < flen) { 682706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 683706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 684706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 685706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 686706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 687706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Check and process easy case 688706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 689706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (fp->state) { 690706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_INITIAL: 691706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STARTING: 692706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, "%s: Oops, RCN in %s.\n", 693706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name, State2Nam(fp->state)); 694706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 695706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 696706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSED: 697706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPED: 698706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->SendTerminateAck)(fp, lhp->id); 699706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 700706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 701706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSING: 702706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPING: 703706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 704706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 705706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 706706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 707706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = m_pullup(bp); 708706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dec.ackend = dec.ack; 709706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dec.nakend = dec.nak; 710706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dec.rejend = dec.rej; 711706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp = MBUF_CTOP(bp); 712706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->DecodeConfig)(fp, cp, cp + flen, MODE_NAK, &dec); 713706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (flen < (int)sizeof(struct fsm_opt_hdr)) 714706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, " [EMPTY]\n"); 715706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 716706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (fp->state) { 717706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_REQSENT: 718706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKSENT: 719706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmInitRestartCounter(fp, FSM_REQ_TIMER); 720706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendConfigReq(fp); 721706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 722706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_OPENED: 723706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerDown)(fp); 724706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendConfigReq(fp); 725706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_REQSENT); 726706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerDown)(fp->parent->object, fp); 727706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 728706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKRCVD: 729706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendConfigReq(fp); 730706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_REQSENT); 731706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 732706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 733706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 734706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 735706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 736706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 737706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 738706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmRecvTermReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 739706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/* RTR */ 740706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 741706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (fp->state) { 742706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_INITIAL: 743706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STARTING: 744706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, "%s: Oops, RTR in %s\n", 745706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name, State2Nam(fp->state)); 746706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 747706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSED: 748706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPED: 749706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSING: 750706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPING: 751706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_REQSENT: 752706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->SendTerminateAck)(fp, lhp->id); 753706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 754706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKRCVD: 755706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKSENT: 756706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->SendTerminateAck)(fp, lhp->id); 757706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_REQSENT); 758706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 759706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_OPENED: 760706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerDown)(fp); 761706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->SendTerminateAck)(fp, lhp->id); 762706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmInitRestartCounter(fp, FSM_TRM_TIMER); 763706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh timer_Start(&fp->FsmTimer); /* Start restart timer */ 764706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->restart = 0; 765706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_STOPPING); 766706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerDown)(fp->parent->object, fp); 767706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* A delayed ST_STOPPED is now scheduled */ 768706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 769706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 770706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 771706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 772706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 773706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 774706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmRecvTermAck(struct fsm *fp, struct fsmheader *lhp __unused, struct mbuf *bp) 775706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/* RTA */ 776706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 777706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (fp->state) { 778706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSING: 779706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerFinish)(fp); 780706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_CLOSED); 781706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerFinish)(fp->parent->object, fp); 782706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 783706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPING: 784706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerFinish)(fp); 785706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_STOPPED); 786706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerFinish)(fp->parent->object, fp); 787706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 788706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKRCVD: 789706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_REQSENT); 790706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 791706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_OPENED: 792706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerDown)(fp); 793706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendConfigReq(fp); 794706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_REQSENT); 795706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerDown)(fp->parent->object, fp); 796706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 797706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 798706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 799706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 800706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 801706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 802706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmRecvConfigRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 803706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/* RCJ */ 804706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 805706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct fsm_decode dec; 806706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh size_t plen; 807706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int flen; 808706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_char *cp; 809706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 810706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh plen = m_length(bp); 811706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh flen = ntohs(lhp->length) - sizeof *lhp; 812706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if ((int)plen < flen) { 813706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 814706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 815706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 816706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 817706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lcp_SendIdentification(&fp->link->lcp); 818706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 819706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 820706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Check and process easy case 821706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 822706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (fp->state) { 823706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_INITIAL: 824706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STARTING: 825706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, "%s: Oops, RCJ in %s.\n", 826706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name, State2Nam(fp->state)); 827706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 828706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 829706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSED: 830706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPED: 831706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->SendTerminateAck)(fp, lhp->id); 832706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 833706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 834706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSING: 835706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_STOPPING: 836706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 837706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 838706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 839706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 840706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = m_pullup(bp); 841706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dec.ackend = dec.ack; 842706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dec.nakend = dec.nak; 843706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dec.rejend = dec.rej; 844706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp = MBUF_CTOP(bp); 845706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->DecodeConfig)(fp, cp, cp + flen, MODE_REJ, &dec); 846706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (flen < (int)sizeof(struct fsm_opt_hdr)) 847706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, " [EMPTY]\n"); 848706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 849706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (fp->state) { 850706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_REQSENT: 851706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKSENT: 852706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmInitRestartCounter(fp, FSM_REQ_TIMER); 853706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendConfigReq(fp); 854706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 855706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_OPENED: 856706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerDown)(fp); 857706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendConfigReq(fp); 858706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_REQSENT); 859706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerDown)(fp->parent->object, fp); 860706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 861706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_ACKRCVD: 862706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendConfigReq(fp); 863706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_REQSENT); 864706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 865706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 866706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 867706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 868706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 869706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 870706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmRecvCodeRej(struct fsm *fp __unused, struct fsmheader *lhp __unused, 871706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mbuf *bp) 872706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 873706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 874706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 875706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 876706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 877706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmRecvProtoRej(struct fsm *fp, struct fsmheader *lhp __unused, struct mbuf *bp) 878706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 879706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct physical *p = link2physical(fp->link); 880706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_short proto; 881706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 882706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (m_length(bp) < 2) { 883706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 884706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 885706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 886706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = mbuf_Read(bp, &proto, 2); 887706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh proto = ntohs(proto); 888706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, "%s: -- Protocol 0x%04x (%s) was rejected!\n", 889706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name, proto, hdlc_Protocol2Nam(proto)); 890706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 891706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (proto) { 892706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case PROTO_LQR: 893706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (p) 894706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lqr_Stop(p, LQM_LQR); 895706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else 896706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogERROR, "%s: FsmRecvProtoRej: Not a physical link !\n", 897706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name); 898706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 899706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case PROTO_CCP: 900706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->proto == PROTO_LCP) { 901706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp = &fp->link->ccp.fsm; 902706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Despite the RFC (1661), don't do an out-of-place TLF */ 903706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* (*fp->fn->LayerFinish)(fp); */ 904706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (fp->state) { 905706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSED: 906706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ST_CLOSING: 907706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_CLOSED); 908706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 909706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh default: 910706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_STOPPED); 911706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 912706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 913706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* See above */ 914706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* (*fp->parent->LayerFinish)(fp->parent->object, fp); */ 915706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 916706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 917706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case PROTO_IPCP: 918706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->proto == PROTO_LCP) { 919706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, "%s: IPCP protocol reject closes IPCP !\n", 920706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name); 921706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Close(&fp->bundle->ncp.ipcp.fsm); 922706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 923706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 924706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NOINET6 925706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case PROTO_IPV6CP: 926706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->proto == PROTO_LCP) { 927706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, "%s: IPV6CP protocol reject closes IPV6CP !\n", 928706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name); 929706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Close(&fp->bundle->ncp.ipv6cp.fsm); 930706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 931706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 932706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif 933706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case PROTO_MP: 934706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->proto == PROTO_LCP) { 935706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct lcp *lcp = fsm2lcp(fp); 936706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 937706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (lcp->want_mrru && lcp->his_mrru) { 938706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, "%s: MP protocol reject is fatal !\n", 939706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name); 940706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Close(fp); 941706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 942706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 943706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 944706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 945706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 946706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 947706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 948706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 949706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmRecvEchoReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 950706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 951706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct lcp *lcp = fsm2lcp(fp); 952706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_char *cp; 953706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_int32_t magic; 954706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 955706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = m_pullup(bp); 956706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_settype(bp, MB_ECHOIN); 957706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 958706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (lcp && ntohs(lhp->length) - sizeof *lhp >= 4) { 959706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp = MBUF_CTOP(bp); 960706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ua_ntohl(cp, &magic); 961706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (magic != lcp->his_magic) { 962706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, "%s: RecvEchoReq: magic 0x%08lx is wrong," 963706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh " expecting 0x%08lx\n", fp->link->name, (u_long)magic, 964706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (u_long)lcp->his_magic); 965706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* XXX: We should send terminate request */ 966706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 967706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->state == ST_OPENED) { 968706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ua_htonl(&lcp->want_magic, cp); /* local magic */ 969706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Output(fp, CODE_ECHOREP, lhp->id, cp, 970706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ntohs(lhp->length) - sizeof *lhp, MB_ECHOOUT); 971706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 972706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 973706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 974706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 975706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 976706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 977706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmRecvEchoRep(struct fsm *fp, struct fsmheader *lhp __unused, struct mbuf *bp) 978706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 979706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fsm2lcp(fp)) 980706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = lqr_RecvEcho(fp, bp); 981706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 982706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 983706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 984706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 985706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 986706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmRecvDiscReq(struct fsm *fp __unused, struct fsmheader *lhp __unused, 987706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mbuf *bp) 988706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 989706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 990706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 991706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 992706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 993706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmRecvIdent(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 994706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 995706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_int32_t magic; 996706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_short len; 997706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_char *cp; 998706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 999706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh len = ntohs(lhp->length) - sizeof *lhp; 1000706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (len >= 4) { 1001706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = m_pullup(m_append(bp, "", 1)); 1002706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp = MBUF_CTOP(bp); 1003706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ua_ntohl(cp, &magic); 1004706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (magic != fp->link->lcp.his_magic) 1005706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, "%s: RecvIdent: magic 0x%08lx is wrong," 1006706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh " expecting 0x%08lx\n", fp->link->name, (u_long)magic, 1007706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (u_long)fp->link->lcp.his_magic); 1008706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp[len] = '\0'; 1009706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lcp_RecvIdentification(&fp->link->lcp, cp + 4); 1010706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1011706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 1012706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1013706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1014706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 1015706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmRecvTimeRemain(struct fsm *fp __unused, struct fsmheader *lhp __unused, 1016706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mbuf *bp) 1017706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1018706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 1019706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1020706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1021706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 1022706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmRecvResetReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 1023706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1024706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if ((*fp->fn->RecvResetReq)(fp)) { 1025706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 1026706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * All sendable compressed packets are queued in the first (lowest 1027706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * priority) modem output queue.... dump 'em to the priority queue 1028706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * so that they arrive at the peer before our ResetAck. 1029706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 1030706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh link_SequenceQueue(fp->link); 1031706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Output(fp, CODE_RESETACK, lhp->id, NULL, 0, MB_CCPOUT); 1032706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1033706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 1034706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1035706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1036706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 1037706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehFsmRecvResetAck(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 1038706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1039706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->RecvResetAck)(fp, lhp->id); 1040706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 1041706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1042706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1043706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 1044706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehfsm_Input(struct fsm *fp, struct mbuf *bp) 1045706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1046706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh size_t len; 1047706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct fsmheader lh; 1048706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh const struct fsmcodedesc *codep; 1049706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1050706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh len = m_length(bp); 1051706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (len < sizeof(struct fsmheader)) { 1052706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 1053706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 1054706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1055706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = mbuf_Read(bp, &lh, sizeof lh); 1056706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1057706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (ntohs(lh.length) > len) { 1058706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogWARN, "%s: Oops: Got %zu bytes but %d byte payload " 1059706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh "- dropped\n", fp->link->name, len, (int)ntohs(lh.length)); 1060706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 1061706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 1062706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1063706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1064706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (lh.code < fp->min_code || lh.code > fp->max_code || 1065706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lh.code > sizeof FsmCodes / sizeof *FsmCodes) { 1066706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 1067706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Use a private id. This is really a response-type packet, but we 1068706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * MUST send a unique id for each REQ.... 1069706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 1070706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh static u_char id; 1071706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1072706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = m_prepend(bp, &lh, sizeof lh, 0); 1073706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = m_pullup(bp); 1074706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Output(fp, CODE_CODEREJ, id++, MBUF_CTOP(bp), bp->m_len, MB_UNKNOWN); 1075706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 1076706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 1077706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1078706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1079706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh codep = FsmCodes + lh.code - 1; 1080706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (lh.id != fp->reqid && codep->check_reqid && 1081706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh Enabled(fp->bundle, OPT_IDCHECK)) { 1082706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, "%s: Recv%s(%d), dropped (expected %d)\n", 1083706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name, codep->name, lh.id, fp->reqid); 1084706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 1085706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1086706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1087706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, "%s: Recv%s(%d) state = %s\n", 1088706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name, codep->name, lh.id, State2Nam(fp->state)); 1089706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1090706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (codep->inc_reqid && (lh.id == fp->reqid || 1091706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (!Enabled(fp->bundle, OPT_IDCHECK) && codep->check_reqid))) 1092706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->reqid++; /* That's the end of that ``exchange''.... */ 1093706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1094706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*codep->recv)(fp, &lh, bp); 1095706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1096706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1097706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehint 1098706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehfsm_NullRecvResetReq(struct fsm *fp) 1099706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1100706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, "%s: Oops - received unexpected reset req\n", 1101706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name); 1102706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 1; 1103706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1104706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1105706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 1106706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehfsm_NullRecvResetAck(struct fsm *fp, u_char id __unused) 1107706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1108706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(fp->LogLevel, "%s: Oops - received unexpected reset ack\n", 1109706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->link->name); 1110706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1111706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1112706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 1113706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehfsm_Reopen(struct fsm *fp) 1114706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1115706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->state == ST_OPENED) { 1116706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->fn->LayerDown)(fp); 1117706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmInitRestartCounter(fp, FSM_REQ_TIMER); 1118706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FsmSendConfigReq(fp); 1119706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NewState(fp, ST_REQSENT); 1120706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*fp->parent->LayerDown)(fp->parent->object, fp); 1121706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1122706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1123706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1124706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 1125706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehfsm2initial(struct fsm *fp) 1126706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1127706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh timer_Stop(&fp->FsmTimer); 1128706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh timer_Stop(&fp->OpenTimer); 1129706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh timer_Stop(&fp->StoppedTimer); 1130706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->state == ST_STOPPED) 1131706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Close(fp); 1132706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->state > ST_INITIAL) 1133706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Down(fp); 1134706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->state > ST_INITIAL) 1135706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Close(fp); 1136706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1137706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1138706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct fsm_opt * 1139706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehfsm_readopt(u_char **cp) 1140706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1141706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct fsm_opt *o = (struct fsm_opt *)*cp; 1142706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1143706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (o->hdr.len < sizeof(struct fsm_opt_hdr)) { 1144706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogERROR, "Bad option length %d (out of phase?)\n", o->hdr.len); 1145706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return NULL; 1146706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1147706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1148706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *cp += o->hdr.len; 1149706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1150706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (o->hdr.len > sizeof(struct fsm_opt)) { 1151706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogERROR, "Warning: Truncating option length from %d to %d\n", 1152706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh o->hdr.len, (int)sizeof(struct fsm_opt)); 1153706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh o->hdr.len = sizeof(struct fsm_opt); 1154706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1155706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1156706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return o; 1157706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1158706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1159706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int 1160706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehfsm_opt(u_char *opt, int optlen, const struct fsm_opt *o) 1161706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1162706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh unsigned cplen = o->hdr.len; 1163706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1164706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (optlen < (int)sizeof(struct fsm_opt_hdr)) 1165706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh optlen = 0; 1166706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1167706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if ((int)cplen > optlen) { 1168706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogERROR, "Can't REJ length %d - trunating to %d\n", 1169706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cplen, optlen); 1170706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cplen = optlen; 1171706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1172706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(opt, o, cplen); 1173706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (cplen) 1174706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh opt[1] = cplen; 1175706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1176706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return cplen; 1177706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1178706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1179706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 1180706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehfsm_rej(struct fsm_decode *dec, const struct fsm_opt *o) 1181706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1182706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!dec) 1183706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 1184706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dec->rejend += fsm_opt(dec->rejend, FSM_OPTLEN - (dec->rejend - dec->rej), o); 1185706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1186706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1187706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 1188706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehfsm_ack(struct fsm_decode *dec, const struct fsm_opt *o) 1189706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1190706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!dec) 1191706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 1192706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dec->ackend += fsm_opt(dec->ackend, FSM_OPTLEN - (dec->ackend - dec->ack), o); 1193706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1194706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1195706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 1196706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehfsm_nak(struct fsm_decode *dec, const struct fsm_opt *o) 1197706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1198706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!dec) 1199706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 1200706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dec->nakend += fsm_opt(dec->nakend, FSM_OPTLEN - (dec->nakend - dec->nak), o); 1201706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1202706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1203706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 1204706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehfsm_opt_normalise(struct fsm_decode *dec) 1205706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1206706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (dec->rejend != dec->rej) { 1207706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* rejects are preferred */ 1208706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dec->ackend = dec->ack; 1209706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dec->nakend = dec->nak; 1210706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else if (dec->nakend != dec->nak) 1211706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* then NAKs */ 1212706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dec->ackend = dec->ack; 1213706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1214