Exemple #1
0
static void IGMP_rcv_query
   (
      IP_IF_PTR   ipif,          /* [IN] the interface which receive the report */
      _ip_address group_ip,      /* [IN] the ip address of the multicast group */
      uint32_t     max_resp_time  /* [IN] the maximum response time of the query */
   )
{ /* Body */
   MC_MEMBER_PTR  member;


   /* sanity check */
   if (IN_LOCAL_MULTICAST(group_ip)) {
      return;
   } /* Endif */

#ifndef IGMP_V2
   max_resp_time = 0;   /* force a IGMP_V1 report */
#endif

   /* test if it is a IGMPv1 query */
   if (max_resp_time == 0) {
      max_resp_time = IGMP_V1_QUERY_RESPONSE_INTERVAL;
#ifdef IGMP_V2
      /* set the time out */
      ipif->IGMP_V1_ROUTER_FLAG = TRUE;
      ipif->IGMP_V1_ROUTER_TIMEOUT = RTCS_time_get()
                                     + IGMP_V1_ROUTER_TIMEOUT_VALUE;
#endif /* IGMP_V2 */
      group_ip = 0;  /* with IGMPv1, an query is always general (never group-specific) */
   } else  {
      /* convert IGMP_UNIT (1/10 sec) into the local unit (1/1000 sec) */
      max_resp_time = max_resp_time * (1000/10);
   } /* Endif */

   /* test if the group is already joined */
   for (member = ipif->IGMP_MEMBER ; member ; member = member->NEXT) {
      /* filter the suitable member(s) */
      if (group_ip && group_ip != member->IGRP.imr_multiaddr.s_addr) {
         continue;
      } /* Endif */

      /* never report a local group */
      if (IN_LOCAL_MULTICAST(member->IGRP.imr_multiaddr.s_addr)) {
         continue;
      } /* Endif */
      if (member->RUNNING_TIMER) {
         /* if a timer is running, check if the timer must be relaunched */
         if (TCPIP_Event_expire(&member->TIMER) > max_resp_time) {
            IGMP_stop_timer(member);
            IGMP_launch_timer(member, RTCS_rand() % max_resp_time);
         } /* Endif */
      } else {
         IGMP_init_timer(member);
         IGMP_launch_timer(member, RTCS_rand() % max_resp_time);
      } /* Endif */
   } /* Endfor */

} /* Endbody */
Exemple #2
0
static bool IGMP_expire
   (
      TCPIP_EVENT_PTR   event          /* [IN/OUT] the expiration event */
   )
{ /* Body */
   MC_MEMBER_PTR  member = event->PRIVATE;
   uint32_t        error;

   member->RUNNING_TIMER = FALSE;

   error = IGMP_send_report(&member->IGRP, IGMP_DEFAULT_REPORT);

   /* an error occurs, retry later */
   if (!error) {
      member->TIMER.TIME = RTCS_rand()%IGMP_UNSOLICITED_REPORT_INTERVAL;
      member->RUNNING_TIMER = TRUE;
      return TRUE;
   } /* Endif */

   /* handle the unsolicited_report repetition */
   if (member->UNSOLICITED_REPORT_COUNTER) {
      member->UNSOLICITED_REPORT_COUNTER--;
      member->TIMER.TIME = IGMP_UNSOLICITED_REPORT_INTERVAL;
      member->RUNNING_TIMER = TRUE;
      return TRUE;
   } /* Endif */
#ifdef IGMP_V2
   member->LAST_REPORTER = TRUE;
#endif

   return FALSE;
} /* Endbody */
Exemple #3
0
void CHAP_challenge
   (
      _ppp_handle    handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */
   PPP_CFG_PTR    ppp_ptr = handle;
   CHAP_DATA_PTR  chap_ptr = &ppp_ptr->CHAP_STATE;
   PCB_PTR        pcb;
   uchar_ptr      outp;
   uint_16        len;
   uint_16        i, idlen;

   chap_ptr->SERVER_STATE = CHAP_STATE_INITIAL;
   chap_ptr->CURID = RTCS_rand() & 0xFF;

   /* Acquire a message buffer */
   /* Start CR 2207 */
   idlen = strlen(PPP_SECRET(ppp_ptr,_PPP_CHAP_LNAME));
   /* End CR 2207 */
   len = CHAP_HDR_LEN + 1 + CHAP_CHALLENGE_LEN + idlen;
   pcb = PPP_pcballoc(PPP_PROT_CHAP, len);
   if (pcb == NULL) {
      return;
   } /* Endif */

   /* Build a Challenge packet */
   outp = pcb->FRAG[0].FRAGMENT + 2;
   *outp++ = CHAP_CODE_CHALLENGE;
   *outp++ = chap_ptr->CURID;
   *outp++ = (len >> 8) & 0xFF;
   *outp++ =  len       & 0xFF;
   *outp++ = CHAP_CHALLENGE_LEN;
   for (i=0; i<CHAP_CHALLENGE_LEN; i++) {
      *outp++ = chap_ptr->MD5[i] = RTCS_rand() & 0xFF;
   } /* Endfor */
   /* Start CR 2207 */
   PPP_memcopy(PPP_SECRET(ppp_ptr,_PPP_CHAP_LNAME), outp, idlen);
   /* End CR 2207 */
   /* Send the PCB */
   PPP_send_rexmit(ppp_ptr, PPP_PROT_CHAP, pcb, 0, CHAP_timeout, chap_ptr);

} /* Endbody */
Exemple #4
0
void PAP_send
   (
      _ppp_handle    handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR    ppp_ptr = handle;
   PAP_DATA_PTR   pap_ptr = &ppp_ptr->PAP_STATE;
   PCB_PTR        pcb;
   unsigned char      *outp;
   uint16_t        len;

   pap_ptr->CLIENT_STATE = PAP_STATE_INITIAL;
   pap_ptr->CURID = RTCS_rand() & 0xFF;

   /* Acquire a PCB */
   len = PAP_HDR_LEN + 2
/* Start CR 2207 */
       + PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET->PPP_ID_LENGTH)
       + PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET->PPP_PW_LENGTH);
/* End CR 2207 */

   pcb = PPP_pcballoc(PPP_PROT_PAP, len);
   if (pcb == NULL) {
      return;
   } /* Endif */

   /* Build an Authenticate-Request packet */
   outp = pcb->FRAG[0].FRAGMENT + 2;
   *outp++ = PAP_CODE_AUTH_REQ;
   *outp++ = pap_ptr->CURID;
   *outp++ = (len >> 8) & 0xFF;
   *outp++ =  len       & 0xFF;
/* Start CR 2207 */
   *outp++ = len = PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET->PPP_ID_LENGTH);
   PPP_memcopy(PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET->PPP_ID_PTR), outp, len);
   outp += len;
   *outp++ = len = PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET->PPP_PW_LENGTH);
   PPP_memcopy(PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET->PPP_PW_PTR), outp, len);
/* End CR 2207 */

   /* Send the PCB */
   PPP_send_rexmit(ppp_ptr, PPP_PROT_PAP, pcb, 0, PAP_timeout, pap_ptr);

#endif /* RTCSCFG_ENABLE_IP4 */

} /* Endbody */
Exemple #5
0
void BOOTP_open
   (
      TCPIP_PARM_BOOTP _PTR_ parms
   )
{ /* Body */
   IP_IF_PTR      if_ptr = (IP_IF_PTR)parms->handle;
   BOOTP_CFG_PTR  bootp = (BOOTP_CFG_PTR) &parms->config;
   uint_32        error;

   error = BOOT_open(BOOT_service);
   if (error) {
      RTCSCMD_complete(parms, error);
      return;
   } /* Endif */

   if_ptr->BOOTFN = BOOTP_service;

   /* Pick a random transaction ID */
   bootp->XID = RTCS_rand();

   /* Set initial timeout */
   bootp->TIMEOUT = BOOTP_TIMEOUT_MIN;
   bootp->SECS = 0;

   /* Build a BOOTREQUEST packet */
   htonc(bootp->PACKET.OP,    BOOTPOP_BOOTREQUEST);
   htonc(bootp->PACKET.HTYPE, if_ptr->DEV_TYPE);
   htonc(bootp->PACKET.HLEN,  if_ptr->DEV_ADDRLEN);
   htonc(bootp->PACKET.HOPS,  0);
   htonl(bootp->PACKET.XID,   bootp->XID);
   htons(bootp->PACKET.FLAGS, 0x8000);
   htonl(bootp->PACKET.CIADDR, INADDR_ANY);
   htonl(bootp->PACKET.YIADDR, INADDR_ANY);
   htonl(bootp->PACKET.SIADDR, INADDR_ANY);
   htonl(bootp->PACKET.GIADDR, INADDR_ANY);

   _mem_zero(bootp->PACKET.CHADDR, sizeof(bootp->PACKET.CHADDR));
   _mem_copy(if_ptr->DEV_ADDR, bootp->PACKET.CHADDR, if_ptr->DEV_ADDRLEN);

   /* Start the retransmission timer to start sending immediately */
   bootp->RESEND.TIME    = 0;
   bootp->RESEND.EVENT   = BOOTP_send;
   bootp->RESEND.PRIVATE = if_ptr;
   TCPIP_Event_add(&bootp->RESEND);

   if_ptr->BOOT = (pointer)parms;

} /* Endbody */
Exemple #6
0
boolean BOOTP_send
   (
      TCPIP_EVENT_PTR   event
         /* [IN/OUT] the resend event */
   )
{ /* Body */
   IP_IF_PTR               if_ptr = (IP_IF_PTR)event->PRIVATE;
   TCPIP_PARM_BOOTP _PTR_  parms = (TCPIP_PARM_BOOTP _PTR_)if_ptr->BOOT;
   BOOTP_CFG_PTR           bootp = (BOOTP_CFG_PTR) &parms->config;
   RTCSPCB_PTR             pcb_ptr;

   /* Set the event to trigger for the next retransmission (+/- 1 sec) */
   bootp->RESEND.TIME = bootp->TIMEOUT + (RTCS_rand() & 0x7FF) - 0x400;

   /* Allocate a PCB */
   pcb_ptr = RTCSPCB_alloc_send();
   if (pcb_ptr == NULL) {
      return TRUE;
   } /* Endif */

   //RTCSLOG_PCB_ALLOC(pcb_ptr);

   /* The only field that changes in BOOTREQUEST packets is 'secs' */
   htons(bootp->PACKET.SECS, bootp->SECS);
   bootp->SECS += bootp->RESEND.TIME >> 10;     /* approx. divide by 1000 */

   /* Double the timeout */
   bootp->TIMEOUT <<= 1;
   if (bootp->TIMEOUT > BOOTP_TIMEOUT_MAX) {
      bootp->TIMEOUT = BOOTP_TIMEOUT_MAX;
   } /* Endif */

   /* Put the BOOTREQUEST in the PCB */
   RTCSPCB_append_fragment(pcb_ptr, sizeof(BOOTP_HEADER), (uchar_ptr)&bootp->PACKET);
   RTCSPCB_append_fragment(pcb_ptr, sizeof(BOOTP_DATA),   parms->data->SNAME);

   RTCSLOG_PCB_WRITE(pcb_ptr, RTCS_LOGCTRL_PORT(IPPORT_BOOTPC), 0);

   /* Send the datagram */
   BOOT_send(pcb_ptr, if_ptr);

   /* Always retransmit */
   return TRUE;

} /* Endbody */
Exemple #7
0
void TCP_half_open_TCB_close
   (
      TCP_CFG_STRUCT_PTR   tcp_cfg  /* IN/OUT - TCP layer data */
   )
{ /* Body */
   TCB_STRUCT_PTR       tcb;
   uint_32              curr_time;
   uint_32              removed_tcb_count = 0;
   int                  i;

   curr_time = RTCS_time_get();
   /*
   ** Delete all the TCBs older than the default retransmission
   ** timeout (3 seconds).
   */
   for (i = 0; i < tcp_cfg->HALF_OPEN_TCB_COUNT; i++) {
      tcb = tcp_cfg->HALF_OPEN_TCB_LIST[i];
      if ((curr_time - tcb->tcb_spawn_time) > TCP_INITIAL_RTO_DEFAULT) {
         TCP_Send_reset(tcb, tcp_cfg);      /* send reset packet */
         TCP_Close_TCB(tcb, RTCSERR_TCP_CONN_ABORTED, tcp_cfg);
         TCP_Process_release(tcb, tcp_cfg);
         i--;   /* we removed a TCB  and replaced another TCB
                   from the end, so we need to check same spot again */
         removed_tcb_count++;
      } /* Endif */
   } /* Endfor */

   /*
   ** Remove one TCB from the half open list randomly. Remove the TCB
   ** with a reset. If this is not an attack the client will resend the SYN.
   */
   if (!removed_tcb_count && tcp_cfg->HALF_OPEN_TCB_COUNT) {
      i = RTCS_rand() % tcp_cfg->HALF_OPEN_TCB_COUNT;
      tcb = tcp_cfg->HALF_OPEN_TCB_LIST[i];
      TCP_Send_reset(tcb, tcp_cfg);      /* send reset packet */
      TCP_Close_TCB(tcb, RTCSERR_TCP_CONN_ABORTED, tcp_cfg);
      TCP_Process_release(tcb, tcp_cfg);
   } /* Endif */
} /* Endbody */
Exemple #8
0
static void CHAP_timeout
   (
      pointer        chap_data,
            /* [IN/OUT] - CHAP state */
      PCB_PTR        pcb,
            /* [IN] - expired packet */
      boolean        hard
            /* [IN] - TRUE if this is a hard timeout (TO- event) */
   )
{ /* Body */
   CHAP_DATA_PTR  chap_ptr = chap_data;
   uint_16 i;

   /* Increment the identifier */
   chap_ptr->CURID = (chap_ptr->CURID + 1) & 0xFF;
   pcb->FRAG[0].FRAGMENT[3] = chap_ptr->CURID;

   /* Generate a new challenge */
   for (i=0; i<CHAP_CHALLENGE_LEN; i++) {
      pcb->FRAG[0].FRAGMENT[i+7]= chap_ptr->MD5[i] = RTCS_rand() & 0xFF;
   } /* Endfor */

} /* Endbody */
Exemple #9
0
uint32_t PPPFSM_init
   (
      PPPFSM_CFG_PTR    fsm,
            /* [IN/OUT] - State Machine */
      _ppp_handle       handle,
            /* [IN] - the PPP state structure */
      PPPFSM_CALL_PTR   call_ptr,
            /* [IN] - Protocol-specific call table */
      void             *param
            /* [IN] - Parameter for protocol-specific calls */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4


   PPP_memzero(fsm, sizeof(PPPFSM_CFG));
   fsm->HANDLE  = handle;
   fsm->CALL    = call_ptr;
   fsm->PRIVATE = param;
   fsm->STATE   = PPP_STATE_INITIAL;
   fsm->CURID   = RTCS_rand() & 0xFF;

   /* Initialize the mutex */
   if (PPP_mutex_init(&fsm->MUTEX)) {
      return RTCSERR_PPP_INIT_MUTEX_FAILED;
   } /* Endif */

   return PPP_OK;
   
#else   

    return RTCSERR_IP_IS_DISABLED;

#endif /* RTCSCFG_ENABLE_IP4  */

} /* Endbody */