/*
 * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
 */
static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len) {
    int ret;
    int treat_as_reject;

    if (id != f->reqid || f->seen_ack)	/* Expected id? */
	return;				/* Nope, toss... */

    if (code == CONFNAK) {
	++f->rnakloops;
	treat_as_reject = (f->rnakloops >= f->maxnakloops);
	if (f->callbacks->nakci == NULL
	    || !(ret = f->callbacks->nakci(f, inp, len, treat_as_reject))) {
	    ppp_error("Received bad configure-nak: %P", inp, len);
	    return;
	}
    } else {
	f->rnakloops = 0;
	if (f->callbacks->rejci == NULL
	    || !(ret = f->callbacks->rejci(f, inp, len))) {
	    ppp_error("Received bad configure-rej: %P", inp, len);
	    return;
	}
    }

    f->seen_ack = 1;

    switch (f->state) {
    case PPP_FSM_CLOSED:
    case PPP_FSM_STOPPED:
	fsm_sdata(f, TERMACK, id, NULL, 0);
	break;

    case PPP_FSM_REQSENT:
    case PPP_FSM_ACKSENT:
	/* They didn't agree to what we wanted - try another request */
	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
	if (ret < 0)
	    f->state = PPP_FSM_STOPPED;		/* kludge for stopping CCP */
	else
	    fsm_sconfreq(f, 0);		/* Send Configure-Request */
	break;

    case PPP_FSM_ACKRCVD:
	/* Got a Nak/reject when we had already had an Ack?? oh well... */
	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
	fsm_sconfreq(f, 0);
	f->state = PPP_FSM_REQSENT;
	break;

    case PPP_FSM_OPENED:
	/* Go down and restart negotiation */
	if (f->callbacks->down)
	    (*f->callbacks->down)(f);	/* Inform upper layers */
	fsm_sconfreq(f, 0);		/* Send initial Configure-Request */
	f->state = PPP_FSM_REQSENT;
	break;
    default:
	break;
    }
}
Exemplo n.º 2
0
Arquivo: ccp.c Projeto: rtemss/rtems
/*
 * Handle a CCP-specific code.
 */
static int
ccp_extcode(
    fsm *f,
    int code, int id,
    u_char *p,
    int len)
{
    switch (code) {
    case CCP_RESETREQ:
        if (f->state != OPENED)
            break;
        /* send a reset-ack, which the transmitter will see and
           reset its compression state. */
        fsm_sdata(f, CCP_RESETACK, id, NULL, 0);
        break;

    case CCP_RESETACK:
        if (ccp_localstate[f->unit] & RACK_PENDING && id == f->reqid) {
            ccp_localstate[f->unit] &= ~(RACK_PENDING | RREQ_REPEAT);
            UNTIMEOUT(ccp_rack_timeout, f);
        }
        break;

    default:
        return 0;
    }

    return 1;
}
Exemplo n.º 3
0
static void
lcp_timeout(void *ctx)
{
	lcp *_this;
	u_char *cp, buf[32];

	_this = ctx;
	if (_this->echo_failures >= _this->echo_max_retries) {
		fsm_log(&_this->fsm, LOG_NOTICE, "keepalive failure.");
		if (_this->fsm.ppp != NULL) {
#ifdef USE_NPPPD_RADIUS
			ppp_set_radius_terminate_cause(_this->fsm.ppp,
			    RADIUS_TERMNATE_CAUSE_IDLE_TIMEOUT);
#endif
			ppp_stop(_this->fsm.ppp, NULL);
		}
		return;
	}
	cp = buf;
	PUTLONG(_this->magic_number, cp);
	fsm_sdata(&_this->fsm, ECHOREQ, _this->fsm.id++, buf, 4);
	_this->echo_failures++;

	lcp_reset_timeout(_this);
}
/*
 * terminate_layer - Start process of shutting down the FSM
 *
 * Cancel any timeout running, notify upper layers we're done, and
 * send a terminate-request message as configured.
 */
static void terminate_layer(fsm *f, int nextstate) {
    ppp_pcb *pcb = f->pcb;

    if( f->state != PPP_FSM_OPENED )
	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
    else if( f->callbacks->down )
	(*f->callbacks->down)(f);	/* Inform upper layers we're down */

    /* Init restart counter and send Terminate-Request */
    f->retransmits = pcb->settings.fsm_max_term_transmits;
    fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
	      (const u_char *) f->term_reason, f->term_reason_len);

    if (f->retransmits == 0) {
	/*
	 * User asked for no terminate requests at all; just close it.
	 * We've already fired off one Terminate-Request just to be nice
	 * to the peer, but we're not going to wait for a reply.
	 */
	f->state = nextstate == PPP_FSM_CLOSING ? PPP_FSM_CLOSED : PPP_FSM_STOPPED;
	if( f->callbacks->finished )
	    (*f->callbacks->finished)(f);
	return;
    }

    TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time);
    --f->retransmits;

    f->state = nextstate;
}
Exemplo n.º 5
0
Arquivo: fsm.c Projeto: AoLaD/rtems
/*
 * fsm_rtermreq - Receive Terminate-Req.
 */
static void
fsm_rtermreq(
    fsm *f,
    int id,
    u_char *p,
    int len)
{
    switch (f->state) {
    case ACKRCVD:
    case ACKSENT:
	f->state = REQSENT;		/* Start over but keep trying */
	break;

    case OPENED:
	if (len > 0) {
	    info("%s terminated by peer (%0.*v)", PROTO_NAME(f), len, p);
	} else
	    info("%s terminated by peer", PROTO_NAME(f));
	if (f->callbacks->down)
	    (*f->callbacks->down)(f);	/* Inform upper layers */
	f->retransmits = 0;
	f->state = STOPPING;
	TIMEOUT(fsm_timeout, f, f->timeouttime);
	break;
    }

    fsm_sdata(f, TERMACK, id, NULL, 0);
}
Exemplo n.º 6
0
/*
 * fsm_rtermreq - Receive Terminate-Req.
 */
static void
fsm_rtermreq(fsm *f, int id, u_char *p, int len)
{
  LWIP_UNUSED_ARG(p);

  FSMDEBUG(LOG_INFO, ("fsm_rtermreq(%s): Rcvd id %d state=%d (%s)\n",
        PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));

  switch (f->state) {
    case LS_ACKRCVD:
    case LS_ACKSENT:
      f->state = LS_REQSENT;    /* Start over but keep trying */
      break;

    case LS_OPENED:
      if (len > 0) {
        FSMDEBUG(LOG_INFO, ("%s terminated by peer (%p)\n", PROTO_NAME(f), p));
      } else {
        FSMDEBUG(LOG_INFO, ("%s terminated by peer\n", PROTO_NAME(f)));
      }
      if (f->callbacks->down) {
        (*f->callbacks->down)(f);  /* Inform upper layers */
      }
      f->retransmits = 0;
      f->state = LS_STOPPING;
      TIMEOUT(fsm_timeout, f, f->timeouttime);
      break;
  }

  fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);
}
Exemplo n.º 7
0
Arquivo: lcp.c Projeto: AoLaD/rtems
/*
 * lcp_extcode - Handle a LCP-specific code.
 */
static int
lcp_extcode(
    fsm *f,
    int code, int id,
    u_char *inp,
    int len)
{
    u_char *magp;

    switch( code ){
    case PROTREJ:
	lcp_rprotrej(f, inp, len);
	break;

    case ECHOREQ:
	if (f->state != OPENED)
	    break;
	magp = inp;
	PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
	fsm_sdata(f, ECHOREP, id, inp, len);
	break;

    case ECHOREP:
	lcp_received_echo_reply(f, id, inp, len);
	break;

    case DISCREQ:
	break;

    default:
	return 0;
    }
    return 1;
}
Exemplo n.º 8
0
/*
 * fsm_rtermreq - Receive Terminate-Req.
 */
static void
fsm_rtermreq(fsm *f, int id, u_char *p, int len)
{
    char str[80];

    FSMDEBUG((LOG_INFO, "fsm_rtermreq(%s): Rcvd id %d.",
	      PROTO_NAME(f), id));

    switch (f->state) {
    case ACKRCVD:
    case ACKSENT:
	f->state = REQSENT;		/* Start over but keep trying */
	break;

    case OPENED:
	if (len > 0) {
	    fmtmsg(str, sizeof(str), "%0.*v", len, p);
	    syslog(LOG_INFO, "%s terminated by peer (%s)", PROTO_NAME(f), str);
	} else
	    syslog(LOG_INFO, "%s terminated by peer", PROTO_NAME(f));
	if (f->callbacks->down)
	    (*f->callbacks->down)(f);	/* Inform upper layers */
	f->retransmits = 0;
	f->state = STOPPING;
	TIMEOUT(fsm_timeout, f, f->timeouttime);
	break;
    }

    fsm_sdata(f, TERMACK, id, NULL, 0);
}
/*
 * fsm_rtermreq - Receive Terminate-Req.
 */
static void fsm_rtermreq(fsm *f, int id, u_char *p, int len) {
    ppp_pcb *pcb = f->pcb;

    switch (f->state) {
    case PPP_FSM_ACKRCVD:
    case PPP_FSM_ACKSENT:
	f->state = PPP_FSM_REQSENT;		/* Start over but keep trying */
	break;

    case PPP_FSM_OPENED:
	if (len > 0) {
	    ppp_info("%s terminated by peer (%0.*v)", PROTO_NAME(f), len, p);
	} else
	    ppp_info("%s terminated by peer", PROTO_NAME(f));
	f->retransmits = 0;
	f->state = PPP_FSM_STOPPING;
	if (f->callbacks->down)
	    (*f->callbacks->down)(f);	/* Inform upper layers */
	TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time);
	break;
    default:
	break;
    }

    fsm_sdata(f, TERMACK, id, NULL, 0);
}
Exemplo n.º 10
0
/**
 * sending Protocol-Reject.
 */
void
lcp_send_protrej(lcp *_this, u_char *pktp, int lpktp)
{
	LCP_ASSERT(_this != NULL);
	LCP_ASSERT(pktp != NULL);

	fsm_sdata(&_this->fsm, PROTREJ, _this->fsm.id++, pktp, lpktp);
}
Exemplo n.º 11
0
/*
 * fsm_timeout - Timeout expired.
 */
static void
fsm_timeout(void *arg)
{
  fsm *f = (fsm *) arg;

  switch (f->state) {
    case LS_CLOSING:
    case LS_STOPPING:
      if( f->retransmits <= 0 ) {
        FSMDEBUG(LOG_WARNING, ("%s: timeout sending Terminate-Request state=%d (%s)\n",
             PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
        /*
         * We've waited for an ack long enough.  Peer probably heard us.
         */
        f->state = (f->state == LS_CLOSING)? LS_CLOSED: LS_STOPPED;
        if( f->callbacks->finished ) {
          (*f->callbacks->finished)(f);
        }
      } else {
        FSMDEBUG(LOG_WARNING, ("%s: timeout resending Terminate-Requests state=%d (%s)\n",
             PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
        /* Send Terminate-Request */
        fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
            (u_char *) f->term_reason, f->term_reason_len);
        TIMEOUT(fsm_timeout, f, f->timeouttime);
        --f->retransmits;
      }
      break;

    case LS_REQSENT:
    case LS_ACKRCVD:
    case LS_ACKSENT:
      if (f->retransmits <= 0) {
        FSMDEBUG(LOG_WARNING, ("%s: timeout sending Config-Requests state=%d (%s)\n",
         PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
        f->state = LS_STOPPED;
        if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) {
          (*f->callbacks->finished)(f);
        }
      } else {
        FSMDEBUG(LOG_WARNING, ("%s: timeout resending Config-Request state=%d (%s)\n",
         PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
        /* Retransmit the configure-request */
        if (f->callbacks->retransmit) {
          (*f->callbacks->retransmit)(f);
        }
        fsm_sconfreq(f, 1);    /* Re-send Configure-Request */
        if( f->state == LS_ACKRCVD ) {
          f->state = LS_REQSENT;
        }
      }
      break;

    default:
      FSMDEBUG(LOG_INFO, ("%s: UNHANDLED timeout event in state %d (%s)!\n",
          PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
  }
}
Exemplo n.º 12
0
/*
 * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
 */
static void
fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len)
{
  int (*proc) (fsm *, u_char *, int);
  int ret;

  FSMDEBUG(LOG_INFO, ("fsm_rconfnakrej(%s): Rcvd id %d state=%d (%s)\n",
        PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));

  if (id != f->reqid || f->seen_ack) { /* Expected id? */
    return;        /* Nope, toss... */
  }
  proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;
  if (!proc || !((ret = proc(f, inp, len)))) {
    /* Nak/reject is bad - ignore it */
    FSMDEBUG(LOG_INFO, ("%s: received bad %s (length %d)\n",
          PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));
    return;
  }
  f->seen_ack = 1;

  switch (f->state) {
    case LS_CLOSED:
    case LS_STOPPED:
      fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);
      break;
    
    case LS_REQSENT:
    case LS_ACKSENT:
      /* They didn't agree to what we wanted - try another request */
      UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
      if (ret < 0) {
        f->state = LS_STOPPED;    /* kludge for stopping CCP */
      } else {
        fsm_sconfreq(f, 0);    /* Send Configure-Request */
      }
      break;
    
    case LS_ACKRCVD:
      /* Got a Nak/reject when we had already had an Ack?? oh well... */
      UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
      fsm_sconfreq(f, 0);
      f->state = LS_REQSENT;
      break;
    
    case LS_OPENED:
      /* Go down and restart negotiation */
      if (f->callbacks->down) {
        (*f->callbacks->down)(f);  /* Inform upper layers */
      }
      fsm_sconfreq(f, 0);    /* Send initial Configure-Request */
      f->state = LS_REQSENT;
      break;
  }
}
Exemplo n.º 13
0
/*
 * fsm_rconfack - Receive Configure-Ack.
 */
static void
fsm_rconfack(fsm *f, int id, u_char *inp, int len)
{
  FSMDEBUG(LOG_INFO, ("fsm_rconfack(%s): Rcvd id %d state=%d (%s)\n",
        PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));
  
  if (id != f->reqid || f->seen_ack) {   /* Expected id? */
    return; /* Nope, toss... */
  }
  if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): (len == 0)) ) {
    /* Ack is bad - ignore it */
    FSMDEBUG(LOG_INFO, ("%s: received bad Ack (length %d)\n",
          PROTO_NAME(f), len));
    return;
  }
  f->seen_ack = 1;
  
  switch (f->state) {
    case LS_CLOSED:
    case LS_STOPPED:
      fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);
      break;
    
    case LS_REQSENT:
      f->state = LS_ACKRCVD;
      f->retransmits = f->maxconfreqtransmits;
      break;
    
    case LS_ACKRCVD:
      /* Huh? an extra valid Ack? oh well... */
      UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
      fsm_sconfreq(f, 0);
      f->state = LS_REQSENT;
      break;
    
    case LS_ACKSENT:
      UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
      f->state = LS_OPENED;
      f->retransmits = f->maxconfreqtransmits;
      if (f->callbacks->up) {
        (*f->callbacks->up)(f);  /* Inform upper layers */
      }
      break;
    
    case LS_OPENED:
      /* Go down and restart negotiation */
      if (f->callbacks->down) {
        (*f->callbacks->down)(f);  /* Inform upper layers */
      }
      fsm_sconfreq(f, 0);    /* Send initial Configure-Request */
      f->state = LS_REQSENT;
      break;
  }
}
Exemplo n.º 14
0
/*
 * fsm_rconfack - Receive Configure-Ack.
 */
static void
fsm_rconfack(fsm *f, int id, u_char *inp, int len)
{
    FSMDEBUG((LOG_INFO, "fsm_rconfack(%s): Rcvd id %d.",
	      PROTO_NAME(f), id));

    if (id != f->reqid || f->seen_ack)		/* Expected id? */
	return;					/* Nope, toss... */
    if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len):
	  (len == 0)) ){
	/* Ack is bad - ignore it */
	log_packet(inp, len, "Received bad configure-ack: ", LOG_ERR);
	FSMDEBUG((LOG_INFO, "%s: received bad Ack (length %d)",
		  PROTO_NAME(f), len));
	return;
    }
    f->seen_ack = 1;

    switch (f->state) {
    case CLOSED:
    case STOPPED:
	fsm_sdata(f, TERMACK, id, NULL, 0);
	break;

    case REQSENT:
	f->state = ACKRCVD;
	f->retransmits = f->maxconfreqtransmits;
	break;

    case ACKRCVD:
	/* Huh? an extra valid Ack? oh well... */
	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
	fsm_sconfreq(f, 0);
	f->state = REQSENT;
	break;

    case ACKSENT:
	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
	f->state = OPENED;
	f->retransmits = f->maxconfreqtransmits;
	if (f->callbacks->up)
	    (*f->callbacks->up)(f);	/* Inform upper layers */
	break;

    case OPENED:
	/* Go down and restart negotiation */
	if (f->callbacks->down)
	    (*f->callbacks->down)(f);	/* Inform upper layers */
	fsm_sconfreq(f, 0);		/* Send initial Configure-Request */
	f->state = REQSENT;
	break;
    }
}
Exemplo n.º 15
0
Arquivo: fsm.c Projeto: AoLaD/rtems
/*
 * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
 */
static void
fsm_rconfnakrej(
    fsm *f,
    int code, int id,
    u_char *inp,
    int len)
{
    int (*proc)(fsm *, u_char *, int);
    int ret;

    if (id != f->reqid || f->seen_ack)	/* Expected id? */
	return;				/* Nope, toss... */
    proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;
    if (!proc || !(ret = proc(f, inp, len))) {
	/* Nak/reject is bad - ignore it */
	error("Received bad configure-nak/rej: %P", inp, len);
	return;
    }
    f->seen_ack = 1;

    switch (f->state) {
    case CLOSED:
    case STOPPED:
	fsm_sdata(f, TERMACK, id, NULL, 0);
	break;

    case REQSENT:
    case ACKSENT:
	/* They didn't agree to what we wanted - try another request */
	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
	if (ret < 0)
	    f->state = STOPPED;		/* kludge for stopping CCP */
	else
	    fsm_sconfreq(f, 0);		/* Send Configure-Request */
	break;

    case ACKRCVD:
	/* Got a Nak/reject when we had already had an Ack?? oh well... */
	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
	fsm_sconfreq(f, 0);
	f->state = REQSENT;
	break;

    case OPENED:
	/* Go down and restart negotiation */
	if (f->callbacks->down)
	    (*f->callbacks->down)(f);	/* Inform upper layers */
	fsm_sconfreq(f, 0);		/* Send initial Configure-Request */
	f->state = REQSENT;
	break;
    }
}
/*
 * fsm_rconfack - Receive Configure-Ack.
 */
static void fsm_rconfack(fsm *f, int id, u_char *inp, int len) {
    ppp_pcb *pcb = f->pcb;

    if (id != f->reqid || f->seen_ack)		/* Expected id? */
	return;					/* Nope, toss... */
    if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len):
	  (len == 0)) ){
	/* Ack is bad - ignore it */
	ppp_error("Received bad configure-ack: %P", inp, len);
	return;
    }
    f->seen_ack = 1;
    f->rnakloops = 0;

    switch (f->state) {
    case PPP_FSM_CLOSED:
    case PPP_FSM_STOPPED:
	fsm_sdata(f, TERMACK, id, NULL, 0);
	break;

    case PPP_FSM_REQSENT:
	f->state = PPP_FSM_ACKRCVD;
	f->retransmits = pcb->settings.fsm_max_conf_req_transmits;
	break;

    case PPP_FSM_ACKRCVD:
	/* Huh? an extra valid Ack? oh well... */
	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
	fsm_sconfreq(f, 0);
	f->state = PPP_FSM_REQSENT;
	break;

    case PPP_FSM_ACKSENT:
	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
	f->state = PPP_FSM_OPENED;
	f->retransmits = pcb->settings.fsm_max_conf_req_transmits;
	if (f->callbacks->up)
	    (*f->callbacks->up)(f);	/* Inform upper layers */
	break;

    case PPP_FSM_OPENED:
	/* Go down and restart negotiation */
	if (f->callbacks->down)
	    (*f->callbacks->down)(f);	/* Inform upper layers */
	fsm_sconfreq(f, 0);		/* Send initial Configure-Request */
	f->state = PPP_FSM_REQSENT;
	break;
    default:
	break;
    }
}
Exemplo n.º 17
0
/*
 * fsm_timeout - Timeout expired.
 */
static void
fsm_timeout(void *arg)
{
    fsm *f = (fsm *) arg;

    switch (f->state) {
    case CLOSING:
    case STOPPING:
	if( f->retransmits <= 0 ){
	    /*
	     * We've waited for an ack long enough.  Peer probably heard us.
	     */
	    f->state = (f->state == CLOSING)? CLOSED: STOPPED;
	    if( f->callbacks->finished )
		(*f->callbacks->finished)(f);
	} else {
	    /* Send Terminate-Request */
	    fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
		      (u_char *) f->term_reason, f->term_reason_len);
	    TIMEOUT(fsm_timeout, f, f->timeouttime);
	    --f->retransmits;
	}
	break;

    case REQSENT:
    case ACKRCVD:
    case ACKSENT:
	if (f->retransmits <= 0) {
	    syslog(LOG_WARNING, "%s: timeout sending Config-Requests",
		   PROTO_NAME(f));
	    f->state = STOPPED;
	    if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished )
		(*f->callbacks->finished)(f);

	} else {
	    /* Retransmit the configure-request */
	    if (f->callbacks->retransmit)
		(*f->callbacks->retransmit)(f);
	    fsm_sconfreq(f, 1);		/* Re-send Configure-Request */
	    if( f->state == ACKRCVD )
		f->state = REQSENT;
	}
	break;

    default:
	FSMDEBUG((LOG_INFO, "%s: Timeout event in state %d!",
		  PROTO_NAME(f), f->state));
    }
}
Exemplo n.º 18
0
/*
 * fsm_sconfreq - Send a Configure-Request.
 */
static void
fsm_sconfreq(fsm *f, int retransmit)
{
  u_char *outp;
  int cilen;
  
  if( f->state != LS_REQSENT && f->state != LS_ACKRCVD && f->state != LS_ACKSENT ) {
    /* Not currently negotiating - reset options */
    if( f->callbacks->resetci ) {
      (*f->callbacks->resetci)(f);
    }
    f->nakloops = 0;
  }
  
  if( !retransmit ) {
    /* New request - reset retransmission counter, use new ID */
    f->retransmits = f->maxconfreqtransmits;
    f->reqid = ++f->id;
  }
  
  f->seen_ack = 0;
  
  /*
   * Make up the request packet
   */
  outp = outpacket_buf[f->unit] + PPP_HDRLEN + HEADERLEN;
  if( f->callbacks->cilen && f->callbacks->addci ) {
    cilen = (*f->callbacks->cilen)(f);
    if( cilen > peer_mru[f->unit] - (int)HEADERLEN ) {
      cilen = peer_mru[f->unit] - HEADERLEN;
    }
    if (f->callbacks->addci) {
      (*f->callbacks->addci)(f, outp, &cilen);
    }
  } else {
    cilen = 0;
  }

  /* send the request to our peer */
  fsm_sdata(f, CONFREQ, f->reqid, outp, cilen);
  
  /* start the retransmit timer */
  --f->retransmits;
  TIMEOUT(fsm_timeout, f, f->timeouttime);
  
  FSMDEBUG(LOG_INFO, ("%s: sending Configure-Request, id %d\n",
        PROTO_NAME(f), f->reqid));
}
Exemplo n.º 19
0
Arquivo: lcp.c Projeto: AoLaD/rtems
/*
 * lcp_sprotrej - Send a Protocol-Reject for some protocol.
 */
void
lcp_sprotrej(
    int unit,
    u_char *p,
    int len)
{
    /*
     * Send back the protocol and the information field of the
     * rejected packet.  We only get here if LCP is in the OPENED state.
     */
    p += 2;
    len -= 2;

    fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id,
	      p, len);
}
/*
 * fsm_timeout - Timeout expired.
 */
static void fsm_timeout(void *arg) {
    fsm *f = (fsm *) arg;
    ppp_pcb *pcb = f->pcb;

    switch (f->state) {
    case PPP_FSM_CLOSING:
    case PPP_FSM_STOPPING:
	if( f->retransmits <= 0 ){
	    /*
	     * We've waited for an ack long enough.  Peer probably heard us.
	     */
	    f->state = (f->state == PPP_FSM_CLOSING)? PPP_FSM_CLOSED: PPP_FSM_STOPPED;
	    if( f->callbacks->finished )
		(*f->callbacks->finished)(f);
	} else {
	    /* Send Terminate-Request */
	    fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
		      (const u_char *) f->term_reason, f->term_reason_len);
	    TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time);
	    --f->retransmits;
	}
	break;

    case PPP_FSM_REQSENT:
    case PPP_FSM_ACKRCVD:
    case PPP_FSM_ACKSENT:
	if (f->retransmits <= 0) {
	    ppp_warn("%s: timeout sending Config-Requests", PROTO_NAME(f));
	    f->state = PPP_FSM_STOPPED;
	    if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished )
		(*f->callbacks->finished)(f);

	} else {
	    /* Retransmit the configure-request */
	    if (f->callbacks->retransmit)
		(*f->callbacks->retransmit)(f);
	    fsm_sconfreq(f, 1);		/* Re-send Configure-Request */
	    if( f->state == PPP_FSM_ACKRCVD )
		f->state = PPP_FSM_REQSENT;
	}
	break;

    default:
	FSMDEBUG(("%s: Timeout event in state %d!", PROTO_NAME(f), f->state));
	/* no break */
    }
}
Exemplo n.º 21
0
/*
 * fsm_protreject - Peer doesn't speak this protocol.
 *
 * Treat this as a catastrophic error (RXJ-).
 */
void
fsm_protreject(fsm *f)
{
  switch( f->state ) {
    case LS_CLOSING:
      UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
      /* fall through */
    case LS_CLOSED:
      f->state = LS_CLOSED;
      if( f->callbacks->finished ) {
        (*f->callbacks->finished)(f);
      }
      break;

    case LS_STOPPING:
    case LS_REQSENT:
    case LS_ACKRCVD:
    case LS_ACKSENT:
      UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
      /* fall through */
    case LS_STOPPED:
      f->state = LS_STOPPED;
      if( f->callbacks->finished ) {
        (*f->callbacks->finished)(f);
      }
      break;
    
    case LS_OPENED:
      if( f->callbacks->down ) {
        (*f->callbacks->down)(f);
      }
      /* Init restart counter, send Terminate-Request */
      f->retransmits = f->maxtermtransmits;
      fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
            (u_char *) f->term_reason, f->term_reason_len);
      TIMEOUT(fsm_timeout, f, f->timeouttime);
      --f->retransmits;

      f->state = LS_STOPPING;
      break;
    
    default:
      FSMDEBUG(LOG_INFO, ("%s: Protocol-reject event in state %d (%s)!\n",
            PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
    }
}
Exemplo n.º 22
0
Arquivo: fsm.c Projeto: AoLaD/rtems
/*
 * fsm_sconfreq - Send a Configure-Request.
 */
static void
fsm_sconfreq(
    fsm *f,
    int retransmit)
{
    u_char *outp;
    int cilen;

    if( f->state != REQSENT && f->state != ACKRCVD && f->state != ACKSENT ){
	/* Not currently negotiating - reset options */
	if( f->callbacks->resetci )
	    (*f->callbacks->resetci)(f);
	f->nakloops = 0;
    }

    if( !retransmit ){
	/* New request - reset retransmission counter, use new ID */
	f->retransmits = f->maxconfreqtransmits;
	f->reqid = ++f->id;
    }

    f->seen_ack = 0;

    /*
     * Make up the request packet
     */
    outp = outpacket_buf + PPP_HDRLEN + HEADERLEN;
    if( f->callbacks->cilen && f->callbacks->addci ){
	cilen = (*f->callbacks->cilen)(f);
	if( cilen > peer_mru[f->unit] - HEADERLEN )
	    cilen = peer_mru[f->unit] - HEADERLEN;
	if (f->callbacks->addci)
	    (*f->callbacks->addci)(f, outp, &cilen);
    } else
	cilen = 0;

    /* send the request to our peer */
    fsm_sdata(f, CONFREQ, f->reqid, outp, cilen);

    /* start the retransmit timer */
    --f->retransmits;
    TIMEOUT(fsm_timeout, f, f->timeouttime);
}
Exemplo n.º 23
0
/*
 * fsm_close - Start closing connection.
 *
 * Cancel timeouts and either initiate close or possibly go directly to
 * the LS_CLOSED state.
 */
void
fsm_close(fsm *f, char *reason)
{
  int oldState = f->state;

  LWIP_UNUSED_ARG(oldState);

  f->term_reason = reason;
  f->term_reason_len = (reason == NULL ? 0 : (int)strlen(reason));
  switch( f->state ) {
    case LS_STARTING:
      f->state = LS_INITIAL;
      break;
    case LS_STOPPED:
      f->state = LS_CLOSED;
      break;
    case LS_STOPPING:
      f->state = LS_CLOSING;
      break;

    case LS_REQSENT:
    case LS_ACKRCVD:
    case LS_ACKSENT:
    case LS_OPENED:
      if( f->state != LS_OPENED ) {
        UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
      } else if( f->callbacks->down ) {
        (*f->callbacks->down)(f);  /* Inform upper layers we're down */
      }
      /* Init restart counter, send Terminate-Request */
      f->retransmits = f->maxtermtransmits;
      fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
            (u_char *) f->term_reason, f->term_reason_len);
      TIMEOUT(fsm_timeout, f, f->timeouttime);
      --f->retransmits;

      f->state = LS_CLOSING;
      break;
  }

  FSMDEBUG(LOG_INFO, ("%s: close reason=%s state %d (%s) -> %d (%s)\n",
      PROTO_NAME(f), reason, oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state]));
}
Exemplo n.º 24
0
static int
lcp_rechoreq(fsm *f, int id, u_char *inp, int inlen)
{
	u_char *inp0;
	lcp *_this;
	int len;

	if (inlen < 4)
		return 0;

	_this = &f->ppp->lcp;
	inp0 = inp;
	PUTLONG(_this->magic_number, inp)

	len = MIN(inlen, f->ppp->peer_mru - 8);
	fsm_sdata(f, ECHOREP, id, inp0, len);

	return 1;
}
Exemplo n.º 25
0
Arquivo: fsm.c Projeto: AoLaD/rtems
/*
 * fsm_close - Start closing connection.
 *
 * Cancel timeouts and either initiate close or possibly go directly to
 * the CLOSED state.
 */
void
fsm_close(
    fsm *f,
    char *reason)
{
    f->term_reason = reason;
    f->term_reason_len = (reason == NULL? 0: strlen(reason));
    switch( f->state ){
    case STARTING:
	f->state = INITIAL;
	break;
    case STOPPED:
	f->state = CLOSED;
	break;
    case STOPPING:
	f->state = CLOSING;
	break;

    case REQSENT:
    case ACKRCVD:
    case ACKSENT:
    case OPENED:
	if( f->state != OPENED )
	    UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
	else if( f->callbacks->down )
	    (*f->callbacks->down)(f);	/* Inform upper layers we're down */

	/* Init restart counter, send Terminate-Request */
	f->retransmits = f->maxtermtransmits;
	fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
		  (u_char *) f->term_reason, f->term_reason_len);
	TIMEOUT(fsm_timeout, f, f->timeouttime);
	--f->retransmits;

	f->state = CLOSING;
	break;
    }
}
Exemplo n.º 26
0
/*
 * fsm_rconfreq - Receive Configure-Request.
 */
static void
fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len)
{
  int code, reject_if_disagree;

  FSMDEBUG(LOG_INFO, ("fsm_rconfreq(%s): Rcvd id %d state=%d (%s)\n", 
        PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));
  switch( f->state ) {
    case LS_CLOSED:
      /* Go away, we're closed */
      fsm_sdata(f, TERMACK, id, NULL, 0);
      return;
    case LS_CLOSING:
    case LS_STOPPING:
      return;

    case LS_OPENED:
      /* Go down and restart negotiation */
      if( f->callbacks->down ) {
        (*f->callbacks->down)(f);  /* Inform upper layers */
      }
      fsm_sconfreq(f, 0);    /* Send initial Configure-Request */
      break;

    case LS_STOPPED:
      /* Negotiation started by our peer */
      fsm_sconfreq(f, 0);    /* Send initial Configure-Request */
      f->state = LS_REQSENT;
      break;
  }
  
  /*
  * Pass the requested configuration options
  * to protocol-specific code for checking.
  */
  if (f->callbacks->reqci) {    /* Check CI */
    reject_if_disagree = (f->nakloops >= f->maxnakloops);
    code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree);
  } else if (len) {
    code = CONFREJ;      /* Reject all CI */
  } else {
    code = CONFACK;
  }
  
  /* send the Ack, Nak or Rej to the peer */
  fsm_sdata(f, (u_char)code, id, inp, len);
  
  if (code == CONFACK) {
    if (f->state == LS_ACKRCVD) {
      UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
      f->state = LS_OPENED;
      if (f->callbacks->up) {
        (*f->callbacks->up)(f);  /* Inform upper layers */
      }
    } else {
      f->state = LS_ACKSENT;
    }
    f->nakloops = 0;
  } else {
    /* we sent CONFACK or CONFREJ */
    if (f->state != LS_ACKRCVD) {
      f->state = LS_REQSENT;
    }
    if( code == CONFNAK ) {
      ++f->nakloops;
    }
  }
}
Exemplo n.º 27
0
/*
 * fsm_input - Input packet.
 */
void
fsm_input(fsm *f, u_char *inpacket, int l)
{
  u_char *inp = inpacket;
  u_char code, id;
  int len;

  /*
  * Parse header (code, id and length).
  * If packet too short, drop it.
  */
  if (l < HEADERLEN) {
    FSMDEBUG(LOG_WARNING, ("fsm_input(%x): Rcvd short header.\n",
          f->protocol));
    return;
  }
  GETCHAR(code, inp);
  GETCHAR(id, inp);
  GETSHORT(len, inp);
  if (len < HEADERLEN) {
    FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd illegal length.\n",
        f->protocol));
    return;
  }
  if (len > l) {
    FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd short packet.\n",
        f->protocol));
    return;
  }
  len -= HEADERLEN;    /* subtract header length */

  if( f->state == LS_INITIAL || f->state == LS_STARTING ) {
    FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd packet in state %d (%s).\n",
        f->protocol, f->state, ppperr_strerr[f->state]));
    return;
  }
  FSMDEBUG(LOG_INFO, ("fsm_input(%s):%d,%d,%d\n", PROTO_NAME(f), code, id, l));
  /*
   * Action depends on code.
   */
  switch (code) {
    case CONFREQ:
      fsm_rconfreq(f, id, inp, len);
      break;
    
    case CONFACK:
      fsm_rconfack(f, id, inp, len);
      break;
    
    case CONFNAK:
    case CONFREJ:
      fsm_rconfnakrej(f, code, id, inp, len);
      break;
    
    case TERMREQ:
      fsm_rtermreq(f, id, inp, len);
      break;
    
    case TERMACK:
      fsm_rtermack(f);
      break;
    
    case CODEREJ:
      fsm_rcoderej(f, inp, len);
      break;
    
    default:
      FSMDEBUG(LOG_INFO, ("fsm_input(%s): default: \n", PROTO_NAME(f)));
      if( !f->callbacks->extcode ||
          !(*f->callbacks->extcode)(f, code, id, inp, len) ) {
        fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN);
      }
      break;
  }
}
/*
 * fsm_input - Input packet.
 */
void fsm_input(fsm *f, u_char *inpacket, int l) {
    u_char *inp;
    u_char code, id;
    int len;

    /*
     * Parse header (code, id and length).
     * If packet too short, drop it.
     */
    inp = inpacket;
    if (l < HEADERLEN) {
	FSMDEBUG(("fsm_input(%x): Rcvd short header.", f->protocol));
	return;
    }
    GETCHAR(code, inp);
    GETCHAR(id, inp);
    GETSHORT(len, inp);
    if (len < HEADERLEN) {
	FSMDEBUG(("fsm_input(%x): Rcvd illegal length.", f->protocol));
	return;
    }
    if (len > l) {
	FSMDEBUG(("fsm_input(%x): Rcvd short packet.", f->protocol));
	return;
    }
    len -= HEADERLEN;		/* subtract header length */

    if( f->state == PPP_FSM_INITIAL || f->state == PPP_FSM_STARTING ){
	FSMDEBUG(("fsm_input(%x): Rcvd packet in state %d.",
		  f->protocol, f->state));
	return;
    }

    /*
     * Action depends on code.
     */
    switch (code) {
    case CONFREQ:
	fsm_rconfreq(f, id, inp, len);
	break;
    
    case CONFACK:
	fsm_rconfack(f, id, inp, len);
	break;
    
    case CONFNAK:
    case CONFREJ:
	fsm_rconfnakrej(f, code, id, inp, len);
	break;
    
    case TERMREQ:
	fsm_rtermreq(f, id, inp, len);
	break;
    
    case TERMACK:
	fsm_rtermack(f);
	break;
    
    case CODEREJ:
	fsm_rcoderej(f, inp, len);
	break;
    
    default:
	if( !f->callbacks->extcode
	   || !(*f->callbacks->extcode)(f, code, id, inp, len) )
	    fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN);
	break;
    }
}
/*
 * fsm_rconfreq - Receive Configure-Request.
 */
static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len) {
    int code, reject_if_disagree;

    switch( f->state ){
    case PPP_FSM_CLOSED:
	/* Go away, we're closed */
	fsm_sdata(f, TERMACK, id, NULL, 0);
	return;
    case PPP_FSM_CLOSING:
    case PPP_FSM_STOPPING:
	return;

    case PPP_FSM_OPENED:
	/* Go down and restart negotiation */
	if( f->callbacks->down )
	    (*f->callbacks->down)(f);	/* Inform upper layers */
	fsm_sconfreq(f, 0);		/* Send initial Configure-Request */
	f->state = PPP_FSM_REQSENT;
	break;

    case PPP_FSM_STOPPED:
	/* Negotiation started by our peer */
	fsm_sconfreq(f, 0);		/* Send initial Configure-Request */
	f->state = PPP_FSM_REQSENT;
	break;
    default:
	break;
    }

    /*
     * Pass the requested configuration options
     * to protocol-specific code for checking.
     */
    if (f->callbacks->reqci){		/* Check CI */
	reject_if_disagree = (f->nakloops >= f->maxnakloops);
	code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree);
    } else if (len)
	code = CONFREJ;			/* Reject all CI */
    else
	code = CONFACK;

    /* send the Ack, Nak or Rej to the peer */
    fsm_sdata(f, code, id, inp, len);

    if (code == CONFACK) {
	if (f->state == PPP_FSM_ACKRCVD) {
	    UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
	    f->state = PPP_FSM_OPENED;
	    if (f->callbacks->up)
		(*f->callbacks->up)(f);	/* Inform upper layers */
	} else
	    f->state = PPP_FSM_ACKSENT;
	f->nakloops = 0;

    } else {
	/* we sent CONFACK or CONFREJ */
	if (f->state != PPP_FSM_ACKRCVD)
	    f->state = PPP_FSM_REQSENT;
	if( code == CONFNAK )
	    ++f->nakloops;
    }
}