original files of m241
This commit is contained in:
@@ -0,0 +1,515 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_RCPL8_2024030303 $ $RCSfile: ipnet_cmd_arp.c,v $ $Revision: 1.50.10.4 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipnet2/src/ipnet_cmd_arp.c,v $
|
||||
* $Author: lwang7 $
|
||||
* $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_INET
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_cmd.h>
|
||||
#include <ipcom_getopt.h>
|
||||
#include <ipcom_sysctl.h>
|
||||
|
||||
#include "ipnet.h"
|
||||
#include "ipnet_eth.h"
|
||||
#include "ipnet_cmd.h"
|
||||
#include "ipnet_routesock.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 LOCAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipnet_arp_print_entry
|
||||
*===========================================================================
|
||||
* Description: Prints an ARP entry.
|
||||
* Parameters: rt - An ARP entry.
|
||||
* addrs - Addresses in the ARP entry.
|
||||
* Returns: 0 == success, <0 == error
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipnet_arp_print_entry(struct Ipnet_rt_msghdr *rt,
|
||||
struct Ip_sockaddr *addrs[IPNET_RTAX_MAX])
|
||||
{
|
||||
char str_addr[IPNET_ETH_ADDR_SIZE * 3];
|
||||
char ifname[IP_IFNAMSIZ];
|
||||
|
||||
(void)ipcom_inet_ntop(IP_AF_INET,
|
||||
&((struct Ip_sockaddr_in*) addrs[IPNET_RTAX_DST])->sin_addr,
|
||||
str_addr, sizeof(str_addr));
|
||||
|
||||
ipcom_printf("%16s", str_addr);
|
||||
ipcom_printf(" at %s ",
|
||||
ipcom_cmd_sockaddr_to_str(addrs[IPNET_RTAX_GATEWAY],
|
||||
IP_FALSE,
|
||||
IP_TRUE,
|
||||
str_addr,
|
||||
sizeof(str_addr)));
|
||||
if (IP_BIT_ISSET(rt->rtm_flags, IPNET_RTF_LOCAL))
|
||||
ipcom_printf("local ");
|
||||
if (rt->rtm_rmx.rmx_expire == IPCOM_ADDR_INFINITE)
|
||||
ipcom_printf("permanent ");
|
||||
if (IP_BIT_ISSET(rt->rtm_flags, IPNET_RTF_PROTO2))
|
||||
ipcom_printf("published ");
|
||||
ipcom_printf("on %s"IP_LF,
|
||||
ipcom_if_indextoname(rt->rtm_index, ifname));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipnet_arp_delete_or_probe
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipnet_arp_delete_or_probe(Ip_bool silent,
|
||||
Ip_u32 ifindex,
|
||||
IP_CONST char *str_ip4_addr,
|
||||
Ip_bool is_delete)
|
||||
{
|
||||
struct Ip_arpreq arpreq;
|
||||
struct Ip_sockaddr_in *addr = (struct Ip_sockaddr_in *) &arpreq.arp_pa;
|
||||
int ret;
|
||||
|
||||
ipcom_memset(&arpreq, 0, sizeof(arpreq));
|
||||
IPCOM_SA_LEN_SET(&arpreq.arp_ha, sizeof(arpreq.arp_ha));
|
||||
arpreq.arp_ha.sdl_family = IP_AF_LINK;
|
||||
arpreq.arp_ha.sdl_type = IP_IFT_ETHER;
|
||||
arpreq.arp_ha.sdl_index = (Ip_u16) ifindex;
|
||||
|
||||
IPCOM_SA_LEN_SET(&arpreq.arp_pa, sizeof(struct Ip_sockaddr));
|
||||
arpreq.arp_pa.sa_family = IP_AF_INET;
|
||||
|
||||
ret = ipcom_inet_pton(IP_AF_INET, str_ip4_addr, &addr->sin_addr);
|
||||
if (ret == -1)
|
||||
goto errout;
|
||||
if (ret == 0)
|
||||
{
|
||||
if (silent == IP_FALSE)
|
||||
ipcom_printf("arp: %s is not a valid IPv4 address."IP_LF, str_ip4_addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
int s;
|
||||
|
||||
s = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0);
|
||||
if (s < 0)
|
||||
goto errout;
|
||||
ret = ipcom_socketioctl(s, is_delete ? IP_SIOCDARP : IP_SIOCPARP, &arpreq);
|
||||
ipcom_socketclose(s);
|
||||
if (ret < 0)
|
||||
goto errout;
|
||||
if (is_delete && silent == IP_FALSE)
|
||||
ipcom_printf("arp: %s deleted."IP_LF, str_ip4_addr);
|
||||
}
|
||||
return 0;
|
||||
|
||||
errout:
|
||||
return -ipcom_errno;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipnet_arp_delete_entry
|
||||
*===========================================================================
|
||||
* Description: Deletes a single ARP entry
|
||||
* Parameters: silent - IP_TRUE to quince if all output to stdout.
|
||||
* ifindex - interface the ARP entry is assigned to
|
||||
* str_ip4_addr - the IPv4 address of the ARP entry
|
||||
* Returns: 0 = success
|
||||
* <0 = negative errno
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipnet_arp_delete_entry(Ip_bool silent, Ip_u32 ifindex, IP_CONST char *str_ip4_addr)
|
||||
{
|
||||
return ipnet_arp_delete_or_probe(silent, ifindex, str_ip4_addr, IP_TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipnet_arp_delete_cb
|
||||
*===========================================================================
|
||||
* Description: Deletes a single ARP entry.
|
||||
* Parameters: rt - An ARP entry.
|
||||
* addrs - Addresses in the ARP entry.
|
||||
* Returns: 0 == success, <0 == error
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipnet_arp_delete_cb(struct Ipnet_rt_msghdr *rt,
|
||||
struct Ip_sockaddr *addrs[IPNET_RTAX_MAX])
|
||||
{
|
||||
char addr_str[IP_INET_ADDRSTRLEN];
|
||||
struct Ip_sockaddr_in *in;
|
||||
|
||||
in = (struct Ip_sockaddr_in *) addrs[IPNET_RTAX_DST];
|
||||
return ipnet_arp_delete_entry(IP_TRUE,
|
||||
rt->rtm_index,
|
||||
ipcom_inet_ntop(IP_AF_INET,
|
||||
&in->sin_addr,
|
||||
addr_str,
|
||||
sizeof(addr_str)));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipnet_arp_force_probe
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipnet_arp_force_probe(Ip_bool silent, Ip_u32 ifindex, IP_CONST char *str_ip4_addr)
|
||||
{
|
||||
return ipnet_arp_delete_or_probe(silent, ifindex, str_ip4_addr, IP_FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipnet_arp_add_entry
|
||||
*===========================================================================
|
||||
* Description: Adds an ARP entry.
|
||||
* Parameters: silent - IP_TRUE to quench all output to stdout.
|
||||
* str_ip4_addr - IPv4 address
|
||||
* str_link_addr - Ethernet address
|
||||
* ifindex - interface index the entry should be added to
|
||||
* arp_flags - IP_ATF_xxx flags.
|
||||
* is_add - IP_TRUE if this is really an add request
|
||||
* IP_FALSE if an unsolicitated ARP response should
|
||||
* be sent
|
||||
* Returns: 0 = success
|
||||
* <0 = negative errno
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipnet_arp_add_entry(Ip_bool silent,
|
||||
IP_CONST char *str_ip4_addr,
|
||||
IP_CONST char *str_link_addr,
|
||||
Ip_u32 ifindex,
|
||||
int arp_flags,
|
||||
Ip_bool is_add)
|
||||
{
|
||||
int ret;
|
||||
int s;
|
||||
struct Ip_arpreq arpreq;
|
||||
|
||||
ipcom_memset(&arpreq, 0, sizeof(struct Ip_arpreq));
|
||||
arpreq.arp_flags = arp_flags;
|
||||
|
||||
ret = ipcom_getsockaddrbyaddr(IP_AF_LINK,
|
||||
str_link_addr,
|
||||
(struct Ip_sockaddr *) &arpreq.arp_ha);
|
||||
if (ret < 0 || arpreq.arp_ha.sdl_alen != IPNET_ETH_ADDR_SIZE)
|
||||
{
|
||||
if (silent == IP_FALSE)
|
||||
ipcom_printf("arp: '%s' is not a valid link address."IP_LF, str_link_addr);
|
||||
goto errout;
|
||||
}
|
||||
arpreq.arp_ha.sdl_type = IP_IFT_ETHER;
|
||||
arpreq.arp_ha.sdl_index = (Ip_u16) ifindex;
|
||||
|
||||
ret = ipcom_getsockaddrbyaddr(IP_AF_INET, str_ip4_addr, &arpreq.arp_pa);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (silent == IP_FALSE)
|
||||
ipcom_printf("arp: '%s' is not a valid IPv4 address."IP_LF, str_ip4_addr);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
s = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0);
|
||||
ret = ipcom_socketioctl(s, is_add ? IP_SIOCSARP : IP_SIOCUARP, &arpreq);
|
||||
ipcom_socketclose(s);
|
||||
if (ret < 0)
|
||||
goto errout;
|
||||
|
||||
return 0;
|
||||
|
||||
errout:
|
||||
return -ipcom_errno;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipnet_arp_print_usage
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipnet_arp_print_usage(void)
|
||||
{
|
||||
ipcom_printf(IP_LF
|
||||
"NAME"IP_LF
|
||||
" arp - address resolution display and control"IP_LF
|
||||
IP_LF);
|
||||
ipcom_printf("SYNOPSIS"IP_LF
|
||||
" arp [-silent] [-V <routetab>] [-i <ifname>] -a"IP_LF
|
||||
" arp [-silent] [-V <routetab>] [-i <ifname>] -A"IP_LF
|
||||
" arp [-silent] [-V <routetab>] [-i <ifname>] -F"IP_LF
|
||||
" arp [-silent] [-V <routetab>] [-i <ifname>] -d <hostaddress>"IP_LF
|
||||
" arp [-silent] [-V <routetab>] [-i <ifname>] [-p] [-t] -s <hostaddress> <ether_addr>"IP_LF
|
||||
" arp [-silent] [-V <routetab>] [-i <ifname>] -r <hostaddress>"IP_LF
|
||||
" arp [-silent] [-V <routetab>] [-i <ifname>] -u <peeraddress> <ether_addr>"IP_LF
|
||||
IP_LF);
|
||||
ipcom_printf("DESCRIPTION"IP_LF
|
||||
" The arp program displays and modifies the Internet-to-Ethernet address"IP_LF
|
||||
" translation tables used by the address resolution protocol."IP_LF
|
||||
IP_LF
|
||||
" Options:"IP_LF
|
||||
" -silent Suppress output. MUST be the first argument."IP_LF
|
||||
" -i <ifname> Specify interface. First one if not specified."IP_LF
|
||||
" -t Temporary ARP entry."IP_LF
|
||||
" -p Public ARP entry (i.e. proxy ARP entry)."IP_LF
|
||||
" -V <routetab> Specify route table. 0 if not specified."IP_LF
|
||||
IP_LF);
|
||||
ipcom_printf(" Commands:"IP_LF
|
||||
" -a Display the currently existing ARP entries."IP_LF
|
||||
" -A Delete all the ARP entries."IP_LF
|
||||
" -F Delete all the non-permanent ARP entries."IP_LF
|
||||
" -d Delete specified ARP entry."IP_LF
|
||||
" -s Register a ARP entry for a node."IP_LF
|
||||
" -r Send an ARP request to the host address."IP_LF
|
||||
" -u Send an unsolicited ARP response."IP_LF);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipnet_cmd_arp
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC int
|
||||
ipnet_cmd_arp(int argc, char **argv)
|
||||
{
|
||||
int c, ret = 17;
|
||||
Ip_u32 ifindex = 0;
|
||||
#if IPCOM_VR_MAX > 1
|
||||
int vr = ipcom_proc_vr_get();
|
||||
int vr_new = vr;
|
||||
#endif
|
||||
Ipcom_getopt opt;
|
||||
int arp_flags = IP_ATF_PERM;
|
||||
Ip_bool silent = IP_FALSE;
|
||||
Ip_bool all_neighbors = IP_FALSE;
|
||||
int opt_mask = 0;
|
||||
|
||||
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, "aAFd:si:V:vtpgr:u", &opt)) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
#if IPCOM_VR_MAX > 1
|
||||
case 'V' :
|
||||
vr_new = ipcom_atoi(opt.optarg);
|
||||
break;
|
||||
#endif
|
||||
case 'i' :
|
||||
ifindex = ipcom_if_nametoindex(opt.optarg);
|
||||
if(ifindex == 0)
|
||||
{
|
||||
if (silent == IP_FALSE)
|
||||
ipcom_printf("arp: %s is not a valid interface."IP_LF, opt.optarg);
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
IP_BIT_CLR(arp_flags, IP_ATF_PERM);
|
||||
break;
|
||||
case 'p':
|
||||
IP_BIT_SET(arp_flags, IP_ATF_PUBL);
|
||||
break;
|
||||
case 'g':
|
||||
IP_BIT_SET(arp_flags, IP_ATF_GRAT);
|
||||
break;
|
||||
case 'v':
|
||||
all_neighbors = IP_TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if IPCOM_VR_MAX > 1
|
||||
if (vr != vr_new)
|
||||
ipcom_proc_vr_set(vr_new);
|
||||
#endif
|
||||
|
||||
/* Parse commands */
|
||||
ipcom_getopt_clear_r(&opt);
|
||||
while ((c = ipcom_getopt_r(argc, argv, "aAFd:si:V:vtpgr:u", &opt)) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'a':
|
||||
ret = ipnet_cmd_neigh_for_each(IP_AF_INET,
|
||||
ifindex,
|
||||
all_neighbors,
|
||||
ipnet_arp_print_entry);
|
||||
goto done;
|
||||
case 'A':
|
||||
ret = ipnet_cmd_neigh_for_each(IP_AF_INET,
|
||||
ifindex,
|
||||
all_neighbors,
|
||||
ipnet_arp_delete_cb);
|
||||
goto done;
|
||||
case 'F':
|
||||
/*Flush all non-permanent entries.*/
|
||||
IP_BIT_SET(opt_mask, IP_ARPOPT_NONPERM);
|
||||
ret = ipnet_cmd_neigh_for_each_optmask(IP_AF_INET,
|
||||
ifindex,
|
||||
all_neighbors,
|
||||
opt_mask,
|
||||
ipnet_arp_delete_cb);
|
||||
goto done;
|
||||
case 'd':
|
||||
ret = ipnet_arp_delete_entry(silent, ifindex, opt.optarg);
|
||||
goto done;
|
||||
case 'r':
|
||||
ret = ipnet_arp_force_probe(silent, ifindex, opt.optarg);
|
||||
goto done;
|
||||
case 's':
|
||||
case 'u':
|
||||
if (argc < opt.optind + 2)
|
||||
goto done;
|
||||
ret = ipnet_arp_add_entry(silent,
|
||||
argv[opt.optind], /* host addr */
|
||||
argv[opt.optind+1], /* Ether addr */
|
||||
ifindex,
|
||||
arp_flags,
|
||||
c == 's');
|
||||
goto done;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (ret == 17 && silent == IP_FALSE)
|
||||
ipnet_arp_print_usage();
|
||||
|
||||
if (ret < 0 && silent == IP_FALSE)
|
||||
ipcom_printf("arp: operation failed, errno: %s" IP_LF, ipcom_strerror(-ret));
|
||||
|
||||
#if IPCOM_VR_MAX > 1
|
||||
if (vr != vr_new)
|
||||
ipcom_proc_vr_set(vr);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* IPCOM_USE_INET */
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user