📄 pppfsm.c
字号:
/* Out of Sync; kill the remote */
fsm_sendtermack(fsm_p, hdr.id);
/* fallthru */
case fsmTERM_Sent:
/* We are attempting to close connection; */
/* wait for timeout to resend a Terminate Request */
free_p(bpp);
break;
};
break;
case CONFIG_NAK:
switch(fsm_p->state) {
case fsmREQ_Sent:
case fsmACK_Sent:
/* Update our config request to reflect NAKed options */
if ((*fsm_p->pdc->nak)(fsm_p, &hdr, bpp) == 0) {
/* Send updated config request */
fsm_sendreq(fsm_p);
}
break;
case fsmOPENED: /* Unexpected event? */
(*fsm_p->pdc->closing)(fsm_p);
(*fsm_p->pdc->starting)(fsm_p);
fsm_reset(fsm_p);
/* fallthru */
case fsmACK_Rcvd: /* Unexpected event? */
free_p(bpp);
fsm_sendreq(fsm_p);
fsm_p->state = fsmREQ_Sent;
break;
case fsmCLOSED:
case fsmLISTEN:
/* Out of Sync; kill the remote */
fsm_sendtermack(fsm_p, hdr.id);
/* fallthru */
case fsmTERM_Sent:
/* We are attempting to close connection; */
/* wait for timeout to resend a Terminate Request */
free_p(bpp);
break;
};
break;
case CONFIG_REJ:
switch(fsm_p->state) {
case fsmREQ_Sent:
case fsmACK_Sent:
if((*fsm_p->pdc->reject)(fsm_p, &hdr, bpp) == 0) {
fsm_sendreq(fsm_p);
}
break;
case fsmOPENED: /* Unexpected event? */
(*fsm_p->pdc->closing)(fsm_p);
(*fsm_p->pdc->starting)(fsm_p);
fsm_reset(fsm_p);
/* fallthru */
case fsmACK_Rcvd: /* Unexpected event? */
free_p(bpp);
fsm_sendreq(fsm_p);
fsm_p->state = fsmREQ_Sent;
break;
case fsmCLOSED:
case fsmLISTEN:
/* Out of Sync; kill the remote */
fsm_sendtermack(fsm_p, hdr.id);
/* fallthru */
case fsmTERM_Sent:
/* We are attempting to close connection; */
/* wait for timeout to resend a Terminate Request */
free_p(bpp);
break;
};
break;
case TERM_REQ:
fsm_log(fsm_p, "Peer requested Termination");
switch(fsm_p->state) {
case fsmOPENED:
fsm_sendtermack(fsm_p, hdr.id);
(*fsm_p->pdc->closing)(fsm_p);
(*fsm_p->pdc->stopping)(fsm_p);
fsm_reset(fsm_p);
break;
case fsmACK_Rcvd:
case fsmACK_Sent:
fsm_p->state = fsmREQ_Sent;
/* fallthru */
case fsmREQ_Sent:
case fsmTERM_Sent:
/* waiting for timeout */
/* fallthru */
case fsmCLOSED:
case fsmLISTEN:
/* Unexpected, but make them happy */
fsm_sendtermack(fsm_p, hdr.id);
break;
};
break;
case TERM_ACK:
switch(fsm_p->state) {
case fsmTERM_Sent:
stop_timer(&(fsm_p->timer));
fsm_log(fsm_p, "Terminated");
(*fsm_p->pdc->stopping)(fsm_p);
fsm_reset(fsm_p);
break;
case fsmOPENED:
/* Remote host has abruptly closed connection */
fsm_log(fsm_p, "Terminated unexpectly");
(*fsm_p->pdc->closing)(fsm_p);
fsm_reset(fsm_p);
if ( fsm_sendreq(fsm_p) == 0 ) {
fsm_p->state = fsmREQ_Sent;
}
break;
case fsmACK_Sent:
case fsmACK_Rcvd:
fsm_p->state = fsmREQ_Sent;
/* fallthru */
case fsmREQ_Sent:
/* waiting for timeout */
/* fallthru */
case fsmCLOSED:
case fsmLISTEN:
/* Unexpected, but no action needed */
break;
};
break;
case CODE_REJ:
trace_log(PPPiface,"%s PPP/%s Code Reject;"
" indicates faulty implementation",
fsm_p->ppp_p->iface->name,
fsm_p->pdc->name);
(*fsm_p->pdc->stopping)(fsm_p);
fsm_reset(fsm_p);
free_p(bpp);
break;
case PROT_REJ:
trace_log(PPPiface,"%s PPP/%s Protocol Reject;"
" please do not use this protocol",
fsm_p->ppp_p->iface->name,
fsm_p->pdc->name);
free_p(bpp);
break;
case ECHO_REQ:
switch(fsm_p->state) {
case fsmOPENED:
fsm_send( fsm_p, ECHO_REPLY, hdr.id, bpp );
break;
case fsmCLOSED:
case fsmLISTEN:
/* Out of Sync; kill the remote */
fsm_sendtermack(fsm_p, hdr.id);
/* fallthru */
case fsmREQ_Sent:
case fsmACK_Rcvd:
case fsmACK_Sent:
case fsmTERM_Sent:
/* ignore */
free_p(bpp);
break;
};
break;
case ECHO_REPLY:
case DISCARD_REQ:
case QUALITY_REPORT:
free_p(bpp);
break;
default:
trace_log(PPPiface,"%s PPP/%s Unknown packet type: %d;"
" Sending Code Reject",
fsm_p->ppp_p->iface->name,
fsm_p->pdc->name,
hdr.code);
hdr.len += CONFIG_HDR_LEN; /* restore length */
htoncnf( &hdr, bpp ); /* put header back on */
fsm_send( fsm_p, CODE_REJ, hdr.id, bpp );
switch(fsm_p->state) {
case fsmREQ_Sent:
case fsmACK_Rcvd:
case fsmACK_Sent:
case fsmOPENED:
fsm_p->state = fsmLISTEN;
break;
case fsmCLOSED:
case fsmLISTEN:
case fsmTERM_Sent:
/* no change */
break;
};
break;
}
}
/************************************************************************/
/* Timeout while waiting for reply from remote host */
static void
fsm_timeout(vp)
void *vp;
{
struct fsm_s *fsm_p = (struct fsm_s *)vp;
PPPtrace = fsm_p->ppp_p->trace;
PPPiface = fsm_p->ppp_p->iface;
fsm_log( fsm_p, "Timeout" );
switch(fsm_p->state) {
case fsmREQ_Sent:
case fsmACK_Rcvd:
case fsmACK_Sent:
if (fsm_p->retry > 0) {
fsm_sendreq(fsm_p);
fsm_p->state = fsmREQ_Sent;
} else {
fsm_log(fsm_p, "Request retry exceeded");
fsm_reset(fsm_p);
}
break;
case fsmTERM_Sent:
if (fsm_p->retry > 0) {
fsm_sendtermreq(fsm_p);
} else {
fsm_log(fsm_p, "Terminate retry exceeded");
(*fsm_p->pdc->stopping)(fsm_p);
fsm_reset(fsm_p);
}
break;
case fsmCLOSED:
case fsmLISTEN:
case fsmOPENED:
/* nothing to do */
break;
}
}
/************************************************************************/
/* I N I T I A L I Z A T I O N */
/************************************************************************/
/* Start FSM (after open event, and physical line up) */
void
fsm_start(fsm_p)
struct fsm_s *fsm_p;
{
if ( fsm_p->pdv == NULL )
return;
PPPtrace = fsm_p->ppp_p->trace;
PPPiface = fsm_p->ppp_p->iface;
fsm_log(fsm_p, "Start");
if ( !(fsm_p->flags & (FSM_ACTIVE | FSM_PASSIVE)) )
return;
switch ( fsm_p->state ) {
case fsmCLOSED:
case fsmLISTEN:
case fsmTERM_Sent:
(*fsm_p->pdc->starting)(fsm_p);
fsm_reset(fsm_p);
if ( fsm_p->flags & FSM_ACTIVE ){
fsm_sendreq(fsm_p);
fsm_p->state = fsmREQ_Sent;
}
break;
default:
/* already started */
break;
};
}
/************************************************************************/
/* Physical Line Down Event */
void
fsm_down(fsm_p)
struct fsm_s *fsm_p;
{
if ( fsm_p->pdv == NULL )
return;
PPPtrace = fsm_p->ppp_p->trace;
PPPiface = fsm_p->ppp_p->iface;
fsm_log(fsm_p, "Down");
switch ( fsm_p->state ) {
case fsmREQ_Sent:
case fsmACK_Rcvd:
case fsmACK_Sent:
stop_timer(&(fsm_p->timer));
fsm_reset(fsm_p);
break;
case fsmOPENED:
(*fsm_p->pdc->closing)(fsm_p);
/* fallthru */
case fsmTERM_Sent:
fsm_reset(fsm_p);
break;
case fsmCLOSED:
case fsmLISTEN:
/* nothing to do */
break;
};
}
/************************************************************************/
/* Close the connection */
void
fsm_close(fsm_p)
struct fsm_s *fsm_p;
{
if ( fsm_p->pdv == NULL )
return;
PPPtrace = fsm_p->ppp_p->trace;
PPPiface = fsm_p->ppp_p->iface;
fsm_log(fsm_p, "Close");
switch ( fsm_p->state ) {
case fsmOPENED:
(*fsm_p->pdc->closing)(fsm_p);
/* fallthru */
case fsmACK_Sent:
fsm_p->retry = fsm_p->try_terminate;
fsm_sendtermreq(fsm_p);
fsm_p->state = fsmTERM_Sent;
break;
case fsmREQ_Sent:
case fsmACK_Rcvd:
/* simply wait for REQ timeout to expire */
fsm_p->retry = 0;
fsm_p->state = fsmTERM_Sent;
break;
case fsmLISTEN:
fsm_p->state = fsmCLOSED;
break;
case fsmTERM_Sent:
case fsmCLOSED:
/* nothing to do */
break;
};
}
/************************************************************************/
/* Initialize the fsm for this protocol
* Called from protocol _init
*/
void
fsm_init(fsm_p)
struct fsm_s *fsm_p;
{
struct timer *t = &(fsm_p->timer);
PPP_DEBUG_ROUTINES("fsm_init()");
fsm_p->try_req = fsm_p->pdc->try_req;
fsm_p->try_nak = fsm_p->pdc->try_nak;
fsm_p->try_terminate = fsm_p->pdc->try_terminate;
fsm_reset(fsm_p);
/* Initialize timer */
t->func = (void (*)())fsm_timeout;
t->arg = (void *)fsm_p;
set_timer(t, fsm_p->pdc->timeout);
fsm_timer(fsm_p);
stop_timer(t);
}
void
fsm_free(fsm_p)
struct fsm_s *fsm_p;
{
if ( fsm_p->pdv != NULL ) {
(*fsm_p->pdc->free)(fsm_p);
free( fsm_p->pdv );
fsm_p->pdv = NULL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -