LWIP_etharp.c

这几天一直看LWIP,知道今天才看完ETHARP.C,其实和我以前看的一位南开的老师写的差不多,就是比那个复杂了点。

本来想看1.3呢,但是我觉得1.3太乱了,本人能力有限就选择了0.72了。下面是我看etharp.c的一点体会,总结一下了。

这个c文件有个相对应的.h文件etharp.h

定义了ARP协议的头及IP协议的头,一些和arp有关的函数:

 

void etharp_init(void); 初始化ARP

void etharp_tmr(void); 随着时钟节拍,更新entry 的状态

struct pbuf *etharp_ip_input(struct netif *netif, struct pbuf *p);

 ip输入中提取ARP

struct pbuf *etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr,

         struct pbuf *p); ARP输入

struct pbuf *etharp_output(struct netif *netif, struct ip_addr *ipaddr,

         struct pbuf *q); ARP输出返回能输出的包

err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q);

                          ARP查询

//供内部

static s8_t find_arp_entry(void)//返回一个最有理由的ARPentry,不是过期了就是空的

static struct pbuf * update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags);当在ip_input()arp_input()函数中调用,也就是当在前两种情况里捕捉到了entry时更新ARP

 

当然主要就是介绍这些函数了。

在介绍函数之前,还有几个结构体要说明一下:

一个是:entry:

struct etharp_entry {

  struct ip_addr ipaddr;    //ip

  struct eth_addr ethaddr; //mac

  enum etharp_state state;  //状态即下面要说的

#if ARP_QUEUEING

struct pbuf *p; //更新entry 的包,在update()等函数中都有用哦,其实//可以不用

#endif

  u8_t ctime;               //有效时间

};

 

一个是:ARP表的entry的状态有三:EMPTYPENDINGSTABLE即空的,未确定的,稳定的

空的就是这个entry还没用;未确定的就是entry中只有ip没有mac,等着去更新呢,用更新包;稳定的就是都有了的

下面具体介绍函数了:

1、 初始化函数:把状态置为EMPTY,然后把CTIME = 0

2etharp_tmr(),节拍更新函数,随着时钟节拍,更新entry 的状态,如ctime ++;当过期了状态就成EMPTY

3ip_input():arp表里维护的是最近刚用的ip_mac地址entry,从输入的ip包中更新arp这个函数就是这样,当这个包被送往ip层之前一定要把ip_mac取出来,更新表

4arp_input():在里面也需要调用arp_update()函数来更新ARP表;当我们接受到arp输入时有两种情况:一、别人要我们的mac,我们必须发给他;二、我们要别人的mac,别人给咱发过来了,因为一上来就用这次接受的信息更新了ARP表了所以这时就不在更新了

5arp_output():有可能是广播,组播,单播,如果有mac地址,就把这个能发出去的包返回;如果没有的话,就得调用下一个函数etharp_query()了

6etharp_query():查询ARP

不管ARP表中有没有要查询的ip_addr的记录,pbuf *q总要进入arp_table[i]队列,

关于什么时候发request,程序有两个选择:一、用户想在一个稳定的entry里发ip包,所以想在arp_update函数中发送ip包,这时entry得到了更新,是一个稳定的了;二、立即发ARP_REQUEST,立即得到entry;

程序好像选了前者,不过我认为后者挺好的啊

就是ARP表里已经有ip,但没mac,也就是未确定的,当调用arp_update()时,更新entry自然有了mac,这个mac是在ip_input() arp_input()中提取的,这时再发ip;

立即发就是立即发arp包,然后获得mac地址,在发ip

下边两个是供内部使用的函数:

find_arp_entry(void)//返回一个最有理由的ARPentry,不是过期了就是空的

arp_update():供内部

更新ARP表,参数提供ipmacentry,如果表中有ip,则更新mac地址,并把pbuf中的ip包发出去

如果没有,能插入则插入这个entry.

 

你可能感兴趣的:(LWIP_etharp.c)