【lwip】09-IPv4协议&超全源码实现分析( 七 )

  • 调用ip4_route_src()匹配网卡 。
  • 调用ip4_output_if()把数据包传入IP层处理 。
  • /** * Simple interface to ip_output_if. It finds the outgoing network * interface and calls upon ip_output_if to do the actual work. * * @param p the packet to send (p->payload points to the data, e.g. nextprotocol header; if dest == LWIP_IP_HDRINCL, p already includes anIP header and p->payload points to that IP header) * @param src the source IP address to send from (if src =https://www.huyubaike.com/biancheng/= IP4_ADDR_ANY, the *IPaddress of the netif used to send is used as source address) * @param dest the destination IP address to send the packet to * @param ttl the TTL value to be set in the IP header * @param tos the TOS value to be set in the IP header * @param proto the PROTOCOL to be set in the IP header * * @return ERR_RTE if no route is found *see ip_output_if() for more return values */err_tip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,u8_t ttl, u8_t tos, u8_t proto){struct netif *netif;/* 下传到IP层的pbuf的ref必须为1,即是没有被其它地方引用 , 因为pbuf下传到IP层后 , pbuf的payload指针会被更改 。如果这个pbuf被其它地方引用了,可能会导致数据混乱 。*/LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);/* 根据目的IP地址为数据报寻找一个合适的网络接口(匹配网卡) */if ((netif = ip4_route_src(src, dest)) == NULL) { /* 没找到,记录信息,返回错误 */LWIP_DEBUGF(IP_DEBUG, ("ip4_output: 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);return ERR_RTE;}/* 匹配到网卡,传入IP层处理:组包、发送 */return ip4_output_if(p, src, dest, ttl, tos, proto, netif);}9.7.3 发包前的网卡匹配IP层收到上层的数据包后,需要匹配到网络接口 , 才能组IP包发出去 。
    这里调用ip4_route_src()进行网卡匹配 。具体分析参考前面 。
    9.7.4 组建、发送IP包注意几个函数的区别:
    • ip4_output_if():这个函数封装了底层IP层组包、发送的实现函数 。
    • ip4_output_if_src():这个函数就是IP层组包、发送的实现函数 。不支持IP首部的选项字段 。
    • ip4_output_if_opt():这也是IP层组包、发送的实现函数,会用选中的网卡IP地址覆盖传入的源IP地址 。支持IP首部的选项字段 。
    • ip4_output_if_opt_src():这也是IP层组包、发送的实现函数,不会用选中的网卡IP地址覆盖传入的源IP地址 。支持IP首部的选项字段 。
    相关宏:
    IP_OPTIONS_SEND
    • IP首报文首部选项字段宏开关 。
    • 如果开启了该宏 , 则会调用上述带_opt字样的函数,操作IP首部报文的选项字段 。
    LWIP_IP_HDRINCL:缺省为NULL
    • 如果把这个宏当目的IP地址传入IP层组包、发送的相关函数ip4_output_if()或其底层函数时 , 表示当前这个pbuf已经组好IP首部了 。
    • 一般用于TCP重传 。
    LWIP_CHECKSUM_CTRL_PER_NETIF
    • 允许每个网卡配置checksum功能 。
    相关变量:
    • ip_id:IP首部标识,全局值 。
    我们就分析ip4_output_if_opt_src()函数,比较全 。
    ip4_output_if_opt_src()
    • 先处理选项字段,在处理IP首部其它字段 。
    • struct pbuf *p:传输层协议需要发送的数据包pbuf,payload指针已指向传输层协议首部 。
    • const ip4_addr_t *src:源IP地址 。
    • const ip4_addr_t *dest:目的IP地址 。
    • u8_t ttl:IP首部TTL字段 。
    • u8_t tos:IP首部TOS字段 。
    • u8_t proto:IP首部上层协议字段 。
    • struct netif *netif:发送IP数据报的网卡 。
    • void *ip_options:IP首部选项字段值 。
    • u16_t optlen:IP首部选项字段的长度 。
    概要内容: