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;