From 5bb216fb90c9bf476d0011661242299e808147ed Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 23 Jun 2018 10:13:38 -0600 Subject: [PATCH] net/: There are many different checks for IPv6 multicast addresses. Most of the checks are different. RFC 3513 clearly specifies how to detect an IPv6 multilcast address: they should begin with 0xffxx. I did not change some of the checks in ipv6_input.c, however. In that file, the comments indicate that the code should only pick of certain mulicast address that begin withi 0xff02. --- include/nuttx/net/ip.h | 14 +++++++++++++- net/icmpv6/icmpv6_solicit.c | 3 ++- net/netdev/netdev_findbyaddr.c | 8 ++------ net/sixlowpan/sixlowpan_utils.c | 7 +++++-- net/udp/udp_finddev.c | 9 +-------- 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/include/nuttx/net/ip.h b/include/nuttx/net/ip.h index c7d5b40615..bae0091b8c 100644 --- a/include/nuttx/net/ip.h +++ b/include/nuttx/net/ip.h @@ -587,7 +587,19 @@ bool net_ipv6addr_maskcmp(const net_ipv6addr_t addr1, * Name: net_is_addr_mcast * * Description: - * Is address a multicast address? see RFC 3513. + * Is address a multicast address? See RFC 3513: + * + * An IPv6 multicast address is an identifier for a group of interfaces + * (typically on different nodes). An interface may belong to any number + * of multicast groups. Multicast addresses have the following format: + * + * | 8 | 4 | 4 | 112 bits | + * +------ -+----+----+---------------------------------------------+ + * |11111111|flgs|scop| group ID | + * +--------+----+----+---------------------------------------------+ + * + * binary 11111111 at the start of the address identifies the address as + * being a multicast address. * ****************************************************************************/ diff --git a/net/icmpv6/icmpv6_solicit.c b/net/icmpv6/icmpv6_solicit.c index ca941e24f4..74275bb063 100644 --- a/net/icmpv6/icmpv6_solicit.c +++ b/net/icmpv6/icmpv6_solicit.c @@ -67,7 +67,8 @@ /**************************************************************************** * Private Data ****************************************************************************/ -/* First 6 swords of the multi-cast address in network byte order */ + +/* First 6 hwords of the multi-cast address in network byte order */ static const uint16_t g_icmpv_mcastaddr[6] = { diff --git a/net/netdev/netdev_findbyaddr.c b/net/netdev/netdev_findbyaddr.c index c7a0765e87..32e634792a 100644 --- a/net/netdev/netdev_findbyaddr.c +++ b/net/netdev/netdev_findbyaddr.c @@ -300,13 +300,9 @@ FAR struct net_driver_s *netdev_findby_ipv6addr(const net_ipv6addr_t lipaddr, int ret; #endif - /* First, check if this is the multicast IP address We should actually - * pick off certain multicast address (all hosts multicast address, and - * the solicited-node multicast address). We will cheat here and accept - * all multicast packets that are destined for the ff02::/16 addresses. - */ + /* First, check if this is the multicast IP address */ - if (ripaddr[0] == HTONS(0xff02)) + if (net_is_addr_mcast(ripaddr)) { /* Yes.. Check the local, bound address. Is it INADDR_ANY? */ diff --git a/net/sixlowpan/sixlowpan_utils.c b/net/sixlowpan/sixlowpan_utils.c index 644ad1484e..3539413418 100644 --- a/net/sixlowpan/sixlowpan_utils.c +++ b/net/sixlowpan/sixlowpan_utils.c @@ -235,7 +235,7 @@ int sixlowpan_nexthopaddr(FAR struct radio_driver_s *radio, * * 128 112 96 80 64 48 32 16 * ---- ---- ---- ---- ---- ---- ---- ---- - * ff02 xxxx xxxx xxxx xxxx xxxx xxxx xxxx Multicast + * ffxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx Multicast address (RFC 3513) * ff02 0000 0000 0000 0000 0000 0000 0001 All nodes multicast group * xxxx 0000 0000 0000 0000 00ff fe00 xx00 1-byte short address IEEE 48-bit MAC * xxxx 0000 0000 0000 0000 00ff fe00 xxxx 2-byte short address IEEE 48-bit MAC @@ -274,7 +274,7 @@ int sixlowpan_destaddrfromip(FAR struct radio_driver_s *radio, /* Check for a multicast address */ - if (ipaddr[0] == HTONS(0xff02)) + if (net_is_addr_mcast(ipaddr[0])) { DEBUGASSERT(radio->r_properties != NULL); ret = radio->r_properties(radio, &properties); @@ -299,6 +299,9 @@ int sixlowpan_destaddrfromip(FAR struct radio_driver_s *radio, memcpy(destaddr, &properties.sp_bcast, sizeof(struct netdev_varaddr_s)); } + + /* Some other RFC 3513 multicast address */ + else { memcpy(destaddr, &properties.sp_mcast, diff --git a/net/udp/udp_finddev.c b/net/udp/udp_finddev.c index 0dc70b1a06..b3ddb60c3d 100644 --- a/net/udp/udp_finddev.c +++ b/net/udp/udp_finddev.c @@ -193,16 +193,9 @@ FAR struct net_driver_s *udp_find_raddr_device(FAR struct udp_conn_s *conn) /* Check if the remote, destination address is a multicast * address. If this is the case, select the device * using the locally bound address (assuming that there is one). - * - * The general form of all well-known, reserved IPv6 multicast - * addresses is: ff0x::xx/16 (which includes most, but not all - * possible multicast addresses). */ - if ((conn->u.ipv6.raddr[0] & HTONS(0xfff0)) == HTONS(0xff00) && - conn->u.ipv6.raddr[1] == 0 && conn->u.ipv6.raddr[2] == 0 && - conn->u.ipv6.raddr[3] == 0 && conn->u.ipv6.raddr[4] == 0 && - conn->u.ipv6.raddr[5] == 0 && conn->u.ipv6.raddr[6] == 0) + if (net_is_addr_mcast(conn->u.ipv6.raddr)) { /* Make sure that the socket is bound to some non-zero, local * address. Zero is used as an indication that the laddr is