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 -gt integer | integer -le integer |
integer -lt integer | integer -ne 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 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>) will map the IP address of a router on a local network(<router>)
to an external network characterized by the <target> IP address and to an external network characterized by the <target> IP address and
a network mask <netmask> 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: 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>] 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 brw-rw-rw- 0 ram0
nsh> dd if=/dev/ram0 of=/dev/null 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 This command removes an entry from the routing table. The entry
removed will be the first entry in the routing table that matches removed will be the first entry in the routing table that matches
the external network characterized by the <target> IP address and the external network characterized by the <target> IP address and
the network mask <netmask> 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: 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 o df

View File

@ -111,7 +111,7 @@ static const struct cmdmap_s g_cmdmap[] =
#endif #endif
#if defined(CONFIG_NET) && defined(CONFIG_NET_ROUTE) && !defined(CONFIG_NSH_DISABLE_ADDROUTE) #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 #endif
#if defined(CONFIG_NET) && defined(CONFIG_NET_ARP) && !defined(CONFIG_NSH_DISABLE_ARP) #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 # endif
#if defined(CONFIG_NET) && defined(CONFIG_NET_ROUTE) && !defined(CONFIG_NSH_DISABLE_DELROUTE) #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 #endif
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT) && \ #if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT) && \

View File

@ -41,8 +41,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <net/route.h> #include <ctype.h>
#include <net/route.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
@ -53,6 +54,44 @@
#if defined(CONFIG_NET) && defined(CONFIG_NET_ROUTE) #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 * Public Functions
****************************************************************************/ ****************************************************************************/
@ -60,7 +99,7 @@
/**************************************************************************** /****************************************************************************
* Name: cmd_addroute * 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; } inaddr;
sa_family_t family; sa_family_t family;
int rtrndx;
int shift;
int sockfd; int sockfd;
int ret; int ret;
/* NSH has already verified that there are exactly three arguments, so /* Check if slash notation is used with the target address */
* we don't have to look at the argument list.
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 */ /* Convert the target IP address string into its binary form */
#ifdef CONFIG_NET_IPv4 #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 */ /* Convert the netmask IP address string into its binary form */
ret = inet_pton(family, argv[2], &inaddr); if (shift >= 0)
if (ret != 1)
{ {
nsh_output(vtbl, g_fmtarginvalid, argv[0]); #ifdef CONFIG_NET_IPv4
goto errout_with_sockfd; #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 */ /* 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 */ /* 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) if (ret != 1)
{ {
nsh_output(vtbl, g_fmtarginvalid, argv[0]); nsh_output(vtbl, g_fmtarginvalid, argv[0]);
@ -263,7 +370,7 @@ errout:
/**************************************************************************** /****************************************************************************
* Name: cmd_delroute * 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; } inaddr;
sa_family_t family; sa_family_t family;
int shift;
int sockfd; int sockfd;
int ret; int ret;
/* NSH has already verified that there are exactly two arguments, so /* Check if slash notation is used with the target address */
* we don't have to look at the argument list.
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 */ /* Convert the target IP address string into its binary form */
#ifdef CONFIG_NET_IPv4 #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 */ /* Convert the netmask IP address string into its binary form */
ret = inet_pton(family, argv[2], &inaddr); if (shift >= 0)
if (ret != 1)
{ {
nsh_output(vtbl, g_fmtarginvalid, argv[0]); #ifdef CONFIG_NET_IPv4
goto errout_with_sockfd; #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 */ /* Format the netmask sockaddr instance */