void RIP_service( RTCSPCB_PTR pcb, /* [IN/OUT] incoming packet */ UCB_STRUCT_PTR ucb_ptr /* [IN] target UCB */ ) { /* Body */ RIP_HEADER_PTR hd = (RIP_HEADER_PTR)RTCSPCB_DATA(pcb); /* check the version number */ if (mqx_ntohc(hd->VERSION) != RIP_V1 && mqx_ntohc(hd->VERSION) != RIP_V2) { RTCSLOG_PCB_FREE(pcb, RTCS_OK); RTCSPCB_free(pcb); } /* Endif */ RTCSLOG_PCB_READ(pcb, RTCS_LOGCTRL_PORT(IPPORT_RIP), mqx_ntohc(hd->VERSION)); switch (mqx_ntohc(hd->COMMAND)) { case RIPCMD_REQUEST: RIP_process_inreq(pcb); break; case RIPCMD_RESPONSE: RIP_process_inresp(pcb); break; default: break; } /* Endswitch */ RTCSLOG_PCB_FREE(pcb, RTCS_OK); RTCSPCB_free(pcb); } /* Endbody */
static uint32_t RIP_send_pkt( IP_IF_PTR ipif, /* [IN] the outgoing interface */ _ip_address ipdst, /* [IN] the destination ip */ uint16_t portdst,/* [IN] the destination port */ unsigned char *data, /* [IN] the data to send */ uint32_t len /* [IN] the length of data to send */ ) { /* Body */ RTCSPCB_PTR pcb; RIP_CFG_STRUCT_PTR ripcfg = RTCS_getcfg(RIP); RIP_HEADER_PTR hd = (RIP_HEADER_PTR)data; uint32_t err; _ip_address ipsrc = IP_get_ipif_addr(ipif); if (ipsrc == INADDR_ANY) { _mem_free(data); return RTCS_OK; } /* Endif */ /* Allocate a PCB */ pcb = RTCSPCB_alloc_send(); if (pcb == NULL) { _mem_free(data); return RTCSERR_PCB_ALLOC; } /* Endif */ //RTCSLOG_PCB_ALLOC(pcb); /* add my data in the pcb */ err = RTCSPCB_append_fragment_autofree(pcb, len, data); if (err) { _mem_free(data); RTCSLOG_PCB_FREE(pcb, err); RTCSPCB_free(pcb); return err; } /* Endif */ RTCSLOG_PCB_WRITE(pcb, RTCS_LOGCTRL_PORT(IPPORT_RIP), mqx_ntohc(hd->VERSION)); /* dont advertize in limited broadcast but in ip broadcast */ if (ipdst == INADDR_BROADCAST){ _ip_address netmask; ipdst = IP_get_ipif_addr(ipif); /* Get IP address of interface */ IP_get_netmask(ipif, ipdst, &netmask); /* Get netmask */ ipdst = ipdst | ~netmask; } /* Endif */ /* send it */ /* use a flag to prevent the broadcast/multicast packet from ** looping back to us. */ return UDP_send_internal(ripcfg->UCB, ipsrc, ipdst, portdst, pcb, RTCS_MSG_NOLOOP); } /* Endbody */
void RTCSLOG_enable ( uint32_t logtype /* [IN] the type of log entry to enable */ ) { /* Body */ RTCS_DATA_PTR rtcs = RTCS_get_data(); if (rtcs) { rtcs->RTCS_LOG_CONTROL |= logtype; RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_IFTYPE (IPIFTYPE_ETHERNET) ); RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_IFTYPE (IPIFTYPE_PPP) ); RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_IFTYPE (IPIFTYPE_LOOPBACK) ); RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_ARP (IPIFTYPE_ETHERNET) ); RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_PROTO (IPPROTO_ICMP) ); RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_PROTO (IPPROTO_IGMP) ); RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_PROTO (IPPROTO_IP) ); RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_PROTO (IPPROTO_TCP) ); RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_PROTO (IPPROTO_UDP) ); RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_PROTO (IPPROTO_OSPF) ); RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_PORT (IPPORT_BOOTPC) ); RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_PORT (IPPORT_RIP) ); } } /* 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 BOOTP_service ( RTCSPCB_PTR rtcs_pcb /* [IN] BOOTREPLY packet */ ) { /* Body */ IP_IF_PTR if_ptr = (IP_IF_PTR)rtcs_pcb->IFSRC; TCPIP_PARM_BOOTP _PTR_ parms = (TCPIP_PARM_BOOTP _PTR_)if_ptr->BOOT; BOOTP_CFG_PTR bootp = (BOOTP_CFG_PTR) &parms->config; BOOTP_PACKET_PTR bootreply; IPIF_PARM parms_bind; uint_32 error; uchar_ptr opt; uchar len, optval, optlen; /* Make sure the datagram is large enough */ bootreply = (BOOTP_PACKET_PTR)RTCSPCB_DATA(rtcs_pcb); if (RTCSPCB_SIZE(rtcs_pcb) < sizeof(BOOTP_PACKET)) { RTCSLOG_PCB_FREE(rtcs_pcb, RTCS_OK); RTCSPCB_free(rtcs_pcb); return; } /* Endif */ /* Make sure the XID matches */ if (ntohl(bootreply->HEAD.XID) != bootp->XID) { RTCSLOG_PCB_FREE(rtcs_pcb, RTCS_OK); RTCSPCB_free(rtcs_pcb); return; } /* Endif */ RTCSLOG_PCB_READ(rtcs_pcb, RTCS_LOGCTRL_PORT(IPPORT_BOOTPC), 0); /* OK, assume this reply is for us */ BOOTP_close(if_ptr); /* Get our IP address, and pick the default netmask */ parms_bind.ihandle = if_ptr; parms_bind.address = ntohl(bootreply->HEAD.YIADDR); parms_bind.locmask = 0xFFFFFFFFL; parms_bind.netmask = IN_DEFAULT_NET(parms_bind.address); parms_bind.probe = FALSE; parms->data->SADDR = ntohl(bootreply->HEAD.SIADDR); #if RTCSCFG_BOOTP_RETURN_YIADDR parms->data->CLIENTADDR = ntohl(bootreply->HEAD.YIADDR); #endif _mem_copy(bootreply->DATA.SNAME, parms->data->SNAME, sizeof(BOOTP_DATA)); RTCSLOG_PCB_FREE(rtcs_pcb, RTCS_OK); RTCSPCB_free(rtcs_pcb); /* Parse the vend field for recognized options */ opt = parms->data->OPTIONS; len = sizeof(parms->data->OPTIONS); if (ntohl(opt) == BOOTP_MAGIC) { opt += 4; len -= 4; #define BOOTP_NEXTOPT opt += optlen; \ break while (len) { /* Get the next option code */ optval = ntohc(opt); opt++; len--; /* Interpret the pad and end options */ if (optval == BOOTPOPT_END) break; if (optval == BOOTPOPT_PAD) continue; /* All other codes have a length byte */ if (len == 0) break; optlen = ntohc(opt); opt++; len--; if (len < optlen) break; len -= optlen; switch (optval) { case BOOTPOPT_MASK: if (optlen != 4) {BOOTP_NEXTOPT;} parms_bind.netmask = ntohl(opt); opt += 4; break; default: BOOTP_NEXTOPT; } /* Endswitch */ } /* Endwhile */ } /* Endif */ /* Bind the received IP address to this interface */ error = RTCSCMD_internal(parms_bind, IPIF_bind); /* Done -- unblock the application */ RTCSCMD_complete(parms, error); } /* Endbody */