647 lines
21 KiB
C
647 lines
21 KiB
C
/*
|
|
******************************************************************************
|
|
* SOURCE FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipnet_cmd_ndp.c,v $ $Revision: 1.50.10.3 $
|
|
* $Source: /home/interpeak/CVSRoot/ipnet2/src/ipnet_cmd_ndp.c,v $
|
|
* $Author: kenneth $
|
|
* $State: Exp $ $Locker: $
|
|
*
|
|
* INTERPEAK_COPYRIGHT_STRING
|
|
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
|
******************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
|
|
#ifdef IPCOM_KERNEL
|
|
#undef IPCOM_KERNEL
|
|
#endif
|
|
#include "ipnet_config.h"
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#ifdef IPCOM_USE_INET6
|
|
|
|
#define IPCOM_USE_CLIB_PROTO
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_cmd.h>
|
|
#include <ipcom_getopt.h>
|
|
|
|
#include "ipnet.h"
|
|
#include "ipnet_cmd.h"
|
|
#include "ipnet_ctrl.h"
|
|
#include "ipnet_h.h"
|
|
#include "ipnet_routesock.h"
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 LOCAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_ndp_expire_time_str
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters: expires - IPCOM_ADDR_INFINITE, or time in seconds until
|
|
* entry expiration
|
|
* str_expire - buffer to write string representing 'expires'
|
|
* into
|
|
* Returns: str_expire
|
|
*
|
|
*/
|
|
IP_STATIC IP_CONST char*
|
|
ipnet_ndp_expire_time_str(Ip_u32 expires, char *str_expire)
|
|
{
|
|
if (expires == (Ip_time_t)IPCOM_ADDR_INFINITE)
|
|
ipcom_sprintf(str_expire, "perm");
|
|
else
|
|
ipcom_sprintf(str_expire, "%u s", expires);
|
|
return str_expire;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_ndp_state_str
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC char
|
|
ipnet_ndp_state_str(Ipnet_nd_state_t status)
|
|
{
|
|
switch (status)
|
|
{
|
|
case IPNET_ND_REACHABLE:
|
|
return 'R';
|
|
case IPNET_ND_STALE:
|
|
return 'S';
|
|
case IPNET_ND_DELAY:
|
|
return 'D';
|
|
case IPNET_ND_PROBE:
|
|
return 'P';
|
|
default:
|
|
/* Incomplete */
|
|
return 'I';
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_ndp_print_ndp_entry
|
|
*===========================================================================
|
|
* Description: Prints a NDP entry
|
|
* Parameters: rt - A NDP entry
|
|
* addrs - Addresses for this NDP entry.
|
|
* Returns: 0 = success, -1 = fail.
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipnet_ndp_print_entry(struct Ipnet_rt_msghdr *rt,
|
|
struct Ip_sockaddr *addrs[IPNET_RTAX_MAX])
|
|
{
|
|
struct Ipnet_tag_nc_entry tag;
|
|
char str[256];
|
|
int ret;
|
|
|
|
tag.hdr.type = IPNET_CTRL_GET_NC_ENTRY;
|
|
tag.hdr.size = sizeof(tag);
|
|
tag.ifindex = rt->rtm_index;
|
|
ipcom_memcpy(&tag.addr,
|
|
addrs[IPNET_RTAX_DST],
|
|
sizeof(tag.addr));
|
|
tag.vr_index = (Ip_u16) ipcom_proc_vr_get();
|
|
ret = ipnet_ctrl(&tag.hdr);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
ipcom_printf("%-35s ",
|
|
ipcom_cmd_sockaddr_to_str((struct Ip_sockaddr *) &tag.addr,
|
|
IP_FALSE,
|
|
IP_TRUE,
|
|
str,
|
|
sizeof(str)));
|
|
ipcom_printf("%-18s ",
|
|
ipcom_cmd_sockaddr_to_str((struct Ip_sockaddr *) &tag.link_addr,
|
|
IP_FALSE,
|
|
IP_TRUE,
|
|
str,
|
|
sizeof(str)));
|
|
ipcom_printf("%-9s ", ipcom_if_indextoname(tag.ifindex, str));
|
|
ipcom_printf("%-7s ", ipnet_ndp_expire_time_str(tag.expires_sec, str));
|
|
ipcom_printf("%c", ipnet_ndp_state_str(tag.state));
|
|
ipcom_printf("\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_ndp_delete_ndp_entry
|
|
*===========================================================================
|
|
* Description: Deletes a NDP entry.
|
|
* Parameters: silent - IP_TRUE to quench any output to stdout.
|
|
* ifindex - interface the NDP entry is assigned to
|
|
* str_ip6_addr - the IPv6 address of the NDP entry
|
|
* Returns: 0 = success, -1 == error
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipnet_ndp_delete_ndp_entry(Ip_bool silent,
|
|
Ip_u32 ifindex,
|
|
IP_CONST char *str_ip6_addr)
|
|
{
|
|
struct Ipnet_tag_nc_entry tag;
|
|
|
|
if (ipcom_getsockaddrbyaddrname(IP_AF_INET6,
|
|
IP_TRUE,
|
|
str_ip6_addr,
|
|
(struct Ip_sockaddr *) &tag.addr) < 0)
|
|
{
|
|
if (silent == IP_FALSE)
|
|
ipcom_printf("%s is not a valid IPv6 address\n", str_ip6_addr);
|
|
return -1;
|
|
}
|
|
|
|
tag.hdr.type = IPNET_CTRL_DEL_NC_ENTRY;
|
|
tag.hdr.size = sizeof(tag);
|
|
tag.vr_index = (Ip_u16) ipcom_proc_vr_get();
|
|
tag.ifindex = ifindex;
|
|
if (ipnet_ctrl(&tag.hdr) < 0)
|
|
{
|
|
if (silent == IP_FALSE)
|
|
ipcom_printf("Failed to delete %s: %s", str_ip6_addr, ipcom_strerror(ipcom_errno));
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_ndp_delete_cb
|
|
*===========================================================================
|
|
* Description: Deletes a single NDP entry.
|
|
* Parameters: rt - An NDP entry.
|
|
* addrs - Addresses in the NDP entry.
|
|
* Returns: 0 == success, <0 == error
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipnet_ndp_delete_cb(struct Ipnet_rt_msghdr *rt,
|
|
struct Ip_sockaddr *addrs[IPNET_RTAX_MAX])
|
|
{
|
|
char addr_str[IP_INET6_ADDRSTRLEN];
|
|
struct Ip_sockaddr_in6 *in6;
|
|
|
|
in6 = (struct Ip_sockaddr_in6 *) addrs[IPNET_RTAX_DST];
|
|
return ipnet_ndp_delete_ndp_entry(IP_TRUE,
|
|
rt->rtm_index,
|
|
ipcom_inet_ntop(IP_AF_INET6,
|
|
&in6->sin6_addr,
|
|
addr_str,
|
|
sizeof(addr_str)));
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_ndp_print_default_router_entries
|
|
*===========================================================================
|
|
* Description: Prints all default routers.
|
|
* Parameters: silent - IP_TRUE to suppress any output to stdout.
|
|
* Returns: 0 = success, -1 = fail.
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipnet_ndp_print_prefix_entries(Ip_bool silent)
|
|
{
|
|
if (silent == IP_FALSE)
|
|
{
|
|
struct Ipnet_tag_prefix_entry tag;
|
|
char str[44];
|
|
int ret;
|
|
|
|
ipcom_printf("%-40s%-10s%-8s\n", "Prefix", "Expire", "Netif");
|
|
tag.hdr.type = IPNET_CTRL_NEW_ENUM_PREFIX_ENTRY;
|
|
tag.hdr.size = sizeof(tag);
|
|
tag.ifindex = 0;
|
|
tag.vr_index = (Ip_u16) ipcom_proc_vr_get();
|
|
for (;;)
|
|
{
|
|
ret = ipnet_ctrl(&tag.hdr);
|
|
if (ret == IPNET_CTRL_ENUM_DONE)
|
|
break;
|
|
if (ret < 0)
|
|
{
|
|
ipcom_printf("ipnet_ctrl() failed to enumerate prefix entry: %s"IP_LF,
|
|
ipcom_strerror(ipcom_errno));
|
|
return -1;
|
|
}
|
|
tag.hdr.type = IPNET_CTRL_CONT_ENUM_PREFIX_ENTRY;
|
|
|
|
(void)ipcom_cmd_sockaddr_to_str((struct Ip_sockaddr *) &tag.prefix,
|
|
IP_FALSE, IP_FALSE, str, sizeof(str));
|
|
ipcom_sprintf(&str[ipcom_strlen(str)], "/%d", tag.bits);
|
|
ipcom_printf("%-39s ", str);
|
|
ipcom_printf("%-9s ", ipnet_ndp_expire_time_str(tag.expires_sec, str));
|
|
ipcom_printf("%-7s ", ipcom_if_indextoname(tag.ifindex, str));
|
|
ipcom_printf("\n");
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_ndp_print_default_router_entries
|
|
*===========================================================================
|
|
* Description: Prints all routers that has announced themself.
|
|
* Parameters: silent - IP_TRUE to suppress any output to stdout.
|
|
* Returns: 0 = success, -1 = fail.
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipnet_ndp_print_default_router_entries(Ip_bool silent)
|
|
{
|
|
if (silent == IP_FALSE)
|
|
{
|
|
struct Ipnet_tag_router_entry tag;
|
|
char str[IP_INET6_ADDRSTRLEN];
|
|
int ret;
|
|
|
|
ipcom_printf("%-36s%-10s%-8s\n", "Router address", "Expire", "Netif");
|
|
tag.hdr.type = IPNET_CTRL_NEW_ENUM_ROUTER_ENTRY;
|
|
tag.hdr.size = sizeof(tag);
|
|
tag.vr_index = (Ip_u16) ipcom_proc_vr_get();
|
|
for (;;)
|
|
{
|
|
ret = ipnet_ctrl(&tag.hdr);
|
|
if (ret == IPNET_CTRL_ENUM_DONE)
|
|
break;
|
|
if (ret < 0)
|
|
{
|
|
ipcom_printf("ipnet_ctrl() failed to get router entry: %s"IP_LF,
|
|
ipcom_strerror(ipcom_errno));
|
|
return -1;
|
|
}
|
|
tag.hdr.type = IPNET_CTRL_CONT_ENUM_ROUTER_ENTRY;
|
|
|
|
ipcom_printf("%-35s ", ipcom_inet_ntop(IP_AF_INET6, &tag.addr, str, sizeof(str)));
|
|
ipcom_printf("%-9s ", ipnet_ndp_expire_time_str(tag.expires_sec, str));
|
|
ipcom_printf("%-7s ", ipcom_if_indextoname(tag.ifindex, str));
|
|
ipcom_printf("\n");
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_ndp_remove_all_default_router_entries
|
|
*===========================================================================
|
|
* Description: Remove all default router entries.
|
|
* Parameters: silent - IP_TRUE to suppress any output to stdout.
|
|
* Returns: 0 = success, -1 = fail.
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipnet_ndp_remove_all_default_router_entries(Ip_bool silent)
|
|
{
|
|
struct Ipnet_tag_router_entry tag;
|
|
int ret;
|
|
|
|
tag.hdr.size = sizeof(tag);
|
|
tag.vr_index = (Ip_u16) ipcom_proc_vr_get();
|
|
for (;;)
|
|
{
|
|
tag.hdr.type = IPNET_CTRL_NEW_ENUM_ROUTER_ENTRY;
|
|
ret = ipnet_ctrl(&tag.hdr);
|
|
if (ret == IPNET_CTRL_ENUM_DONE)
|
|
break;
|
|
if (ret < 0)
|
|
{
|
|
if (silent == IP_FALSE)
|
|
ipcom_printf("ipnet_ctrl() failed to get router entry: %s"IP_LF,
|
|
ipcom_strerror(ipcom_errno));
|
|
return -1;
|
|
}
|
|
|
|
tag.hdr.type = IPNET_CTRL_DEL_ROUTER_ENTRY;
|
|
if (ipnet_ctrl(&tag.hdr) < 0)
|
|
{
|
|
if (silent == IP_FALSE)
|
|
ipcom_printf("ipnet_ctrl() failed to delete router entry: %s"IP_LF,
|
|
ipcom_strerror(ipcom_errno));
|
|
return -1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_ndp_add_entry
|
|
*===========================================================================
|
|
* Description: Adds a neighbor cache entry.
|
|
* Parameters: ifname - The name of the interface to a NC entry.
|
|
* str_ip6_addr - The address of the entry.
|
|
* str_link_addr - The link layer address.
|
|
* Returns: 0 = success, -1 = fail.
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipnet_ndp_add_entry(Ip_bool silent,
|
|
Ip_u32 ifindex,
|
|
IP_CONST char *str_ip6_addr,
|
|
IP_CONST char *str_link_addr)
|
|
{
|
|
struct Ipnet_tag_nc_entry tag;
|
|
char ifname[IP_IFNAMSIZ];
|
|
|
|
if (ifindex)
|
|
ipcom_if_indextoname(ifindex, ifname);
|
|
else
|
|
strncpy(ifname, "*unspecified*", IP_IFNAMSIZ);
|
|
|
|
if (ipcom_getsockaddrbyaddrname(IP_AF_INET6, IP_TRUE, str_ip6_addr,
|
|
(struct Ip_sockaddr *) &tag.addr) < 0)
|
|
{
|
|
if (silent == IP_FALSE)
|
|
ipcom_printf("%s is not a valid IPv6 address\n", str_ip6_addr);
|
|
goto errout;
|
|
}
|
|
|
|
tag.hdr.type = IPNET_CTRL_ADD_NC_ENTRY;
|
|
tag.hdr.size = sizeof(tag);
|
|
tag.ifindex = ifindex;
|
|
tag.is_router = IP_FALSE;
|
|
tag.expires_sec = IPCOM_ADDR_INFINITE;
|
|
tag.vr_index = (Ip_u16) ipcom_proc_vr_get();
|
|
if (ipcom_getsockaddrbyaddr(IP_AF_LINK,
|
|
str_link_addr,
|
|
(struct Ip_sockaddr *) &tag.link_addr) < 0)
|
|
{
|
|
if (silent == IP_FALSE)
|
|
ipcom_printf("%s is not a valid link address for %s\n",
|
|
str_link_addr,
|
|
(ipcom_if_indextoname(ifindex, ifname)
|
|
? ifname
|
|
: "<unknown>"));
|
|
return -1;
|
|
}
|
|
if (ipnet_ctrl(&tag.hdr) < 0)
|
|
{
|
|
if (silent == IP_FALSE)
|
|
ipcom_printf("Failed to add NC entry to %s\n",
|
|
(ipcom_if_indextoname(ifindex, ifname)
|
|
? ifname
|
|
: "<unknown>"));
|
|
goto errout;
|
|
}
|
|
|
|
return 0;
|
|
|
|
errout:
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_ndp_print_usage
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC void
|
|
ipnet_ndp_print_usage(void)
|
|
{
|
|
ipcom_printf(IP_LF);
|
|
ipcom_printf("NAME" IP_LF);
|
|
ipcom_printf(" ndp - control/diagnose IPv6 neighbor discovery protocol" IP_LF);
|
|
ipcom_printf(IP_LF);
|
|
ipcom_printf("SYNOPSIS" IP_LF);
|
|
ipcom_printf(" ndp [-silent] [-V <routetab>] -a" IP_LF);
|
|
ipcom_printf(" ndp [-silent] [-V <routetab>] -A" IP_LF);
|
|
ipcom_printf(" ndp [-silent] [-V <routetab>] -c" IP_LF);
|
|
ipcom_printf(" ndp [-silent] [-V <routetab>] [-i <ifname>] -d hostaddress" IP_LF);
|
|
ipcom_printf(" ndp [-silent] [-V <routetab>] -p" IP_LF);
|
|
ipcom_printf(" ndp [-silent] [-V <routetab>] -r" IP_LF);
|
|
ipcom_printf(" ndp [-silent] [-V <routetab>] -R" IP_LF);
|
|
ipcom_printf(" ndp [-silent] [[-V <routetab>] | [-i <ifname>]] -s nodeaddress ether_addr" IP_LF);
|
|
ipcom_printf(IP_LF);
|
|
ipcom_printf("DESCRIPTION" IP_LF);
|
|
ipcom_printf(" The ndp command manipulates the address mapping table used by Neighbor" IP_LF);
|
|
ipcom_printf(" Discovery Protocol (NDP). It can take up to 1 minute before deleted" IP_LF);
|
|
ipcom_printf(" entries is removed, but they should be shown as 'expired' immediately." IP_LF);
|
|
ipcom_printf(IP_LF);
|
|
ipcom_printf(" Options:"IP_LF);
|
|
ipcom_printf(" -silent Suppress output. MUST be first argument"IP_LF);
|
|
ipcom_printf(" -i <ifname> Specify interface. Selected by the stack otherwise."IP_LF);
|
|
ipcom_printf(" -V <routetab> Specify route table. <routetab> = 0 if not specified."IP_LF);
|
|
ipcom_printf(IP_LF);
|
|
ipcom_printf(" Commands:" IP_LF);
|
|
ipcom_printf(" -a Dump the currently existing NDP entries." IP_LF);
|
|
ipcom_printf(" -A Erase all NDP entries." IP_LF);
|
|
ipcom_printf(" -d Delete specified NDP entry." IP_LF);
|
|
ipcom_printf(" -p Show prefix list." IP_LF);
|
|
ipcom_printf(" -r Show the list of default routers added by the router advertisement protocol." IP_LF);
|
|
ipcom_printf(" -R Flush all default routers added by the router advertisement protocol." IP_LF);
|
|
ipcom_printf(" -s Register a NDP entry for a node. The entry will be permanent." IP_LF);
|
|
ipcom_printf(" Specify -V or -i, not both." IP_LF);
|
|
ipcom_printf("" IP_LF);
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_cmd_ndp
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_PUBLIC int
|
|
ipnet_cmd_ndp(int argc, char **argv)
|
|
{
|
|
#if IPCOM_VR_MAX > 1
|
|
Ip_u16 org_vr_index = (Ip_u16) ipcom_proc_vr_get();
|
|
Ip_u16 vr_index = org_vr_index;
|
|
#endif
|
|
Ip_u32 ifindex = 0;
|
|
Ip_bool silent = IP_FALSE;
|
|
int c;
|
|
int ret = 17;
|
|
Ipcom_getopt opt;
|
|
|
|
if (argc > 1)
|
|
{
|
|
if (ipcom_strcmp(argv[1], "-silent") == 0)
|
|
{
|
|
silent = IP_TRUE;
|
|
argc--;
|
|
argv++;
|
|
}
|
|
}
|
|
|
|
/* Parse options */
|
|
ipcom_getopt_clear_r(&opt);
|
|
while ((c = ipcom_getopt_r(argc, argv, "AHPRad:hprsV:i:", &opt)) != -1)
|
|
{
|
|
switch (c)
|
|
{
|
|
case 'V' :
|
|
#if IPCOM_VR_MAX > 1
|
|
vr_index = (Ip_u16) ipcom_atoi(opt.optarg);
|
|
#endif
|
|
break;
|
|
case 'i' :
|
|
ifindex = ipcom_if_nametoindex(opt.optarg);
|
|
if(ifindex == 0)
|
|
{
|
|
if (silent == IP_FALSE)
|
|
ipcom_printf("%s is not a valid interface."IP_LF, opt.optarg);
|
|
goto done;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
#if IPCOM_VR_MAX > 1
|
|
ipcom_proc_vr_set(vr_index);
|
|
#endif
|
|
|
|
ipcom_getopt_clear_r(&opt);
|
|
while ((c = ipcom_getopt_r(argc, argv, "AHRad:hprsV:i:", &opt)) != -1)
|
|
{
|
|
switch (c)
|
|
{
|
|
case 'a':
|
|
ipcom_printf("%-35s %-18s %-9s %-7s %-4s\n",
|
|
"Neighbor",
|
|
"Linklayer Address",
|
|
"Netif",
|
|
"Expire",
|
|
"St");
|
|
ret = ipnet_cmd_neigh_for_each(IP_AF_INET6,
|
|
ifindex,
|
|
IP_TRUE,
|
|
ipnet_ndp_print_entry);
|
|
break;
|
|
case 'A':
|
|
ret = ipnet_cmd_neigh_for_each(IP_AF_INET6,
|
|
ifindex,
|
|
IP_TRUE,
|
|
ipnet_ndp_delete_cb);
|
|
break;
|
|
case 'd':
|
|
ret = ipnet_ndp_delete_ndp_entry(silent, ifindex, opt.optarg);
|
|
break;
|
|
case 'p':
|
|
ret = ipnet_ndp_print_prefix_entries(silent);
|
|
break;
|
|
case 'R':
|
|
ret = ipnet_ndp_remove_all_default_router_entries(silent);
|
|
break;
|
|
case 'r':
|
|
ret = ipnet_ndp_print_default_router_entries(silent);
|
|
break;
|
|
case 's':
|
|
if (argc < opt.optind + 2)
|
|
goto done;
|
|
ret = ipnet_ndp_add_entry(silent, ifindex, argv[opt.optind], argv[opt.optind+1]);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
done:
|
|
#if IPCOM_VR_MAX > 1
|
|
ipcom_proc_vr_set(org_vr_index);
|
|
#endif
|
|
|
|
if (ret == 17 && silent == IP_FALSE)
|
|
ipnet_ndp_print_usage();
|
|
|
|
return ret;
|
|
}
|
|
|
|
#endif /* IPCOM_USE_INET6 */
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|
|
|