⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arp.c

📁 ARM2410+DM9000的驱动与寄存器配置代码
💻 C
字号:
#include <string.h>
#include "arp.h"
#include "eth.h"
//SA:源地址,48位,表明该帧的数据是哪个网卡发的,即发送端的网卡地址,同样是6个字节.
/*DA:目的地址,以太网的地址为48位(6个字节)二进制地址,表明该帧传输给哪个网卡.
如果为FFFFFFFFFFFF,则是广播地址,广播地址的数据可以被任何网卡接收到.*/
/*TYPE:类型字段,表明该帧的数据是什么类型的数据,不同的协议的类型字段不同。如:0800H 表示数据为IP包,
0806H 表示数据为ARP包,814CH是SNMP包,8137H为IPX/SPX包,(小于0600H的值是用于IEEE802的,表示数据包的长度。)*/
/*
__packed struct eth_hdr {
  struct eth_addr dest;//6 bytes  目的地址
  struct eth_addr src; //6 bytes  源地址
  u16_t type;          //2 bytes  类型 指定接收数据的高层协议
  //data               //46 - 1500bytes  数据字段的内容
};
*/
/*__packed struct eth_addr {
  u8_t addr[6];
};*/

__packed struct arp_hdr {
  struct eth_hdr ethhdr;
  u16_t hwtype;            //Hardware type  16
  u16_t protocol;          //Protocol type  16
  u8_t hwlen;              //Hardware address length 8
  u8_t protolen;           //Protocol address length 8
  u16_t opcode;            //Opcode  16
  struct eth_addr shwaddr; //Source hardware address 32
  u32_t sipaddr;           //Source protocol address 32
  struct eth_addr dhwaddr; //Destination hardware address 32
  u32_t dipaddr;           //Destination protocol address 32
};
//   entry  记载条目
struct arp_entry {
  u32_t ipaddr;
  struct eth_addr ethaddr;
  u8_t time;
};
//arp高速缓存,存放最近的IP地址到arp地址之间的映射
static struct arp_entry arp_table[ARPTAB_SIZE];
static u8_t arp_time;
//初始化ARP环境
void arp_init(void)
{
	memset(arp_table, 0, sizeof(arp_table));
	arp_time = 0;
}
//输入ARP包,成功返回0,否则返回-1
u32_t arp_in(u8_t *ethbuf, u16_t len)
{
	//u32_t tmp;
	struct arp_hdr *pArp = (struct arp_hdr *)ethbuf;
	if(pArp->ethhdr.type != HTONS(ETHTYPE_ARP))
		return -1;
	switch(pArp->opcode)
	{
	case HTONS(ARP_REQUEST):
		dbglog(("\narp request "));
		dbglog(("dipaddr %u.%u.%u.%u", IPADDR1(pArp->dipaddr),
				IPADDR2(pArp->dipaddr), IPADDR3(pArp->dipaddr), 
				IPADDR4(pArp->dipaddr)));
		if(pArp->dipaddr == getipaddr())
		{
			dbglog((" sipaddr %u.%u.%u.%u", IPADDR1(pArp->sipaddr),
					IPADDR2(pArp->sipaddr), IPADDR3(pArp->sipaddr), 
					IPADDR4(pArp->sipaddr)));
					//#define ARP_REPLY    2
			pArp->opcode = HTONS(ARP_REPLY);
			//
			pArp->dhwaddr = pArp->shwaddr;
			pArp->shwaddr = getethaddr();
			pArp->ethhdr.dest = pArp->dhwaddr;
			pArp->ethhdr.src = pArp->shwaddr;
			//
			//tmp = pArp->dipaddr;
			pArp->dipaddr = pArp->sipaddr;
			pArp->sipaddr = getipaddr();//tmp;
			//
			eth_send(ethbuf, sizeof(struct arp_hdr));
			arp_update(pArp->dipaddr, &pArp->dhwaddr);
			return 0;
		}
		break;
		//#define ARP_REPLY    2
	case HTONS(ARP_REPLY):
		arp_update(pArp->sipaddr, &pArp->shwaddr);
		return 0;
		break;
	}
	return -1;
}


/*目的地址,以太网的地址为48位(6个字节)二进制地址,表明该帧传输给哪个网卡.
如果为FFFFFFFFFFFF,则是广播地址,广播地址的数据可以被任何网卡接收到.*/
//根据IP地址获取MAC地址,成功返回0,否则返回-1
//ARP的功能:实现从IP地址到对应物理地址的转换
//IP:4*8=32       ARP:6*8=48   //传入u32_t小端的IP地址
u32_t arp_getethaddr(u32_t ipaddr, struct eth_addr *ethaddr)
{
	u32_t i;
	/*
	//   entry  记载条目
struct arp_entry {
  u32_t ipaddr;
  struct eth_addr ethaddr;
  u8_t time;
};
//arp高速缓存,存放最近的IP地址到arp地址之间的映射
static struct arp_entry arp_table[ARPTAB_SIZE];
	*/
	for(i=0; i<ARPTAB_SIZE; i++)
	{
		if(arp_table[i].ipaddr == ipaddr)
		{
			*ethaddr = arp_table[i].ethaddr;
			return 0;
		}
	}
	/*__packed struct eth_hdr {
  struct eth_addr dest;//6 bytes  目的地址
  struct eth_addr src; //6 bytes  源地址
  u16_t type;          //2 bytes  类型 指定接收数据的高层协议
  //data               //46 - 1500bytes  数据字段的内容
};
	*/
	/*
	__packed struct arp_hdr {
  struct eth_hdr ethhdr;
  u16_t hwtype;            //Hardware type  16
  u16_t protocol;          //Protocol type  16
  u8_t hwlen;              //Hardware address length 8
  u8_t protolen;           //Protocol address length 8
  u16_t opcode;            //Opcode  16
  struct eth_addr shwaddr; //Source hardware address 32
  u32_t sipaddr;           //Source protocol address 32
  struct eth_addr dhwaddr; //Destination hardware address 32
  u32_t dipaddr;           //Destination protocol address 32
};
	*/
	{
		struct arp_hdr arp;
		const static struct eth_addr eth_broadcast_addr = {0xff,0xff,0xff,0xff,0xff,0xff};
		const static struct eth_addr eth_zero_addr = {0x00,0x00,0x00,0x00,0x00,0x00};

		arp.ethhdr.dest = eth_broadcast_addr;
		arp.ethhdr.src = getethaddr();
		//#define ETHTYPE_ARP 0x0806
		arp.ethhdr.type = HTONS(ETHTYPE_ARP);
		arp.hwtype = HTONS(0x0001);
		arp.protocol = HTONS(0x0800);
		arp.hwlen = 6;
		arp.protolen = 4;
		//#define ARP_REQUEST  1
		arp.opcode = HTONS(ARP_REQUEST);
		arp.shwaddr = getethaddr();
		arp.sipaddr = getipaddr();
		arp.dhwaddr = eth_zero_addr;
		arp.dipaddr = ipaddr;
		eth_send((u8_t*)&arp, sizeof(struct arp_hdr));
	}
	return -1;
}

//更新ARP Table ,成功返回0,否则返回-1。
u32_t arp_update(u32_t ipaddr, struct eth_addr *ethaddr)
{
	u32_t i;
	struct arp_entry *ptr = NULL;
	for(i=0; i<ARPTAB_SIZE; i++)
	{
		if((ptr == NULL && arp_table[i].ipaddr == 0) ||
			arp_table[i].ipaddr == ipaddr)
		{
			ptr = &arp_table[i];
		}
	}

	if(ptr != NULL)
	{
		ptr->ipaddr = ipaddr;
		ptr->ethaddr = *ethaddr;
		ptr->time = arp_time;
		return 0;
	}

	return -1;
}

//刷新ARP时间
void arp_timer(void)
{
	u32_t i;

	arp_time++;
	for(i=0; i<ARPTAB_SIZE; i++)
	{
		if(arp_table[i].ipaddr != 0 && 
			(arp_time - arp_table[i].time) > ARP_MAXAGE)
		{
			memset(&arp_table[i], 0, sizeof(struct arp_entry));
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -