diff options
author | David Sidrane <david_s5@nscdg.com> | 2015-01-16 06:54:11 -1000 |
---|---|---|
committer | David Sidrane <david_s5@nscdg.com> | 2015-01-16 06:54:11 -1000 |
commit | 0f646fd2f50d1726615c47580ae9dc6832e26076 (patch) | |
tree | c04cb7c3574d0dca6192d7dea05c58990ab5816f | |
parent | 118398f627d6b4219f8c33cda8e97ba01dddec22 (diff) | |
parent | 8c1935a004d78bfcdd80638c38fcaa07152f6815 (diff) | |
download | px4-nuttx-0f646fd2f50d1726615c47580ae9dc6832e26076.tar.gz px4-nuttx-0f646fd2f50d1726615c47580ae9dc6832e26076.tar.bz2 px4-nuttx-0f646fd2f50d1726615c47580ae9dc6832e26076.zip |
Merge remote-tracking branch 'upstream/master' into upstream
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 */ + |