diff --git a/ChangeLog.txt b/ChangeLog.txt index c7e730261..b4eec3b68 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1548,4 +1548,6 @@ * apps/netutils/dhcpd: DHCPD no longer calls directly into the OS but uses the new network IOCTL commands to modify the ARP table (2016-02-08). + * apps/nshlib: Add an 'arp' command that will support access to + the OS ARP table (2016-02-08). diff --git a/netutils/netlib/netlib_setarp.c b/netutils/netlib/netlib_setarp.c index 80317221c..26d200ee5 100644 --- a/netutils/netlib/netlib_setarp.c +++ b/netutils/netlib/netlib_setarp.c @@ -89,7 +89,7 @@ int netlib_set_arpmapping(FAR const struct sockaddr_in *inaddr, memcpy(&req.arp_pa, inaddr, sizeof(struct sockaddr_in)); req.arp_ha.sa_family = ARPHRD_ETHER; - memcpy(&req.arp_ha, macaddr,ETHER_ADDR_LEN); + memcpy(&req.arp_ha.sa_data, macaddr, ETHER_ADDR_LEN); ret = ioctl(sockfd, SIOCSARP, (unsigned long)((uintptr_t)&req)); if (ret < 0) diff --git a/nshlib/Kconfig b/nshlib/Kconfig index f6261abd8..a843c5f72 100644 --- a/nshlib/Kconfig +++ b/nshlib/Kconfig @@ -195,6 +195,12 @@ config NSH_DISABLE_ADDROUTE default y if DEFAULT_SMALL default n if !DEFAULT_SMALL +config NSH_DISABLE_ARP + bool "Disable arp" + default y if DEFAULT_SMALL + default n if !DEFAULT_SMALL + depends on NET_ARP + config NSH_DISABLE_BASE64DEC bool "Disable base64dec" default y if DEFAULT_SMALL diff --git a/nshlib/README.txt b/nshlib/README.txt index b839cc76d..13f4ad7f4 100644 --- a/nshlib/README.txt +++ b/nshlib/README.txt @@ -297,6 +297,33 @@ o addroute nsh> addroute 1.1.1.1 2.2.2.2 3.3.3.3 +o arp [-a |-d |-s ] + + Access the OS ARP table. + + -a + Will show the hardware address that the IP address is mapped to. + + -d + Will delete the mapping for the IP address from the ARP table + + -s + Will set (or replace) the mapping of the IP address to the + hardware address + + Example: + + nsh> arp -a 10.0.0.1 + nsh: arp: ioctl failed: 22 + + nsh> arp -s 10.0.0.1 00:13:3b:12:73:e6 + nsh> arp -a 10.0.0.1 + HWAddr: 00:13:3b:12:73:e6 + + nsh> arp -d 10.0.0.1 + nsh> arp -a 10.0.0.1 + nsh: arp: ioctl failed: 22 + o base64dec [-w] [-f] o base64dec [-w] [-f] @@ -1143,6 +1170,7 @@ Command Dependencies on Configuration Settings ---------- -------------------------- [ !CONFIG_NSH_DISABLESCRIPT addroute CONFIG_NET && CONFIG_NET_ROUTE + arp CONFIG_NET && CONFIG_NET_ARP base64dec CONFIG_NETUTILS_CODECS && CONFIG_CODECS_BASE64 base64enc CONFIG_NETUTILS_CODECS && CONFIG_CODECS_BASE64 basename -- diff --git a/nshlib/nsh.h b/nshlib/nsh.h index 068261bc0..1ed07a124 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -1092,6 +1092,9 @@ int cmd_lsmod(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif /* CONFIG_NFILE_DESCRIPTORS */ #if defined(CONFIG_NET) +# if defined(CONFIG_NET_ARP) && !defined(CONFIG_NSH_DISABLE_ARP) + int cmd_arp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +# endif # if defined(CONFIG_NET_ROUTE) && !defined(CONFIG_NSH_DISABLE_ADDROUTE) int cmd_addroute(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); # endif diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index 3bce11d40..d8a26ab11 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -114,6 +114,10 @@ static const struct cmdmap_s g_cmdmap[] = { "addroute", cmd_addroute, 4, 4, " " }, #endif +#if defined(CONFIG_NET) && defined(CONFIG_NET_ARP) && !defined(CONFIG_NSH_DISABLE_ARP) + { "arp", cmd_arp, 3, 4, "[-a |-d |-s ]" }, +#endif + #if defined(CONFIG_NETUTILS_CODECS) && defined(CONFIG_CODECS_BASE64) # ifndef CONFIG_NSH_DISABLE_BASE64DEC { "base64dec", cmd_base64decode, 2, 4, "[-w] [-f] " }, diff --git a/nshlib/nsh_netcmds.c b/nshlib/nsh_netcmds.c index 1e6d834dc..0684d1b9e 100644 --- a/nshlib/nsh_netcmds.c +++ b/nshlib/nsh_netcmds.c @@ -628,6 +628,36 @@ static int nsh_foreach_netdev(nsh_netdev_callback_t callback, } #endif +/**************************************************************************** + * Name: cmd_get + ****************************************************************************/ +#if defined(CONFIG_NET_ARP) && !defined(CONFIG_NSH_DISABLE_ARP) +int mac_nibble(unsigned int ch, unsigned int *nibble) +{ + unsigned int ret; + + if (ch >= '0' && ch <= '9') + { + ret = ch - '0'; + } + else if (ch >= 'A' && ch <= 'F') + { + ret = ch - 'A' + 10; + } + else if (ch >= 'a' && ch <= 'f') + { + ret = ch - 'a' + 10; + } + else + { + return -EINVAL; + } + + *nibble = ret; + return OK; +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -1160,6 +1190,145 @@ int cmd_nslookup(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) } #endif +/**************************************************************************** + * Name: cmd_arp + ****************************************************************************/ + +#if defined(CONFIG_NET_ARP) && !defined(CONFIG_NSH_DISABLE_ARP) +int cmd_arp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + FAR char *ptr; + struct sockaddr_in inaddr; + struct ether_addr mac; + int ret; + int i; + + /* Forms: + * + * aap -a + * arp -d + * arp -s + */ + + if (strcmp(argv[1], "-a") == 0) + { + if (argc != 3) + { + goto errout_toomany; + } + + /* Show the corresponding hardware address */ + + inaddr.sin_family = AF_INET; + inaddr.sin_port = INADDR_ANY; + inaddr.sin_addr.s_addr = inet_addr(argv[2]); + + ret = netlib_get_arpmapping(&inaddr, mac.ether_addr_octet); + if (ret < 0) + { + goto errout_cmdfaild; + } + + nsh_output(vtbl, "HWAddr: %s\n", ether_ntoa(&mac)); + } + else if (strcmp(argv[1], "-d") == 0) + { + if (argc != 3) + { + goto errout_toomany; + } + + /* Delete the corresponding address mapping from the arp table */ + + inaddr.sin_family = AF_INET; + inaddr.sin_port = INADDR_ANY; + inaddr.sin_addr.s_addr = inet_addr(argv[2]); + + ret = netlib_del_arpmapping(&inaddr); + if (ret < 0) + { + goto errout_cmdfaild; + } + } + else if (strcmp(argv[1], "-s") == 0) + { + unsigned int nibble; + unsigned int byte; + char delim; + + if (argc != 4) + { + goto errout_missing; + } + + /* Convert the MAC address string to a binary */ + + for (i = 0, ptr = argv[3]; i < ETHER_ADDR_LEN; i++) + { + ret = mac_nibble(*ptr++, &nibble); + if (ret < 0) + { + goto errout_invalid; + } + + byte = nibble << 4; + + ret = mac_nibble(*ptr++, &nibble); + if (ret < 0) + { + goto errout_invalid; + } + + byte |= nibble; + + delim = (i >= (ETHER_ADDR_LEN-1)) ? '\0' : ':'; + if (*ptr++ != delim) + { + goto errout_invalid; + } + + mac.ether_addr_octet[i] = byte; + } + + /* Add the address mapping to the arp table */ + + inaddr.sin_family = AF_INET; + inaddr.sin_port = INADDR_ANY; + inaddr.sin_addr.s_addr = inet_addr(argv[2]); + + ret = netlib_set_arpmapping(&inaddr, mac.ether_addr_octet); + if (ret < 0) + { + goto errout_cmdfaild; + } + } + else + { + goto errout_invalid; + } + + return OK; + +/* Error exits */ + +errout_cmdfaild: + nsh_output(vtbl, g_fmtcmdfailed, argv[0], "ioctl", NSH_ERRNO); + return ERROR; + +errout_missing: + nsh_output(vtbl, g_fmttoomanyargs, argv[0]); + return ERROR; + +errout_toomany: + nsh_output(vtbl, g_fmtargrequired, argv[0]); + return ERROR; + +errout_invalid: + nsh_output(vtbl, g_fmtarginvalid, argv[0]); + return ERROR; +} +#endif + /**************************************************************************** * Name: cmd_ping ****************************************************************************/