Move some useful internal logic from recvfrom.c and udp_callback.c and put them in ip.h where they can be used more generally
This commit is contained in:
parent
686dcbb79c
commit
db741dd695
|
@ -327,18 +327,51 @@ EXTERN const net_ipv6addr_t g_ipv6_llnetmask; /* Netmask for local link addres
|
|||
((uint16_t*)(addr))[7] = HTONS((addr7)); \
|
||||
} while (0)
|
||||
|
||||
/****************************************************************************
|
||||
* Macro: ip6_map_ipv4addr
|
||||
*
|
||||
* Description:
|
||||
* Hybrid dual-stack IPv6/IPv4 implementations recognize a special class
|
||||
* of addresses, the IPv4-mapped IPv6 addresses. These addresses consist
|
||||
* of:
|
||||
*
|
||||
* 1. An 80-bit prefix of zeros,
|
||||
* 2. Te next 16 bits are one, and
|
||||
* 3. he remaining, least-significant 32 bits contain the IPv4 address.
|
||||
*
|
||||
* This macro encodes an IPv4 address in an IPv6 address in this fashion.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ipv4addr - The IPv4 address to be mapped (scalar)
|
||||
* ipv6addr - The IPv6 address in which to map the IPv4 address (array)
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define ip6_map_ipv4addr(ipv4addr, ipv6addr) \
|
||||
do \
|
||||
{ \
|
||||
memset(ipv6addr, 0, 5 * sizeof(uint16_t)); \
|
||||
ipv6addr[5] = 0xffff; \
|
||||
ipv6addr[6] = (uint16_t)((uint32_t)ip4addr >> 16); \
|
||||
ipv6addr[7] = (uint16_t)ip4addr & 0xffff; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/****************************************************************************
|
||||
* Macro: ip6_get_ipv4addr
|
||||
*
|
||||
* Description:
|
||||
* Decode an encoded IPv4 address.
|
||||
* Decode an IPv4-mapped IPv6 address.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ipv6addr - The IPv6 address (net_ipv6addr_t) containing the encoded
|
||||
* ipv6addr - The IPv6 address (net_ipv6addr_t array) containing the mapped
|
||||
* IPv4 address
|
||||
*
|
||||
* Returned Value:
|
||||
* The decode IPv4 addreses (in_addr_t)
|
||||
* The decoded IPv4 address (scalar in_addr_t)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
@ -352,13 +385,13 @@ EXTERN const net_ipv6addr_t g_ipv6_llnetmask; /* Netmask for local link addres
|
|||
* Macro: ip6_is_ipv4addr
|
||||
*
|
||||
* Description:
|
||||
* Test if an IPv6 is an encoded IPv4 address.
|
||||
* Test if an IPv6 is an IPv4-mapped IPv6 address.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ipv6addr - The IPv6 address to be tested
|
||||
*
|
||||
* Returned Value:
|
||||
* True is returned if ipv6addr holds an encoded IPv4 address.
|
||||
* True is returned if ipv6addr holds a mapped IPv4 address.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
|
|
@ -971,20 +971,23 @@ static inline void recvfrom_udpsender(struct net_driver_s *dev, struct recvfrom_
|
|||
FAR struct udp_conn_s *conn = (FAR struct udp_conn_s*)pstate->rf_sock->s_conn;
|
||||
FAR struct sockaddr_in6 *infrom6 = (FAR struct sockaddr_in6 *)infrom;
|
||||
|
||||
/* Hybrid dual-stack IPv6/IPv4 implementations recognize a special
|
||||
* class of addresses, the IPv4-mapped IPv6 addresses.
|
||||
*/
|
||||
|
||||
if (conn->domain == PF_INET6)
|
||||
{
|
||||
in_addr_t ipv4addr;
|
||||
|
||||
/* Encode the IPv4 address as an IPv4-mapped IPv6 address */
|
||||
|
||||
infrom6->sin6_family = AF_INET6;
|
||||
infrom6->sin6_port = udp->srcport;
|
||||
*fromlen = sizeof(struct sockaddr_in6);
|
||||
|
||||
memset(infrom6->sin6_addr.s6_addr, 0,
|
||||
sizeof(infrom6->sin6_addr.s6_addr) - sizeof(in_addr_t));
|
||||
|
||||
infrom6->sin6_addr.s6_addr[10] = 0xff;
|
||||
infrom6->sin6_addr.s6_addr[11] = 0xff;
|
||||
|
||||
memcpy(&infrom6->sin6_addr.s6_addr[12], ipv4->srcipaddr
|
||||
sizeof(in_addr_t));
|
||||
ipv4addr = net_ip4addr_conv32(ipv4->srcipaddr);
|
||||
ip6_map_ipv4addr(ipv4addr,
|
||||
(net_ipv6addr_t)src_addr6.sin6_addr.s6_addr16);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
|
|
@ -133,19 +133,22 @@ static uint16_t udp_datahandler(FAR struct net_driver_s *dev, FAR struct udp_con
|
|||
FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
/* Hybrid dual-stack IPv6/IPv4 implementations recognize a special
|
||||
* class of addresses, the IPv4-mapped IPv6 addresses.
|
||||
*/
|
||||
|
||||
if (conn->domain == PF_INET6)
|
||||
{
|
||||
in_addr_t ipv4addr;
|
||||
|
||||
/* Encode the IPv4 address as an IPv-mapped IPv6 address */
|
||||
|
||||
src_addr6.sin6_family = AF_INET6;
|
||||
src_addr6.sin6_port = udp->srcport;
|
||||
|
||||
memset(src_addr6.sin6_addr.s6_addr, 0,
|
||||
sizeof(src_addr6.sin6_addr.s6_addr) - sizeof(in_addr_t));
|
||||
|
||||
src_addr6.sin6_addr.s6_addr[10] = 0xff;
|
||||
src_addr6.sin6_addr.s6_addr[11] = 0xff;
|
||||
|
||||
memcpy(&src_addr6.sin6_addr.s6_addr[12], ipv4->srcipaddr,
|
||||
sizeof(in_addr_t));
|
||||
ipv4addr = net_ip4addr_conv32(ipv4->srcipaddr);
|
||||
ip6_map_ipv4addr(ipv4addr,
|
||||
(net_ipv6addr_t)src_addr6.sin6_addr.s6_addr16);
|
||||
|
||||
src_addr_size = sizeof(src_addr6);
|
||||
src_addr = &src_addr6;
|
||||
|
|
Loading…
Reference in New Issue