博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
lwIP ARP协议分析
阅读量:4110 次
发布时间:2019-05-25

本文共 2145 字,大约阅读时间需要 7 分钟。

ARP 协议分析

总的来说,lwip将链路层ethernet的协议分组格式分为ether和etherarp
分开处理。ip分组先进入etharp_ip_input更新一下arp表项,然后直接进入
netif的input传递给上层ip层。arp分组直接进入etharp_arp_input。
不送如ip层。
奇怪的是,lwip把ether header的结构定义在etharp中。

-ARP 数据结构

-- arp表状态
enum etharp_state {
  ETHARP_STATE_EMPTY,  /* 表项空 */
  ETHARP_STATE_PENDING,
  ETHARP_STATE_STABLE, /* 稳定状态表项,该表项中MAC值可直接取出 */
  ETHARP_STATE_EXPIRED  /* 超时表项 */
};
-- arp表项结构
struct etharp_entry {
  struct pbuf *p;  /* arp 请求队列 */
  struct ip_addr ipaddr;
  struct eth_addr ethaddr;
  enum etharp_state state;
  u8_t ctime; /* 超时值 */
};
-- ARP 链路层协议分组
struct etharp_hdr {
  struct eth_hdr ethhdr; /* ether header */
  u16_t hwtype;
  u16_t proto;
  u16_t _hwlen_protolen;
  u16_t opcode;
  struct eth_addr shwaddr;
  struct ip_addr2 sipaddr;
  struct eth_addr dhwaddr;
  struct ip_addr2 dipaddr;
}

- ARP 函数

void etharp_init();
初始化所有静态ARP表项,状态为EMPTY。
 
static err_t update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags);
首先排除广播、多播及any地址。然后,
将ipaddr及ethaddr对加入arp表项中,该表项索引由find_entry获得。
加入后,将该arp表项中还未发送的IP包(这些IP包是由etharp_ouput函数,在
处理IP包发送时,由于未找到对应ip的mac地址,由etharp_query加入到
pending arp的未发送IP包链表中。现在我们得到mac和ip对应值后,就
可以将这些IP包发送出去),发送到netif驱动。
该函数被etharp_ip_input及etharp_arp_input调用。
 
static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags);
查询包含ipaddr的表项。
查询优先级:1. pending 2. stable 3. empty。
find_entry总是根据这些优先级查找是否由匹配项,如果有,立刻返回该项
索引。否则根据优先级产看是否有过期表项,并覆盖它。
 
void etharp_ip_input(struct netif *netif, struct pbuf *p);
该函数是再ip分组传上ip层之前,将ip分组的mac和ip映射到
arp表项中做更新。这样的设计好像比较浪费。完全可以加大arp
表项,去除该过程
 
void etharp_arp_input(struct netif *netif,
 struct eth_addr *ethaddr, struct pbuf *p);
arp分组到来,直接交给该函数处理。
无论netif的ip地址是否被配置过,都将该ARP分组的源ip和mac地址
加入到ARP表项中。如果一个ARP请求的目的ip地址是本地ip地址。
则发送response ARP分组。
 
err_t etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q);
该函数分开处理两种地址类型的网络层包,
1)多播及广播。直接调用netif->linkoutput发送出去,该函数为网卡驱动。
2)单播。单播的IP包又分三种处理方式。a. 目的ip在arp表项中,并且stable。
则直接构造以太头,调用网卡驱动,发送以太帧。b. 目的ip不在arp表项中,
修改arp表项状态为pending,并调用etharp_request,发送ARP REQUEST。
c. 目的ip在ARP表项中。但状态为pending(这个状态是由b条件引起的,可能
ARP RESPONSE在处理该条件时还为返回)。将待发送的IP包的缓冲区PBUF_REF
替换成PBUF_POOL或PBUF_RAM(暂时不知道为啥)。这些包将会在update_arp_input
中被发送。

- ARP 协议处理流程图

转载地址:http://noosi.baihongyu.com/

你可能感兴趣的文章
pytorch(四)
查看>>
pytorch(5)
查看>>
pytorch(6)
查看>>
opencv 指定版本下载
查看>>
ubuntu相关
查看>>
C++ 调用json
查看>>
nano中设置脚本开机自启动
查看>>
动态库调动态库
查看>>
Kubernetes集群搭建之CNI-Flanneld部署篇
查看>>
k8s web终端连接工具
查看>>
手绘VS码绘(一):静态图绘制(码绘使用P5.js)
查看>>
手绘VS码绘(二):动态图绘制(码绘使用Processing)
查看>>
基于P5.js的“绘画系统”
查看>>
《达芬奇的人生密码》观后感
查看>>
论文翻译:《一个包容性设计的具体例子:聋人导向可访问性》
查看>>
基于“分形”编写的交互应用
查看>>
《融入动画技术的交互应用》主题博文推荐
查看>>
链睿和家乐福合作推出下一代零售业隐私保护技术
查看>>
Unifrax宣布新建SiFAB™生产线
查看>>
艾默生纪念谷轮™在空调和制冷领域的百年创新成就
查看>>