- 首页 > 生活 > >
【lwip】09-IPv4协议&超全源码实现分析( 六 )
遍历网卡:
- 有效网卡先匹配子网;
- 子网匹配失败就匹配网关,网卡不能有广播能力 。
环回IP:如果开启了各个网卡的环回功能,且没有创建环回网卡:
- 说明:因为创建了环回网卡,在遍历链表时,就会把环回IP 127.x.x.x都会匹配到环回网卡 。
- 对于环回IP,优先匹配默认网卡
netif_default
。 - 再遍历网卡,第一个协议栈有效的网卡即可 。
钩子匹配:(由用户实现)
- 先
LWIP_HOOK_IP4_ROUTE_SRC(src, dest);
- 再
LWIP_HOOK_IP4_ROUTE(dest);
以上都没有匹配成功,则使用netif_default
,必须条件:
- 默认网卡
netif_default
存在; - 默认网卡协议栈有效;
- 默认网卡数据链路有效;
- 默认网卡IP有效 。
- 匹配的目的IP不能为环回IP(因为如果是环回IP,前面已经匹配过了,除非没有开启该功能)
/** * Finds the appropriate network interface for a given IP address. It * searches the list of network interfaces linearly. A match is found * if the masked IP address of the network interface equals the masked * IP address given to the function. * * @param dest the destination IP address for which to find the route * @return the netif on which to send to reach dest */struct netif *ip4_route(const ip4_addr_t *dest){#if !LWIP_SINGLE_NETIFstruct netif *netif;/* 确保在tcpip内核锁内 */LWIP_ASSERT_CORE_LOCKED();#if LWIP_MULTICAST_TX_OPTIONS /* 开启了组播TX功能 *//* 如果目的IP是一个组播地址,且协议栈内创建了组播专用网卡,则选用组播专用网卡接口 */if (ip4_addr_ismulticast(dest) && ip4_default_multicast_netif) {return ip4_default_multicast_netif;}#endif /* LWIP_MULTICAST_TX_OPTIONS *//* bug #54569: in case LWIP_SINGLE_NETIF=1 and LWIP_DEBUGF() disabled, the following loop is optimized away */LWIP_UNUSED_ARG(dest);/* 遍历网卡链表 */NETIF_FOREACH(netif) {/* 网卡协议栈有效,网卡链路层也有效,网卡的IP地址不为全0 */if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) {/* 匹配传入的目的IP和网卡是否处于同一个子网 */if (ip4_addr_net_eq(dest, netif_ip4_addr(netif), netif_ip4_netmask(netif))) {/* 匹配成功 。返回netif,以转发IP数据包 */return netif;}/* 当前网卡子网匹配不成功 *//* 那就匹配下网关,匹配规则:网卡没有广播功能,目的IP和网关IP一致 。也算匹配成功,因为上层的目的是到网关 。当前网卡能把数据传达到网卡 。*/if (((netif->flags & NETIF_FLAG_BROADCAST) == 0) && ip4_addr_eq(dest, netif_ip4_gw(netif))) {/* 匹配成功 。返回netif,以转发IP数据包 */return netif;}}}/* 到这,遍历网卡,匹配失败 *//* 开启了环回功能,但是没有创建环回网卡 。(因为如果创建了环回网卡,在遍历网卡链表时就已经处理过了,这里不需要再处理) */#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF/* 如果目的IP是一个环回IP地址,则优先返回默认网卡,否则返回网卡链表中第一个协议栈使能了的网卡作为当前环回网卡 */if (ip4_addr_isloopback(dest)) { /* 目的IP是一个环回IP */if ((netif_default != NULL) && netif_is_up(netif_default)) {/* 优先考虑默认网卡 。如果有默认网卡,且默认网卡协议栈使能了,则以此网卡作为本次环回网卡 */return netif_default;}/* 默认网卡没有匹配成功,则从网卡链表中找一个协议栈已使能的网卡作为本次环回网卡 */NETIF_FOREACH(netif) {if (netif_is_up(netif)) {return netif;}}return NULL; /* 都没找到,那就匹配失败 */}#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */#ifdef LWIP_HOOK_IP4_ROUTE_SRC /* 如果开启了匹配网卡的钩子宏函数 */netif = LWIP_HOOK_IP4_ROUTE_SRC(NULL, dest); /* 使用宏钩子匹配 */if (netif != NULL) {return netif;}#elif defined(LWIP_HOOK_IP4_ROUTE) /* 网卡匹配钩子 */netif = LWIP_HOOK_IP4_ROUTE(dest); /* 使用宏钩子匹配 */if (netif != NULL) {return netif;}#endif#endif /* !LWIP_SINGLE_NETIF *//* 上述方案都无法匹配到网卡,就检查网卡网卡是否正常,正常则就返回默认网卡 */if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default) ||ip4_addr_isany_val(*netif_ip4_addr(netif_default)) || ip4_addr_isloopback(dest)) {LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));IP_STATS_INC(ip.rterr);MIB2_STATS_INC(mib2.ipoutnoroutes);return NULL;}return netif_default; /* 返回默认网络接口 */}
经验总结扩展阅读
-
-
室内设计师苏哥 若“条件允许”,可以在厨房添置这3样东西,省心又方便
-
-
-
-
-
-
-
-
-
相亲见面后 真正想娶你的男人,他对你的用心可以由他的行为窥探一二
-
节日关爱女性,筑情“三八”——《健康与美容》杂志社敬献“三八”节日礼
-
结绿|儿媳体检查出生病,儿子只顾打牌不照顾妻子,婆婆赶来掀翻麻将桌
-
@头条情感首先|你对有纹身的女人持什么看法?你会与有纹身的女人谈恋爱吗?
-
2022年11月23日打更吉日一览表 2022年11月23日打更好吗
-
-
-
毛孔乳液洁面乳,抗老必备,即刻进入柔润粉嫩,这些洗面奶。爱了,爱了
-
-