1 ARP协议简介

ARP协议是Address Resolution Protocol(地址解析协议)的缩写。所谓的“地址解析”就是主机在发送帧前将目标IP地址转换为目标MAC地址的过程。

ARP协议的基本功能就是通过目标设备的IP地址(32位),查询目标设备的MAC地址(48位),以保证通信的顺利进行。

2 ARP协议的数据结构

typedef struct _arp_hdr      //以太网头部 + ARP首部结构
{
ETH_HDR  ethhdr;//以太网首部
U16  hwtype;//硬件类型(1表示传输的是以太网MAC地址)
U16  protocol;//协议类型(0x800表示传输的IP地址)
U8   hwlen;//硬件地址长度(6)
U8   protolen;//协议地址长度(4)
U16  opcode;//操作(1表示ARP请求,2表示ARP应答)
U8   s_mac[6];//发送者MAC地址
U8   s_ipaddr[4];//发送者IP地址
U8   d_mac[6];//目的端MAC地址
U8   d_ipaddr[4];//目的端IP地址
}ARP_HDR;

3 发送ARP请求数据包

3.1 发送ARP数据包的过程

(1)为ARP协议的数据包的相关值进行赋值。

(2)设置发送的数据包的长度

(3)发送数据包

3.2 发送ARP数据包的函数

void arp_request(void)   //发送ARP请求数据包
{
///经验发现:每次发射前,需要进行一定的初始化
//3.2 软件复位
DM9000_Write(NCR,0x03); //软件复位,MAC内部循环反馈(?)
uDelay(3000);           //延时10us以上,等待软件复位完成
DM9000_Write(NCR,0x00); //复位完成,设置正常工作模式
DM9000_Write(NCR,0x03); //第二次软件复位。确保软件复位完全成功
uDelay(3000);
DM9000_Write(NCR,0x00);
//3.3 使能中断
DM9000_Write(IMR,0x80);//使能指向SRAM的指针的自动返回功能
//3.4 清除原网络和中断状态
DM9000_Write(NSR,0x2c); //清除各种状态标志位
DM9000_Write(ISR,0xbf); //清除所有中断标志位,8-bit
//3.5 对发射和接收进行新的控制
//    对中断进行新的控制
DM9000_Write(RXCR,0x39);//接收控制
DM9000_Write(TXCR,0x00);//发送控制
DM9000_Write(BPTR,0x3f);//设置RX的最低阀值,小于将产生拥塞
DM9000_Write(FCTR,0x00);//接收FIFO门限3K,8K
DM9000_Write(FCR,0xff);//启动一些控制功能
DM9000_Write(SMCR,0x00);//未启动特殊模?
///
ARPBUF = (ARP_HDR*)&Buffer;    //ARPBUF指向Buffer
//为ARPBUF赋值
memcpy(ARPBUF->ethhdr.d_mac,host_mac_addr,6);
memcpy(ARPBUF->ethhdr.s_mac,mac_addr,6);
ARPBUF->ethhdr.type = HON(0x0806);
ARPBUF->hwtype = HON(1);
ARPBUF->protocol = HON(0x0800);
ARPBUF->hwlen = 6;
ARPBUF->protolen =4;
ARPBUF->opcode = HON(1);
memcpy(ARPBUF->s_mac, mac_addr,6);
memcpy(ARPBUF->s_ipaddr, ip_addr,4);
memcpy(ARPBUF->d_mac, host_mac_addr,6);//
memcpy(ARPBUF->d_ipaddr, host_ip_addr,4);
packet_len = 42;//14+28
//将ARP发送出去
DM9000_sendPacket(Buffer, packet_len);
}

4  ARP协议接收处理函数

4.1 ARP协议接收数据包的处理过程

(1)根据 HON(ARPBUF->ethhdr.type)判断所接受的数据包是否符合ARP协议

(2)根据HON(ARPBUF->opcode)判断接收的是请求还是应答。

4.2 ARP协议接收处理函数

U8 arp_process(void) //ARP接收函数,成功返回1,否则返回0
{
ARPBUF = (ARP_HDR*)&RX_Buffer; //ARPBUF指向Buffer
if( HON(ARPBUF->ethhdr.type) != 0x0806)
{
Uart_Printf("非ARP协议包");
return 0;
}
else
{
Uart_Printf("\r\n收到的为ARP协议包\r\n");
}
//简单判断ARP数据包是否有损坏,有损坏则丢弃,不予处理
if(packet_len < 28)  //数据包长度小于28个字节,为无效数据。
{
Uart_Printf("未进入,数据包长度小");
return 0;
}
switch (HON(ARPBUF->opcode) )
{
case 1: //处理ARP请求
if(
//判断是否是自己的IP,是否向自己询问MAC地址
(ARPBUF->d_ipaddr[0] == ip_addr[0]) &&
(ARPBUF->d_ipaddr[1] == ip_addr[1]) &&
(ARPBUF->d_ipaddr[2] == ip_addr[2]) &&
(ARPBUF->d_ipaddr[3] == ip_addr[3])   )
{
ARPBUF->opcode = HON(2);    //设置为ARP应答
memcpy(ARPBUF->ethhdr.d_mac,ARPBUF->ethhdr.s_mac,6);
memcpy(ARPBUF->ethhdr.s_mac,mac_addr,6);
memcpy(ARPBUF->s_mac, mac_addr,6);
memcpy(ARPBUF->s_ipaddr, ip_addr,4);
memcpy(ARPBUF->d_mac, ARPBUF->s_mac,6);//
memcpy(ARPBUF->d_ipaddr, ARPBUF->s_ipaddr,4);
packet_len = 42;
DM9000_sendPacket(RX_Buffer,packet_len);    //发送ARP数据包
Uart_Printf("TQ接收到ARP请求包");
return 1;
}
else
{
return 0;
}
break;
case 2: //处理ARP应答
//Uart_Printf("\r\nARPBUF->d_ipaddr[3]=%d\r\n",ARPBUF->d_ipaddr[3]);
//Uart_Printf("\r\n ip_addr[3]=%d\r\n",ip_addr[3]);
if(//再次判断是否是自己的IP,是否向自己询问MAC地址
(ARPBUF->d_ipaddr[0] == ip_addr[0]) &&
(ARPBUF->d_ipaddr[1] == ip_addr[1]) &&
(ARPBUF->d_ipaddr[2] == ip_addr[2]) &&
(ARPBUF->d_ipaddr[3] == ip_addr[3])
)
{
memcpy(host_mac_addr,ARPBUF->s_mac,6);//保存服务器MAC地址
Uart_Printf("TQ接收到ARP应答包");
return 1;
}
else
{
return 0;
}
break;
default://不是ARP协议
Uart_Printf("进入default");
return 0;
break;
}
}

【学习笔记】DM9000裸机驱动(三)之简单ARP协议的实现相关推荐

  1. Ext.Net学习笔记19:Ext.Net FormPanel 简单用法

    Ext.Net学习笔记19:Ext.Net FormPanel 简单用法 FormPanel是一个常用的控件,Ext.Net中的FormPanel控件同样具有非常丰富的功能,在接下来的笔记中我们将一起 ...

  2. 一、css清除浮动方法学习笔记总结(超详细,简单易懂)

    ** css清除浮动方法学习笔记总结(超详细,简单易懂) ** 问题: 上图中,由于container(父级元素)未设置高度,其内部子元素设置了float浮动,导致与container同级(也就是co ...

  3. Python数据挖掘学习笔记】九.回归模型LinearRegression简单分析氧化物数据

    #2018-03-23 16:26:20 March Friday the 12 week, the 082 day SZ SSMR [Python数据挖掘学习笔记]九.回归模型LinearRegre ...

  4. x%3e=y%3e=z的c语言表达式,我的C语学习笔记-C语言教程(三).doc

    我的C语学习笔记- C语言教程(三) C语言教程---第一章: C语言概论 C语言教程---第二章: 数据类型.运算符.表达式 C语言教程---第三章: C语言程序设计初步 C语言教程---第四章: ...

  5. 【计算机网络学习笔记06】以太网帧结构、HDLC协议

    [计算机网络学习笔记06]以太网帧结构.HDLC协议 一.以太网帧结构 1.1 两种帧格式 1)Ethernet_II帧格式 2)IEEE802.3帧格式 1.2 帧的3种发送方式 1)单播: 帧从单 ...

  6. 简简单单 My SQL 学习笔记(2)——分组和简单数据的查询

    初始数据 创建表(要记得先选择好我们的数据库 use+数据库名) create table student( studentno int(4) primary key not null auto_in ...

  7. 电路学习笔记01——一到三章

    电路学习笔记和总结 第一章 电路模型和电路定律 重难点一 参考方向 1 关联方向时 P = UI 结果大于零,则算得的是吸收功率 结果小于零,则算得的是发出功率 2 非关联方向时 直接当作是关联方向计 ...

  8. 树莓派学习笔记——Linux I2C驱动说明

    1.前言 [linux内核说明] 通常情况下,I2C设备由内核驱动控制,但是某些情况下I2C设备也可由用户空间控制.如果在用户空间控制I2C设备,需要访问/dev目录中所提供的接口,在使用I2C设备之 ...

  9. linux2.6驱动学习笔记之字符驱动

    1.字符驱动组成 1.1字符驱动的模块加载与卸载 //设备结构体模板 struct xxx_dev_t { struct cdev cdev; ...... }xxx_dev; 在字符驱动模块加载函数 ...

最新文章

  1. 政务大数据共享难题的破解路径有哪些?
  2. nix与linux的区别,linux – Nix / OS架构概述?
  3. Magical Sticks 棍子拼接
  4. 《剑指offer》旋转数组的最小数字
  5. 将流数据输出到Mysql中
  6. 网络协议从入门到底层原理(10)WebSocket、WebService、RESTful、HTTPDNS、FTP文件传输协议、邮件相关协议、IPv6
  7. python suds 调用webservice 缓存
  8. Java中String转换int
  9. matlab 线性回归 参数显著性,matlab做多元线性回归后回归系数的显著性检验
  10. 码力十足学量化|如何获取指数成分股及权重数据
  11. 外包的水有多深?华为18k的外包测试岗能去吗?
  12. bigboss help啊
  13. 远程控制工具哪个好?向日葵VS ToDesk,安卓移动设备远程操控哪个更好用?
  14. linux运行魔力宝贝,魔力宝贝私服架设详细简易教程
  15. 华为手机拍照那么厉害,为什么你却总拍不好?肯定是没调整这些设置
  16. nginx代理图片和视频
  17. 严重性代码说明项目文件行禁止显示状态错误LNK2019无法解析的外部符号 main,函数 “int __cdecl invoke_main(void)“ (? invoke_main@@YAHX
  18. 论文复刻:排污权机制是否提高了企业全要素生产率(附代码、数据、原文献)
  19. 安防无战事:一场10213亿元的误会 1
  20. vue渲染.md文件

热门文章

  1. Selenium Webdriver系列教程(1)—快速开始
  2. 使用javaxMail发送邮件
  3. docker 部署maven服务器,并将代码发布到maven服务器,并kie-server关联
  4. 一个银行抢劫犯的抢劫日记
  5. 一文读懂UWB超宽带技术
  6. 解决:ImportError: No module named ‘StringIO‘
  7. “F12键无效的解决方法
  8. PostgreSQL系统视图
  9. c与MATLAB混合编程 mxArray矩阵赋值
  10. dubbo zookeeper not connected