diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h index 99033e33e..2f3decf48 100644 --- a/include/netutils/netlib.h +++ b/include/netutils/netlib.h @@ -314,7 +314,8 @@ int netlib_set_arpmapping(FAR const struct sockaddr_in *inaddr, FAR const uint8_t *macaddr); #ifdef CONFIG_NETLINK_ROUTE struct arp_enty_s; -int netlib_get_arptable(FAR struct arp_enty_s *arptab, unsigned int nentries); +ssize_t netlib_get_arptable(FAR struct arp_entry_s *arptab, + unsigned int nentries); #endif #endif diff --git a/netutils/netlib/netlib_getarptab.c b/netutils/netlib/netlib_getarptab.c index 5a6c5519a..87bb08b1a 100644 --- a/netutils/netlib/netlib_getarptab.c +++ b/netutils/netlib/netlib_getarptab.c @@ -90,11 +90,12 @@ struct netlib_recvfrom_response_s * size sizeof(struct arp_entry_s) * * Return: - * 0 on success; a negated errno value on failure. + * The number of ARP table entries read is returnd on success; a negated + * errno value is returned on failure. * ****************************************************************************/ -int netlib_get_arptable(FAR struct arp_enty_s *arptab, unsigned int nentries) +ssize_t netlib_get_arptable(FAR struct arp_entry_s *arptab, unsigned int nentries) { FAR struct netlib_recvfrom_response_s *resp; struct netlib_sendto_request_s req; @@ -104,7 +105,7 @@ int netlib_get_arptable(FAR struct arp_enty_s *arptab, unsigned int nentries) ssize_t paysize; ssize_t maxsize; int fd; - int ret = EXIT_FAILURE; + int ret; /* Allocate a buffer to hold the response */ @@ -114,6 +115,7 @@ int netlib_get_arptable(FAR struct arp_enty_s *arptab, unsigned int nentries) if (resp == NULL) { fprintf(stderr, "ERROR: Faile to allocat response buffer\n"); + ret = -ENOMEM; return EXIT_FAILURE; } @@ -124,6 +126,7 @@ int netlib_get_arptable(FAR struct arp_enty_s *arptab, unsigned int nentries) { int errcode = errno; fprintf(stderr, "ERROR: socket() failed: %d\n", errcode); + ret = -errcode; goto errout_with_resp; } @@ -140,6 +143,7 @@ int netlib_get_arptable(FAR struct arp_enty_s *arptab, unsigned int nentries) { int errcode = errno; fprintf(stderr, "ERROR: send() failed: %d\n", errcode); + ret = -errcode; goto errout_with_socket; } @@ -148,6 +152,7 @@ int netlib_get_arptable(FAR struct arp_enty_s *arptab, unsigned int nentries) { int errcode = errno; fprintf(stderr, "ERROR: recv() failed: %d\n", errcode); + ret = -errcode; goto errout_with_socket; } @@ -157,6 +162,7 @@ int netlib_get_arptable(FAR struct arp_enty_s *arptab, unsigned int nentries) resp->hdr.nlmsg_len > nrecvd) { fprintf(stderr, "ERROR: Bad message\n"); + ret = -EIO; goto errout_with_socket; } @@ -169,7 +175,7 @@ int netlib_get_arptable(FAR struct arp_enty_s *arptab, unsigned int nentries) } memcpy(arptab, resp->data, paysize); - ret = EXIT_SUCCESS; + ret = paysize / sizeof(struct arp_entry_s); errout_with_socket: close(fd); diff --git a/nshlib/README.txt b/nshlib/README.txt index 74b0a7aa5..b3ba71aa2 100644 --- a/nshlib/README.txt +++ b/nshlib/README.txt @@ -318,7 +318,7 @@ o addroute [] The second form of the addroute command can be used to set the default gateway. -o arp [-a |-d |-s ] +o arp [-t|-a |-d |-s ] Access the OS ARP table. @@ -332,6 +332,10 @@ o arp [-a |-d |-s ] Will set (or replace) the mapping of the IP address to the hardware address . + -t + Will dump the entire content of the ARP table. This option is only + available if CONFIG_NETLINK_ROUTE is enabled. + Example: nsh> arp -a 10.0.0.1 diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index 5f9d6c000..52c8821a1 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -113,8 +113,12 @@ static const struct cmdmap_s g_cmdmap[] = #endif #if defined(CONFIG_NET) && defined(CONFIG_NET_ARP) && !defined(CONFIG_NSH_DISABLE_ARP) +#ifdef CONFIG_NETLINK_ROUTE + { "arp", cmd_arp, 2, 4, "[-t|-a |-d |-s ]" }, +#else { "arp", cmd_arp, 3, 4, "[-a |-d |-s ]" }, #endif +#endif #if defined(CONFIG_NETUTILS_CODECS) && defined(CONFIG_CODECS_BASE64) # ifndef CONFIG_NSH_DISABLE_BASE64DEC diff --git a/nshlib/nsh_netcmds.c b/nshlib/nsh_netcmds.c index 35e37371c..341349105 100644 --- a/nshlib/nsh_netcmds.c +++ b/nshlib/nsh_netcmds.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -85,6 +86,10 @@ # endif #endif +#ifdef CONFIG_NETLINK_ROUTE +# include +#endif + #ifdef CONFIG_NETUTILS_NETLIB # include "netutils/netlib.h" #endif @@ -1049,11 +1054,90 @@ int cmd_arp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) /* Forms: * - * aap -a + * arp -t + * arp -a * arp -d * arp -s */ +#ifdef CONFIG_NETLINK_ROUTE + if (strcmp(argv[1], "-t") == 0) + { + FAR struct arp_entry_s *arptab; + size_t arpsize; + ssize_t nentries; + char ipaddr[16]; + char ethaddr[24]; + int i; + + if (argc != 2) + { + goto errout_toomany; + } + + /* Allocate a buffer to hold the ARP table */ + + arpsize = CONFIG_NET_ARPTAB_SIZE * sizeof(struct arp_entry_s); + arptab = (FAR struct arp_entry_s *)malloc(arpsize); + if (arptab == NULL) + { + nsh_error(vtbl, g_fmtcmdoutofmemory, argv[0]); + return ERROR; + } + + /* Read the ARP table */ + + nentries = netlib_get_arptable(arptab, CONFIG_NET_ARPTAB_SIZE); + if (nentries < 0) + { + nsh_error(vtbl, g_fmtcmdfailed, argv[0], netlib_get_arptable, + NSH_ERRNO_OF(-nentries)); + free(arptab); + return ERROR; + } + + /* Dump the ARP table + * + * xx.xx.xx.xx xx:xx:xx:xx:xx:xx xxxxxxxx[xxxxxxxx] + */ + + nsh_output(vtbl, "%-12s %-17s Last Access Time\n", + "IP Address", "Ethernet Address"); + + for (i = 0; i < nentries; i++) + { + FAR uint8_t *ptr; + + /* Convert the IPv4 address to a string */ + + ptr = (FAR uint8_t *)&arptab[i].at_ipaddr; + snprintf(ipaddr, 16, "%u.%u.%u.%u", + ptr[0], ptr[1], ptr[2], ptr[3]); + + /* Convert the MAC address string to a binary */ + + snprintf(ethaddr, 24, "%02x:%02x:%02x:%02x:%02x:%02x", + arptab[i].at_ethaddr.ether_addr_octet[0], + arptab[i].at_ethaddr.ether_addr_octet[1], + arptab[i].at_ethaddr.ether_addr_octet[2], + arptab[i].at_ethaddr.ether_addr_octet[3], + arptab[i].at_ethaddr.ether_addr_octet[4], + arptab[i].at_ethaddr.ether_addr_octet[5]); + +#ifdef CONFIG_SYSTEM_TIME64 + nsh_output(vtbl, "%12s %17s 0x%" PRIx64 "\n", + ipaddr, ethaddr, (uint64_t)arptab[i].at_time); +#else + nsh_output(vtbl, "%12s %17s 0x%" PRIx32 "\n", + ipaddr, ethaddr, (uint32_t)arptab[i].at_time); +#endif + } + + free(arptab); + ret = OK; + } + else +#endif if (strcmp(argv[1], "-a") == 0) { if (argc != 3)