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 + -
显示快捷键?