summaryrefslogtreecommitdiff
path: root/nuttx/net/arp/arp_send.c
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-08-20 07:09:02 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-08-20 07:09:02 -0600
commit0badc39867862713fa986902e485dcd86548ccb4 (patch)
tree07bd66a5cf7d1e3db18a4d3de080d3b80f76b0aa /nuttx/net/arp/arp_send.c
parent97b2c4764338acf8d89d0a859e3ec269b6c098b4 (diff)
downloadpx4-nuttx-0badc39867862713fa986902e485dcd86548ccb4.tar.gz
px4-nuttx-0badc39867862713fa986902e485dcd86548ccb4.tar.bz2
px4-nuttx-0badc39867862713fa986902e485dcd86548ccb4.zip
ARP reuestion logc needs to do the right thing if (1) the address is a broadcast or multicast address, and (2) if the IP address lies outside of the network. Thanks to Manuel Stuehn
Diffstat (limited to 'nuttx/net/arp/arp_send.c')
-rw-r--r--nuttx/net/arp/arp_send.c57
1 files changed, 56 insertions, 1 deletions
diff --git a/nuttx/net/arp/arp_send.c b/nuttx/net/arp/arp_send.c
index b0feb45e9..e97156823 100644
--- a/nuttx/net/arp/arp_send.c
+++ b/nuttx/net/arp/arp_send.c
@@ -54,6 +54,7 @@
#include "netdev/netdev.h"
#include "devif/devif.h"
+#include "route/route.h"
#include "arp/arp.h"
#ifdef CONFIG_NET_ARP_SEND
@@ -168,7 +169,7 @@ static uint16_t arp_send_interrupt(FAR struct net_driver_s *dev,
* of timeouts occur without receiving the ARP replay.
*
* Parameters:
- * ipaddr The IP address to be queried.
+ * ipaddr The IP address to be queried (in network order).
*
* Returned Value:
* Zero (OK) is returned on success and the IP address mapping can now be
@@ -191,6 +192,33 @@ int arp_send(in_addr_t ipaddr)
net_lock_t save;
int ret;
+ /* First check if destination is a local broadcast. */
+
+ if (ipaddr == INADDR_BROADCAST)
+ {
+ /* We don't need to send the ARP request */
+
+ return OK;
+ }
+
+#if defined(CONFIG_NET_IGMP) && !defined(CONFIG_NET_IPv6)
+ /* Check if the destination address is a multicast address
+ *
+ * - IPv4: multicast addresses lie in the class D group -- The address range
+ * 224.0.0.0 to 239.255.255.255 (224.0.0.0/4)
+ *
+ * - IPv6 multicast addresses are have the high-order octet of the
+ * addresses=0xff (ff00::/8.)
+ */
+
+ if (NTOHL(ipaddr) >= 0xe0000000 && NTOHL(ipaddr) <= 0xefffffff)
+ {
+ /* We don't need to send the ARP request */
+
+ return OK;
+ }
+#endif
+
/* Get the device that can route this request */
dev = netdev_findbyaddr(ipaddr);
@@ -201,6 +229,33 @@ int arp_send(in_addr_t ipaddr)
goto errout;
}
+ /* Check if the destination address is on the local network. */
+
+ if (!net_ipaddr_maskcmp(ipaddr, dev->d_ipaddr, dev->d_netmask))
+ {
+ net_ipaddr_t dripaddr;
+
+ /* Destination address is not on the local network */
+
+#ifdef CONFIG_NET_ROUTE
+
+ /* We have a routing table.. find the correct router to use in
+ * this case (or, as a fall-back, use the device's default router
+ * address). We will use the router IP address instead of the
+ * destination address when determining the MAC address.
+ */
+
+ netdev_router(dev, ipaddr, &dripaddr);
+#else
+ /* Use the device's default router IP address instead of the
+ * destination address when determining the MAC address.
+ */
+
+ net_ipaddr_copy(dripaddr, dev->d_draddr);
+#endif
+ ipaddr = dripaddr;
+ }
+
/* Allocate resources to receive a callback. This and the following
* initialization is performed with the network lock because we don't
* want anything to happen until we are ready.