mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2026-05-28 11:07:51 +08:00
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:
@@ -61,6 +61,10 @@
|
||||
#include "lwip/api.h"
|
||||
#include "netif/ppp/ppp_impl.h"
|
||||
|
||||
#if LWIP_IPV4 && LWIP_IPV6
|
||||
const ip_addr_t ip_addr_any_type = IPADDR_ANY_TYPE_INIT;
|
||||
#endif
|
||||
|
||||
/* Compile-time sanity checks for configuration errors.
|
||||
* These can be done independently of LWIP_DEBUG, without penalty.
|
||||
*/
|
||||
|
||||
@@ -167,7 +167,7 @@ raw_input(struct pbuf *p, struct netif *inp)
|
||||
err_t
|
||||
raw_bind(struct raw_pcb *pcb, const ip_addr_t *ipaddr)
|
||||
{
|
||||
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;
|
||||
}
|
||||
ip_addr_set_ipaddr(&pcb->local_ip, ipaddr);
|
||||
@@ -190,7 +190,7 @@ raw_bind(struct raw_pcb *pcb, const ip_addr_t *ipaddr)
|
||||
err_t
|
||||
raw_connect(struct raw_pcb *pcb, const ip_addr_t *ipaddr)
|
||||
{
|
||||
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;
|
||||
}
|
||||
ip_addr_set_ipaddr(&pcb->remote_ip, ipaddr);
|
||||
|
||||
@@ -450,7 +450,7 @@ tcp_bind(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
|
||||
#endif /* LWIP_IPV4 */
|
||||
|
||||
/* still need to check for ipaddr == NULL in IPv6 only case */
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -756,7 +756,7 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port,
|
||||
u32_t iss;
|
||||
u16_t old_local_port;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -147,11 +147,20 @@ again:
|
||||
* @return 1 on match, 0 otherwise
|
||||
*/
|
||||
static u8_t
|
||||
udp_input_local_match(struct udp_pcb *pcb, struct netif *inp, u8_t broadcast)
|
||||
udp_input_local_match(struct udp_pcb *pcb, struct netif *netif, u8_t broadcast)
|
||||
{
|
||||
LWIP_UNUSED_ARG(netif); /* in IPv6 only case */
|
||||
LWIP_UNUSED_ARG(broadcast); /* in IPv6 only case */
|
||||
|
||||
/* @todo: Add special dualstack case here */
|
||||
/* Dual-stack: PCBs listening to any IP type also listen to any IP address */
|
||||
if(IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
|
||||
#if IP_SOF_BROADCAST_RECV
|
||||
if(broadcast && !ip_get_option(pcb, SOF_BROADCAST)) {
|
||||
return 0;
|
||||
}
|
||||
#endif /* IP_SOF_BROADCAST_RECV */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Only need to check PCB if incoming IP version matches PCB IP version */
|
||||
if(ip_current_is_v6() == IP_IS_V6_VAL(pcb->local_ip)) {
|
||||
@@ -167,7 +176,7 @@ udp_input_local_match(struct udp_pcb *pcb, struct netif *inp, u8_t broadcast)
|
||||
{
|
||||
if(ip4_addr_isany(ip_2_ip4(&pcb->local_ip)) ||
|
||||
((ip4_current_dest_addr()->addr == IPADDR_BROADCAST)) ||
|
||||
ip4_addr_netcmp(ip_2_ip4(&pcb->local_ip), ip4_current_dest_addr(), netif_ip4_netmask(inp))) {
|
||||
ip4_addr_netcmp(ip_2_ip4(&pcb->local_ip), ip4_current_dest_addr(), netif_ip4_netmask(netif))) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -907,7 +916,7 @@ udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
|
||||
#endif /* LWIP_IPV4 */
|
||||
|
||||
/* still need to check for ipaddr == NULL in IPv6 only case */
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -998,7 +1007,7 @@ udp_connect(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1123,9 +1132,8 @@ udp_new(void)
|
||||
return pcb;
|
||||
}
|
||||
|
||||
#if LWIP_IPV6
|
||||
/**
|
||||
* Create a UDP PCB for IPv6.
|
||||
* Create a UDP PCB for specific IP type. See IPADDR_TYPE_XX definitions.
|
||||
*
|
||||
* @return The UDP PCB which was created. NULL if the PCB data structure
|
||||
* could not be allocated.
|
||||
@@ -1133,17 +1141,18 @@ udp_new(void)
|
||||
* @see udp_remove()
|
||||
*/
|
||||
struct udp_pcb *
|
||||
udp_new_ip6(void)
|
||||
udp_new_ip_type(u8_t type)
|
||||
{
|
||||
struct udp_pcb *pcb;
|
||||
pcb = udp_new();
|
||||
#if LWIP_IPV4
|
||||
IP_SET_TYPE_VAL(pcb->local_ip, IPADDR_TYPE_V6);
|
||||
IP_SET_TYPE_VAL(pcb->remote_ip, IPADDR_TYPE_V6);
|
||||
#endif /* LWIP_IPV4 */
|
||||
#if LWIP_IPV4 && LWIP_IPV6
|
||||
IP_SET_TYPE_VAL(pcb->local_ip, type);
|
||||
IP_SET_TYPE_VAL(pcb->remote_ip, type);
|
||||
#else
|
||||
LWIP_UNUSED_ARG(type);
|
||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||
return pcb;
|
||||
}
|
||||
#endif /* LWIP_IPV6 */
|
||||
|
||||
#if LWIP_IPV4
|
||||
/** This function is called from netif.c when address is changed
|
||||
|
||||
Reference in New Issue
Block a user