Files
m241Neelima/components/ip_net2-6.9/iplite2/src/iplite_cmd_arp.c
T
2026-07-30 11:19:44 +05:30

487 lines
13 KiB
C

/*
******************************************************************************
* SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: iplite_cmd_arp.c,v $ $Revision: 1.23 $
* $Source: /home/interpeak/CVSRoot/iplite2/src/iplite_cmd_arp.c,v $
* $Author: lob $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#ifndef IPCOM_KERNEL
#define IPCOM_KERNEL
#endif
#include "iplite_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef IPCOM_USE_INET
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_clib.h>
#include <ipcom_getopt.h>
#include "iplite_h.h"
#include "iplite_eth.h"
#include "iplite_cmd.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
IP_PUBLIC int iplite_cmd_arp(int argc, char **argv);
IP_STATIC int iplite_arp_add_entry(IP_CONST char *str_ip4_addr, IP_CONST char *str_link_addr, Ip_u32 ifindex);
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 LOCAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* iplite_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
iplite_arp_print_entry(Iplite_netif *netif, Iplite_arp_entry *entry)
{
char str_addr[IPLITE_ETH_ADDR_SIZE * 3];
struct Ip_in_addr ina;
char buf[128];
ina.s_addr = entry->ipaddr_n;
if (ipcom_inet_ntop(IP_AF_INET, &ina, str_addr, sizeof(str_addr)) == IP_NULL)
{
return -ipcom_errno;
}
ipcom_sprintf(buf, "%16s", str_addr);
ipcom_sprintf(buf + 16, " at %s [%s]"IP_LF,
iplite_cmd_hwaddr_to_str((Ip_u8 *) entry->state.valid.ethaddr,
sizeof (entry->state.valid.ethaddr),
str_addr,
sizeof (str_addr)),
netif->ipcom.name);
IPLITE_CODE_UNLOCK();
ipcom_printf(buf);
IPLITE_CODE_LOCK();
return 0;
}
/*
*===========================================================================
* iplite_arp_for_each
*===========================================================================
* Description: Lists all ARP entries and call the callback function for each.
* Parameters: ifindex - The interface specified at the command prompt.
* cb - The callback function to call.
* Returns: 0 == success, <0 == error
*
*/
IP_STATIC int
iplite_arp_for_each(Ip_u32 ifindex,
int (*cb)(Iplite_netif *netif, Iplite_arp_entry *entry))
{
int i;
int j;
Iplite_arp_entry *entry;
Iplite_netif *netif;
IPLITE_CODE_LOCK();
for(i = 1; i < IPLITE_CONF_MAX_NETIF; i++)
{
netif = iplite.netifs[i];
if(netif == IP_NULL)
continue;
if(netif->eth == IP_NULL)
continue;
if(ifindex && ifindex != (Ip_u32)i)
continue;
/* List the ARP cache. */
for (j = 0; j < IPLITE_ARP_MAX_CACHE; j++)
{
entry = netif->eth->arp_cache[j];
if (entry != IP_NULL)
(void)cb(netif, entry);
}
}
IPLITE_CODE_UNLOCK();
return 0;
}
/*
*===========================================================================
* iplite_arp_delete_entry
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
iplite_arp_delete_entry(Iplite_netif *netif, Iplite_arp_entry *entry)
{
int i;
for (i = 0; i < IPLITE_ARP_MAX_CACHE; i++)
{
if (netif->eth->arp_cache[i] == entry)
{
iplite_kfree(entry);
netif->eth->arp_cache[i] = IP_NULL;
break;
}
}
return 0;
}
/*
*===========================================================================
* iplite_arp_add_entry
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
iplite_arp_add_entry(IP_CONST char *str_ip4_addr, IP_CONST char *str_link_addr, Ip_u32 ifindex)
{
struct Ip_in_addr ina;
Ip_u8 ethaddr[IPLITE_ETH_ADDR_SIZE];
Iplite_netif *netif;
int i = 0;
Iplite_arp_entry **arp_entry;
int ret = 0;
char macstr[30]; /* 6*4+5+1 */
char *str;
char *endptr;
char *tmp;
Ip_u32 n;
ipcom_strncpy(macstr, str_link_addr, sizeof(macstr) - 1);
macstr[sizeof(macstr) - 1] = '\0';
ret = ipcom_inet_pton(IP_AF_INET, str_ip4_addr, &ina);
if (ret < 0)
return -ipcom_errno;
if (ret == 0)
return -IP_ERRNO_EINVAL; /* Invalid IPv4 address */
str = ipcom_strtok_r(macstr, ":", &tmp);
while (str != IP_NULL)
{
n = ipcom_strtol(str, &endptr, 16);
if (*endptr != '\0')
return -IP_ERRNO_EINVAL; /* Trailing garbage in hex-number */
ethaddr[i] = (Ip_u8) n;
i++;
str = ipcom_strtok_r(IP_NULL, ":", &tmp);
}
if (i != IPLITE_ETH_ADDR_SIZE)
return -IP_ERRNO_EINVAL;
IPLITE_CODE_LOCK();
if (ifindex == 0)
netif = iplite_ip4_get_netif(ina.s_addr, IP_NULL);
else
netif = iplite.netifs[ifindex];
if (netif == IP_NULL)
{
ret = -IP_ERRNO_EINVAL;
goto errout;
}
do
{
arp_entry = &netif->eth->arp_cache[i];
i++;
}
while (*arp_entry != IP_NULL && i < IPLITE_ARP_MAX_CACHE);
if (i >= IPLITE_ARP_MAX_CACHE)
{
ret = -IP_ERRNO_ENOBUFS;
goto errout;
}
*arp_entry = iplite_kmalloc(sizeof(Iplite_arp_entry));
if (*arp_entry == IP_NULL)
{
ret = -IP_ERRNO_ENOMEM;
goto errout;
}
(*arp_entry)->ipaddr_n = ina.s_addr;
(*arp_entry)->state.valid.enddate = IPLITE_ARP_TIMEOUT_PERMANENT;
ipcom_memcpy((*arp_entry)->state.valid.ethaddr, ethaddr, IPLITE_ETH_ADDR_SIZE);
ret = 0;
errout:
IPLITE_CODE_UNLOCK();
return ret;
}
/*
*===========================================================================
* iplite_cmd_arp_get_entry_from_addr
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
iplite_cmd_arp_get_entry_from_addr(char *str_addr, Iplite_netif **matching_if, Iplite_arp_entry **matching_entry)
{
struct Ip_in_addr ina;
Iplite_arp_entry *entry = IP_NULL;
Iplite_netif *netif = IP_NULL;
int i = 1;
int j;
if (ipcom_inet_pton (IP_AF_INET, str_addr, &ina) < 0)
{
return -ipcom_errno;
}
while (i < IPLITE_CONF_MAX_NETIF && entry == IP_NULL)
{
netif = iplite.netifs[i];
i++;
if (netif == IP_NULL)
continue;
if (netif->eth == IP_NULL)
continue;
for (j = 0; j < IPLITE_ARP_MAX_CACHE; j++)
{
entry = netif->eth->arp_cache[j];
if (entry != IP_NULL && entry->ipaddr_n == ina.s_addr)
break;
else
entry = IP_NULL;
}
}
if (entry != IP_NULL)
{
*matching_if = netif;
*matching_entry = entry;
return 0;
}
else
{
return -IP_ERRNO_ENXIO;
}
}
/*
*===========================================================================
* iplite_arp_print_usage
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
iplite_arp_print_usage(void)
{
ipcom_printf(IP_LF);
ipcom_printf("NAME"IP_LF);
ipcom_printf(" arp - address resolution display and control"IP_LF);
ipcom_printf(IP_LF);
ipcom_printf("SYNOPSIS"IP_LF);
ipcom_printf(" arp [-i <ifname>] -a"IP_LF);
ipcom_printf(" arp [-i <ifname>] -A"IP_LF);
ipcom_printf(" arp -d hostaddress"IP_LF);
ipcom_printf(" arp [-i <ifname>] -s nodeaddress ether_addr"IP_LF);
ipcom_printf(IP_LF);
ipcom_printf("DESCRIPTION"IP_LF);
ipcom_printf(" The arp program displays and modifies the Internet-to-Ethernet address"IP_LF);
ipcom_printf(" translation tables used by the address resolution protocol."IP_LF);
ipcom_printf(IP_LF);
ipcom_printf(" Options:"IP_LF);
ipcom_printf(" -i <ifname> Specify interface. First one if not specified."IP_LF);
ipcom_printf(IP_LF);
ipcom_printf(" Commands:"IP_LF);
ipcom_printf(" -a Display the currently existing ARP entries."IP_LF);
ipcom_printf(" -A Erase all the ARP entries."IP_LF);
ipcom_printf(" -d Delete specified ARP entry."IP_LF);
ipcom_printf(" -s Register a ARP entry for a node."IP_LF);
ipcom_printf(IP_LF);
}
/*
****************************************************************************
* 10 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* iplite_cmd_arp
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC int
iplite_cmd_arp(int argc, char **argv)
{
int c, ret = 17;
Ip_u32 ifindex = 0;
Ipcom_getopt opt;
/* Parse options */
ipcom_getopt_clear_r(&opt);
while ((c = ipcom_getopt_r(argc, argv, "aAd:si:", &opt)) != -1)
{
switch (c)
{
case 'i' :
ifindex = ipcom_if_nametoindex(opt.optarg);
if (ifindex == 0)
{
ipcom_printf("arp: %s is not a valid interface."IP_LF, opt.optarg);
goto done;
}
break;
default:
break;
}
}
/* Parse commands */
ipcom_getopt_clear_r(&opt);
while ((c = ipcom_getopt_r(argc, argv, "aAd:si:", &opt)) != -1)
{
switch (c)
{
case 'a':
ret = iplite_arp_for_each(ifindex, iplite_arp_print_entry);
goto done;
case 'A':
ret = iplite_arp_for_each(ifindex, iplite_arp_delete_entry);
goto done;
case 'd':
{
Iplite_arp_entry *entry;
Iplite_netif *netif;
ret = iplite_cmd_arp_get_entry_from_addr(opt.optarg,
&netif, &entry);
if (ret == 0)
{
IPLITE_CODE_LOCK();
ret = iplite_arp_delete_entry(netif, entry);
IPLITE_CODE_UNLOCK();
}
}
goto done;
case 's':
if (argc < opt.optind + 2)
goto done;
ret = iplite_arp_add_entry(argv[opt.optind], argv[opt.optind+1], ifindex);
goto done;
case 'i' :
case 'V' :
default:
break;
}
}
done:
if (ret == 17)
iplite_arp_print_usage();
if (ret < 0)
ipcom_printf("arp: operation failed, errno: %s" IP_LF, ipcom_strerror(-ret));
ipcom_printf(IP_LF);
return ret;
}
#endif /* IPCOM_USE_INET */
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/