예제 #1
0
파일: fsm.c 프로젝트: 0x00dec0de/Rovnix
/*
 * 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;
    }
}