/* ******************************************************************************* * INTERPEAK SOURCE FILE * * Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmipfa_cmd_fa.c,v $ $Revision: 1.30 $ * $Source: /home/interpeak/CVSRoot/ipmipfa/src/ipmipfa_cmd_fa.c,v $ * $Author: jhorteli $ * $State: Exp $ $Locker: $ * * INTERPEAK_COPYRIGHT_STRING * Design and implementation by Niklas Lundberg ****************************************************************************** */ /* ******************************************************************************* * 1 DESCRIPTION ******************************************************************************* * */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #define IPCOM_USE_CLIB_PROTO #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ipmipfa.h" #include "ipmipfa_attr.h" #include "ipmipfa_cli.h" /* **************************************************************************** * 4 DEFINES **************************************************************************** */ enum { IPMIPFA_CMD_LLH = 1, IPMIPFA_CMD_OP_LIST, IPMIPFA_CMD_OP_SHOW, IPMIPFA_CMD_OP_STATS, IPMIPFA_CMD_OP_REVOKE, IPMIPFA_CMD_OP_STOP, IPMIPFA_CMD_OP_START, IPMIPFA_CMD_OP_DELETE, IPMIPFA_CMD_OP_MUTE, }; /* **************************************************************************** * 5 TYPES **************************************************************************** */ /* **************************************************************************** * 6 EXTERN PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 7 LOCAL PROTOTYPES **************************************************************************** */ IP_PUBLIC int ipmipfa_cmd_fa(int argc, char **argv); /* **************************************************************************** * 8 DATA **************************************************************************** */ IP_STATIC Ipcom_cmd_int_str_map ipmipfa_cmd_ops[] = { { IPMIPFA_CMD_LLH, "st" }, { IPMIPFA_CMD_LLH, "tt" }, { IPMIPFA_CMD_LLH, "lu" }, { IPMIPFA_CMD_LLH, "ld" }, { IPMIPFA_CMD_OP_LIST, "list" }, { IPMIPFA_CMD_OP_SHOW, "show" }, { IPMIPFA_CMD_OP_REVOKE, "revoke" }, { IPMIPFA_CMD_OP_DELETE, "delete" }, { IPMIPFA_CMD_OP_STOP, "stop" }, { IPMIPFA_CMD_OP_START, "start" }, { IPMIPFA_CMD_OP_MUTE, "mute" }, { IPMIPFA_CMD_OP_STATS , "stats" }, { IPMIPFA_CMD_OP_STATS , "statistics" }, { 0, 0 } }; IP_STATIC Ipcom_cmd_int_str_map ipmipfa_cmd_l2_ops[] = { { IPMIPFA_CLI_BC_X_L2_TRIGGER_ST, "st" }, { IPMIPFA_CLI_BC_X_L2_TRIGGER_TT, "tt" }, { IPMIPFA_CLI_BC_X_L2_TRIGGER_LU, "lu" }, { IPMIPFA_CLI_BC_X_L2_TRIGGER_LD, "ld" }, { 0, 0 } }; /* **************************************************************************** * 9 STATIC FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipmipfa_cmd_registered_flags *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC char * ipmipfa_cmd_regflags(char *buffer, struct Ipmip_attr *node) { char *tt = ""; Ip_u32 tmp = ipmipfa_cli_node_get_tunnel_type(node); if (tmp == IPMIP_TUNNELTYPE_GRE) tt = "G"; else if (tmp == IPMIP_TUNNELTYPE_MINENC) tt = "M"; tmp = ipmipfa_cli_node_get_tunnel_flags(node); ipcom_sprintf(buffer, "%-2s %s%s%s", ipmipfa_attr_bc_x_regshort[ipmipfa_cli_node_get_registration_type(node)], IP_BIT_ISTRUE(tmp, IPMIP4_TUNNELMODE_REVERSE)? "T" : "", IP_BIT_ARESET(tmp, IPMIP4_TUNNELMODE_NAT_T_CONFIRMED)? "*" : "", tt); return buffer; } IP_STATIC void ipmipfa_cmd_print_binding_fmt(Ip_u32 identity, const char *hoa, const char *hagent, const char *ifname, const char *lifetime, const char *flags) { /* */ if (identity) ipcom_printf("0x%08x %-10s %-15s %-15s %-16s %-15s"IP_LF, identity, flags, hoa, hagent, ifname, lifetime); else ipcom_printf("Identity %-10s %-15s %-15s %-16s %-15s"IP_LF, flags, hoa, hagent, ifname, lifetime); } IP_STATIC void ipmipfa_cmd_print_binding(Ipmip_proc_t *proc, struct Ipmip_attr *node) { ipcom_snprintf(proc->ntop.ntop_name, sizeof(proc->ntop.ntop_name), "%d/%d", ipmipfa_cli_node_get_time_remaining(node), ipmipfa_cli_node_get_time_granted(node)); /* OK; Time to print */ ipmipfa_cmd_print_binding_fmt(ipmipfa_cli_node_get_handle(node), ipmip_ntop_inet(proc, ipmipfa_cli_node_get_home_address(node)), ipmip_ntop_inet(proc, ipmipfa_cli_node_get_home_agent(node)), ipmipfa_cli_node_get_ifname(node), proc->ntop.ntop_name, ipmipfa_cmd_regflags(proc->ntop.ntop_pbuf, node)); } /* *=========================================================================== * ipmipfa_cmd_show_binding *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC void ipmipfa_cmd_show_binding(Ipmip_proc_t *proc, struct Ipmip_attr *node) { Ip_u32 tmp; const char *ptr; Ipmip_lladdr_t *lladdr; /**/ ipcom_printf("0x%08x %s:%s:"IP_LF, ipmipfa_cli_node_get_handle(node), ipmip_ntop_inet(proc, ipmipfa_cli_node_get_home_address(node)), ipmip_ntop_inet(proc, ipmipfa_cli_node_get_home_agent(node))); ipcom_printf(" Creation : %s"IP_LF, ipmip_ntop_tm(proc, ipmipfa_cli_node_get_created(node))); /* Is it a valid NAI */ if ((ptr = ipmipfa_cli_node_get_nai(node)) != IP_NULL) ipcom_printf(" Mobile NAI : %s"IP_LF, ptr); if ((lladdr = ipmipfa_cli_node_get_lladdr(node)) != IP_NULL) ipcom_printf(" Link : %s"IP_LF, ipmip_ntop_lladdr(proc, lladdr)); ipcom_printf(" Registration Type : %s"IP_LF, ipmipfa_attr_bc_x_regtype[ipmipfa_cli_node_get_registration_type(node)]); ipcom_printf(" Forwarding Address : %s"IP_LF, ipmip_ntop_inet(proc, ipmipfa_cli_node_get_tunnel_endpoint(node))); ipcom_printf(" Registration:"IP_LF); ipcom_printf(" Last updated : %s"IP_LF, ipmip_ntop_tm(proc, ipmipfa_cli_node_get_last_updated(node))); ipcom_printf(" Lifetime requested: %u"IP_LF, ipmipfa_cli_node_get_time_granted(node)); ipcom_printf(" Lifetime remaining: %u"IP_LF, ipmipfa_cli_node_get_time_remaining(node)); tmp = ipmipfa_cli_node_get_tunnel_flags(node); ipcom_printf(" Reverse tunnel : %s"IP_LF, IP_BIT_ISSET(tmp, IPMIP4_TUNNELMODE_REVERSE)? "yes" : "no"); if (IP_BIT_ARESET(tmp, IPMIP4_TUNNELMODE_REVOCATION_CONFIRMED)) ipcom_printf(" Revocation : yes%s"IP_LF, IP_BIT_ISSET(tmp, IPMIP4_TUNNELMODE_REVOCATION_INFORM)? " (inform)" : ""); else ipcom_printf(" Revocation : no"IP_LF); ipcom_printf(" Nat traversal : %s"IP_LF, IP_BIT_ARESET(tmp, IPMIP4_TUNNELMODE_NAT_T_CONFIRMED)? "yes" : "no"); ipcom_printf(" Interface : %s"IP_LF, ipmipfa_cli_node_get_ifname(node)); tmp = ipmipfa_cli_node_get_spi_mobile_foreign(node); if (tmp) ipcom_printf(" SPI MF : %u"IP_LF, tmp); tmp = ipmipfa_cli_node_get_spi_foreign_home(node); if (tmp) ipcom_printf(" SPI FH : %u"IP_LF, tmp); tmp = ipmipfa_cli_node_get_spi_mobile_AAA(node); if (tmp) ipcom_printf(" SPI AAA : %u"IP_LF, tmp); ipcom_printf(" Tunnel type : %s"IP_LF, ipmip_util_tunnel_to_desc(ipmipfa_cli_node_get_tunnel_type(node))); /**/ ipcom_printf(" Sent Bytes : %lld"IP_LF, ipmipfa_cli_node_get_stats_snd_octets64(node)); ipcom_printf(" Sent Packets : %lld"IP_LF, ipmipfa_cli_node_get_stats_snd_pkts64(node)); ipcom_printf(" Receive Bytes : %lld"IP_LF, ipmipfa_cli_node_get_stats_rcv_octets64(node)); ipcom_printf(" Receive Packets : %lld"IP_LF, ipmipfa_cli_node_get_stats_rcv_pkts64(node)); } IP_STATIC void ipmipfa_cmd_handle_exec(Ipmip_proc_t *proc, Ipmip_cli_daemon_t *daemon, Ip_u32 handle, Ip_u32 cmd) { struct Ipmip_attr *node; Ipmip_cli_daemon_req_t nreq; ipmip_cli_daemon_request_init(&nreq); if ((node = ipmipfa_cli_node_get(daemon, &nreq, handle)) != IP_NULL) { switch (cmd) { case IPMIPFA_CMD_OP_LIST: ipmipfa_cmd_print_binding(proc, node); break; case IPMIPFA_CMD_OP_SHOW: ipmipfa_cmd_show_binding(proc, node); break; case IPMIPFA_CMD_OP_REVOKE: ipmipfa_cli_node_revoke(daemon, handle); break; case IPMIPFA_CMD_OP_DELETE: ipmipfa_cli_node_delete(daemon, handle); break; } } ipmip_cli_daemon_request_release(&nreq); } /* **************************************************************************** * 10 GLOBAL FUNCTIONS **************************************************************************** */ /* **************************************************************************** * 11 PUBLIC FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipmipfa_cmd_fa *=========================================================================== * Description: * Parameters: . * Returns: . * */ IP_PUBLIC int ipmipfa_cmd_fa(int argc, char **argv) { Ipcom_getopt opt; int c; int op_val; char *op; Ipmip_proc_t *proc = IP_NULL; int used = 1; int vr = ipcom_proc_vr_get(); int vr_new = vr; Ipmip_cli_daemon_t daemon; Ipmip_cli_daemon_req_t req; int i; /**/ daemon.fd = IP_INVALID_SOCKET; ipmip_cli_daemon_request_init(&req); ipcom_getopt_clear_r(&opt); proc = ipmip_proc_alloc(); if (proc == IP_NULL) { ipcom_printf("fa: 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 (ipmipfa_cli_connect(&daemon)) break; ipcom_sleep(1); } if (daemon.fd == IP_INVALID_SOCKET) { ipcom_printf("fa: failed to connect to foreign agent"IP_LF); ipmip_proc_destroy(proc); ipcom_proc_vr_set(vr); return -1; } op = argv[used]; op_val = ipcom_cmd_str_to_key(ipmipfa_cmd_ops, op); if (op_val == -1) { /**/ if (ipmip4_cli_shell_pmipv4_cmd(argc - used + 1, argv + used - 1, proc, &daemon) == -1 && 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 == IPMIPFA_CMD_OP_STATS) { struct Ipmipfa_mib_faVisitorEntry **fahdr = ipmipfa_attr_mib_faVisitorEntry(); struct Ipmipfa_mib_RegistrationCounters *regcnt = ipmipfa_attr_mib_RegistrationCounters(); i = 0; if (fahdr) { for (i = 0; fahdr[i] != IP_NULL; i++) ; ipcom_free(fahdr); } ipcom_printf("Number of nodes : %d"IP_LF, i); if (regcnt) { ipcom_printf("Received Registration Requests: %d"IP_LF, regcnt->faRegRequestsReceived); ipcom_printf("Received Registration Requests: %d"IP_LF, regcnt->faRegRequestsReceived); ipcom_printf("Relayed Registration Requests : %d"IP_LF, regcnt->faRegRequestsRelayed); ipcom_printf("Received Registration Replies : %d"IP_LF, regcnt->faRegRepliesRecieved); ipcom_printf("Relayed Registration Replies : %d"IP_LF, regcnt->faRegRepliesRelayed); ipcom_printf("Errors:"IP_LF); ipcom_printf(" Reason Unspecified : %d"IP_LF, regcnt->faReasonUnspecified); ipcom_printf(" Administratively Prohibited : %d"IP_LF, regcnt->faAdmProhibited); ipcom_printf(" Insufficient Resources : %d"IP_LF, regcnt->faInsufficientResource); ipcom_printf(" MN Authentication Failure : %d"IP_LF, regcnt->faMNAuthenticationFailure); ipcom_printf(" Lifetime Too Long : %d"IP_LF, regcnt->faRegLifetimeTooLong); ipcom_printf(" Poorly Formed Request : %d"IP_LF, regcnt->faPoorlyFormedRequests); ipcom_printf(" Encapsulation Unavailable : %d"IP_LF, regcnt->faPoorlyFormedReplies); ipcom_printf(" Home Agent Unreachable : %d"IP_LF, regcnt->faHAUnreachable); ipcom_printf(" HA Authentication Failure : %d"IP_LF, regcnt->faHAAuthenticationFailure); ipcom_printf(" Poorly Formed Replies : %d"IP_LF, regcnt->faPoorlyFormedReplies); ipcom_free(regcnt); } } else if (op_val == IPMIPFA_CMD_OP_SHOW || op_val == IPMIPFA_CMD_OP_REVOKE || op_val == IPMIPFA_CMD_OP_DELETE || op_val == IPMIPFA_CMD_OP_LIST) { static struct Ip_option long_options[] = { {"hoa", 1, 0, 0}, {"ha", 1, 0, 0}, {"nai", 1, 0, 0}, {"all", 0, 0, 0}, {"ifname", 1, 0, 0}, {0, 0, 0, 0} }; Ip_bool all = IP_FALSE; const char *nai = IP_NULL; const char *ifname = IP_NULL; Ip_u32 hoa = 0; Ip_u32 ha = 0; int ret = IPCOM_SUCCESS; int args = 0; /* --nai=joel@interpeak.se * --ha=10.2.3.1 * --hoa=101.1.1.20 */ /* Show node information */ opt.long_only = 1; opt.long_options = long_options; while ((i = ipcom_getopt_r(argc - used, argv + used, "a", &opt)) != -1) { args++; switch (i) { case 0: switch(opt.long_index) { case 0: /* hoa -- Home Address */ if (ipcom_inet_pton(IP_AF_INET, opt.optarg, &hoa) != 1) { ipcom_printf("bad '--hoa' IPv4 address."IP_LF); goto usage; } break; case 1: /* ha */ if (ipcom_inet_pton(IP_AF_INET, opt.optarg, &ha) != 1) { ipcom_printf("bad '--ha' IPv4 address."IP_LF); goto usage; } break; case 2: /* nai */ nai = opt.optarg; break; case 3: all = IP_TRUE; break; case 4: ifname = opt.optarg; 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': all = IP_TRUE; break; default: ipcom_printf("fa: invalid option '%c'"IP_LF, i); goto usage; } } /**/ if (op_val == IPMIPFA_CMD_OP_LIST) ipmipfa_cmd_print_binding_fmt(0, "Home Address", "Home Agent", "Interface", "Lifetime", "Status"); if (args > 0) { if (all) ret = ipmipfa_cli_node_list(&daemon, &req, IP_NULL, IP_NULL, 0, 0); else ret = ipmipfa_cli_node_list(&daemon, &req, nai, ifname, hoa, ha); if (ret == IPCOM_SUCCESS) { Ipmip_attr_iter_t riter; Ip_u32 handle; /**/ ipmip_cli_daemon_iter_request_init(&req, &riter); while ((handle = ipmipfa_cli_handle_next(&riter)) != 0) ipmipfa_cmd_handle_exec(proc, &daemon, handle, op_val); } } else { for (i = opt.optind + used; i < argc; i++) ipmipfa_cmd_handle_exec(proc, &daemon, ipcom_strtoul(argv[i], IP_NULL, 0), op_val); } } else if (op_val == IPMIPFA_CMD_OP_START) ipmipfa_cli_daemon_start(&daemon); else if (op_val == IPMIPFA_CMD_OP_STOP) ipmipfa_cli_daemon_stop(&daemon); else if (op_val == IPMIPFA_CMD_OP_MUTE) ipmipfa_cli_daemon_mute(&daemon); else if (op_val == IPMIPFA_CMD_LLH) { const char *ll = IP_NULL; const char *ifname = IP_NULL; Ip_u32 mnip = 0; Ip_u32 faip = 0; int trigger = ipcom_cmd_str_to_key(ipmipfa_cmd_l2_ops, op); static struct Ip_option long_options[] = { {"fa", 1, 0, 0}, {"hoa", 1, 0, 0}, {"ifname", 1, 0, 0}, {"lla", 1, 0, 0}, {0, 0, 0, 0} }; opt.long_only = 1; opt.long_options = long_options; while((c = ipcom_getopt_r(argc - used, argv + used, "", &opt)) != -1) { switch (c) { case 0: switch(opt.long_index) { case 0: /* fa */ if (ipcom_inet_pton(IP_AF_INET, opt.optarg, &faip) != 1) { ipcom_printf("bad '-faip' IPv4 address."IP_LF); goto usage; } break; case 1: /* hoa */ if (ipcom_inet_pton(IP_AF_INET, opt.optarg, &mnip) != 1) { ipcom_printf("bad '--hoa' IPv4 address."IP_LF); goto usage; } break; case 2: /* ifname */ ifname = opt.optarg; break; case 3: /* lla */ ll = opt.optarg; 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; default: goto usage; } } /* Send Trigger */ ipmipfa_cli_daemon_l2_trigger(&daemon, trigger, mnip, ifname, faip, ll); } goto exit_out; /****** Usage ******/ usage: ipmip_util_identprintf(proc, 0, "NAME"IP_LF); ipmip_util_identprintf(proc, 1, "fa - Displays Foreign Agent IPv4 bindings, statistics and status" IP_LF); ipmip_util_identprintf(proc, 0, "SYNOPSIS"IP_LF); ipmip_util_identprintf(proc, 1, "fa [arguments]"IP_LF); ipmip_util_identprintf(proc, 0, "DESCRIPTION"IP_LF); ipmip_util_identprintf(proc, 1, "The fa command version %u.%u.%u is used to display current Foreign Agent MIPv4"IP_LF "bindings, statistics and status."IP_LF, (IPMIPFA_RELEASE / 10000) % 100, (IPMIPFA_RELEASE / 100) % 100, IPMIPFA_RELEASE % 100); ipmip_util_identprintf(proc, 0, "COMMANDS"IP_LF); ipmip_util_cmdprintf(proc, 1, "list [-a] [--nai=] [--ifname=] [--hoa=] [--ha=] []", "Short list the specified binding(s)"); ipmip_util_identprintf(proc, 2, "Legend:"IP_LF); ipmip_util_identprintf(proc, 3, "+ - Normal Registration"IP_LF); ipmip_util_identprintf(proc, 3, "- - Pending Registration"IP_LF); ipmip_util_identprintf(proc, 3, "TT - Pre LLH Target Trigger"IP_LF); ipmip_util_identprintf(proc, 3, "ST - Pre LLH Source Trigger"IP_LF); ipmip_util_identprintf(proc, 3, "MT - Pre LLH Mobile Trigger"IP_LF); ipmip_util_identprintf(proc, 3, "tt - Post LLH Target Trigger"IP_LF); ipmip_util_identprintf(proc, 3, "st - Post LLH Source Trigger"IP_LF); ipmip_util_identprintf(proc, 3, "G - GRE Tunneling"IP_LF); ipmip_util_identprintf(proc, 3, "M - Minimal Encapsulation Tunneling"IP_LF); ipmip_util_identprintf(proc, 3, "T - Reverse Encapsulation"IP_LF); ipmip_util_identprintf(proc, 3, "* - NAT UDP Encapsulation"IP_LF); ipmip_util_cmdprintf(proc, 1, "show [-a] [--nai=] [--ifname=] [--hoa=] [--ha=] []", "Show the specified binding(s)"); ipmip_util_cmdprintf(proc, 1, "revoke [-a] [--nai=] [--ifname=] [--hoa=] [--ha=] []", "Revoke the specified binding(s)"); ipmip_util_cmdprintf(proc, 1, "delete [-a] [--nai=] [--ifname=] [--hoa=] [--ha=] []", "Delete the specified binding(s)"); ipmip_util_identprintf(proc, 2, "-a All bindings"IP_LF); ipmip_util_identprintf(proc, 2, "--nai= The network access name"IP_LF); ipmip_util_identprintf(proc, 2, "--hoa= The home address"IP_LF); ipmip_util_identprintf(proc, 2, "--ha= The home agent"IP_LF); ipmip_util_identprintf(proc, 2, "--ifname= The interface the binding is registered on"IP_LF); ipmip_util_identprintf(proc, 2, "handle= The unique handle of this binding"IP_LF); ipmip_util_cmdprintf(proc, 1, "lu --hoa= --ifname= [--fa=] [--lla=]", "Link Up indicator to the specific node"); ipmip_util_cmdprintf(proc, 1, "ld --hoa= --ifname= [--fa=] [--lla=]", "Link Down indicator to the specific node"); ipmip_util_cmdprintf(proc, 1, "tt --hoa= --ifname= [--fa=] [--lla=]", "Target Trigger indicator to the specific node"); ipmip_util_cmdprintf(proc, 1, "st --hoa= --ifname= [--fa=] [--lla=]", "Source Trigger indicator to the specific node"); ipmip_util_identprintf(proc, 2, "--hoa= The home address"IP_LF); ipmip_util_identprintf(proc, 2, "--fa= The foreign agent"IP_LF); ipmip_util_identprintf(proc, 2, "--ifname= The interface the binding is registered on"IP_LF); ipmip_util_identprintf(proc, 2, "--lla= The mobile nodes link layer address"IP_LF); ipmip_util_cmdprintf(proc, 1, "stats", "View global statistics"); ipmip4_cli_shell_pmipv4_usage(proc); ipmip4_cli_shell_usage(proc); exit_out: ipmip_cli_daemon_disconnect(&daemon); ipmip_cli_daemon_request_release(&req); if (proc) ipmip_proc_destroy(proc); ipcom_proc_vr_set(vr); return 0; } /* **************************************************************************** * END OF FILE **************************************************************************** */