diff --git a/include/nuttx/net/arp.h b/include/nuttx/net/arp.h index 477240a5d68..78d76bb8569 100644 --- a/include/nuttx/net/arp.h +++ b/include/nuttx/net/arp.h @@ -2,7 +2,8 @@ * include/nuttx/net/arp.h * Macros and definitions for the ARP module. * - * Copyright (C) 2007, 2009-2012, 2015-2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009-2012, 2015-2016, 2018 Gregory Nutt. All rights + * reserved. * Author: Gregory Nutt * * Derived from uIP with has a similar BSD-style license: @@ -78,7 +79,7 @@ /* One entry in the ARP table (volatile!) */ -struct arp_entry +struct arp_entry_s { in_addr_t at_ipaddr; /* IP address */ struct ether_addr at_ethaddr; /* Hardware address */ diff --git a/net/arp/arp.h b/net/arp/arp.h index 79a0d9a14f6..9764e8ff78d 100644 --- a/net/arp/arp.h +++ b/net/arp/arp.h @@ -1,7 +1,7 @@ /**************************************************************************** * net/arp/arp.h * - * Copyright (C) 2014-2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2014-2016, 2018 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -384,7 +384,7 @@ void arp_notify(in_addr_t ipaddr); * ****************************************************************************/ -FAR struct arp_entry *arp_lookup(in_addr_t ipaddr); +FAR struct arp_entry_s *arp_lookup(in_addr_t ipaddr); /**************************************************************************** * Name: arp_find @@ -394,15 +394,19 @@ FAR struct arp_entry *arp_lookup(in_addr_t ipaddr); * not be in the ARP table (it may, instead, be a local network device). * * Input Parameters: - * ipaddr - Refers to an IP address in network order - * entry - location to return a copy of the ARP table entry. + * ipaddr - Refers to an IP address in network order + * ethaddr - Location to return the corresponding Ethernet MAN address. + * This address may be NULL. In that case, this function may be + * used simply to determine if the Ethernet MAC address is + * available. * * Assumptions * The network is locked to assure exclusive access to the ARP table. * ****************************************************************************/ -int arp_find(in_addr_t ipaddr, FAR struct arp_entry *entry); +struct ether_addr; /* Forward reference */ +int arp_find(in_addr_t ipaddr, FAR struct ether_addr *ethaddr); /**************************************************************************** * Name: arp_delete diff --git a/net/arp/arp_out.c b/net/arp/arp_out.c index fdbf384d073..c9be188b9de 100644 --- a/net/arp/arp_out.c +++ b/net/arp/arp_out.c @@ -1,7 +1,8 @@ /**************************************************************************** * net/arp/arp_out.c * - * Copyright (C) 2007-2011, 2014-2015, 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2011, 2014-2015, 2017-2018 Gregory Nutt. All rights + * reserved. * Author: Gregory Nutt * * Based on uIP which also has a BSD style license: @@ -136,7 +137,7 @@ static const uint8_t g_multicast_ethaddr[3] = void arp_out(FAR struct net_driver_s *dev) { - struct arp_entry entry; + struct ether_addr ethaddr; FAR struct eth_hdr_s *peth = ETHBUF; FAR struct arp_iphdr_s *pip = IPBUF; in_addr_t ipaddr; @@ -250,7 +251,7 @@ void arp_out(FAR struct net_driver_s *dev) /* Check if we already have this destination address in the ARP table */ - ret = arp_find(ipaddr, &entry); + ret = arp_find(ipaddr, ðaddr); if (ret >= 0) { ninfo("ARP request for IP %08lx\n", (unsigned long)ipaddr); @@ -266,7 +267,7 @@ void arp_out(FAR struct net_driver_s *dev) /* Build an Ethernet header. */ - memcpy(peth->dest, entry.at_ethaddr.ether_addr_octet, ETHER_ADDR_LEN); + memcpy(peth->dest, ethaddr.ether_addr_octet, ETHER_ADDR_LEN); /* Finish populating the Ethernet header */ diff --git a/net/arp/arp_send.c b/net/arp/arp_send.c index d335c8ecd41..9fe5d9dfc6a 100644 --- a/net/arp/arp_send.c +++ b/net/arp/arp_send.c @@ -315,8 +315,6 @@ int arp_send(in_addr_t ipaddr) while (state.snd_retries < CONFIG_ARP_SEND_MAXTRIES) { - struct arp_entry entry; - /* Check if the address mapping is present in the ARP table. This * is only really meaningful on the first time through the loop. * @@ -324,7 +322,7 @@ int arp_send(in_addr_t ipaddr) * issue. */ - if (arp_find(ipaddr, &entry) >= 0) + if (arp_find(ipaddr, NULL) >= 0) { /* We have it! Break out with success */ diff --git a/net/arp/arp_table.c b/net/arp/arp_table.c index 292b942cb65..71ea8267b39 100644 --- a/net/arp/arp_table.c +++ b/net/arp/arp_table.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include @@ -66,13 +65,23 @@ #ifdef CONFIG_NET_ARP +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct arp_table_info_s +{ + in_addr_t ai_ipaddr; /* IP address for lookup */ + FAR struct ether_addr *ai_ethaddr; /* Location to return the MAC address */ +}; + /**************************************************************************** * Private Data ****************************************************************************/ /* The table of known address mappings */ -static struct arp_entry g_arptable[CONFIG_NET_ARPTAB_SIZE]; +static struct arp_entry_s g_arptable[CONFIG_NET_ARPTAB_SIZE]; static uint8_t g_arptime; /**************************************************************************** @@ -90,19 +99,38 @@ static uint8_t g_arptime; static int arp_match(FAR struct net_driver_s *dev, FAR void *arg) { - FAR struct arp_entry *entry = arg; + FAR struct arp_table_info_s *info = arg; - if (dev->d_lltype != NET_LL_ETHERNET) + /* Make sure that this is an Ethernet device (or an IEEE 802.11 device + * which is also Ethernet) + */ + + if (dev->d_lltype != NET_LL_ETHERNET && + dev->d_lltype != NET_LL_IEEE80211) { return 0; } - if (!net_ipv4addr_cmp(dev->d_ipaddr, entry->at_ipaddr)) + /* Check if the network device has been assigned the IP address of the + * lookup. + */ + + if (!net_ipv4addr_cmp(dev->d_ipaddr, info->ai_ipaddr)) { return 0; } - memcpy(&entry->at_ethaddr, &dev->d_mac.ether, ETHER_ADDR_LEN); + /* Yes.. Return the matching Ethernet MAC address if the caller of + * arp_find() provided a non-NULL location. + */ + + if (info->ai_ethaddr != NULL) + { + memcpy(info->ai_ethaddr, &dev->d_mac.ether, ETHER_ADDR_LEN); + } + + /* Return success in any event */ + return 1; } @@ -141,7 +169,7 @@ void arp_reset(void) void arp_timer(void) { - FAR struct arp_entry *tabptr; + FAR struct arp_entry_s *tabptr; int i; ++g_arptime; @@ -179,7 +207,7 @@ void arp_timer(void) int arp_update(in_addr_t ipaddr, FAR uint8_t *ethaddr) { - struct arp_entry *tabptr = NULL; + struct arp_entry_s *tabptr = NULL; int i; /* Walk through the ARP mapping table and try to find an entry to @@ -299,9 +327,9 @@ void arp_hdr_update(FAR uint16_t *pipaddr, FAR uint8_t *ethaddr) * ****************************************************************************/ -FAR struct arp_entry *arp_lookup(in_addr_t ipaddr) +FAR struct arp_entry_s *arp_lookup(in_addr_t ipaddr) { - FAR struct arp_entry *tabptr; + FAR struct arp_entry_s *tabptr; int i; /* Check if the IPv4 address is already in the ARP table. */ @@ -328,25 +356,40 @@ FAR struct arp_entry *arp_lookup(in_addr_t ipaddr) * not be in the ARP table (it may, instead, be a local network device). * * Input Parameters: - * ipaddr - Refers to an IP address in network order + * ipaddr - Refers to an IP address in network order + * ethaddr - Location to return the corresponding Ethernet MAN address. + * This address may be NULL. In that case, this function may be + * used simply to determine if the Ethernet MAC address is + * available. * - * Assumptions: + * Assumptions * The network is locked to assure exclusive access to the ARP table. * ****************************************************************************/ -int arp_find(in_addr_t ipaddr, FAR struct arp_entry *entry) +int arp_find(in_addr_t ipaddr, FAR struct ether_addr *ethaddr) { - FAR struct arp_entry *tabptr; - - DEBUGASSERT(entry); + FAR struct arp_entry_s *tabptr; + struct arp_table_info_s info; /* Check if the IPv4 address is already in the ARP table. */ tabptr = arp_lookup(ipaddr); if (tabptr != NULL) { - memcpy(entry, tabptr, sizeof(struct arp_entry)); + /* Yes.. return the Ethernet MAC address if the caller has provided a + * non-NULL address in 'ethaddr'. + */ + + if (ethaddr != NULL) + { + memcpy(ethaddr, &tabptr->at_ethaddr, ETHER_ADDR_LEN); + } + + /* Return success in any case meaning that a valid Ethernet MAC + * address mapping is available for the IP address. + */ + return OK; } @@ -355,8 +398,10 @@ int arp_find(in_addr_t ipaddr, FAR struct arp_entry *entry) * to the Ethernet MAC address assigned to the network device. */ - entry->at_ipaddr = ipaddr; - if (netdev_foreach(arp_match, entry) != 0) + info.ai_ipaddr = ipaddr; + info.ai_ethaddr = ethaddr; + + if (netdev_foreach(arp_match, &info) != 0) { return OK; } @@ -382,7 +427,7 @@ int arp_find(in_addr_t ipaddr, FAR struct arp_entry *entry) void arp_delete(in_addr_t ipaddr) { - FAR struct arp_entry *tabptr; + FAR struct arp_entry_s *tabptr; /* Check if the IPv4 address is in the ARP table. */ diff --git a/net/ipforward/ipfwd_forward.c b/net/ipforward/ipfwd_forward.c index 9323e3d8f76..33ae0c27292 100644 --- a/net/ipforward/ipfwd_forward.c +++ b/net/ipforward/ipfwd_forward.c @@ -159,10 +159,9 @@ static inline bool ipfwd_addrchk(FAR struct forward_s *fwd) { #if !defined(CONFIG_NET_ARP_IPIN) && !defined(CONFIG_NET_ARP_SEND) FAR struct ipv4_hdr_s *ipv4 = (FAR struct ipv4_hdr_s *)fwd->f_iob->io_data; - struct arp_entry entry; int ret; - ret = arp_find(*(in_addr_t *)ipv4->destipaddr, &entry); + ret = arp_find(*(in_addr_t *)ipv4->destipaddr, NULL); return (ret >= 0); #else return true; diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c index df78626aa96..c68accae62a 100644 --- a/net/netdev/netdev_ioctl.c +++ b/net/netdev/netdev_ioctl.c @@ -1259,7 +1259,7 @@ static int netdev_arp_ioctl(FAR struct socket *psock, int cmd, /* Find the existing ARP table entry for this protocol address. */ - FAR struct arp_entry *entry = arp_lookup(addr->sin_addr.s_addr); + FAR struct arp_entry_s *entry = arp_lookup(addr->sin_addr.s_addr); if (entry != NULL) { /* The ARP table is fixed size; an entry is deleted @@ -1287,19 +1287,18 @@ static int netdev_arp_ioctl(FAR struct socket *psock, int cmd, { FAR struct sockaddr_in *addr = (FAR struct sockaddr_in *)&req->arp_pa; - struct arp_entry entry; - /* Find the existing ARP table entry for this protocol address. */ + /* Get the hardware address from an existing ARP table entry + * matching this protocol address. + */ - ret = arp_find(addr->sin_addr.s_addr, &entry); + ret = arp_find(addr->sin_addr.s_addr, + (FAR struct ether_addr *)req->arp_ha.sa_data); if (ret >= 0) { /* Return the mapped hardware address. */ req->arp_ha.sa_family = ARPHRD_ETHER; - memcpy(req->arp_ha.sa_data, - entry.at_ethaddr.ether_addr_octet, - ETHER_ADDR_LEN); ret = OK; } } diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c index bf93ae5e889..2a7ee7b1f61 100644 --- a/net/tcp/tcp_send_buffered.c +++ b/net/tcp/tcp_send_buffered.c @@ -309,9 +309,7 @@ static inline bool psock_send_addrchck(FAR struct tcp_conn_s *conn) #endif #if !defined(CONFIG_NET_ARP_IPIN) && !defined(CONFIG_NET_ARP_SEND) - struct arp_entry entry; - - if (arp_find(conn->u.ipv4.raddr, &entry) >= 0) + if (arp_find(conn->u.ipv4.raddr, NULL) >= 0) { /* Return true if the address was found in the ARP table */ diff --git a/net/tcp/tcp_send_unbuffered.c b/net/tcp/tcp_send_unbuffered.c index f6aecef56cb..5146b164ffb 100644 --- a/net/tcp/tcp_send_unbuffered.c +++ b/net/tcp/tcp_send_unbuffered.c @@ -258,9 +258,7 @@ static inline bool psock_send_addrchck(FAR struct tcp_conn_s *conn) in_addr_t router; #endif #if !defined(CONFIG_NET_ARP_IPIN) && !defined(CONFIG_NET_ARP_SEND) - struct arp_entry entry; - - if (arp_find(conn->u.ipv4.raddr, &entry) >= 0) + if (arp_find(conn->u.ipv4.raddr, NULL) >= 0) { /* Return true if the address was found in the ARP table */ diff --git a/net/tcp/tcp_sendfile.c b/net/tcp/tcp_sendfile.c index f6044b8e672..4496447a846 100644 --- a/net/tcp/tcp_sendfile.c +++ b/net/tcp/tcp_sendfile.c @@ -296,9 +296,7 @@ static inline bool sendfile_addrcheck(FAR struct tcp_conn_s *conn) #endif { #if !defined(CONFIG_NET_ARP_IPIN) && !defined(CONFIG_NET_ARP_SEND) - struct arp_entry entry; - - return (arp_find(conn->u.ipv4.raddr, &entry) >= 0); + return (arp_find(conn->u.ipv4.raddr, NULL) >= 0); #else return true; #endif diff --git a/net/udp/udp_psock_sendto_buffered.c b/net/udp/udp_psock_sendto_buffered.c index e3998d4542a..541aa84dead 100644 --- a/net/udp/udp_psock_sendto_buffered.c +++ b/net/udp/udp_psock_sendto_buffered.c @@ -281,9 +281,7 @@ static inline bool sendto_addrcheck(FAR struct udp_conn_s *conn, #endif { #if !defined(CONFIG_NET_ARP_IPIN) && !defined(CONFIG_NET_ARP_SEND) - struct arp_entry entry; - - return (arp_find(conn->u.ipv4.raddr, entry) >= 0); + return (arp_find(conn->u.ipv4.raddr, NULL) >= 0); #else return true; #endif