You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/08/03 10:16:38 UTC
[nuttx] branch master updated: net:Add check for address binding
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new b10d6be17a net:Add check for address binding
b10d6be17a is described below
commit b10d6be17a63d96d287d970ae180b33d34d93202
Author: wangchen <wa...@xiaomi.com>
AuthorDate: Thu Aug 3 15:19:42 2023 +0800
net:Add check for address binding
Signed-off-by: wangchen <wa...@xiaomi.com>
---
net/inet/inet.h | 1 +
net/inet/inet_globals.c | 6 ++++++
net/tcp/tcp_conn.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++
net/udp/udp_conn.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 111 insertions(+)
diff --git a/net/inet/inet.h b/net/inet/inet.h
index 4add0d2b9e..369ca8a11d 100644
--- a/net/inet/inet.h
+++ b/net/inet/inet.h
@@ -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) || \
diff --git a/net/inet/inet_globals.c b/net/inet/inet_globals.c
index 0f7580468a..87e54825ce 100644
--- a/net/inet/inet_globals.c
+++ b/net/inet/inet_globals.c
@@ -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 */
diff --git a/net/tcp/tcp_conn.c b/net/tcp/tcp_conn.c
index 1c5ce4eb43..1e9319022f 100644
--- a/net/tcp/tcp_conn.c
+++ b/net/tcp/tcp_conn.c
@@ -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 */
diff --git a/net/udp/udp_conn.c b/net/udp/udp_conn.c
index cc6c166fbe..6092584c33 100644
--- a/net/udp/udp_conn.c
+++ b/net/udp/udp_conn.c
@@ -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;