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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */