9.5.3 路由网卡匹配支持源IP和目的IP网卡匹配的接口匹配网卡,一般是按照目的IP来匹配,但是可以通过LWIP_HOOK_IP4_ROUTE_SRC()
钩子宏函数来实现源IP地址和目的IP地址匹配 。
ip4_route_src()
:
- 如果源IP地址不为空,则会先传入
LWIP_HOOK_IP4_ROUTE_SRC()
钩子函数来匹配网卡 。 - 钩子函数匹配失败或者源IP地址为空,则由
ip4_route()
只根据目的IP地址匹配 。
#ifdef LWIP_HOOK_IP4_ROUTE_SRC/** * Source based IPv4 routing must be fully implemented in * LWIP_HOOK_IP4_ROUTE_SRC(). This function only provides the parameters. */struct netif *ip4_route_src(const ip4_addr_t *src, const ip4_addr_t *dest){if (src != NULL) {/* 当src=https://www.huyubaike.com/biancheng/=NULL时,钩子会从ip4_route(dest)调用 */struct netif *netif = LWIP_HOOK_IP4_ROUTE_SRC(src, dest);if (netif != NULL) {return netif;}}return ip4_route(dest);}#endif /* LWIP_HOOK_IP4_ROUTE_SRC */
9.5.4 路由网卡匹配的钩子函数通过分析前面的基函数和接口函数,可发现其实现是支持宏钩子函数,即是支持用户自己实现网卡匹配的逻辑的 。有两个宏钩子:
LWIP_HOOK_IP4_ROUTE_SRC(src, dest)
:钩子入口参数有源IP和目的IP 。LWIP_HOOK_IP4_ROUTE(dest)
:钩子入口参数只有目的IP 。
而且IP包的输入和输出的网卡匹配是不一样的,比如普通的IP单播包,输出时,只需要找到目的IP和网卡处于同一个子网或者是该网卡的网关即可匹配 。而输入时,需要明确目的IP就是该网卡IP 。
收包的网卡匹配除了
ip4_input_accept()
这个主要函数外,还有很多独立的匹配条件,具体看IP层输入章节 。这里只分析
ip4_input_accept()
:- 在调用该API前,应该先配置全局IP数据结构成员值:
struct ip_globals ip_data;
- 需要被匹配的网卡必须在协议栈方向使能了,且IP地址为有效地址 。
- 单播包,目的地址和网卡地址一致,网卡匹配成功 。
- 广播包,IP地址bit全1,必定是广播地址 。如果网卡就被广播能力,且IP地址的主机号bit全1,也是子网广播地址 。都匹配成功 。
- 环回,没有环回网卡,且目的IP地址为环回IP
IPADDR_LOOPBACK
。匹配成功 。
/** Return true if the current input packet should be accepted on this netif */static intip4_input_accept(struct netif *netif){LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n",ip4_addr_get_u32(ip4_current_dest_addr()), ip4_addr_get_u32(netif_ip4_addr(netif)),ip4_addr_get_u32(ip4_current_dest_addr()) & ip4_addr_get_u32(netif_ip4_netmask(netif)),ip4_addr_get_u32(netif_ip4_addr(netif)) & ip4_addr_get_u32(netif_ip4_netmask(netif)),ip4_addr_get_u32(ip4_current_dest_addr()) & ~ip4_addr_get_u32(netif_ip4_netmask(netif))));/* 网卡是否在协议栈中使能且网卡地址有效? */if ((netif_is_up(netif)) && (!ip4_addr_isany_val(*netif_ip4_addr(netif)))) {/* 是否是单播到这个接口地址? */if (ip4_addr_eq(ip4_current_dest_addr(), netif_ip4_addr(netif)) ||/* 或者广播这个接口的网络地址? */ip4_addr_isbroadcast(ip4_current_dest_addr(), netif)#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF /* 如果开启环回功能,但是没有创建环回网卡 *//* 目的IP是一个环回的IP地址,也就是给当前网卡的,能匹配成功 */|| (ip4_addr_get_u32(ip4_current_dest_addr()) == PP_HTONL(IPADDR_LOOPBACK))#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */) {LWIP_DEBUGF(IP_DEBUG, ("ip4_input: packet accepted on interface %c%c\n",netif->name[0], netif->name[1]));/* accept on this netif */return 1;}#if LWIP_AUTOIP/* 更改netif地址后,链路本地地址的连接必须保持(RFC3927 ch. 1.9) *//* 即是netif网卡地址更新为可路由地址了,原本本地链路地址的连接必须保持,所以数据包能得到当前网卡 。匹配成功 */if (autoip_accept_packet(netif, ip4_current_dest_addr())) {LWIP_DEBUGF(IP_DEBUG, ("ip4_input: LLA packet accepted on interface %c%c\n",netif->name[0], netif->name[1]));/* accept on this netif */return 1;}#endif /* LWIP_AUTOIP */}return 0;}
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 生的榛子在家怎么炒熟
- 【第5篇】AI语音简介
- 青椒炒鸡蛋热量
- 洗衣服时应当使用哪种洗衣粉
- 蛋白粉用冷水冲还是热水
- 2023最火女儿生日文案简短 生日文案高级简短
- 晒干辣椒的方法
- 有机鲜牛奶和鲜牛奶区别
- 绿豆芽可以放冰箱几天
- 2023七夕节适合结婚吗 2023年七夕结婚吉利吗