static void RIP_adopt_rt( RTCSPCB_PTR pcb, /* [IN] incoming packet */ IP_ROUTE_INDIRECT_PTR gate, RIP_ENTRY_PTR rte, uint32_t metric, _ip_address *network_ptr, _ip_address *netmask_ptr ) { /* Body */ RIP_HEADER_PTR hd = (RIP_HEADER_PTR)RTCSPCB_DATA(pcb); uint16_t rip_vers = mqx_ntohc(hd->VERSION); _ip_address ipsrc = IP_source(pcb); /* init the common part */ *network_ptr = mqx_ntohl(rte->NETADDR); gate->GATEWAY = ipsrc; if (rip_vers == RIP_V2){ _ip_address nexthop = mqx_ntohl(rte->NEXTHOP); *netmask_ptr = mqx_ntohl(rte->NETMASK); /* incoming nexthop. rfc2453.4.4 */ if (nexthop && IP_is_direct(pcb->IFSRC, nexthop)) gate->GATEWAY = nexthop; }else{ *netmask_ptr = IN_DEFAULT_NET(*network_ptr); } /* if the metric is >= than the RIP_MAX_METRIC, the ourte is down */ if (metric < RIP_MAX_METRIC) { gate->FLAGS |= RTF_UP; } else { gate->FLAGS &= ~RTF_UP; } /* Endif */ /* init the RIP part */ gate->RIP.METRIC = metric; gate->RIP.RT_TAG = mqx_ntohs(rte->RT_TAG); gate->RIP.CHANGED_F = TRUE; gate->RIP.IPIFSRC = pcb->IFSRC; RIP_init_timer(gate, gate->RIP.METRIC); } /* Endbody */
static void RIP_process_inresp( RTCSPCB_PTR pcb /* [IN/OUT] incoming packet */ ) { /* Body */ RIP_CFG_STRUCT_PTR ripcfg = RTCS_getcfg(RIP); unsigned char *pkt = RTCSPCB_DATA(pcb); RIP_HEADER_PTR hd = (RIP_HEADER_PTR)RTCSPCB_DATA(pcb); RIP_ENTRY_PTR rte = (RIP_ENTRY_PTR)(pkt + sizeof(RIP_HEADER)); uint32_t pktlen = RTCSPCB_SIZE(pcb); uint16_t rip_vers = mqx_ntohc(hd->VERSION); IP_ROUTE_INDIRECT_PTR gate; _ip_address netaddr, netmask; if (pktlen < sizeof(RIP_HEADER)) { return; } /* Endif */ pktlen -= sizeof(RIP_HEADER); if (RIP_is_valid_resp(pcb) == FALSE){ return; } /* Endif */ for (; pktlen >= sizeof(RIP_ENTRY); pktlen -= sizeof(RIP_ENTRY), rte++){ if (!RIP_is_valid_rte(rte)) continue; netaddr = mqx_ntohl(rte->NETADDR); if (rip_vers == RIP_V2) netmask = mqx_ntohl(rte->NETMASK); else netmask = IN_DEFAULT_NET(netaddr); gate = ROUTE_get(netaddr, netmask); if (!gate) RIP_create_rt(pcb, rte, rip_vers); else RIP_update_rt(gate, pcb, rte); } /* if this incoming response has changed routes, do a triggered update*/ if (ripcfg->RT_CHANGED_F) RIP_trig_upd(); } /* 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 */