Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions net/inet/inet.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) || \
Expand Down
6 changes: 6 additions & 0 deletions net/inet/inet_globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
53 changes: 53 additions & 0 deletions net/tcp/tcp_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
#include "arp/arp.h"
#include "icmpv6/icmpv6.h"
#include "nat/nat.h"
#include "netdev/netdev.h"

/****************************************************************************
* Private Data
Expand Down Expand Up @@ -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 */

Expand All @@ -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,
Expand Down Expand Up @@ -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 */

Expand All @@ -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 */
Expand Down
51 changes: 51 additions & 0 deletions net/udp/udp_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
Expand All @@ -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;
Expand Down