【lwip】11-UDP协议&源码分析( 九 )

udp_sendto_if():确定UDP本地IP地址,然后调用udp_sendto_if_src()UDP发送数据基函数进行组包 。

  • struct udp_pcb *pcb:负责本次发送的UDP控制块 。
  • struct pbuf *p:需要发送的数据的pbuf 。
  • ip_addr_t *dst_ip:远端IP地址 。
  • u16_t dst_port:远端端口号地址 。
  • struct netif *netif:指定发送UDP报文的网卡 。
  • 参数校验 。
  • 确定本地IP:
    • 如果UDP控制块没有指定本地IP,则获取指定的网卡的IP作为UDP本地IP 。
    • 如果UDP控制块指定了本地IP,则这个IP必须和指定网卡的IP一致,否则不发送 。
/** * @ingroup udp_raw * Send data to a specified address using UDP. * The netif used for sending can be specified. * * This function exists mainly for DHCP, to be able to send UDP packets * on a netif that is still down. * * @param pcb UDP PCB used to send the data. * @param p chain of pbuf's to be sent. * @param dst_ip Destination IP address. * @param dst_port Destination UDP port. * @param netif the netif used for sending. * * dst_ip & dst_port are expected to be in the same byte order as in the pcb. * * @return lwIP error code (@see udp_send for possible error codes) * * @see udp_disconnect() udp_send() */err_tudp_sendto_if(struct udp_pcb *pcb, struct pbuf *p,const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif){const ip_addr_t *src_ip;/* 参数校验 */LWIP_ERROR("udp_sendto_if: invalid pcb", pcb != NULL, return ERR_ARG);LWIP_ERROR("udp_sendto_if: invalid pbuf", p != NULL, return ERR_ARG);LWIP_ERROR("udp_sendto_if: invalid dst_ip", dst_ip != NULL, return ERR_ARG);LWIP_ERROR("udp_sendto_if: invalid netif", netif != NULL, return ERR_ARG);if (!IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) {return ERR_VAL;}/* PCB本地地址是IP_ANY_ADDR还是多播? */#if LWIP_IPV6if (IP_IS_V6(dst_ip)) {if (ip6_addr_isany(ip_2_ip6(&pcb->local_ip)) ||ip6_addr_ismulticast(ip_2_ip6(&pcb->local_ip))) {src_ip = ip6_select_source_address(netif, ip_2_ip6(dst_ip));if (src_ip == NULL) {/* 没有找到合适的源地址 */return ERR_RTE;}} else {/* 使用UDP PCB本地IPv6地址作为源地址,如果仍然有效 */if (netif_get_ip6_addr_match(netif, ip_2_ip6(&pcb->local_ip)) < 0) {/* 地址无效 */return ERR_RTE;}src_ip = &pcb->local_ip;}}#endif /* LWIP_IPV6 */#if LWIP_IPV4 && LWIP_IPV6else#endif /* LWIP_IPV4 && LWIP_IPV6 */#if LWIP_IPV4if (ip4_addr_isany(ip_2_ip4(&pcb->local_ip)) ||ip4_addr_ismulticast(ip_2_ip4(&pcb->local_ip))) {/* 如果UDP控制块本地IP没有指定 , 或者指定的是多播地址,则使用指定的网卡的IP作为UDP本地IP即可 */src_ip = netif_ip_addr4(netif);} else { /**//* 检查UDP PCB本地IP地址是否正确 , 如果netif->ip_addr已更改 , 这可能是旧地址 */if (!ip4_addr_cmp(ip_2_ip4(&(pcb->local_ip)), netif_ip4_addr(netif))) {/* UDP本地IP和指定网卡的IP不匹配,不发送 。*/return ERR_RTE;}/* 确认使用的源IP */src_ip = &pcb->local_ip;}#endif /* LWIP_IPV4 */#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDPreturn udp_sendto_if_src_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum, src_ip);#else /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */return udp_sendto_if_src(pcb, p, dst_ip, dst_port, netif, src_ip);#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */}11.13 UDP接收数据UDP接收处理数据,南向是通过udp_input()API给IP层收到UDP数据报后上交到UDP协议处理 。
udp_input()