8.9 数据包接收分析主要分析ARP协议层的处理 。
通过前面分析了以太网链路层收到数据帧后j由ethernet_input()
,如果是一个合法的以太网数据帧,并且协议是ARP类型,就会上传到etharp_input()
处理 。
etharp_input()
主要内容是:
- 检查ARP报文 。
- ARP请求报文:如果是请求报文的目标IP和本地的匹配,就组装ARP响应报文并发送出去 。
- ARP响应报文:
- 更新ARP缓存表 。
- 把阻塞在arp entry缓存队列的IP数据报发送出去 。
- 释放pbuf 。因为ARP报文到此已经处理完毕 。
etharp_input()
:/** * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache * send out queued IP packets. Updates cache with snooped address pairs. * * Should be called for incoming ARP packets. The pbuf in the argument * is freed by this function. * * @param p The ARP packet that arrived on netif. Is freed by this function. * @param netif The lwIP network interface on which the ARP packet pbuf arrived. * * @see pbuf_free() */voidetharp_input(struct pbuf *p, struct netif *netif){struct etharp_hdr *hdr;ip4_addr_t sipaddr, dipaddr;u8_t for_us, from_us;LWIP_ASSERT_CORE_LOCKED();LWIP_ERROR("netif != NULL", (netif != NULL), return;);hdr = (struct etharp_hdr *)p->payload; /* 把ARP报文拿出来 *//* RFC 826 "Packet Reception": *//* 检查ARP包的合法性 */if ((hdr->hwtype != PP_HTONS(LWIP_IANA_HWTYPE_ETHERNET)) || /* 硬件地址类型只支持以太网类型 */(hdr->hwlen != ETH_HWADDR_LEN) || /* 硬件地址长度检查(MAC类型为6) */(hdr->protolen != sizeof(ip4_addr_t)) || /* 协议地址长度检查 。目前只支持IPV4 */(hdr->proto != PP_HTONS(ETHTYPE_IP)))/* 协议地址类型,IPv4类型 */{ /* ARP报文校验不通过 */LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,("etharp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n",hdr->hwtype, (u16_t)hdr->hwlen, hdr->proto, (u16_t)hdr->protolen));/* 数据包丢弃记录 */ETHARP_STATS_INC(etharp.proterr);ETHARP_STATS_INC(etharp.drop);/* 释放pbuf */pbuf_free(p);return;}/* ARP报文校验通过,记录下 */ETHARP_STATS_INC(etharp.recv);#if LWIP_ACD/* We have to check if a host already has configured our ip address and* continuously check if there is a host with this IP-address so we can* detect collisions.* acd_arp_reply ensures the detection of conflicts. It will handle possible* defending or retreating and will make sure a new IP address is selected.* etharp_input does not need to handle packets that originate "from_us".*/acd_arp_reply(netif, hdr); /* IP冲突处理 。AUTOIP协议范畴,如果开启了AUTOIP,每一个收到的ARP包都会先经过这个处理 。*/#endif /* LWIP_ACD */IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&sipaddr, &hdr->sipaddr); /* 把ARP报文的源IP地址提前出来 */IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&dipaddr, &hdr->dipaddr); /* 把ARP报文的目标IP地址提前出来 */if (ip4_addr_isany_val(*netif_ip4_addr(netif))) { /* 主机网卡没有配置IP地址 */for_us = 0; /* 这个ARP包不是给我们的 */from_us = 0; /* 也不是从我们这里发出去再被转回来的 */} else { /* 主机网卡已经被配置了IP,可以继续分析ARP报文 *//* ARP报文是否是指向我们的 */for_us = (u8_t)ip4_addr_eq(&dipaddr, netif_ip4_addr(netif));/* 收到的这个ARP报文是否是从我们这里发出的 */from_us = (u8_t)ip4_addr_eq(&sipaddr, netif_ip4_addr(netif));}/* 如果这个ARP报文是给我们的:-> 更新ARP缓存表;-> 如果是一个ARP请求报文,那就组装ARP响应报文回去 。-> 如果是一个ARP响应报文,那就把当前arp entry中的缓存队列数据发出去 。如果这个ARP报文不是给我们的:->如果缓存表中有空闲的arp entry,我们也可以保存这个IP-MAC映射 */etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr),for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY); /* 更新ARP缓存表 *//* 检查当前ARP报文的类型 */switch (hdr->opcode) {case PP_HTONS(ARP_REQUEST): /* ARP请求 *//* ARP request. 如果是询问我们这个IP映射的MAC地址,那么就组装ARP响应报文回去 */LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: incoming ARP request\n"));if (for_us && !from_us) { /* 这个ARP请求是询问我们的 *//* 发送ARP响应 */etharp_raw(netif,(struct eth_addr *)netif->hwaddr, &hdr->shwaddr,(struct eth_addr *)netif->hwaddr, netif_ip4_addr(netif),&hdr->shwaddr, &sipaddr,ARP_REPLY);} else if (ip4_addr_isany_val(*netif_ip4_addr(netif))) { /* 我们还没有配置IP *//* { for_us == 0 and netif->ip_addr.addr == 0 } */LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: we are unconfigured, ARP request ignored.\n"));} else { /* 这个ARP请求不是给我们的 *//* { for_us == 0 and netif->ip_addr.addr != 0 } */LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: ARP request was not for us.\n"));}break;case PP_HTONS(ARP_REPLY):/* ARP reply. 已经更新了ARP缓存表 */LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: incoming ARP reply\n"));break;default:LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: ARP unknown opcode type %"S16_F"\n", lwip_htons(hdr->opcode)));ETHARP_STATS_INC(etharp.err); /* 收到的ARP报文异常,记录下 */break;}/* ARP报文处理完毕,释放资源 */pbuf_free(p);}
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Unity坐标系入门
- 原神蔷薇种子怎么获取
- 原神3.0须弥旋曜玉帛位置在哪
- 2023年10月29日结婚好不好 嫁娶吉利吗
- 2023年农历十一月属羊人哪天适合结婚
- 聚财公司名字大全集 招财旺生意的公司名字
- 抖音店铺取名 抖音吸引人店铺名字
- 电影狼溪一共几部?
- 2023年1月30日制作嫁衣行吗 2023年1月30日制作嫁衣好不好
- 菠萝袜是什么袜子?