43 #include "netif/ppp/ppp_opts.h"    55 #include <sys/types.h>    58 #include "netif/ppp/ppp_impl.h"    60 #include "netif/ppp/fsm.h"    62 static void fsm_timeout (
void *);
    63 static void fsm_rconfreq(fsm *f, u_char 
id, u_char *inp, 
int len);
    64 static void fsm_rconfack(fsm *f, 
int id, u_char *inp, 
int len);
    65 static void fsm_rconfnakrej(fsm *f, 
int code, 
int id, u_char *inp, 
int len);
    66 static void fsm_rtermreq(fsm *f, 
int id, u_char *p, 
int len);
    67 static void fsm_rtermack(fsm *f);
    68 static void fsm_rcoderej(fsm *f, u_char *inp, 
int len);
    69 static void fsm_sconfreq(fsm *f, 
int retransmit);
    71 #define PROTO_NAME(f)   ((f)->callbacks->proto_name)    78 void fsm_init(fsm *f) {
    79     ppp_pcb *pcb = f->pcb;
    80     f->state = PPP_FSM_INITIAL;
    83     f->maxnakloops = pcb->settings.fsm_max_nak_loops;
    84     f->term_reason_len = 0;
    91 void fsm_lowerup(fsm *f) {
    94     f->state = PPP_FSM_CLOSED;
    97     case PPP_FSM_STARTING:
    98     if( f->flags & OPT_SILENT )
    99         f->state = PPP_FSM_STOPPED;
   103         f->state = PPP_FSM_REQSENT;
   108     FSMDEBUG((
"%s: Up event in state %d!", PROTO_NAME(f), f->state));
   119 void fsm_lowerdown(fsm *f) {
   122     f->state = PPP_FSM_INITIAL;
   125     case PPP_FSM_STOPPED:
   126     f->state = PPP_FSM_STARTING;
   127     if( f->callbacks->starting )
   128         (*f->callbacks->starting)(f);
   131     case PPP_FSM_CLOSING:
   132     f->state = PPP_FSM_INITIAL;
   133     UNTIMEOUT(fsm_timeout, f);  
   136     case PPP_FSM_STOPPING:
   137     case PPP_FSM_REQSENT:
   138     case PPP_FSM_ACKRCVD:
   139     case PPP_FSM_ACKSENT:
   140     f->state = PPP_FSM_STARTING;
   141     UNTIMEOUT(fsm_timeout, f);  
   145     if( f->callbacks->down )
   146         (*f->callbacks->down)(f);
   147     f->state = PPP_FSM_STARTING;
   151     FSMDEBUG((
"%s: Down event in state %d!", PROTO_NAME(f), f->state));
   160 void fsm_open(fsm *f) {
   162     case PPP_FSM_INITIAL:
   163     f->state = PPP_FSM_STARTING;
   164     if( f->callbacks->starting )
   165         (*f->callbacks->starting)(f);
   169     if( f->flags & OPT_SILENT )
   170         f->state = PPP_FSM_STOPPED;
   174         f->state = PPP_FSM_REQSENT;
   178     case PPP_FSM_CLOSING:
   179     f->state = PPP_FSM_STOPPING;
   182     case PPP_FSM_STOPPED:
   184     if( f->flags & OPT_RESTART ){
   200 static void terminate_layer(fsm *f, 
int nextstate) {
   201     ppp_pcb *pcb = f->pcb;
   203     if( f->state != PPP_FSM_OPENED )
   204     UNTIMEOUT(fsm_timeout, f);  
   205     else if( f->callbacks->down )
   206     (*f->callbacks->down)(f);   
   209     f->retransmits = pcb->settings.fsm_max_term_transmits;
   210     fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
   211           (
const u_char *) f->term_reason, f->term_reason_len);
   213     if (f->retransmits == 0) {
   219     f->state = nextstate == PPP_FSM_CLOSING ? PPP_FSM_CLOSED : PPP_FSM_STOPPED;
   220     if( f->callbacks->finished )
   221         (*f->callbacks->finished)(f);
   225     TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time);
   228     f->state = nextstate;
   237 void fsm_close(fsm *f, 
const char *reason) {
   238     f->term_reason = reason;
   239     f->term_reason_len = (reason == NULL? 0: LWIP_MIN(strlen(reason), 0xFF) );
   241     case PPP_FSM_STARTING:
   242     f->state = PPP_FSM_INITIAL;
   244     case PPP_FSM_STOPPED:
   245     f->state = PPP_FSM_CLOSED;
   247     case PPP_FSM_STOPPING:
   248     f->state = PPP_FSM_CLOSING;
   251     case PPP_FSM_REQSENT:
   252     case PPP_FSM_ACKRCVD:
   253     case PPP_FSM_ACKSENT:
   255     terminate_layer(f, PPP_FSM_CLOSING);
   266 static void fsm_timeout(
void *arg) {
   267     fsm *f = (fsm *) arg;
   268     ppp_pcb *pcb = f->pcb;
   271     case PPP_FSM_CLOSING:
   272     case PPP_FSM_STOPPING:
   273     if( f->retransmits <= 0 ){
   277         f->state = (f->state == PPP_FSM_CLOSING)? PPP_FSM_CLOSED: PPP_FSM_STOPPED;
   278         if( f->callbacks->finished )
   279         (*f->callbacks->finished)(f);
   282         fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
   283               (
const u_char *) f->term_reason, f->term_reason_len);
   284         TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time);
   289     case PPP_FSM_REQSENT:
   290     case PPP_FSM_ACKRCVD:
   291     case PPP_FSM_ACKSENT:
   292     if (f->retransmits <= 0) {
   293         ppp_warn(
"%s: timeout sending Config-Requests", PROTO_NAME(f));
   294         f->state = PPP_FSM_STOPPED;
   295         if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished )
   296         (*f->callbacks->finished)(f);
   300         if (f->callbacks->retransmit)
   301         (*f->callbacks->retransmit)(f);
   303         if( f->state == PPP_FSM_ACKRCVD )
   304         f->state = PPP_FSM_REQSENT;
   309     FSMDEBUG((
"%s: Timeout event in state %d!", PROTO_NAME(f), f->state));
   318 void fsm_input(fsm *f, u_char *inpacket, 
int l) {
   329     FSMDEBUG((
"fsm_input(%x): Rcvd short header.", f->protocol));
   335     if (len < HEADERLEN) {
   336     FSMDEBUG((
"fsm_input(%x): Rcvd illegal length.", f->protocol));
   340     FSMDEBUG((
"fsm_input(%x): Rcvd short packet.", f->protocol));
   345     if( f->state == PPP_FSM_INITIAL || f->state == PPP_FSM_STARTING ){
   346     FSMDEBUG((
"fsm_input(%x): Rcvd packet in state %d.",
   347           f->protocol, f->state));
   356     fsm_rconfreq(f, 
id, inp, len);
   360     fsm_rconfack(f, 
id, inp, len);
   365     fsm_rconfnakrej(f, code, 
id, inp, len);
   369     fsm_rtermreq(f, 
id, inp, len);
   377     fsm_rcoderej(f, inp, len);
   381     if( !f->callbacks->extcode
   382        || !(*f->callbacks->extcode)(f, code, 
id, inp, len) )
   383         fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN);
   392 static void fsm_rconfreq(fsm *f, u_char 
id, u_char *inp, 
int len) {
   393     int code, reject_if_disagree;
   398     fsm_sdata(f, TERMACK, 
id, NULL, 0);
   400     case PPP_FSM_CLOSING:
   401     case PPP_FSM_STOPPING:
   406     if( f->callbacks->down )
   407         (*f->callbacks->down)(f);   
   409     f->state = PPP_FSM_REQSENT;
   412     case PPP_FSM_STOPPED:
   415     f->state = PPP_FSM_REQSENT;
   425     if (f->callbacks->reqci){       
   426     reject_if_disagree = (f->nakloops >= f->maxnakloops);
   427     code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree);
   434     fsm_sdata(f, code, 
id, inp, len);
   436     if (code == CONFACK) {
   437     if (f->state == PPP_FSM_ACKRCVD) {
   438         UNTIMEOUT(fsm_timeout, f);  
   439         f->state = PPP_FSM_OPENED;
   440         if (f->callbacks->up)
   441         (*f->callbacks->up)(f); 
   443         f->state = PPP_FSM_ACKSENT;
   448     if (f->state != PPP_FSM_ACKRCVD)
   449         f->state = PPP_FSM_REQSENT;
   450     if( code == CONFNAK )
   459 static void fsm_rconfack(fsm *f, 
int id, u_char *inp, 
int len) {
   460     ppp_pcb *pcb = f->pcb;
   462     if (
id != f->reqid || f->seen_ack)      
   464     if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len):
   467     ppp_error(
"Received bad configure-ack: %P", inp, len);
   475     case PPP_FSM_STOPPED:
   476     fsm_sdata(f, TERMACK, 
id, NULL, 0);
   479     case PPP_FSM_REQSENT:
   480     f->state = PPP_FSM_ACKRCVD;
   481     f->retransmits = pcb->settings.fsm_max_conf_req_transmits;
   484     case PPP_FSM_ACKRCVD:
   486     UNTIMEOUT(fsm_timeout, f);  
   488     f->state = PPP_FSM_REQSENT;
   491     case PPP_FSM_ACKSENT:
   492     UNTIMEOUT(fsm_timeout, f);  
   493     f->state = PPP_FSM_OPENED;
   494     f->retransmits = pcb->settings.fsm_max_conf_req_transmits;
   495     if (f->callbacks->up)
   496         (*f->callbacks->up)(f); 
   501     if (f->callbacks->down)
   502         (*f->callbacks->down)(f);   
   504     f->state = PPP_FSM_REQSENT;
   515 static void fsm_rconfnakrej(fsm *f, 
int code, 
int id, u_char *inp, 
int len) {
   519     if (
id != f->reqid || f->seen_ack)  
   522     if (code == CONFNAK) {
   524     treat_as_reject = (f->rnakloops >= f->maxnakloops);
   525     if (f->callbacks->nakci == NULL
   526         || !(ret = f->callbacks->nakci(f, inp, len, treat_as_reject))) {
   527         ppp_error(
"Received bad configure-nak: %P", inp, len);
   532     if (f->callbacks->rejci == NULL
   533         || !(ret = f->callbacks->rejci(f, inp, len))) {
   534         ppp_error(
"Received bad configure-rej: %P", inp, len);
   543     case PPP_FSM_STOPPED:
   544     fsm_sdata(f, TERMACK, 
id, NULL, 0);
   547     case PPP_FSM_REQSENT:
   548     case PPP_FSM_ACKSENT:
   550     UNTIMEOUT(fsm_timeout, f);  
   552         f->state = PPP_FSM_STOPPED;     
   557     case PPP_FSM_ACKRCVD:
   559     UNTIMEOUT(fsm_timeout, f);  
   561     f->state = PPP_FSM_REQSENT;
   566     if (f->callbacks->down)
   567         (*f->callbacks->down)(f);   
   569     f->state = PPP_FSM_REQSENT;
   580 static void fsm_rtermreq(fsm *f, 
int id, u_char *p, 
int len) {
   581     ppp_pcb *pcb = f->pcb;
   584     case PPP_FSM_ACKRCVD:
   585     case PPP_FSM_ACKSENT:
   586     f->state = PPP_FSM_REQSENT;     
   591         ppp_info(
"%s terminated by peer (%0.*v)", PROTO_NAME(f), len, p);
   593         ppp_info(
"%s terminated by peer", PROTO_NAME(f));
   595     f->state = PPP_FSM_STOPPING;
   596     if (f->callbacks->down)
   597         (*f->callbacks->down)(f);   
   598     TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time);
   604     fsm_sdata(f, TERMACK, 
id, NULL, 0);
   611 static void fsm_rtermack(fsm *f) {
   613     case PPP_FSM_CLOSING:
   614     UNTIMEOUT(fsm_timeout, f);
   615     f->state = PPP_FSM_CLOSED;
   616     if( f->callbacks->finished )
   617         (*f->callbacks->finished)(f);
   619     case PPP_FSM_STOPPING:
   620     UNTIMEOUT(fsm_timeout, f);
   621     f->state = PPP_FSM_STOPPED;
   622     if( f->callbacks->finished )
   623         (*f->callbacks->finished)(f);
   626     case PPP_FSM_ACKRCVD:
   627     f->state = PPP_FSM_REQSENT;
   631     if (f->callbacks->down)
   632         (*f->callbacks->down)(f);   
   634     f->state = PPP_FSM_REQSENT;
   645 static void fsm_rcoderej(fsm *f, u_char *inp, 
int len) {
   648     if (len < HEADERLEN) {
   649     FSMDEBUG((
"fsm_rcoderej: Rcvd short Code-Reject packet!"));
   654     ppp_warn(
"%s: Rcvd Code-Reject for code %d, id %d", PROTO_NAME(f), code, 
id);
   656     if( f->state == PPP_FSM_ACKRCVD )
   657     f->state = PPP_FSM_REQSENT;
   666 void fsm_protreject(fsm *f) {
   668     case PPP_FSM_CLOSING:
   669     UNTIMEOUT(fsm_timeout, f);  
   673     f->state = PPP_FSM_CLOSED;
   674     if( f->callbacks->finished )
   675         (*f->callbacks->finished)(f);
   678     case PPP_FSM_STOPPING:
   679     case PPP_FSM_REQSENT:
   680     case PPP_FSM_ACKRCVD:
   681     case PPP_FSM_ACKSENT:
   682     UNTIMEOUT(fsm_timeout, f);  
   685     case PPP_FSM_STOPPED:
   686     f->state = PPP_FSM_STOPPED;
   687     if( f->callbacks->finished )
   688         (*f->callbacks->finished)(f);
   692     terminate_layer(f, PPP_FSM_STOPPING);
   696     FSMDEBUG((
"%s: Protocol-reject event in state %d!",
   697           PROTO_NAME(f), f->state));
   706 static void fsm_sconfreq(fsm *f, 
int retransmit) {
   707     ppp_pcb *pcb = f->pcb;
   712     if( f->state != PPP_FSM_REQSENT && f->state != PPP_FSM_ACKRCVD && f->state != PPP_FSM_ACKSENT ){
   714     if( f->callbacks->resetci )
   715         (*f->callbacks->resetci)(f);
   722     f->retransmits = pcb->settings.fsm_max_conf_req_transmits;
   731     if( f->callbacks->cilen && f->callbacks->addci ){
   732     cilen = (*f->callbacks->cilen)(f);
   733     if( cilen > pcb->peer_mru - HEADERLEN )
   734         cilen = pcb->peer_mru - HEADERLEN;
   738     p = 
pbuf_alloc(
PBUF_RAW, (u16_t)(cilen + HEADERLEN + PPP_HDRLEN), PPP_CTRL_PBUF_TYPE);
   748     MAKEHEADER(outp, f->protocol);
   749     PUTCHAR(CONFREQ, outp);
   750     PUTCHAR(f->reqid, outp);
   751     PUTSHORT(cilen + HEADERLEN, outp);
   753     (*f->callbacks->addci)(f, outp, &cilen);
   754     LWIP_ASSERT(
"cilen == p->len - HEADERLEN - PPP_HDRLEN", cilen == p->
len - HEADERLEN - PPP_HDRLEN);
   761     TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time);
   770 void fsm_sdata(fsm *f, u_char code, u_char 
id, 
const u_char *data, 
int datalen) {
   771     ppp_pcb *pcb = f->pcb;
   777     if (datalen > pcb->peer_mru - HEADERLEN)
   778     datalen = pcb->peer_mru - HEADERLEN;
   779     outlen = datalen + HEADERLEN;
   791     MEMCPY(outp + PPP_HDRLEN + HEADERLEN, data, datalen);
   792     MAKEHEADER(outp, f->protocol);
   795     PUTSHORT(outlen, outp);
 
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
u8_t pbuf_free(struct pbuf *p)