LWIP手记【A】arp流程之2

2019-04-13 22:08发布

我在LWIP手记【A】arp流程之典型情况一列举了4种ARP的情况。今天我读了etharp.C的注释。写到: /*-----------------------------------------------------------------------------------------------------*/ /**
 * @file
 * Address Resolution Protocol module for IP over Ethernet
 *
 * Functionally, ARP is divided into two parts. The first maps an IP address
 * to a physical address when sending a packet, and the second part answers
 * requests from other machines for our physical address.
 *
 * This implementation complies with RFC 826 (Ethernet ARP). It supports
 * Gratuitious ARP from RFC3220 (IP Mobility Support for IPv4) section 4.6
 * if an interface calls etharp_gratuitous(our_netif) upon address change.
 */
/*-----------------------------------------------------------------------------------------------------*/ 就是说LWIP的这个etharp.C主要实现两个功能,一个是发帧的时候IP需要映射个MAC地址。另一个功能是其他主机要求得到本地主机的MAC地址时,本地主机需要响应请求。 那么第二个功能似乎不在LWIP手记【A】arp流程之典型情况一列举的4种ARP的情况“”之内啊!什么情况!先不管他。 好的,现在就弄个例子模拟一下第二种功能。 将单片机板卡重启后,用电脑发给单片机一个帧,抓图如下:
好现在就来分析一下上面这个过程。 现在打开ARP的调试功能如下 #define ETHARP_DEBUG                    LWIP_DBG_ON, 把这个过程抓图如下:
看了上面这个图片,是不是感觉迷糊?就是不知道哪个C文件打印的,也不知道第几行? 这是感觉LIWP的打印可以改造一下,原先的如下:
#define LWIP_PLATFORM_DIAG printf
#define LWIP_DEBUGF(debug, message) do {
                               if (
                                   ((debug) & LWIP_DBG_ON) &&
                                   ((debug) & LWIP_DBG_TYPES_ON) &&
                                   ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) {
                                 LWIP_PLATFORM_DIAG message;
                                 if ((debug) & LWIP_DBG_HALT) {
                                   while(1);
                                 }
                               }
                             } while(0)
改造如下: #include "string.h"
#define LWIP_PLATFORM_DIAG printf
#define LWIP_DEBUGF(debug, message) do {
                               if (
                                   ((debug) & LWIP_DBG_ON) &&
                                   ((debug) & LWIP_DBG_TYPES_ON) &&
                                   ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) {
                                           printf ((const char *)__FILE__+(strlen((const char *)__FILE__)-20));
      printf (" %d  ",__LINE__);
                                 LWIP_PLATFORM_DIAG message;
                                 if ((debug) & LWIP_DBG_HALT) {
                                   while(1);
                                 }
                               }
                             } while(0)
改造后,打印如下(把发生arp行为的前后几个不想关的帧也打截个图):
这样分析起来更清晰了点。 为什么要采用打印的方法(或者叫做断言),而不是用断点。因为断点有时候会不符合实际情况,可能是超时之类的。 尽管打印本身也会延时,但是是较小的延时。 把文章开头提到的所谓的“”第二个功能”的流程画个图,如下: 第二个功能的etharp_update_arp_entry这个函数内部没有调用etharp_send_ip这个函数。而是在跳出etharp_update_arp_entry这个函数后执行netif->linkoutput(netif, p);也就是执行low_level_output。 而第一个功能的etharp_update_arp_entry这个函数内部调用了etharp_send_ip这个函数。 区别就在这里。