/* ****************************************************************************** * INTERPEAK SOURCE FILE * * Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmip6pm_cli.c,v $ $Revision: 1.11 $ * $Source: /home/interpeak/CVSRoot/ipmip6pm/src/ipmip6pm_cli.c,v $ * $Author: jhorteli $ * $State: Exp $ $Locker: $ * * INTERPEAK_COPYRIGHT_STRING * Design and implementation by Joel Hortelius ****************************************************************************** */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #include "ipmip6pm_config.h" /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #define IPCOM_USE_CLIB_PROTO #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ipmip6pm.h" #include "ipmip6pm_attr.h" #include "ipmip6pm_cli.h" /* **************************************************************************** * 4 DEFINES **************************************************************************** */ /* **************************************************************************** * 5 TYPES **************************************************************************** */ /* **************************************************************************** * 6 EXTERN PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 7 LOCAL PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 8 DATA **************************************************************************** */ /* **************************************************************************** * 9 STATIC FUNCTIONS **************************************************************************** */ /* **************************************************************************** * 10 GLOBAL FUNCTIONS **************************************************************************** */ /* **************************************************************************** * 11 PUBLIC FUNCTIONS **************************************************************************** */ IP_PUBLIC Ip_bool ipmip6pm_cli_connect(Ipmip_cli_daemon_t *daemon_info) { ipmip_cli_daemon_init(daemon_info, "ipmip6pm", IPCOM_IPD_ID_IPMIP6PM); return ipmip_cli_daemon_connect(daemon_info); } IP_PUBLIC void ipmip6pm_cli_request_set_nai(Ipmip_cli_daemon_req_t *req, const char *nai) { if (nai) ipmip_attr_put_str(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_MOBILE_NAI, nai); } IP_PUBLIC void ipmip6pm_cli_request_set_handle(Ipmip_cli_daemon_req_t *req, Ip_u32 handle) { ipmip_attr_put_u32(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_HANDLE, handle); } IP_PUBLIC void ipmip6pm_cli_request_set_ifname(Ipmip_cli_daemon_req_t *req, const char *ifname) { if (ifname) ipmip_attr_put_str(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_IFNAME, ifname); } IP_PUBLIC void ipmip6pm_cli_request_set_service(Ipmip_cli_daemon_req_t *req, const char *module, const char *value) { Ip_size_t rta = ipmip_attr_begin(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_SERVICE); ipmip_attr_put_str(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_SRV_MODULE, module); ipmip_attr_put_str(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_SRV_VALUE, value); ipmip_attr_end(&req->reqbuf, rta); } IP_PUBLIC void ipmip6pm_cli_request_set_link(Ipmip_cli_daemon_req_t *req, const char *module, const char *value) { Ip_size_t rta = ipmip_attr_begin(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_LINK); ipmip_attr_put_str(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_SRV_MODULE, module); ipmip_attr_put_str(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_SRV_VALUE, value); ipmip_attr_end(&req->reqbuf, rta); } IP_PUBLIC void ipmip6pm_cli_request_set_MAG_configuration(Ipmip_cli_daemon_req_t *req, const char *ifname) { if (ifname) ipmip_attr_put_str(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_COA_IFNAME, ifname); } IP_PUBLIC void ipmip6pm_cli_request_add_prefix(Ipmip_cli_daemon_req_t *req, struct Ipmip6_address *prefix) { if (prefix) ipmip_attr_put(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_HOME_PREFIX_LIST, sizeof(*prefix), prefix); } #ifdef IPMIP_USE_INET IP_PUBLIC void ipmip6pm_cli_request_add_home_address_inet(Ipmip_cli_daemon_req_t *req, struct Ipmip6_inet *prefix) { if (prefix) ipmip_attr_put(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_HOME_ADDRESS_INET, sizeof(*prefix), prefix); } #endif IP_PUBLIC void ipmip6pm_cli_request_set_homeagent(Ipmip_cli_daemon_req_t *req, const struct Ip_in6_addr *homeagent) { if (homeagent) ipmip_attr_put_inet6(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_HOME_AGENT, homeagent); } #ifdef IPMIP_USE_INET IP_PUBLIC void ipmip6pm_cli_request_set_homeagent_inet(Ipmip_cli_daemon_req_t *req, Ip_u32 homeagent) { if (homeagent) ipmip_attr_put_inet(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_HOME_AGENT_INET, homeagent); } #endif IP_PUBLIC void ipmip6pm_cli_request_set_link_layer(Ipmip_cli_daemon_req_t *req, void *lla, Ip_size_t lla_size) { if (lla != IP_NULL && lla_size > 0) ipmip_attr_put(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_IFIDENT, lla_size, lla); } IP_PUBLIC void ipmip6pm_cli_request_set_gre_downlink(Ipmip_cli_daemon_req_t *req, Ip_u32 downlink) { ipmip_attr_put_u32(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_GRE, downlink); } IP_PUBLIC void ipmip6pm_cli_request_set_tunnel_type(Ipmip_cli_daemon_req_t *req, Ip_u8 tunnel_type) { /**/ if (tunnel_type < IPMIP_TUNNELTYPE_MAX) ipmip_attr_put_u32(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_TUNNEL_TYPE, tunnel_type); } IP_PUBLIC void ipmip6pm_cli_request_set_transport_mask(Ipmip_cli_daemon_req_t *req, Ip_u32 mask) { if (mask) ipmip_attr_put_u32(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_TRANSPORT_MASK, mask); } IP_PUBLIC void ipmip6pm_cli_request_set_handoff_indicator(Ipmip_cli_daemon_req_t *req, Ip_u32 handoff_indicator) { ipmip_attr_put_u32(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_HANDOFF_INDICATOR, handoff_indicator); } IP_PUBLIC void ipmip6pm_cli_request_set_access_type(Ipmip_cli_daemon_req_t *req, Ip_u32 access_type) { ipmip_attr_put_u32(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_ACCESS_TYPE, access_type); } IP_PUBLIC Ip_u32 ipmip6pm_cli_handle_next(Ipmip_attr_iter_t *iter) { /**/ return ipmip_attr_get_u32(ipmip_attr_iter_next(iter, IPMIP6PM_CLI_ATTR_BC_P_HANDLE)); } IP_PUBLIC Ip_u32 ipmip6pm_cli_handle_get(Ipmip_cli_daemon_req_t *req) { /**/ return ipmip_attr_get_u32(ipmip_cli_daemon_find_request(req, IPMIP6PM_CLI_ATTR_BC_P_HANDLE)); } IP_PUBLIC const char * ipmip6pm_cli_node_get_ifname(struct Ipmip_attr *node) { /**/ return ipmip_attr_payload_find_str(node, IPMIP6PM_CLI_ATTR_BC_P_IFNAME); } IP_PUBLIC const char * ipmip6pm_cli_node_get_tunnel_ifname(struct Ipmip_attr *node) { /**/ return ipmip_attr_payload_find_str(node, IPMIP6PM_CLI_ATTR_BC_P_TUNNEL_IFNAME); } IP_PUBLIC struct Ip_in6_addr * ipmip6pm_cli_node_get_home_agent(struct Ipmip_attr *node) { /**/ return ipmip_attr_payload_find_inet6(node, IPMIP6PM_CLI_ATTR_BC_P_HOME_AGENT); } #ifdef IPMIP_USE_INET IP_PUBLIC Ip_u32 ipmip6pm_cli_node_get_home_agent_inet(struct Ipmip_attr *node) { /**/ return ipmip_attr_payload_find_inet(node, IPMIP6PM_CLI_ATTR_BC_P_HOME_AGENT_INET); } #endif IP_PUBLIC Ip_u8 ipmip6pm_cli_node_get_tunnel_type(struct Ipmip_attr *node) { /**/ return ipmip_attr_payload_find_u32(node, IPMIP6PM_CLI_ATTR_BC_P_TUNNEL_TYPE); } IP_PUBLIC struct Ipmip_attr * ipmip6pm_cli_node_get_gre_keys(struct Ipmip_attr *node) { return ipmip_attr_payload_find(node, IPMIP6PM_CLI_ATTR_BC_P_GRE); } IP_PUBLIC Ip_u32 ipmip6pm_cli_node_get_transport_mask(struct Ipmip_attr *node) { return ipmip_attr_payload_find_u32(node, IPMIP6PM_CLI_ATTR_BC_P_TRANSPORT_MASK); } IP_PUBLIC const char * ipmip6pm_cli_node_get_nai(struct Ipmip_attr *node) { /**/ return ipmip_attr_payload_find_str(node, IPMIP6PM_CLI_ATTR_BC_P_MOBILE_NAI); } IP_PUBLIC struct Ipmip6_mib_mip6MnBLTable * ipmip6pm_cli_node_get_mip6MnBLTable(struct Ipmip_attr *node) { /**/ return (struct Ipmip6_mib_mip6MnBLTable *)ipmip_attr_payload_find_data(node, IPMIP6PM_CLI_ATTR_BC_P_MIB_mip6MnBLTable); } IP_PUBLIC struct Ipmip6_mib_mip6NodeTrafficEntry * ipmip6pm_cli_node_get_mip6NodeTrafficEntry(struct Ipmip_attr *node) { /**/ return (struct Ipmip6_mib_mip6NodeTrafficEntry *)ipmip_attr_payload_find_data(node, IPMIP6PM_CLI_ATTR_BC_P_MIB_mip6NodeTrafficEntry); } IP_PUBLIC struct Ipmip_lladdr * ipmip6pm_cli_node_get_iflla(struct Ipmip_attr *node) { return (struct Ipmip_lladdr *)ipmip_attr_payload_find_data(node, IPMIP6PM_CLI_ATTR_BC_P_IFLLA); } IP_PUBLIC struct Ipmip_lladdr * ipmip6pm_cli_node_get_MAG_iflla(struct Ipmip_attr *node) { return (struct Ipmip_lladdr *)ipmip_attr_payload_find_data(node, IPMIP6PM_CLI_ATTR_BC_P_MAG_Link_Layer); } IP_PUBLIC struct Ipmip6_address * ipmip6pm_cli_node_get_MAG_link_local(struct Ipmip_attr *node) { return (struct Ipmip6_address *)ipmip_attr_payload_find_data(node, IPMIP6PM_CLI_ATTR_BC_P_MAG_Link_Local); } IP_PUBLIC struct Ipmip6_address * ipmip6pm_cli_node_get_home_prefix_list(struct Ipmip_attr *node, Ip_u32 *sz) { struct Ipmip_attr *rta = ipmip_attr_payload_find(node, IPMIP6PM_CLI_ATTR_BC_P_HOME_PREFIX_LIST); if (rta) { *sz = IPMIP_ATTR_PAYLOAD(rta) / sizeof(Ipmip6_address_t); return *sz? (Ipmip6_address_t *)IPMIP_ATTR_DATA(rta) : IP_NULL; } return IP_NULL; } #ifdef IPMIP_USE_INET IP_PUBLIC struct Ipmip6_inet * ipmip6pm_cli_node_get_home_address_inet(struct Ipmip_attr *node) { return (struct Ipmip6_inet *)ipmip_attr_payload_find_data(node, IPMIP6PM_CLI_ATTR_BC_P_HOME_ADDRESS_INET); } #endif IP_PUBLIC Ip_time_t ipmip6pm_cli_node_get_created(struct Ipmip_attr *node) { /**/ return ipmip_attr_payload_find_time_t(node, IPMIP6PM_CLI_ATTR_BC_P_CREATED); } IP_PUBLIC Ip_u32 ipmip6pm_cli_node_get_access_type(struct Ipmip_attr *node) { return ipmip_attr_payload_find_u32(node, IPMIP6PM_CLI_ATTR_BC_P_ACCESS_TYPE); } IP_PUBLIC Ip_u32 ipmip6pm_cli_node_get_handoff_indicator(struct Ipmip_attr *node) { return ipmip_attr_payload_find_u32(node, IPMIP6PM_CLI_ATTR_BC_P_HANDOFF_INDICATOR); } IP_PUBLIC Ip_u32 ipmip6pm_cli_node_get_status(struct Ipmip_attr *node) { return ipmip_attr_payload_find_u32(node, IPMIP6PM_CLI_ATTR_BC_P_STATUS); } IP_PUBLIC Ip_u32 ipmip6pm_cli_node_get_handle(struct Ipmip_attr *node) { return ipmip_attr_payload_find_u32(node, IPMIP6PM_CLI_ATTR_BC_P_HANDLE); } IP_PUBLIC int ipmip6pm_cli_link_list(Ipmip_cli_daemon_t *daemon, Ipmip_cli_daemon_req_t *req) { ipmip_cli_daemon_request_start(req, IPMIP6PM_CLI_BC_P_LIST_LINK); return ipmip_cli_daemon_request(daemon, req); } IP_PUBLIC Ip_bool ipmip6pm_cli_link_next(Ipmip_attr_iter_t *iter, char **name, char **value) { /**/ struct Ipmip_attr *srv = ipmip_attr_iter_next(iter, IPMIP6PM_CLI_ATTR_BC_P_LINK); if (srv) { *name = ipmip_attr_payload_find_str(srv, IPMIP6PM_CLI_ATTR_BC_P_SRV_MODULE); *value = ipmip_attr_payload_find_str(srv, IPMIP6PM_CLI_ATTR_BC_P_SRV_VALUE); return IP_TRUE; } return IP_FALSE; } IP_PUBLIC int ipmip6pm_cli_service_list(Ipmip_cli_daemon_t *daemon, Ipmip_cli_daemon_req_t *req) { ipmip_cli_daemon_request_start(req, IPMIP6PM_CLI_BC_P_LIST_SERVICE); return ipmip_cli_daemon_request(daemon, req); } IP_PUBLIC Ip_bool ipmip6pm_cli_service_next(Ipmip_attr_iter_t *iter, char **name, char **value) { /**/ struct Ipmip_attr *srv = ipmip_attr_iter_next(iter, IPMIP6PM_CLI_ATTR_BC_P_SERVICE); if (srv) { *name = ipmip_attr_payload_find_str(srv, IPMIP6PM_CLI_ATTR_BC_P_SRV_MODULE); *value = ipmip_attr_payload_find_str(srv, IPMIP6PM_CLI_ATTR_BC_P_SRV_VALUE); return IP_TRUE; } return IP_FALSE; } IP_PUBLIC int ipmip6pm_cli_node_list(Ipmip_cli_daemon_t *daemon, Ipmip_cli_daemon_req_t *req, const char *nai, const char *ifname) { ipmip_cli_daemon_request_start(req, IPMIP6PM_CLI_BC_P_LIST); ipmip6pm_cli_request_set_ifname(req, ifname); ipmip6pm_cli_request_set_nai(req, nai); return ipmip_cli_daemon_request(daemon, req); } IP_PUBLIC struct Ipmip_attr * ipmip6pm_cli_node_get(Ipmip_cli_daemon_t *daemon, Ipmip_cli_daemon_req_t *req, Ip_u32 handle) { ipmip_cli_daemon_request_start(req, IPMIP6PM_CLI_BC_P_GET); ipmip6pm_cli_request_set_handle(req, handle); if (ipmip_cli_daemon_request(daemon, req) == IPCOM_SUCCESS) return ipmip_cli_daemon_find_request(req, IPMIP6PM_CLI_ATTR_BC_P); return IP_NULL; } IP_PUBLIC void ipmip6pm_cli_node_delete(Ipmip_cli_daemon_t *daemon, Ip_u32 handle) { Ipmip_cli_daemon_req_t req; ipmip_cli_daemon_request_init(&req); ipmip_cli_daemon_request_start(&req, IPMIP6PM_CLI_BC_P_DELETE); ipmip6pm_cli_request_set_handle(&req, handle); ipmip_cli_daemon_request(daemon, &req); ipmip_cli_daemon_request_release(&req); } IP_PUBLIC void ipmip6pm_cli_node_deregister(Ipmip_cli_daemon_t *daemon, Ip_u32 handle, Ip_bool ack) { Ipmip_cli_daemon_req_t req; ipmip_cli_daemon_request_init(&req); ipmip_cli_daemon_request_start(&req, ack? IPMIP6PM_CLI_BC_P_DEREGISTER : IPMIP6PM_CLI_BC_P_DEREGISTER_DELETE); ipmip6pm_cli_request_set_handle(&req, handle); ipmip_cli_daemon_request(daemon, &req); ipmip_cli_daemon_request_release(&req); } IP_PUBLIC void ipmip6pm_cli_handoff_request_init(Ipmip_cli_daemon_req_t *req, const char *nai, const char *ifname) { ipmip_cli_daemon_request_start(req, IPMIP6PM_CLI_BC_P_CREATE); ipmip6pm_cli_request_set_nai(req, nai); ipmip6pm_cli_request_set_ifname(req, ifname); } IP_PUBLIC void ipmip6pm_cli_multicast_status(Ipmip_cli_daemon_t *daemon, Ip_bool enable) { if (enable) ipmip_cli_multicast_add(daemon, IPMIP6PM_CLI_BC_P_STATUS); else ipmip_cli_multicast_del(daemon, IPMIP6PM_CLI_BC_P_STATUS); } IP_PUBLIC Ip_u32 ipmip6pm_cli_node_retrieve_status(Ipmip_cli_daemon_t *daemon, Ip_u32 handle) { Ipmip_cli_daemon_req_t req; struct Ipmip_attr *node; Ip_u32 status = IPMIP6PM_CLI_ATTR_BC_P_STATUS_DELETED; ipmip_cli_daemon_request_init(&req); node = ipmip6pm_cli_node_get(daemon, &req, handle); if (node) status = ipmip6pm_cli_node_get_status(node); ipmip_cli_daemon_request_release(&req); return status; } IP_PUBLIC Ip_bool ipmip6pm_cli_node_wait_status(Ipmip_cli_daemon_t *daemon, Ip_u32 handle, Ip_u32 status, struct Ip_timeval *tv) { struct Ipmip_attr *node; Ip_u32 tmp; /* Do initial status check */ tmp = ipmip6pm_cli_node_retrieve_status(daemon, handle); if (tmp == status) return IP_TRUE; if (tmp == IPMIP6PM_CLI_ATTR_BC_P_STATUS_DELETED) return IP_FALSE; /* Wait for it to be reported */ while (ipmip_cli_daemon_recvmsg(daemon, tv) == 0) { struct Ipmip_attr_header *hdr = (struct Ipmip_attr_header *)IPMIP_BUFFER_DATA(&daemon->message); if (IPMIP_ATTR_HDR_SEQUENCE(hdr) == 0 && IPMIP_ATTR_HDR_SYSTEM(hdr) == 0 && IPMIP_ATTR_HDR_TYPE(hdr) == IPMIP6PM_CLI_BC_P_STATUS) { node = ipmip_attr_hdr_find(hdr, IPMIP6PM_CLI_ATTR_BC_P); if (node) { if (ipmip6pm_cli_node_get_handle(node) == handle) { tmp = ipmip6pm_cli_node_get_status(node); if (tmp == status) return IP_TRUE; /* Final state? */ if (tmp == IPMIP6PM_CLI_ATTR_BC_P_STATUS_DELETED) return IP_FALSE; } } } } return IP_FALSE; } IP_PUBLIC int ipmip6pm_cli_lma_list(Ipmip_cli_daemon_t *daemon, Ipmip_cli_daemon_req_t *req) { ipmip_cli_daemon_request_start(req, IPMIP6PM_CLI_BC_P_GET_LMA); return ipmip_cli_daemon_request(daemon, req); } IP_PUBLIC struct Ipmip_attr* ipmip6pm_cli_lma_next(Ipmip_attr_iter_t *iter) { /**/ return ipmip_attr_iter_next(iter, IPMIP6PM_CLI_ATTR_LMA); } IP_PUBLIC struct Ip_in6_addr * ipmip6pm_cli_lma_get_addr_v6(struct Ipmip_attr *lma) { /**/ return ipmip_attr_payload_find_inet6(lma, IPMIP6PM_CLI_ATTR_BC_P_HOME_AGENT); } #ifdef IPMIP_USE_INET IP_PUBLIC Ip_u32 ipmip6pm_cli_lma_get_addr_v4(struct Ipmip_attr *lma) { /**/ return ipmip_attr_payload_find_inet(lma, IPMIP6PM_CLI_ATTR_BC_P_HOME_AGENT_INET); } #endif IP_PUBLIC const char * ipmip6pm_cli_lma_get_ifname(struct Ipmip_attr *lma) { /**/ return ipmip_attr_payload_find_str(lma, IPMIP6PM_CLI_ATTR_BC_P_IFNAME); } IP_PUBLIC void ipmip6pm_cli_request_set_revoke_reason(Ipmip_cli_daemon_req_t *req, Ip_u8 reason) { ipmip_attr_put_u32(&req->reqbuf, IPMIP6PM_CLI_ATTR_BC_P_REVOKE_REASON, reason); } IP_PUBLIC void ipmip6pm_cli_lma_revoke(Ipmip_cli_daemon_t *daemon, const char *ifname, const struct Ip_in6_addr *lma, Ip_u8 reason) { Ipmip_cli_daemon_req_t req; ipmip_cli_daemon_request_init(&req); ipmip_cli_daemon_request_start(&req, IPMIP6PM_CLI_BC_P_REVOKE_LMA); ipmip6pm_cli_request_set_homeagent(&req, lma); ipmip6pm_cli_request_set_revoke_reason(&req, reason); ipmip6pm_cli_request_set_ifname(&req, ifname); ipmip_cli_daemon_request(daemon, &req); ipmip_cli_daemon_request_release(&req); } IP_PUBLIC void ipmip6pm_cli_node_revoke(Ipmip_cli_daemon_t *daemon, Ip_u32 handle, Ip_u32 reason) { Ipmip_cli_daemon_req_t req; ipmip_cli_daemon_request_init(&req); ipmip_cli_daemon_request_start(&req, IPMIP6PM_CLI_BC_P_REVOKE); ipmip6pm_cli_request_set_handle(&req, handle); ipmip6pm_cli_request_set_revoke_reason(&req, reason); ipmip_cli_daemon_request(daemon, &req); ipmip_cli_daemon_request_release(&req); } #ifdef IPMIP_USE_INET IP_PUBLIC void ipmip6pm_cli_node_revoke_inet(Ipmip_cli_daemon_t *daemon, Ip_u32 handle, Ip_u32 reason) { Ipmip_cli_daemon_req_t req; ipmip_cli_daemon_request_init(&req); ipmip_cli_daemon_request_start(&req, IPMIP6PM_CLI_BC_P_REVOKE_INET); ipmip6pm_cli_request_set_handle(&req, handle); ipmip6pm_cli_request_set_revoke_reason(&req, reason); ipmip_cli_daemon_request(daemon, &req); ipmip_cli_daemon_request_release(&req); } #endif /* **************************************************************************** * END OF FILE **************************************************************************** */