1 /*****************************************************************************
2 * fsm.c - Network Control Protocol Finite State Machine program file.
4 * Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
5 * portions Copyright (c) 1997 by Global Election Systems Inc.
7 * The authors hereby grant permission to use, copy, modify, distribute,
8 * and license this software and its documentation for any purpose, provided
9 * that existing copyright notices are retained in all copies and that this
10 * notice and the following disclaimer are included verbatim in any
11 * distributions. No written agreement, license, or royalty fee is required
12 * for any of the authorized uses.
14 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 ******************************************************************************
28 * 03-01-01 Marc Boucher <marc@mbsi.ca>
30 * 97-12-01 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
31 * Original based on BSD fsm.c.
32 *****************************************************************************/
34 * fsm.c - {Link, IP} Control Protocol Finite State Machine.
36 * Copyright (c) 1989 Carnegie Mellon University.
37 * All rights reserved.
39 * Redistribution and use in source and binary forms are permitted
40 * provided that the above copyright notice and this paragraph are
41 * duplicated in all such forms and that any documentation,
42 * advertising materials, and other materials related to such
43 * distribution and use acknowledge that the software was developed
44 * by Carnegie Mellon University. The name of the
45 * University may not be used to endorse or promote products derived
46 * from this software without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
48 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
49 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
54 * Randomize fsm id on link/init.
55 * Deal with variable outgoing MTU.
60 #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
70 /*************************/
71 /*** LOCAL DEFINITIONS ***/
72 /*************************/
76 static const char *ppperr_strerr
[] = {
77 "LS_INITIAL", /* LS_INITIAL 0 */
78 "LS_STARTING", /* LS_STARTING 1 */
79 "LS_CLOSED", /* LS_CLOSED 2 */
80 "LS_STOPPED", /* LS_STOPPED 3 */
81 "LS_CLOSING", /* LS_CLOSING 4 */
82 "LS_STOPPING", /* LS_STOPPING 5 */
83 "LS_REQSENT", /* LS_REQSENT 6 */
84 "LS_ACKRCVD", /* LS_ACKRCVD 7 */
85 "LS_ACKSENT", /* LS_ACKSENT 8 */
86 "LS_OPENED" /* LS_OPENED 9 */
89 #endif /* PPP_DEBUG */
91 /************************/
92 /*** LOCAL DATA TYPES ***/
93 /************************/
96 /***********************************/
97 /*** LOCAL FUNCTION DECLARATIONS ***/
98 /***********************************/
99 static void fsm_timeout (void *);
100 static void fsm_rconfreq (fsm
*, u_char
, u_char
*, int);
101 static void fsm_rconfack (fsm
*, int, u_char
*, int);
102 static void fsm_rconfnakrej (fsm
*, int, int, u_char
*, int);
103 static void fsm_rtermreq (fsm
*, int, u_char
*, int);
104 static void fsm_rtermack (fsm
*);
105 static void fsm_rcoderej (fsm
*, u_char
*, int);
106 static void fsm_sconfreq (fsm
*, int);
108 #define PROTO_NAME(f) ((f)->callbacks->proto_name)
111 /******************************/
112 /*** PUBLIC DATA STRUCTURES ***/
113 /******************************/
116 /*****************************/
117 /*** LOCAL DATA STRUCTURES ***/
118 /*****************************/
119 int peer_mru
[NUM_PPP
];
122 /***********************************/
123 /*** PUBLIC FUNCTION DEFINITIONS ***/
124 /***********************************/
127 * fsm_init - Initialize fsm.
129 * Initialize fsm state.
134 f
->state
= LS_INITIAL
;
136 f
->id
= 0; /* XXX Start with random id? */
137 f
->timeouttime
= FSM_DEFTIMEOUT
;
138 f
->maxconfreqtransmits
= FSM_DEFMAXCONFREQS
;
139 f
->maxtermtransmits
= FSM_DEFMAXTERMREQS
;
140 f
->maxnakloops
= FSM_DEFMAXNAKLOOPS
;
141 f
->term_reason_len
= 0;
146 * fsm_lowerup - The lower layer is up.
151 int oldState
= f
->state
;
153 LWIP_UNUSED_ARG(oldState
);
157 f
->state
= LS_CLOSED
;
161 if( f
->flags
& OPT_SILENT
) {
162 f
->state
= LS_STOPPED
;
164 /* Send an initial configure-request */
166 f
->state
= LS_REQSENT
;
171 FSMDEBUG((LOG_INFO
, "%s: Up event in state %d (%s)!\n",
172 PROTO_NAME(f
), f
->state
, ppperr_strerr
[f
->state
]));
175 FSMDEBUG((LOG_INFO
, "%s: lowerup state %d (%s) -> %d (%s)\n",
176 PROTO_NAME(f
), oldState
, ppperr_strerr
[oldState
], f
->state
, ppperr_strerr
[f
->state
]));
181 * fsm_lowerdown - The lower layer is down.
183 * Cancel all timeouts and inform upper layers.
186 fsm_lowerdown(fsm
*f
)
188 int oldState
= f
->state
;
190 LWIP_UNUSED_ARG(oldState
);
194 f
->state
= LS_INITIAL
;
198 f
->state
= LS_STARTING
;
199 if( f
->callbacks
->starting
) {
200 (*f
->callbacks
->starting
)(f
);
205 f
->state
= LS_INITIAL
;
206 UNTIMEOUT(fsm_timeout
, f
); /* Cancel timeout */
213 f
->state
= LS_STARTING
;
214 UNTIMEOUT(fsm_timeout
, f
); /* Cancel timeout */
218 if( f
->callbacks
->down
) {
219 (*f
->callbacks
->down
)(f
);
221 f
->state
= LS_STARTING
;
225 FSMDEBUG((LOG_INFO
, "%s: Down event in state %d (%s)!\n",
226 PROTO_NAME(f
), f
->state
, ppperr_strerr
[f
->state
]));
229 FSMDEBUG((LOG_INFO
, "%s: lowerdown state %d (%s) -> %d (%s)\n",
230 PROTO_NAME(f
), oldState
, ppperr_strerr
[oldState
], f
->state
, ppperr_strerr
[f
->state
]));
235 * fsm_open - Link is allowed to come up.
240 int oldState
= f
->state
;
242 LWIP_UNUSED_ARG(oldState
);
246 f
->state
= LS_STARTING
;
247 if( f
->callbacks
->starting
) {
248 (*f
->callbacks
->starting
)(f
);
253 if( f
->flags
& OPT_SILENT
) {
254 f
->state
= LS_STOPPED
;
256 /* Send an initial configure-request */
258 f
->state
= LS_REQSENT
;
263 f
->state
= LS_STOPPING
;
267 if( f
->flags
& OPT_RESTART
) {
274 FSMDEBUG((LOG_INFO
, "%s: open state %d (%s) -> %d (%s)\n",
275 PROTO_NAME(f
), oldState
, ppperr_strerr
[oldState
], f
->state
, ppperr_strerr
[f
->state
]));
280 * fsm_close - Start closing connection.
282 * Cancel timeouts and either initiate close or possibly go directly to
283 * the LS_CLOSED state.
286 fsm_close(fsm
*f
, char *reason
)
288 int oldState
= f
->state
;
290 LWIP_UNUSED_ARG(oldState
);
292 f
->term_reason
= reason
;
293 f
->term_reason_len
= (reason
== NULL
? 0: strlen(reason
));
296 f
->state
= LS_INITIAL
;
299 f
->state
= LS_CLOSED
;
302 f
->state
= LS_CLOSING
;
309 if( f
->state
!= LS_OPENED
) {
310 UNTIMEOUT(fsm_timeout
, f
); /* Cancel timeout */
311 } else if( f
->callbacks
->down
) {
312 (*f
->callbacks
->down
)(f
); /* Inform upper layers we're down */
314 /* Init restart counter, send Terminate-Request */
315 f
->retransmits
= f
->maxtermtransmits
;
316 fsm_sdata(f
, TERMREQ
, f
->reqid
= ++f
->id
,
317 (u_char
*) f
->term_reason
, f
->term_reason_len
);
318 TIMEOUT(fsm_timeout
, f
, f
->timeouttime
);
321 f
->state
= LS_CLOSING
;
325 FSMDEBUG((LOG_INFO
, "%s: close reason=%s state %d (%s) -> %d (%s)\n",
326 PROTO_NAME(f
), reason
, oldState
, ppperr_strerr
[oldState
], f
->state
, ppperr_strerr
[f
->state
]));
331 * fsm_sdata - Send some data.
333 * Used for all packets sent to our peer by this module.
336 fsm_sdata( fsm
*f
, u_char code
, u_char id
, u_char
*data
, int datalen
)
341 /* Adjust length to be smaller than MTU */
342 outp
= outpacket_buf
[f
->unit
];
343 if (datalen
> peer_mru
[f
->unit
] - (int)HEADERLEN
) {
344 datalen
= peer_mru
[f
->unit
] - HEADERLEN
;
346 if (datalen
&& data
!= outp
+ PPP_HDRLEN
+ HEADERLEN
) {
347 BCOPY(data
, outp
+ PPP_HDRLEN
+ HEADERLEN
, datalen
);
349 outlen
= datalen
+ HEADERLEN
;
350 MAKEHEADER(outp
, f
->protocol
);
353 PUTSHORT(outlen
, outp
);
354 pppWrite(f
->unit
, outpacket_buf
[f
->unit
], outlen
+ PPP_HDRLEN
);
355 FSMDEBUG((LOG_INFO
, "fsm_sdata(%s): Sent code %d,%d,%d.\n",
356 PROTO_NAME(f
), code
, id
, outlen
));
361 * fsm_input - Input packet.
364 fsm_input(fsm
*f
, u_char
*inpacket
, int l
)
366 u_char
*inp
= inpacket
;
371 * Parse header (code, id and length).
372 * If packet too short, drop it.
375 FSMDEBUG((LOG_WARNING
, "fsm_input(%x): Rcvd short header.\n",
382 if (len
< HEADERLEN
) {
383 FSMDEBUG((LOG_INFO
, "fsm_input(%x): Rcvd illegal length.\n",
388 FSMDEBUG((LOG_INFO
, "fsm_input(%x): Rcvd short packet.\n",
392 len
-= HEADERLEN
; /* subtract header length */
394 if( f
->state
== LS_INITIAL
|| f
->state
== LS_STARTING
) {
395 FSMDEBUG((LOG_INFO
, "fsm_input(%x): Rcvd packet in state %d (%s).\n",
396 f
->protocol
, f
->state
, ppperr_strerr
[f
->state
]));
399 FSMDEBUG((LOG_INFO
, "fsm_input(%s):%d,%d,%d\n", PROTO_NAME(f
), code
, id
, l
));
401 * Action depends on code.
405 fsm_rconfreq(f
, id
, inp
, len
);
409 fsm_rconfack(f
, id
, inp
, len
);
414 fsm_rconfnakrej(f
, code
, id
, inp
, len
);
418 fsm_rtermreq(f
, id
, inp
, len
);
426 fsm_rcoderej(f
, inp
, len
);
430 if( !f
->callbacks
->extcode
||
431 !(*f
->callbacks
->extcode
)(f
, code
, id
, inp
, len
) ) {
432 fsm_sdata(f
, CODEREJ
, ++f
->id
, inpacket
, len
+ HEADERLEN
);
440 * fsm_protreject - Peer doesn't speak this protocol.
442 * Treat this as a catastrophic error (RXJ-).
445 fsm_protreject(fsm
*f
)
449 UNTIMEOUT(fsm_timeout
, f
); /* Cancel timeout */
452 f
->state
= LS_CLOSED
;
453 if( f
->callbacks
->finished
) {
454 (*f
->callbacks
->finished
)(f
);
462 UNTIMEOUT(fsm_timeout
, f
); /* Cancel timeout */
465 f
->state
= LS_STOPPED
;
466 if( f
->callbacks
->finished
) {
467 (*f
->callbacks
->finished
)(f
);
472 if( f
->callbacks
->down
) {
473 (*f
->callbacks
->down
)(f
);
475 /* Init restart counter, send Terminate-Request */
476 f
->retransmits
= f
->maxtermtransmits
;
477 fsm_sdata(f
, TERMREQ
, f
->reqid
= ++f
->id
,
478 (u_char
*) f
->term_reason
, f
->term_reason_len
);
479 TIMEOUT(fsm_timeout
, f
, f
->timeouttime
);
482 f
->state
= LS_STOPPING
;
486 FSMDEBUG((LOG_INFO
, "%s: Protocol-reject event in state %d (%s)!\n",
487 PROTO_NAME(f
), f
->state
, ppperr_strerr
[f
->state
]));
495 /**********************************/
496 /*** LOCAL FUNCTION DEFINITIONS ***/
497 /**********************************/
500 * fsm_timeout - Timeout expired.
503 fsm_timeout(void *arg
)
505 fsm
*f
= (fsm
*) arg
;
510 if( f
->retransmits
<= 0 ) {
511 FSMDEBUG((LOG_WARNING
, "%s: timeout sending Terminate-Request state=%d (%s)\n",
512 PROTO_NAME(f
), f
->state
, ppperr_strerr
[f
->state
]));
514 * We've waited for an ack long enough. Peer probably heard us.
516 f
->state
= (f
->state
== LS_CLOSING
)? LS_CLOSED
: LS_STOPPED
;
517 if( f
->callbacks
->finished
) {
518 (*f
->callbacks
->finished
)(f
);
521 FSMDEBUG((LOG_WARNING
, "%s: timeout resending Terminate-Requests state=%d (%s)\n",
522 PROTO_NAME(f
), f
->state
, ppperr_strerr
[f
->state
]));
523 /* Send Terminate-Request */
524 fsm_sdata(f
, TERMREQ
, f
->reqid
= ++f
->id
,
525 (u_char
*) f
->term_reason
, f
->term_reason_len
);
526 TIMEOUT(fsm_timeout
, f
, f
->timeouttime
);
534 if (f
->retransmits
<= 0) {
535 FSMDEBUG((LOG_WARNING
, "%s: timeout sending Config-Requests state=%d (%s)\n",
536 PROTO_NAME(f
), f
->state
, ppperr_strerr
[f
->state
]));
537 f
->state
= LS_STOPPED
;
538 if( (f
->flags
& OPT_PASSIVE
) == 0 && f
->callbacks
->finished
) {
539 (*f
->callbacks
->finished
)(f
);
542 FSMDEBUG((LOG_WARNING
, "%s: timeout resending Config-Request state=%d (%s)\n",
543 PROTO_NAME(f
), f
->state
, ppperr_strerr
[f
->state
]));
544 /* Retransmit the configure-request */
545 if (f
->callbacks
->retransmit
) {
546 (*f
->callbacks
->retransmit
)(f
);
548 fsm_sconfreq(f
, 1); /* Re-send Configure-Request */
549 if( f
->state
== LS_ACKRCVD
) {
550 f
->state
= LS_REQSENT
;
556 FSMDEBUG((LOG_INFO
, "%s: UNHANDLED timeout event in state %d (%s)!\n",
557 PROTO_NAME(f
), f
->state
, ppperr_strerr
[f
->state
]));
563 * fsm_rconfreq - Receive Configure-Request.
566 fsm_rconfreq(fsm
*f
, u_char id
, u_char
*inp
, int len
)
568 int code
, reject_if_disagree
;
570 FSMDEBUG((LOG_INFO
, "fsm_rconfreq(%s): Rcvd id %d state=%d (%s)\n",
571 PROTO_NAME(f
), id
, f
->state
, ppperr_strerr
[f
->state
]));
574 /* Go away, we're closed */
575 fsm_sdata(f
, TERMACK
, id
, NULL
, 0);
582 /* Go down and restart negotiation */
583 if( f
->callbacks
->down
) {
584 (*f
->callbacks
->down
)(f
); /* Inform upper layers */
586 fsm_sconfreq(f
, 0); /* Send initial Configure-Request */
590 /* Negotiation started by our peer */
591 fsm_sconfreq(f
, 0); /* Send initial Configure-Request */
592 f
->state
= LS_REQSENT
;
597 * Pass the requested configuration options
598 * to protocol-specific code for checking.
600 if (f
->callbacks
->reqci
) { /* Check CI */
601 reject_if_disagree
= (f
->nakloops
>= f
->maxnakloops
);
602 code
= (*f
->callbacks
->reqci
)(f
, inp
, &len
, reject_if_disagree
);
604 code
= CONFREJ
; /* Reject all CI */
609 /* send the Ack, Nak or Rej to the peer */
610 fsm_sdata(f
, (u_char
)code
, id
, inp
, len
);
612 if (code
== CONFACK
) {
613 if (f
->state
== LS_ACKRCVD
) {
614 UNTIMEOUT(fsm_timeout
, f
); /* Cancel timeout */
615 f
->state
= LS_OPENED
;
616 if (f
->callbacks
->up
) {
617 (*f
->callbacks
->up
)(f
); /* Inform upper layers */
620 f
->state
= LS_ACKSENT
;
624 /* we sent CONFACK or CONFREJ */
625 if (f
->state
!= LS_ACKRCVD
) {
626 f
->state
= LS_REQSENT
;
628 if( code
== CONFNAK
) {
636 * fsm_rconfack - Receive Configure-Ack.
639 fsm_rconfack(fsm
*f
, int id
, u_char
*inp
, int len
)
641 FSMDEBUG((LOG_INFO
, "fsm_rconfack(%s): Rcvd id %d state=%d (%s)\n",
642 PROTO_NAME(f
), id
, f
->state
, ppperr_strerr
[f
->state
]));
644 if (id
!= f
->reqid
|| f
->seen_ack
) { /* Expected id? */
645 return; /* Nope, toss... */
647 if( !(f
->callbacks
->ackci
? (*f
->callbacks
->ackci
)(f
, inp
, len
): (len
== 0)) ) {
648 /* Ack is bad - ignore it */
649 FSMDEBUG((LOG_INFO
, "%s: received bad Ack (length %d)\n",
650 PROTO_NAME(f
), len
));
658 fsm_sdata(f
, TERMACK
, (u_char
)id
, NULL
, 0);
662 f
->state
= LS_ACKRCVD
;
663 f
->retransmits
= f
->maxconfreqtransmits
;
667 /* Huh? an extra valid Ack? oh well... */
668 UNTIMEOUT(fsm_timeout
, f
); /* Cancel timeout */
670 f
->state
= LS_REQSENT
;
674 UNTIMEOUT(fsm_timeout
, f
); /* Cancel timeout */
675 f
->state
= LS_OPENED
;
676 f
->retransmits
= f
->maxconfreqtransmits
;
677 if (f
->callbacks
->up
) {
678 (*f
->callbacks
->up
)(f
); /* Inform upper layers */
683 /* Go down and restart negotiation */
684 if (f
->callbacks
->down
) {
685 (*f
->callbacks
->down
)(f
); /* Inform upper layers */
687 fsm_sconfreq(f
, 0); /* Send initial Configure-Request */
688 f
->state
= LS_REQSENT
;
695 * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
698 fsm_rconfnakrej(fsm
*f
, int code
, int id
, u_char
*inp
, int len
)
700 int (*proc
) (fsm
*, u_char
*, int);
703 FSMDEBUG((LOG_INFO
, "fsm_rconfnakrej(%s): Rcvd id %d state=%d (%s)\n",
704 PROTO_NAME(f
), id
, f
->state
, ppperr_strerr
[f
->state
]));
706 if (id
!= f
->reqid
|| f
->seen_ack
) { /* Expected id? */
707 return; /* Nope, toss... */
709 proc
= (code
== CONFNAK
)? f
->callbacks
->nakci
: f
->callbacks
->rejci
;
710 if (!proc
|| !((ret
= proc(f
, inp
, len
)))) {
711 /* Nak/reject is bad - ignore it */
712 FSMDEBUG((LOG_INFO
, "%s: received bad %s (length %d)\n",
713 PROTO_NAME(f
), (code
==CONFNAK
? "Nak": "reject"), len
));
721 fsm_sdata(f
, TERMACK
, (u_char
)id
, NULL
, 0);
726 /* They didn't agree to what we wanted - try another request */
727 UNTIMEOUT(fsm_timeout
, f
); /* Cancel timeout */
729 f
->state
= LS_STOPPED
; /* kludge for stopping CCP */
731 fsm_sconfreq(f
, 0); /* Send Configure-Request */
736 /* Got a Nak/reject when we had already had an Ack?? oh well... */
737 UNTIMEOUT(fsm_timeout
, f
); /* Cancel timeout */
739 f
->state
= LS_REQSENT
;
743 /* Go down and restart negotiation */
744 if (f
->callbacks
->down
) {
745 (*f
->callbacks
->down
)(f
); /* Inform upper layers */
747 fsm_sconfreq(f
, 0); /* Send initial Configure-Request */
748 f
->state
= LS_REQSENT
;
755 * fsm_rtermreq - Receive Terminate-Req.
758 fsm_rtermreq(fsm
*f
, int id
, u_char
*p
, int len
)
762 FSMDEBUG((LOG_INFO
, "fsm_rtermreq(%s): Rcvd id %d state=%d (%s)\n",
763 PROTO_NAME(f
), id
, f
->state
, ppperr_strerr
[f
->state
]));
768 f
->state
= LS_REQSENT
; /* Start over but keep trying */
773 FSMDEBUG((LOG_INFO
, "%s terminated by peer (%x)\n", PROTO_NAME(f
), p
));
775 FSMDEBUG((LOG_INFO
, "%s terminated by peer\n", PROTO_NAME(f
)));
777 if (f
->callbacks
->down
) {
778 (*f
->callbacks
->down
)(f
); /* Inform upper layers */
781 f
->state
= LS_STOPPING
;
782 TIMEOUT(fsm_timeout
, f
, f
->timeouttime
);
786 fsm_sdata(f
, TERMACK
, (u_char
)id
, NULL
, 0);
791 * fsm_rtermack - Receive Terminate-Ack.
796 FSMDEBUG((LOG_INFO
, "fsm_rtermack(%s): state=%d (%s)\n",
797 PROTO_NAME(f
), f
->state
, ppperr_strerr
[f
->state
]));
801 UNTIMEOUT(fsm_timeout
, f
);
802 f
->state
= LS_CLOSED
;
803 if( f
->callbacks
->finished
) {
804 (*f
->callbacks
->finished
)(f
);
809 UNTIMEOUT(fsm_timeout
, f
);
810 f
->state
= LS_STOPPED
;
811 if( f
->callbacks
->finished
) {
812 (*f
->callbacks
->finished
)(f
);
817 f
->state
= LS_REQSENT
;
821 if (f
->callbacks
->down
) {
822 (*f
->callbacks
->down
)(f
); /* Inform upper layers */
831 * fsm_rcoderej - Receive an Code-Reject.
834 fsm_rcoderej(fsm
*f
, u_char
*inp
, int len
)
838 FSMDEBUG((LOG_INFO
, "fsm_rcoderej(%s): state=%d (%s)\n",
839 PROTO_NAME(f
), f
->state
, ppperr_strerr
[f
->state
]));
841 if (len
< HEADERLEN
) {
842 FSMDEBUG((LOG_INFO
, "fsm_rcoderej: Rcvd short Code-Reject packet!\n"));
847 FSMDEBUG((LOG_WARNING
, "%s: Rcvd Code-Reject for code %d, id %d\n",
848 PROTO_NAME(f
), code
, id
));
850 if( f
->state
== LS_ACKRCVD
) {
851 f
->state
= LS_REQSENT
;
857 * fsm_sconfreq - Send a Configure-Request.
860 fsm_sconfreq(fsm
*f
, int retransmit
)
865 if( f
->state
!= LS_REQSENT
&& f
->state
!= LS_ACKRCVD
&& f
->state
!= LS_ACKSENT
) {
866 /* Not currently negotiating - reset options */
867 if( f
->callbacks
->resetci
) {
868 (*f
->callbacks
->resetci
)(f
);
874 /* New request - reset retransmission counter, use new ID */
875 f
->retransmits
= f
->maxconfreqtransmits
;
882 * Make up the request packet
884 outp
= outpacket_buf
[f
->unit
] + PPP_HDRLEN
+ HEADERLEN
;
885 if( f
->callbacks
->cilen
&& f
->callbacks
->addci
) {
886 cilen
= (*f
->callbacks
->cilen
)(f
);
887 if( cilen
> peer_mru
[f
->unit
] - (int)HEADERLEN
) {
888 cilen
= peer_mru
[f
->unit
] - HEADERLEN
;
890 if (f
->callbacks
->addci
) {
891 (*f
->callbacks
->addci
)(f
, outp
, &cilen
);
897 /* send the request to our peer */
898 fsm_sdata(f
, CONFREQ
, f
->reqid
, outp
, cilen
);
900 /* start the retransmit timer */
902 TIMEOUT(fsm_timeout
, f
, f
->timeouttime
);
904 FSMDEBUG((LOG_INFO
, "%s: sending Configure-Request, id %d\n",
905 PROTO_NAME(f
), f
->reqid
));
908 #endif /* PPP_SUPPORT */