net:Add check for address binding

Signed-off-by: wangchen <wangchen41@xiaomi.com>
This commit is contained in:
wangchen 2023-08-03 15:19:42 +08:00 committed by Xiang Xiao
parent b6c2362c6a
commit b10d6be17a
4 changed files with 111 additions and 0 deletions

View File

@ -71,6 +71,7 @@ extern "C"
#ifdef CONFIG_NET_IPv6
EXTERN const net_ipv6addr_t g_ipv6_unspecaddr; /* An address of all zeroes */
EXTERN const net_ipv6addr_t g_ipv6_loopback; /* An address of loopback */
EXTERN const net_ipv6addr_t g_ipv6_allnodes; /* All link local nodes */
#if defined(CONFIG_NET_ICMPv6_AUTOCONF) || defined(CONFIG_NET_ICMPv6_ROUTER) || \

View File

@ -47,6 +47,12 @@ const net_ipv6addr_t g_ipv6_unspecaddr = /* An address of all zeroes */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
const net_ipv6addr_t g_ipv6_loopback = /* An address of loopback */
{
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
HTONS(0x0001)
};
/* IPv6 Multi-cast IP addresses. See RFC 2375 */
const net_ipv6addr_t g_ipv6_allnodes = /* All link local nodes */

View File

@ -69,6 +69,7 @@
#include "arp/arp.h"
#include "icmpv6/icmpv6.h"
#include "nat/nat.h"
#include "netdev/netdev.h"
/****************************************************************************
* Private Data
@ -320,6 +321,7 @@ static inline int tcp_ipv4_bind(FAR struct tcp_conn_s *conn,
{
int port;
int ret;
FAR struct net_driver_s *dev;
/* Verify or select a local port and address */
@ -331,6 +333,29 @@ static inline int tcp_ipv4_bind(FAR struct tcp_conn_s *conn,
return -EINVAL;
}
if (!net_ipv4addr_cmp(addr->sin_addr.s_addr, INADDR_ANY) &&
!net_ipv4addr_cmp(addr->sin_addr.s_addr, HTONL(INADDR_LOOPBACK)) &&
!net_ipv4addr_cmp(addr->sin_addr.s_addr, INADDR_BROADCAST) &&
!IN_MULTICAST(NTOHL(addr->sin_addr.s_addr)))
{
ret = -EADDRNOTAVAIL;
for (dev = g_netdevices; dev; dev = dev->flink)
{
if (net_ipv4addr_cmp(addr->sin_addr.s_addr, dev->d_ipaddr))
{
ret = 0;
break;
}
}
if (ret == -EADDRNOTAVAIL)
{
net_unlock();
return ret;
}
}
/* Verify or select a local port (network byte order) */
port = tcp_selectport(PF_INET,
@ -391,6 +416,7 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
{
int port;
int ret;
FAR struct net_driver_s *dev;
/* Verify or select a local port and address */
@ -402,6 +428,33 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
return -EINVAL;
}
if (!net_ipv6addr_cmp(addr->sin6_addr.in6_u.u6_addr16,
g_ipv6_unspecaddr) &&
!net_ipv6addr_cmp(addr->sin6_addr.in6_u.u6_addr16,
g_ipv6_loopback) &&
!net_ipv6addr_cmp(addr->sin6_addr.in6_u.u6_addr16,
g_ipv6_allnodes) &&
!net_ipv6addr_cmp(addr->sin6_addr.in6_u.u6_addr16, g_ipv6_allnodes))
{
ret = -EADDRNOTAVAIL;
for (dev = g_netdevices; dev; dev = dev->flink)
{
if (net_ipv6addr_cmp(addr->sin6_addr.in6_u.u6_addr16,
dev->d_ipv6addr))
{
ret = 0;
break;
}
}
if (ret == -EADDRNOTAVAIL)
{
net_unlock();
return ret;
}
}
/* Verify or select a local port (network byte order) */
/* The port number must be unique for this address binding */

View File

@ -806,6 +806,7 @@ int udp_bind(FAR struct udp_conn_s *conn, FAR const struct sockaddr *addr)
{
uint16_t portno;
int ret;
FAR struct net_driver_s *dev;
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
if (conn->domain != addr->sa_family)
@ -824,6 +825,29 @@ int udp_bind(FAR struct udp_conn_s *conn, FAR const struct sockaddr *addr)
FAR const struct sockaddr_in *inaddr =
(FAR const struct sockaddr_in *)addr;
if (!net_ipv4addr_cmp(inaddr->sin_addr.s_addr, INADDR_ANY) &&
!net_ipv4addr_cmp(inaddr->sin_addr.s_addr, HTONL(INADDR_LOOPBACK)) &&
!net_ipv4addr_cmp(inaddr->sin_addr.s_addr, INADDR_BROADCAST) &&
!IN_MULTICAST(NTOHL(inaddr->sin_addr.s_addr)))
{
ret = -EADDRNOTAVAIL;
for (dev = g_netdevices; dev; dev = dev->flink)
{
if (net_ipv4addr_cmp(inaddr->sin_addr.s_addr, dev->d_ipaddr))
{
ret = 0;
break;
}
}
if (ret == -EADDRNOTAVAIL)
{
net_unlock();
return ret;
}
}
/* Get the port number that we are binding to */
portno = inaddr->sin_port;
@ -845,6 +869,33 @@ int udp_bind(FAR struct udp_conn_s *conn, FAR const struct sockaddr *addr)
FAR const struct sockaddr_in6 *inaddr =
(FAR const struct sockaddr_in6 *)addr;
if (!net_ipv6addr_cmp(inaddr->sin6_addr.in6_u.u6_addr16,
g_ipv6_unspecaddr) &&
!net_ipv6addr_cmp(inaddr->sin6_addr.in6_u.u6_addr16,
g_ipv6_loopback) &&
!net_ipv6addr_cmp(inaddr->sin6_addr.in6_u.u6_addr16,
g_ipv6_allnodes) &&
!net_ipv6addr_cmp(inaddr->sin6_addr.in6_u.u6_addr16, g_ipv6_allnodes))
{
ret = -EADDRNOTAVAIL;
for (dev = g_netdevices; dev; dev = dev->flink)
{
if (net_ipv6addr_cmp(inaddr->sin6_addr.in6_u.u6_addr16,
dev->d_ipv6addr))
{
ret = 0;
break;
}
}
if (ret == -EADDRNOTAVAIL)
{
net_unlock();
return ret;
}
}
/* Get the port number that we are binding to */
portno = inaddr->sin6_port;