📄 arp.c
字号:
if (memcmp(&ip_addr, SenderPA(arp), IP_ALEN)) add_entry(ni, arp); } /*-------------------------------------------------------------------*/ /* Else if entry was pending, mark resolved and send queued packets. */ /*-------------------------------------------------------------------*/ else if (arp_entry->state == AES_PENDING) { arp_entry->state = AES_RESOLVED; for (; arp_entry->qhead; arp_entry->qhead = arp_entry->qhead->next) arp_entry->ni->transmit(arp_entry->qhead, arp_entry->hw_addr); arp_entry->qcount = 0; } /*-------------------------------------------------------------------*/ /* Reply if packet is ARP request and interface address is valid. */ /*-------------------------------------------------------------------*/ if (ni->ip_addr && (arp->operation == htons(ARP_REQUEST))) arp_reply(ni, SenderHA(arp), SenderPA(arp), UNICAST);}/***********************************************************************//* DhcpArpReq: Broadcast ARP request to see if address is being used *//* *//* Inputs: ni = pointer to network interface *//* ip_addr = address to check for use by other hosts *//* *//***********************************************************************/void DhcpArpReq(Ni *ni, ui32 ip_addr){ ArpEntry arp_entry; /*-------------------------------------------------------------------*/ /* Initialize ARP entry and send request. */ /*-------------------------------------------------------------------*/ arp_entry.ni = ni; arp_entry.pr_addr = ip_addr; arp_entry.state = AES_FREE; arp_entry.qhead = NULL; arp_entry.qcount = 0; arp_entry.timer.running = FALSE; arp_entry.timer.action = arp_timeout; arp_entry.timer.object = &arp_entry; INIT_TMR(arp_entry.timer); send_request(&arp_entry); /*-------------------------------------------------------------------*/ /* Stop ARP timer before exiting since it was created on the stack. */ /*-------------------------------------------------------------------*/ NetTimerStop(&arp_entry.timer);}/***********************************************************************//* DhcpArpCached: Check if specified IP address is in ARP cache *//* *//* Input: ip_addr = IP address to search for *//* *//***********************************************************************/int DhcpArpCached(ui32 ip_addr){ return find_entry(ip_addr) != NULL;}/***********************************************************************//* DhcpArpReply: Broadcast ARP reply to clear outdated entries *//* *//* Input: ni = pointer to network interface *//* *//***********************************************************************/void DhcpArpReply(Ni *ni){ arp_reply(ni, ni->hw_addr, (ui8 *)&ni->ip_addr, BROADCAST);}/***********************************************************************//* RarpIn: Handle incoming RARP packets, replies and requests *//* *//***********************************************************************/void RarpIn(void){ Arp *rarp; Ni *ni = RxBuf->ni; ui8 *aligned; /*-------------------------------------------------------------------*/ /* Align RARP packet to even byte boundary and assign pointer. */ /*-------------------------------------------------------------------*/ aligned = (ui8 *)((ui32)RxBuf->ip_pkt & ~1); if (aligned != RxBuf->ip_pkt) { memmove(aligned, RxBuf->ip_pkt, RxBuf->length); RxBuf->ip_pkt = aligned; } rarp = (Arp *)RxBuf->ip_pkt;#if TCP_PROBE /*-------------------------------------------------------------------*/ /* Decode RARP packet if global decode flag is TRUE. */ /*-------------------------------------------------------------------*/ if (NetProbeFlag) got_arp(rarp);#endif /*-------------------------------------------------------------------*/ /* Verify hardware and protocol type. */ /*-------------------------------------------------------------------*/ if (ntohs(rarp->hw_type) != ni->hw_type || rarp->pr_type != htons(IP_TYPE)) return; /*-------------------------------------------------------------------*/ /* Attempt response if packet is RARP request. */ /*-------------------------------------------------------------------*/ if (rarp->operation == htons(RARP_REQUEST)) {#if RARP_SERVER NetBuf *buf; Arp *reply; ui32 ip_addr; HostDesc *host; /*-----------------------------------------------------------------*/ /* Use hardware address to look up protocol address. */ /*-----------------------------------------------------------------*/ for (host = &HostsTable[0];; ++host) { /*---------------------------------------------------------------*/ /* Return if end of list reached. */ /*---------------------------------------------------------------*/ if (host->ip_addr == 0) return; /*---------------------------------------------------------------*/ /* Break if hardware address match is found. */ /*---------------------------------------------------------------*/ if ((host->hw_type == ni->ha_type) && host->hw_addr && (memcmp(SenderHA(rarp), host->hw_addr, ni->ha_len) == 0)) { ip_addr = host->ip_addr; break; } } /*-----------------------------------------------------------------*/ /* Request a network buffer, exiting if none free. */ /*-----------------------------------------------------------------*/ buf = tcpGetBuf(NIMHLEN + offsetof(Arp, addresses) + 2 * (IP_ALEN + ni->ha_len)); if (buf == NULL) return; /*-----------------------------------------------------------------*/ /* Form RARP header. */ /*-----------------------------------------------------------------*/ reply = (Arp *)buf->ip_pkt; reply->hw_type = htons(ni->hw_type); reply->pr_type = htons(IP_TYPE); reply->ha_len = ni->ha_len; reply->pa_len = IP_ALEN; reply->operation = htons(RARP_REPLY); /*-----------------------------------------------------------------*/ /* Supply target addresses. */ /*-----------------------------------------------------------------*/ memcpy(TargetHA(reply), SenderHA(rarp), ni->ha_len); memcpy(TargetPA(reply), &ip_addr, IP_ALEN); /*-----------------------------------------------------------------*/ /* Fill in sender's hardware and protocol addresses (ours). */ /*-----------------------------------------------------------------*/ memcpy(SenderHA(reply), ni->hw_addr, ni->ha_len); memcpy(SenderPA(reply), &ni->ip_addr, IP_ALEN);#if TCP_PROBE /*-----------------------------------------------------------------*/ /* Decode RARP packet if global decode flag is TRUE. */ /*-----------------------------------------------------------------*/ if (NetProbeFlag) got_arp(reply);#endif /*-----------------------------------------------------------------*/ /* Supply buffer header and request NI to send packet. */ /*-----------------------------------------------------------------*/ buf->length = offsetof(Arp, addresses) + 2 * (IP_ALEN + ni->ha_len); buf->type = htons(RARP_TYPE); ni->transmit(buf, SenderHA(rarp));#endif /* RARP_SERVER */ } /*-------------------------------------------------------------------*/ /* Else process RARP reply. */ /*-------------------------------------------------------------------*/ else { ui32 server; ArpEntry *arp_entry; /*-----------------------------------------------------------------*/ /* Use this packet to update ARP cache. */ /*-----------------------------------------------------------------*/ memcpy(&server, SenderPA(rarp), IP_ALEN); arp_entry = find_entry(server); if (arp_entry) { memcpy(arp_entry->hw_addr, SenderHA(rarp), rarp->ha_len); NetTimerStart(&arp_entry->timer, ARP_TIMEOUT); } else add_entry(ni, rarp); /*-----------------------------------------------------------------*/ /* Return if interface is not waiting for a RARP reply. */ /*-----------------------------------------------------------------*/ if (ni->ip_addr || ((ni->flags & NIF_USE_RARP) == FALSE)) return; /*-----------------------------------------------------------------*/ /* Return if this packet is not directed at us. */ /*-----------------------------------------------------------------*/ if (memcmp(ni->hw_addr, TargetHA(rarp), rarp->ha_len)) return; /*-----------------------------------------------------------------*/ /* Were waiting for this reply. Stop RARP retry timer. */ /*-----------------------------------------------------------------*/ NetTimerStop(&RarpTimer); /*-----------------------------------------------------------------*/ /* Assign IP address and mask, and add this network interface. */ /*-----------------------------------------------------------------*/ memcpy(&ni->ip_addr, TargetPA(rarp), IP_ALEN); ni->ip_mask = IpNetMask(ni->ip_addr); NiRtAdd(ni); /*-----------------------------------------------------------------*/ /* If requested, add RARP server as default gateway. */ /*-----------------------------------------------------------------*/ if (ni->flags & NIF_DEF_GW) RtAdd(server, 0, INADDR_ANY, ni, RT_GATEWAY); }}/***********************************************************************//* RarpAdd: Start IP address resolution using RARP client *//* *//* Input: ni = pointer to network interface *//* *//***********************************************************************/int RarpAdd(Ni *ni){ /*-------------------------------------------------------------------*/ /* Return error if RARP timer is in use. */ /*-------------------------------------------------------------------*/ if (RarpTimer.running) return -1; /*-------------------------------------------------------------------*/ /* Clear NI's IP address field and save NI pointer. */ /*-------------------------------------------------------------------*/ ni->ip_addr = 0; RarpTimer.object = ni; /*-------------------------------------------------------------------*/ /* Initialize retry count and schedule first RARP request. */ /*-------------------------------------------------------------------*/ RarpRetries = 0; NetTimerStart(&RarpTimer, rand() % K2_SECONDS); return 0;}/***********************************************************************//* NetQueryArp: Display contents of ARP cache *//* *//***********************************************************************/void NetQueryArp(void){ int n, i = 0; ArpEntry *entry = Entry; /*-------------------------------------------------------------------*/ /* Print ARP table heading. */ /*-------------------------------------------------------------------*/ printf("IP Address MAC Address\n" "========== ===========\n"); /*-------------------------------------------------------------------*/ /* Search through ARP table, checking each entry. */ /*-------------------------------------------------------------------*/ do { /*-----------------------------------------------------------------*/ /* If entry is valid, print IP address and MAC address. */ /*-----------------------------------------------------------------*/ if (entry->state != AES_FREE) { n = printIP(entry->pr_addr); while (++n < 18) putchar(' '); printEth(entry->hw_addr); putchar('\n'); } /*-----------------------------------------------------------------*/ /* Increment entry pointer, wrapping when end is reached. */ /*-----------------------------------------------------------------*/ if (++entry == &ArpTbl[ARP_TSIZE]) entry = &ArpTbl[0]; } while (++i < ARP_TSIZE);}/***********************************************************************//* Local Function Definitions *//***********************************************************************//***********************************************************************//* rarp_timeout: Process RARP request timeout *//* *//* Input: object = pointer to network interface *//* *//***********************************************************************/static void rarp_timeout(void *object){ int timeout; Ni *ni = object; uint length = offsetof(Arp, addresses) + 2 * (IP_ALEN + ni->ha_len); NetBuf *buf; Arp *rarp; /*-------------------------------------------------------------------*/ /* Broadcast RARP request if able to allocate transmit buffer. */ /*-------------------------------------------------------------------*/ buf = tcpGetBuf(NIMHLEN + length); if (buf) { /*-----------------------------------------------------------------*/ /* Get pointer to packet frame and complete RARP message fields. */ /*-----------------------------------------------------------------*/ rarp = (Arp *)buf->ip_pkt; rarp->hw_type = htons(ni->hw_type); rarp->pr_type = htons(IP_TYPE); rarp->ha_len = ni->ha_len; rarp->pa_len = IP_ALEN; rarp->operation = htons(RARP_REQUEST); memcpy(SenderHA(rarp), ni->hw_addr, ni->ha_len); memset(SenderPA(rarp), 0, IP_ALEN); memcpy(TargetHA(rarp), ni->hw_addr, ni->ha_len); memset(TargetPA(rarp), 0, IP_ALEN);#if TCP_PROBE /*-----------------------------------------------------------------*/ /* Decode RARP packet if global decode flag is TRUE. */ /*-----------------------------------------------------------------*/ if (NetProbeFlag) got_arp(rarp);#endif /*-----------------------------------------------------------------*/ /* Complete buffer data and request NI to transmit packet. */ /*-----------------------------------------------------------------*/ buf->length = length;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -