summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-01-17 17:07:54 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-01-17 17:07:54 -0600
commitf73aebe9714ca9ede07a4b5a234b6c5f85490b4c (patch)
tree2e08a2999556fbab9fab8a0f0ec399af06572c46 /nuttx
parent4848dd3d3c775335518ee7bebd09eec2444e4475 (diff)
downloadpx4-nuttx-f73aebe9714ca9ede07a4b5a234b6c5f85490b4c.tar.gz
px4-nuttx-f73aebe9714ca9ede07a4b5a234b6c5f85490b4c.tar.bz2
px4-nuttx-f73aebe9714ca9ede07a4b5a234b6c5f85490b4c.zip
Networking: Straighten up use if IPv6/IPv4 in TCP connection logic
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/include/net/if.h10
-rw-r--r--nuttx/net/socket/bind.c10
-rw-r--r--nuttx/net/tcp/tcp.h10
-rw-r--r--nuttx/net/tcp/tcp_conn.c593
4 files changed, 474 insertions, 149 deletions
diff --git a/nuttx/include/net/if.h b/nuttx/include/net/if.h
index 56e778048..cd44f495b 100644
--- a/nuttx/include/net/if.h
+++ b/nuttx/include/net/if.h
@@ -74,11 +74,11 @@
#define IFF_CLR_IPv6(f) do { (f) &= ~IFF_IPv6; } while (0)
#define IFF_CLR_NOARP(f) do { (f) &= ~IFF_NOARP; } while (0)
-#define IFF_IS_DOWN(f) ((f) & IFF_DOWN) != 0)
-#define IFF_IS_UP(f) ((f) & IFF_UP) != 0)
-#define IFF_IS_RUNNING(f) ((f) & IFF_RUNNING) != 0)
-#define IFF_IS_IPv6(f) ((f) & IFF_IPv6) != 0)
-#define IFF_IS_NOARP(f) ((f) & IFF_NOARP) != 0)
+#define IFF_IS_DOWN(f) (((f) & IFF_DOWN) != 0)
+#define IFF_IS_UP(f) (((f) & IFF_UP) != 0)
+#define IFF_IS_RUNNING(f) (((f) & IFF_RUNNING) != 0)
+#define IFF_IS_IPv6(f) (((f) & IFF_IPv6) != 0)
+#define IFF_IS_NOARP(f) (((f) & IFF_NOARP) != 0)
#define IFF_SET_IPv4(f) IFF_CLR_IPv6(f)
#define IFF_CLR_IPv4(f) IFF_SET_IPv6(f)
diff --git a/nuttx/net/socket/bind.c b/nuttx/net/socket/bind.c
index 489a8a228..2cde978f9 100644
--- a/nuttx/net/socket/bind.c
+++ b/nuttx/net/socket/bind.c
@@ -146,14 +146,6 @@ int psock_bind(FAR struct socket *psock, const struct sockaddr *addr,
#ifdef CONFIG_NET_PKT
FAR const struct sockaddr_ll *lladdr = (const struct sockaddr_ll *)addr;
#endif
-#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_UDP)
-#ifdef CONFIG_NET_IPv6
- FAR const struct sockaddr_in6 *inaddr = (const struct sockaddr_in6 *)addr;
-#else
- FAR const struct sockaddr_in *inaddr = (const struct sockaddr_in *)addr;
-#endif
-#endif
-
int err;
int ret = OK;
@@ -204,7 +196,7 @@ int psock_bind(FAR struct socket *psock, const struct sockaddr *addr,
#ifdef CONFIG_NET_TCP
case SOCK_STREAM:
- ret = tcp_bind(psock->s_conn, inaddr);
+ ret = tcp_bind(psock->s_conn, addr);
psock->s_flags |= _SF_BOUND;
break;
#endif
diff --git a/nuttx/net/tcp/tcp.h b/nuttx/net/tcp/tcp.h
index 53c7f7257..16a5bbce8 100644
--- a/nuttx/net/tcp/tcp.h
+++ b/nuttx/net/tcp/tcp.h
@@ -269,7 +269,7 @@ extern "C"
/* Defined in tcp_conn.c ****************************************************/
-struct sockaddr; /* Forward reference */
+struct sockaddr; /* Forward reference */
struct tcp_iphdr_s; /* Forward reference */
/****************************************************************************
@@ -366,13 +366,7 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
*
****************************************************************************/
-#ifdef CONFIG_NET_IPv6
-int tcp_bind(FAR struct tcp_conn_s *conn,
- FAR const struct sockaddr_in6 *addr);
-#else
-int tcp_bind(FAR struct tcp_conn_s *conn,
- FAR const struct sockaddr_in *addr);
-#endif
+int tcp_bind(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr);
/****************************************************************************
* Name: tcp_connect
diff --git a/nuttx/net/tcp/tcp_conn.c b/nuttx/net/tcp/tcp_conn.c
index a8283278b..b364e74ee 100644
--- a/nuttx/net/tcp/tcp_conn.c
+++ b/nuttx/net/tcp/tcp_conn.c
@@ -64,8 +64,8 @@
* Pre-processor Definitions
****************************************************************************/
-#define IPv4 ((struct net_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
-#define IPv6 ((struct net_ipv6hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
+#define IPv4BUF ((struct net_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
+#define IPv6BUF ((struct net_ipv6hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
/****************************************************************************
* Private Data
@@ -92,7 +92,7 @@ static uint16_t g_last_tcp_port;
****************************************************************************/
/****************************************************************************
- * Name: tcp_listener
+ * Name: tcp_ipv4_listener
*
* Description:
* Given a local port number (in network byte order), find the TCP
@@ -103,11 +103,9 @@ static uint16_t g_last_tcp_port;
*
****************************************************************************/
-#ifdef CONFIG_NETDEV_MULTINIC
-static FAR struct tcp_conn_s *tcp_listener(in_addr_t ipaddr, uint16_t portno)
-#else
-static FAR struct tcp_conn_s *tcp_listener(uint16_t portno)
-#endif
+#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NETDEV_MULTINIC)
+static inline FAR struct tcp_conn_s *tcp_ipv4_listener(inaddr_t ipaddr,
+ uint16_t portno)
{
FAR struct tcp_conn_s *conn;
int i;
@@ -124,7 +122,6 @@ static FAR struct tcp_conn_s *tcp_listener(uint16_t portno)
if (conn->tcpstateflags != TCP_CLOSED && conn->lport == portno)
{
-#ifdef CONFIG_NETDEV_MULTINIC
/* If there are multiple interface devices, then the local IP
* address of the connection must also match. INADDR_ANY is a
* special case: There can only be instance of a port number
@@ -132,12 +129,7 @@ static FAR struct tcp_conn_s *tcp_listener(uint16_t portno)
*/
if (net_ipv4addr_cmp(conn->u.ipv4.laddr, ipaddr) ||
-#ifdef CONFIG_NET_IPv6
- net_ipv4addr_cmp(conn->u.ipv4.laddr, g_ipv4_allzeroaddr))
-#else
net_ipv4addr_cmp(conn->u.ipv4.laddr, INADDR_ANY))
-#endif
-#endif
{
/* The port number is in use, return the connection */
@@ -148,6 +140,123 @@ static FAR struct tcp_conn_s *tcp_listener(uint16_t portno)
return NULL;
}
+#endif /* CONFIG_NET_IPv4 && CONFIG_NETDEV_MULTINIC */
+
+/****************************************************************************
+ * Name: tcp_ipv6_listener
+ *
+ * Description:
+ * Given a local port number (in network byte order), find the TCP
+ * connection that listens on this this port.
+ *
+ * Primary uses: (1) to determine if a port number is available, (2) to
+ * To identify the socket that will accept new connections on a local port.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_NET_IPv6) && defined(CONFIG_NETDEV_MULTINIC)
+static inline FAR struct tcp_conn_s *tcp_ipv6_ listener(net_ipv6addr_t ipaddr,
+ uint16_t portno)
+{
+ FAR struct tcp_conn_s *conn;
+ int i;
+
+ /* Check if this port number is in use by any active UIP TCP connection */
+
+ for (i = 0; i < CONFIG_NET_TCP_CONNS; i++)
+ {
+ conn = &g_tcp_connections[i];
+
+ /* Check if this connection is open and the local port assignment
+ * matches the requested port number.
+ */
+
+ if (conn->tcpstateflags != TCP_CLOSED && conn->lport == portno)
+ {
+ /* If there are multiple interface devices, then the local IP
+ * address of the connection must also match. INADDR_ANY is a
+ * special case: There can only be instance of a port number
+ * with INADDR_ANY.
+ */
+
+ if (net_ipv6addr_cmp(conn->u.ipv6.laddr, ipaddr) ||
+ net_ipv6addr_cmp(conn->u.ipv6.laddr, g_ipv6_allzeroaddr))
+ {
+ /* The port number is in use, return the connection */
+
+ return conn;
+ }
+ }
+ }
+
+ return NULL;
+}
+#endif /* CONFIG_NET_IPv6 && CONFIG_NETDEV_MULTINIC */
+
+/****************************************************************************
+ * Name: tcp_listener
+ *
+ * Description:
+ * Given a local port number (in network byte order), find the TCP
+ * connection that listens on this this port.
+ *
+ * Primary uses: (1) to determine if a port number is available, (2) to
+ * To identify the socket that will accept new connections on a local port.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NETDEV_MULTINIC
+static FAR struct tcp_conn_s *
+ tcp_listener(uint8_t domain, FAR const union ip_binding_u *ipaddr,
+ uint16_t portno)
+{
+#ifdef CONFIG_NET_IPv4
+#ifdef CONFIG_NET_IPv6
+ if (domain == PF_INET)
+#endif
+ {
+ return tcp_ipv4_listener(ipaddr->ipv4, portno);
+ }
+#endif /* CONFIG_NET_IPv4 */
+
+#ifdef CONFIG_NET_IPv6
+#ifdef CONFIG_NET_IPv4
+ else
+#endif
+ {
+ return tcp_ipv6_listener(ipaddr->ipv6, portno);
+ }
+#endif /* CONFIG_NET_IPv6 */
+}
+
+#else /* CONFIG_NETDEV_MULTINIC */
+
+static FAR struct tcp_conn_s *tcp_listener(uint16_t portno)
+{
+ FAR struct tcp_conn_s *conn;
+ int i;
+
+ /* Check if this port number is in use by any active UIP TCP connection */
+
+ for (i = 0; i < CONFIG_NET_TCP_CONNS; i++)
+ {
+ conn = &g_tcp_connections[i];
+
+ /* Check if this connection is open and the local port assignment
+ * matches the requested port number.
+ */
+
+ if (conn->tcpstateflags != TCP_CLOSED && conn->lport == portno)
+ {
+ /* The port number is in use, return the connection */
+
+ return conn;
+ }
+ }
+
+ return NULL;
+}
+#endif /* CONFIG_NETDEV_MULTINIC */
/****************************************************************************
* Name: tcp_selectport
@@ -175,7 +284,8 @@ static FAR struct tcp_conn_s *tcp_listener(uint16_t portno)
****************************************************************************/
#ifdef CONFIG_NETDEV_MULTINIC
-static int tcp_selectport(in_addr_t ipaddr, uint16_t portno)
+static int tcp_selectport(uint8_t domain, FAR const union ip_addr_u *ipaddr,
+ uint16_t portno)
#else
static int tcp_selectport(uint16_t portno)
#endif
@@ -203,7 +313,7 @@ static int tcp_selectport(uint16_t portno)
}
}
#ifdef CONFIG_NETDEV_MULTINIC
- while (tcp_listener(ipaddr, htons(g_last_tcp_port)));
+ while (tcp_listener(domain, ipaddr, htons(g_last_tcp_port)));
#else
while (tcp_listener(htons(g_last_tcp_port)));
#endif
@@ -215,7 +325,7 @@ static int tcp_selectport(uint16_t portno)
*/
#ifdef CONFIG_NETDEV_MULTINIC
- if (tcp_listener(ipaddr, portno))
+ if (tcp_listener(domain, ipaddr, portno))
#else
if (tcp_listener(portno))
#endif
@@ -232,6 +342,266 @@ static int tcp_selectport(uint16_t portno)
}
/****************************************************************************
+ * Name: tcp_ipv4_active
+ *
+ * Description:
+ * Find a connection structure that is the appropriate
+ * connection to be used with the provided TCP/IP header
+ *
+ * Assumptions:
+ * This function is called from UIP logic at interrupt level
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv4
+static inline FAR struct tcp_conn_s *
+ tcp_ipv4_active(FAR struct net_driver_s *dev, FAR struct tcp_hdr_s *tcp)
+{
+ FAR struct net_iphdr_s *ip = IPv4BUF;
+ FAR struct tcp_conn_s *conn;
+ in_addr_t srcipaddr;
+#ifdef CONFIG_NETDEV_MULTINIC
+ in_addr_t destipaddr;
+#endif
+
+ conn = (FAR struct tcp_conn_s *)g_active_tcp_connections.head;
+ srcipaddr = net_ip4addr_conv32(ip->srcipaddr);
+#ifdef CONFIG_NETDEV_MULTINIC
+ destipaddr = net_ip4addr_conv32(ip->destipaddr);
+#endif
+
+ while (conn)
+ {
+ /* Find an open connection matching the TCP input. The following
+ * checks are performed:
+ *
+ * - The local port number is checked against the destination port
+ * number in the received packet.
+ * - The remote port number is checked if the connection is bound
+ * to a remote port.
+ * - If multiple network interfaces are supported, then the local
+ * IP address is available and we will insist that the
+ * destination IP matches the bound address. If a socket is
+ * bound to INADDRY_ANY, then it should receive all packets
+ * directed to the port.
+ * - Finally, if the connection is bound to a remote IP address,
+ * the source IP address of the packet is checked.
+ *
+ * If all of the above are true then the newly received TCP packet
+ * is destined for this TCP connection.
+ */
+
+ if (conn->tcpstateflags != TCP_CLOSED &&
+ tcp->destport == conn->lport &&
+ tcp->srcport == conn->rport &&
+#ifdef CONFIG_NETDEV_MULTINIC
+ (net_ipv4addr_cmp(conn->u.ipv4.laddr, g_ipv4_allzeroaddr) ||
+ net_ipv4addr_cmp(destipaddr, conn->u.ipv4.laddr)) &&
+#endif
+ net_ipv4addr_cmp(srcipaddr, conn->u.ipv4.raddr))
+ {
+ /* Matching connection found.. break out of the loop and return a
+ * reference to it.
+ */
+
+ break;
+ }
+
+ /* Look at the next active connection */
+
+ conn = (FAR struct tcp_conn_s *)conn->node.flink;
+ }
+
+ return conn;
+}
+#endif /* CONFIG_NET_IPv4 */
+
+/****************************************************************************
+ * Name: tcp_ipv6_active
+ *
+ * Description:
+ * Find a connection structure that is the appropriate
+ * connection to be used with the provided TCP/IP header
+ *
+ * Assumptions:
+ * This function is called from UIP logic at interrupt level
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv6
+static inline FAR struct tcp_conn_s *
+ tcp_ipv6_active(FAR struct net_driver_s *dev, FAR struct tcp_hdr_s *tcp)
+{
+ FAR struct net_ipv6hdr_s *ip = IPv6BUF;
+ FAR struct tcp_conn_s *conn;
+ net_ipv6addr_t *srcipaddr;
+#ifdef CONFIG_NETDEV_MULTINIC
+ net_ipv6addr_t destipaddr;
+#endif
+
+ conn = (FAR struct tcp_conn_s *)g_active_tcp_connections.head;
+ srcipaddr = (net_ipv6addr_t *)ip->srcipaddr;
+#ifdef CONFIG_NETDEV_MULTINIC
+ destipaddr = (net_ipv6addr_t *)ip->destipaddr;
+#endif
+
+ while (conn)
+ {
+ /* Find an open connection matching the TCP input. The following
+ * checks are performed:
+ *
+ * - The local port number is checked against the destination port
+ * number in the received packet.
+ * - The remote port number is checked if the connection is bound
+ * to a remote port.
+ * - If multiple network interfaces are supported, then the local
+ * IP address is available and we will insist that the
+ * destination IP matches the bound address. If a socket is
+ * bound to INADDRY_ANY, then it should receive all packets
+ * directed to the port.
+ * - Finally, if the connection is bound to a remote IP address,
+ * the source IP address of the packet is checked.
+ *
+ * If all of the above are true then the newly received TCP packet
+ * is destined for this TCP connection.
+ */
+
+ if (conn->tcpstateflags != TCP_CLOSED &&
+ tcp->destport == conn->lport &&
+ tcp->srcport == conn->rport &&
+#ifdef CONFIG_NETDEV_MULTINIC
+ (net_ipv6addr_cmp(conn->u.ipv6.laddr, g_ipv6_allzeroaddr) ||
+ net_ipv6addr_cmp(*destipaddr, conn->u.ipv6.laddr)) &&
+#endif
+ net_ipv6addr_cmp(*srcipaddr, conn->u.ipv6.raddr))
+ {
+ /* Matching connection found.. break out of the loop and return a
+ * reference to it.
+ */
+
+ break;
+ }
+
+ /* Look at the next active connection */
+
+ conn = (FAR struct tcp_conn_s *)conn->node.flink;
+ }
+
+ return conn;
+}
+#endif /* CONFIG_NET_IPv6 */
+
+/****************************************************************************
+ * Name: tcp_ipv4_bind
+ *
+ * Description:
+ * This function implements the lower level parts of the standard TCP
+ * bind() operation.
+ *
+ * Return:
+ * 0 on success or -EADDRINUSE on failure
+ *
+ * Assumptions:
+ * This function is called from normal user level code.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv4
+static inline int tcp_ipv4_bind(FAR struct tcp_conn_s *conn,
+ FAR const struct sockaddr_in *addr)
+{
+ net_lock_t flags;
+ int port;
+
+ /* Verify or select a local port and address */
+
+ flags = net_lock();
+
+ /* Verify or select a local port */
+
+#ifdef CONFIG_NETDEV_MULTINIC
+ port = tcp_selectport(PF_INET,
+ (FAR const union ip_addr_u ipaddr *)&addr->sin_addr.s_addr,
+ ntohs(addr->sin_port));
+#else
+ port = tcp_selectport(ntohs(addr->sin_port));
+#endif
+
+ net_unlock(flags);
+
+ if (port < 0)
+ {
+ return port;
+ }
+
+ /* Save the local address in the connection structure. */
+
+ conn->lport = addr->sin_port;
+
+#ifdef CONFIG_NETDEV_MULTINIC
+ net_ipv4addr_copy(conn->u.ipv4.laddr, ipaddr);
+#endif
+
+ return OK;
+}
+#endif /* CONFIG_NET_IPv4 */
+
+/****************************************************************************
+ * Name: tcp_ipv6_bind
+ *
+ * Description:
+ * This function implements the lower level parts of the standard TCP
+ * bind() operation.
+ *
+ * Return:
+ * 0 on success or -EADDRINUSE on failure
+ *
+ * Assumptions:
+ * This function is called from normal user level code.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv6
+static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
+ FAR const struct sockaddr_in6 *addr)
+{
+ net_lock_t flags;
+ int port;
+
+ /* Verify or select a local port and address */
+
+ flags = net_lock();
+
+ /* Verify or select a local port */
+
+#ifdef CONFIG_NETDEV_MULTINIC
+ port = tcp_selectport(PF_INET6,
+ (FAR const union ip_addr_u ipaddr *)addr->sin6_addr.in6_u.u6_addr16,
+ ntohs(addr->sin_port));
+#else
+ port = tcp_selectport(ntohs(addr->sin_port));
+#endif
+
+ net_unlock(flags);
+
+ if (port < 0)
+ {
+ return port;
+ }
+
+ /* Save the local address in the connection structure. */
+
+ conn->lport = addr->sin_port;
+
+#ifdef CONFIG_NETDEV_MULTINIC
+ net_ipv6addr_copy(conn->u.ipv6.laddr, addr->sin6_addr.in6_u.u6_addr16);
+#endif
+
+ return OK;
+}
+#endif /* CONFIG_NET_IPv6 */
+
+/****************************************************************************
* Public Functions
****************************************************************************/
@@ -489,62 +859,23 @@ void tcp_free(FAR struct tcp_conn_s *conn)
FAR struct tcp_conn_s *tcp_active(FAR struct net_driver_s *dev,
FAR struct tcp_hdr_s *tcp)
{
- FAR struct net_iphdr_s *ip = IPv4;
- FAR struct tcp_conn_s *conn;
- in_addr_t srcipaddr;
-#ifdef CONFIG_NETDEV_MULTINIC
- in_addr_t destipaddr;
-#endif
-
- conn = (FAR struct tcp_conn_s *)g_active_tcp_connections.head;
- srcipaddr = net_ip4addr_conv32(ip->srcipaddr);
-#ifdef CONFIG_NETDEV_MULTINIC
- destipaddr = net_ip4addr_conv32(ip->destipaddr);
+#ifdef CONFIG_NET_IPv6
+#ifdef CONFIG_NET_IPv4
+ if (IFF_IS_IPv6(dev->d_flags))
#endif
-
- while (conn)
{
- /* Find an open connection matching the TCP input. The following
- * checks are performed:
- *
- * - The local port number is checked against the destination port
- * number in the received packet.
- * - The remote port number is checked if the connection is bound
- * to a remote port.
- * - If multiple network interfaces are supported, then the local
- * IP address is available and we will insist that the
- * destination IP matches the bound address. If a socket is
- * bound to INADDRY_ANY, then it should receive all packets
- * directed to the port.
- * - Finally, if the connection is bound to a remote IP address,
- * the source IP address of the packet is checked.
- *
- * If all of the above are true then the newly received TCP packet
- * is destined for this TCP connection.
- */
+ return tcp_ipv6_active(dev, tcp);
+ }
+#endif /* CONFIG_NET_IPv6 */
- if (conn->tcpstateflags != TCP_CLOSED &&
- tcp->destport == conn->lport &&
- tcp->srcport == conn->rport &&
-#ifdef CONFIG_NETDEV_MULTINIC
- (net_ipv4addr_cmp(conn->u.ipv4.laddr, g_ipv4_allzeroaddr) ||
- net_ipv4addr_cmp(destipaddr, conn->u.ipv4.laddr)) &&
+#ifdef CONFIG_NET_IPv4
+#ifdef CONFIG_NET_IPv6
+ else
#endif
- net_ipv4addr_cmp(srcipaddr, conn->u.ipv4.raddr))
- {
- /* Matching connection found.. break out of the loop and return a
- * reference to it.
- */
-
- break;
- }
-
- /* Look at the next active connection */
-
- conn = (FAR struct tcp_conn_s *)conn->node.flink;
+ {
+ return tcp_ipv4_active(dev, tcp);
}
-
- return conn;
+#endif /* CONFIG_NET_IPv4 */
}
/****************************************************************************
@@ -587,14 +918,23 @@ FAR struct tcp_conn_s *tcp_nextconn(FAR struct tcp_conn_s *conn)
FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
FAR struct tcp_hdr_s *tcp)
{
- FAR struct net_iphdr_s *ip = IPv4;
FAR struct tcp_conn_s *conn;
+ uint8_t domain;
-#ifdef CONFIG_NET_IPv4
- conn = tcp_alloc(PF_INET);
-#else
- conn = tcp_alloc(PF_INET6);
+ /* Get the appropriate IP domain */
+
+#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv4)
+ bool ipv6 = IFF_IS_IPv6(dev->d_flags);
+ domain = ipv6 ? PF_INET6 : PF_INET;
+#elif defined(CONFIG_NET_IPv4)
+ domain = PF_INET;
+#else /* defined(CONFIG_NET_IPv6) */
+ domain = PF_INET6;
#endif
+
+ /* Allocate the connection structure */
+
+ conn = tcp_alloc(domain);
if (conn)
{
/* Fill in the necessary fields for the new connection. */
@@ -606,19 +946,47 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
conn->nrtx = 0;
conn->lport = tcp->destport;
conn->rport = tcp->srcport;
- conn->mss = TCP_IPv4_INITIAL_MSS(dev);
- net_ipv4addr_copy(conn->u.ipv4.raddr, net_ip4addr_conv32(ip->srcipaddr));
+
+#ifdef CONFIG_NET_IPv6
+#ifdef CONFIG_NET_IPv4
+ if (ipv6)
+#endif
+ {
+ FAR struct net_ipv6hdr_s *ip = IPv6BUF;
+
+ conn->mss = TCP_IPv6_INITIAL_MSS(dev);
+ net_ipv6addr_copy(conn->u.ipv6.raddr, ip->srcipaddr);
+#ifdef CONFIG_NETDEV_MULTINIC
+ net_ipv6addr_copy(conn->u.ipv6.laddr, ip->destipaddr);
+#endif
+ }
+#endif /* CONFIG_NET_IPv6 */
+
+#ifdef CONFIG_NET_IPv4
+#ifdef CONFIG_NET_IPv6
+ else
+#endif
+ {
+ FAR struct net_iphdr_s *ip = IPv4BUF;
+
+ conn->mss = TCP_IPv4_INITIAL_MSS(dev);
+ net_ipv4addr_copy(conn->u.ipv4.raddr,
+ net_ip4addr_conv32(ip->srcipaddr));
#ifdef CONFIG_NETDEV_MULTINIC
- net_ipv4addr_copy(conn->u.ipv4.laddr, net_ip4addr_conv32(ip->destipaddr));
+ net_ipv4addr_copy(conn->u.ipv4.laddr,
+ net_ip4addr_conv32(ip->destipaddr));
#endif
+ }
+#endif /* CONFIG_NET_IPv4 */
+
conn->tcpstateflags = TCP_SYN_RCVD;
tcp_initsequence(conn->sndseq);
- conn->unacked = 1;
+ conn->unacked = 1;
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
- conn->expired = 0;
- conn->isn = 0;
- conn->sent = 0;
+ conn->expired = 0;
+ conn->isn = 0;
+ conn->sent = 0;
#endif
/* rcvseq should be the seqno from the incoming packet + 1. */
@@ -663,60 +1031,31 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
*
****************************************************************************/
-#ifdef CONFIG_NET_IPv6
-int tcp_bind(FAR struct tcp_conn_s *conn,
- FAR const struct sockaddr_in6 *addr)
-#else
-int tcp_bind(FAR struct tcp_conn_s *conn,
- FAR const struct sockaddr_in *addr)
-#endif
+int tcp_bind(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
{
- net_lock_t flags;
- int port;
-#ifdef CONFIG_NETDEV_MULTINIC
- in_addr_t ipaddr;
-#endif
-
- /* Verify or select a local port and address */
-
- flags = net_lock();
-
-#ifdef CONFIG_NETDEV_MULTINIC
+#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
- /* Get the IPv6 address that we are binding to */
-
- ipaddr = addr->sin6_addr.in6_u.u6_addr16;
-
-#else
- /* Get the IPv4 address that we are binding to */
-
- ipaddr = addr->sin_addr.s_addr;
-
-#endif
-
- port = tcp_selectport(ipaddr, ntohs(addr->sin_port));
-#else
- /* Verify or select a local port */
-
- port = tcp_selectport(ntohs(addr->sin_port));
+ if (conn->domain == PF_INET)
#endif
-
- net_unlock(flags);
-
- if (port < 0)
{
- return port;
- }
-
- /* Save the local address in the connection structure. */
+ FAR const struct sockaddr_in *inaddr =
+ (FAR const struct sockaddr_in *)addr;
- conn->lport = addr->sin_port;
+ return tcp_ipv4_bind(conn, inaddr);
+ }
+#endif /* CONFIG_NET_IPv4 */
-#ifdef CONFIG_NETDEV_MULTINIC
- net_ipv4addr_copy(conn->u.ipv4.laddr, ipaddr);
+#ifdef CONFIG_NET_IPv6
+#ifdef CONFIG_NET_IPv4
+ else
#endif
+ {
+ FAR const struct sockaddr_in6 *inaddr =
+ (FAR const struct sockaddr_in6 *)addr;
- return OK;
+ return tcp_ipv6_bind(conn, inaddr);
+ }
+#endif /* CONFIG_NET_IPv6 */
}
/****************************************************************************
@@ -761,7 +1100,7 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
flags = net_lock();
#ifdef CONFIG_NETDEV_MULTINIC
- port = tcp_selectport(conn->u.ipv4.laddr, ntohs(conn->lport));
+ port = tcp_selectport(conn->domain, &conn->u, ntohs(conn->lport));
#else
port = tcp_selectport(ntohs(conn->lport));
#endif