]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/ppp/fsm.c
This commit was generated by cvs2svn to compensate for changes in r76589,
[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     if (fp->state == ST_OPENED) {
353       FsmInitRestartCounter(fp, FSM_TRM_TIMER);
354       FsmSendTerminateReq(fp);
355       NewState(fp, ST_CLOSING);
356       (*fp->parent->LayerDown)(fp->parent->object, fp);
357     }
358     break;
359   case ST_REQSENT:
360   case ST_ACKRCVD:
361   case ST_ACKSENT:
362     FsmInitRestartCounter(fp, FSM_TRM_TIMER);
363     FsmSendTerminateReq(fp);
364     NewState(fp, ST_CLOSING);
365     break;
366   }
367 }
368
369 /*
370  *      Send functions
371  */
372 static void
373 FsmSendConfigReq(struct fsm *fp)
374 {
375   if (fp->more.reqs-- > 0 && fp->restart-- > 0) {
376     (*fp->fn->SendConfigReq)(fp);
377     timer_Start(&fp->FsmTimer);         /* Start restart timer */
378   } else {
379     if (fp->more.reqs < 0)
380       log_Printf(LogPHASE, "%s: Too many %s REQs sent - abandoning "
381                  "negotiation\n", fp->link->name, fp->name);
382     lcp_SendIdentification(&fp->link->lcp);
383     fsm_Close(fp);
384   }
385 }
386
387 static void
388 FsmSendTerminateReq(struct fsm *fp)
389 {
390   fsm_Output(fp, CODE_TERMREQ, fp->reqid, NULL, 0, MB_UNKNOWN);
391   (*fp->fn->SentTerminateReq)(fp);
392   timer_Start(&fp->FsmTimer);   /* Start restart timer */
393   fp->restart--;                /* Decrement restart counter */
394 }
395
396 /*
397  *      Timeout actions
398  */
399 static void
400 FsmTimeout(void *v)
401 {
402   struct fsm *fp = (struct fsm *)v;
403
404   if (fp->restart) {
405     switch (fp->state) {
406     case ST_CLOSING:
407     case ST_STOPPING:
408       FsmSendTerminateReq(fp);
409       break;
410     case ST_REQSENT:
411     case ST_ACKSENT:
412       FsmSendConfigReq(fp);
413       break;
414     case ST_ACKRCVD:
415       FsmSendConfigReq(fp);
416       NewState(fp, ST_REQSENT);
417       break;
418     }
419     timer_Start(&fp->FsmTimer);
420   } else {
421     switch (fp->state) {
422     case ST_CLOSING:
423       (*fp->fn->LayerFinish)(fp);
424       NewState(fp, ST_CLOSED);
425       (*fp->parent->LayerFinish)(fp->parent->object, fp);
426       break;
427     case ST_STOPPING:
428       (*fp->fn->LayerFinish)(fp);
429       NewState(fp, ST_STOPPED);
430       (*fp->parent->LayerFinish)(fp->parent->object, fp);
431       break;
432     case ST_REQSENT:            /* XXX: 3p */
433     case ST_ACKSENT:
434     case ST_ACKRCVD:
435       (*fp->fn->LayerFinish)(fp);
436       NewState(fp, ST_STOPPED);
437       (*fp->parent->LayerFinish)(fp->parent->object, fp);
438       break;
439     }
440   }
441 }
442
443 static void
444 FsmInitRestartCounter(struct fsm *fp, int what)
445 {
446   timer_Stop(&fp->FsmTimer);
447   fp->FsmTimer.func = FsmTimeout;
448   fp->FsmTimer.arg = (void *)fp;
449   (*fp->fn->InitRestartCounter)(fp, what);
450 }
451
452 /*
453  * Actions when receive packets
454  */
455 static void
456 FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
457 /* RCR */
458 {
459   struct fsm_decode dec;
460   int plen, flen;
461   int ackaction = 0;
462
463   plen = m_length(bp);
464   flen = ntohs(lhp->length) - sizeof *lhp;
465   if (plen < flen) {
466     log_Printf(LogWARN, "%s: FsmRecvConfigReq: plen (%d) < flen (%d)\n",
467               fp->link->name, plen, flen);
468     m_freem(bp);
469     return;
470   }
471
472   /* Check and process easy case */
473   switch (fp->state) {
474   case ST_INITIAL:
475     if (fp->proto == PROTO_CCP && fp->link->lcp.fsm.state == ST_OPENED) {
476       /*
477        * ccp_SetOpenMode() leaves us in initial if we're disabling
478        * & denying everything.
479        */
480       bp = m_prepend(bp, lhp, sizeof *lhp, 2);
481       bp = proto_Prepend(bp, fp->proto, 0, 0);
482       bp = m_pullup(bp);
483       lcp_SendProtoRej(&fp->link->lcp, MBUF_CTOP(bp), bp->m_len);
484       m_freem(bp);
485       return;
486     }
487     /* Drop through */
488   case ST_STARTING:
489     log_Printf(fp->LogLevel, "%s: Oops, RCR in %s.\n",
490               fp->link->name, State2Nam(fp->state));
491     m_freem(bp);
492     return;
493   case ST_CLOSED:
494     (*fp->fn->SendTerminateAck)(fp, lhp->id);
495     m_freem(bp);
496     return;
497   case ST_CLOSING:
498     log_Printf(fp->LogLevel, "%s: Error: Got ConfigReq while state = %s\n",
499               fp->link->name, State2Nam(fp->state));
500   case ST_STOPPING:
501     m_freem(bp);
502     return;
503   case ST_OPENED:
504     (*fp->fn->LayerDown)(fp);
505     (*fp->parent->LayerDown)(fp->parent->object, fp);
506     break;
507   }
508
509   bp = m_pullup(bp);
510   dec.ackend = dec.ack;
511   dec.nakend = dec.nak;
512   dec.rejend = dec.rej;
513   (*fp->fn->DecodeConfig)(fp, MBUF_CTOP(bp), flen, MODE_REQ, &dec);
514   if (flen < sizeof(struct fsmconfig))
515     log_Printf(fp->LogLevel, "  [EMPTY]\n");
516
517   if (dec.nakend == dec.nak && dec.rejend == dec.rej)
518     ackaction = 1;
519
520   switch (fp->state) {
521   case ST_STOPPED:
522     FsmInitRestartCounter(fp, FSM_REQ_TIMER);
523     /* Fall through */
524
525   case ST_OPENED:
526     FsmSendConfigReq(fp);
527     break;
528   }
529
530   if (dec.rejend != dec.rej)
531     fsm_Output(fp, CODE_CONFIGREJ, lhp->id, dec.rej, dec.rejend - dec.rej,
532                MB_UNKNOWN);
533   if (dec.nakend != dec.nak)
534     fsm_Output(fp, CODE_CONFIGNAK, lhp->id, dec.nak, dec.nakend - dec.nak,
535                MB_UNKNOWN);
536   if (ackaction)
537     fsm_Output(fp, CODE_CONFIGACK, lhp->id, dec.ack, dec.ackend - dec.ack,
538                MB_UNKNOWN);
539
540   switch (fp->state) {
541   case ST_STOPPED:
542       /*
543        * According to the RFC (1661) state transition table, a TLS isn't
544        * required for a RCR when state == ST_STOPPED, but the RFC
545        * must be wrong as TLS hasn't yet been called (since the last TLF)
546        */
547     (*fp->fn->LayerStart)(fp);
548     (*fp->parent->LayerStart)(fp->parent->object, fp);
549     /* Fall through */
550
551   case ST_OPENED:
552     if (ackaction)
553       NewState(fp, ST_ACKSENT);
554     else
555       NewState(fp, ST_REQSENT);
556     break;
557   case ST_REQSENT:
558     if (ackaction)
559       NewState(fp, ST_ACKSENT);
560     break;
561   case ST_ACKRCVD:
562     if (ackaction) {
563       NewState(fp, ST_OPENED);
564       if ((*fp->fn->LayerUp)(fp))
565         (*fp->parent->LayerUp)(fp->parent->object, fp);
566       else {
567         (*fp->fn->LayerDown)(fp);
568         FsmInitRestartCounter(fp, FSM_TRM_TIMER);
569         FsmSendTerminateReq(fp);
570         NewState(fp, ST_CLOSING);
571         lcp_SendIdentification(&fp->link->lcp);
572       }
573     }
574     break;
575   case ST_ACKSENT:
576     if (!ackaction)
577       NewState(fp, ST_REQSENT);
578     break;
579   }
580   m_freem(bp);
581
582   if (dec.rejend != dec.rej && --fp->more.rejs <= 0) {
583     log_Printf(LogPHASE, "%s: Too many %s REJs sent - abandoning negotiation\n",
584                fp->link->name, fp->name);
585     lcp_SendIdentification(&fp->link->lcp);
586     fsm_Close(fp);
587   }
588
589   if (dec.nakend != dec.nak && --fp->more.naks <= 0) {
590     log_Printf(LogPHASE, "%s: Too many %s NAKs sent - abandoning negotiation\n",
591                fp->link->name, fp->name);
592     lcp_SendIdentification(&fp->link->lcp);
593     fsm_Close(fp);
594   }
595 }
596
597 static void
598 FsmRecvConfigAck(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
599 /* RCA */
600 {
601   switch (fp->state) {
602     case ST_CLOSED:
603     case ST_STOPPED:
604     (*fp->fn->SendTerminateAck)(fp, lhp->id);
605     break;
606   case ST_CLOSING:
607   case ST_STOPPING:
608     break;
609   case ST_REQSENT:
610     FsmInitRestartCounter(fp, FSM_REQ_TIMER);
611     NewState(fp, ST_ACKRCVD);
612     break;
613   case ST_ACKRCVD:
614     FsmSendConfigReq(fp);
615     NewState(fp, ST_REQSENT);
616     break;
617   case ST_ACKSENT:
618     FsmInitRestartCounter(fp, FSM_REQ_TIMER);
619     NewState(fp, ST_OPENED);
620     if ((*fp->fn->LayerUp)(fp))
621       (*fp->parent->LayerUp)(fp->parent->object, fp);
622     else {
623       (*fp->fn->LayerDown)(fp);
624       FsmInitRestartCounter(fp, FSM_TRM_TIMER);
625       FsmSendTerminateReq(fp);
626       NewState(fp, ST_CLOSING);
627       lcp_SendIdentification(&fp->link->lcp);
628     }
629     break;
630   case ST_OPENED:
631     (*fp->fn->LayerDown)(fp);
632     FsmSendConfigReq(fp);
633     NewState(fp, ST_REQSENT);
634     (*fp->parent->LayerDown)(fp->parent->object, fp);
635     break;
636   }
637   m_freem(bp);
638 }
639
640 static void
641 FsmRecvConfigNak(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
642 /* RCN */
643 {
644   struct fsm_decode dec;
645   int plen, flen;
646
647   plen = m_length(bp);
648   flen = ntohs(lhp->length) - sizeof *lhp;
649   if (plen < flen) {
650     m_freem(bp);
651     return;
652   }
653
654   /*
655    * Check and process easy case
656    */
657   switch (fp->state) {
658   case ST_INITIAL:
659   case ST_STARTING:
660     log_Printf(fp->LogLevel, "%s: Oops, RCN in %s.\n",
661               fp->link->name, State2Nam(fp->state));
662     m_freem(bp);
663     return;
664   case ST_CLOSED:
665   case ST_STOPPED:
666     (*fp->fn->SendTerminateAck)(fp, lhp->id);
667     m_freem(bp);
668     return;
669   case ST_CLOSING:
670   case ST_STOPPING:
671     m_freem(bp);
672     return;
673   }
674
675   bp = m_pullup(bp);
676   dec.ackend = dec.ack;
677   dec.nakend = dec.nak;
678   dec.rejend = dec.rej;
679   (*fp->fn->DecodeConfig)(fp, MBUF_CTOP(bp), flen, MODE_NAK, &dec);
680   if (flen < sizeof(struct fsmconfig))
681     log_Printf(fp->LogLevel, "  [EMPTY]\n");
682
683   switch (fp->state) {
684   case ST_REQSENT:
685   case ST_ACKSENT:
686     FsmInitRestartCounter(fp, FSM_REQ_TIMER);
687     FsmSendConfigReq(fp);
688     break;
689   case ST_OPENED:
690     (*fp->fn->LayerDown)(fp);
691     FsmSendConfigReq(fp);
692     NewState(fp, ST_REQSENT);
693     (*fp->parent->LayerDown)(fp->parent->object, fp);
694     break;
695   case ST_ACKRCVD:
696     FsmSendConfigReq(fp);
697     NewState(fp, ST_REQSENT);
698     break;
699   }
700
701   m_freem(bp);
702 }
703
704 static void
705 FsmRecvTermReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
706 /* RTR */
707 {
708   switch (fp->state) {
709   case ST_INITIAL:
710   case ST_STARTING:
711     log_Printf(fp->LogLevel, "%s: Oops, RTR in %s\n",
712               fp->link->name, State2Nam(fp->state));
713     break;
714   case ST_CLOSED:
715   case ST_STOPPED:
716   case ST_CLOSING:
717   case ST_STOPPING:
718   case ST_REQSENT:
719     (*fp->fn->SendTerminateAck)(fp, lhp->id);
720     break;
721   case ST_ACKRCVD:
722   case ST_ACKSENT:
723     (*fp->fn->SendTerminateAck)(fp, lhp->id);
724     NewState(fp, ST_REQSENT);
725     break;
726   case ST_OPENED:
727     (*fp->fn->LayerDown)(fp);
728     (*fp->fn->SendTerminateAck)(fp, lhp->id);
729     FsmInitRestartCounter(fp, FSM_TRM_TIMER);
730     timer_Start(&fp->FsmTimer);                 /* Start restart timer */
731     fp->restart = 0;
732     NewState(fp, ST_STOPPING);
733     (*fp->parent->LayerDown)(fp->parent->object, fp);
734     /* A delayed ST_STOPPED is now scheduled */
735     break;
736   }
737   m_freem(bp);
738 }
739
740 static void
741 FsmRecvTermAck(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
742 /* RTA */
743 {
744   switch (fp->state) {
745   case ST_CLOSING:
746     (*fp->fn->LayerFinish)(fp);
747     NewState(fp, ST_CLOSED);
748     (*fp->parent->LayerFinish)(fp->parent->object, fp);
749     break;
750   case ST_STOPPING:
751     (*fp->fn->LayerFinish)(fp);
752     NewState(fp, ST_STOPPED);
753     (*fp->parent->LayerFinish)(fp->parent->object, fp);
754     break;
755   case ST_ACKRCVD:
756     NewState(fp, ST_REQSENT);
757     break;
758   case ST_OPENED:
759     (*fp->fn->LayerDown)(fp);
760     FsmSendConfigReq(fp);
761     NewState(fp, ST_REQSENT);
762     (*fp->parent->LayerDown)(fp->parent->object, fp);
763     break;
764   }
765   m_freem(bp);
766 }
767
768 static void
769 FsmRecvConfigRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
770 /* RCJ */
771 {
772   struct fsm_decode dec;
773   int plen, flen;
774
775   plen = m_length(bp);
776   flen = ntohs(lhp->length) - sizeof *lhp;
777   if (plen < flen) {
778     m_freem(bp);
779     return;
780   }
781
782   lcp_SendIdentification(&fp->link->lcp);
783
784   /*
785    * Check and process easy case
786    */
787   switch (fp->state) {
788   case ST_INITIAL:
789   case ST_STARTING:
790     log_Printf(fp->LogLevel, "%s: Oops, RCJ in %s.\n",
791               fp->link->name, State2Nam(fp->state));
792     m_freem(bp);
793     return;
794   case ST_CLOSED:
795   case ST_STOPPED:
796     (*fp->fn->SendTerminateAck)(fp, lhp->id);
797     m_freem(bp);
798     return;
799   case ST_CLOSING:
800   case ST_STOPPING:
801     m_freem(bp);
802     return;
803   }
804
805   bp = m_pullup(bp);
806   dec.ackend = dec.ack;
807   dec.nakend = dec.nak;
808   dec.rejend = dec.rej;
809   (*fp->fn->DecodeConfig)(fp, MBUF_CTOP(bp), flen, MODE_REJ, &dec);
810   if (flen < sizeof(struct fsmconfig))
811     log_Printf(fp->LogLevel, "  [EMPTY]\n");
812
813   switch (fp->state) {
814   case ST_REQSENT:
815   case ST_ACKSENT:
816     FsmInitRestartCounter(fp, FSM_REQ_TIMER);
817     FsmSendConfigReq(fp);
818     break;
819   case ST_OPENED:
820     (*fp->fn->LayerDown)(fp);
821     FsmSendConfigReq(fp);
822     NewState(fp, ST_REQSENT);
823     (*fp->parent->LayerDown)(fp->parent->object, fp);
824     break;
825   case ST_ACKRCVD:
826     FsmSendConfigReq(fp);
827     NewState(fp, ST_REQSENT);
828     break;
829   }
830   m_freem(bp);
831 }
832
833 static void
834 FsmRecvCodeRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
835 {
836   m_freem(bp);
837 }
838
839 static void
840 FsmRecvProtoRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
841 {
842   struct physical *p = link2physical(fp->link);
843   u_short proto;
844
845   if (m_length(bp) < 2) {
846     m_freem(bp);
847     return;
848   }
849   bp = mbuf_Read(bp, &proto, 2);
850   proto = ntohs(proto);
851   log_Printf(fp->LogLevel, "%s: -- Protocol 0x%04x (%s) was rejected!\n",
852             fp->link->name, proto, hdlc_Protocol2Nam(proto));
853
854   switch (proto) {
855   case PROTO_LQR:
856     if (p)
857       lqr_Stop(p, LQM_LQR);
858     else
859       log_Printf(LogERROR, "%s: FsmRecvProtoRej: Not a physical link !\n",
860                 fp->link->name);
861     break;
862   case PROTO_CCP:
863     if (fp->proto == PROTO_LCP) {
864       fp = &fp->link->ccp.fsm;
865       /* Despite the RFC (1661), don't do an out-of-place TLF */
866       /* (*fp->fn->LayerFinish)(fp); */
867       switch (fp->state) {
868       case ST_CLOSED:
869       case ST_CLOSING:
870         NewState(fp, ST_CLOSED);
871       default:
872         NewState(fp, ST_STOPPED);
873         break;
874       }
875       /* See above */
876       /* (*fp->parent->LayerFinish)(fp->parent->object, fp); */
877     }
878     break;
879   case PROTO_IPCP:
880     if (fp->proto == PROTO_LCP) {
881       log_Printf(LogPHASE, "%s: IPCP protocol reject closes IPCP !\n",
882                 fp->link->name);
883       fsm_Close(&fp->bundle->ncp.ipcp.fsm);
884     }
885     break;
886   case PROTO_MP:
887     if (fp->proto == PROTO_LCP) {
888       struct lcp *lcp = fsm2lcp(fp);
889
890       if (lcp->want_mrru && lcp->his_mrru) {
891         log_Printf(LogPHASE, "%s: MP protocol reject is fatal !\n",
892                   fp->link->name);
893         fsm_Close(fp);
894       }
895     }
896     break;
897   }
898   m_freem(bp);
899 }
900
901 static void
902 FsmRecvEchoReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
903 {
904   struct lcp *lcp = fsm2lcp(fp);
905   u_char *cp;
906   u_int32_t magic;
907
908   bp = m_pullup(bp);
909   m_settype(bp, MB_ECHOIN);
910
911   if (lcp && ntohs(lhp->length) - sizeof *lhp >= 4) {
912     cp = MBUF_CTOP(bp);
913     ua_ntohl(cp, &magic);
914     if (magic != lcp->his_magic) {
915       log_Printf(fp->LogLevel, "%s: RecvEchoReq: magic 0x%08lx is wrong,"
916                  " expecting 0x%08lx\n", fp->link->name, (u_long)magic,
917                  (u_long)lcp->his_magic);
918       /* XXX: We should send terminate request */
919     }
920     if (fp->state == ST_OPENED) {
921       ua_htonl(&lcp->want_magic, cp);           /* local magic */
922       fsm_Output(fp, CODE_ECHOREP, lhp->id, cp,
923                  ntohs(lhp->length) - sizeof *lhp, MB_ECHOOUT);
924     }
925   }
926   m_freem(bp);
927 }
928
929 static void
930 FsmRecvEchoRep(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
931 {
932   if (fsm2lcp(fp))
933     bp = lqr_RecvEcho(fp, bp);
934
935   m_freem(bp);
936 }
937
938 static void
939 FsmRecvDiscReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
940 {
941   m_freem(bp);
942 }
943
944 static void
945 FsmRecvIdent(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
946 {
947   u_int32_t magic;
948   u_short len;
949   u_char *cp;
950
951   len = ntohs(lhp->length) - sizeof *lhp;
952   if (len >= 4) {
953     bp = m_pullup(m_append(bp, "", 1));
954     cp = MBUF_CTOP(bp);
955     ua_ntohl(cp, &magic);
956     if (magic != fp->link->lcp.his_magic)
957       log_Printf(fp->LogLevel, "%s: RecvIdent: magic 0x%08lx is wrong,"
958                  " expecting 0x%08lx\n", fp->link->name, (u_long)magic,
959                  (u_long)fp->link->lcp.his_magic);
960     cp[len] = '\0';
961     lcp_RecvIdentification(&fp->link->lcp, cp + 4);
962   }
963   m_freem(bp);
964 }
965
966 static void
967 FsmRecvTimeRemain(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
968 {
969   m_freem(bp);
970 }
971
972 static void
973 FsmRecvResetReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
974 {
975   (*fp->fn->RecvResetReq)(fp);
976   /*
977    * All sendable compressed packets are queued in the first (lowest
978    * priority) modem output queue.... dump 'em to the priority queue
979    * so that they arrive at the peer before our ResetAck.
980    */
981   link_SequenceQueue(fp->link);
982   fsm_Output(fp, CODE_RESETACK, lhp->id, NULL, 0, MB_CCPOUT);
983   m_freem(bp);
984 }
985
986 static void
987 FsmRecvResetAck(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
988 {
989   (*fp->fn->RecvResetAck)(fp, lhp->id);
990   m_freem(bp);
991 }
992
993 void
994 fsm_Input(struct fsm *fp, struct mbuf *bp)
995 {
996   int len;
997   struct fsmheader lh;
998   const struct fsmcodedesc *codep;
999
1000   len = m_length(bp);
1001   if (len < sizeof(struct fsmheader)) {
1002     m_freem(bp);
1003     return;
1004   }
1005   bp = mbuf_Read(bp, &lh, sizeof lh);
1006
1007   if (ntohs(lh.length) > len) {
1008     log_Printf(LogWARN, "%s: Oops: Got %d bytes but %d byte payload "
1009                "- dropped\n", fp->link->name, len, (int)ntohs(lh.length));
1010     m_freem(bp);
1011     return;
1012   }
1013
1014   if (lh.code < fp->min_code || lh.code > fp->max_code ||
1015       lh.code > sizeof FsmCodes / sizeof *FsmCodes) {
1016     /*
1017      * Use a private id.  This is really a response-type packet, but we
1018      * MUST send a unique id for each REQ....
1019      */
1020     static u_char id;
1021
1022     bp = m_prepend(bp, &lh, sizeof lh, 0);
1023     bp = m_pullup(bp);
1024     fsm_Output(fp, CODE_CODEREJ, id++, MBUF_CTOP(bp), bp->m_len, MB_UNKNOWN);
1025     m_freem(bp);
1026     return;
1027   }
1028
1029   codep = FsmCodes + lh.code - 1;
1030   if (lh.id != fp->reqid && codep->check_reqid &&
1031       Enabled(fp->bundle, OPT_IDCHECK)) {
1032     log_Printf(fp->LogLevel, "%s: Recv%s(%d), dropped (expected %d)\n",
1033               fp->link->name, codep->name, lh.id, fp->reqid);
1034     return;
1035   }
1036
1037   log_Printf(fp->LogLevel, "%s: Recv%s(%d) state = %s\n",
1038             fp->link->name, codep->name, lh.id, State2Nam(fp->state));
1039
1040   if (codep->inc_reqid && (lh.id == fp->reqid ||
1041       (!Enabled(fp->bundle, OPT_IDCHECK) && codep->check_reqid)))
1042     fp->reqid++;        /* That's the end of that ``exchange''.... */
1043
1044   (*codep->recv)(fp, &lh, bp);
1045 }
1046
1047 void
1048 fsm_NullRecvResetReq(struct fsm *fp)
1049 {
1050   log_Printf(fp->LogLevel, "%s: Oops - received unexpected reset req\n",
1051             fp->link->name);
1052 }
1053
1054 void
1055 fsm_NullRecvResetAck(struct fsm *fp, u_char id)
1056 {
1057   log_Printf(fp->LogLevel, "%s: Oops - received unexpected reset ack\n",
1058             fp->link->name);
1059 }
1060
1061 void
1062 fsm_Reopen(struct fsm *fp)
1063 {
1064   if (fp->state == ST_OPENED) {
1065     (*fp->fn->LayerDown)(fp);
1066     FsmInitRestartCounter(fp, FSM_REQ_TIMER);
1067     FsmSendConfigReq(fp);
1068     NewState(fp, ST_REQSENT);
1069     (*fp->parent->LayerDown)(fp->parent->object, fp);
1070   }
1071 }
1072
1073 void
1074 fsm2initial(struct fsm *fp)
1075 {
1076   timer_Stop(&fp->FsmTimer);
1077   timer_Stop(&fp->OpenTimer);
1078   timer_Stop(&fp->StoppedTimer);
1079   if (fp->state == ST_STOPPED)
1080     fsm_Close(fp);
1081   if (fp->state > ST_INITIAL)
1082     fsm_Down(fp);
1083   if (fp->state > ST_INITIAL)
1084     fsm_Close(fp);
1085 }