diff --git a/net/arp/arp.h b/net/arp/arp.h index 05c7974cd5..a065cbe161 100644 --- a/net/arp/arp.h +++ b/net/arp/arp.h @@ -54,6 +54,7 @@ #include #include +#include #include @@ -369,21 +370,38 @@ void arp_notify(in_addr_t ipaddr); #endif /**************************************************************************** - * Name: arp_find + * Name: arp_lookup * * Description: - * Find the ARP entry corresponding to this IP address. + * Find the ARP entry corresponding to this IP address in the ARP table. * * Input Parameters: * ipaddr - Refers to an IP address in network order * - * Assumptions - * The network is locked; Returned value will become unstable when the - * network is unlocked or if any other network APIs are called. + * Assumptions: + * The network is locked. * ****************************************************************************/ -FAR struct arp_entry *arp_find(in_addr_t ipaddr); +FAR struct arp_entry *arp_lookup(in_addr_t ipaddr); + +/**************************************************************************** + * Name: arp_find + * + * Description: + * Find the ARP entry corresponding to this IP address which may or may + * 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. + * + * Assumptions + * The network is locked. + * + ****************************************************************************/ + +int arp_find(in_addr_t ipaddr, FAR struct arp_entry *entry); /**************************************************************************** * Name: arp_delete @@ -400,14 +418,7 @@ FAR struct arp_entry *arp_find(in_addr_t ipaddr); * ****************************************************************************/ -#define arp_delete(ipaddr) \ -{ \ - struct arp_entry *tabptr = arp_find(ipaddr); \ - if (tabptr) \ - { \ - tabptr->at_ipaddr = 0; \ - } \ -} +void arp_delete(in_addr_t ipaddr); /**************************************************************************** * Name: arp_update @@ -487,7 +498,7 @@ void arp_dump(FAR struct arp_hdr_s *arp); # define arp_wait_cancel(n) (0) # define arp_wait(n,t) (0) # define arp_notify(i) -# define arp_find(i) (NULL) +# define arp_find(i,e) (-ENOSYS) # define arp_delete(i) # define arp_update(i,m); # define arp_hdr_update(i,m); diff --git a/net/arp/arp_out.c b/net/arp/arp_out.c index 70a2275837..fdbf384d07 100644 --- a/net/arp/arp_out.c +++ b/net/arp/arp_out.c @@ -136,11 +136,12 @@ static const uint8_t g_multicast_ethaddr[3] = void arp_out(FAR struct net_driver_s *dev) { - FAR const struct arp_entry *tabptr = NULL; - FAR struct eth_hdr_s *peth = ETHBUF; - FAR struct arp_iphdr_s *pip = IPBUF; - in_addr_t ipaddr; - in_addr_t destipaddr; + struct arp_entry entry; + FAR struct eth_hdr_s *peth = ETHBUF; + FAR struct arp_iphdr_s *pip = IPBUF; + in_addr_t ipaddr; + in_addr_t destipaddr; + int ret; #if defined(CONFIG_NET_PKT) || defined(CONFIG_NET_ARP_SEND) /* Skip sending ARP requests when the frame to be transmitted was @@ -249,8 +250,8 @@ void arp_out(FAR struct net_driver_s *dev) /* Check if we already have this destination address in the ARP table */ - tabptr = arp_find(ipaddr); - if (tabptr == NULL) + ret = arp_find(ipaddr, &entry); + if (ret >= 0) { ninfo("ARP request for IP %08lx\n", (unsigned long)ipaddr); @@ -265,7 +266,7 @@ void arp_out(FAR struct net_driver_s *dev) /* Build an Ethernet header. */ - memcpy(peth->dest, tabptr->at_ethaddr.ether_addr_octet, ETHER_ADDR_LEN); + memcpy(peth->dest, entry.at_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 38bb23bf0f..d335c8ecd4 100644 --- a/net/arp/arp_send.c +++ b/net/arp/arp_send.c @@ -304,7 +304,8 @@ int arp_send(in_addr_t ipaddr) /* Remember the routing device name */ - strncpy((FAR char *)state.snd_ifname, (FAR const char *)dev->d_ifname, IFNAMSIZ); + strncpy((FAR char *)state.snd_ifname, (FAR const char *)dev->d_ifname, + IFNAMSIZ); /* Now loop, testing if the address mapping is in the ARP table and re- * sending the ARP request if it is not. @@ -314,6 +315,8 @@ 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. * @@ -321,7 +324,7 @@ int arp_send(in_addr_t ipaddr) * issue. */ - if (arp_find(ipaddr)) + if (arp_find(ipaddr, &entry) >= 0) { /* We have it! Break out with success */ diff --git a/net/arp/arp_table.c b/net/arp/arp_table.c index c7d8c11129..611c64608e 100644 --- a/net/arp/arp_table.c +++ b/net/arp/arp_table.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -284,10 +285,10 @@ void arp_hdr_update(FAR uint16_t *pipaddr, FAR uint8_t *ethaddr) } /**************************************************************************** - * Name: arp_find + * Name: arp_lookup * * Description: - * Find the ARP entry corresponding to this IP address. + * Find the ARP entry corresponding to this IP address in the ARP table. * * Input Parameters: * ipaddr - Refers to an IP address in network order @@ -297,10 +298,9 @@ void arp_hdr_update(FAR uint16_t *pipaddr, FAR uint8_t *ethaddr) * ****************************************************************************/ -FAR struct arp_entry *arp_find(in_addr_t ipaddr) +FAR struct arp_entry *arp_lookup(in_addr_t ipaddr) { FAR struct arp_entry *tabptr; - struct arp_entry entry; int i; /* Check if the IPv4 address is already in the ARP table. */ @@ -314,21 +314,86 @@ FAR struct arp_entry *arp_find(in_addr_t ipaddr) } } - /* No.. check if the IPv4 address is the address assigned to a local - * Ethernet network device. If so, return a "fake" arp table entry - * mapping that IP address to the Ethernet MAC address of the device. - */ - - entry.at_ipaddr = ipaddr; - if (netdev_foreach(arp_match, &entry) != 0) - { - return &entry; - } - /* Not found */ return NULL; } +/**************************************************************************** + * Name: arp_find + * + * Description: + * Find the ARP entry corresponding to this IP address which may or may + * 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 + * + * Assumptions: + * The network is locked. + * + ****************************************************************************/ + +int arp_find(in_addr_t ipaddr, FAR struct arp_entry *entry) +{ + FAR struct arp_entry *tabptr; + + DEBUGASSERT(entry); + + /* 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)); + return OK; + } + + /* No.. check if the IPv4 address is the address assigned to a local + * Ethernet network device. If so, return a "fake" arp table entry + * mapping that IP address to the Ethernet MAC address of the device. + */ + + entry->at_ipaddr = ipaddr; + if (netdev_foreach(arp_match, entry) != 0) + { + return OK; + } + + /* Not found */ + + return -ENOENT; +} + +/**************************************************************************** + * Name: arp_delete + * + * Description: + * Remove an IP association from the ARP table + * + * Input Parameters: + * ipaddr - Refers to an IP address in network order + * + * Assumptions + * Interrupts are disabled to assure exclusive access to the ARP table + * (and because arp_find() is called). + * + ****************************************************************************/ + +void arp_delete(in_addr_t ipaddr) +{ + FAR struct arp_entry *tabptr; + + /* Check if the IPv4 address is in the ARP table. */ + + tabptr = arp_lookup(ipaddr); + if (tabptr != NULL) + { + /* Yes.. set the IP address to zero to "delete" it */ + + tabptr->at_ipaddr = 0; + } +} + #endif /* CONFIG_NET_ARP */ #endif /* CONFIG_NET */ diff --git a/net/ipforward/ipfwd_forward.c b/net/ipforward/ipfwd_forward.c index d85942a50f..d92f1e9ca2 100644 --- a/net/ipforward/ipfwd_forward.c +++ b/net/ipforward/ipfwd_forward.c @@ -159,7 +159,11 @@ 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; - return (arp_find(*(in_addr_t *)ipv4->destipaddr) != NULL); + struct arp_entry entry; + int ret; + + ret = arp_find(*(in_addr_t *)ipv4->destipaddr, &entry); + return (ret >= 0); #else return true; #endif diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c index 8a9cdf8d69..df78626aa9 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_find(addr->sin_addr.s_addr); + FAR struct arp_entry *entry = arp_lookup(addr->sin_addr.s_addr); if (entry != NULL) { /* The ARP table is fixed size; an entry is deleted @@ -1287,24 +1287,21 @@ 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. */ - FAR struct arp_entry *entry = arp_find(addr->sin_addr.s_addr); - if (entry != NULL) + ret = arp_find(addr->sin_addr.s_addr, &entry); + 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, + entry.at_ethaddr.ether_addr_octet, ETHER_ADDR_LEN); ret = OK; } - else - { - ret = -ENOENT; - } } else { diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c index ffe0249bc4..bf93ae5e88 100644 --- a/net/tcp/tcp_send_buffered.c +++ b/net/tcp/tcp_send_buffered.c @@ -309,7 +309,9 @@ static inline bool psock_send_addrchck(FAR struct tcp_conn_s *conn) #endif #if !defined(CONFIG_NET_ARP_IPIN) && !defined(CONFIG_NET_ARP_SEND) - if (arp_find(conn->u.ipv4.raddr) != NULL) + struct arp_entry entry; + + if (arp_find(conn->u.ipv4.raddr, &entry) >= 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 ddcd2a1eb0..f6aecef56c 100644 --- a/net/tcp/tcp_send_unbuffered.c +++ b/net/tcp/tcp_send_unbuffered.c @@ -257,9 +257,10 @@ static inline bool psock_send_addrchck(FAR struct tcp_conn_s *conn) #ifdef CONFIG_NET_ROUTE in_addr_t router; #endif - #if !defined(CONFIG_NET_ARP_IPIN) && !defined(CONFIG_NET_ARP_SEND) - if (arp_find(conn->u.ipv4.raddr) != NULL) + struct arp_entry entry; + + if (arp_find(conn->u.ipv4.raddr, &entry) >= 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 16c7e9d622..f6044b8e67 100644 --- a/net/tcp/tcp_sendfile.c +++ b/net/tcp/tcp_sendfile.c @@ -296,7 +296,9 @@ static inline bool sendfile_addrcheck(FAR struct tcp_conn_s *conn) #endif { #if !defined(CONFIG_NET_ARP_IPIN) && !defined(CONFIG_NET_ARP_SEND) - return (arp_find(conn->u.ipv4.raddr) != NULL); + struct arp_entry entry; + + return (arp_find(conn->u.ipv4.raddr, &entry) >= 0); #else return true; #endif diff --git a/net/udp/udp_psock_sendto_buffered.c b/net/udp/udp_psock_sendto_buffered.c index 8d5608ab9a..e3998d4542 100644 --- a/net/udp/udp_psock_sendto_buffered.c +++ b/net/udp/udp_psock_sendto_buffered.c @@ -281,7 +281,9 @@ static inline bool sendto_addrcheck(FAR struct udp_conn_s *conn, #endif { #if !defined(CONFIG_NET_ARP_IPIN) && !defined(CONFIG_NET_ARP_SEND) - return (arp_find(conn->u.ipv4.raddr) != NULL); + struct arp_entry entry; + + return (arp_find(conn->u.ipv4.raddr, entry) >= 0); #else return true; #endif