新闻中心

EEPW首页>嵌入式系统>设计应用> 单片机驱动DM9000网卡芯片

单片机驱动DM9000网卡芯片

作者: 时间:2016-11-24 来源:网络 收藏


2、ARP的处理程序

ARP协议原理很简单,下面我们来编写ARP协议的处理函数。新建文件命名为arp.c,填写如下函数

unsigned char mac_addr[6] = {*,*,*,*,*,*};

unsigned char ip_addr[4] = { 192, 168, *, * };

unsigned char host_ip_addr[4] = { 192, 168, *, * };

unsigned char host_mac_addr[6]={ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

unsigned char Buffer[1000];

uint16 packet_len;

#define HON(n) ((((uint16)((n) & 0xff)) << 8) | (((n) & 0xff00) >> 8))

void arp_request(void) //发送ARP请求数据包

{

//以太网首部

memcpy(ARPBUF->ethhdr.d_mac, host_mac_addr, 6);

memcpy(ARPBUF->ethhdr.s_mac, mac_addr, 6);

ARPBUF->ethhdr.type = HON( 0x0806 );

//ARP首部

ARPBUF->hwtype = HON( 1 );

ARPBUF->protocol = HON( 0x0800 );

ARPBUF->hwlen = 6;

ARPBUF->protolen = 4;

ARPBUF->opcode = HON( 0 );

memcpy(ARPBUF->smac, mac_addr, 6);

memcpy(ARPBUF->sipaddr, ip_addr, 4);

memcpy(ARPBUF->dipaddr, host_ip_addr, 4);

packet_len = 42;//14+28=42

sendpacket( Buffer, packet_len );

}

注释:ARPBUF的宏定义和ARP首部结构,在前面已经讲过。同时注意执行该函数时中断的处理。这里没

作处理。

看上去很easy吧,下面函数实现接收ARP请求或接收ARP应答的处理。

unsigned char arp_process(void)//ARP接收函数,成功返回1,否则返回0

{

//简单判断ARP数据包有无损坏,有损坏则丢弃,不予处理

if( packet_len < 28 )//ARP数据长度为28字节为无效数据

{

return 0;

}

switch ( HON( ARPBUF->opcode ) )

{

case 0: //处理ARP请求

if( ARPBUF->dipaddr[0] == ip_addr[0] &&

ARPBUF->dipaddr[1] == ip_addr[1] &&

ARPBUF->dipaddr[2] == ip_addr[2] &&

ARPBUF->dipaddr[3] == ip_addr[3] )//判断是否是自己的IP,是否向自己询问MAC地址

{
ARPBUF->opcode = HON( 2 );//设置为ARP应答

memcpy(ARPBUF->dmac, ARPBUF->smac, 6);

memcpy(ARPBUF->ethhdr.d_mac, ARPBUF->smac, 6);

memcpy(ARPBUF->smac, mac_addr, 6);

memcpy(ARPBUF->ethhdr.s_mac, mac_addr, 6);

memcpy(ARPBUF->dipaddr, ARPBUF->sipaddr, 4);

memcpy(ARPBUF->sipaddr, ip_addr, 4);

ARPBUF->ethhdr.type = HON( 0x0806 );

packet_len = 42;

sendpacket( Buffer, packet_len );//发送ARP数据包

return 1;

}

else

{

return 0;

}

break;

case 1: //处理ARP应答

if( ARPBUF->dipaddr[0] == ip_addr[0] &&

ARPBUF->dipaddr[1] == ip_addr[1] &&

ARPBUF->dipaddr[2] == ip_addr[2] &&

ARPBUF->dipaddr[3] == ip_addr[3] )//再次判断IP,是否是给自己的应答

{

memcpy(host_mac_addr, ARPBUF->smac, 6);//保存服务器MAC地址

return 1;

}

else

{

return 0;

}

break;

default://不是ARP协议

return 0;

}

}

根据ARP协议格式看这两个函数并不困难。于是我们又得到两个函数:arp_request()和

arp_process()。

3、ARP程序调试

下面我们修改主函数和中断处理函数。

将mian()函数中的“sendpacket(60);”语句换成“arp_request();”语句。

void int_issue(void) //中断处理函数,需要根据自己的处理器进行设置

{

unsigned int i;

i = receivepacket(Buffer);//将数据读取到Buffer中。

if(i == 0)

{

return;

}

else

{

i = arp_process();

if(i == 1)//判断是否是ARP协议

print_hostmacaddr();//打印目标机的MAC地址,就是用串口打印host_mac_addr[]中的6

个字节

}

}

保存运行调试。

图7 主机MAC地址

至此,关于DM9000的调试过程就完成了。之后我还调试了UDP通讯、TCP通讯等,主要是关于协议的

处理了,这里就不介绍了。有兴趣的朋友可以参看《TCP/IP协议》第一卷,将会有很大帮助。希望这些

调试过程能为读者或多或少的提供些有用的信息,也欢迎大家和我一起讨论


上一页 1 2 下一页

评论


技术专区

关闭