arp.c
来自「ADS下的bios工程」· C语言 代码 · 共 147 行
C
147 行
#include <bios/types.h>#include <bios/netdev.h>#include <bios/string.h>#include <bios/time.h>#undef DEBUG_S3C4_ARP#ifdef DEBUG_S3C4_ARP #define DEBUG_ARP(fmt, args...) printf("%s-%s()[%d]: " fmt, __FILE__, __FUNCTION__, __LINE__, args)#else #define DEBUG_ARP(fmt, args...)#endifstatic u32 cached_ip;static u8 cached_hw[8];int arp_send(struct netdev *nd, u32 ip_addr);int arp_lookup(struct netdev *nd, u32 addr, u8 *eth_addr);int arp_reply(struct netdev *nd, u32 ip_addr);int arp_send(struct netdev *nd, u32 ip_addr){ static struct arphdr ar; static struct buflist bl, *blp; { int k=10000; while(k--); } bl.data = &ar; bl.size = sizeof(ar); bl.next = NULL; memzero(&ar, sizeof(ar)); ar.ar_hrd = htons(1); /* ARPHRD_ETHER */ ar.ar_pro = htons(ETH_P_IP); ar.ar_hln = nd->hw_addr_len; ar.ar_pln = sizeof(ip_addr); ar.ar_op = htons(1); /* ARPOP_REQUEST */ memcpy(ar.ar_sha, nd->hw_addr, nd->hw_addr_len); memcpy(ar.ar_sip, &nd->ip_addr, sizeof(nd->ip_addr)); memcpy(ar.ar_tip, &ip_addr, sizeof(ip_addr)); blp = nd->eth_header(nd, nd->hw_broadcast, ETH_P_ARP, &bl); DEBUG_ARP("\n%s","->"); return blp ? nd->eth_send(nd, blp) : -1;}static int arp_reply_valid(struct netdev *nd, u32 ip_addr, struct arphdr *ar){ int valid; valid = ar->ar_hrd == htons(1); /* ARPHRD_ETHER */ valid = valid && ar->ar_pro == htons(ETH_P_IP); valid = valid && ar->ar_hln == nd->hw_addr_len; valid = valid && ar->ar_pln == sizeof(ip_addr); valid = valid && ar->ar_op == htons(2); /* ARPOP_REPLY */ valid = valid && memeq(ar->ar_tha, nd->hw_addr, nd->hw_addr_len); valid = valid && memeq(ar->ar_tip, &nd->ip_addr, sizeof(nd->ip_addr)); valid = valid && memeq(ar->ar_sip, &ip_addr, sizeof(ip_addr)); return valid;}int arp_lookup(struct netdev *nd, u32 addr, u8 *eth_addr){ int retries = 15, timeout = 25; while(addr != cached_ip && retries) { static struct arphdr *ar; static char buffer[1024]; int bytes; int next_try; ar = (struct arphdr *)buffer; DEBUG_ARP("\n%s","->"); arp_send(nd, addr); next_try = centisecs + timeout; timeout = timeout * 2; if (timeout > 500) timeout = 500; do { DEBUG_ARP("\n%s","->"); bytes = nd->eth_recv(nd, ETH_P_ARP, buffer); DEBUG_ARP("BYTES(%d)\n",bytes); if (bytes >= sizeof(*ar) && arp_reply_valid(nd, addr, ar)) break; bytes = 0; } while (centisecs < next_try); retries -= 1; if (!bytes) continue; cached_ip = addr; memcpy(cached_hw, ar->ar_sha, ar->ar_hln); } if (addr == cached_ip) { memcpy(eth_addr, cached_hw, nd->hw_addr_len); DEBUG_ARP("CACHED_HW(%x)\n",cached_hw); return 0; } return 1;}int arp_reply(struct netdev *nd, u32 ip_addr){ static struct arphdr ar; static struct buflist bl, *blp; bl.data = &ar; bl.size = sizeof(ar); bl.next = NULL; memzero(&ar, sizeof(ar)); ar.ar_hrd = htons(1); /* ARPHRD_ETHER */ ar.ar_pro = htons(ETH_P_IP); ar.ar_hln = nd->hw_addr_len; ar.ar_pln = sizeof(ip_addr); ar.ar_op = htons(2); /* ARPOP_REQUEST */ memcpy(ar.ar_sha, nd->hw_addr, nd->hw_addr_len); memcpy(ar.ar_tha, nd->tha_addr, nd->hw_addr_len); memcpy(ar.ar_sip, &nd->ip_addr, sizeof(nd->ip_addr)); memcpy(ar.ar_tip, &ip_addr, sizeof(ip_addr)); blp = nd->eth_header(nd, nd->tha_addr, ETH_P_ARP, &bl); DEBUG_ARP("\n%s","->"); return blp ? nd->eth_send(nd, blp) : -1;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?