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