Implement UDP dual-stack PCB support

Create special IP address type "IPADDR_TYPE_ANY" for it.
SNMP uses new feature in non-netconn mode.

TODO: Same for TCP & RAW, adapt NETCONN to use this feature
This commit is contained in:
Dirk Ziegelmeier
2016-02-24 22:33:05 +01:00
parent 1dde3d6e56
commit 953b7bdd59
8 changed files with 62 additions and 35 deletions

View File

@@ -42,6 +42,11 @@
extern "C" {
#endif
/** These are the values for ip_addr_t.type */
#define IPADDR_TYPE_V4 0U
#define IPADDR_TYPE_V6 6U
#define IPADDR_TYPE_ANY 46U
#if LWIP_IPV4 && LWIP_IPV6
/** A union struct for both IP version's addresses.
* ATTENTION: watch out for its size when adding IPv6 address scope!
@@ -54,19 +59,21 @@ typedef struct _ip_addr {
u8_t type;
} ip_addr_t;
/** These are the values for ip_addr_t.type */
#define IPADDR_TYPE_V4 0U
#define IPADDR_TYPE_V6 6U
extern const ip_addr_t ip_addr_any_type;
#define IPADDR4_INIT(u32val) { { { { u32val, 0ul, 0ul, 0ul } } }, IPADDR_TYPE_V4 }
#define IPADDR6_INIT(a, b, c, d) { { { { a, b, c, d } } }, IPADDR_TYPE_V6 }
#define IP_IS_ANY_TYPE_VAL(ipaddr) ((ipaddr).type == IPADDR_TYPE_ANY)
#define IPADDR_ANY_TYPE_INIT { { { { 0ul, 0ul, 0ul, 0ul } } }, IPADDR_TYPE_ANY }
#define IP_IS_V6_VAL(ipaddr) ((ipaddr).type == IPADDR_TYPE_V6)
#define IP_IS_V6(ipaddr) (((ipaddr) != NULL) && IP_IS_V6_VAL(*(ipaddr)))
#define IP_SET_TYPE_VAL(ipaddr, iptype) do { (ipaddr).type = (iptype); }while(0)
#define IP_SET_TYPE(ipaddr, iptype) do { if((ipaddr) != NULL) { IP_SET_TYPE_VAL(*(ipaddr), iptype); }}while(0)
#define IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr) (IP_IS_V6_VAL(pcb->local_ip) == IP_IS_V6(ipaddr))
#define IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr) (pcb->local_ip.type == ipaddr->type)
#define IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr) (IP_IS_ANY_TYPE_VAL(pcb->local_ip) || IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr))
/* Convert generic ip address to specific protocol version */
#define ip_2_ip6(ipaddr) (&((ipaddr)->u_addr.ip6))
@@ -88,12 +95,10 @@ typedef struct _ip_addr {
IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); }}while(0)
#define ip_addr_get_ip4_u32(ipaddr) (((ipaddr) && !IP_IS_V6(ipaddr)) ? \
ip4_addr_get_u32(ip_2_ip4(ipaddr)) : 0)
#define ip_addr_set(dest, src) do{if(IP_IS_V6(src)){ \
ip6_addr_set(ip_2_ip6(dest), ip_2_ip6(src)); IP_SET_TYPE(dest, IPADDR_TYPE_V6); }else{ \
ip4_addr_set(ip_2_ip4(dest), ip_2_ip4(src)); IP_SET_TYPE(dest, IPADDR_TYPE_V4); }}while(0)
#define ip_addr_set_ipaddr(dest, src) do{if(IP_IS_V6(src)){ \
ip6_addr_set(ip_2_ip6(dest), ip_2_ip6(src)); IP_SET_TYPE(dest, IPADDR_TYPE_V6); }else{ \
ip4_addr_set(ip_2_ip4(dest), ip_2_ip4(src)); IP_SET_TYPE(dest, IPADDR_TYPE_V4); }}while(0)
#define ip_addr_set(dest, src) do{ IP_SET_TYPE(dest, src->type); if(IP_IS_V6(src)){ \
ip6_addr_set(ip_2_ip6(dest), ip_2_ip6(src)); }else{ \
ip4_addr_set(ip_2_ip4(dest), ip_2_ip4(src)); }}while(0)
#define ip_addr_set_ipaddr(dest, src) ip_addr_set(dest, src)
#define ip_addr_set_zero(ipaddr) do{ \
ip6_addr_set_zero(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, 0); }while(0)
#define ip_addr_set_zero_ip4(ipaddr) do{ \
@@ -150,7 +155,8 @@ int ipaddr_aton(const char *cp, ip_addr_t *addr);
#else /* LWIP_IPV4 && LWIP_IPV6 */
#define IP_ADDR_PCB_VERSION_MATCH(addr, pcb) 1
#define IP_ADDR_PCB_VERSION_MATCH(addr, pcb) 1
#define IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr) 1
#if LWIP_IPV4
@@ -158,6 +164,7 @@ typedef ip4_addr_t ip_addr_t;
#define IPADDR4_INIT(u32val) { u32val }
#define IP_IS_V6_VAL(ipaddr) 0
#define IP_IS_V6(ipaddr) 0
#define IP_IS_ANY_TYPE_VAL(ipaddr) 0
#define IP_SET_TYPE_VAL(ipaddr, iptype)
#define IP_SET_TYPE(ipaddr, iptype)
#define ip_2_ip4(ipaddr) (ipaddr)
@@ -195,6 +202,7 @@ typedef ip6_addr_t ip_addr_t;
#define IPADDR6_INIT(a, b, c, d) { { a, b, c, d } }
#define IP_IS_V6_VAL(ipaddr) 1
#define IP_IS_V6(ipaddr) 1
#define IP_IS_ANY_TYPE_VAL(ipaddr) 0
#define IP_SET_TYPE_VAL(ipaddr, iptype)
#define IP_SET_TYPE(ipaddr, iptype)
#define ip_2_ip6(ipaddr) (ipaddr)
@@ -265,6 +273,12 @@ extern const ip_addr_t ip6_addr_any;
#endif
#if LWIP_IPV4 && LWIP_IPV6
#define IP_ANY_TYPE (&ip_addr_any_type)
#else
#define IP_ANY_TYPE IP_ADDR_ANY
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -123,6 +123,7 @@ extern struct udp_pcb *udp_pcbs;
/* The following functions is the application layer interface to the
UDP code. */
struct udp_pcb * udp_new (void);
struct udp_pcb * udp_new_ip_type(u8_t type);
void udp_remove (struct udp_pcb *pcb);
err_t udp_bind (struct udp_pcb *pcb, const ip_addr_t *ipaddr,
u16_t port);
@@ -164,10 +165,6 @@ void udp_input (struct pbuf *p, struct netif *inp);
void udp_init (void);
#if LWIP_IPV6
struct udp_pcb * udp_new_ip6(void);
#endif /* LWIP_IPV6 */
#if LWIP_MULTICAST_TX_OPTIONS
#define udp_set_multicast_netif_addr(pcb, ip4addr) ip_addr_copy_from_ip4((pcb)->multicast_ip, *(ip4addr))
#define udp_get_multicast_netif_addr(pcb) ip_2_ip4(&(pcb)->multicast_ip)