当前位置:网站首页>Lwip之ARP模块实现
Lwip之ARP模块实现
2022-06-26 23:58:00 【龙赤子】
一:数据结构
这里主要介绍arp表结构
struct etharp_entry {
#if ARP_QUEUEING
/**
* Pointer to queue of pending outgoing packets on this ARP entry.
*/
struct pbuf *p;
#endif
struct ip_addr ipaddr;
struct eth_addr ethaddr;
enum etharp_state state;
u8_t ctime;
};
该结构是ARP模块操作的主要数据结构,主要数据项包括:
IP地址:表示要获取该ip地址对应的端口的mac地址
MAC地址:用来保存获取后的mac地址
状态:表示当前的表项的状态
时间计数:每一个表项都有一个有效时间,通过该域可以知道当前的表项是否还有效
另外,还可能包含一个pbuf指针,用来指向等待该入口的数据包。这个数据项选用与否根据外部设置来决定。
通常,arp表是一个数组,其中的每一项表示一个ip-mac地址对,每时每刻,不断有新的地址对被添加进来,同时清除失效的地址对,这可以通过一定的策略来完成。(这里失效的地址对不一定就是时间失效的地址对)
二:函数接口
函数名:etharp_init()
功能:arp模块的初始化
操作:主要操作是初始化arp表,表项的时间清零,状态设置为空状态。
函数名:etharp_tmr()
功能:该函数是arp定时器超时执行函数,每当arp定时到达后执行该函数,它会清除arp表中失效的(超时的?)entry
操作:该函数遍历整个arp表项,每判断一个表项,就根据当前表项的状态和时间决定该表项下一时刻的状态。
函数名:find_entry(struct ip_addr *ipaddr, u8_t flags)
功能:查询arp表,找到一个匹配项或者新的入口
操作:分三步,首先遍历查询整个arp表,记住候选资格,其次选择具备候选资格的入口,最后创建新的入口。在一个简单的遍历查询中,需要做以下一些工作:记住第一个空的入口;记住最老的稳定的入口;记住最老的,不带排队数据包的未决入口;记住最老的带排队数据包的未决入口。除了空状态,对于其他状态,如果其ip地址匹配,则直接返回该表项的索引。另外,参数flags决定是否选择try_hard模式,如果选择了此模式,那么就允许创建新的入口通过回收活动的入口,也就是说这种模式下即使所有的入口都在使用,那么也会根据相应的算法回收一个最近最不重要的入口提供给新的请求。如果没有找到匹配项,并且flag参数设置了try_hard模式,就会按照下述策略进行新入口的选择:空入口;最老的稳定入口;最老的不带排队包的未决入口;最老的带排队包的未决入口。如果按照上述策略能够找到一个arp表项的索引,就将该索引作为新的入口。
函数名:update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags)
功能:在arp表中更新或者插入一个IP/MAC地址对。如果一个未决的入口已经被决定了,那么其上所有排队的包都将被发送。
操作:首先判断参数中的IP地址,如果不是单播地址,则当错误参数处理。之后调用find_entry找到一个索引项,设置该索引项。如果其上有排队的数据包,则发送这些数据包
函数名:etharp_ip_input(struct netif *netif, struct pbuf *p)
功能:使用收到的ip包的源地址更新本地网络的arp表。对该函数的调用处在收到数据包之后,传递给IP层之前。对该函数的调用主要用于更新arp表,基本操作为提取出接收到的数据包中的IP地址信息,如果是属于本地局域网,则调用update_arp_entry进行arp表的更新。
操作:首先判断包的源地址,如果不在本地网络上,则什么也不做,返回;否则,调用update_arp_entry更新arp表。
函数名:eth_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
功能:响应arp请求;对于arp响应,添加入口项,并发送排队数据包;更新地址对。另外,该函数会进行释放pbuf的操作,也就是说为接收到的arp数据包分配的pbuf会在这里释放。如果是arp请求,则直接复用该pbuf,修改设置,发送arp响应。
操作:如果当前进入的arp包的目的地址是本地地址,则以try_hard模式调用update_arp_entry更新arp表,否则,使用普通模式更新arp表。之后,根据arp的操作码决定何种操作:如果是arp请求,并且目的地址就是本地地址,则就地构造arp响应包,将本机的mac地址填充进去,然后发送;如果是arp响应包,更新本地arp表(前面已做过)。最后释放pbuf。
函数名:etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
功能:为输出的数据包添加以太网头或者解决解决以太网地址。来自上层的数据包在调用驱动接口发送之前,调用该函数设置mac地址
操作:如果是广播包或者组播包,则直接设置其mac地址,并直接发送。如果是单播包,则查看包是否要出本地网络。如果目的地址在本地局域网,则直接调用etharp_query接口,查询arp表,发送数据包;否则,查看接口是否有默认的网关。若无默认的网关,则返回错误,如果有默认的网关,则将IP地址设置为网关的地址,同样调用etharp_query接口发送。
函数名:etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
功能:发送arp请求并/或排队数据包。如果要发送包的ip地址不在arp表中,则添加一个pending状态的表项并发送一个arp请求到给定的ip地址,最后将数据包在该入口上排队;如果已经存在一个pending状态的arp表项,一个新的arp请求发送,包排队;如果该ip地址已经是arp表中的一个stable项,并且数据包不为空,则直接发送该数据包,此时不发送arp请求;前述情况,如果数据包为空,此时发送一个arp请求。
操作:调用find_entry找到一个入口索引,如果该入口的状态为empty,则设置为pending。对于pending状态的入口或者空数据包情况,调用etharp_request发送arp请求。如果数据包不为空,并且当前入口为stable状态,则填充包的mac地址,然后发送。如果入口的状态为pending,则将该数据包排队。
函数名:etharp_request(struct netif *netif, struct ip_addr *ipaddr)
功能:根据给定的接口和ip地址,发送请求
操作:首先为arp请求分配一个pbuf,设置该pbuf,发送arp请求包,最后释放pbuf。
网上的关于lwip的arp模块的分析图如下所示
关于arp部分有个问题就是是否需要每收到一个IP包都需要更新arp表(即etharp_ip_input函数是否需要),似乎有点浪费

边栏推荐
- 国内外最好的12款项目管理系统优劣势分析
- Analysis on the advantages and disadvantages of the best 12 project management systems at home and abroad
- Competition Registration | one of the key ai+ scientific computing competitions - China open source scientific software creativity competition, competing for 100000 bonus!
- Service discovery, storage engine and static website of go language
- Thesis study -- Analysis of the influence of rainfall field division method on rainfall control rate
- 2022健康博览会,山东养生保健展会,产后健康、睡眠健康展
- CPU的异常处理
- Overview of Freescale MCU
- Kubernetes visual interface dashboard
- Leetcode 718. Longest repeating subarray (violence enumeration, to be solved)
猜你喜欢

冲刺强基计划数学物理专题二

Color matching and related issues

Thesis study -- Analysis of the influence of rainfall field division method on rainfall control rate

Development and learning route of golang language

超硬核!华为智慧屏上的家庭相册竟可以自动精准分类?

Installation of xshell and xftp
![[microservices] Understanding microservices](/img/62/e826e692e7fd6e6e8dab2baa4dd170.png)
[microservices] Understanding microservices

An article takes you to learn container escape

Special topic II on mathematical physics of the sprint strong foundation program

运用物理信息神经网络求解流体力学方程
随机推荐
The fourth bullet of redis interview eight part essay (end)
超硬核!华为智慧屏上的家庭相册竟可以自动精准分类?
墨者学院-X-Forwarded-For注入漏洞实战
An article takes you to learn container escape
Can I open an account for stock trading on my mobile phone? Is it safe to open an account for stock trading on the Internet
简单快速的数网络(网络中的网络套娃)
Leetcode skimming 4 Find the median of two positive arrays
Freescale 单片机概述
网络中的网络(套娃)
在线上买养老年金险正规安全吗?有没有保单?
Analysis on the advantages and disadvantages of the best 12 project management systems at home and abroad
Hit the point! The largest model training collection!
复杂数据没头绪?
redis详细教程
Understanding of "the eigenvectors corresponding to different eigenvalues cannot be orthogonalized"
全網最全的混合精度訓練原理
基于SSMP的宠物医院管理系统
“message“:“Bad capabilities. Specify either app or appTopLevelWindow to create a session“
當Transformer遇見偏微分方程求解
Technical dry goods | what is a big model? Oversized model? Foundation Model?