summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Sidrane <david_s5@nscdg.com>2015-01-16 06:54:11 -1000
committerDavid Sidrane <david_s5@nscdg.com>2015-01-16 06:54:11 -1000
commit0f646fd2f50d1726615c47580ae9dc6832e26076 (patch)
treec04cb7c3574d0dca6192d7dea05c58990ab5816f
parent118398f627d6b4219f8c33cda8e97ba01dddec22 (diff)
parent8c1935a004d78bfcdd80638c38fcaa07152f6815 (diff)
downloadpx4-nuttx-0f646fd2f50d1726615c47580ae9dc6832e26076.tar.gz
px4-nuttx-0f646fd2f50d1726615c47580ae9dc6832e26076.tar.bz2
px4-nuttx-0f646fd2f50d1726615c47580ae9dc6832e26076.zip
Merge remote-tracking branch 'upstream/master' into upstream
-rwxr-xr-xnuttx/ChangeLog11
-rw-r--r--nuttx/drivers/net/cs89x0.c65
-rw-r--r--nuttx/drivers/net/dm90x0.c60
-rw-r--r--nuttx/drivers/net/e1000.c60
-rw-r--r--nuttx/drivers/net/enc28j60.c63
-rw-r--r--nuttx/drivers/net/encx24j600.c71
-rw-r--r--nuttx/drivers/net/skeleton.c64
-rw-r--r--nuttx/drivers/net/vnet.c60
-rw-r--r--nuttx/include/nuttx/net/icmpv6.h24
-rw-r--r--nuttx/include/nuttx/net/igmp.h75
-rw-r--r--nuttx/include/nuttx/net/ip.h67
-rw-r--r--nuttx/include/nuttx/net/net.h3
-rw-r--r--nuttx/include/nuttx/net/netconfig.h27
-rw-r--r--nuttx/include/nuttx/net/netdev.h26
-rw-r--r--nuttx/include/nuttx/net/tcp.h87
-rw-r--r--nuttx/include/nuttx/net/udp.h78
-rw-r--r--nuttx/libc/libc.csv4
-rw-r--r--nuttx/libc/net/lib_inetntoa.c7
-rw-r--r--nuttx/libc/net/lib_inetntop.c170
-rw-r--r--nuttx/libc/net/lib_inetpton.c176
-rw-r--r--nuttx/net/arp/arp_arpin.c6
-rw-r--r--nuttx/net/arp/arp_format.c4
-rw-r--r--nuttx/net/arp/arp_ipin.c2
-rw-r--r--nuttx/net/arp/arp_out.c12
-rw-r--r--nuttx/net/arp/arp_send.c14
-rw-r--r--nuttx/net/arp/arp_table.c4
-rw-r--r--nuttx/net/devif/ipv4_input.c8
-rw-r--r--nuttx/net/devif/ipv6_input.c6
-rw-r--r--nuttx/net/icmp/icmp.h2
-rw-r--r--nuttx/net/icmp/icmp_input.c4
-rw-r--r--nuttx/net/icmp/icmp_ping.c24
-rw-r--r--nuttx/net/icmp/icmp_send.c6
-rw-r--r--nuttx/net/icmpv6/icmpv6.h2
-rw-r--r--nuttx/net/icmpv6/icmpv6_input.c2
-rw-r--r--nuttx/net/icmpv6/icmpv6_ping.c22
-rw-r--r--nuttx/net/icmpv6/icmpv6_send.c6
-rw-r--r--nuttx/net/ipv6/ipv6.h6
-rw-r--r--nuttx/net/ipv6/ipv6_neighbor.c16
-rw-r--r--nuttx/net/netdev/netdev.h17
-rw-r--r--nuttx/net/netdev/netdev_findbyaddr.c199
-rw-r--r--nuttx/net/netdev/netdev_ioctl.c36
-rw-r--r--nuttx/net/netdev/netdev_rxnotify.c4
-rw-r--r--nuttx/net/netdev/netdev_txnotify.c4
-rw-r--r--nuttx/net/pkt/pkt_poll.c4
-rw-r--r--nuttx/net/socket/getsockname.c295
-rw-r--r--nuttx/net/socket/recvfrom.c9
-rw-r--r--nuttx/net/socket/socket.c131
-rw-r--r--nuttx/net/tcp/tcp.h107
-rw-r--r--nuttx/net/tcp/tcp_appsend.c8
-rw-r--r--nuttx/net/tcp/tcp_conn.c62
-rw-r--r--nuttx/net/tcp/tcp_input.c188
-rw-r--r--nuttx/net/tcp/tcp_poll.c16
-rw-r--r--nuttx/net/tcp/tcp_send.c4
-rw-r--r--nuttx/net/tcp/tcp_send_buffered.c6
-rw-r--r--nuttx/net/tcp/tcp_timer.c8
-rw-r--r--nuttx/net/udp/udp.h52
-rw-r--r--nuttx/net/udp/udp_conn.c22
-rw-r--r--nuttx/net/udp/udp_input.c97
-rw-r--r--nuttx/net/udp/udp_poll.c16
-rw-r--r--nuttx/net/udp/udp_send.c2
-rw-r--r--nuttx/net/utils/Make.defs8
-rw-r--r--nuttx/net/utils/net_ipv6_maskcmp.c111
62 files changed, 2039 insertions, 711 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index f4cedd92a..80c05fdfc 100755
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -9416,5 +9416,12 @@
net/devif/devif_input.c to ipv4_input.c, remove all IPv6-specific
logic, and (4) xplit IPv4 header structure out as net_ipv4hdr_s from
net_iphdr_s (2015-01-15).
- * arch/: All Ethernet drivers: Call ipv6_input() if IPv6 is enabled
- and an IPv6 packet is received (2015-01-15).
+ * arch/ and drivers/net: All Ethernet drivers: Call ipv6_input() if
+ IPv6 is enabled and an IPv6 packet is received (2015-01-15).
+ * net/devif, net/tcp, net/ucp, include/nuttx/net: Seperate tcp_input()
+ and udp_input() into seprate functions tcp_ipv4_input(),
+ tcp_ipv6_input(), udp_ipv4_input(), and upd_ipv6_input() than can deal
+ will the data offsets caused by the differing sizes of the IP header
+ (2015-01-15).
+ * net/utils/net_ipv6_maskcmp.c: Add missing implementation of
+ net_ipv6_maskcmp() (2015-01-15).
diff --git a/nuttx/drivers/net/cs89x0.c b/nuttx/drivers/net/cs89x0.c
index d779d40f3..16301cdf1 100644
--- a/nuttx/drivers/net/cs89x0.c
+++ b/nuttx/drivers/net/cs89x0.c
@@ -430,14 +430,18 @@ static void cs89x0_receive(struct cs89x0_driver_s *cs89x0, uint16_t isq)
#ifdef CONFIG_C89x0_STATISTICS
cd89x0->cs_stats.rx_packets++;
#endif
+
/* We only accept IP packets of the configured type and ARP packets */
-#ifdef CONFIG_NET_IPv6
- if (BUF->type == HTONS(ETHTYPE_IP6))
-#else
+#ifdef CONFIG_NET_IPv4
if (BUF->type == HTONS(ETHTYPE_IP))
-#endif
{
+ nllvdbg("IPv4 frame\n");
+
+ /* Handle ARP on input then give the IPv4 packet to the network
+ * layer
+ */
+
arp_ipin(&cs89x0->cs_dev);
ipv4_input(&cs89x0->cs_dev);
@@ -447,11 +451,55 @@ static void cs89x0_receive(struct cs89x0_driver_s *cs89x0, uint16_t isq)
if (cs89x0->cs_dev.d_len > 0)
{
- arp_out(&cs89x0->cs_dev);
+ /* Update the Ethernet header with the correct MAC address */
+
+#ifdef CONFIG_NET_IPv6
+ if (BUF->type == HTONS(ETHTYPE_IP))
+#endif
+ {
+ arp_out(&cs89x0->cs_dev);
+ }
+
+ /* And send the packet */
+
+ cs89x0_transmit(cs89x0);
+ }
+ }
+ else
+#endif
+#ifdef CONFIG_NET_IPv6
+ if (BUF->type == HTONS(ETHTYPE_IP6))
+ {
+ nllvdbg("Iv6 frame\n");
+
+ /* Give the IPv6 packet to the network layer */
+
+ ipv6_input(&cs89x0->cs_dev);
+
+ /* If the above function invocation resulted in data that should be
+ * sent out on the network, the field d_len will set to a value > 0.
+ */
+
+ if (cs89x0->cs_dev.d_len > 0)
+ {
+#ifdef CONFIG_NET_IPv4
+ /* Update the Ethernet header with the correct MAC address */
+
+ if (BUF->type == HTONS(ETHTYPE_IP))
+ {
+ arp_out(&cs89x0->cs_dev);
+ }
+#endif
+
+ /* And send the packet */
+
cs89x0_transmit(cs89x0);
}
}
- else if (BUF->type == htons(ETHTYPE_ARP))
+ else
+#endif
+#ifdef CONFIG_NET_ARP
+ if (BUF->type == htons(ETHTYPE_ARP))
{
arp_arpin(&cs89x0->cs_dev);
@@ -464,6 +512,11 @@ static void cs89x0_receive(struct cs89x0_driver_s *cs89x0, uint16_t isq)
cs89x0_transmit(cs89x0);
}
}
+ else
+#endif
+ {
+ nllvdbg("Unrecognized packet type %02x\n", BUF->type);
+ }
}
/****************************************************************************
diff --git a/nuttx/drivers/net/dm90x0.c b/nuttx/drivers/net/dm90x0.c
index f911a408f..1b2afdbb3 100644
--- a/nuttx/drivers/net/dm90x0.c
+++ b/nuttx/drivers/net/dm90x0.c
@@ -980,12 +980,15 @@ static void dm9x_receive(struct dm9x_driver_s *dm9x)
/* We only accept IP packets of the configured type and ARP packets */
-#ifdef CONFIG_NET_IPv6
- if (BUF->type == HTONS(ETHTYPE_IP6))
-#else
+#ifdef CONFIG_NET_IPv4
if (BUF->type == HTONS(ETHTYPE_IP))
-#endif
{
+ nllvdbg("IPv4 frame\n");
+
+ /* Handle ARP on input then give the IPv4 packet to the network
+ * layer
+ */
+
arp_ipin(&dm9x->dm_dev);
ipv4_input(&dm9x->dm_dev);
@@ -995,11 +998,55 @@ static void dm9x_receive(struct dm9x_driver_s *dm9x)
if (dm9x->dm_dev.d_len > 0)
{
- arp_out(&dm9x->dm_dev);
+ /* Update the Ethernet header with the correct MAC address */
+
+#ifdef CONFIG_NET_IPv6
+ if (BUF->type == HTONS(ETHTYPE_IP))
+#endif
+ {
+ arp_out(&dm9x->dm_dev);
+ }
+
+ /* And send the packet */
+
dm9x_transmit(dm9x);
}
}
- else if (BUF->type == htons(ETHTYPE_ARP))
+ else
+#endif
+#ifdef CONFIG_NET_IPv6
+ if (BUF->type == HTONS(ETHTYPE_IP6))
+ {
+ nllvdbg("Iv6 frame\n");
+
+ /* Give the IPv6 packet to the network layer */
+
+ ipv6_input(&dm9x->dm_dev);
+
+ /* If the above function invocation resulted in data that should be
+ * sent out on the network, the field d_len will set to a value > 0.
+ */
+
+ if (dm9x->dm_dev.d_len > 0)
+ {
+#ifdef CONFIG_NET_IPv4
+ /* Update the Ethernet header with the correct MAC address */
+
+ if (BUF->type == HTONS(ETHTYPE_IP))
+ {
+ arp_out(&dm9x->dm_dev);
+ }
+#endif
+
+ /* And send the packet */
+
+ dm9x_transmit(dm9x);
+ }
+ }
+ else
+#endif
+#ifdef CONFIG_NET_ARP
+ if (BUF->type == htons(ETHTYPE_ARP))
{
arp_arpin(&dm9x->dm_dev);
@@ -1012,6 +1059,7 @@ static void dm9x_receive(struct dm9x_driver_s *dm9x)
dm9x_transmit(dm9x);
}
}
+#endif
}
#if defined(CONFIG_DM9X_STATS)
diff --git a/nuttx/drivers/net/e1000.c b/nuttx/drivers/net/e1000.c
index 017df480d..604bcaf51 100644
--- a/nuttx/drivers/net/e1000.c
+++ b/nuttx/drivers/net/e1000.c
@@ -567,12 +567,15 @@ static void e1000_receive(struct e1000_dev *e1000)
/* We only accept IP packets of the configured type and ARP packets */
-#ifdef CONFIG_NET_IPv6
- if (BUF->type == HTONS(ETHTYPE_IP6))
-#else
+#ifdef CONFIG_NET_IPv4
if (BUF->type == HTONS(ETHTYPE_IP))
-#endif
{
+ nllvdbg("IPv4 frame\n");
+
+ /* Handle ARP on input then give the IPv4 packet to the network
+ * layer
+ */
+
arp_ipin(&e1000->netdev);
ipv4_input(&e1000->netdev);
@@ -582,11 +585,55 @@ static void e1000_receive(struct e1000_dev *e1000)
if (e1000->netdev.d_len > 0)
{
- arp_out(&e1000->netdev);
+ /* Update the Ethernet header with the correct MAC address */
+
+#ifdef CONFIG_NET_IPv6
+ if (BUF->type == HTONS(ETHTYPE_IP))
+#endif
+ {
+ arp_out(&e1000->netdev);
+ }
+
+ /* And send the packet */
+
e1000_transmit(e1000);
}
}
- else if (BUF->type == htons(ETHTYPE_ARP))
+ else
+#endif
+#ifdef CONFIG_NET_IPv6
+ if (BUF->type == HTONS(ETHTYPE_IP6))
+ {
+ nllvdbg("Iv6 frame\n");
+
+ /* Give the IPv6 packet to the network layer */
+
+ ipv6_input(&e1000->netdev);
+
+ /* If the above function invocation resulted in data that should be
+ * sent out on the network, the field d_len will set to a value > 0.
+ */
+
+ if (e1000->netdev.d_len > 0)
+ {
+#ifdef CONFIG_NET_IPv4
+ /* Update the Ethernet header with the correct MAC address */
+
+ if (BUF->type == HTONS(ETHTYPE_IP))
+ {
+ arp_out(&e1000->netdev);
+ }
+#endif
+
+ /* And send the packet */
+
+ e1000_transmit(e1000);
+ }
+ }
+ else
+#endif
+#ifdef CONFIG_NET_ARP
+ if (BUF->type == htons(ETHTYPE_ARP))
{
arp_arpin(&e1000->netdev);
@@ -598,6 +645,7 @@ static void e1000_receive(struct e1000_dev *e1000)
{
e1000_transmit(e1000);
}
+#endif
}
next:
diff --git a/nuttx/drivers/net/enc28j60.c b/nuttx/drivers/net/enc28j60.c
index 547a148f6..defefb81c 100644
--- a/nuttx/drivers/net/enc28j60.c
+++ b/nuttx/drivers/net/enc28j60.c
@@ -1374,15 +1374,17 @@ static void enc_rxerif(FAR struct enc_driver_s *priv)
static void enc_rxdispatch(FAR struct enc_driver_s *priv)
{
- /* We only accept IP packets of the configured type and ARP packets */
+ /* We only accept IP packets of the configured type and ARP packets */
-#ifdef CONFIG_NET_IPv6
- if (BUF->type == HTONS(ETHTYPE_IP6))
-#else
+#ifdef CONFIG_NET_IPv4
if (BUF->type == HTONS(ETHTYPE_IP))
-#endif
{
- nllvdbg("IP packet received (%02x)\n", BUF->type);
+ nllvdbg("IPv4 frame\n");
+
+ /* Handle ARP on input then give the IPv4 packet to the network
+ * layer
+ */
+
arp_ipin(&priv->dev);
ipv4_input(&priv->dev);
@@ -1392,11 +1394,55 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv)
if (priv->dev.d_len > 0)
{
- arp_out(&priv->dev);
+ /* Update the Ethernet header with the correct MAC address */
+
+#ifdef CONFIG_NET_IPv6
+ if (BUF->type == HTONS(ETHTYPE_IP))
+#endif
+ {
+ arp_out(&priv->dev);
+ }
+
+ /* And send the packet */
+
+ enc_transmit(priv);
+ }
+ }
+ else
+#endif
+#ifdef CONFIG_NET_IPv6
+ if (BUF->type == HTONS(ETHTYPE_IP6))
+ {
+ nllvdbg("Iv6 frame\n");
+
+ /* Give the IPv6 packet to the network layer */
+
+ ipv6_input(&priv->dev);
+
+ /* If the above function invocation resulted in data that should be
+ * sent out on the network, the field d_len will set to a value > 0.
+ */
+
+ if (priv->dev.d_len > 0)
+ {
+#ifdef CONFIG_NET_IPv4
+ /* Update the Ethernet header with the correct MAC address */
+
+ if (BUF->type == HTONS(ETHTYPE_IP))
+ {
+ arp_out(&priv->dev);
+ }
+#endif
+
+ /* And send the packet */
+
enc_transmit(priv);
}
}
- else if (BUF->type == htons(ETHTYPE_ARP))
+ else
+#endif
+#ifdef CONFIG_NET_ARP
+ if (BUF->type == htons(ETHTYPE_ARP))
{
nllvdbg("ARP packet received (%02x)\n", BUF->type);
arp_arpin(&priv->dev);
@@ -1411,6 +1457,7 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv)
}
}
else
+#endif
{
nlldbg("Unsupported packet type dropped (%02x)\n", htons(BUF->type));
}
diff --git a/nuttx/drivers/net/encx24j600.c b/nuttx/drivers/net/encx24j600.c
index ae7d141d5..035184cef 100644
--- a/nuttx/drivers/net/encx24j600.c
+++ b/nuttx/drivers/net/encx24j600.c
@@ -1495,20 +1495,21 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv)
/* We only accept IP packets of the configured type and ARP packets */
-#ifdef CONFIG_NET_IPv6
- if (BUF->type == HTONS(ETHTYPE_IP6))
-#else
+#ifdef CONFIG_NET_IPv4
if (BUF->type == HTONS(ETHTYPE_IP))
-#endif
{
- nllvdbg("Try to process IP packet (%02x)\n", BUF->type);
+ nllvdbg("IPv4 frame\n");
+
+ /* Handle ARP on input then give the IPv4 packet to the network
+ * layer
+ */
arp_ipin(&priv->dev);
ret = ipv4_input(&priv->dev);
if (ret == OK || (clock_systimer() - descr->ts) > ENC_RXTIMEOUT)
{
- /* If packet has been sucessfully processed or has timed out,
+ /* If packet has been successfully processed or has timed out,
* free it.
*/
@@ -1521,11 +1522,64 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv)
if (priv->dev.d_len > 0)
{
- arp_out(&priv->dev);
+ /* Update the Ethernet header with the correct MAC address */
+
+#ifdef CONFIG_NET_IPv6
+ if (BUF->type == HTONS(ETHTYPE_IP))
+#endif
+ {
+ arp_out(&priv->dev);
+ }
+
+ /* And send the packet */
+
enc_txenqueue(priv);
}
}
- else if (BUF->type == htons(ETHTYPE_ARP))
+ else
+#endif
+#ifdef CONFIG_NET_IPv6
+ if (BUF->type == HTONS(ETHTYPE_IP6))
+ {
+ nllvdbg("Iv6 frame\n");
+
+ /* Give the IPv6 packet to the network layer */
+
+ ret = ipv6_input(&priv->dev);
+
+ if (ret == OK || (clock_systimer() - descr->ts) > ENC_RXTIMEOUT)
+ {
+ /* If packet has been successfully processed or has timed out,
+ * free it.
+ */
+
+ enc_rxrmpkt(priv, descr);
+ }
+
+ /* If the above function invocation resulted in data that should be
+ * sent out on the network, the field d_len will set to a value > 0.
+ */
+
+ if (priv->dev.d_len > 0)
+ {
+#ifdef CONFIG_NET_IPv4
+ /* Update the Ethernet header with the correct MAC address */
+
+ if (BUF->type == HTONS(ETHTYPE_IP))
+ {
+ arp_out(&priv->dev);
+ }
+#endif
+
+ /* And send the packet */
+
+ enc_txenqueue(priv);
+ }
+ }
+ else
+#endif
+#ifdef CONFIG_NET_ARP
+ if (BUF->type == htons(ETHTYPE_ARP))
{
nllvdbg("ARP packet received (%02x)\n", BUF->type);
arp_arpin(&priv->dev);
@@ -1544,6 +1598,7 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv)
}
}
else
+#endif
{
/* free unsupported packet */
diff --git a/nuttx/drivers/net/skeleton.c b/nuttx/drivers/net/skeleton.c
index e61fe6111..1a932c056 100644
--- a/nuttx/drivers/net/skeleton.c
+++ b/nuttx/drivers/net/skeleton.c
@@ -286,12 +286,15 @@ static void skel_receive(FAR struct skel_driver_s *skel)
/* We only accept IP packets of the configured type and ARP packets */
-#ifdef CONFIG_NET_IPv6
- if (BUF->type == HTONS(ETHTYPE_IP6))
-#else
+#ifdef CONFIG_NET_IPv4
if (BUF->type == HTONS(ETHTYPE_IP))
-#endif
{
+ nllvdbg("IPv4 frame\n");
+
+ /* Handle ARP on input then give the IPv4 packet to the network
+ * layer
+ */
+
arp_ipin(&skel->sk_dev);
ipv4_input(&skel->sk_dev);
@@ -300,12 +303,56 @@ static void skel_receive(FAR struct skel_driver_s *skel)
*/
if (skel->sk_dev.d_len > 0)
+ {
+ /* Update the Ethernet header with the correct MAC address */
+
+#ifdef CONFIG_NET_IPv6
+ if (BUF->type == HTONS(ETHTYPE_IP))
+#endif
+ {
+ arp_out(&skel->sk_dev);
+ }
+
+ /* And send the packet */
+
+ skel_transmit(skel);
+ }
+ }
+ else
+#endif
+#ifdef CONFIG_NET_IPv6
+ if (BUF->type == HTONS(ETHTYPE_IP6))
+ {
+ nllvdbg("Iv6 frame\n");
+
+ /* Give the IPv6 packet to the network layer */
+
+ ipv6_input(&skel->sk_dev);
+
+ /* If the above function invocation resulted in data that should be
+ * sent out on the network, the field d_len will set to a value > 0.
+ */
+
+ if (skel->sk_dev.d_len > 0)
{
- arp_out(&skel->sk_dev);
- skel_transmit(skel);
- }
+#ifdef CONFIG_NET_IPv4
+ /* Update the Ethernet header with the correct MAC address */
+
+ if (BUF->type == HTONS(ETHTYPE_IP))
+ {
+ arp_out(&skel->sk_dev);
+ }
+#endif
+
+ /* And send the packet */
+
+ skel_transmit(skel);
+ }
}
- else if (BUF->type == htons(ETHTYPE_ARP))
+ else
+#endif
+#ifdef CONFIG_NET_ARP
+ if (BUF->type == htons(ETHTYPE_ARP))
{
arp_arpin(&skel->sk_dev);
@@ -318,6 +365,7 @@ static void skel_receive(FAR struct skel_driver_s *skel)
skel_transmit(skel);
}
}
+#endif
}
while (); /* While there are more packets to be processed */
}
diff --git a/nuttx/drivers/net/vnet.c b/nuttx/drivers/net/vnet.c
index 5190099a9..02f348d74 100644
--- a/nuttx/drivers/net/vnet.c
+++ b/nuttx/drivers/net/vnet.c
@@ -303,12 +303,15 @@ void rtos_vnet_recv(struct rgmp_vnet *rgmp_vnet, char *data, int len)
/* We only accept IP packets of the configured type and ARP packets */
-#ifdef CONFIG_NET_IPv6
- if (BUF->type == HTONS(ETHTYPE_IP6))
-#else
+#ifdef CONFIG_NET_IPv4
if (BUF->type == HTONS(ETHTYPE_IP))
-#endif
{
+ nllvdbg("IPv4 frame\n");
+
+ /* Handle ARP on input then give the IPv4 packet to the network
+ * layer
+ */
+
arp_ipin(&vnet->sk_dev);
ipv4_input(&vnet->sk_dev);
@@ -318,11 +321,55 @@ void rtos_vnet_recv(struct rgmp_vnet *rgmp_vnet, char *data, int len)
if (vnet->sk_dev.d_len > 0)
{
- arp_out(&vnet->sk_dev);
+ /* Update the Ethernet header with the correct MAC address */
+
+#ifdef CONFIG_NET_IPv6
+ if (BUF->type == HTONS(ETHTYPE_IP))
+#endif
+ {
+ arp_out(&vnet->sk_dev);
+ }
+
+ /* And send the packet */
+
vnet_transmit(vnet);
}
}
- else if (BUF->type == htons(ETHTYPE_ARP))
+ else
+#endif
+#ifdef CONFIG_NET_IPv6
+ if (BUF->type == HTONS(ETHTYPE_IP6))
+ {
+ nllvdbg("Iv6 frame\n");
+
+ /* Give the IPv6 packet to the network layer */
+
+ ipv6_input(&vnet->sk_dev);
+
+ /* If the above function invocation resulted in data that should be
+ * sent out on the network, the field d_len will set to a value > 0.
+ */
+
+ if (vnet->sk_dev.d_len > 0)
+ {
+#ifdef CONFIG_NET_IPv4
+ /* Update the Ethernet header with the correct MAC address */
+
+ if (BUF->type == HTONS(ETHTYPE_IP))
+ {
+ arp_out(&vnet->sk_dev);
+ }
+#endif
+
+ /* And send the packet */
+
+ vnet_transmit(vnet);
+ }
+ }
+ else
+#endif
+#ifdef CONFIG_NET_ARP
+ if (BUF->type == htons(ETHTYPE_ARP))
{
arp_arpin(&vnet->sk_dev);
@@ -335,6 +382,7 @@ void rtos_vnet_recv(struct rgmp_vnet *rgmp_vnet, char *data, int len)
vnet_transmit(vnet);
}
}
+#endif
}
while (0); /* While there are more packets to be processed */
}
diff --git a/nuttx/include/nuttx/net/icmpv6.h b/nuttx/include/nuttx/net/icmpv6.h
index d0b1e9f66..279498270 100644
--- a/nuttx/include/nuttx/net/icmpv6.h
+++ b/nuttx/include/nuttx/net/icmpv6.h
@@ -114,20 +114,20 @@ struct icmpv6_iphdr_s
{
/* IPv6 Ip header */
- uint8_t vtc; /* Bits 0-3: version, bits 4-7: traffic class (MS) */
- uint8_t tcf; /* Bits 0-3: traffic class (LS), bits 4-7: flow label (MS) */
- uint16_t flow; /* 16-bit flow label (LS) */
- uint8_t len[2]; /* 16-bit Payload length */
- uint8_t proto; /* 8-bit Next header (same as IPv4 protocol field) */
- uint8_t ttl; /* 8-bit Hop limit (like IPv4 TTL field) */
- net_ip6addr_t srcipaddr; /* 128-bit Source address */
- net_ip6addr_t destipaddr; /* 128-bit Destination address */
+ uint8_t vtc; /* Bits 0-3: version, bits 4-7: traffic class (MS) */
+ uint8_t tcf; /* Bits 0-3: traffic class (LS), bits 4-7: flow label (MS) */
+ uint16_t flow; /* 16-bit flow label (LS) */
+ uint8_t len[2]; /* 16-bit Payload length */
+ uint8_t proto; /* 8-bit Next header (same as IPv4 protocol field) */
+ uint8_t ttl; /* 8-bit Hop limit (like IPv4 TTL field) */
+ net_ipv6addr_t srcipaddr; /* 128-bit Source address */
+ net_ipv6addr_t destipaddr; /* 128-bit Destination address */
/* ICMPv6 header */
- uint8_t type; /* Defines the format of the ICMP message */
- uint8_t icode; /* Further qualifies the ICMP messsage */
- uint16_t icmpv6chksum; /* Checksum of ICMP header and data */
+ uint8_t type; /* Defines the format of the ICMP message */
+ uint8_t icode; /* Further qualifies the ICMP messages */
+ uint16_t icmpv6chksum; /* Checksum of ICMP header and data */
/* Data following the ICMP header contains the data specific to the
* message type indicated by the Type and Code fields.
@@ -200,7 +200,7 @@ extern "C"
*
****************************************************************************/
-int icmpv6_ping(net_ipaddr_t addr, uint16_t id, uint16_t seqno,
+int icmpv6_ping(net_ipv6addr_t addr, uint16_t id, uint16_t seqno,
uint16_t datalen, int dsecs);
#undef EXTERN
diff --git a/nuttx/include/nuttx/net/igmp.h b/nuttx/include/nuttx/net/igmp.h
index a6a69c335..68028daee 100644
--- a/nuttx/include/nuttx/net/igmp.h
+++ b/nuttx/include/nuttx/net/igmp.h
@@ -125,37 +125,57 @@
* (0x11); in other messages it is set to 0 and ignored by the receiver.
*/
+#ifdef CONFIG_NET_IPv4
struct igmp_iphdr_s
{
-#ifdef CONFIG_NET_IPv6
+ /* IPv4 IP header */
- /* IPv6 Ip header */
+ uint8_t vhl; /* 8-bit Version (4) and header length (6 with Router Alert) */
+ uint8_t tos; /* 8-bit Type of service (e.g., 6=TCP) */
+ uint8_t len[2]; /* 16-bit Total length */
+ uint8_t ipid[2]; /* 16-bit Identification */
+ uint8_t ipoffset[2]; /* 16-bit IP flags + fragment offset */
+ uint8_t ttl; /* 8-bit Time to Live */
+ uint8_t proto; /* 8-bit Protocol */
+ uint16_t ipchksum; /* 16-bit Header checksum */
+ uint16_t srcipaddr[2]; /* 32-bit Source IP address */
+ uint16_t destipaddr[2]; /* 32-bit Destination IP address */
- uint8_t vtc; /* Bits 0-3: version, bits 4-7: traffic class (MS) */
- uint8_t tcf; /* Bits 0-3: traffic class (LS), bits 4-7: flow label (MS) */
- uint16_t flow; /* 16-bit flow label (LS) */
- uint8_t len[2]; /* 16-bit Payload length */
- uint8_t proto; /* 8-bit Next header (same as IPv4 protocol field) */
- uint8_t ttl; /* 8-bit Hop limit (like IPv4 TTL field) */
- net_ip6addr_t srcipaddr; /* 128-bit Source address */
- net_ip6addr_t destipaddr; /* 128-bit Destination address */
+ /* Router Alert IP header option */
-#else /* CONFIG_NET_IPv6 */
+ uint16_t ra[2];
- /* IPv4 IP header */
+ /* IGMPv2 header:
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Type | Max Resp Time | Checksum |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Group Address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
- uint8_t vhl; /* 8-bit Version (4) and header length (6 with Router Alert) */
- uint8_t tos; /* 8-bit Type of service (e.g., 6=TCP) */
- uint8_t len[2]; /* 16-bit Total length */
- uint8_t ipid[2]; /* 16-bit Identification */
- uint8_t ipoffset[2]; /* 16-bit IP flags + fragment offset */
- uint8_t ttl; /* 8-bit Time to Live */
- uint8_t proto; /* 8-bit Protocol */
- uint16_t ipchksum; /* 16-bit Header checksum */
- uint16_t srcipaddr[2]; /* 32-bit Source IP address */
- uint16_t destipaddr[2]; /* 32-bit Destination IP address */
+ uint8_t type; /* 8-bit IGMP packet type */
+ uint8_t maxresp; /* 8-bit Max response time */
+ uint16_t chksum; /* 16-bit Checksum */
+ uint16_t grpaddr[2]; /* 32-bit Group address */
+};
+#endif
-#endif /* CONFIG_NET_IPv6 */
+#ifdef CONFIG_NET_IPv6
+struct igmp_ipv6hdr_s
+{
+ /* IPv6 Ip header */
+
+ uint8_t vtc; /* Bits 0-3: version, bits 4-7: traffic class (MS) */
+ uint8_t tcf; /* Bits 0-3: traffic class (LS), bits 4-7: flow label (MS) */
+ uint16_t flow; /* 16-bit flow label (LS) */
+ uint8_t len[2]; /* 16-bit Payload length */
+ uint8_t proto; /* 8-bit Next header (same as IPv4 protocol field) */
+ uint8_t ttl; /* 8-bit Hop limit (like IPv4 TTL field) */
+ net_ipv6addr_t srcipaddr; /* 128-bit Source address */
+ net_ipv6addr_t destipaddr; /* 128-bit Destination address */
/* Router Alert IP header option */
@@ -172,11 +192,12 @@ struct igmp_iphdr_s
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
- uint8_t type; /* 8-bit IGMP packet type */
- uint8_t maxresp; /* 8-bit Max response time */
- uint16_t chksum; /* 16-bit Checksum */
- uint16_t grpaddr[2]; /* 32-bit Group address */
+ uint8_t type; /* 8-bit IGMP packet type */
+ uint8_t maxresp; /* 8-bit Max response time */
+ uint16_t chksum; /* 16-bit Checksum */
+ uint16_t grpaddr[2]; /* 32-bit Group address */
};
+#endif
#ifdef CONFIG_NET_STATISTICS
struct igmp_stats_s
diff --git a/nuttx/include/nuttx/net/ip.h b/nuttx/include/nuttx/net/ip.h
index 160e00fa6..5e573f2d6 100644
--- a/nuttx/include/nuttx/net/ip.h
+++ b/nuttx/include/nuttx/net/ip.h
@@ -92,13 +92,12 @@
/* Representation of an IP address */
-typedef in_addr_t net_ip4addr_t;
-typedef uint16_t net_ip6addr_t[8];
+typedef uint16_t net_ipv6addr_t[8];
#ifdef CONFIG_NET_IPv6
-typedef net_ip6addr_t net_ipaddr_t;
+typedef net_ipv6addr_t net_ipaddr_t;
#else
-typedef net_ip4addr_t net_ipaddr_t;
+typedef in_addr_t net_ipaddr_t;
#endif
#ifdef CONFIG_NET_IPv4
@@ -106,16 +105,16 @@ typedef net_ip4addr_t net_ipaddr_t;
struct net_iphdr_s
{
- uint8_t vhl; /* 8-bit Version (4) and header length (5 or 6) */
- uint8_t tos; /* 8-bit Type of service (e.g., 6=TCP) */
- uint8_t len[2]; /* 16-bit Total length */
- uint8_t ipid[2]; /* 16-bit Identification */
- uint8_t ipoffset[2]; /* 16-bit IP flags + fragment offset */
- uint8_t ttl; /* 8-bit Time to Live */
- uint8_t proto; /* 8-bit Protocol */
- uint16_t ipchksum; /* 16-bit Header checksum */
- uint16_t srcipaddr[2]; /* 32-bit Source IP address */
- uint16_t destipaddr[2]; /* 32-bit Destination IP address */
+ uint8_t vhl; /* 8-bit Version (4) and header length (5 or 6) */
+ uint8_t tos; /* 8-bit Type of service (e.g., 6=TCP) */
+ uint8_t len[2]; /* 16-bit Total length */
+ uint8_t ipid[2]; /* 16-bit Identification */
+ uint8_t ipoffset[2]; /* 16-bit IP flags + fragment offset */
+ uint8_t ttl; /* 8-bit Time to Live */
+ uint8_t proto; /* 8-bit Protocol */
+ uint16_t ipchksum; /* 16-bit Header checksum */
+ uint16_t srcipaddr[2]; /* 32-bit Source IP address */
+ uint16_t destipaddr[2]; /* 32-bit Destination IP address */
};
#endif
@@ -124,14 +123,14 @@ struct net_iphdr_s
struct net_ipv6hdr_s
{
- uint8_t vtc; /* Bits 0-3: version, bits 4-7: traffic class (MS) */
- uint8_t tcf; /* Bits 0-3: traffic class (LS), 4-bits: flow label (MS) */
- uint16_t flow; /* 16-bit flow label (LS) */
- uint8_t len[2]; /* 16-bit Payload length */
- uint8_t proto; /* 8-bit Next header (same as IPv4 protocol field) */
- uint8_t ttl; /* 8-bit Hop limit (like IPv4 TTL field) */
- net_ip6addr_t srcipaddr; /* 128-bit Source address */
- net_ip6addr_t destipaddr; /* 128-bit Destination address */
+ uint8_t vtc; /* Bits 0-3: version, bits 4-7: traffic class (MS) */
+ uint8_t tcf; /* Bits 0-3: traffic class (LS), 4-bits: flow label (MS) */
+ uint16_t flow; /* 16-bit flow label (LS) */
+ uint8_t len[2]; /* 16-bit Payload length */
+ uint8_t proto; /* 8-bit Next header (same as IPv4 protocol field) */
+ uint8_t ttl; /* 8-bit Hop limit (like IPv4 TTL field) */
+ net_ipv6addr_t srcipaddr; /* 128-bit Source address */
+ net_ipv6addr_t destipaddr; /* 128-bit Destination address */
};
#endif
@@ -229,7 +228,7 @@ struct net_ipv6hdr_s
((uint16_t*)(dest))[1] = ((uint16_t*)(src))[1]; \
} while (0)
-#define net_ipv6addr_copy(dest, src) memcpy(&dest, &src, sizeof(net_ip6addr_t))
+#define net_ipv6addr_copy(dest, src) memcpy(&dest, &src, sizeof(net_ipv6addr_t))
#define net_ipv6addr_hdrcopy(dest, src) net_ipv6addr_copy(dest, src)
#ifndef CONFIG_NET_IPv6
@@ -262,7 +261,7 @@ struct net_ipv6hdr_s
net_ipv4addr_cmp(net_ip4addr_conv32(addr1), net_ip4addr_conv32(addr2))
#define net_ipv6addr_cmp(addr1, addr2) \
- (memcmp(&addr1, &addr2, sizeof(net_ip6addr_t)) == 0)
+ (memcmp(&addr1, &addr2, sizeof(net_ipv6addr_t)) == 0)
#define net_ipv6addr_hdrcmp(addr1, addr2) \
net_ipv6addr_cmp(addr1, addr2)
@@ -280,9 +279,9 @@ struct net_ipv6hdr_s
*
* Example:
*
- * net_ipaddr_t ipaddr1;
- * net_ipaddr_t ipaddr2;
- * net_ipaddr_t mask;
+ * in_addr_t ipaddr1;
+ * in_addr_t ipaddr2;
+ * in_addr_t mask;
*
* net_ipaddr(&mask, 255,255,255,0);
* net_ipaddr(&ipaddr1, 192,16,1,2);
@@ -297,13 +296,19 @@ struct net_ipv6hdr_s
* mask The netmask.
*/
-#ifndef CONFIG_NET_IPv6
-# define net_ipaddr_maskcmp(addr1, addr2, mask) \
+#define net_ipv4addr_maskcmp(addr1, addr2, mask) \
(((in_addr_t)(addr1) & (in_addr_t)(mask)) == \
((in_addr_t)(addr2) & (in_addr_t)(mask)))
+
+#ifndef CONFIG_NET_IPv6
+# define net_ipaddr_maskcmp(a,b,m) net_ipv4addr_maskcmp(a,b,m)
+
#else
-bool net_ipaddr_maskcmp(net_ipaddr_t addr1, net_ipaddr_t addr2,
- net_ipaddr_t mask);
+bool net_ipv6addr_maskcmp(const net_ipv6addr_t addr1,
+ const net_ipv6addr_t addr2,
+ const net_ipv6addr_t mask);
+
+# define net_ipaddr_maskcmp(a,b,m) net_ipv6addr_maskcmp(a,b,m)
#endif
/* Mask out the network part of an IP address, given the address and
diff --git a/nuttx/include/nuttx/net/net.h b/nuttx/include/nuttx/net/net.h
index b077b7371..dcec612aa 100644
--- a/nuttx/include/nuttx/net/net.h
+++ b/nuttx/include/nuttx/net/net.h
@@ -96,7 +96,8 @@ struct devif_callback_s; /* Forward reference */
struct socket
{
- int s_crefs; /* Reference count on the socket */
+ int16_t s_crefs; /* Reference count on the socket */
+ uint8_t s_domain; /* Domain: PF_INET, PF_INET6, or PF_PACKET */
uint8_t s_type; /* Protocol type: Only SOCK_STREAM or SOCK_DGRAM */
uint8_t s_flags; /* See _SF_* definitions */
diff --git a/nuttx/include/nuttx/net/netconfig.h b/nuttx/include/nuttx/net/netconfig.h
index 247160355..9df3a6f2c 100644
--- a/nuttx/include/nuttx/net/netconfig.h
+++ b/nuttx/include/nuttx/net/netconfig.h
@@ -9,7 +9,7 @@
* Note: Network configuration options the netconfig.h should not be changed,
* but rather the per-project defconfig file.
*
- * Copyright (C) 2007, 2011, 2014 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007, 2011, 2014-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* This logic was leveraged from uIP which also has a BSD-style license:
@@ -139,9 +139,10 @@
#elif defined(CONFIG_NET_SLIP)
/* There is no link layer header with SLIP */
-# ifdef CONFIG_NET_IPv6
-# error SLIP is not available for IPv6
+# ifdef CONFIG_NET_IPv4
+# error SLIP requires IPv4 support
# endif
+
# define NET_LL_HDRLEN(d) 0
# define NET_DEV_MTU(d) CONFIG_NET_SLIP_MTU
# define MIN_NET_DEV_MTU CONFIG_NET_SLIP_MTU
@@ -210,21 +211,21 @@
#endif
/* The UDP maximum packet size. This is should not be to set to more
- * than NET_DEV_MTU(d) - NET_LL_HDRLEN(dev) - IPUDP_HDRLEN.
+ * than NET_DEV_MTU(d) - NET_LL_HDRLEN(dev) - IPv4UDP_HDRLEN.
*/
-#define UDP_MSS(d) (NET_DEV_MTU(d) - NET_LL_HDRLEN(d) - IPUDP_HDRLEN)
+#define UDP_MSS(d) (NET_DEV_MTU(d) - NET_LL_HDRLEN(d) - IPv4UDP_HDRLEN)
#ifdef CONFIG_NET_ETHERNET
-# define MIN_UDP_MSS (CONFIG_NET_ETH_MTU - ETH_HDRLEN - IPUDP_HDRLEN)
+# define MIN_UDP_MSS (CONFIG_NET_ETH_MTU - ETH_HDRLEN - IPv4UDP_HDRLEN)
#else /* if defined(CONFIG_NET_SLIP) */
-# define MIN_UDP_MSS (CONFIG_NET_SLIP_MTU - IPUDP_HDRLEN)
+# define MIN_UDP_MSS (CONFIG_NET_SLIP_MTU - IPv4UDP_HDRLEN)
#endif
#ifdef CONFIG_NET_SLIP
-# define MAX_UDP_MSS (CONFIG_NET_SLIP_MTU - IPUDP_HDRLEN)
+# define MAX_UDP_MSS (CONFIG_NET_SLIP_MTU - IPv4UDP_HDRLEN)
#else /* if defined(CONFIG_NET_ETHERNET) */
-# define MAX_UDP_MSS (CONFIG_NET_ETH_MTU - ETH_HDRLEN - IPUDP_HDRLEN)
+# define MAX_UDP_MSS (CONFIG_NET_ETH_MTU - ETH_HDRLEN - IPv4UDP_HDRLEN)
#endif
/* TCP configuration options */
@@ -287,7 +288,7 @@
#define TCP_MAXSYNRTX 5
/* The TCP maximum segment size. This is should not be set to more
- * than NET_DEV_MTU(dev) - NET_LL_HDRLEN(dev) - IPTCP_HDRLEN.
+ * than NET_DEV_MTU(dev) - NET_LL_HDRLEN(dev) - IPv4TCP_HDRLEN.
*
* In the case where there are multiple network devices with different
* link layer protocols (CONFIG_NET_MULTILINK), each network device
@@ -295,13 +296,13 @@
* the minimum MSS for that case.
*/
-#define TCP_MSS(d) (NET_DEV_MTU(d) - NET_LL_HDRLEN(d) - IPTCP_HDRLEN)
+#define TCP_MSS(d) (NET_DEV_MTU(d) - NET_LL_HDRLEN(d) - IPv4TCP_HDRLEN)
#ifdef CONFIG_NET_ETHERNET
-# define ETH_TCP_MSS (CONFIG_NET_ETH_MTU - ETH_HDRLEN - IPTCP_HDRLEN)
+# define ETH_TCP_MSS (CONFIG_NET_ETH_MTU - ETH_HDRLEN - IPv4TCP_HDRLEN)
# define MIN_TCP_MSS ETH_TCP_MSS
#elif defined(CONFIG_NET_SLIP)
-# define SLIP_TCP_MSS (CONFIG_NET_SLIP_MTU - IPTCP_HDRLEN)
+# define SLIP_TCP_MSS (CONFIG_NET_SLIP_MTU - IPv4TCP_HDRLEN)
# define MIN_TCP_MSS SLIP_TCP_MSS
#endif
diff --git a/nuttx/include/nuttx/net/netdev.h b/nuttx/include/nuttx/net/netdev.h
index 4a51f0e44..e66c378d5 100644
--- a/nuttx/include/nuttx/net/netdev.h
+++ b/nuttx/include/nuttx/net/netdev.h
@@ -2,7 +2,7 @@
* include/nuttx/net/netdev.h
* Defines architecture-specific device driver interfaces to the uIP network.
*
- * Copyright (C) 2007, 2009, 2011-2014 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007, 2009, 2011-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Derived largely from portions of uIP with has a similar BSD-styple license:
@@ -99,25 +99,33 @@ struct net_driver_s
#ifdef CONFIG_NET_MULTILINK
/* Multi network devices using multiple data links protocols are selected */
- uint8_t d_lltype; /* See enum net_datalink_e */
- uint8_t d_llhdrlen; /* Link layer header size */
- uint16_t d_mtu; /* Maximum packet size */
+ uint8_t d_lltype; /* See enum net_datalink_e */
+ uint8_t d_llhdrlen; /* Link layer header size */
+ uint16_t d_mtu; /* Maximum packet size */
#ifdef CONFIG_NET_TCP
- uint16_t d_recvwndo; /* TCP receive window size */
+ uint16_t d_recvwndo; /* TCP receive window size */
#endif
#endif
#ifdef CONFIG_NET_ETHERNET
/* Ethernet device identity */
- struct ether_addr d_mac; /* Device MAC address */
+ struct ether_addr d_mac; /* Device MAC address */
#endif
/* Network identity */
- net_ipaddr_t d_ipaddr; /* Host IP address assigned to the network interface */
- net_ipaddr_t d_draddr; /* Default router IP address */
- net_ipaddr_t d_netmask; /* Network subnet mask */
+#ifdef CONFIG_NET_IPv4
+ in_addr_t d_ipaddr; /* Host IPv4 address assigned to the network interface */
+ in_addr_t d_draddr; /* Default router IP address */
+ in_addr_t d_netmask; /* Network subnet mask */
+#endif
+
+#ifdef CONFIG_NET_IPv6
+ net_ipv6addr_t d_ipv6addr; /* Host IPv6 address assigned to the network interface */
+ net_ipv6addr_t d_ipv6draddr; /* Default router IPv6 address */
+ net_ipv6addr_t d_ipv6netmask; /* Network IPv6 subnet mask */
+#endif
/* The d_buf array is used to hold incoming and outgoing packets. The device
* driver should place incoming data into this buffer. When sending data,
diff --git a/nuttx/include/nuttx/net/tcp.h b/nuttx/include/nuttx/net/tcp.h
index 0384f3bc5..8a33f81cd 100644
--- a/nuttx/include/nuttx/net/tcp.h
+++ b/nuttx/include/nuttx/net/tcp.h
@@ -98,7 +98,14 @@
/* TCP header sizes */
#define TCP_HDRLEN 20 /* Size of TCP header */
-#define IPTCP_HDRLEN (TCP_HDRLEN + IPv4_HDRLEN) /* Size of IPv4 + TCP header */
+
+#ifdef CONFIG_NET_IPv4
+# define IPv4TCP_HDRLEN (TCP_HDRLEN + IPv4_HDRLEN) /* Size of IPv4 + TCP header */
+#endif
+
+#ifdef CONFIG_NET_IPv6
+# define IPv6TCP_HDRLEN (TCP_HDRLEN + IPv6_HDRLEN) /* Size of IPv4 + TCP header */
+#endif
/* Initial minimum MSS according to RFC 879
*
@@ -121,39 +128,68 @@
* Public Type Definitions
****************************************************************************/
+/* TCP header */
+
+struct tcp_hdr_s
+{
+ uint16_t srcport;
+ uint16_t destport;
+ uint8_t seqno[4];
+ uint8_t ackno[4];
+ uint8_t tcpoffset;
+ uint8_t flags;
+ uint8_t wnd[2];
+ uint16_t tcpchksum;
+ uint8_t urgp[2];
+ uint8_t optdata[4];
+};
+
/* The TCP and IP headers */
+#ifdef CONFIG_NET_IPv4
struct tcp_iphdr_s
{
-#ifdef CONFIG_NET_IPv6
-
- /* IPv6 Ip header */
+ /* IPv4 IP header */
- uint8_t vtc; /* Bits 0-3: version, bits 4-7: traffic class (MS) */
- uint8_t tcf; /* Bits 0-3: traffic class (LS), 4-bits: flow label (MS) */
- uint16_t flow; /* 16-bit flow label (LS) */
- uint8_t len[2]; /* 16-bit Payload length */
- uint8_t proto; /* 8-bit Next header (same as IPv4 protocol field) */
- uint8_t ttl; /* 8-bit Hop limit (like IPv4 TTL field) */
- net_ip6addr_t srcipaddr; /* 128-bit Source address */
- net_ip6addr_t destipaddr; /* 128-bit Destination address */
+ uint8_t vhl; /* 8-bit Version (4) and header length (5 or 6) */
+ uint8_t tos; /* 8-bit Type of service (e.g., 6=TCP) */
+ uint8_t len[2]; /* 16-bit Total length */
+ uint8_t ipid[2]; /* 16-bit Identification */
+ uint8_t ipoffset[2]; /* 16-bit IP flags + fragment offset */
+ uint8_t ttl; /* 8-bit Time to Live */
+ uint8_t proto; /* 8-bit Protocol */
+ uint16_t ipchksum; /* 16-bit Header checksum */
+ uint16_t srcipaddr[2]; /* 32-bit Source IP address */
+ uint16_t destipaddr[2]; /* 32-bit Destination IP address */
-#else /* CONFIG_NET_IPv6 */
+ /* TCP header */
- /* IPv4 IP header */
+ uint16_t srcport;
+ uint16_t destport;
+ uint8_t seqno[4];
+ uint8_t ackno[4];
+ uint8_t tcpoffset;
+ uint8_t flags;
+ uint8_t wnd[2];
+ uint16_t tcpchksum;
+ uint8_t urgp[2];
+ uint8_t optdata[4];
+};
+#endif
- uint8_t vhl; /* 8-bit Version (4) and header length (5 or 6) */
- uint8_t tos; /* 8-bit Type of service (e.g., 6=TCP) */
- uint8_t len[2]; /* 16-bit Total length */
- uint8_t ipid[2]; /* 16-bit Identification */
- uint8_t ipoffset[2]; /* 16-bit IP flags + fragment offset */
- uint8_t ttl; /* 8-bit Time to Live */
- uint8_t proto; /* 8-bit Protocol */
- uint16_t ipchksum; /* 16-bit Header checksum */
- uint16_t srcipaddr[2]; /* 32-bit Source IP address */
- uint16_t destipaddr[2]; /* 32-bit Destination IP address */
+#ifdef CONFIG_NET_IPv6
+struct tcp_ipv6hdr_s
+{
+ /* IPv6 IP header */
-#endif /* CONFIG_NET_IPv6 */
+ uint8_t vtc; /* Bits 0-3: version, bits 4-7: traffic class (MS) */
+ uint8_t tcf; /* Bits 0-3: traffic class (LS), 4-bits: flow label (MS) */
+ uint16_t flow; /* 16-bit flow label (LS) */
+ uint8_t len[2]; /* 16-bit Payload length */
+ uint8_t proto; /* 8-bit Next header (same as IPv4 protocol field) */
+ uint8_t ttl; /* 8-bit Hop limit (like IPv4 TTL field) */
+ net_ipv6addr_t srcipaddr; /* 128-bit Source address */
+ net_ipv6addr_t destipaddr; /* 128-bit Destination address */
/* TCP header */
@@ -168,6 +204,7 @@ struct tcp_iphdr_s
uint8_t urgp[2];
uint8_t optdata[4];
};
+#endif
/* The structure holding the TCP/IP statistics that are gathered if
* CONFIG_NET_STATISTICS is defined.
diff --git a/nuttx/include/nuttx/net/udp.h b/nuttx/include/nuttx/net/udp.h
index c32120c74..4b2d305d6 100644
--- a/nuttx/include/nuttx/net/udp.h
+++ b/nuttx/include/nuttx/net/udp.h
@@ -62,45 +62,70 @@
/* Header sizes */
-#define UDP_HDRLEN 8 /* Size of UDP header */
-#define IPUDP_HDRLEN (UDP_HDRLEN + IPv4_HDRLEN) /* Size of IPv4 + UDP header */
+#define UDP_HDRLEN 8 /* Size of UDP header */
+
+#ifdef CONFIG_NET_IPv4
+# define IPv4UDP_HDRLEN (UDP_HDRLEN + IPv4_HDRLEN) /* Size of IPv4 + UDP headers */
+#endif
+
+#ifdef CONFIG_NET_IPv6
+# define IPv6UDP_HDRLEN (UDP_HDRLEN + IPv6_HDRLEN) /* Size of IPv6 + UDP headers */
+#endif
/****************************************************************************
* Public Type Definitions
****************************************************************************/
+
+/* The UDP header */
+
+struct udp_hdr_s
+{
+ uint16_t srcport;
+ uint16_t destport;
+ uint16_t udplen;
+ uint16_t udpchksum;
+};
+
/* The UDP and IP headers */
+#ifdef CONFIG_NET_IPv4
struct udp_iphdr_s
{
-#ifdef CONFIG_NET_IPv6
-
- /* IPv6 Ip header */
+ /* IPv4 header */
- uint8_t vtc; /* Bits 0-3: version, bits 4-7: traffic class (MS) */
- uint8_t tcf; /* Bits 0-3: traffic class (LS), 4-bits: flow label (MS) */
- uint16_t flow; /* 16-bit flow label (LS) */
- uint8_t len[2]; /* 16-bit Payload length */
- uint8_t proto; /* 8-bit Next header (same as IPv4 protocol field) */
- uint8_t ttl; /* 8-bit Hop limit (like IPv4 TTL field) */
- net_ip6addr_t srcipaddr; /* 128-bit Source address */
- net_ip6addr_t destipaddr; /* 128-bit Destination address */
+ uint8_t vhl; /* 8-bit Version (4) and header length (5 or 6) */
+ uint8_t tos; /* 8-bit Type of service (e.g., 6=TCP) */
+ uint8_t len[2]; /* 16-bit Total length */
+ uint8_t ipid[2]; /* 16-bit Identification */
+ uint8_t ipoffset[2]; /* 16-bit IP flags + fragment offset */
+ uint8_t ttl; /* 8-bit Time to Live */
+ uint8_t proto; /* 8-bit Protocol */
+ uint16_t ipchksum; /* 16-bit Header checksum */
+ uint16_t srcipaddr[2]; /* 32-bit Source IP address */
+ uint16_t destipaddr[2]; /* 32-bit Destination IP address */
-#else /* CONFIG_NET_IPv6 */
+ /* UDP header */
- /* IPv4 header */
+ uint16_t srcport;
+ uint16_t destport;
+ uint16_t udplen;
+ uint16_t udpchksum;
+};
+#endif
- uint8_t vhl; /* 8-bit Version (4) and header length (5 or 6) */
- uint8_t tos; /* 8-bit Type of service (e.g., 6=TCP) */
- uint8_t len[2]; /* 16-bit Total length */
- uint8_t ipid[2]; /* 16-bit Identification */
- uint8_t ipoffset[2]; /* 16-bit IP flags + fragment offset */
- uint8_t ttl; /* 8-bit Time to Live */
- uint8_t proto; /* 8-bit Protocol */
- uint16_t ipchksum; /* 16-bit Header checksum */
- uint16_t srcipaddr[2]; /* 32-bit Source IP address */
- uint16_t destipaddr[2]; /* 32-bit Destination IP address */
+#ifdef CONFIG_NET_IPv6
+struct udp_ipv6hdr_s
+{
+ /* IPv6 Ip header */
-#endif /* CONFIG_NET_IPv6 */
+ uint8_t vtc; /* Bits 0-3: version, bits 4-7: traffic class (MS) */
+ uint8_t tcf; /* Bits 0-3: traffic class (LS), 4-bits: flow label (MS) */
+ uint16_t flow; /* 16-bit flow label (LS) */
+ uint8_t len[2]; /* 16-bit Payload length */
+ uint8_t proto; /* 8-bit Next header (same as IPv4 protocol field) */
+ uint8_t ttl; /* 8-bit Hop limit (like IPv4 TTL field) */
+ net_ipv6addr_t srcipaddr; /* 128-bit Source address */
+ net_ipv6addr_t destipaddr; /* 128-bit Destination address */
/* UDP header */
@@ -109,6 +134,7 @@ struct udp_iphdr_s
uint16_t udplen;
uint16_t udpchksum;
};
+#endif
/* The structure holding the UDP statistics that are gathered if
* CONFIG_NET_STATISTICS is defined.
diff --git a/nuttx/libc/libc.csv b/nuttx/libc/libc.csv
index 1a6e38cac..605989c2a 100644
--- a/nuttx/libc/libc.csv
+++ b/nuttx/libc/libc.csv
@@ -1,4 +1,4 @@
-"_inet_ntoa","arpa/inet.h","!defined(CONFIG_NET_IPv6) && !defined(CONFIG_CAN_PASS_STRUCTS)","FAR char","in_addr_t"
+"_inet_ntoa","arpa/inet.h","defined(CONFIG_NET_IPv4) && !defined(CONFIG_CAN_PASS_STRUCTS)","FAR char","in_addr_t"
"abort","stdlib.h","","void"
"abs","stdlib.h","","int","int"
"aio_error","aio.h","defined(CONFIG_FS_AIO)","int","FAR struct aiocb *"
@@ -56,7 +56,7 @@
"htons","arpa/inet.h","","uint16_t","uint16_t"
"imaxabs","inttypes.h","","intmax_t","intmax_t"
"inet_addr","arpa/inet.h","","in_addr_t","FAR const char "
-"inet_ntoa","arpa/inet.h","!defined(CONFIG_NET_IPv6) && defined(CONFIG_CAN_PASS_STRUCTS)","FAR char","struct in_addr"
+"inet_ntoa","arpa/inet.h","defined(CONFIG_NET_IPv4) && defined(CONFIG_CAN_PASS_STRUCTS)","FAR char","struct in_addr"
"inet_ntop","arpa/inet.h","","FAR const char","int","FAR const void *","FAR char *","socklen_t"
"inet_pton","arpa/inet.h","","int","int","FAR const char *","FAR void *"
"labs","stdlib.h","","long int","long int"
diff --git a/nuttx/libc/net/lib_inetntoa.c b/nuttx/libc/net/lib_inetntoa.c
index f7152d154..f04c3a48f 100644
--- a/nuttx/libc/net/lib_inetntoa.c
+++ b/nuttx/libc/net/lib_inetntoa.c
@@ -1,7 +1,7 @@
/****************************************************************************
* libc/net/lib_inetntoa.c
*
- * Copyright (C) 2007-2008, 2011-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2008, 2011-2012, 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -44,7 +44,7 @@
#include <arpa/inet.h>
#include <netinet/in.h>
-#ifndef CONFIG_NET_IPv6
+#ifdef CONFIG_NET_IPv4
/****************************************************************************
* Global Functions
@@ -78,5 +78,4 @@ FAR char *_inet_ntoa(in_addr_t in)
return buffer;
}
#endif
-#endif /* !CONFIG_NET_IPv6 */
-
+#endif /* CONFIG_NET_IPv4 */
diff --git a/nuttx/libc/net/lib_inetntop.c b/nuttx/libc/net/lib_inetntop.c
index ffa7ba26d..1f3d33c6f 100644
--- a/nuttx/libc/net/lib_inetntop.c
+++ b/nuttx/libc/net/lib_inetntop.c
@@ -1,7 +1,7 @@
/****************************************************************************
* libc/net/lib_inetntop.c
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Includes some logic extracted from hwport_ftpd, written by Jaehyuk Cho
@@ -54,22 +54,20 @@
#include <arpa/inet.h>
/****************************************************************************
- * Public Functions
+ * Private Functions
****************************************************************************/
/****************************************************************************
- * Name: inet_ntop
+ * Name: inet_ipv4_ntop
*
* Description:
- * The inet_ntop() function converts a numeric address into a text string
- * suitable for presentation.
+ * The inet_ipv4_ntop() function converts a numeric IPv4 address into a
+ * text string suitable for presentation.
*
* Input Parameters:
- * af - The af argument specifies the family of the address. This can be
- * AF_INET or AF_INET6.
* src - The src argument points to a buffer holding an address of the
* specified type. The address must be in network byte order.
- * dst - The dst argument points to a buffer where the function stores
+ * dest - The dest argument points to a buffer where the function stores
* the resulting text string; it shall not be NULL.
* size - The size argument specifies the size of this buffer, which must
* be large enough to hold the text string (INET_ADDRSTRLEN
@@ -80,35 +78,57 @@
* if the conversion succeeds. Otherwise, NULL is returned and the errno
* is set to indicate the error. There follow errno values may be set:
*
- * EAFNOSUPPORT - The af argument is invalid.
* ENOSPC - The size of the inet_ntop() result buffer is inadequate
*
****************************************************************************/
-FAR const char *inet_ntop(int af, FAR const void *src, FAR char *dst, socklen_t size)
+#ifdef CONFIG_NET_IPv4
+static int inet_ipv4_ntop(FAR const void *src, FAR char *dest, socklen_t size)
{
- int errval;
-#ifndef CONFIG_NET_IPv6
FAR char *ptr;
- DEBUGASSERT(src && dst);
-
- if (af != AF_INET)
- {
- errval = EAFNOSUPPORT;
- goto errout;
- }
-
if (size < INET_ADDRSTRLEN)
{
- errval = ENOSPC;
- goto errout;
+ return -ENOSPC;
}
ptr = (FAR char*)src;
- sprintf(dst, "%d.%d.%d.%d", ptr[0], ptr[1], ptr[2], ptr[3]);
- return dst;
-#else
+ sprintf(dest, "%d.%d.%d.%d", ptr[0], ptr[1], ptr[2], ptr[3]);
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: inet_ipv6_ntop
+ *
+ * Description:
+ * The inet_ipv6_ntop() function converts a numeric IPv6 address into a
+ * text string suitable for presentation.
+ *
+ * Input Parameters:
+ * af - The af argument specifies the family of the address. This can be
+ * AF_INET or AF_INET6.
+ * src - The src argument points to a buffer holding an address of the
+ * specified type. The address must be in network byte order.
+ * dest - The dest argument points to a buffer where the function stores
+ * the resulting text string; it shall not be NULL.
+ * size - The size argument specifies the size of this buffer, which must
+ * be large enough to hold the text string (INET_ADDRSTRLEN
+ * characters for IPv4, INET6_ADDRSTRLEN characters for IPv6).
+ *
+ * Returned Value:
+ * inet_ntop() returns a pointer to the buffer containing the text string
+ * if the conversion succeeds. Otherwise, NULL is returned and the errno
+ * is set to indicate the error. There follow errno values may be set:
+ *
+ * EAFNOSUPPORT - The af argument is invalid.
+ * ENOSPC - The size of the inet_ntop() result buffer is inadequate
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv6
+static int inet_ipv6_ntop(FAR const void *src, FAR char *dest, socklen_t size)
+{
FAR const struct in6_addr *in6_addr;
uint16_t warray[8];
int offset;
@@ -117,18 +137,9 @@ FAR const char *inet_ntop(int af, FAR const void *src, FAR char *dst, socklen_t
int maxentry;
int maxcount;
- DEBUGASSERT(src && dst);
-
- if (af != AF_INET6)
- {
- errval = EAFNOSUPPORT;
- goto errout;
- }
-
if (size < INET6_ADDRSTRLEN)
{
- errval = ENOSPC;
- goto errout;
+ return -ENOSPC;
}
in6_addr = (FAR const struct in6_addr *)src;
@@ -167,36 +178,105 @@ FAR const char *inet_ntop(int af, FAR const void *src, FAR char *dst, socklen_t
}
offset = 0;
- dst[0] = '\0';
+ dest[0] = '\0';
while (offset < 8)
{
if (offset == maxentry)
{
- size -= snprintf(&dst[strlen(dst)], size, ":");
+ size -= snprintf(&dest[strlen(dest)], size, ":");
offset += maxcount;
if (offset >= 8)
{
- size -= snprintf(&dst[strlen(dst)], size, ":");
+ size -= snprintf(&dest[strlen(dest)], size, ":");
}
}
else
{
if (offset > 0)
{
- size -= snprintf(&dst[strlen(dst)], size, ":");
+ size -= snprintf(&dest[strlen(dest)], size, ":");
}
- size -= snprintf(&dst[strlen(dst)], size, "%x", warray[offset]);
+ size -= snprintf(&dest[strlen(dest)], size, "%x", warray[offset]);
offset++;
}
}
- return dst;
+ return OK;
+}
#endif
-errout:
- set_errno(errval);
- memset(dst, 0, size);
- return NULL;
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: inet_ntop
+ *
+ * Description:
+ * The inet_ntop() function converts a numeric address into a text string
+ * suitable for presentation.
+ *
+ * Input Parameters:
+ * af - The af argument specifies the family of the address. This can be
+ * AF_INET or AF_INET6.
+ * src - The src argument points to a buffer holding an address of the
+ * specified type. The address must be in network byte order.
+ * dest - The dest argument points to a buffer where the function stores
+ * the resulting text string; it shall not be NULL.
+ * size - The size argument specifies the size of this buffer, which must
+ * be large enough to hold the text string (INET_ADDRSTRLEN
+ * characters for IPv4, INET6_ADDRSTRLEN characters for IPv6).
+ *
+ * Returned Value:
+ * inet_ntop() returns a pointer to the buffer containing the text string
+ * if the conversion succeeds. Otherwise, NULL is returned and the errno
+ * is set to indicate the error. There follow errno values may be set:
+ *
+ * EAFNOSUPPORT - The af argument is invalid.
+ * ENOSPC - The size of the inet_ntop() result buffer is inadequate
+ *
+ ****************************************************************************/
+
+FAR const char *inet_ntop(int af, FAR const void *src, FAR char *dest,
+ socklen_t size)
+{
+ int ret;
+
+ DEBUGASSERT(src && dest);
+
+ /* Do the conversion according to the IP version */
+
+ switch (af)
+ {
+#ifdef CONFIG_NET_IPv4
+ case AF_INET:
+ ret = inet_ipv4_ntop(src, dest, size);
+ break;
+#endif
+
+#ifdef CONFIG_NET_IPv6
+ case AF_INET6:
+ ret = inet_ipv6_ntop(src, dest, size);
+ break;
+#endif
+
+ default:
+ ret = -EAFNOSUPPORT;
+ break;
+ }
+
+ /* Handle errors in the conversion */
+
+ if (ret < 0)
+ {
+ set_errno(-ret);
+ memset(dest, 0, size);
+ return NULL;
+ }
+
+ /* Return success */
+
+ return dest;
}
diff --git a/nuttx/libc/net/lib_inetpton.c b/nuttx/libc/net/lib_inetpton.c
index 8b058e044..72229d2f2 100644
--- a/nuttx/libc/net/lib_inetpton.c
+++ b/nuttx/libc/net/lib_inetpton.c
@@ -56,61 +56,33 @@
#include <netinet/in.h>
/****************************************************************************
- * Public Functions
+ * Private Functions
****************************************************************************/
/****************************************************************************
- * Name: inet_pton
+ * Name: inet_ipv4_pton
*
* Description:
- * The inet_pton() function converts an address in its standard text
- * presentation form into its numeric binary form.
- *
- * If the af argument of inet_pton() is AF_INET, the src string will be
- * in the standard IPv4 dotted-decimal form:
- *
- * ddd.ddd.ddd.ddd
- *
- * where "ddd" is a one to three digit decimal number between 0 and 255.
- *
- * If the af argument of inet_pton() is AF_INET6, the src string will be in
- * one of the following standard IPv6 text forms:
- *
- * 1. The preferred form is "x:x:x:x:x:x:x:x", where the 'x' s are the
- * hexadecimal values of the eight 16-bit pieces of the address. Leading
- * zeros in individual fields can be omitted, but there must be at least
- * one numeral in every field.
- *
- * 2. A string of contiguous zero fields in the preferred form can be shown
- * as "::". The "::" can only appear once in an address. Unspecified
- * addresses ( "0:0:0:0:0:0:0:0" ) may be represented simply as "::".
- *
- * 3. A third form that is sometimes more convenient when dealing with a
- * mixed environment of IPv4 and IPv6 nodes is "x:x:x:x:x:x:d.d.d.d",
- * where the 'x' s are the hexadecimal values of the six high-order
- * 16-bit pieces of the address, and the 'd' s are the decimal values
- * of the four low-order 8-bit pieces of the address (standard IPv4
- * representation).
+ * The inet_ipv4_pton() function converts an IPv4 address in its standard
+ * text presentation form into its numeric binary form.
*
* Input Parameters:
- * af - The af argument specifies the family of the address. This can be
- * AF_INET or AF_INET6.
* src - The src argument points to the string being passed in.
- * dst - The dst argument points to a numstr into which the function stores
+ * dest - The dest argument points to a numstr into which the function stores
* the numeric address; this must be large enough to hold the numeric
* address (32 bits for AF_INET, 128 bits for AF_INET6).
*
* Returned Value:
* The inet_pton() function returns 1 if the conversion succeeds, with the
- * address pointed to by dst in network byte order. It will return 0 if the
+ * address pointed to by dest in network byte order. It will return 0 if the
* input is not a valid IPv4 dotted-decimal string or a valid IPv6 address
* string, or -1 with errno set to EAFNOSUPPOR] if the af argument is unknown.
*
****************************************************************************/
-int inet_pton(int af, FAR const char *src, FAR void *dst)
+#ifdef CONFIG_NET_IPv4
+static int inet_ipv4_pton(FAR const char *src, FAR void *dest)
{
-#ifndef CONFIG_NET_IPv6
size_t srcoffset;
size_t numoffset;
int value;
@@ -119,17 +91,9 @@ int inet_pton(int af, FAR const char *src, FAR void *dst)
char numstr[4];
uint8_t *ip;
- DEBUGASSERT(src && dst);
-
- if (af != AF_INET)
- {
- set_errno(EAFNOSUPPORT);
- return -1;
- }
-
- (void)memset(dst, 0, sizeof(struct in_addr));
+ (void)memset(dest, 0, sizeof(struct in_addr));
- ip = (uint8_t *)dst;
+ ip = (uint8_t *)dest;
srcoffset = 0;
numoffset = 0;
ndots = 0;
@@ -204,7 +168,33 @@ int inet_pton(int af, FAR const char *src, FAR void *dst)
/* Return zero if there is any problem parsing the input */
return 0;
-#else
+}
+#endif
+
+/****************************************************************************
+ * Name: inet_ipv6_pton
+ *
+ * Description:
+ * The inet_ipv6_pton() function converts an IPv6 address in its standard
+ * text presentation form into its numeric binary form.
+ *
+ * Input Parameters:
+ * src - The src argument points to the string being passed in.
+ * dest - The dest argument points to a numstr into which the function stores
+ * the numeric address; this must be large enough to hold the numeric
+ * address (32 bits for AF_INET, 128 bits for AF_INET6).
+ *
+ * Returned Value:
+ * The inet_pton() function returns 1 if the conversion succeeds, with the
+ * address pointed to by dest in network byte order. It will return 0 if the
+ * input is not a valid IPv4 dotted-decimal string or a valid IPv6 address
+ * string, or -1 with errno set to EAFNOSUPPOR] if the af argument is unknown.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv6
+static int inet_ipv6_pton(FAR const char *src, FAR void *dest)
+{
size_t srcoffset;
size_t numoffset;
long value;
@@ -216,15 +206,7 @@ int inet_pton(int af, FAR const char *src, FAR void *dst)
uint8_t rip[sizeof(struct in6_addr)];
bool rtime;
- DEBUGASSERT(src && dst);
-
- if (af != AF_INET6)
- {
- set_errno(EAFNOSUPPORT);
- return -1;
- }
-
- (void)memset(dst, 0, sizeof(struct in6_addr));
+ (void)memset(dest, 0, sizeof(struct in6_addr));
srcoffset = 0;
numoffset = 0;
@@ -298,12 +280,12 @@ int inet_pton(int af, FAR const char *src, FAR void *dst)
if (nsep > 0)
{
- memcpy(dst, &ip[0], nsep << 1);
+ memcpy(dest, &ip[0], nsep << 1);
}
if (nrsep > 0)
{
- memcpy(dst + (16 - (nrsep << 1)), &rip[0], nrsep << 1);
+ memcpy(dest + (16 - (nrsep << 1)), &rip[0], nrsep << 1);
}
/* Return 1 if the conversion succeeds */
@@ -335,5 +317,83 @@ int inet_pton(int af, FAR const char *src, FAR void *dst)
/* Return zero if there is any problem parsing the input */
return 0;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: inet_pton
+ *
+ * Description:
+ * The inet_pton() function converts an address in its standard text
+ * presentation form into its numeric binary form.
+ *
+ * If the af argument of inet_pton() is AF_INET, the src string will be
+ * in the standard IPv4 dotted-decimal form:
+ *
+ * ddd.ddd.ddd.ddd
+ *
+ * where "ddd" is a one to three digit decimal number between 0 and 255.
+ *
+ * If the af argument of inet_pton() is AF_INET6, the src string will be in
+ * one of the following standard IPv6 text forms:
+ *
+ * 1. The preferred form is "x:x:x:x:x:x:x:x", where the 'x' s are the
+ * hexadecimal values of the eight 16-bit pieces of the address. Leading
+ * zeros in individual fields can be omitted, but there must be at least
+ * one numeral in every field.
+ *
+ * 2. A string of contiguous zero fields in the preferred form can be shown
+ * as "::". The "::" can only appear once in an address. Unspecified
+ * addresses ( "0:0:0:0:0:0:0:0" ) may be represented simply as "::".
+ *
+ * 3. A third form that is sometimes more convenient when dealing with a
+ * mixed environment of IPv4 and IPv6 nodes is "x:x:x:x:x:x:d.d.d.d",
+ * where the 'x' s are the hexadecimal values of the six high-order
+ * 16-bit pieces of the address, and the 'd' s are the decimal values
+ * of the four low-order 8-bit pieces of the address (standard IPv4
+ * representation).
+ *
+ * Input Parameters:
+ * af - The af argument specifies the family of the address. This can be
+ * AF_INET or AF_INET6.
+ * src - The src argument points to the string being passed in.
+ * dest - The dest argument points to a numstr into which the function stores
+ * the numeric address; this must be large enough to hold the numeric
+ * address (32 bits for AF_INET, 128 bits for AF_INET6).
+ *
+ * Returned Value:
+ * The inet_pton() function returns 1 if the conversion succeeds, with the
+ * address pointed to by dest in network byte order. It will return 0 if the
+ * input is not a valid IPv4 dotted-decimal string or a valid IPv6 address
+ * string, or -1 with errno set to EAFNOSUPPORT] if the af argument is
+ * unknown.
+ *
+ ****************************************************************************/
+
+int inet_pton(int af, FAR const char *src, FAR void *dest)
+{
+ DEBUGASSERT(src && dest);
+
+ /* Do the conversion according to the IP version */
+
+ switch (af)
+ {
+#ifdef CONFIG_NET_IPv4
+ case AF_INET:
+ return inet_ipv4_pton(src, dest);
+#endif
+
+#ifdef CONFIG_NET_IPv6
+ case AF_INET6:
+ return inet_ipv6_pton(src, dest);
#endif
+
+ default:
+ set_errno(EAFNOSUPPORT);
+ return ERROR;
+ }
}
diff --git a/nuttx/net/arp/arp_arpin.c b/nuttx/net/arp/arp_arpin.c
index eed1539a6..99ff7ee67 100644
--- a/nuttx/net/arp/arp_arpin.c
+++ b/nuttx/net/arp/arp_arpin.c
@@ -123,7 +123,7 @@ void arp_arpin(FAR struct net_driver_s *dev)
/* ARP request. If it asked for our address, we send out a reply. */
- if (net_ipaddr_cmp(ipaddr, dev->d_ipaddr))
+ if (net_ipv4addr_cmp(ipaddr, dev->d_ipaddr))
{
struct eth_hdr_s *peth = ETHBUF;
@@ -142,7 +142,7 @@ void arp_arpin(FAR struct net_driver_s *dev)
parp->ah_dipaddr[0] = parp->ah_sipaddr[0];
parp->ah_dipaddr[1] = parp->ah_sipaddr[1];
- net_ipaddr_hdrcopy(parp->ah_sipaddr, &dev->d_ipaddr);
+ net_ipv4addr_hdrcopy(parp->ah_sipaddr, &dev->d_ipaddr);
arp_dump(parp);
peth->type = HTONS(ETHTYPE_ARP);
@@ -157,7 +157,7 @@ void arp_arpin(FAR struct net_driver_s *dev)
* for us.
*/
- if (net_ipaddr_cmp(ipaddr, dev->d_ipaddr))
+ if (net_ipv4addr_cmp(ipaddr, dev->d_ipaddr))
{
/* Yes... Insert the address mapping in the ARP table */
diff --git a/nuttx/net/arp/arp_format.c b/nuttx/net/arp/arp_format.c
index 50a3054e1..21cd99d20 100644
--- a/nuttx/net/arp/arp_format.c
+++ b/nuttx/net/arp/arp_format.c
@@ -105,8 +105,8 @@ void arp_format(FAR struct net_driver_s *dev, in_addr_t ipaddr)
memcpy(eth->src, dev->d_mac.ether_addr_octet, ETHER_ADDR_LEN);
memcpy(arp->ah_shwaddr, dev->d_mac.ether_addr_octet, ETHER_ADDR_LEN);
- net_ipaddr_hdrcopy(arp->ah_dipaddr, &ipaddr);
- net_ipaddr_hdrcopy(arp->ah_sipaddr, &dev->d_ipaddr);
+ net_ipv4addr_hdrcopy(arp->ah_dipaddr, &ipaddr);
+ net_ipv4addr_hdrcopy(arp->ah_sipaddr, &dev->d_ipaddr);
arp->ah_opcode = HTONS(ARP_REQUEST);
arp->ah_hwtype = HTONS(ARP_HWTYPE_ETH);
diff --git a/nuttx/net/arp/arp_ipin.c b/nuttx/net/arp/arp_ipin.c
index ddd7102a1..558af73f3 100644
--- a/nuttx/net/arp/arp_ipin.c
+++ b/nuttx/net/arp/arp_ipin.c
@@ -99,7 +99,7 @@ void arp_ipin(FAR struct net_driver_s *dev)
*/
srcipaddr = net_ip4addr_conv32(IPBUF->eh_srcipaddr);
- if (net_ipaddr_maskcmp(srcipaddr, dev->d_ipaddr, dev->d_netmask))
+ if (net_ipv4addr_maskcmp(srcipaddr, dev->d_ipaddr, dev->d_netmask))
{
arp_update(IPBUF->eh_srcipaddr, ETHBUF->src);
}
diff --git a/nuttx/net/arp/arp_out.c b/nuttx/net/arp/arp_out.c
index 6b5b038c7..b5d5af755 100644
--- a/nuttx/net/arp/arp_out.c
+++ b/nuttx/net/arp/arp_out.c
@@ -92,7 +92,7 @@ static const uint16_t g_broadcast_ipaddr[2] = {0xffff, 0xffff};
* The following is the first three octects of the IGMP address:
*/
-#if defined(CONFIG_NET_IGMP) && !defined(CONFIG_NET_IPv6)
+#ifdef CONFIG_NET_IGMP
static const uint8_t g_multicast_ethaddr[3] = {0x01, 0x00, 0x5e};
#endif
@@ -163,12 +163,12 @@ void arp_out(FAR struct net_driver_s *dev)
/* First check if destination is a local broadcast. */
- if (net_ipaddr_hdrcmp(pip->eh_destipaddr, g_broadcast_ipaddr))
+ if (net_ipv4addr_hdrcmp(pip->eh_destipaddr, g_broadcast_ipaddr))
{
memcpy(peth->dest, g_broadcast_ethaddr.ether_addr_octet, ETHER_ADDR_LEN);
}
-#if defined(CONFIG_NET_IGMP) && !defined(CONFIG_NET_IPv6)
+#ifdef CONFIG_NET_IGMP
/* Check if the destination address is a multicast address
*
* - IPv4: multicast addresses lie in the class D group -- The address range
@@ -196,7 +196,7 @@ void arp_out(FAR struct net_driver_s *dev)
/* Check if the destination address is on the local network. */
destipaddr = net_ip4addr_conv32(pip->eh_destipaddr);
- if (!net_ipaddr_maskcmp(destipaddr, dev->d_ipaddr, dev->d_netmask))
+ if (!net_ipv4addr_maskcmp(destipaddr, dev->d_ipaddr, dev->d_netmask))
{
/* Destination address is not on the local network */
@@ -213,14 +213,14 @@ void arp_out(FAR struct net_driver_s *dev)
* destination address when determining the MAC address.
*/
- net_ipaddr_copy(ipaddr, dev->d_draddr);
+ net_ipv4addr_copy(ipaddr, dev->d_draddr);
#endif
}
else
{
/* Else, we use the destination IP address. */
- net_ipaddr_copy(ipaddr, destipaddr);
+ net_ipv4addr_copy(ipaddr, destipaddr);
}
/* Check if we already have this destination address in the ARP table */
diff --git a/nuttx/net/arp/arp_send.c b/nuttx/net/arp/arp_send.c
index b3803d0f1..e0d29c9df 100644
--- a/nuttx/net/arp/arp_send.c
+++ b/nuttx/net/arp/arp_send.c
@@ -202,7 +202,7 @@ int arp_send(in_addr_t ipaddr)
return OK;
}
-#if defined(CONFIG_NET_IGMP) && !defined(CONFIG_NET_IPv6)
+#ifdef CONFIG_NET_IGMP
/* Check if the destination address is a multicast address
*
* - IPv4: multicast addresses lie in the class D group -- The address range
@@ -223,9 +223,9 @@ int arp_send(in_addr_t ipaddr)
/* Get the device that can route this request */
#ifdef CONFIG_NET_MULTILINK
- dev = netdev_findbyaddr(g_allzeroaddr, ipaddr);
+ dev = netdev_findby_ipv4addr(g_allzeroaddr, ipaddr);
#else
- dev = netdev_findbyaddr(ipaddr);
+ dev = netdev_findby_ipv4addr(ipaddr);
#endif
if (!dev)
{
@@ -250,9 +250,9 @@ int arp_send(in_addr_t ipaddr)
/* Check if the destination address is on the local network. */
- if (!net_ipaddr_maskcmp(ipaddr, dev->d_ipaddr, dev->d_netmask))
+ if (!net_ipv4addr_maskcmp(ipaddr, dev->d_ipaddr, dev->d_netmask))
{
- net_ipaddr_t dripaddr;
+ in_addr_t dripaddr;
/* Destination address is not on the local network */
@@ -270,7 +270,7 @@ int arp_send(in_addr_t ipaddr)
* destination address when determining the MAC address.
*/
- net_ipaddr_copy(dripaddr, dev->d_draddr);
+ net_ipv4addr_copy(dripaddr, dev->d_draddr);
#endif
ipaddr = dripaddr;
}
@@ -338,7 +338,7 @@ int arp_send(in_addr_t ipaddr)
/* Notify the device driver that new TX data is available.
* NOTES: This is in essence what netdev_txnotify() does, which
- * is not possible to call since it expects a net_ipaddr_t as
+ * is not possible to call since it expects a in_addr_t as
* its single argument to lookup the network interface.
*/
diff --git a/nuttx/net/arp/arp_table.c b/nuttx/net/arp/arp_table.c
index c1b356f41..a9e201c73 100644
--- a/nuttx/net/arp/arp_table.c
+++ b/nuttx/net/arp/arp_table.c
@@ -173,7 +173,7 @@ void arp_update(FAR uint16_t *pipaddr, FAR uint8_t *ethaddr)
* the IP address in this ARP table entry.
*/
- if (net_ipaddr_cmp(ipaddr, tabptr->at_ipaddr))
+ if (net_ipv4addr_cmp(ipaddr, tabptr->at_ipaddr))
{
/* An old entry found, update this and return. */
@@ -252,7 +252,7 @@ FAR struct arp_entry *arp_find(in_addr_t ipaddr)
for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i)
{
tabptr = &g_arptable[i];
- if (net_ipaddr_cmp(ipaddr, tabptr->at_ipaddr))
+ if (net_ipv4addr_cmp(ipaddr, tabptr->at_ipaddr))
{
return tabptr;
}
diff --git a/nuttx/net/devif/ipv4_input.c b/nuttx/net/devif/ipv4_input.c
index c15e22f04..f10cfc68a 100644
--- a/nuttx/net/devif/ipv4_input.c
+++ b/nuttx/net/devif/ipv4_input.c
@@ -383,7 +383,7 @@ int ipv4_input(FAR struct net_driver_s *dev)
if (pbuf->proto == IP_PROTO_UDP &&
net_ipv4addr_cmp(net_ip4addr_conv32(pbuf->destipaddr), g_alloneaddr))
{
- return udp_input(dev);
+ return udp_ipv4_input(dev);
}
/* In most other cases, the device must be assigned a non-zero IP
@@ -425,7 +425,7 @@ int ipv4_input(FAR struct net_driver_s *dev)
if (!net_ipv4addr_cmp(net_ip4addr_conv32(pbuf->destipaddr), dev->d_ipaddr))
{
#ifdef CONFIG_NET_IGMP
- net_ipv4addr_t destip = net_ip4addr_conv32(pbuf->destipaddr);
+ in_addr_t destip = net_ip4addr_conv32(pbuf->destipaddr);
if (igmp_grpfind(dev, &destip) == NULL)
#endif
{
@@ -457,13 +457,13 @@ int ipv4_input(FAR struct net_driver_s *dev)
{
#ifdef CONFIG_NET_TCP
case IP_PROTO_TCP: /* TCP input */
- tcp_input(dev);
+ tcp_ipv4_input(dev);
break;
#endif
#ifdef CONFIG_NET_UDP
case IP_PROTO_UDP: /* UDP input */
- udp_input(dev);
+ udp_ipv4_input(dev);
break;
#endif
diff --git a/nuttx/net/devif/ipv6_input.c b/nuttx/net/devif/ipv6_input.c
index c02db74c1..f98ef48a9 100644
--- a/nuttx/net/devif/ipv6_input.c
+++ b/nuttx/net/devif/ipv6_input.c
@@ -198,7 +198,7 @@ int ipv6_input(FAR struct net_driver_s *dev)
if (pbuf->proto == IP_PROTO_UDP &&
net_ipv6addr_cmp(pbuf->destipaddr, g_alloneaddr))
{
- return udp_input(dev);
+ return udp_ipv6_input(dev);
}
/* In most other cases, the device must be assigned a non-zero IP
@@ -251,13 +251,13 @@ int ipv6_input(FAR struct net_driver_s *dev)
{
#ifdef CONFIG_NET_TCP
case IP_PROTO_TCP: /* TCP input */
- tcp_input(dev);
+ tcp_ipv6_input(dev);
break;
#endif
#ifdef CONFIG_NET_UDP
case IP_PROTO_UDP: /* UDP input */
- udp_input(dev);
+ udp_ipv6_input(dev);
break;
#endif
diff --git a/nuttx/net/icmp/icmp.h b/nuttx/net/icmp/icmp.h
index a5cad2b19..3e55d4c51 100644
--- a/nuttx/net/icmp/icmp.h
+++ b/nuttx/net/icmp/icmp.h
@@ -85,7 +85,7 @@ void icmp_poll(FAR struct net_driver_s *dev);
/* Defined in icmp_send.c ***************************************************/
#ifdef CONFIG_NET_ICMP_PING
-void icmp_send(FAR struct net_driver_s *dev, FAR net_ipaddr_t *destaddr);
+void icmp_send(FAR struct net_driver_s *dev, FAR in_addr_t *destaddr);
#endif /* CONFIG_NET_ICMP_PING */
#undef EXTERN
diff --git a/nuttx/net/icmp/icmp_input.c b/nuttx/net/icmp/icmp_input.c
index 4539faf13..268742120 100644
--- a/nuttx/net/icmp/icmp_input.c
+++ b/nuttx/net/icmp/icmp_input.c
@@ -139,8 +139,8 @@ void icmp_input(FAR struct net_driver_s *dev)
/* Swap IP addresses. */
- net_ipaddr_hdrcopy(picmp->destipaddr, picmp->srcipaddr);
- net_ipaddr_hdrcopy(picmp->srcipaddr, &dev->d_ipaddr);
+ net_ipv4addr_hdrcopy(picmp->destipaddr, picmp->srcipaddr);
+ net_ipv4addr_hdrcopy(picmp->srcipaddr, &dev->d_ipaddr);
/* Recalculate the ICMP checksum */
diff --git a/nuttx/net/icmp/icmp_ping.c b/nuttx/net/icmp/icmp_ping.c
index efcf64256..ef50fc97c 100644
--- a/nuttx/net/icmp/icmp_ping.c
+++ b/nuttx/net/icmp/icmp_ping.c
@@ -81,15 +81,15 @@ struct icmp_ping_s
{
FAR struct devif_callback_s *png_cb; /* Reference to callback instance */
- sem_t png_sem; /* Use to manage the wait for the response */
- uint32_t png_time; /* Start time for determining timeouts */
- uint32_t png_ticks; /* System clock ticks to wait */
- int png_result; /* 0: success; <0:negated errno on fail */
- net_ipaddr_t png_addr; /* The peer to be ping'ed */
- uint16_t png_id; /* Used to match requests with replies */
- uint16_t png_seqno; /* IN: seqno to send; OUT: seqno recieved */
- uint16_t png_datlen; /* The length of data to send in the ECHO request */
- bool png_sent; /* true... the PING request has been sent */
+ sem_t png_sem; /* Use to manage the wait for the response */
+ uint32_t png_time; /* Start time for determining timeouts */
+ uint32_t png_ticks; /* System clock ticks to wait */
+ int png_result; /* 0: success; <0:negated errno on fail */
+ in_addr_t png_addr; /* The peer to be ping'ed */
+ uint16_t png_id; /* Used to match requests with replies */
+ uint16_t png_seqno; /* IN: seqno to send; OUT: seqno recieved */
+ uint16_t png_datlen; /* The length of data to send in the ECHO request */
+ bool png_sent; /* true... the PING request has been sent */
};
/****************************************************************************
@@ -251,7 +251,7 @@ static uint16_t ping_interrupt(FAR struct net_driver_s *dev, FAR void *conn,
* device.
*/
- if (!net_ipaddr_maskcmp(pstate->png_addr, dev->d_ipaddr, dev->d_netmask))
+ if (!net_ipv4addr_maskcmp(pstate->png_addr, dev->d_ipaddr, dev->d_netmask))
{
/* Destination address was not on the local network served by this
* device. If a timeout occurs, then the most likely reason is
@@ -324,8 +324,8 @@ end_wait:
*
****************************************************************************/
-int icmp_ping(net_ipaddr_t addr, uint16_t id, uint16_t seqno,
- uint16_t datalen, int dsecs)
+int icmp_ping(in_addr_t addr, uint16_t id, uint16_t seqno, uint16_t datalen,
+ int dsecs)
{
struct icmp_ping_s state;
net_lock_t save;
diff --git a/nuttx/net/icmp/icmp_send.c b/nuttx/net/icmp/icmp_send.c
index 2ff347ee7..e451e67cb 100644
--- a/nuttx/net/icmp/icmp_send.c
+++ b/nuttx/net/icmp/icmp_send.c
@@ -92,7 +92,7 @@
*
****************************************************************************/
-void icmp_send(FAR struct net_driver_s *dev, FAR net_ipaddr_t *destaddr)
+void icmp_send(FAR struct net_driver_s *dev, FAR in_addr_t *destaddr)
{
FAR struct icmp_iphdr_s *picmp = ICMPBUF;
@@ -124,8 +124,8 @@ void icmp_send(FAR struct net_driver_s *dev, FAR net_ipaddr_t *destaddr)
picmp->ttl = IP_TTL;
picmp->proto = IP_PROTO_ICMP;
- net_ipaddr_hdrcopy(picmp->srcipaddr, &dev->d_ipaddr);
- net_ipaddr_hdrcopy(picmp->destipaddr, destaddr);
+ net_ipv4addr_hdrcopy(picmp->srcipaddr, &dev->d_ipaddr);
+ net_ipv4addr_hdrcopy(picmp->destipaddr, destaddr);
/* Calculate IP checksum. */
diff --git a/nuttx/net/icmpv6/icmpv6.h b/nuttx/net/icmpv6/icmpv6.h
index 0e872334b..c5740e8f0 100644
--- a/nuttx/net/icmpv6/icmpv6.h
+++ b/nuttx/net/icmpv6/icmpv6.h
@@ -85,7 +85,7 @@ void icmpv6_poll(FAR struct net_driver_s *dev);
/* Defined in icmpv6_send.c *************************************************/
#ifdef CONFIG_NET_ICMPv6_PING
-void icmpv6_send(FAR struct net_driver_s *dev, FAR net_ipaddr_t *destaddr);
+void icmpv6_send(FAR struct net_driver_s *dev, FAR net_ipv6addr_t *destaddr);
#endif /* CONFIG_NET_ICMPv6_PING */
#undef EXTERN
diff --git a/nuttx/net/icmpv6/icmpv6_input.c b/nuttx/net/icmpv6/icmpv6_input.c
index 1bc1e4bc3..6b53a13f1 100644
--- a/nuttx/net/icmpv6/icmpv6_input.c
+++ b/nuttx/net/icmpv6/icmpv6_input.c
@@ -122,7 +122,7 @@ void icmpv6_input(FAR struct net_driver_s *dev)
if (picmp->type == ICMPv6_NEIGHBOR_SOLICITATION)
{
- if (net_ipaddr_cmp(picmp->icmpv6data, dev->d_ipaddr))
+ if (net_ipv6addr_cmp(picmp->icmpv6data, dev->d_ipaddr))
{
if (picmp->options[0] == ICMPv6_OPTION_SOURCE_LINK_ADDRESS)
{
diff --git a/nuttx/net/icmpv6/icmpv6_ping.c b/nuttx/net/icmpv6/icmpv6_ping.c
index 46b71d55f..34b71bc7a 100644
--- a/nuttx/net/icmpv6/icmpv6_ping.c
+++ b/nuttx/net/icmpv6/icmpv6_ping.c
@@ -81,15 +81,15 @@ struct icmpv6_ping_s
{
FAR struct devif_callback_s *png_cb; /* Reference to callback instance */
- sem_t png_sem; /* Use to manage the wait for the response */
- uint32_t png_time; /* Start time for determining timeouts */
- uint32_t png_ticks; /* System clock ticks to wait */
- int png_result; /* 0: success; <0:negated errno on fail */
- net_ipaddr_t png_addr; /* The peer to be ping'ed */
- uint16_t png_id; /* Used to match requests with replies */
- uint16_t png_seqno; /* IN: seqno to send; OUT: seqno recieved */
- uint16_t png_datlen; /* The length of data to send in the ECHO request */
- bool png_sent; /* true... the PING request has been sent */
+ sem_t png_sem; /* Use to manage the wait for the response */
+ uint32_t png_time; /* Start time for determining timeouts */
+ uint32_t png_ticks; /* System clock ticks to wait */
+ int png_result; /* 0: success; <0:negated errno on fail */
+ net_ipv6addr_t png_addr; /* The peer to be ping'ed */
+ uint16_t png_id; /* Used to match requests with replies */
+ uint16_t png_seqno; /* IN: seqno to send; OUT: seqno recieved */
+ uint16_t png_datlen; /* The length of data to send in the ECHO request */
+ bool png_sent; /* true... the PING request has been sent */
};
/****************************************************************************
@@ -250,7 +250,7 @@ static uint16_t ping_interrupt(FAR struct net_driver_s *dev, FAR void *conn,
* device.
*/
- if (!net_ipaddr_maskcmp(pstate->png_addr, dev->d_ipaddr, dev->d_netmask))
+ if (!net_ipv6addr_maskcmp(pstate->png_addr, dev->d_ipaddr, dev->d_netmask))
{
/* Destination address was not on the local network served by this
* device. If a timeout occurs, then the most likely reason is
@@ -323,7 +323,7 @@ end_wait:
*
****************************************************************************/
-int icmpv6_ping(net_ipaddr_t addr, uint16_t id, uint16_t seqno,
+int icmpv6_ping(net_ipv6addr_t addr, uint16_t id, uint16_t seqno,
uint16_t datalen, int dsecs)
{
struct icmpv6_ping_s state;
diff --git a/nuttx/net/icmpv6/icmpv6_send.c b/nuttx/net/icmpv6/icmpv6_send.c
index 3c071ed54..6df8dc26b 100644
--- a/nuttx/net/icmpv6/icmpv6_send.c
+++ b/nuttx/net/icmpv6/icmpv6_send.c
@@ -92,7 +92,7 @@
*
****************************************************************************/
-void icmpv6_send(FAR struct net_driver_s *dev, FAR net_ipaddr_t *destaddr)
+void icmpv6_send(FAR struct net_driver_s *dev, FAR net_ipv6addr_t *destaddr)
{
FAR struct icmpv6_iphdr_s *picmpv6 = ICMPv6BUF;
@@ -122,8 +122,8 @@ void icmpv6_send(FAR struct net_driver_s *dev, FAR net_ipaddr_t *destaddr)
picmpv6->nexthdr = IP_PROTO_ICMPv6;
picmpv6->hoplimit = IP_TTL;
- net_ipaddr_copy(picmpv6->srcipaddr, &dev->d_ipaddr);
- net_ipaddr_copy(picmpv6->destipaddr, destaddr);
+ net_ipv6addr_copy(picmpv6->srcipaddr, &dev->d_ipaddr);
+ net_ipv6addr_copy(picmpv6->destipaddr, destaddr);
/* Calculate the ICMPv6 checksum. */
diff --git a/nuttx/net/ipv6/ipv6.h b/nuttx/net/ipv6/ipv6.h
index 7027cc390..9ea1f0d5e 100644
--- a/nuttx/net/ipv6/ipv6.h
+++ b/nuttx/net/ipv6/ipv6.h
@@ -75,9 +75,9 @@ struct net_neighbor_addr_s
****************************************************************************/
void net_neighbor_init(void);
-void net_neighbor_add(net_ipaddr_t ipaddr, struct net_neighbor_addr_s *addr);
-void net_neighbor_update(net_ipaddr_t ipaddr);
-struct net_neighbor_addr_s *net_neighbor_lookup(net_ipaddr_t ipaddr);
+void net_neighbor_add(net_ipv6addr_t ipaddr, struct net_neighbor_addr_s *addr);
+void net_neighbor_update(net_ipv6addr_t ipaddr);
+struct net_neighbor_addr_s *net_neighbor_lookup(net_ipv6addr_t ipaddr);
void net_neighbor_periodic(void);
#endif /* CONFIG_NET_IPv6 */
diff --git a/nuttx/net/ipv6/ipv6_neighbor.c b/nuttx/net/ipv6/ipv6_neighbor.c
index 454a5f0f2..3be02e4c6 100644
--- a/nuttx/net/ipv6/ipv6_neighbor.c
+++ b/nuttx/net/ipv6/ipv6_neighbor.c
@@ -65,7 +65,7 @@
struct neighbor_entry
{
- net_ipaddr_t ipaddr;
+ net_ipv6addr_t ipaddr;
struct net_neighbor_addr_s addr;
uint8_t time;
};
@@ -80,13 +80,13 @@ static struct neighbor_entry entries[ENTRIES];
* Private Functions
****************************************************************************/
-static struct neighbor_entry *find_entry(net_ipaddr_t ipaddr)
+static struct neighbor_entry *find_entry(net_ipv6addr_t ipaddr)
{
int i;
for (i = 0; i < ENTRIES; ++i)
{
- if (net_ipaddr_cmp(entries[i].ipaddr, ipaddr))
+ if (net_ipv6addr_cmp(entries[i].ipaddr, ipaddr))
{
return &entries[i];
}
@@ -122,7 +122,7 @@ void net_neighbor_periodic(void)
}
}
-void net_neighbor_add(net_ipaddr_t ipaddr, struct net_neighbor_addr_s *addr)
+void net_neighbor_add(net_ipv6addr_t ipaddr, struct net_neighbor_addr_s *addr)
{
uint8_t oldest_time;
int oldest;
@@ -145,7 +145,7 @@ void net_neighbor_add(net_ipaddr_t ipaddr, struct net_neighbor_addr_s *addr)
oldest = i;
break;
}
- if (net_ipaddr_cmp(entries[i].ipaddr, addr))
+ if (net_ipv6addr_cmp(entries[i].ipaddr, addr))
{
oldest = i;
break;
@@ -162,11 +162,11 @@ void net_neighbor_add(net_ipaddr_t ipaddr, struct net_neighbor_addr_s *addr)
*/
entries[oldest].time = 0;
- net_ipaddr_copy(entries[oldest].ipaddr, ipaddr);
+ net_ipv6addr_copy(entries[oldest].ipaddr, ipaddr);
memcpy(&entries[oldest].addr, addr, sizeof(struct net_neighbor_addr_s));
}
-void net_neighbor_update(net_ipaddr_t ipaddr)
+void net_neighbor_update(net_ipv6addr_t ipaddr)
{
struct neighbor_entry *e;
@@ -177,7 +177,7 @@ void net_neighbor_update(net_ipaddr_t ipaddr)
}
}
-struct net_neighbor_addr_s *net_neighbor_lookup(net_ipaddr_t ipaddr)
+struct net_neighbor_addr_s *net_neighbor_lookup(net_ipv6addr_t ipaddr)
{
struct neighbor_entry *e;
diff --git a/nuttx/net/netdev/netdev.h b/nuttx/net/netdev/netdev.h
index 70333a283..b25cda598 100644
--- a/nuttx/net/netdev/netdev.h
+++ b/nuttx/net/netdev/netdev.h
@@ -94,11 +94,22 @@ FAR struct net_driver_s *netdev_findbyname(FAR const char *ifname);
/* netdev_findbyaddr.c *******************************************************/
#if CONFIG_NSOCKET_DESCRIPTORS > 0
+#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_MULTILINK
-FAR struct net_driver_s *netdev_findbyaddr(const net_ipaddr_t lipaddr,
- const net_ipaddr_t ripaddr);
+FAR struct net_driver_s *netdev_findby_ipv4addr(in_addr_t lipaddr,
+ in_addr_t ripaddr);
#else
-FAR struct net_driver_s *netdev_findbyaddr(const net_ipaddr_t ripaddr);
+FAR struct net_driver_s *netdev_findby_ipv4addr(in_addr_t ripaddr);
+#endif
+#endif
+
+#ifdef CONFIG_NET_IPv6
+#ifdef CONFIG_NET_MULTILINK
+FAR struct net_driver_s *netdev_findby_ipv6addr(const net_ipv6addr_t lipaddr,
+ const net_ipv6addr_t ripaddr);
+#else
+FAR struct net_driver_s *netdev_findby_ipv6addr(const net_ipv6addr_t ripaddr);
+#endif
#endif
#endif
diff --git a/nuttx/net/netdev/netdev_findbyaddr.c b/nuttx/net/netdev/netdev_findbyaddr.c
index f232f178e..570b84a0c 100644
--- a/nuttx/net/netdev/netdev_findbyaddr.c
+++ b/nuttx/net/netdev/netdev_findbyaddr.c
@@ -73,7 +73,7 @@
****************************************************************************/
/****************************************************************************
- * Function: netdev_finddevice
+ * Function: netdev_finddevice_ipv4addr
*
* Description:
* Find a previously registered network device by matching a local address
@@ -91,7 +91,8 @@
*
****************************************************************************/
-static FAR struct net_driver_s *netdev_finddevice(const net_ipaddr_t ripaddr)
+#ifdef CONFIG_NET_IPv4
+static FAR struct net_driver_s *netdev_finddevice_ipv4addr(in_addr_t ripaddr)
{
FAR struct net_driver_s *dev;
@@ -121,17 +122,71 @@ static FAR struct net_driver_s *netdev_finddevice(const net_ipaddr_t ripaddr)
netdev_semgive();
return NULL;
}
+#endif /* CONFIG_NET_IPv4 */
+
+/****************************************************************************
+ * Function: netdev_finddevice_ipv6addr
+ *
+ * Description:
+ * Find a previously registered network device by matching a local address
+ * with the subnet served by the device. Only "up" devices are considered
+ * (since a "down" device has no meaningful address).
+ *
+ * Parameters:
+ * ripaddr - Remote address of a connection to use in the lookup
+ *
+ * Returned Value:
+ * Pointer to driver on success; null on failure
+ *
+ * Assumptions:
+ * Called from normal user mode
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv6
+static FAR struct net_driver_s *
+netdev_finddevice_ipv6addr(const net_ipv6addr_t ripaddr)
+{
+ FAR struct net_driver_s *dev;
+
+ /* Examine each registered network device */
+
+ netdev_semtake();
+ for (dev = g_netdevices; dev; dev = dev->flink)
+ {
+ /* Is the interface in the "up" state? */
+
+ if ((dev->d_flags & IFF_UP) != 0)
+ {
+ /* Yes.. check for an address match (under the netmask) */
+
+ if (net_ipaddr_maskcmp(dev->d_ipv6ipaddr, ripaddr, dev->d_ipv6netmask))
+ {
+ /* Its a match */
+
+ netdev_semgive();
+ return dev;
+ }
+ }
+ }
+
+ /* No device with the matching address found */
+
+ netdev_semgive();
+ return NULL;
+}
+#endif /* CONFIG_NET_IPv6 */
/****************************************************************************
* Global Functions
****************************************************************************/
/****************************************************************************
- * Function: netdev_findbyaddr
+ * Function: netdev_findby_ipv4addr
*
* Description:
* Find a previously registered network device by matching an arbitrary
- * IP address.
+ * IPv4 address.
*
* Parameters:
* lipaddr - Local, bound address of a connection. Used only if ripaddr
@@ -146,11 +201,12 @@ static FAR struct net_driver_s *netdev_finddevice(const net_ipaddr_t ripaddr)
*
****************************************************************************/
+#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_MULTILINK
-FAR struct net_driver_s *netdev_findbyaddr(const net_ipaddr_t lipaddr,
- const net_ipaddr_t ripaddr)
+FAR struct net_driver_s *netdev_findby_ipv4addr(in_addr_t lipaddr,
+ in_addr_t ripaddr)
#else
-FAR struct net_driver_s *netdev_findbyaddr(const net_ipaddr_t ripaddr)
+FAR struct net_driver_s *netdev_findby_ipv4addr(in_addr_t ripaddr)
#endif
{
struct net_driver_s *dev;
@@ -161,12 +217,12 @@ FAR struct net_driver_s *netdev_findbyaddr(const net_ipaddr_t ripaddr)
/* First, check if this is the broadcast IP address */
- if (net_ipaddr_cmp(ripaddr, g_alloneaddr))
+ if (net_ipv4addr_cmp(ripaddr, g_alloneaddr))
{
#ifdef CONFIG_NET_MULTILINK
/* Yes.. Check the local, bound address. Is it INADDR_ANY? */
- if (net_ipaddr_cmp(lipaddr, g_allzeroaddr))
+ if (net_ipv4addr_cmp(lipaddr, g_allzeroaddr))
{
/* Yes.. In this case, I think we are supposed to send the
* broadcast packet out ALL local networks. I am not sure
@@ -180,7 +236,7 @@ FAR struct net_driver_s *netdev_findbyaddr(const net_ipaddr_t ripaddr)
{
/* Return the device associated with the local address */
- return netdev_finddevice(lipaddr);
+ return netdev_finddevice_ipv4addr(lipaddr);
}
#else
/* If there is only a single, registered network interface, then the
@@ -193,7 +249,7 @@ FAR struct net_driver_s *netdev_findbyaddr(const net_ipaddr_t ripaddr)
/* Check if the address maps to a local network */
- dev = netdev_finddevice(ripaddr);
+ dev = netdev_finddevice_ipv4addr(ripaddr);
if (dev)
{
return dev;
@@ -206,18 +262,132 @@ FAR struct net_driver_s *netdev_findbyaddr(const net_ipaddr_t ripaddr)
* address of a router that can forward packets to the external network.
*/
+ ret = net_router(ripaddr, &router);
+ if (ret >= 0)
+ {
+ /* Success... try to find the network device associated with the local
+ * router address
+ */
+
+ dev = netdev_finddevice_ipv4addr(router);
+ if (dev)
+ {
+ return dev;
+ }
+ }
+#endif /* CONFIG_NET_ROUTE */
+
+ /* The above lookup will fail if the packet is being sent out of our
+ * out subnet to a router and there is no routing information.
+ */
+
+#ifndef CONFIG_NET_MULTILINK
+ /* If there is only a single, registered network interface, then the
+ * decision is pretty easy. Use that device and its default router
+ * address.
+ */
+
+ dev = g_netdevices;
+#endif
+
+ /* If we will did not find the network device, then we might as well fail
+ * because we are not configured properly to determine the route to the
+ * destination.
+ */
+
+ return dev;
+}
+#endif /* CONFIG_NET_IPv4 */
+
+/****************************************************************************
+ * Function: netdev_findby_ipv6addr
+ *
+ * Description:
+ * Find a previously registered network device by matching an arbitrary
+ * IPv6 address.
+ *
+ * Parameters:
+ * lipaddr - Local, bound address of a connection. Used only if ripaddr
+ * is the broadcast address. Used only if CONFIG_NET_MULTILINK.
+ * ripaddr - Remote address of a connection to use in the lookup
+ *
+ * Returned Value:
+ * Pointer to driver on success; null on failure
+ *
+ * Assumptions:
+ * Called from normal user mode
+ *
+ ****************************************************************************/
+
#ifdef CONFIG_NET_IPv6
- ret = net_router(ripaddr, router);
+#ifdef CONFIG_NET_MULTILINK
+FAR struct net_driver_s *netdev_findby_ipv6addr(const net_ipv6addr_t lipaddr,
+ const net_ipv6addr_t ripaddr)
#else
- ret = net_router(ripaddr, &router);
+FAR struct net_driver_s *netdev_findby_ipv6addr(const net_ipv6addr_t ripaddr)
#endif
+{
+ struct net_driver_s *dev;
+#ifdef CONFIG_NET_ROUTE
+ net_ipaddr_t router;
+ int ret;
+#endif
+
+ /* First, check if this is the broadcast IP address */
+
+ if (net_ipv6addr_cmp(ripaddr, g_alloneaddr))
+ {
+#ifdef CONFIG_NET_MULTILINK
+ /* Yes.. Check the local, bound address. Is it INADDR_ANY? */
+
+ if (net_ipv6addr_cmp(lipaddr, g_allzeroaddr))
+ {
+ /* Yes.. In this case, I think we are supposed to send the
+ * broadcast packet out ALL local networks. I am not sure
+ * of that and, in any event, there is nothing we can do
+ * about that here.
+ */
+
+ return NULL;
+ }
+ else
+ {
+ /* Return the device associated with the local address */
+
+ return netdev_finddevice_ipv6addr(lipaddr);
+ }
+#else
+ /* If there is only a single, registered network interface, then the
+ * decision is pretty easy.
+ */
+
+ return g_netdevices;
+#endif
+ }
+
+ /* Check if the address maps to a local network */
+
+ dev = netdev_finddevice_ipv6addr(ripaddr);
+ if (dev)
+ {
+ return dev;
+ }
+
+ /* No.. The address lies on an external network */
+
+#ifdef CONFIG_NET_ROUTE
+ /* If we have a routing table, then perhaps we can find the local
+ * address of a router that can forward packets to the external network.
+ */
+
+ ret = net_router(ripaddr, router);
if (ret >= 0)
{
/* Success... try to find the network device associated with the local
* router address
*/
- dev = netdev_finddevice(router);
+ dev = netdev_finddevice_ipv6addr(router);
if (dev)
{
return dev;
@@ -245,5 +415,6 @@ FAR struct net_driver_s *netdev_findbyaddr(const net_ipaddr_t ripaddr)
return dev;
}
+#endif /* CONFIG_NET_IPv6 */
#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS */
diff --git a/nuttx/net/netdev/netdev_ioctl.c b/nuttx/net/netdev/netdev_ioctl.c
index bd8d6ede9..93bae2f18 100644
--- a/nuttx/net/netdev/netdev_ioctl.c
+++ b/nuttx/net/netdev/netdev_ioctl.c
@@ -95,13 +95,12 @@
****************************************************************************/
#ifdef CONFIG_NET_IPv4
-static void ioctl_getipv4addr(FAR struct sockaddr *outaddr,
- FAR const net_ipaddr_t *inaddr)
+static void ioctl_getipv4addr(FAR struct sockaddr *outaddr, in_addr_t inaddr)
{
FAR struct sockaddr_in *dest = (FAR struct sockaddr_in *)outaddr;
dest->sin_family = AF_INET;
dest->sin_port = 0;
- dest->sin_addr.s_addr = *inaddr;
+ dest->sin_addr.s_addr = inaddr;
}
#endif
@@ -119,7 +118,7 @@ static void ioctl_getipv4addr(FAR struct sockaddr *outaddr,
#ifdef CONFIG_NET_IPv6
static void ioctl_getipv6addr(FAR struct sockaddr_storage *outaddr,
- FAR const net_ipaddr_t *inaddr)
+ FAR const net_ipv6addr_t inaddr)
{
FAR struct sockaddr_in6 *dest = (FAR struct sockaddr_in6 *)outaddr;
dest->sin_family = AF_INET6;
@@ -142,7 +141,7 @@ static void ioctl_getipv6addr(FAR struct sockaddr_storage *outaddr,
****************************************************************************/
#ifdef CONFIG_NET_IPv4
-static void ioctl_setipv4addr(FAR net_ipaddr_t *outaddr,
+static void ioctl_setipv4addr(FAR in_addr_t *outaddr,
FAR const struct sockaddr *inaddr)
{
FAR const struct sockaddr_in *src = (FAR const struct sockaddr_in *)inaddr;
@@ -164,7 +163,7 @@ static void ioctl_setipv4addr(FAR net_ipaddr_t *outaddr,
****************************************************************************/
#ifdef CONFIG_NET_IPv6
-static void ioctl_setipv6addr(FAR net_ipaddr_t *outaddr,
+static void ioctl_setipv6addr(FAR net_ipv6addr_t outaddr,
FAR const struct sockaddr_storage *inaddr)
{
FAR const struct sockaddr_in6 *src = (FAR const struct sockaddr_in6 *)inaddr;
@@ -288,7 +287,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd,
dev = netdev_ifrdev(req);
if (dev)
{
- ioctl_getipv4addr(&req->ifr_addr, &dev->d_ipaddr);
+ ioctl_getipv4addr(&req->ifr_addr, dev->d_ipaddr);
ret = OK;
}
}
@@ -317,7 +316,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd,
dev = netdev_ifrdev(req);
if (dev)
{
- ioctl_getipv4addr(&req->ifr_dstaddr, &dev->d_draddr);
+ ioctl_getipv4addr(&req->ifr_dstaddr, dev->d_draddr);
ret = OK;
}
}
@@ -352,7 +351,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd,
dev = netdev_ifrdev(req);
if (dev)
{
- ioctl_getipv4addr(&req->ifr_addr, &dev->d_netmask);
+ ioctl_getipv4addr(&req->ifr_addr, dev->d_netmask);
ret = OK;
}
}
@@ -380,7 +379,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd,
{
FAR struct lifreq *lreq = (FAR struct lifreq *)req;
- ioctl_getipv6addr(&lreq->lifr_addr, &dev->d_ipaddr);
+ ioctl_getipv6addr(&lreq->lifr_addr, dev->d_ipv6addr);
ret = OK;
}
}
@@ -396,7 +395,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd,
FAR struct lifreq *lreq = (FAR struct lifreq *)req;
ioctl_ifdown(dev);
- ioctl_setipv6addr(&dev->d_ipaddr, &lreq->lifr_addr);
+ ioctl_setipv6addr(dev->d_ipv6addr, &lreq->lifr_addr);
ioctl_ifup(dev);
ret = OK;
}
@@ -412,7 +411,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd,
{
FAR struct lifreq *lreq = (FAR struct lifreq *)req;
- ioctl_getipv6addr(&lreq->lifr_dstaddr, &dev->d_draddr);
+ ioctl_getipv6addr(&lreq->lifr_dstaddr, dev->d_ipv6draddr);
ret = OK;
}
}
@@ -427,7 +426,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd,
{
FAR struct lifreq *lreq = (FAR struct lifreq *)req;
- ioctl_setipv6addr(&dev->d_draddr, &lreq->lifr_dstaddr);
+ ioctl_setipv6addr(dev->d_ipv6draddr, &lreq->lifr_dstaddr);
ret = OK;
}
}
@@ -451,7 +450,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd,
{
FAR struct lifreq *lreq = (FAR struct lifreq *)req;
- ioctl_getipv6addr(&lreq->lifr_addr, &dev->d_netmask);
+ ioctl_getipv6addr(&lreq->lifr_addr, dev->d_ipv6netmask);
ret = OK;
}
}
@@ -465,7 +464,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd,
if (dev)
{
FAR struct lifreq *lreq = (FAR struct lifreq *)req;
- ioctl_setipv6addr(&dev->d_netmask, &lreq->lifr_addr);
+ ioctl_setipv6addr(dev->d_ipv6netmask, &lreq->lifr_addr);
ret = OK;
}
}
@@ -560,7 +559,12 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd,
if (dev)
{
ioctl_ifdown(dev);
- memset(&dev->d_ipaddr, 0, sizeof(net_ipaddr_t));
+#ifdef CONFIG_NET_IPv4
+ dev->d_ipaddr = 0;
+#endif
+#ifdef CONFIG_NET_IPv6
+ memset(&dev->d_ipv6addr, 0, sizeof(net_ipv6addr_t));
+#endif
ret = OK;
}
}
diff --git a/nuttx/net/netdev/netdev_rxnotify.c b/nuttx/net/netdev/netdev_rxnotify.c
index e471dbb54..a859d8178 100644
--- a/nuttx/net/netdev/netdev_rxnotify.c
+++ b/nuttx/net/netdev/netdev_rxnotify.c
@@ -102,9 +102,9 @@ void netdev_rxnotify(const net_ipaddr_t ripaddr)
/* Find the device driver that serves the subnet of the remote address */
#ifdef CONFIG_NET_MULTILINK
- dev = netdev_findbyaddr(lipaddr, ripaddr);
+ dev = netdev_findby_ipv4addr(lipaddr, ripaddr);
#else
- dev = netdev_findbyaddr(ripaddr);
+ dev = netdev_findby_ipv4addr(ripaddr);
#endif
if (dev && dev->d_rxavail)
diff --git a/nuttx/net/netdev/netdev_txnotify.c b/nuttx/net/netdev/netdev_txnotify.c
index 644a6a2a2..1e9a80c47 100644
--- a/nuttx/net/netdev/netdev_txnotify.c
+++ b/nuttx/net/netdev/netdev_txnotify.c
@@ -102,9 +102,9 @@ void netdev_txnotify(const net_ipaddr_t ripaddr)
/* Find the device driver that serves the subnet of the remote address */
#ifdef CONFIG_NET_MULTILINK
- dev = netdev_findbyaddr(lipaddr, ripaddr);
+ dev = netdev_findby_ipv4addr(lipaddr, ripaddr);
#else
- dev = netdev_findbyaddr(ripaddr);
+ dev = netdev_findby_ipv4addr(ripaddr);
#endif
if (dev && dev->d_txavail)
diff --git a/nuttx/net/pkt/pkt_poll.c b/nuttx/net/pkt/pkt_poll.c
index 7c8384268..e3db35b56 100644
--- a/nuttx/net/pkt/pkt_poll.c
+++ b/nuttx/net/pkt/pkt_poll.c
@@ -102,8 +102,8 @@ void pkt_poll(FAR struct net_driver_s *dev, FAR struct pkt_conn_s *conn)
{
/* Setup for the application callback */
- dev->d_appdata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPUDP_HDRLEN];
- dev->d_snddata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPUDP_HDRLEN];
+ dev->d_appdata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPv4UDP_HDRLEN];
+ dev->d_snddata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPv4UDP_HDRLEN];
dev->d_len = 0;
dev->d_sndlen = 0;
diff --git a/nuttx/net/socket/getsockname.c b/nuttx/net/socket/getsockname.c
index 34fea0c12..04b96b01b 100644
--- a/nuttx/net/socket/getsockname.c
+++ b/nuttx/net/socket/getsockname.c
@@ -61,26 +61,14 @@
****************************************************************************/
/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Function: getsockname
+ * Function: get_ipv4_sockname
*
* Description:
* The getsockname() function retrieves the locally-bound name of the
- * specified socket, stores this address in the sockaddr structure pointed
- * to by the 'addr' argument, and stores the length of this address in the
- * object pointed to by the 'addrlen' argument.
- *
- * If the actual length of the address is greater than the length of the
- * supplied sockaddr structure, the stored address will be truncated.
- *
- * If the socket has not been bound to a local name, the value stored in
- * the object pointed to by address is unspecified.
+ * specified PF_NET socket.
*
* Parameters:
- * sockfd Socket descriptor of socket [in]
+ * psock Point to the socket structure instance [in]
* addr sockaddr structure to receive data [out]
* addrlen Length of sockaddr structure [in/out]
*
@@ -98,56 +86,152 @@
*
****************************************************************************/
-int getsockname(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
+#ifdef CONFIG_NET_IPv4
+int ipv4_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr,
+ FAR socklen_t *addrlen)
{
- FAR struct socket *psock = sockfd_socket(sockfd);
FAR struct net_driver_s *dev;
-
#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_UDP)
-#ifdef CONFIG_NET_IPv6
- FAR struct sockaddr_in6 *outaddr = (FAR struct sockaddr_in6 *)addr;
-#else
FAR struct sockaddr_in *outaddr = (FAR struct sockaddr_in *)addr;
#endif
+#ifdef CONFIG_NETDEV_MULTINIC
+ in_addr_t lipaddr;
+ in_addr_t ripaddr;
#endif
- int err;
+ /* Check if enough space has been provided for the full address */
- /* Verify that the sockfd corresponds to valid, allocated socket */
+ if (*addrlen < sizeof(struct sockaddr_in))
+ {
+ /* This function is supposed to return the partial address if
+ * a smaller buffer has been provided. This support has not
+ * been implemented.
+ */
- if (!psock || psock->s_crefs <= 0)
+ return -ENOSYS;
+ }
+
+ /* Set the port number */
+
+ switch (psock->s_type)
{
- err = EBADF;
- goto errout;
+#ifdef CONFIG_NET_TCP
+ case SOCK_STREAM:
+ {
+ FAR struct tcp_conn_s *tcp_conn = (FAR struct tcp_conn_s *)psock->s_conn;
+ outaddr->sin_port = tcp_conn->lport; /* Already in network byte order */
+#ifdef CONFIG_NETDEV_MULTINIC
+ lipaddr = tcp_conn->lipaddr;
+ ripaddr = tcp_conn->ripaddr;
+#endif
+ }
+ break;
+#endif
+
+#ifdef CONFIG_NET_UDP
+ case SOCK_DGRAM:
+ {
+ FAR struct udp_conn_s *udp_conn = (FAR struct udp_conn_s *)psock->s_conn;
+ outaddr->sin_port = udp_conn->lport; /* Already in network byte order */
+#ifdef CONFIG_NETDEV_MULTINIC
+ lipaddr = udp_conn->lipaddr;
+ ripaddr = udp_conn->ripaddr;
+#endif
+ }
+ break;
+#endif
+
+ default:
+ return -EOPNOTSUPP;
}
- /* Some sanity checking... Shouldn't need this on a buckled up embedded
- * system (?)
+ /* The socket/connection does not know its IP address unless
+ * CONFIG_NETDEV_MULTINIC is selected. Otherwise the design supports only
+ * a single network device and only the network device knows the IP address.
*/
-#ifdef CONFIG_DEBUG
- if (!addr || !addrlen)
+ netdev_semtake();
+
+#ifdef CONFIG_NETDEV_MULTINIC
+ /* Find the device matching the IPv4 address in the connection structure */
+
+ dev = netdev_findby_ipv4addr(lipaddr, ripaddr);
+#else
+ /* There is only one, the first network device in the list. */
+
+ dev = g_netdevices;
+#endif
+
+ if (!dev)
{
- err = EINVAL;
- goto errout;
+ netdev_semgive();
+ return -EINVAL;
}
+
+ /* Set the address family and the IP address */
+
+#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_UDP)
+ outaddr->sin_family = AF_INET;
+ outaddr->sin_addr.s_addr = dev->d_ipaddr;
+ *addrlen = sizeof(struct sockaddr_in);
#endif
+ netdev_semgive();
- /* Check if enough space has been provided for the full address */
+ /* Return success */
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Function: ipv6_getsockname
+ *
+ * Description:
+ * The getsockname() function retrieves the locally-bound name of the
+ * specified PF_NET6 socket.
+ *
+ * Parameters:
+ * psock Point to the socket structure instance [in]
+ * addr sockaddr structure to receive data [out]
+ * addrlen Length of sockaddr structure [in/out]
+ *
+ * Returned Value:
+ * On success, 0 is returned, the 'addr' argument points to the address
+ * of the socket, and the 'addrlen' argument points to the length of the
+ * address. Otherwise, -1 is returned and errno is set to indicate the error.
+ * Possible errno values that may be returned include:
+ *
+ * EBADF - The socket argument is not a valid file descriptor.
+ * EOPNOTSUPP - The operation is not supported for this socket's protocol.
+ * EINVAL - The socket has been shut down.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
#ifdef CONFIG_NET_IPv6
- if (*addrlen < sizeof(struct sockaddr_in6))
-#else
- if (*addrlen < sizeof(struct sockaddr_in))
+int ipv6_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr,
+ FAR socklen_t *addrlen)
+{
+ FAR struct net_driver_s *dev;
+#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_UDP)
+ FAR struct sockaddr_in6 *outaddr = (FAR struct sockaddr_in6 *)addr;
+#endif
+#ifdef CONFIG_NETDEV_MULTINIC
+ net_ipv6addr_t *lipaddr;
+ net_ipv6addr_t *ripaddr;
#endif
+
+ /* Check if enough space has been provided for the full address */
+
+ if (*addrlen < sizeof(struct sockaddr_in6))
{
/* This function is supposed to return the partial address if
* a smaller buffer has been provided. This support has not
* been implemented.
*/
- err = ENOSYS;
- goto errout;
+ return -ENOSYS;
}
/* Set the port number */
@@ -159,6 +243,10 @@ int getsockname(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
{
FAR struct tcp_conn_s *tcp_conn = (FAR struct tcp_conn_s *)psock->s_conn;
outaddr->sin_port = tcp_conn->lport; /* Already in network byte order */
+#ifdef CONFIG_NETDEV_MULTINIC
+ lipaddr = tcp_conn->lipaddr;
+ ripaddr = tcp_conn->ripaddr;
+#endif
}
break;
#endif
@@ -168,6 +256,10 @@ int getsockname(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
{
FAR struct udp_conn_s *udp_conn = (FAR struct udp_conn_s *)psock->s_conn;
outaddr->sin_port = udp_conn->lport; /* Already in network byte order */
+#ifdef CONFIG_NETDEV_MULTINIC
+ lipaddr = &udp_conn->lipaddr;
+ ripaddr = &udp_conn->ripaddr;
+#endif
}
break;
#endif
@@ -177,42 +269,139 @@ int getsockname(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
goto errout;
}
- /* ISSUE: As of this writing, the socket/connection does not know its IP
- * address. This is because the uIP design is only intended to support
- * a single network device and, therefore, only the network device knows
- * the IP address.
- *
- * Right now, we can just pick the first network device. But that may
- * not work in the future.
+ /* The socket/connection does not know its IP address unless
+ * CONFIG_NETDEV_MULTINIC is selected. Otherwise the design supports only
+ * a single network device and only the network device knows the IP address.
*/
netdev_semtake();
+
+#ifdef CONFIG_NETDEV_MULTINIC
+ /* Find the device matching the IPv6 address in the connection structure */
+
+ dev = netdev_findby_ipv6addr(*lipaddr, *ripaddr);
+#else
+ /* There is only one, the first network device in the list. */
+
dev = g_netdevices;
+#endif
+
if (!dev)
{
netdev_semgive();
- err = EINVAL;
- goto errout;
+ return -EINVAL;
}
/* Set the address family and the IP address */
#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_UDP)
-#ifdef CONFIG_NET_IPv6
outaddr->sin_family = AF_INET6;
memcpy(outaddr->sin6_addr.in6_u.u6_addr8, dev->d_ipaddr, 16);
*addrlen = sizeof(struct sockaddr_in6);
-#else
- outaddr->sin_family = AF_INET;
- outaddr->sin_addr.s_addr = dev->d_ipaddr;
- *addrlen = sizeof(struct sockaddr_in);
-#endif
#endif
netdev_semgive();
/* Return success */
return OK;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: getsockname
+ *
+ * Description:
+ * The getsockname() function retrieves the locally-bound name of the
+ * specified socket, stores this address in the sockaddr structure pointed
+ * to by the 'addr' argument, and stores the length of this address in the
+ * object pointed to by the 'addrlen' argument.
+ *
+ * If the actual length of the address is greater than the length of the
+ * supplied sockaddr structure, the stored address will be truncated.
+ *
+ * If the socket has not been bound to a local name, the value stored in
+ * the object pointed to by address is unspecified.
+ *
+ * Parameters:
+ * sockfd Socket descriptor of socket [in]
+ * addr sockaddr structure to receive data [out]
+ * addrlen Length of sockaddr structure [in/out]
+ *
+ * Returned Value:
+ * On success, 0 is returned, the 'addr' argument points to the address
+ * of the socket, and the 'addrlen' argument points to the length of the
+ * address. Otherwise, -1 is returned and errno is set to indicate the error.
+ * Possible errno values that may be returned include:
+ *
+ * EBADF - The socket argument is not a valid file descriptor.
+ * EOPNOTSUPP - The operation is not supported for this socket's protocol.
+ * EINVAL - The socket has been shut down.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int getsockname(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
+{
+ FAR struct socket *psock = sockfd_socket(sockfd);
+ int ret;
+ int err;
+
+ /* Verify that the sockfd corresponds to valid, allocated socket */
+
+ if (!psock || psock->s_crefs <= 0)
+ {
+ err = EBADF;
+ goto errout;
+ }
+
+ /* Some sanity checking... Shouldn't need this on a buckled up embedded
+ * system (?)
+ */
+
+#ifdef CONFIG_DEBUG
+ if (!addr || !addrlen)
+ {
+ err = EINVAL;
+ goto errout;
+ }
+#endif
+
+ /* Handle by address domain */
+
+ switch (psock->s_domain)
+ {
+#ifdef CONFIG_NET_IPv4
+ case PF_INET:
+ ret = ipv4_getsockname(psock, addr, addrlen);
+ break;
+#endif
+
+#ifdef CONFIG_NET_IPv6
+ case PF_INET6:
+ ret = ipv6_getsockname(psock, addr, addrlen);
+ break;
+#endif
+
+ case PF_PACKET:
+ default:
+ err = EAFNOSUPPORT;
+ goto errout;
+ }
+
+ /* Check for failure */
+
+ if (ret < 0)
+ {
+ err = -ret;
+ goto errout;
+ }
+
+ return OK;
errout:
set_errno(err);
diff --git a/nuttx/net/socket/recvfrom.c b/nuttx/net/socket/recvfrom.c
index 160246715..a16f23c2b 100644
--- a/nuttx/net/socket/recvfrom.c
+++ b/nuttx/net/socket/recvfrom.c
@@ -74,8 +74,13 @@
* Pre-processor Definitions
****************************************************************************/
-#define UDPBUF ((struct udp_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
-#define TCPBUF ((struct tcp_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
+#if defined(CONFIG_NET_IPv4)
+# define UDPBUF ((struct udp_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
+# define TCPBUF ((struct tcp_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
+#elif defined(CONFIG_NET_IPv6)
+# define UDPBUF ((struct udp_ipv6hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
+# define TCPBUF ((struct tcp_ipv6hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
+#endif
/****************************************************************************
* Private Types
diff --git a/nuttx/net/socket/socket.c b/nuttx/net/socket/socket.c
index 505dbfc0e..6dadf79d3 100644
--- a/nuttx/net/socket/socket.c
+++ b/nuttx/net/socket/socket.c
@@ -1,7 +1,7 @@
/****************************************************************************
* net/socket/socket.c
*
- * Copyright (C) 2007-2009, 2012, 2014 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009, 2012, 2014-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -96,66 +96,85 @@
int psock_socket(int domain, int type, int protocol, FAR struct socket *psock)
{
+ bool ipdomain = false;
int err;
/* Only PF_INET, PF_INET6 or PF_PACKET domains supported */
- if (
-#if defined(CONFIG_NET_IPv6)
- domain != PF_INET6
-#else
- domain != PF_INET
+ switch (domain)
+ {
+#ifdef CONFIG_NET_IPv4
+ case PF_INET:
+ ipdomain = true;
+ break;
#endif
-#if defined(CONFIG_NET_PKT)
- && domain != PF_PACKET
+
+#ifdef CONFIG_NET_IPv6
+ case PF_INET6:
+ ipdomain = true;
+ break;
#endif
- )
- {
+
+#ifdef CONFIG_NET_PKT
+ case PF_PACKET:
+ break;
+#endif
+
+ default:
err = EAFNOSUPPORT;
goto errout;
}
/* Only SOCK_STREAM, SOCK_DGRAM and possible SOCK_RAW are supported */
- if (
-#if defined(CONFIG_NET_TCP)
- (type == SOCK_STREAM && protocol != 0 && protocol != IPPROTO_TCP) ||
-#endif
-#if defined(CONFIG_NET_UDP)
- (type == SOCK_DGRAM && protocol != 0 && protocol != IPPROTO_UDP) ||
-#endif
- (
-#if defined(CONFIG_NET_TCP)
-#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_PKT)
- type != SOCK_STREAM &&
-#else
- type != SOCK_STREAM
-#endif
-#endif
-#if defined(CONFIG_NET_UDP)
-#if defined(CONFIG_NET_PKT)
- type != SOCK_DGRAM &&
-#else
- type != SOCK_DGRAM
+ switch (type)
+ {
+#ifdef CONFIG_NET_TCP
+ case SOCK_STREAM:
+ if ((protocol != 0 && protocol != IPPROTO_TCP) || !ipdomain)
+ {
+ err = EPROTONOSUPPORT;
+ goto errout;
+ }
+
+ break;
#endif
+
+#ifdef CONFIG_NET_UDP
+ case SOCK_DGRAM:
+ if ((protocol != 0 && protocol != IPPROTO_UDP) || !ipdomain)
+ {
+ err = EPROTONOSUPPORT;
+ goto errout;
+ }
+
+ break;
#endif
-#if defined(CONFIG_NET_PKT)
- type != SOCK_RAW
+
+#ifdef CONFIG_NET_PKT
+ case SOCK_RAW:
+ if (ipdomain)
+ {
+ err = EPROTONOSUPPORT;
+ goto errout;
+ }
+
+ break;
#endif
- )
- )
- {
- err = EPROTONOSUPPORT;
- goto errout;
+
+ default:
+ err = EPROTONOSUPPORT;
+ goto errout;
}
/* Everything looks good. Initialize the socket structure */
/* Save the protocol type */
- psock->s_type = type;
- psock->s_conn = NULL;
+ psock->s_domain = domain;
+ psock->s_type = type;
+ psock->s_conn = NULL;
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
- psock->s_sndcb = NULL;
+ psock->s_sndcb = NULL;
#endif
/* Allocate the appropriate connection structure. This reserves the
@@ -166,19 +185,19 @@ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock)
err = ENOMEM; /* Assume failure to allocate connection instance */
switch (type)
{
-#ifdef CONFIG_NET_PKT
- case SOCK_RAW:
+#ifdef CONFIG_NET_TCP
+ case SOCK_STREAM:
{
- /* Allocate the packet socket connection structure and save
- * in the new socket instance.
+ /* Allocate the TCP connection structure and save in the new
+ * socket instance.
*/
- FAR struct pkt_conn_s *conn = pkt_alloc();
+ FAR struct tcp_conn_s *conn = tcp_alloc();
if (!conn)
{
/* Failed to reserve a connection structure */
- goto errout;
+ goto errout; /* With err == ENFILE or ENOMEM */
}
/* Set the reference count on the connection structure. This
@@ -193,14 +212,14 @@ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock)
break;
#endif
-#ifdef CONFIG_NET_TCP
- case SOCK_STREAM:
+#ifdef CONFIG_NET_UDP
+ case SOCK_DGRAM:
{
- /* Allocate the TCP connection structure and save in the new
+ /* Allocate the UDP connection structure and save in the new
* socket instance.
*/
- FAR struct tcp_conn_s *conn = tcp_alloc();
+ FAR struct udp_conn_s *conn = udp_alloc();
if (!conn)
{
/* Failed to reserve a connection structure */
@@ -220,19 +239,19 @@ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock)
break;
#endif
-#ifdef CONFIG_NET_UDP
- case SOCK_DGRAM:
+#ifdef CONFIG_NET_PKT
+ case SOCK_RAW:
{
- /* Allocate the UDP connection structure and save in the new
- * socket instance.
+ /* Allocate the packet socket connection structure and save
+ * in the new socket instance.
*/
- FAR struct udp_conn_s *conn = udp_alloc();
+ FAR struct pkt_conn_s *conn = pkt_alloc();
if (!conn)
{
/* Failed to reserve a connection structure */
- goto errout; /* With err == ENFILE or ENOMEM */
+ goto errout;
}
/* Set the reference count on the connection structure. This
diff --git a/nuttx/net/tcp/tcp.h b/nuttx/net/tcp/tcp.h
index f7afc6ff0..863c227cc 100644
--- a/nuttx/net/tcp/tcp.h
+++ b/nuttx/net/tcp/tcp.h
@@ -103,6 +103,7 @@
struct net_driver_s; /* Forward reference */
struct devif_callback_s; /* Forward reference */
struct tcp_backlog_s; /* Forward reference */
+struct tcp_hdr_s; /* Forward reference */
struct tcp_conn_s
{
@@ -272,7 +273,7 @@ extern "C"
struct tcp_iphdr_s; /* Forward reference */
/****************************************************************************
- * Name: tcp_initialize()
+ * Name: tcp_initialize
*
* Description:
* Initialize the TCP/IP connection structures. Called only once and only
@@ -283,12 +284,12 @@ struct tcp_iphdr_s; /* Forward reference */
void tcp_initialize(void);
/****************************************************************************
- * Name: tcp_alloc()
+ * Name: tcp_alloc
*
* Description:
* Find a free TCP/IP connection structure and allocate it
* for use. This is normally something done by the implementation of the
- * socket() API but is also called from the interrupt level when a TCP
+ * socket() API but is also called from the driver level when a TCP
* packet is received while "listening"
*
****************************************************************************/
@@ -296,7 +297,7 @@ void tcp_initialize(void);
FAR struct tcp_conn_s *tcp_alloc(void);
/****************************************************************************
- * Name: tcp_free()
+ * Name: tcp_free
*
* Description:
* Free a connection structure that is no longer in use. This should be
@@ -307,51 +308,51 @@ FAR struct tcp_conn_s *tcp_alloc(void);
void tcp_free(FAR struct tcp_conn_s *conn);
/****************************************************************************
- * Name: tcp_active()
+ * Name: tcp_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
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
-FAR struct tcp_conn_s *tcp_active(struct tcp_iphdr_s *buf);
+FAR struct tcp_conn_s *tcp_active(FAR struct net_driver_s *dev,
+ FAR struct tcp_hdr_s *tcp);
/****************************************************************************
- * Name: tcp_nextconn()
+ * Name: tcp_nextconn
*
* Description:
* Traverse the list of active TCP connections
*
* Assumptions:
- * This function is called from UIP logic at interrupt level (or with
- * interrupts disabled).
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
FAR struct tcp_conn_s *tcp_nextconn(FAR struct tcp_conn_s *conn);
/****************************************************************************
- * Name: tcp_alloc_accept()
+ * Name: tcp_alloc_accept
*
* Description:
- * Called when driver interrupt processing matches the incoming packet
- * with a connection in LISTEN. In that case, this function will create
- * a new connection and initialize it to send a SYNACK in return.
+ * Called when driver processing matches the incoming packet with a
+ * connection in LISTEN. In that case, this function will create a new
+ * connection and initialize it to send a SYNACK in return.
*
* Assumptions:
- * This function is called from UIP logic at interrupt level
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
- FAR struct tcp_iphdr_s *buf);
+ FAR struct tcp_hdr_s *tcp);
/****************************************************************************
- * Name: tcp_bind()
+ * Name: tcp_bind
*
* Description:
* This function implements the lower level parts of the standard TCP
@@ -409,7 +410,7 @@ int tcp_connect(FAR struct tcp_conn_s *conn,
* Set the TCP/IP sequence number
*
* Assumptions:
- * This function may called from the interrupt level
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -422,7 +423,7 @@ void tcp_setsequence(FAR uint8_t *seqno, uint32_t value);
* Get the TCP/IP sequence number
*
* Assumptions:
- * This function may called from the interrupt level
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -435,7 +436,7 @@ uint32_t tcp_getsequence(FAR uint8_t *seqno);
* Add the length to get the next TCP sequence number.
*
* Assumptions:
- * This function may called from the interrupt level
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -449,7 +450,7 @@ uint32_t tcp_addsequence(FAR uint8_t *seqno, uint16_t len);
* established.
*
* Assumptions:
- * This function may called from the interrupt level
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -462,7 +463,7 @@ void tcp_initsequence(FAR uint8_t *seqno);
* Increment the TCP/IP sequence number
*
* Assumptions:
- * This function is called from the interrupt level
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -483,7 +484,7 @@ void tcp_nextsequence(void);
* None
*
* Assumptions:
- * Called from the interrupt level or with interrupts disabled.
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -505,7 +506,7 @@ void tcp_poll(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn);
* None
*
* Assumptions:
- * Called from the interrupt level or with interrupts disabled.
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -560,7 +561,7 @@ int tcp_listen(FAR struct tcp_conn_s *conn);
* Return true is there is a listener for the specified port
*
* Assumptions:
- * Called at interrupt level
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -573,7 +574,7 @@ bool tcp_islistener(uint16_t portno);
* Accept the new connection for the specified listening port.
*
* Assumptions:
- * Called at interrupt level
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -597,7 +598,7 @@ int tcp_accept_connection(FAR struct net_driver_s *dev,
* None
*
* Assumptions:
- * Called from the interrupt level or with interrupts disabled.
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -617,7 +618,7 @@ void tcp_send(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
* None
*
* Assumptions:
- * Called from the interrupt level or with interrupts disabled.
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -638,7 +639,7 @@ void tcp_reset(FAR struct net_driver_s *dev);
* None
*
* Assumptions:
- * Called from the interrupt level or with interrupts disabled.
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -663,7 +664,7 @@ void tcp_ack(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
* None
*
* Assumptions:
- * Called from the interrupt level or with interrupts disabled.
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -685,7 +686,7 @@ void tcp_appsend(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
* None
*
* Assumptions:
- * Called from the interrupt level or with interrupts disabled.
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -694,10 +695,10 @@ void tcp_rexmit(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
/* Defined in tcp_input.c ***************************************************/
/****************************************************************************
- * Name: tcp_input
+ * Name: tcp_ipv4_input
*
* Description:
- * Handle incoming TCP input
+ * Handle incoming TCP input with IPv4 header
*
* Parameters:
* dev - The device driver structure containing the received TCP packet.
@@ -706,11 +707,34 @@ void tcp_rexmit(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
* None
*
* Assumptions:
- * Called from the interrupt level or with interrupts disabled.
+ * Called from the Ethernet driver with the network stack locked
*
****************************************************************************/
-void tcp_input(FAR struct net_driver_s *dev);
+#ifdef CONFIG_NET_IPv4
+void tcp_ipv4_input(FAR struct net_driver_s *dev);
+#endif
+
+/****************************************************************************
+ * Name: tcp_ipv6_input
+ *
+ * Description:
+ * Handle incoming TCP input with IPv4 header
+ *
+ * Parameters:
+ * dev - The device driver structure containing the received TCP packet.
+ *
+ * Return:
+ * None
+ *
+ * Assumptions:
+ * Called from the Ethernet driver with the network stack locked
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv6
+void tcp_ipv6_input(FAR struct net_driver_s *dev);
+#endif
/* Defined in tcp_callback.c ************************************************/
/****************************************************************************
@@ -720,7 +744,7 @@ void tcp_input(FAR struct net_driver_s *dev);
* Inform the application holding the TCP socket of a change in state.
*
* Assumptions:
- * This function is called at the interrupt level with interrupts disabled.
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -749,7 +773,7 @@ uint16_t tcp_callback(FAR struct net_driver_s *dev,
* Assumptions:
* - The caller has checked that TCP_NEWDATA is set in flags and that is no
* other handler available to process the incoming data.
- * - This function is called at the interrupt level with interrupts disabled.
+ * - Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -788,8 +812,7 @@ int tcp_backlogcreate(FAR struct tcp_conn_s *conn, int nblg);
* is freed that has pending connections.
*
* Assumptions:
- * The caller has disabled interrupts so that there can be no conflict
- * with ongoing, interrupt driven activity
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -808,7 +831,7 @@ int tcp_backlogdestroy(FAR struct tcp_conn_s *conn);
* function adds the new connection to the backlog.
*
* Assumptions:
- * Called from the interrupt level with interrupts disabled
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -864,7 +887,7 @@ FAR struct tcp_conn_s *tcp_backlogremove(FAR struct tcp_conn_s *conn);
* to remove the defunct connection from the list.
*
* Assumptions:
- * Called from the interrupt level with interrupts disabled
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -984,7 +1007,7 @@ FAR struct tcp_wrbuffer_s *tcp_wrbuffer_alloc(void);
* buffered data.
*
* Assumptions:
- * Called from interrupt level with interrupts disabled.
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
diff --git a/nuttx/net/tcp/tcp_appsend.c b/nuttx/net/tcp/tcp_appsend.c
index 1d1670ca8..339e2f255 100644
--- a/nuttx/net/tcp/tcp_appsend.c
+++ b/nuttx/net/tcp/tcp_appsend.c
@@ -112,7 +112,7 @@ void tcp_appsend(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
conn->tcpstateflags = TCP_CLOSED;
nllvdbg("TCP state: TCP_CLOSED\n");
- tcp_send(dev, conn, TCP_RST | TCP_ACK, IPTCP_HDRLEN);
+ tcp_send(dev, conn, TCP_RST | TCP_ACK, IPv4TCP_HDRLEN);
}
/* Check for connection closed */
@@ -125,7 +125,7 @@ void tcp_appsend(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
nllvdbg("TCP state: TCP_FIN_WAIT_1\n");
dev->d_sndlen = 0;
- tcp_send(dev, conn, TCP_FIN | TCP_ACK, IPTCP_HDRLEN);
+ tcp_send(dev, conn, TCP_FIN | TCP_ACK, IPv4TCP_HDRLEN);
}
/* None of the above */
@@ -204,14 +204,14 @@ void tcp_rexmit(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
* the IP and TCP headers.
*/
- tcp_send(dev, conn, TCP_ACK | TCP_PSH, dev->d_sndlen + IPTCP_HDRLEN);
+ tcp_send(dev, conn, TCP_ACK | TCP_PSH, dev->d_sndlen + IPv4TCP_HDRLEN);
}
/* If there is no data to send, just send out a pure ACK if one is requested`. */
else if ((result & TCP_SNDACK) != 0)
{
- tcp_send(dev, conn, TCP_ACK, IPTCP_HDRLEN);
+ tcp_send(dev, conn, TCP_ACK, IPv4TCP_HDRLEN);
}
/* There is nothing to do -- drop the packet */
diff --git a/nuttx/net/tcp/tcp_conn.c b/nuttx/net/tcp/tcp_conn.c
index 5209646b1..f5f46a829 100644
--- a/nuttx/net/tcp/tcp_conn.c
+++ b/nuttx/net/tcp/tcp_conn.c
@@ -61,6 +61,13 @@
#include "tcp/tcp.h"
/****************************************************************************
+ * 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)])
+
+/****************************************************************************
* Private Data
****************************************************************************/
@@ -85,7 +92,7 @@ static uint16_t g_last_tcp_port;
****************************************************************************/
/****************************************************************************
- * Name: tcp_listener()
+ * Name: tcp_listener
*
* Description:
* Given a local port number (in network byte order), find the TCP
@@ -144,7 +151,7 @@ static FAR struct tcp_conn_s *tcp_listener(uint16_t portno)
}
/****************************************************************************
- * Name: tcp_selectport()
+ * Name: tcp_selectport
*
* Description:
* If the port number is zero; select an unused port for the connection.
@@ -230,7 +237,7 @@ static int tcp_selectport(uint16_t portno)
****************************************************************************/
/****************************************************************************
- * Name: tcp_initialize()
+ * Name: tcp_initialize
*
* Description:
* Initialize the TCP/IP connection structures. Called only once and only
@@ -261,7 +268,7 @@ void tcp_initialize(void)
}
/****************************************************************************
- * Name: tcp_alloc()
+ * Name: tcp_alloc
*
* Description:
* Find a free TCP/IP connection structure and allocate it
@@ -374,7 +381,7 @@ FAR struct tcp_conn_s *tcp_alloc(void)
}
/****************************************************************************
- * Name: tcp_free()
+ * Name: tcp_free
*
* Description:
* Free a connection structure that is no longer in use. This should be
@@ -466,7 +473,7 @@ void tcp_free(FAR struct tcp_conn_s *conn)
}
/****************************************************************************
- * Name: tcp_active()
+ * Name: tcp_active
*
* Description:
* Find a connection structure that is the appropriate
@@ -477,12 +484,20 @@ void tcp_free(FAR struct tcp_conn_s *conn)
*
****************************************************************************/
-FAR struct tcp_conn_s *tcp_active(struct tcp_iphdr_s *buf)
+FAR struct tcp_conn_s *tcp_active(FAR struct net_driver_s *dev,
+ FAR struct tcp_hdr_s *tcp)
{
- FAR struct tcp_conn_s *conn = (struct tcp_conn_s *)g_active_tcp_connections.head;
- in_addr_t srcipaddr = net_ip4addr_conv32(buf->srcipaddr);
+ 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 = net_ip4addr_conv32(buf->destipaddr);
+ 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)
@@ -507,8 +522,8 @@ FAR struct tcp_conn_s *tcp_active(struct tcp_iphdr_s *buf)
*/
if (conn->tcpstateflags != TCP_CLOSED &&
- buf->destport == conn->lport &&
- buf->srcport == conn->rport &&
+ tcp->destport == conn->lport &&
+ tcp->srcport == conn->rport &&
#ifdef CONFIG_NETDEV_MULTINIC
(net_ipaddr_cmp(conn->lipaddr, g_allzeroaddr) ||
net_ipaddr_cmp(destipaddr, conn->lipaddr)) &&
@@ -531,7 +546,7 @@ FAR struct tcp_conn_s *tcp_active(struct tcp_iphdr_s *buf)
}
/****************************************************************************
- * Name: tcp_nextconn()
+ * Name: tcp_nextconn
*
* Description:
* Traverse the list of active TCP connections
@@ -555,7 +570,7 @@ FAR struct tcp_conn_s *tcp_nextconn(FAR struct tcp_conn_s *conn)
}
/****************************************************************************
- * Name: tcp_alloc_accept()
+ * Name: tcp_alloc_accept
*
* Description:
* Called when driver interrupt processing matches the incoming packet
@@ -568,9 +583,12 @@ 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_iphdr_s *buf)
+ FAR struct tcp_hdr_s *tcp)
{
- FAR struct tcp_conn_s *conn = tcp_alloc();
+ FAR struct net_iphdr_s *ip = IPv4;
+ FAR struct tcp_conn_s *conn;
+
+ conn = tcp_alloc();
if (conn)
{
/* Fill in the necessary fields for the new connection. */
@@ -580,12 +598,12 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
conn->sa = 0;
conn->sv = 4;
conn->nrtx = 0;
- conn->lport = buf->destport;
- conn->rport = buf->srcport;
+ conn->lport = tcp->destport;
+ conn->rport = tcp->srcport;
conn->mss = TCP_INITIAL_MSS(dev);
- net_ipaddr_copy(conn->ripaddr, net_ip4addr_conv32(buf->srcipaddr));
+ net_ipaddr_copy(conn->ripaddr, net_ip4addr_conv32(ip->srcipaddr));
#ifdef CONFIG_NETDEV_MULTINIC
- net_ipaddr_copy(conn->lipaddr, net_ip4addr_conv32(buf->destipaddr));
+ net_ipaddr_copy(conn->lipaddr, net_ip4addr_conv32(ip->destipaddr));
#endif
conn->tcpstateflags = TCP_SYN_RCVD;
@@ -599,7 +617,7 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
/* rcvseq should be the seqno from the incoming packet + 1. */
- memcpy(conn->rcvseq, buf->seqno, 4);
+ memcpy(conn->rcvseq, tcp->seqno, 4);
#ifdef CONFIG_NET_TCP_READAHEAD
/* Initialize the list of TCP read-ahead buffers */
@@ -625,7 +643,7 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
}
/****************************************************************************
- * Name: tcp_bind()
+ * Name: tcp_bind
*
* Description:
* This function implements the lower level parts of the standard TCP
diff --git a/nuttx/net/tcp/tcp_input.c b/nuttx/net/tcp/tcp_input.c
index c447045ec..c7c808afd 100644
--- a/nuttx/net/tcp/tcp_input.c
+++ b/nuttx/net/tcp/tcp_input.c
@@ -64,8 +64,6 @@
* Pre-processor Definitions
****************************************************************************/
-#define BUF ((struct tcp_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
-
/****************************************************************************
* Public Variables
****************************************************************************/
@@ -79,17 +77,15 @@
****************************************************************************/
/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
* Name: tcp_input
*
* Description:
* Handle incoming TCP input
*
* Parameters:
- * dev - The device driver structure containing the received TCP packet.
+ * dev - The device driver structure containing the received TCP packet.
+ * tcp - A pointer to the TCP header in the packet
+ * tcpiplen - Combined length of the IP and TCP headers
*
* Return:
* None
@@ -99,10 +95,11 @@
*
****************************************************************************/
-void tcp_input(FAR struct net_driver_s *dev)
+static void tcp_input(FAR struct net_driver_s *dev,
+ FAR struct tcp_hdr_s *tcp, unsigned int tcpiplen)
{
FAR struct tcp_conn_s *conn = NULL;
- FAR struct tcp_iphdr_s *pbuf = BUF;
+ unsigned int hdrlen;
uint16_t tmp16;
uint16_t flags;
uint8_t opt;
@@ -110,13 +107,21 @@ void tcp_input(FAR struct net_driver_s *dev)
int len;
int i;
- dev->d_snddata = &dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev)];
- dev->d_appdata = &dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev)];
-
#ifdef CONFIG_NET_STATISTICS
+ /* Bump up the count of TCP packets received */
+
g_netstats.tcp.recv++;
#endif
+ /* Get the size of the link layer header, the IP header, and the TCP header */
+
+ hdrlen = tcpiplen + NET_LL_HDRLEN(dev);
+
+ /* Initialize for tcp_send() */
+
+ dev->d_snddata = &dev->d_buf[hdrlen];
+ dev->d_appdata = &dev->d_buf[hdrlen];
+
/* Start of TCP input header processing code. */
if (tcp_chksum(dev) != 0xffff)
@@ -133,7 +138,7 @@ void tcp_input(FAR struct net_driver_s *dev)
/* Demultiplex this segment. First check any active connections. */
- conn = tcp_active(pbuf);
+ conn = tcp_active(dev, tcp);
if (conn)
{
/* We found an active connection.. Check for the subsequent SYN
@@ -143,7 +148,7 @@ void tcp_input(FAR struct net_driver_s *dev)
*/
if ((conn->tcpstateflags & TCP_STATE_MASK) != TCP_SYN_RCVD &&
- (BUF->flags & TCP_CTL) == TCP_SYN)
+ (tcp->flags & TCP_CTL) == TCP_SYN)
{
goto reset;
}
@@ -159,13 +164,13 @@ void tcp_input(FAR struct net_driver_s *dev)
* it is an old packet and we send a RST.
*/
- if ((pbuf->flags & TCP_CTL) == TCP_SYN)
+ if ((tcp->flags & TCP_CTL) == TCP_SYN)
{
/* This is a SYN packet for a connection. Find the connection
* listening on this port.
*/
- tmp16 = pbuf->destport;
+ tmp16 = tcp->destport;
if (tcp_islistener(tmp16))
{
/* We matched the incoming packet with a connection in LISTEN.
@@ -177,7 +182,7 @@ void tcp_input(FAR struct net_driver_s *dev)
* user application to accept it.
*/
- conn = tcp_alloc_accept(dev, pbuf);
+ conn = tcp_alloc_accept(dev, tcp);
if (conn)
{
/* The connection structure was successfully allocated. Now see if
@@ -215,11 +220,11 @@ void tcp_input(FAR struct net_driver_s *dev)
/* Parse the TCP MSS option, if present. */
- if ((pbuf->tcpoffset & 0xf0) > 0x50)
+ if ((tcp->tcpoffset & 0xf0) > 0x50)
{
- for (i = 0; i < ((pbuf->tcpoffset >> 4) - 5) << 2 ;)
+ for (i = 0; i < ((tcp->tcpoffset >> 4) - 5) << 2 ;)
{
- opt = dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + i];
+ opt = dev->d_buf[hdrlen + i];
if (opt == TCP_OPT_END)
{
/* End of options. */
@@ -233,12 +238,12 @@ void tcp_input(FAR struct net_driver_s *dev)
++i;
}
else if (opt == TCP_OPT_MSS &&
- dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 1 + i] == TCP_OPT_MSS_LEN)
+ dev->d_buf[hdrlen + 1 + i] == TCP_OPT_MSS_LEN)
{
/* An MSS option with the right option length. */
- tmp16 = ((uint16_t)dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 2 + i] << 8) |
- (uint16_t)dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 3 + i];
+ tmp16 = ((uint16_t)dev->d_buf[hdrlen + 2 + i] << 8) |
+ (uint16_t)dev->d_buf[hdrlen + 3 + i];
conn->mss = tmp16 > TCP_MSS(dev) ? TCP_MSS(dev) : tmp16;
/* And we are done processing options. */
@@ -251,7 +256,7 @@ void tcp_input(FAR struct net_driver_s *dev)
* can skip past them.
*/
- if (dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 1 + i] == 0)
+ if (dev->d_buf[hdrlen + 1 + i] == 0)
{
/* If the length field is zero, the options are malformed
* and we don't process them further.
@@ -259,7 +264,7 @@ void tcp_input(FAR struct net_driver_s *dev)
break;
}
- i += dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 1 + i];
+ i += dev->d_buf[hdrlen + 1 + i];
}
}
}
@@ -279,7 +284,7 @@ reset:
/* We do not send resets in response to resets. */
- if ((pbuf->flags & TCP_RST) != 0)
+ if ((tcp->flags & TCP_RST) != 0)
{
goto drop;
}
@@ -294,7 +299,7 @@ found:
/* Update the connection's window size */
- conn->winsize = ((uint16_t)pbuf->wnd[0] << 8) + (uint16_t)pbuf->wnd[1];
+ conn->winsize = ((uint16_t)tcp->wnd[0] << 8) + (uint16_t)tcp->wnd[1];
flags = 0;
@@ -304,7 +309,7 @@ found:
* before we accept the reset.
*/
- if ((pbuf->flags & TCP_RST) != 0)
+ if ((tcp->flags & TCP_RST) != 0)
{
conn->tcpstateflags = TCP_CLOSED;
nlldbg("RESET - TCP state: TCP_CLOSED\n");
@@ -317,7 +322,7 @@ found:
* any data to us.
*/
- len = (pbuf->tcpoffset >> 4) << 2;
+ len = (tcp->tcpoffset >> 4) << 2;
/* d_len will contain the length of the actual TCP data. This is
* calculated by subtracting the length of the TCP header (in
@@ -334,14 +339,14 @@ found:
*/
if (!((((conn->tcpstateflags & TCP_STATE_MASK) == TCP_SYN_SENT) &&
- ((pbuf->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
+ ((tcp->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
(((conn->tcpstateflags & TCP_STATE_MASK) == TCP_SYN_RCVD) &&
- ((pbuf->flags & TCP_CTL) == TCP_SYN))))
+ ((tcp->flags & TCP_CTL) == TCP_SYN))))
{
- if ((dev->d_len > 0 || ((pbuf->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
- memcmp(pbuf->seqno, conn->rcvseq, 4) != 0)
+ if ((dev->d_len > 0 || ((tcp->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
+ memcmp(tcp->seqno, conn->rcvseq, 4) != 0)
{
- tcp_send(dev, conn, TCP_ACK, IPTCP_HDRLEN);
+ tcp_send(dev, conn, TCP_ACK, tcpiplen);
return;
}
}
@@ -352,7 +357,7 @@ found:
* retransmission timer.
*/
- if ((pbuf->flags & TCP_ACK) != 0 && conn->unacked > 0)
+ if ((tcp->flags & TCP_ACK) != 0 && conn->unacked > 0)
{
uint32_t unackseq;
uint32_t ackseq;
@@ -372,7 +377,7 @@ found:
* incoming packet.
*/
- ackseq = tcp_getsequence(pbuf->ackno);
+ ackseq = tcp_getsequence(tcp->ackno);
/* Check how many of the outstanding bytes have been acknowledged. For
* a most uIP send operation, this should always be true. However,
@@ -464,7 +469,7 @@ found:
conn->tcpstateflags = TCP_ESTABLISHED;
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
- conn->isn = tcp_getsequence(pbuf->ackno);
+ conn->isn = tcp_getsequence(tcp->ackno);
tcp_setsequence(conn->sndseq, conn->isn);
conn->sent = 0;
#endif
@@ -486,7 +491,7 @@ found:
/* We need to retransmit the SYNACK */
- if ((pbuf->flags & TCP_CTL) == TCP_SYN)
+ if ((tcp->flags & TCP_CTL) == TCP_SYN)
{
tcp_ack(dev, conn, TCP_ACK | TCP_SYN);
return;
@@ -501,15 +506,15 @@ found:
* state.
*/
- if ((flags & TCP_ACKDATA) != 0 && (pbuf->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))
+ if ((flags & TCP_ACKDATA) != 0 && (tcp->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))
{
/* Parse the TCP MSS option, if present. */
- if ((pbuf->tcpoffset & 0xf0) > 0x50)
+ if ((tcp->tcpoffset & 0xf0) > 0x50)
{
- for (i = 0; i < ((pbuf->tcpoffset >> 4) - 5) << 2 ;)
+ for (i = 0; i < ((tcp->tcpoffset >> 4) - 5) << 2 ;)
{
- opt = dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + i];
+ opt = dev->d_buf[hdrlen + i];
if (opt == TCP_OPT_END)
{
/* End of options. */
@@ -523,13 +528,13 @@ found:
++i;
}
else if (opt == TCP_OPT_MSS &&
- dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 1 + i] == TCP_OPT_MSS_LEN)
+ dev->d_buf[hdrlen + 1 + i] == TCP_OPT_MSS_LEN)
{
/* An MSS option with the right option length. */
tmp16 =
- (dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 2 + i] << 8) |
- dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 3 + i];
+ (dev->d_buf[hdrlen + 2 + i] << 8) |
+ dev->d_buf[hdrlen + 3 + i];
conn->mss = tmp16 > TCP_MSS(dev) ? TCP_MSS(dev) : tmp16;
/* And we are done processing options. */
@@ -542,7 +547,7 @@ found:
* easily can skip past them.
*/
- if (dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 1 + i] == 0)
+ if (dev->d_buf[hdrlen + 1 + i] == 0)
{
/* If the length field is zero, the options are
* malformed and we don't process them further.
@@ -550,19 +555,19 @@ found:
break;
}
- i += dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 1 + i];
+ i += dev->d_buf[hdrlen + 1 + i];
}
}
}
conn->tcpstateflags = TCP_ESTABLISHED;
- memcpy(conn->rcvseq, pbuf->seqno, 4);
+ memcpy(conn->rcvseq, tcp->seqno, 4);
net_incr32(conn->rcvseq, 1);
conn->unacked = 0;
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
- conn->isn = tcp_getsequence(pbuf->ackno);
+ conn->isn = tcp_getsequence(tcp->ackno);
tcp_setsequence(conn->sndseq, conn->isn);
#endif
dev->d_len = 0;
@@ -585,7 +590,7 @@ found:
/* We do not send resets in response to resets. */
- if ((pbuf->flags & TCP_RST) != 0)
+ if ((tcp->flags & TCP_RST) != 0)
{
goto drop;
}
@@ -606,7 +611,7 @@ found:
* sequence numbers will be screwed up.
*/
- if ((pbuf->flags & TCP_FIN) != 0 && (conn->tcpstateflags & TCP_STOPPED) == 0)
+ if ((tcp->flags & TCP_FIN) != 0 && (conn->tcpstateflags & TCP_STOPPED) == 0)
{
/* Needs to be investigated further.
* Windows often sends FIN packets together with the last ACK for
@@ -639,7 +644,7 @@ found:
conn->nrtx = 0;
nllvdbg("TCP state: TCP_LAST_ACK\n");
- tcp_send(dev, conn, TCP_FIN | TCP_ACK, IPTCP_HDRLEN);
+ tcp_send(dev, conn, TCP_FIN | TCP_ACK, tcpiplen);
return;
}
@@ -647,10 +652,10 @@ found:
* data that we must pass to the application.
*/
- if ((pbuf->flags & TCP_URG) != 0)
+ if ((tcp->flags & TCP_URG) != 0)
{
#ifdef CONFIG_NET_TCPURGDATA
- dev->d_urglen = (pbuf->urgp[0] << 8) | pbuf->urgp[1];
+ dev->d_urglen = (tcp->urgp[0] << 8) | tcp->urgp[1];
if (dev->d_urglen > dev->d_len)
{
/* There is more urgent data in the next segment to come. */
@@ -667,8 +672,8 @@ found:
{
dev->d_urglen = 0;
#else /* CONFIG_NET_TCPURGDATA */
- dev->d_appdata = ((uint8_t*)dev->d_appdata) + ((pbuf->urgp[0] << 8) | pbuf->urgp[1]);
- dev->d_len -= (pbuf->urgp[0] << 8) | pbuf->urgp[1];
+ dev->d_appdata = ((uint8_t*)dev->d_appdata) + ((tcp->urgp[0] << 8) | tcp->urgp[1]);
+ dev->d_len -= (tcp->urgp[0] << 8) | tcp->urgp[1];
#endif /* CONFIG_NET_TCPURGDATA */
}
@@ -692,8 +697,7 @@ found:
* When the application is called, the d_len field
* contains the length of the incoming data. The application can
* access the incoming data through the global pointer
- * d_appdata, which usually points IPTCP_HDRLEN + NET_LL_HDRLEN(dev)
- * bytes into the d_buf array.
+ * d_appdata, which usually points hdrlen bytes into the d_buf array.
*
* If the application wishes to send any data, this data should be
* put into the d_appdata and the length of the data should be
@@ -761,7 +765,7 @@ found:
net_incr32(conn->rcvseq, dev->d_len);
}
- if ((pbuf->flags & TCP_FIN) != 0)
+ if ((tcp->flags & TCP_FIN) != 0)
{
if ((flags & TCP_ACKDATA) != 0)
{
@@ -778,7 +782,7 @@ found:
net_incr32(conn->rcvseq, 1);
(void)tcp_callback(dev, conn, TCP_CLOSE);
- tcp_send(dev, conn, TCP_ACK, IPTCP_HDRLEN);
+ tcp_send(dev, conn, TCP_ACK, tcpiplen);
return;
}
else if ((flags & TCP_ACKDATA) != 0)
@@ -791,7 +795,7 @@ found:
if (dev->d_len > 0)
{
- tcp_send(dev, conn, TCP_ACK, IPTCP_HDRLEN);
+ tcp_send(dev, conn, TCP_ACK, tcpiplen);
return;
}
@@ -803,7 +807,7 @@ found:
net_incr32(conn->rcvseq, dev->d_len);
}
- if ((pbuf->flags & TCP_FIN) != 0)
+ if ((tcp->flags & TCP_FIN) != 0)
{
conn->tcpstateflags = TCP_TIME_WAIT;
conn->timer = 0;
@@ -811,20 +815,20 @@ found:
net_incr32(conn->rcvseq, 1);
(void)tcp_callback(dev, conn, TCP_CLOSE);
- tcp_send(dev, conn, TCP_ACK, IPTCP_HDRLEN);
+ tcp_send(dev, conn, TCP_ACK, tcpiplen);
return;
}
if (dev->d_len > 0)
{
- tcp_send(dev, conn, TCP_ACK, IPTCP_HDRLEN);
+ tcp_send(dev, conn, TCP_ACK, tcpiplen);
return;
}
goto drop;
case TCP_TIME_WAIT:
- tcp_send(dev, conn, TCP_ACK, IPTCP_HDRLEN);
+ tcp_send(dev, conn, TCP_ACK, tcpiplen);
return;
case TCP_CLOSING:
@@ -843,4 +847,58 @@ drop:
dev->d_len = 0;
}
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: tcp_ipv4_input
+ *
+ * Description:
+ * Handle incoming TCP input with IPv4 header
+ *
+ * Parameters:
+ * dev - The device driver structure containing the received TCP packet.
+ *
+ * Return:
+ * None
+ *
+ * Assumptions:
+ * Called from the Ethernet driver with the network stack locked
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv4
+void tcp_ipv4_input(FAR struct net_driver_s *dev)
+{
+ unsigned int offset = IPv4_HDRLEN + NET_LL_HDRLEN(dev);
+ tcp_input(dev, (FAR struct tcp_hdr_s *)&dev->d_buf[offset], IPv4TCP_HDRLEN);
+}
+#endif
+
+/****************************************************************************
+ * Name: tcp_ipv6_input
+ *
+ * Description:
+ * Handle incoming TCP input with IPv4 header
+ *
+ * Parameters:
+ * dev - The device driver structure containing the received TCP packet.
+ *
+ * Return:
+ * None
+ *
+ * Assumptions:
+ * Called from the Ethernet driver with the network stack locked
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv6
+void tcp_ipv6_input(FAR struct net_driver_s *dev)
+{
+ unsigned int offset = IPv6_HDRLEN + NET_LL_HDRLEN(dev);
+ tcp_input(dev, (FAR struct tcp_hdr_s *)&dev->d_buf[offset], IPv6TCP_HDRLEN);
+}
+#endif
+
#endif /* CONFIG_NET && CONFIG_NET_TCP */
diff --git a/nuttx/net/tcp/tcp_poll.c b/nuttx/net/tcp/tcp_poll.c
index 0c2ea66f5..0f6175638 100644
--- a/nuttx/net/tcp/tcp_poll.c
+++ b/nuttx/net/tcp/tcp_poll.c
@@ -101,10 +101,18 @@ void tcp_poll(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn)
if ((conn->tcpstateflags & TCP_STATE_MASK) == TCP_ESTABLISHED)
{
- /* Set up for the callback */
-
- dev->d_snddata = &dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev)];
- dev->d_appdata = &dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev)];
+ /* Set up for the callback. We can't know in advance if the application
+ * is going to send a IPv4 or an IPv6 packet, so this setup may not
+ * actually be used.
+ */
+
+#if defined(CONFIG_NET_IPv4)
+ dev->d_snddata = &dev->d_buf[IPv4TCP_HDRLEN + NET_LL_HDRLEN(dev)];
+ dev->d_appdata = &dev->d_buf[IPv4TCP_HDRLEN + NET_LL_HDRLEN(dev)];
+#else /* if defined(CONFIG_NET_IPv6) */
+ dev->d_snddata = &dev->d_buf[IPv6TCP_HDRLEN + NET_LL_HDRLEN(dev)];
+ dev->d_appdata = &dev->d_buf[IPv6TCP_HDRLEN + NET_LL_HDRLEN(dev)];
+#endif
dev->d_len = 0;
dev->d_sndlen = 0;
diff --git a/nuttx/net/tcp/tcp_send.c b/nuttx/net/tcp/tcp_send.c
index 7546b2e2b..bc488b51e 100644
--- a/nuttx/net/tcp/tcp_send.c
+++ b/nuttx/net/tcp/tcp_send.c
@@ -275,7 +275,7 @@ void tcp_reset(FAR struct net_driver_s *dev)
#endif
pbuf->flags = TCP_RST | TCP_ACK;
- dev->d_len = IPTCP_HDRLEN;
+ dev->d_len = IPv4TCP_HDRLEN;
pbuf->tcpoffset = 5 << 4;
/* Flip the seqno and ackno fields in the TCP header. */
@@ -362,7 +362,7 @@ void tcp_ack(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
pbuf->optdata[1] = TCP_OPT_MSS_LEN;
pbuf->optdata[2] = TCP_MSS(dev) / 256;
pbuf->optdata[3] = TCP_MSS(dev) & 255;
- dev->d_len = IPTCP_HDRLEN + TCP_OPT_MSS_LEN;
+ dev->d_len = IPv4TCP_HDRLEN + TCP_OPT_MSS_LEN;
pbuf->tcpoffset = ((TCP_HDRLEN + TCP_OPT_MSS_LEN) / 4) << 4;
/* Complete the common portions of the TCP message */
diff --git a/nuttx/net/tcp/tcp_send_buffered.c b/nuttx/net/tcp/tcp_send_buffered.c
index c50b81040..ed0632ccd 100644
--- a/nuttx/net/tcp/tcp_send_buffered.c
+++ b/nuttx/net/tcp/tcp_send_buffered.c
@@ -79,7 +79,11 @@
* Pre-processor Definitions
****************************************************************************/
-#define TCPBUF ((struct tcp_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
+#if defined(CONFIG_NET_IPv4)
+# define TCPBUF ((struct tcp_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
+#elif defined(CONFIG_NET_IPv6)
+# define TCPBUF ((struct tcp_ipv6hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
+#endif
/* Debug */
diff --git a/nuttx/net/tcp/tcp_timer.c b/nuttx/net/tcp/tcp_timer.c
index c0482380c..5ed9c8d10 100644
--- a/nuttx/net/tcp/tcp_timer.c
+++ b/nuttx/net/tcp/tcp_timer.c
@@ -100,8 +100,8 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
{
uint8_t result;
- dev->d_snddata = &dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev)];
- dev->d_appdata = &dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev)];
+ dev->d_snddata = &dev->d_buf[IPv4TCP_HDRLEN + NET_LL_HDRLEN(dev)];
+ dev->d_appdata = &dev->d_buf[IPv4TCP_HDRLEN + NET_LL_HDRLEN(dev)];
/* Increase the TCP sequence number */
@@ -183,7 +183,7 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
/* We also send a reset packet to the remote host. */
- tcp_send(dev, conn, TCP_RST | TCP_ACK, IPTCP_HDRLEN);
+ tcp_send(dev, conn, TCP_RST | TCP_ACK, IPv4TCP_HDRLEN);
goto done;
}
@@ -234,7 +234,7 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
case TCP_LAST_ACK:
/* In all these states we should retransmit a FINACK. */
- tcp_send(dev, conn, TCP_FIN | TCP_ACK, IPTCP_HDRLEN);
+ tcp_send(dev, conn, TCP_FIN | TCP_ACK, IPv4TCP_HDRLEN);
goto done;
}
}
diff --git a/nuttx/net/udp/udp.h b/nuttx/net/udp/udp.h
index f13b85517..758f89a96 100644
--- a/nuttx/net/udp/udp.h
+++ b/nuttx/net/udp/udp.h
@@ -62,6 +62,7 @@
/* Representation of a uIP UDP connection */
struct devif_callback_s; /* Forward reference */
+struct udp_hdr_s; /* Forward reference */
struct udp_conn_s
{
@@ -96,8 +97,8 @@ extern "C"
* Public Function Prototypes
****************************************************************************/
-struct udp_iphdr_s; /* Forward reference */
-struct net_driver_s; /* Forward reference */
+struct net_driver_s; /* Forward reference */
+struct udp_iphdr_s; /* Forward reference */
/* Defined in udp_conn.c ****************************************************/
/****************************************************************************
@@ -141,11 +142,12 @@ void udp_free(FAR struct udp_conn_s *conn);
* connection to be used within the provided TCP/IP header
*
* Assumptions:
- * This function is called from UIP logic at interrupt level
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
-FAR struct udp_conn_s *udp_active(FAR struct udp_iphdr_s *buf);
+FAR struct udp_conn_s *udp_active(FAR struct net_driver_s *dev,
+ FAR struct udp_hdr_s *udp);
/****************************************************************************
* Name: udp_nextconn()
@@ -154,8 +156,7 @@ FAR struct udp_conn_s *udp_active(FAR struct udp_iphdr_s *buf);
* Traverse the list of allocated UDP connections
*
* Assumptions:
- * This function is called from UIP logic at interrupt level (or with
- * interrupts disabled).
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -224,7 +225,7 @@ int udp_connect(FAR struct udp_conn_s *conn,
* None
*
* Assumptions:
- * Called from the interrupt level or with interrupts disabled.
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -245,7 +246,7 @@ void udp_poll(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn);
* None
*
* Assumptions:
- * Called from the interrupt level or with interrupts disabled.
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
@@ -253,10 +254,10 @@ void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn);
/* Defined in udp_input.c ***************************************************/
/****************************************************************************
- * Name: udp_input
+ * Name: udp_ipv4_input
*
* Description:
- * Handle incoming UDP input
+ * Handle incoming UDP input in an IPv4 packet
*
* Parameters:
* dev - The device driver structure containing the received UDP packet
@@ -267,11 +268,36 @@ void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn);
* but no receive in place to catch the packet yet.
*
* Assumptions:
- * Called from the interrupt level or with interrupts disabled.
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
-int udp_input(FAR struct net_driver_s *dev);
+#ifdef CONFIG_NET_IPv4
+int udp_ipv4_input(FAR struct net_driver_s *dev);
+#endif
+
+/****************************************************************************
+ * Name: udp_ipv6_input
+ *
+ * Description:
+ * Handle incoming UDP input in an IPv6 packet
+ *
+ * Parameters:
+ * dev - The device driver structure containing the received UDP packet
+ *
+ * Return:
+ * OK The packet has been processed and can be deleted
+ * ERROR Hold the packet and try again later. There is a listening socket
+ * but no receive in place to catch the packet yet.
+ *
+ * Assumptions:
+ * Called from network stack logic with the network stack locked
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv6
+int udp_ipv6_input(FAR struct net_driver_s *dev);
+#endif
/* Defined in udp_callback.c ************************************************/
/****************************************************************************
@@ -284,7 +310,7 @@ int udp_input(FAR struct net_driver_s *dev);
* OK if packet has been processed, otherwise ERROR.
*
* Assumptions:
- * This function is called at the interrupt level with interrupts disabled.
+ * Called from network stack logic with the network stack locked
*
****************************************************************************/
diff --git a/nuttx/net/udp/udp_conn.c b/nuttx/net/udp/udp_conn.c
index 3cdb7ce44..fd73b9a2d 100644
--- a/nuttx/net/udp/udp_conn.c
+++ b/nuttx/net/udp/udp_conn.c
@@ -63,6 +63,12 @@
#include "udp/udp.h"
/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define IPv4 ((struct net_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
+
+/****************************************************************************
* Private Data
****************************************************************************/
@@ -342,11 +348,13 @@ void udp_free(FAR struct udp_conn_s *conn)
*
****************************************************************************/
-FAR struct udp_conn_s *udp_active(FAR struct udp_iphdr_s *buf)
+FAR struct udp_conn_s *udp_active(FAR struct net_driver_s *dev,
+ FAR struct udp_hdr_s *udp)
{
- FAR struct udp_conn_s *conn =
- (FAR struct udp_conn_s *)g_active_udp_connections.head;
+ FAR struct net_iphdr_s *ip = IPv4;
+ FAR struct udp_conn_s *conn;
+ conn = (FAR struct udp_conn_s *)g_active_udp_connections.head;
while (conn)
{
/* If the local UDP port is non-zero, the connection is considered
@@ -370,16 +378,16 @@ FAR struct udp_conn_s *udp_active(FAR struct udp_iphdr_s *buf)
* is destined for this UDP connection.
*/
- if (conn->lport != 0 && buf->destport == conn->lport &&
- (conn->rport == 0 || buf->srcport == conn->rport) &&
+ if (conn->lport != 0 && udp->destport == conn->lport &&
+ (conn->rport == 0 || udp->srcport == conn->rport) &&
#ifdef CONFIG_NETDEV_MULTINIC
(net_ipaddr_cmp(conn->lipaddr, g_allzeroaddr) ||
net_ipaddr_cmp(conn->lipaddr, g_alloneaddr) ||
- net_ipaddr_hdrcmp(buf->destipaddr, &conn->lipaddr)) &&
+ net_ipaddr_hdrcmp(ip->destipaddr, &conn->lipaddr)) &&
#endif
(net_ipaddr_cmp(conn->ripaddr, g_allzeroaddr) ||
net_ipaddr_cmp(conn->ripaddr, g_alloneaddr) ||
- net_ipaddr_hdrcmp(buf->srcipaddr, &conn->ripaddr)))
+ net_ipaddr_hdrcmp(ip->srcipaddr, &conn->ripaddr)))
{
/* Matching connection found.. return a reference to it */
diff --git a/nuttx/net/udp/udp_input.c b/nuttx/net/udp/udp_input.c
index 99b16761f..d53b9185c 100644
--- a/nuttx/net/udp/udp_input.c
+++ b/nuttx/net/udp/udp_input.c
@@ -60,8 +60,6 @@
* Pre-processor Definitions
****************************************************************************/
-#define UDPBUF ((struct udp_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
-
/****************************************************************************
* Public Variables
****************************************************************************/
@@ -75,17 +73,15 @@
****************************************************************************/
/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
* Name: udp_input
*
* Description:
* Handle incoming UDP input
*
* Parameters:
- * dev - The device driver structure containing the received UDP packet
+ * dev - The device driver structure containing the received UDP packet
+ * udp - A pointer to the UDP header in the packet
+ * udpiplen - Length of the IP and UDP headers
*
* Return:
* OK The packet has been processed and can be deleted
@@ -97,12 +93,15 @@
*
****************************************************************************/
-int udp_input(FAR struct net_driver_s *dev)
+static int udp_input(FAR struct net_driver_s *dev, FAR struct udp_hdr_s *udp,
+ unsigned int udpiplen)
{
FAR struct udp_conn_s *conn;
- FAR struct udp_iphdr_s *pbuf = UDPBUF;
+ unsigned int hdrlen;
int ret = OK;
+ /* Update the count of UDP packets received */
+
#ifdef CONFIG_NET_STATISTICS
g_netstats.udp.recv++;
#endif
@@ -112,10 +111,16 @@ int udp_input(FAR struct net_driver_s *dev)
* application sets d_sndlen, it has a packet to send.
*/
- dev->d_len -= IPUDP_HDRLEN;
+ dev->d_len -= udpiplen;
+
+ /* Get the size of the link layer header, the IP header, and the UDP header */
+
+ hdrlen = udpiplen + NET_LL_HDRLEN(dev);
+
#ifdef CONFIG_NET_UDP_CHECKSUMS
- dev->d_appdata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPUDP_HDRLEN];
- if (pbuf->udpchksum != 0 && udp_chksum(dev) != 0xffff)
+ dev->d_appdata = &dev->d_buf[hdrlen];
+
+ if (udp->udpchksum != 0 && udp_chksum(dev) != 0xffff)
{
#ifdef CONFIG_NET_STATISTICS
g_netstats.udp.drop++;
@@ -134,7 +139,7 @@ int udp_input(FAR struct net_driver_s *dev)
* receiving a UDP datagram (multicast reception). This could be
* handled easily by something like:
*
- * for (conn = NULL; conn = udp_active (pbuf, conn); )
+ * for (conn = NULL; conn = udp_active(dev, udp); )
*
* If the callback logic that receives a packet responds with an
* outgoing packet, then it will over-write the received buffer,
@@ -143,15 +148,15 @@ int udp_input(FAR struct net_driver_s *dev)
* packet as read-only.
*/
- conn = udp_active(pbuf);
+ conn = udp_active(dev, udp);
if (conn)
{
uint16_t flags;
/* Set-up for the application callback */
- dev->d_appdata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPUDP_HDRLEN];
- dev->d_snddata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPUDP_HDRLEN];
+ dev->d_appdata = &dev->d_buf[hdrlen];
+ dev->d_snddata = &dev->d_buf[hdrlen];
dev->d_sndlen = 0;
/* Perform the application callback */
@@ -188,4 +193,64 @@ int udp_input(FAR struct net_driver_s *dev)
return ret;
}
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: udp_ipv4_input
+ *
+ * Description:
+ * Handle incoming UDP input in an IPv4 packet
+ *
+ * Parameters:
+ * dev - The device driver structure containing the received UDP packet
+ *
+ * Return:
+ * OK The packet has been processed and can be deleted
+ * ERROR Hold the packet and try again later. There is a listening socket
+ * but no receive in place to catch the packet yet.
+ *
+ * Assumptions:
+ * Called from network stack logic with the network stack locked
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv4
+int udp_ipv4_input(FAR struct net_driver_s *dev)
+{
+ unsigned int offset = IPv4_HDRLEN + NET_LL_HDRLEN(dev);
+ return udp_input(dev, (FAR struct udp_hdr_s *)&dev->d_buf[offset],
+ IPv4UDP_HDRLEN);
+}
+#endif
+
+/****************************************************************************
+ * Name: udp_ipv6_input
+ *
+ * Description:
+ * Handle incoming UDP input in an IPv6 packet
+ *
+ * Parameters:
+ * dev - The device driver structure containing the received UDP packet
+ *
+ * Return:
+ * OK The packet has been processed and can be deleted
+ * ERROR Hold the packet and try again later. There is a listening socket
+ * but no receive in place to catch the packet yet.
+ *
+ * Assumptions:
+ * Called from network stack logic with the network stack locked
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv6
+int udp_ipv6_input(FAR struct net_driver_s *dev)
+{
+ unsigned int offset = IPv6_HDRLEN + NET_LL_HDRLEN(dev);
+ return udp_input(dev, (FAR struct udp_hdr_s *)&dev->d_buf[offset],
+ IPv6UDP_HDRLEN);
+}
+#endif
+
#endif /* CONFIG_NET && CONFIG_NET_UDP */
diff --git a/nuttx/net/udp/udp_poll.c b/nuttx/net/udp/udp_poll.c
index e490b88ab..43ea3e8cc 100644
--- a/nuttx/net/udp/udp_poll.c
+++ b/nuttx/net/udp/udp_poll.c
@@ -98,10 +98,18 @@ void udp_poll(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn)
if (conn->lport != 0)
{
- /* Set-up for the application callback */
-
- dev->d_appdata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPUDP_HDRLEN];
- dev->d_snddata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPUDP_HDRLEN];
+ /* Set up for the callback. We can't know in advance if the application
+ * is going to send a IPv4 or an IPv6 packet, so this setup may not
+ * actually be used.
+ */
+
+#if defined(CONFIG_NET_IPv4)
+ dev->d_appdata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPv4UDP_HDRLEN];
+ dev->d_snddata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPv4UDP_HDRLEN];
+#else /* if defined(CONFIG_NET_IPv6) */
+ dev->d_appdata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPv6UDP_HDRLEN];
+ dev->d_snddata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPv6UDP_HDRLEN];
+#endif
dev->d_len = 0;
dev->d_sndlen = 0;
diff --git a/nuttx/net/udp/udp_send.c b/nuttx/net/udp/udp_send.c
index 658e826ba..098d7c4fc 100644
--- a/nuttx/net/udp/udp_send.c
+++ b/nuttx/net/udp/udp_send.c
@@ -109,7 +109,7 @@ void udp_send(struct net_driver_s *dev, struct udp_conn_s *conn)
* the IP and UDP headers (and, eventually, the Ethernet header)
*/
- dev->d_len = dev->d_sndlen + IPUDP_HDRLEN;
+ dev->d_len = dev->d_sndlen + IPv4UDP_HDRLEN;
/* Initialize the IP header. Note that for IPv6, the IP length field
* does not include the IPv6 IP header length.
diff --git a/nuttx/net/utils/Make.defs b/nuttx/net/utils/Make.defs
index c8bf78e6b..39d2bbf21 100644
--- a/nuttx/net/utils/Make.defs
+++ b/nuttx/net/utils/Make.defs
@@ -33,9 +33,17 @@
#
############################################################################
+# Common utilities
+
NET_CSRCS += net_dsec2tick.c net_dsec2timeval.c net_timeval2dsec.c
NET_CSRCS += net_chksum.c
+# IPv6 utilities
+
+ifeq ($(CONFIG_NET_IPv6),y)
+NET_CSRCS += net_ipv6_maskcmp.c
+endif
+
# Non-interrupt level support required?
ifeq ($(CONFIG_NET_NOINTS),y)
diff --git a/nuttx/net/utils/net_ipv6_maskcmp.c b/nuttx/net/utils/net_ipv6_maskcmp.c
new file mode 100644
index 000000000..897f56dcf
--- /dev/null
+++ b/nuttx/net/utils/net_ipv6_maskcmp.c
@@ -0,0 +1,111 @@
+/****************************************************************************
+ * net/utils/net_ipv6_maskcmp.c
+ *
+ * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/clock.h>
+#include <nuttx/net/ip.h>
+
+#include "utils/utils.h"
+
+#ifdef CONFIG_NET_IPv6
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: net_timeval2dsec
+ *
+ * Description:
+ * Compare two IP addresses under a netmask. The mask is used to mask
+ * out the bits that are to be compared: Buts within the mask much
+ * match exactly; bits outside if the mask are ignored.
+ *
+ * Example:
+ *
+ * net_ipv6addr_t ipaddr1;
+ * net_ipv6addr_t ipaddr2;
+ * net_ipv6addr_t mask;
+ *
+ * net_ipv6addr(&mask, 255,255,255,0);
+ * net_ipv6addr(&ipaddr1, 192,16,1,2);
+ * net_iv6paddr(&ipaddr2, 192,16,1,3);
+ * if (net_ipv6addr_maskcmp(ipaddr1, ipaddr2, &mask))
+ * {
+ * printf("They are the same");
+ * }
+ *
+ * Parameters:
+ * addr1 - The first IP address.
+ * addr2 - The second IP address.
+ * mask - The netmask.
+ *
+ * Returned Value:
+ * True if the address under the mask are equal
+ *
+ ****************************************************************************/
+
+bool net_ipv6addr_maskcmp(const net_ipv6addr_t addr1,
+ const net_ipv6addr_t addr2,
+ const net_ipv6addr_t mask)
+{
+ int i;
+
+ /* Start from the "bottom" where the addresses will most likely differ */
+
+ for (i = 7; i >= 0; i--)
+ {
+ /* Same? */
+
+ if ((addr1[i] & mask[i]) != (addr2[i] & mask[i]))
+ {
+ /* No.. the addresses are different */
+
+ return false;
+ }
+ }
+
+ /* The addresses are the same */
+
+ return true;
+}
+
+#endif /* CONFIG_NET_IPv6 */
+