8.7.2 ARP报文组建发送函数(基函数)ARP请求包是通过etharp_raw()
函数进行组包和发送的,然后通过封装该函数得出不同需求的ARP请求函数供给上层使用 。
/** * Send a raw ARP packet (opcode and all addresses can be modified) * * @param netif the lwip network interface on which to send the ARP packet * @param ethsrc_addr the source MAC address for the ethernet header * @param ethdst_addr the destination MAC address for the ethernet header * @param hwsrc_addr the source MAC address for the ARP protocol header * @param ipsrc_addr the source IP address for the ARP protocol header * @param hwdst_addr the destination MAC address for the ARP protocol header * @param ipdst_addr the destination IP address for the ARP protocol header * @param opcode the type of the ARP packet * @return ERR_OK if the ARP packet has been sent *ERR_MEM if the ARP packet couldn't be allocated *any other err_t on failure */static err_tetharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,const struct eth_addr *ethdst_addr,const struct eth_addr *hwsrc_addr, const ip4_addr_t *ipsrc_addr,const struct eth_addr *hwdst_addr, const ip4_addr_t *ipdst_addr,const u16_t opcode){struct pbuf *p;err_t result = ERR_OK;struct etharp_hdr *hdr;LWIP_ASSERT("netif != NULL", netif != NULL);/* 链路层组包,为ARP报文申请内存资源 */p = pbuf_alloc(PBUF_LINK, SIZEOF_ETHARP_HDR, PBUF_RAM);if (p == NULL) { /* 内存资源申请失败 */LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,("etharp_raw: could not allocate pbuf for ARP request.\n"));ETHARP_STATS_INC(etharp.memerr);return ERR_MEM;}LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr",(p->len >= SIZEOF_ETHARP_HDR));hdr = (struct etharp_hdr *)p->payload;LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n"));hdr->opcode = lwip_htons(opcode); /* 操作字段 */LWIP_ASSERT("netif->hwaddr_len must be the same as ETH_HWADDR_LEN for etharp!",(netif->hwaddr_len == ETH_HWADDR_LEN));SMEMCPY(&hdr->shwaddr, hwsrc_addr, ETH_HWADDR_LEN); /* 源MAC字段 */SMEMCPY(&hdr->dhwaddr, hwdst_addr, ETH_HWADDR_LEN); /* 目标MAC字段 */IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(&hdr->sipaddr, ipsrc_addr); /* 源IP字段 */IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(&hdr->dipaddr, ipdst_addr); /* 目标IP字段 */hdr->hwtype = PP_HTONS(LWIP_IANA_HWTYPE_ETHERNET); /* 硬件类型 */hdr->proto = PP_HTONS(ETHTYPE_IP); /* 协议类型 */hdr->hwlen = ETH_HWADDR_LEN; /* 硬件地址长度 */hdr->protolen = sizeof(ip4_addr_t); /* 协议地址长度 *//* 发送ARP包 */#if LWIP_AUTOIP/* 如果我们源IP为本地链路的IP,说明本ARP报文为ARP探测包,用于检查当前链路这个目标IP是否被占用了 。所以需要用以太网帧的目标MAC需要设置为广播MAC(参见RFC3927第2.5节最后一段)*/if (ip4_addr_islinklocal(ipsrc_addr)) {ethernet_output(netif, p, ethsrc_addr, ðbroadcast, ETHTYPE_ARP); /* 发送以太网帧 */} else#endif /* LWIP_AUTOIP */{ /* 非ARP探测包,可按指定MAC封装以太网首部的目标MAC */ethernet_output(netif, p, ethsrc_addr, ethdst_addr, ETHTYPE_ARP); /* 发送以太网帧 */}/* lwip状态记录 */ETHARP_STATS_INC(etharp.xmit);/* 释放当前ARP报文资源 */pbuf_free(p);p = NULL;return result;}
8.7.3 发送ARP请求包etharp_request_dst()
:
- 发起ARP请求 。
- 可指定目标MAC 。
/** * Send an ARP request packet asking for ipaddr to a specific eth address. * Used to send unicast request to refresh the ARP table just before an entry times out. * * @param netif the lwip network interface on which to send the request * @param ipaddr the IP address for which to ask * @param hw_dst_addr the ethernet address to send this packet to * @return ERR_OK if the request has been sent *ERR_MEM if the ARP packet couldn't be allocated *any other err_t on failure */static err_tetharp_request_dst(struct netif *netif, const ip4_addr_t *ipaddr, const struct eth_addr *hw_dst_addr){return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, hw_dst_addr,(struct eth_addr *)netif->hwaddr, netif_ip4_addr(netif), ðzero,ipaddr, ARP_REQUEST); /* ARP请求 */}
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Unity坐标系入门
- 原神蔷薇种子怎么获取
- 原神3.0须弥旋曜玉帛位置在哪
- 2023年10月29日结婚好不好 嫁娶吉利吗
- 2023年农历十一月属羊人哪天适合结婚
- 聚财公司名字大全集 招财旺生意的公司名字
- 抖音店铺取名 抖音吸引人店铺名字
- 电影狼溪一共几部?
- 2023年1月30日制作嫁衣行吗 2023年1月30日制作嫁衣好不好
- 菠萝袜是什么袜子?