NSH addroute and delroute: All expression of the netmask in IPv4 CIDR or IPv6 slash notation. This really reduces the pain of using the commands, especially for IPv6.

This commit is contained in:
Gregory Nutt 2017-08-10 10:30:20 -06:00
parent f58768db3d
commit 52e4da1e41
3 changed files with 207 additions and 22 deletions

View File

@ -286,16 +286,23 @@ o test <expression>
integer -gt integer | integer -le integer |
integer -lt integer | integer -ne integer
o addroute <target> <netmask> <router>
o addroute <target> [<netmask>] <router>
This command adds an entry in the routing table. The new entry
will map the IP address of a router on a local network(<router>)
to an external network characterized by the <target> IP address and
a network mask <netmask>
The netmask may also be expressed using IPv4 CIDR or IPv6 slash
notation. In that case, the netmask need not be provided.
Example:
nsh> addroute 1.1.1.1 2.2.2.2 3.3.3.3
nsh> addroute 11.0.0.0 255.255.255.0 10.0.0.2
which is equivalent to
nsh> addroute 11.0.0.0/24 10.0.0.2
o arp [-a <ipaddr>|-d <ipaddr>|-s <ipaddr> <hwaddr>]
@ -418,16 +425,23 @@ o dd if=<infile> of=<outfile> [bs=<sectsize>] [count=<sectors>] [skip=<sectors>]
brw-rw-rw- 0 ram0
nsh> dd if=/dev/ram0 of=/dev/null
o delroute <target> <netmask>
o delroute <target> [<netmask>]
This command removes an entry from the routing table. The entry
removed will be the first entry in the routing table that matches
the external network characterized by the <target> IP address and
the network mask <netmask>
The netmask may also be expressed using IPv4 CIDR or IPv6 slash
notation. In that case, the netmask need not be provided.
Example:
nsh> delroute 1.1.1.1 2.2.2.2
nsh> delroute 11.0.0.0 255.255.255.0
which is equivalent to
nsh> delroute 11.0.0.0/24
o df

View File

@ -111,7 +111,7 @@ static const struct cmdmap_s g_cmdmap[] =
#endif
#if defined(CONFIG_NET) && defined(CONFIG_NET_ROUTE) && !defined(CONFIG_NSH_DISABLE_ADDROUTE)
{ "addroute", cmd_addroute, 4, 4, "<target> <netmask> <router>" },
{ "addroute", cmd_addroute, 3, 4, "<target> [<netmask>] <router>" },
#endif
#if defined(CONFIG_NET) && defined(CONFIG_NET_ARP) && !defined(CONFIG_NSH_DISABLE_ARP)
@ -165,7 +165,7 @@ static const struct cmdmap_s g_cmdmap[] =
# endif
#if defined(CONFIG_NET) && defined(CONFIG_NET_ROUTE) && !defined(CONFIG_NSH_DISABLE_DELROUTE)
{ "delroute", cmd_delroute, 3, 3, "<target> <netmask>" },
{ "delroute", cmd_delroute, 2, 3, "<target> [<netmask>]" },
#endif
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT) && \

View File

@ -41,8 +41,9 @@
#include <stdlib.h>
#include <string.h>
#include <net/route.h>
#include <ctype.h>
#include <net/route.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@ -53,6 +54,44 @@
#if defined(CONFIG_NET) && defined(CONFIG_NET_ROUTE)
/****************************************************************************
* Private Functions
****************************************************************************/
static int slash_notation(FAR char *arg)
{
FAR char *sptr;
FAR char *ptr;
/* If an address contains a /, then the netmask is imply by the following
* numeric value.
*/
sptr = strchr(arg, '/');
if (sptr != NULL)
{
/* Make sure that everything following the slash is a decimal digit. */
ptr = sptr + 1;
while (isdigit(*ptr))
{
ptr++;
}
/* There should be nothing be digits after the slash and up to the
* NULL terminator.
*/
if (*ptr == '\0')
{
*sptr++ = '\0';
return atoi(sptr);
}
}
return ERROR;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -60,7 +99,7 @@
/****************************************************************************
* Name: cmd_addroute
*
* nsh> addroute <target> <netmask> <router>
* nsh> addroute <target> [<netmask>] <router>
*
****************************************************************************/
@ -108,13 +147,30 @@ int cmd_addroute(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
} inaddr;
sa_family_t family;
int rtrndx;
int shift;
int sockfd;
int ret;
/* NSH has already verified that there are exactly three arguments, so
* we don't have to look at the argument list.
/* Check if slash notation is used with the target address */
shift = slash_notation(argv[1]);
/* There will be 2 or 3 arguments, depending on if slash notation is
* used.
*/
if (shift > 0 && argc != 3)
{
nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
goto errout;
}
else if (shift < 0 && argc != 4)
{
nsh_output(vtbl, g_fmtargrequired, argv[0]);
goto errout;
}
/* Convert the target IP address string into its binary form */
#ifdef CONFIG_NET_IPv4
@ -172,12 +228,63 @@ int cmd_addroute(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
/* Convert the netmask IP address string into its binary form */
ret = inet_pton(family, argv[2], &inaddr);
if (ret != 1)
if (shift >= 0)
{
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
goto errout_with_sockfd;
#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
if (family == PF_INET)
#endif
{
if (shift > 32)
{
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
goto errout_with_sockfd;
}
inaddr.ipv4.s_addr = (0xffffffff << shift);
}
#endif
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
else
#endif
{
int i;
memset(&inaddr.ipv6, 0, sizeof(struct sockaddr_in6));
for (i = 7; i >= 0 && shift >= 16; i--, shift -= 16)
{
inaddr.ipv6.s6_addr16[i] = 0xffff;
}
if (shift > 16 || (shift > 0 && i < 0))
{
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
goto errout_with_sockfd;
}
if (shift > 0)
{
inaddr.ipv6.s6_addr16[i] = (0xffff << (16 - shift));
}
}
#endif
rtrndx = 2;
}
else
{
/* Slash notation not used.. mask should follow the target address */
ret = inet_pton(family, argv[2], &inaddr);
if (ret != 1)
{
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
goto errout_with_sockfd;
}
rtrndx = 3;
}
/* Format the netmask sockaddr instance */
@ -206,7 +313,7 @@ int cmd_addroute(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
/* Convert the router IP address string into its binary form */
ret = inet_pton(family, argv[3], &inaddr);
ret = inet_pton(family, argv[rtrndx], &inaddr);
if (ret != 1)
{
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
@ -263,7 +370,7 @@ errout:
/****************************************************************************
* Name: cmd_delroute
*
* nsh> delroute <target> <netmask>
* nsh> delroute <target> [<netmask>]
*
****************************************************************************/
@ -301,13 +408,29 @@ int cmd_delroute(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
} inaddr;
sa_family_t family;
int shift;
int sockfd;
int ret;
/* NSH has already verified that there are exactly two arguments, so
* we don't have to look at the argument list.
/* Check if slash notation is used with the target address */
shift = slash_notation(argv[1]);
/* There will be 1 or 2 arguments, depending on if slash notation is
* used.
*/
if (shift > 0 && argc != 2)
{
nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
goto errout;
}
else if (shift < 0 && argc != 3)
{
nsh_output(vtbl, g_fmtargrequired, argv[0]);
goto errout;
}
/* Convert the target IP address string into its binary form */
#ifdef CONFIG_NET_IPv4
@ -365,11 +488,59 @@ int cmd_delroute(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
/* Convert the netmask IP address string into its binary form */
ret = inet_pton(family, argv[2], &inaddr);
if (ret != 1)
if (shift >= 0)
{
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
goto errout_with_sockfd;
#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
if (family == PF_INET)
#endif
{
if (shift > 32)
{
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
goto errout_with_sockfd;
}
inaddr.ipv4.s_addr = (0xffffffff << shift);
}
#endif
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
else
#endif
{
int i;
memset(&inaddr.ipv6, 0, sizeof(struct sockaddr_in6));
for (i = 7; i >= 0 && shift >= 16; i--, shift -= 16)
{
inaddr.ipv6.s6_addr16[i] = 0xffff;
}
if (shift > 16 || (shift > 0 && i < 0))
{
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
goto errout_with_sockfd;
}
if (shift > 0)
{
inaddr.ipv6.s6_addr16[i] = (0xffff << (16 - shift));
}
}
#endif
}
else
{
/* Slash notation not used.. mask should follow the target address */
ret = inet_pton(family, argv[2], &inaddr);
if (ret != 1)
{
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
goto errout_with_sockfd;
}
}
/* Format the netmask sockaddr instance */