Add an 'arp' command to NSH to support access to the OS ARP table

This commit is contained in:
Gregory Nutt 2016-02-08 14:49:05 -06:00
parent 85b5341d7b
commit b8c8bea22c
7 changed files with 213 additions and 1 deletions

View File

@ -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).

View File

@ -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)

View File

@ -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

View File

@ -297,6 +297,33 @@ o addroute <target> <netmask> <router>
nsh> addroute 1.1.1.1 2.2.2.2 3.3.3.3
o arp [-a <ipaddr>|-d <ipaddr>|-s <ipaddr> <hwaddr>]
Access the OS ARP table.
-a <ipaddr>
Will show the hardware address that the IP address <ipaddr> is mapped to.
-d <ipaddr>
Will delete the mapping for the IP address <ipaddr> from the ARP table
-s <ipaddr> <hwaddr>
Will set (or replace) the mapping of the IP address <ipaddr> to the
hardware address <hwaddr>
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] <string or filepath>
o base64dec [-w] [-f] <string or filepath>
@ -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 --

View File

@ -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

View File

@ -114,6 +114,10 @@ static const struct cmdmap_s g_cmdmap[] =
{ "addroute", cmd_addroute, 4, 4, "<target> <netmask> <router>" },
#endif
#if defined(CONFIG_NET) && defined(CONFIG_NET_ARP) && !defined(CONFIG_NSH_DISABLE_ARP)
{ "arp", cmd_arp, 3, 4, "[-a <ipaddr>|-d <ipaddr>|-s <ipaddr> <hwaddr>]" },
#endif
#if defined(CONFIG_NETUTILS_CODECS) && defined(CONFIG_CODECS_BASE64)
# ifndef CONFIG_NSH_DISABLE_BASE64DEC
{ "base64dec", cmd_base64decode, 2, 4, "[-w] [-f] <string or filepath>" },

View File

@ -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 <ipaddr>
* arp -d <ipdaddr>
* arp -s <ipaddr> <hwaddr>
*/
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
****************************************************************************/