summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-01-21 14:13:03 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-01-21 14:13:03 -0600
commitd84f91852509b203c7585b0f4f8b88edb0393ef5 (patch)
treef36dc973185438d5a6c2bd6df48c1ea28aa7b0fb
parentab894a8a5647baf0b33e4cf03e12c39fa6f068ae (diff)
downloadnuttx-d84f91852509b203c7585b0f4f8b88edb0393ef5.tar.gz
nuttx-d84f91852509b203c7585b0f4f8b88edb0393ef5.tar.bz2
nuttx-d84f91852509b203c7585b0f4f8b88edb0393ef5.zip
Networking: IPv6 receipt logic errors. Don't save neighbor address in table when solicitation is recieved. Save it when the advertisement is received
-rw-r--r--nuttx/net/icmpv6/icmpv6_input.c79
1 files changed, 55 insertions, 24 deletions
diff --git a/nuttx/net/icmpv6/icmpv6_input.c b/nuttx/net/icmpv6/icmpv6_input.c
index 002830b58..ef10abc75 100644
--- a/nuttx/net/icmpv6/icmpv6_input.c
+++ b/nuttx/net/icmpv6/icmpv6_input.c
@@ -135,31 +135,19 @@ void icmpv6_input(FAR struct net_driver_s *dev)
FAR struct icmpv6_neighbor_solicit_s *sol;
FAR struct icmpv6_neighbor_advertise_s *adv;
- /* If the data matches our address, add the neighbor to the list
- * of neighbors.
- *
- * Missing checks:
- * optlen = 1 (8 octets)i
- * Should only update Neighbor Table if [O]verride bit is set in flags
- */
+ /* Check if we are the target of the solicitation */
sol = ICMPv6SOLICIT;
if (net_ipv6addr_cmp(sol->tgtaddr, dev->d_ipv6addr))
{
- if (sol->opttype == ICMPv6_OPT_SRCLLADDR)
- {
- /* Save the sender's address in our neighbor list. */
-
- neighbor_add(icmp->srcipaddr,
- (FAR struct neighbor_addr_s *)sol->srclladdr);
- }
-
- /* We should now send a neighbor advertisement back to where the
- * neighbor solicitation came from.
+ /* Yes.. Send a neighbor advertisement back to where the neighbor
+ * solicitation came from.
+ *
+ *
+ * Set up the IPv6 header. Most is probably already in place from
+ * the Neighbor Solitication. We could save some time here.
*/
- /* Set up the IPv6 header (most is probably already in place) */
-
icmp->vtc = 0x60; /* Version/traffic class (MS) */
icmp->tcf = 0; /* Traffic class (LS)/Flow label (MS) */
icmp->flow = 0; /* Flow label (LS) */
@@ -235,9 +223,50 @@ void icmpv6_input(FAR struct net_driver_s *dev)
}
else
{
- goto drop;
+ goto icmpv6_drop_packet;
}
}
+
+ /* If we get a neighbor advertise for our address we should send
+ * a neighbor advertisement message back.
+ */
+
+ else if (icmp->type == ICMPv6_NEIGHBOR_ADVERTISE)
+ {
+ FAR struct icmpv6_neighbor_advertise_s *adv;
+
+ /* If the IPv6 destination address matches our address, and if so,
+ * add the neighbor address mapping to the list of neighbors.
+ *
+ * Missing checks:
+ * optlen = 1 (8 octets)
+ * Should only update Neighbor Table if [O]verride bit is set in flags
+ */
+
+ adv = ICMPv6ADVERTISE;
+ if (net_ipv6addr_cmp(icmp->destipaddr, dev->d_ipv6addr))
+ {
+ /* This message is required to support the Target link-layer
+ * address option.
+ */
+
+ if (adv->opttype == ICMPv6_OPT_TGTLLADDR)
+ {
+ /* Save the sender's address mapping in our Neighbor Table. */
+
+ neighbor_add(icmp->srcipaddr,
+ (FAR struct neighbor_addr_s *)adv->tgtlladdr);
+
+ /* We consumed the packet but we don't send anything in
+ * response.
+ */
+
+ goto icmpv_send_nothing;
+ }
+ }
+
+ goto icmpv6_drop_packet;
+ }
else if (icmp->type == ICMPv6_ECHO_REQUEST)
{
/* ICMPv6 echo (i.e., ping) processing. This is simple, we only
@@ -276,7 +305,7 @@ void icmpv6_input(FAR struct net_driver_s *dev)
{
/* The ECHO reply was not handled */
- goto drop;
+ goto icmpv6_drop_packet;
}
}
#endif
@@ -284,7 +313,7 @@ void icmpv6_input(FAR struct net_driver_s *dev)
else
{
nlldbg("Unknown ICMPv6 cmd: %d\n", icmp->type);
- goto typeerr;
+ goto icmpv6_type_error;
}
/* No additional neighbor lookup is required on this packet. */
@@ -300,15 +329,17 @@ void icmpv6_input(FAR struct net_driver_s *dev)
#endif
return;
-typeerr:
+icmpv6_type_error:
#ifdef CONFIG_NET_STATISTICS
g_netstats.icmpv6.typeerr++;
#endif
-drop:
+icmpv6_drop_packet:
#ifdef CONFIG_NET_STATISTICS
g_netstats.icmpv6.drop++;
#endif
+
+icmpv_send_nothing:
dev->d_len = 0;
}