Dual-stack fixes in raw/udp/tcp

bind() may change IP type when previous type is IPADDR_TYPE_ANY
connect() IP type must exactly match bind IP type
Use correct IPADDRx_ANY type when calling ip_route()
This commit is contained in:
Dirk Ziegelmeier 2016-11-16 23:30:19 +01:00
parent 1712b06a64
commit d026a3954a
4 changed files with 23 additions and 6 deletions

View File

@ -209,7 +209,7 @@ raw_input(struct pbuf *p, struct netif *inp)
err_t err_t
raw_bind(struct raw_pcb *pcb, const ip_addr_t *ipaddr) raw_bind(struct raw_pcb *pcb, const ip_addr_t *ipaddr)
{ {
if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr)) { if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) {
return ERR_VAL; return ERR_VAL;
} }
ip_addr_set_ipaddr(&pcb->local_ip, ipaddr); ip_addr_set_ipaddr(&pcb->local_ip, ipaddr);
@ -320,7 +320,13 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *ipaddr)
} }
} }
if(IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
/* Don't call ip_route() with IP_ANY_TYPE */
netif = ip_route(IP46_ADDR_ANY(IP_GET_TYPE(ipaddr)), ipaddr);
} else {
netif = ip_route(&pcb->local_ip, ipaddr); netif = ip_route(&pcb->local_ip, ipaddr);
}
if (netif == NULL) { if (netif == NULL) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to ")); LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to "));
ip_addr_debug_print(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ipaddr); ip_addr_debug_print(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ipaddr);

View File

@ -551,7 +551,7 @@ tcp_bind(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
#endif /* LWIP_IPV4 */ #endif /* LWIP_IPV4 */
/* still need to check for ipaddr == NULL in IPv6 only case */ /* still need to check for ipaddr == NULL in IPv6 only case */
if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr)) { if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) {
return ERR_VAL; return ERR_VAL;
} }

View File

@ -571,7 +571,12 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
#endif /* LWIP_IPV6 || (LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS) */ #endif /* LWIP_IPV6 || (LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS) */
/* find the outgoing network interface for this packet */ /* find the outgoing network interface for this packet */
if(IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
/* Don't call ip_route() with IP_ANY_TYPE */
netif = ip_route(IP46_ADDR_ANY(IP_GET_TYPE(dst_ip_route)), dst_ip_route);
} else {
netif = ip_route(&pcb->local_ip, dst_ip_route); netif = ip_route(&pcb->local_ip, dst_ip_route);
}
/* no outgoing network interface could be found? */ /* no outgoing network interface could be found? */
if (netif == NULL) { if (netif == NULL) {
@ -912,7 +917,7 @@ udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
#endif /* LWIP_IPV4 */ #endif /* LWIP_IPV4 */
/* still need to check for ipaddr == NULL in IPv6 only case */ /* still need to check for ipaddr == NULL in IPv6 only case */
if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr)) { if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) {
return ERR_VAL; return ERR_VAL;
} }
@ -1002,7 +1007,7 @@ udp_connect(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
{ {
struct udp_pcb *ipcb; struct udp_pcb *ipcb;
if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) { if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr)) {
return ERR_VAL; return ERR_VAL;
} }

View File

@ -226,6 +226,8 @@ int ipaddr_aton(const char *cp, ip_addr_t *addr);
#define unmap_ipv6_mapped_ipv4(ip4addr, ip6addr) \ #define unmap_ipv6_mapped_ipv4(ip4addr, ip6addr) \
(ip4addr)->addr = (ip6addr)->addr[3]; (ip4addr)->addr = (ip6addr)->addr[3];
#define IP46_ADDR_ANY(type) (((type) == IPADDR_TYPE_V6)? IP6_ADDR_ANY : IP4_ADDR_ANY)
#else /* LWIP_IPV4 && LWIP_IPV6 */ #else /* LWIP_IPV4 && LWIP_IPV6 */
#define IP_ADDR_PCB_VERSION_MATCH(addr, pcb) 1 #define IP_ADDR_PCB_VERSION_MATCH(addr, pcb) 1
@ -274,6 +276,8 @@ typedef ip4_addr_t ip_addr_t;
#define IPADDR_STRLEN_MAX IP4ADDR_STRLEN_MAX #define IPADDR_STRLEN_MAX IP4ADDR_STRLEN_MAX
#define IP46_ADDR_ANY(type) (IP4_ADDR_ANY)
#else /* LWIP_IPV4 */ #else /* LWIP_IPV4 */
typedef ip6_addr_t ip_addr_t; typedef ip6_addr_t ip_addr_t;
@ -315,6 +319,8 @@ typedef ip6_addr_t ip_addr_t;
#define IPADDR_STRLEN_MAX IP6ADDR_STRLEN_MAX #define IPADDR_STRLEN_MAX IP6ADDR_STRLEN_MAX
#define IP46_ADDR_ANY(type) (IP6_ADDR_ANY)
#endif /* LWIP_IPV4 */ #endif /* LWIP_IPV4 */
#endif /* LWIP_IPV4 && LWIP_IPV6 */ #endif /* LWIP_IPV4 && LWIP_IPV6 */