diff --git a/net/arp/arp.h b/net/arp/arp.h index 7c86c556bd..9e477b15fc 100644 --- a/net/arp/arp.h +++ b/net/arp/arp.h @@ -42,6 +42,7 @@ #include +#include #include #include @@ -362,23 +363,6 @@ void arp_notify(in_addr_t ipaddr); # define arp_notify(i) #endif -/**************************************************************************** - * Name: arp_lookup - * - * Description: - * 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 to assure exclusive access to the ARP table. - * The return value will become unstable when the network is unlocked. - * - ****************************************************************************/ - -FAR struct arp_entry_s *arp_lookup(in_addr_t ipaddr); - /**************************************************************************** * Name: arp_find * @@ -387,11 +371,12 @@ FAR struct arp_entry_s *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. + * dev - Device structure * * Assumptions * The network is locked to assure exclusive access to the ARP table. @@ -399,7 +384,8 @@ FAR struct arp_entry_s *arp_lookup(in_addr_t ipaddr); ****************************************************************************/ struct ether_addr; /* Forward reference */ -int arp_find(in_addr_t ipaddr, FAR struct ether_addr *ethaddr); +int arp_find(in_addr_t ipaddr, FAR uint8_t *ethaddr, + FAR struct net_driver_s *dev); /**************************************************************************** * Name: arp_delete @@ -409,13 +395,14 @@ int arp_find(in_addr_t ipaddr, FAR struct ether_addr *ethaddr); * * Input Parameters: * ipaddr - Refers to an IP address in network order + * dev - Device structure * * Assumptions * The network is locked to assure exclusive access to the ARP table. * ****************************************************************************/ -void arp_delete(in_addr_t ipaddr); +int arp_delete(in_addr_t ipaddr, FAR struct net_driver_s *dev); /**************************************************************************** * Name: arp_cleanup @@ -455,7 +442,7 @@ void arp_cleanup(FAR struct net_driver_s *dev); ****************************************************************************/ int arp_update(FAR struct net_driver_s *dev, in_addr_t ipaddr, - FAR uint8_t *ethaddr); + FAR const uint8_t *ethaddr); /**************************************************************************** * Name: arp_hdr_update @@ -479,7 +466,7 @@ int arp_update(FAR struct net_driver_s *dev, in_addr_t ipaddr, ****************************************************************************/ void arp_hdr_update(FAR struct net_driver_s *dev, FAR uint16_t *pipaddr, - FAR uint8_t *ethaddr); + FAR const uint8_t *ethaddr); /**************************************************************************** * Name: arp_snapshot @@ -541,8 +528,8 @@ 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,e) (-ENOSYS) -# define arp_delete(i) +# define arp_find(i,e,d) (-ENOSYS) +# define arp_delete(i,d) (-ENOSYS) # define arp_cleanup(d) # define arp_update(d,i,m); # define arp_hdr_update(d,i,m); diff --git a/net/arp/arp_out.c b/net/arp/arp_out.c index bd5ef3aab6..851635eee6 100644 --- a/net/arp/arp_out.c +++ b/net/arp/arp_out.c @@ -261,7 +261,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, ðaddr); + ret = arp_find(ipaddr, ethaddr.ether_addr_octet, dev); if (ret < 0) { ninfo("ARP request for IP %08lx\n", (unsigned long)ipaddr); diff --git a/net/arp/arp_send.c b/net/arp/arp_send.c index c95fcf828d..6a4f182f23 100644 --- a/net/arp/arp_send.c +++ b/net/arp/arp_send.c @@ -301,7 +301,7 @@ int arp_send(in_addr_t ipaddr) * issue. */ - if (arp_find(ipaddr, NULL) >= 0) + if (arp_find(ipaddr, NULL, dev) >= 0) { /* We have it! Break out with success */ diff --git a/net/arp/arp_table.c b/net/arp/arp_table.c index b26534e304..1f940453e6 100644 --- a/net/arp/arp_table.c +++ b/net/arp/arp_table.c @@ -78,8 +78,8 @@ 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 */ + in_addr_t ai_ipaddr; /* IP address for lookup */ + FAR uint8_t *ai_ethaddr; /* Location to return the MAC address */ }; /**************************************************************************** @@ -169,6 +169,46 @@ arp_return_old_entry(FAR struct arp_entry_s *e1, FAR struct arp_entry_s *e2) } } +/**************************************************************************** + * Name: arp_lookup + * + * Description: + * Find the ARP entry corresponding to this IP address in the ARP table. + * + * Input Parameters: + * ipaddr - Refers to an IP address in network order + * dev - Device structure + * + * Assumptions: + * The network is locked to assure exclusive access to the ARP table. + * The return value will become unstable when the network is unlocked. + * + ****************************************************************************/ + +static FAR struct arp_entry_s *arp_lookup(in_addr_t ipaddr, + FAR struct net_driver_s *dev) +{ + FAR struct arp_entry_s *tabptr; + int i; + + /* Check if the IPv4 address is already in the ARP table. */ + + for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i) + { + tabptr = &g_arptable[i]; + if (tabptr->at_dev == dev && + net_ipv4addr_cmp(ipaddr, tabptr->at_ipaddr) && + clock_systime_ticks() - tabptr->at_time <= ARP_MAXAGE_TICK) + { + return tabptr; + } + } + + /* Not found */ + + return NULL; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -195,7 +235,7 @@ arp_return_old_entry(FAR struct arp_entry_s *e1, FAR struct arp_entry_s *e2) ****************************************************************************/ int arp_update(FAR struct net_driver_s *dev, in_addr_t ipaddr, - FAR uint8_t *ethaddr) + FAR const uint8_t *ethaddr) { FAR struct arp_entry_s *tabptr = &g_arptable[0]; int i; @@ -211,7 +251,8 @@ int arp_update(FAR struct net_driver_s *dev, in_addr_t ipaddr, * the IP address in this ARP table entry. */ - if (g_arptable[i].at_ipaddr != 0 && + if (g_arptable[i].at_dev == dev && + g_arptable[i].at_ipaddr != 0 && net_ipv4addr_cmp(ipaddr, g_arptable[i].at_ipaddr)) { /* An old entry found, break. */ @@ -260,7 +301,7 @@ int arp_update(FAR struct net_driver_s *dev, in_addr_t ipaddr, ****************************************************************************/ void arp_hdr_update(FAR struct net_driver_s *dev, FAR uint16_t *pipaddr, - FAR uint8_t *ethaddr) + FAR const uint8_t *ethaddr) { in_addr_t ipaddr = net_ip4addr_conv32(pipaddr); @@ -269,43 +310,6 @@ void arp_hdr_update(FAR struct net_driver_s *dev, FAR uint16_t *pipaddr, arp_update(dev, ipaddr, ethaddr); } -/**************************************************************************** - * Name: arp_lookup - * - * Description: - * 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 to assure exclusive access to the ARP table. - * The return value will become unstable when the network is unlocked. - * - ****************************************************************************/ - -FAR struct arp_entry_s *arp_lookup(in_addr_t ipaddr) -{ - FAR struct arp_entry_s *tabptr; - int i; - - /* Check if the IPv4 address is already in the ARP table. */ - - for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i) - { - tabptr = &g_arptable[i]; - if (net_ipv4addr_cmp(ipaddr, tabptr->at_ipaddr) && - clock_systime_ticks() - tabptr->at_time <= ARP_MAXAGE_TICK) - { - return tabptr; - } - } - - /* Not found */ - - return NULL; -} - /**************************************************************************** * Name: arp_find * @@ -314,25 +318,27 @@ FAR struct arp_entry_s *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. + * dev - Device structure * * Assumptions * The network is locked to assure exclusive access to the ARP table. * ****************************************************************************/ -int arp_find(in_addr_t ipaddr, FAR struct ether_addr *ethaddr) +int arp_find(in_addr_t ipaddr, FAR uint8_t *ethaddr, + FAR struct net_driver_s *dev) { 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); + tabptr = arp_lookup(ipaddr, dev); if (tabptr != NULL) { /* Yes.. return the Ethernet MAC address if the caller has provided a @@ -377,25 +383,29 @@ int arp_find(in_addr_t ipaddr, FAR struct ether_addr *ethaddr) * * Input Parameters: * ipaddr - Refers to an IP address in network order + * dev - Device structure * * Assumptions * The network is locked to assure exclusive access to the ARP table. * ****************************************************************************/ -void arp_delete(in_addr_t ipaddr) +int arp_delete(in_addr_t ipaddr, FAR struct net_driver_s *dev) { FAR struct arp_entry_s *tabptr; /* Check if the IPv4 address is in the ARP table. */ - tabptr = arp_lookup(ipaddr); + tabptr = arp_lookup(ipaddr, dev); if (tabptr != NULL) { /* Yes.. Set the IP address to zero to "delete" it */ tabptr->at_ipaddr = 0; + return OK; } + + return -ENOENT; } /**************************************************************************** diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c index 09448d4154..764d093be1 100644 --- a/net/netdev/netdev_ioctl.c +++ b/net/netdev/netdev_ioctl.c @@ -1220,40 +1220,6 @@ static int netdev_imsf_ioctl(FAR struct socket *psock, int cmd, } #endif -/**************************************************************************** - * Name: netdev_arp_callback - * - * Description: - * This is a callback that checks if the Ethernet network device has the - * indicated name - * - * Input Parameters: - * dev Ethernet driver device structure - * req The argument of the ioctl cmd - * - * Returned Value: - * 1 on success - * 0 on error - ****************************************************************************/ - -#ifdef CONFIG_NET_ARP -static int netdev_arp_callback(FAR struct net_driver_s *dev, FAR void *arg) -{ - FAR struct arpreq *req = arg; - FAR struct sockaddr_in *addr = (FAR struct sockaddr_in *)&req->arp_pa; - - if (strncmp(dev->d_ifname, (FAR const char *)req->arp_dev, - sizeof(dev->d_ifname))) - { - return 0; - } - - arp_update(dev, addr->sin_addr.s_addr, - (FAR uint8_t *)req->arp_ha.sa_data); - return 1; -} -#endif - /**************************************************************************** * Name: netdev_arp_ioctl * @@ -1276,15 +1242,25 @@ static int netdev_arp_callback(FAR struct net_driver_s *dev, FAR void *arg) static int netdev_arp_ioctl(FAR struct socket *psock, int cmd, FAR struct arpreq *req) { + FAR struct net_driver_s *dev = NULL; + FAR struct sockaddr_in *addr = NULL; int ret; + if (req != NULL) + { + addr = (FAR struct sockaddr_in *)&req->arp_pa; + dev = req->arp_dev[0] ? + netdev_findbyname((FAR const char *)req->arp_dev) : + netdev_findby_ripv4addr(INADDR_ANY, addr->sin_addr.s_addr); + } + /* Execute the command */ switch (cmd) { case SIOCSARP: /* Set an ARP mapping */ { - if (req != NULL && + if (dev != NULL && req != NULL && req->arp_pa.sa_family == AF_INET && req->arp_ha.sa_family == ARPHRD_ETHER) { @@ -1292,7 +1268,8 @@ static int netdev_arp_ioctl(FAR struct socket *psock, int cmd, * address -OR- add a new ARP table entry if there is not. */ - ret = netdev_foreach(netdev_arp_callback, req) ? OK : -EINVAL; + ret = arp_update(dev, addr->sin_addr.s_addr, + (FAR const uint8_t *)req->arp_ha.sa_data); } else { @@ -1303,28 +1280,11 @@ static int netdev_arp_ioctl(FAR struct socket *psock, int cmd, case SIOCDARP: /* Delete an ARP mapping */ { - if (req != NULL && req->arp_pa.sa_family == AF_INET) + if (dev != NULL && req != NULL && req->arp_pa.sa_family == AF_INET) { - FAR struct sockaddr_in *addr = - (FAR struct sockaddr_in *)&req->arp_pa; + /* Delete the ARP entry for this protocol address. */ - /* Find the existing ARP entry for this protocol address. */ - - 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 - * by nullifying its protocol address. - */ - - entry->at_ipaddr = 0; - ret = OK; - } - else - { - ret = -ENOENT; - } + ret = arp_delete(addr->sin_addr.s_addr, dev); } else { @@ -1337,15 +1297,8 @@ static int netdev_arp_ioctl(FAR struct socket *psock, int cmd, { if (req != NULL && req->arp_pa.sa_family == AF_INET) { - FAR struct sockaddr_in *addr = - (FAR struct sockaddr_in *)&req->arp_pa; - - /* Get the hardware address from an existing ARP table entry - * matching this protocol address. - */ - ret = arp_find(addr->sin_addr.s_addr, - (FAR struct ether_addr *)req->arp_ha.sa_data); + (FAR uint8_t *)req->arp_ha.sa_data, dev); if (ret >= 0) { /* Return the mapped hardware address. */