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

615 lines
22 KiB
C

/*
*******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmipha_cmd_ha.c,v $ $Revision: 1.26 $
* $Source: /home/interpeak/CVSRoot/ipmipha/src/ipmipha_cmd_ha.c,v $
* $Author: jhorteli $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Niklas Lundberg <n@interpeak.se>
******************************************************************************
*/
/*
*******************************************************************************
* 1 DESCRIPTION
*******************************************************************************
*
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_clib.h>
#include <ipcom_err.h>
#include <ipcom_getopt.h>
#include <ipcom_inet.h>
#include <ipcom_sock2.h>
#include <ipcom_cmd.h>
#include <ipcom_getopt.h>
#include <ipcom_list.h>
#include <ipcom_ipd.h>
#include <ipmip.h>
#include <private/ipmip_context.h>
#include <private/ipmip_cli.h>
#include <ipmip4.h>
#include <private/ipmip4_msgext.h>
#include <private/ipmip4_ntop.h>
#include "ipmipha.h"
#include "ipmipha_mib.h"
#include "ipmipha_attr.h"
#include "ipmipha_cli.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPMIPHA_CMD_OP_LIST (1)
#define IPMIPHA_CMD_OP_SHOW (2)
#define IPMIPHA_CMD_OP_EVENTS (3)
#define IPMIPHA_CMD_OP_FLUSH (4)
#define IPMIPHA_CMD_OP_REVOKE (5)
#define IPMIPHA_CMD_OP_STOP (6)
#define IPMIPHA_CMD_OP_START (7)
#define IPMIPHA_CMD_OP_DELETE (8)
#define IPMIPHA_CMD_OP_MUTE (9)
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
IP_PUBLIC int ipmipha_cmd_ha(int argc, char **argv);
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
IP_STATIC Ipcom_cmd_int_str_map ipmipha_cmd_ops[] =
{
{ IPMIPHA_CMD_OP_LIST, "list" },
{ IPMIPHA_CMD_OP_SHOW, "show" },
{ IPMIPHA_CMD_OP_EVENTS, "events" },
{ IPMIPHA_CMD_OP_FLUSH, "flush" },
{ IPMIPHA_CMD_OP_REVOKE, "revoke" },
{ IPMIPHA_CMD_OP_DELETE, "delete" },
{ IPMIPHA_CMD_OP_STOP, "stop" },
{ IPMIPHA_CMD_OP_START, "start" },
{ IPMIPHA_CMD_OP_MUTE, "mute" },
{ 0, 0 }
};
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipmipha_cmd_binding_flags
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC char *
ipmipha_cmd_binding_flags(char *buffer,
struct Ipmip_attr *binding)
{
char *tt = "";
Ip_u32 type = ipmipha_cli_binding_get_tunnel_type(binding);
Ip_u32 flags = ipmipha_cli_binding_get_registration_flags(binding);
if (type == IPMIP_TUNNELTYPE_GRE)
tt = "G";
else if (type == IPMIP_TUNNELTYPE_MINENC)
tt = "M";
ipcom_sprintf(buffer,
"%s%s%s%s",
IP_BIT_ISTRUE(flags, IPMIP4_CODE_REQ_BROADCAST)? "B" : "",
IP_BIT_ISTRUE(flags, IPMIP4_CODE_REQ_REVERSE_TUNNELING)? "T" : "",
IP_BIT_ISTRUE(flags, IPMIP4_CODE_REQ_DECAPSULATION)? "D" : "",
tt);
return buffer;
}
/*
*===========================================================================
* ipmipha_cmd_coa_flags
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC const char *
ipmipha_cmd_coa_nat(struct Ipmip_attr *binding)
{
Ip_u32 flags = ipmipha_cli_binding_get_tunnel_flags(binding);
if (IP_BIT_ARESET(flags, IPMIP4_TUNNELMODE_NAT_T_CONFIRMED))
return "*";
return "";
}
/*
*===========================================================================
* ipmipha_cmd_print_binding_fmt
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipmipha_cmd_print_binding_fmt(const char *hoa,
const char *coa,
const char *ifname,
const char *lifetime,
const char *flags)
{
/* */
ipcom_printf("%-20s %-20s %-16s %-15s %s"IP_LF,
hoa, coa, ifname, lifetime, flags);
}
/*
*===========================================================================
* ipmipha_cmd_print_binding
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipmipha_cmd_print_binding(Ipmip_proc_t *proc,
Ip_u32 num,
struct Ipmip_attr *node,
struct Ipmip_attr *binding,
Ip_bool verbose)
{
ipcom_snprintf(proc->ntop.ntop_lla, sizeof(proc->ntop.ntop_lla),
"%d/%d",
ipmipha_cli_binding_get_time_remaining(binding),
ipmipha_cli_binding_get_time_granted(binding));
ipcom_snprintf(proc->ntop.ntop_pbuf, sizeof(proc->ntop.ntop_pbuf), "%s%s", ipmip_ntop_inet(proc, ipmipha_cli_binding_get_address(binding)), ipmipha_cmd_coa_nat(binding));
if (num == 0)
{
ipmipha_cmd_print_binding_fmt(ipmip_ntop_inet(proc, ipmipha_cli_node_get_home_address(node)),
proc->ntop.ntop_pbuf,
ipmipha_cli_node_get_ifname(node),
proc->ntop.ntop_lla,
ipmipha_cmd_binding_flags(proc->ntop.ntop_name, binding));
}
else if (verbose)
{
ipmipha_cmd_print_binding_fmt("",
proc->ntop.ntop_pbuf,
ipmipha_cli_node_get_ifname(node),
proc->ntop.ntop_lla,
ipmipha_cmd_binding_flags(proc->ntop.ntop_name, binding));
}
}
/*
*===========================================================================
* ipmipha_cmd_show_binding
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipmipha_cmd_show_binding(Ipmip_proc_t *proc,
Ip_u32 num,
struct Ipmip_attr *node,
struct Ipmip_attr *binding,
Ip_bool verbose)
{
if (num == 0)
{
const char *str;
/**/
ipcom_printf("Node %08x:"IP_LF, ipmipha_cli_node_get_handle(node));
ipcom_printf(" Home Address : %s"IP_LF, ipmip_ntop_inet(proc, ipmipha_cli_node_get_home_address(node)));
ipcom_printf(" Creation : %s"IP_LF, ipmip_ntop_tm(proc, ipmipha_cli_node_get_created(node)));
ipcom_printf(" Interface : %s"IP_LF, ipmipha_cli_node_get_ifname(node));
/**/
ipcom_printf(" Sent Bytes : %lld"IP_LF, ipmipha_cli_node_get_stats_snd_octets64(node));
ipcom_printf(" Sent Packets : %lld"IP_LF, ipmipha_cli_node_get_stats_snd_pkts64(node));
ipcom_printf(" Receive Bytes : %lld"IP_LF, ipmipha_cli_node_get_stats_rcv_octets64(node));
ipcom_printf(" Receive Packets : %lld"IP_LF, ipmipha_cli_node_get_stats_rcv_pkts64(node));
if ((str = ipmipha_cli_node_get_nai(node)) != IP_NULL)
ipcom_printf(" Mobile NAI : %s"IP_LF, str);
if ((str = ipmipha_cli_node_get_nai_aaah(node)) != IP_NULL)
ipcom_printf(" AAAH NAI : %s"IP_LF, str);
}
if (verbose)
{
Ip_u32 tmp;
Ip_u32 flags = ipmipha_cli_binding_get_registration_flags(binding);
ipcom_printf(" Care-of Address %s:"IP_LF, ipmip_ntop_inet(proc, ipmipha_cli_binding_get_address(binding)));
ipcom_printf(" Creation : %s"IP_LF, ipmip_ntop_tm(proc, ipmipha_cli_binding_get_created(binding)));
ipcom_printf(" Last updated : %s"IP_LF, ipmip_ntop_tm(proc, ipmipha_cli_binding_get_last_updated(binding)));
ipcom_printf(" Lifetime requested: %u"IP_LF, ipmipha_cli_binding_get_time_granted(binding));
ipcom_printf(" Lifetime remaining: %u"IP_LF, ipmipha_cli_binding_get_time_remaining(binding));
ipcom_printf(" Mode : %s"IP_LF, IP_BIT_ISTRUE(flags, IPMIP4_CODE_REQ_DECAPSULATION)? "co-located" : "foreign agent");
/**/
ipcom_printf(" Sent Bytes# : %lld"IP_LF, ipmipha_cli_binding_get_stats_snd_octets64(binding));
ipcom_printf(" Sent Packets# : %lld"IP_LF, ipmipha_cli_binding_get_stats_snd_pkts64(binding));
ipcom_printf(" Receive Bytes# : %lld"IP_LF, ipmipha_cli_binding_get_stats_rcv_octets64(binding));
ipcom_printf(" Receive Packets# : %lld"IP_LF, ipmipha_cli_binding_get_stats_rcv_pkts64(binding));
ipcom_printf(" Broadcast : %s"IP_LF, IP_BIT_ISTRUE(flags, IPMIP4_CODE_REQ_BROADCAST)? "yes" : "no");
ipcom_printf(" Reverse tunnel : %s"IP_LF, IP_BIT_ISTRUE(flags, IPMIP4_CODE_REQ_REVERSE_TUNNELING)? "yes" : "no");
tmp = ipmipha_cli_binding_get_spi_mobile_foreign(binding);
if (tmp)
ipcom_printf(" SPI MH : %u"IP_LF, tmp);
tmp = ipmipha_cli_binding_get_spi_foreign_home(binding);
if (tmp)
ipcom_printf(" SPI FH : %u"IP_LF, tmp);
tmp = ipmipha_cli_binding_get_spi_mobile_AAA(binding);
if (tmp)
ipcom_printf(" SPI AAA : %u"IP_LF, tmp);
tmp = ipmipha_cli_binding_get_tunnel_type(binding);
ipcom_printf(" Tunnel type : %s"IP_LF, ipmip_util_tunnel_to_desc(tmp));
tmp = ipmipha_cli_binding_get_tunnel_flags(binding);
ipcom_printf(" Reg. Revocation : %s"IP_LF, IP_BIT_ARESET(tmp, IPMIP4_TUNNELMODE_REVOCATION_CONFIRMED)? (IP_BIT_ISSET(flags, IPMIP4_TUNNELMODE_REVOCATION_INFORM)? "yes (inform)" : "yes") : "no");
if (IP_BIT_ARESET(tmp, IPMIP4_TUNNELMODE_NAT_T_CONFIRMED))
{
ipcom_printf(" Nat traversal : yes"IP_LF);
ipcom_printf(" Nat endpoint : %s"IP_LF, ipmip_ntop_inet(proc, ipmipha_cli_binding_get_tunnel_endpoint(binding)));
ipcom_printf(" Nat port : %u"IP_LF, ipmipha_cli_binding_get_tunnel_port(binding));
}
else
{
ipcom_printf(" Nat traversal : no"IP_LF);
}
}
}
IP_STATIC void
ipmipha_cmd_handle_exec(Ipmip_proc_t *proc,
Ipmip_cli_daemon_t *daemon,
Ip_u32 handle,
Ip_u32 cmd,
Ip_bool verbose)
{
struct Ipmip_attr *node;
Ipmip_cli_daemon_req_t nreq;
ipmip_cli_daemon_request_init(&nreq);
if (cmd == IPMIPHA_CMD_OP_REVOKE)
ipmipha_cli_node_revoke(daemon, handle);
else if (cmd == IPMIPHA_CMD_OP_DELETE)
ipmipha_cli_node_delete(daemon, handle);
else if ((node = ipmipha_cli_node_get(daemon, &nreq, handle)) != IP_NULL)
{
Ipmip_attr_iter_t riter;
struct Ipmip_attr *binding;
Ip_u32 num = 0;
/**/
ipmip_attr_payload_iter_init(node, &riter);
while ((binding = ipmipha_cli_binding_next(&riter)) != IP_NULL)
{
switch (cmd)
{
case IPMIPHA_CMD_OP_LIST:
ipmipha_cmd_print_binding(proc, num, node, binding, verbose);
break;
case IPMIPHA_CMD_OP_SHOW:
ipmipha_cmd_show_binding(proc, num, node, binding, verbose);
break;
}
num++;
}
}
ipmip_cli_daemon_request_release(&nreq);
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipmipha_cmd_ha
*===========================================================================
* Description:
* Parameters: .
* Returns: .
*
*/
IP_PUBLIC int
ipmipha_cmd_ha(int argc, char **argv)
{
Ipcom_getopt opt;
int op_val;
char *op;
Ipmip_proc_t *proc = IP_NULL;
Ipmip_cli_daemon_t daemon;
Ipmip_cli_daemon_req_t req;
int i;
int used = 1;
int vr = ipcom_proc_vr_get();
int vr_new = vr;
daemon.fd = IP_INVALID_SOCKET;
ipmip_cli_daemon_request_init(&req);
proc = ipmip_proc_alloc();
if (proc == IP_NULL)
{
ipcom_printf("ha: failed to create process context"IP_LF);
return -1;
}
if (argc < 2)
goto usage;
if (argc >= 4 && ipcom_strcmp(argv[1], "-V") == 0)
{
used += 2;
vr_new = ipcom_atoi(argv[2]);
}
ipcom_proc_vr_set(vr_new);
/* Get a connection to the home agent. */
for (i = 0; i < 10; i++)
{
if (ipmipha_cli_connect(&daemon))
break;
ipcom_sleep(1);
}
if (daemon.fd == IP_INVALID_SOCKET)
{
ipcom_printf("ha: failed to connect to home agent"IP_LF);
ipmip_proc_destroy(proc);
ipcom_proc_vr_set(vr);
return -1;
}
op = argv[used];
op_val = ipcom_cmd_str_to_key(ipmipha_cmd_ops, op);
if (op_val == -1)
{
if (ipmip4_cli_shell_cmd(argc - used + 1, argv + used - 1, proc, &daemon) == -1)
{
ipcom_printf("'%s' is an invalid operation"IP_LF, op);
goto usage;
}
goto exit_out;
}
ipcom_getopt_clear_r(&opt);
if (op_val == IPMIPHA_CMD_OP_LIST ||
op_val == IPMIPHA_CMD_OP_SHOW ||
op_val == IPMIPHA_CMD_OP_REVOKE ||
op_val == IPMIPHA_CMD_OP_DELETE)
{
/* Show node information */
Ip_bool all = IP_FALSE;
Ip_bool verbose = IP_FALSE;
const char *ifname = IP_NULL;
const char *nai = IP_NULL;
Ip_u32 hoa = 0;
int args = 0;
int ret = IPCOM_SUCCESS;
static struct Ip_option long_options[] =
{
{"hoa", 1, 0, 0},
{"nai", 1, 0, 0},
{"all", 0, 0, 0},
{"ifname", 1, 0, 0},
{"verbose", 0, 0, 0},
{0, 0, 0, 0}
};
opt.long_only = 1;
opt.long_options = long_options;
while ((i = ipcom_getopt_r(argc - used, argv + used, "av", &opt)) != -1)
{
switch (i)
{
case 0:
switch(opt.long_index)
{
case 0:
/* hoa -- Home Address */
args++;
if (ipcom_inet_pton(IP_AF_INET, opt.optarg, &hoa) != 1)
{
ipcom_printf("bad '--hoa' IPv4 address."IP_LF);
goto usage;
}
break;
case 1:
/* nai */
args++;
nai = opt.optarg;
break;
case 2:
args++;
all = IP_TRUE;
break;
case 3:
args++;
ifname = opt.optarg;
break;
case 4:
verbose = IP_TRUE;
break;
default:
ipcom_printf("unknown option %s", long_options[opt.long_index].name);
if (opt.optarg)
ipcom_printf(" with arg %s", opt.optarg);
ipcom_printf(IP_LF);
goto usage;
}
break;
case 'a':
args++;
all = IP_TRUE;
break;
case 'v':
verbose = IP_TRUE;
break;
default:
ipcom_printf("fa: invalid option '%c'"IP_LF, i);
goto usage;
}
}
if (op_val == IPMIPHA_CMD_OP_LIST)
ipmipha_cmd_print_binding_fmt("Home Address",
"Care of Address",
"Interface",
"Lifetime",
"Flags");
if (args > 0)
{
if (all)
ret = ipmipha_cli_node_list(&daemon, &req, IP_NULL, IP_NULL, 0);
else if (args)
ret = ipmipha_cli_node_list(&daemon, &req, nai, ifname, hoa);
if (ret == IPCOM_SUCCESS)
{
Ipmip_attr_iter_t riter;
Ip_u32 handle;
/**/
ipmip_cli_daemon_iter_request_init(&req, &riter);
while ((handle = ipmipha_cli_handle_next(&riter)) != 0)
ipmipha_cmd_handle_exec(proc, &daemon, handle, op_val, verbose);
}
}
else
{
for (i = opt.optind + used; i < argc; i++)
ipmipha_cmd_handle_exec(proc, &daemon, ipcom_strtoul(argv[i], IP_NULL, 0), op_val, verbose);
}
}
else if (op_val == IPMIPHA_CMD_OP_START)
ipmipha_cli_daemon_start(&daemon);
else if (op_val == IPMIPHA_CMD_OP_STOP)
ipmipha_cli_daemon_stop(&daemon);
else if (op_val == IPMIPHA_CMD_OP_MUTE)
ipmipha_cli_daemon_mute(&daemon);
ipmip_cli_daemon_disconnect(&daemon);
ipmip_cli_daemon_request_release(&req);
ipmip_proc_destroy(proc);
ipcom_proc_vr_set(vr);
return 0;
usage:
ipmip_util_identprintf(proc, 0, "NAME"IP_LF);
ipmip_util_identprintf(proc, 1, "ha - Displays Home Agent IPv4 bindings, statistics and status" IP_LF);
ipmip_util_identprintf(proc, 0, "SYNOPSIS"IP_LF);
ipmip_util_identprintf(proc, 1, "ha <command> [arguments]"IP_LF);
ipmip_util_identprintf(proc, 0, "DESCRIPTION"IP_LF);
ipmip_util_identprintf(proc, 1,
"The ha command version %u.%u.%u is used to display current Home Agent MIPv4"IP_LF
"bindings, statistics and status."IP_LF,
(IPMIPHA_RELEASE / 10000) % 100, (IPMIPHA_RELEASE / 100) % 100, IPMIPHA_RELEASE % 100);
ipmip_util_identprintf(proc, 0, "COMMANDS"IP_LF);
ipmip_util_cmdprintf(proc, 1, "list [-a] [--nai=<nai>] [--ifname=<interface>] [--hoa=<home address>] [<handle>]", "Short list the specified binding(s)");
ipmip_util_cmdprintf(proc, 1, "show [-a] [--verbose] [--nai=<nai>] [--ifname=<interface>] [--hoa=<home address>] [<handle>]", "Show the specified binding(s)");
ipmip_util_cmdprintf(proc, 1, "revoke [-a] [--nai=<nai>] [--ifname=<interface>] [--hoa=<home address>] [<handle>]", "Revoke the specified binding(s)");
ipmip_util_cmdprintf(proc, 1, "delete [-a] [--nai=<nai>] [--ifname=<interface>] [--hoa=<home address>] [<handle>]", "Delete the specified binding(s)");
ipmip_util_identprintf(proc, 2, "-a All bindings"IP_LF);
ipmip_util_identprintf(proc, 2, "--nai=<nai> The network access name"IP_LF);
ipmip_util_identprintf(proc, 2, "--verbose Verbose output"IP_LF);
ipmip_util_identprintf(proc, 2, "--hoa=<home address> The home address"IP_LF);
ipmip_util_identprintf(proc, 2, "--ifname=<interface> The interface the binding is registered on"IP_LF);
ipmip_util_identprintf(proc, 2, "handle=<handle number> The unique handle of this binding"IP_LF);
ipmip4_cli_shell_usage(proc);
exit_out:
ipmip_cli_daemon_disconnect(&daemon);
ipmip_cli_daemon_request_release(&req);
ipmip_proc_destroy(proc);
ipcom_proc_vr_set(vr);
return -1;
}
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/