/* ****************************************************************************** * INTERPEAK SOURCE FILE * * Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmipfa_attr.c,v $ $Revision: 1.18.16.1 $ * $Source: /home/interpeak/CVSRoot/ipmipfa/src/ipmipfa_attr.c,v $ * $Author: jsheng $ * $State: Exp $ $Locker: $ * * INTERPEAK_COPYRIGHT_STRING * Design and implementation by Joel Hortelius ****************************************************************************** */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #include "ipmipfa_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 "ipmipfa.h" #include "ipmipfa_h.h" #include "ipmipfa_node.h" #include "ipmipfa_cli.h" #include "ipmipfa_llh.h" #include "ipmipfa_attr_h.h" #include "ipmipfa_pktbuf.h" /* **************************************************************************** * 4 DEFINES **************************************************************************** */ #define IPMIPFA_ATTR_BUFSIZ 512 /* **************************************************************************** * 5 TYPES **************************************************************************** */ typedef struct Ipmipfa_attr_trigger { Ipmip_cli_message_t *request; Ipmipfa_iff_t *ifp; Ipmip_lladdr_t *lla; Ip_u32 mnip; Ip_u32 faip; int trigger; } Ipmipfa_attr_trigger_t; typedef struct Ipmipfa_attr_node_search { Ip_u32 hoa; Ip_u32 ha; char *nai; Ip_size_t nai_len; Ipmip_lladdr_t *lla; Ipmip_buffer_t *response; } Ipmipfa_attr_node_search_t; /* **************************************************************************** * 6 EXTERN PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 7 LOCAL PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 8 DATA **************************************************************************** */ const char *ipmipfa_attr_bc_x_regtype[] = { "Normal", "Pending", "Low Latency Pre TT", "Low Latency Pre ST", "Low Latency Pre MT", "Low Latency Post TT", "Low Latency Post ST" }; const char *ipmipfa_attr_bc_x_regshort[] = { "+ ", "- ", "TT", "ST", "MT", "tt", "st" }; /* **************************************************************************** * 9 STATIC FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipmipfa_node_del_cb *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC void ipmipfa_attr_list_search(Ipmipfa_data_t *data, Ipmip_proc_t *proc, Ipmipfa_node_t *node, Ipmipfa_attr_node_search_t *response, void *unused) { IPMIP_UNUSED_PARAMETER(unused); IPMIP_UNUSED_PARAMETER(data); IPMIP_UNUSED_PARAMETER(proc); if (response->hoa != 0 && node->mib.faVisitorHomeAddress.s_addr != response->hoa) return; if (response->ha != 0 && node->mib.faVisitorHomeAgentAddress.s_addr != response->ha) return; if (response->nai && (node->nai == IP_NULL || !ipmip_util_strnncmp(response->nai, response->nai_len, (char *)IPMIP4_MSGEXT_SHDR_EXT_DATA(node->nai), IPMIP4_MSGEXT_SHDR_EXT_SIZE(node->nai)))) return; if (response->lla && !ipmip_lladdr_cmp(node->reginfo.faVisitorMAC, response->lla)) return; /**/ ipmip_attr_put_u32(response->response, IPMIPFA_CLI_ATTR_BC_X_HANDLE, node->faVisitorIdentity); } /* **************************************************************************** * 10 GLOBAL FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipmipfa_attr_node_dump *=========================================================================== * Description: Dump a node * Parameters: event - Current event * data - Data * proc - Current process * lock - Command locking structure * node - Node. * Returns: IP_FALSE * */ IP_STATIC int ipmipfa_attr_node_execute(int event, Ipmipfa_data_t *data, Ipmip_proc_t *proc, Ipmip_cli_message_t *request, Ipmipfa_node_t *node) { int tret = IPMIP_TIMER_RET_DONE; if (event == IPMIP_TIMER_EVENT_RUN) { struct Ipmip_attr_header *hdr = (struct Ipmip_attr_header *)IPMIP_BUFFER_DATA(&request->request); Ip_size_t rhdr = 0; Ip_size_t rta; if (node == IP_NULL) rhdr = ipmip_attr_hdr_err(&request->message, hdr, IP_ERRNO_ENOENT, IP_NULL); else { switch (IPMIP_ATTR_HDR_TYPE(hdr)) { case IPMIPFA_CLI_BC_X_REVOKE: rhdr = ipmip_attr_hdr_ack(&request->message, hdr); ipmipfa_node_revoke(data, proc, node); break; case IPMIPFA_CLI_BC_X_DELETE: rhdr = ipmip_attr_hdr_ack(&request->message, hdr); tret = ipmipfa_node_terminate(data, proc, node, node->ifp->ext.revocation_inform != IPMIP_SYSVAR_MODE_DISABLED); break; case IPMIPFA_CLI_BC_X_GET: { /**/ rhdr = ipmip_attr_hdr_ack(&request->message, hdr); /* Dump the information */ /* Either an embryo creation or an accepted registration */ rta = ipmip_attr_begin(&request->message, IPMIPFA_CLI_ATTR_BC_X); ipmip_attr_put_time_t(&request->message, IPMIPFA_CLI_ATTR_BC_X_CREATION_TIME, node->faVisitorCreationTime); ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_HANDLE, node->faVisitorIdentity); ipmip_attr_put_str(&request->message, IPMIPFA_CLI_ATTR_BC_X_IFNAME, node->ifp->iff.ipmip.ifname); if (node->nai) ipmip_attr_put_str(&request->message, IPMIPFA_CLI_ATTR_BC_X_NAI, (char *)IPMIP4_MSGEXT_SHDR_EXT_DATA(node->nai)); ipmip_attr_put(&request->message, IPMIPFA_CLI_ATTR_BC_X_LLADDR, node->reginfo.faVisitorMAC->len, node->reginfo.faVisitorMAC); if (node->mib.faVisitorRegIsAccepted || node->pending.faVisitorPendingRequest == IP_NULL) { ipmip_attr_put_inet(&request->message, IPMIPFA_CLI_ATTR_BC_X_HOA, node->mib.faVisitorHomeAddress.s_addr); ipmip_attr_put_inet(&request->message, IPMIPFA_CLI_ATTR_BC_X_HA, node->mib.faVisitorHomeAgentAddress.s_addr); ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_TIME_GRANTED, node->mib.faVisitorTimeGranted); ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_TIME_REMAINING, node->mib.faVisitorTimeRemaining); ipmip_attr_put_time_t(&request->message, IPMIPFA_CLI_ATTR_BC_X_LAST_UPDATED, node->faVisitorLastUpdated); ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_REG_TYPE, node->faVisitorRegType); ipmip_attr_put_inet(&request->message, IPMIPFA_CLI_ATTR_BC_X_TUNNEL_ENDPOINT, node->faVisitorTunnelingEndpoint); ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_TUNNEL_TYPE, node->faVisitorTunnelType); ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_TUNNEL_FLAGS, node->faVisitorTunnelFlags); if (node->faVisitorSPIMobileForeign) ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_SPI_MF, node->faVisitorSPIMobileForeign); if (node->faVisitorSPIForeignHome) ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_SPI_FH, node->faVisitorSPIForeignHome); if (node->faVisitorSPIMobileAAA) ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_SPI_AAA, node->faVisitorSPIMobileAAA); ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_REGIDHIGH, node->mib.faVisitorRegIDHigh); ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_REGIDLOW, node->mib.faVisitorRegIDLow); ipmip_attr_put_inet(&request->message, IPMIPFA_CLI_ATTR_BC_X_VISITOR_IP, node->mib.faVisitorIPAddress.s_addr); ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_REG_FLAGS, node->mib.faVisitorRegFlags); ipmip_attr_put_u64(&request->message, IPMIPFA_CLI_ATTR_BC_X_STATS_RCV_OCTETS64, node->faVisitorRcvOctets); ipmip_attr_put_u64(&request->message, IPMIPFA_CLI_ATTR_BC_X_STATS_RCV_PKTS64, node->faVisitorRcvPkts); ipmip_attr_put_u64(&request->message, IPMIPFA_CLI_ATTR_BC_X_STATS_SND_OCTETS64, node->faVisitorSndOctets); ipmip_attr_put_u64(&request->message, IPMIPFA_CLI_ATTR_BC_X_STATS_SND_PKTS64, node->faVisitorSndPkts); } else { Ip_time_t now = ipmip_util_time(); /* Need to build the entry in question */ ipmip_attr_put_inet(&request->message, IPMIPFA_CLI_ATTR_BC_X_HOA, node->pending.faVisitorPendingRequest->pktinfo.faVisitorHomeAddress); ipmip_attr_put_inet(&request->message, IPMIPFA_CLI_ATTR_BC_X_HA, node->pending.faVisitorPendingRequest->pktinfo.faVisitorHomeAgentAddress); ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_TIME_GRANTED, node->pending.faVisitorPendingRequest->pktinfo.faVisitorTimeGranted); ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_TIME_REMAINING, node->pending.faVisitorPendingRequest->pktinfo.faVisitorTimeGranted - (now - node->pending.faVisitorLastUpdated)); ipmip_attr_put_time_t(&request->message, IPMIPFA_CLI_ATTR_BC_X_LAST_UPDATED, node->pending.faVisitorLastUpdated); ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_REG_TYPE, IPMIPFA_CLI_ATTR_BC_X_REGTYPE_PENDING); ipmip_attr_put_inet(&request->message, IPMIPFA_CLI_ATTR_BC_X_TUNNEL_ENDPOINT, node->pending.faVisitorPendingRequest->pktinfo.faVisitorHomeAgentAddress); ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_TUNNEL_TYPE, node->pending.faVisitorPendingRequest->reginfo.faVisitorTunnelType); ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_TUNNEL_FLAGS, node->pending.faVisitorPendingRequest->reginfo.faVisitorTunnelFlags); if (node->pending.faVisitorPendingRequest->reginfo.faVisitorSPIMobileForeign) ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_SPI_MF, node->pending.faVisitorPendingRequest->reginfo.faVisitorSPIMobileForeign->spi); if (node->pending.faVisitorPendingRequest->reginfo.faVisitorSPIForeignHome) ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_SPI_FH, node->pending.faVisitorPendingRequest->reginfo.faVisitorSPIForeignHome->spi); if (node->pending.faVisitorPendingRequest->reginfo.faVisitorSPIMobileAAA) ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_SPI_AAA, node->pending.faVisitorPendingRequest->reginfo.faVisitorSPIMobileAAA); ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_REGIDHIGH, node->pending.faVisitorPendingRequest->reginfo.faVisitorRegIDHigh); ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_REGIDLOW, node->pending.faVisitorPendingRequest->pktinfo.faVisitorRegIDLow); ipmip_attr_put_inet(&request->message, IPMIPFA_CLI_ATTR_BC_X_VISITOR_IP, node->pending.faVisitorPendingRequest->ipmip4.ipmip.srcinfo.src->sin.sin_addr.s_addr); ipmip_attr_put_u32(&request->message, IPMIPFA_CLI_ATTR_BC_X_REG_FLAGS, node->pending.faVisitorPendingRequest->reginfo.faVisitorRegFlags); } /* RTA end */ ipmip_attr_end(&request->message, rta); } break; } } /* If we have a reply header; terminate it */ ipmip_attr_hdr_finalize(&request->message, rhdr); /* Commit the reply */ ipmip_cli_message_commit(&data->ipmip4.ipmip, proc, request); } else { /* Free the request */ ipmip_cli_message_free(&data->ipmip4.ipmip, proc, request); } /**/ return tret; } IP_STATIC int ipmipfa_attr_node_trigger_execute(int event, Ipmipfa_data_t *data, Ipmip_proc_t *proc, Ipmipfa_attr_trigger_t *trigger, Ipmipfa_node_t *node) { int ret = IPMIP_TIMER_RET_DONE; if (event == IPMIP_TIMER_EVENT_RUN) { Ipmipfa_llh_agent_t *agent; Ip_size_t rhdr = 0; struct Ipmip_attr_header *hdr = (struct Ipmip_attr_header *)IPMIP_BUFFER_DATA(&trigger->request->request); /* Check the trigger type */ switch(trigger->trigger) { case IPMIPFA_CLI_BC_X_L2_TRIGGER_ST: /* Found the mobile node? */ if (node == IP_NULL) { IPMIP4_EVENT_IF(INFO, proc, ipmip_log_event_add(&data->ipmip4.ipmip, proc, "HoA=%s FA=%s Received Source Trigger (L2-ST) message mapped to no existing node", ipmip_ntop_inet(proc, trigger->mnip), ipmip_ntop_inet(proc, trigger->faip))); ret = -IP_ERRNO_ENOENT; break; } /* Must find the nFA */ if ((agent = ipmipfa_llh_ip_to_agent(data, proc, trigger->ifp, trigger->faip)) == IP_NULL) { IPMIP4_EVENT_IF(INFO, proc, ipmip_log_event_add(&data->ipmip4.ipmip, proc, "HoA=%s FA=%s Received Source Trigger (L2-ST) message mapped to no known FA", ipmip_ntop_inet(proc, trigger->mnip), ipmip_ntop_inet(proc, trigger->faip))); ret = -IP_ERRNO_EINVAL; break; } rhdr = ipmip_attr_hdr_ack(&trigger->request->message, hdr); /* Do the source trigger */ ipmipfa_llh_L2_ST(data, proc, node, agent, trigger->lla, trigger->ifp, 0, IPMIPFA_CLI_ATTR_BC_X_REGTYPE_PRE_L2_ST); break; case IPMIPFA_CLI_BC_X_L2_TRIGGER_TT: /* Need to transmit a PrRtAdv tunneled through the specified * oFA */ /* Must find the oFA */ if ((agent = ipmipfa_llh_ip_to_agent(data, proc, trigger->ifp, trigger->faip)) == IP_NULL) { IPMIP4_EVENT_IF(INFO, proc, ipmip_log_event_add(&data->ipmip4.ipmip, proc, "HoA=%s FA=%s Received Target Trigger (L2-TT) message mapped to no known FA", ipmip_ntop_inet(proc, trigger->mnip), ipmip_ntop_inet(proc, trigger->faip))); ret = -IP_ERRNO_EINVAL; break; } rhdr = ipmip_attr_hdr_ack(&trigger->request->message, hdr); ipmipfa_llh_L2_TT(data, proc, trigger->mnip, 0, trigger->lla, trigger->ifp, node, agent, IP_FALSE); break; case IPMIPFA_CLI_BC_X_L2_TRIGGER_LU: /* L2_LU indication for this node */ rhdr = ipmip_attr_hdr_ack(&trigger->request->message, hdr); ipmipfa_llh_L2_LU(data, proc, node, trigger->mnip, trigger->ifp, trigger->lla); break; case IPMIPFA_CLI_BC_X_L2_TRIGGER_LD: /* L2_LD indication for this node */ if (node != IP_NULL) { rhdr = ipmip_attr_hdr_ack(&trigger->request->message, hdr); ret = ipmipfa_llh_L2_LD(data, proc, node, trigger->lla); } else { ret = -IP_ERRNO_ENOENT; break; } break; } /* If we have a reply header; terminate it */ if (ret < 0) rhdr = ipmip_attr_hdr_err(&trigger->request->message, hdr, -ret , IP_NULL); ipmip_attr_hdr_finalize(&trigger->request->message, rhdr); /* Commit the reply */ ipmip_cli_message_commit(&data->ipmip4.ipmip, proc, trigger->request); } else { /* Free the request */ ipmip_cli_message_free(&data->ipmip4.ipmip, proc, trigger->request); } if (trigger->lla) ipcom_free(trigger->lla); ipcom_free(trigger); return ret < 0? IPMIP_TIMER_RET_DONE : ret; } IP_GLOBAL int ipmipfa_attr_command(struct Ipmipfa_data *data, struct Ipmip_proc *proc, struct Ipmip_cli_message *request) { struct Ipmip_attr_header *hdr = (struct Ipmip_attr_header *)IPMIP_BUFFER_DATA(&request->request); Ip_size_t rhdr; unsigned int si, f; switch (IPMIP_ATTR_HDR_TYPE(hdr)) { case IPMIPFA_CLI_BC_X_LIST: if (data->conf == IP_NULL) return -IP_ERRNO_EPERM; { struct Ipmip_attr *idattr[IPMIPFA_CLI_ATTR_BC_X_MAX + 1]; Ipmipfa_attr_node_search_t search; /* parse it */ ipmip_attr_hdr_parse(IPMIPFA_CLI_ATTR_BC_X_MAX, hdr, idattr); ipcom_memset(&search, 0, sizeof(search)); search.ha = ipmip_attr_get_inet(idattr[IPMIPFA_CLI_ATTR_BC_X_HA]); search.hoa = ipmip_attr_get_inet(idattr[IPMIPFA_CLI_ATTR_BC_X_HOA]); search.lla = ipmip_attr_get_data(idattr[IPMIPFA_CLI_ATTR_BC_X_LLADDR]); search.nai = ipmip_attr_get_data(idattr[IPMIPFA_CLI_ATTR_BC_X_NAI]); if (search.nai) search.nai_len = IPMIP_ATTR_PAYLOAD(idattr[IPMIPFA_CLI_ATTR_BC_X_NAI]); search.response = &request->message; rhdr = ipmip_attr_hdr_ack(&request->message, hdr); /* Add all nodes */ ipmip_context_id_lock(data->idents); ipmip_context_id_foreach(&data->ipmip4.ipmip, proc, data->idents, (Ipmip_util_hash_foreach_t)ipmipfa_attr_list_search, &search, IP_NULL); ipmip_context_id_unlock(data->idents); } break; case IPMIPFA_CLI_BC_X_L2_TRIGGER_ST: case IPMIPFA_CLI_BC_X_L2_TRIGGER_TT: case IPMIPFA_CLI_BC_X_L2_TRIGGER_LD: case IPMIPFA_CLI_BC_X_L2_TRIGGER_LU: if (data->conf == IP_NULL) return -IP_ERRNO_EPERM; { struct Ipmip_attr *idattr[IPMIPFA_CLI_ATTR_BC_X_MAX + 1]; Ipmipfa_attr_trigger_t *trigger; char *str; /* parse it */ ipmip_attr_hdr_parse(IPMIPFA_CLI_ATTR_BC_X_MAX, hdr, idattr); if (idattr[IPMIPFA_CLI_ATTR_BC_X_IFNAME] == IP_NULL) return -IP_ERRNO_EINVAL; trigger = ipcom_calloc(1, sizeof(*trigger)); if(IP_NULL == trigger) return -IP_ERRNO_ENOENT; trigger->ifp = (Ipmipfa_iff_t *)ipmip_if_findbyname(&data->conf->if_head, IPMIP_ATTR_DATA(idattr[IPMIPFA_CLI_ATTR_BC_X_IFNAME])); if (trigger->ifp == IP_NULL) { ipcom_free(trigger); return -IP_ERRNO_ENOENT; } trigger->faip = ipmip_attr_get_inet(idattr[IPMIPFA_CLI_ATTR_BC_X_VISITOR_IP]); trigger->mnip = ipmip_attr_get_inet(idattr[IPMIPFA_CLI_ATTR_BC_X_HOA]); str = ipmip_attr_get_str(idattr[IPMIPFA_CLI_ATTR_BC_X_LLA_NAME]); if (str != IP_NULL) trigger->lla = ipmip_lladdr_parse(proc, trigger->ifp->iff.ipmip.lladdr->type, trigger->ifp->iff.ipmip.lladdr->subtype, str); trigger->trigger = IPMIP_ATTR_HDR_TYPE(hdr); switch (trigger->trigger) { case IPMIPFA_CLI_BC_X_L2_TRIGGER_ST: case IPMIPFA_CLI_BC_X_L2_TRIGGER_TT: if (trigger->faip == 0) { if (trigger->lla) ipcom_free(trigger->lla); ipcom_free(trigger); return -IP_ERRNO_EINVAL; } break; case IPMIPFA_CLI_BC_X_L2_TRIGGER_LD: case IPMIPFA_CLI_BC_X_L2_TRIGGER_LU: if (trigger->lla == IP_NULL) { ipcom_free(trigger); return -IP_ERRNO_EINVAL; } break; } trigger->request = request; /* Do the LLH pre registration TT trigger */ ipmipfa_node_findbykey(data, proc, trigger->ifp, trigger->mnip, 0, IP_NULL, trigger->lla, &request->timer, (Ipmip_timer_func_t)ipmipfa_attr_node_trigger_execute, trigger); return 0; } case IPMIPFA_CLI_BC_X_REVOKE: case IPMIPFA_CLI_BC_X_DELETE: case IPMIPFA_CLI_BC_X_GET: if (data->conf == IP_NULL) return -IP_ERRNO_EPERM; { Ip_u32 handle = ipmip_attr_hdr_find_u32(hdr, IPMIPFA_CLI_ATTR_BC_X_HANDLE); /**/ if (handle == IP_NULL) return -IP_ERRNO_EINVAL; /* Get by identity */ ipmipfa_node_lookup_handle(data, proc, handle, &request->timer, (Ipmip_timer_func_t)ipmipfa_attr_node_execute, request); return 0; } case IPMIPFA_CLI_DAEMON_START: if (data->conf == IP_NULL) return -IP_ERRNO_EPERM; rhdr = ipmip_attr_hdr_ack(&request->message, hdr); if (data->shutdown) { data->shutdown = 0; if (data->conf) { Ipmipfa_iff_t *iff; /* Send instant RtAdv on all active interfaces */ for (iff = IPCOM_LIST_FIRST(&data->conf->if_head); iff; iff = IPCOM_LIST_NEXT(&iff->iff.ipmip.next)) { /* Should I send a multicast PrRtAdv? */ if (iff->adv_interval > 0) ipmipfa_agent_advert_output(data, proc, iff, IP_NULL, IP_NULL, IP_NULL, IP_FALSE); } } } break; case IPMIPFA_CLI_DAEMON_STOP: if (data->conf == IP_NULL) return -IP_ERRNO_EPERM; rhdr = ipmip_attr_hdr_ack(&request->message, hdr); data->shutdown = IPMIPFA_SHUTDOWN_ALL; break; case IPMIPFA_CLI_DAEMON_MUTE: if (data->conf == IP_NULL) return -IP_ERRNO_EPERM; rhdr = ipmip_attr_hdr_ack(&request->message, hdr); data->shutdown |= IPMIPFA_SHUTDOWN_MUTE; break; case IPMIPFA_CLI_DAEMON_REGISTRATION_COUNTERS: rhdr = ipmip_attr_hdr_ack(&request->message, hdr); ipmip_attr_put(&request->message, IPMIPFA_CLI_ATTR_DAEMON_REGCOUNTER, sizeof(data->mibRegCounters), &data->mibRegCounters); break; case IPMIP_CLI_NAME_LIST: rhdr = ipmip_attr_hdr_ack(&request->message, hdr); if (data->conf != IP_NULL) { /* Dump each configuration item we've currently got in human readable form */ Ipmipfa_iff_t *ife; ipmip_attr_put_str(&request->message, IPMIP_CLI_ITEM_NAME, "global"); /* Add interfaces */ for (ife = IPCOM_LIST_FIRST(&data->conf->if_head); ife; ife = IPCOM_LIST_NEXT(&ife->iff.ipmip.next)) ipmip_attr_put_str(&request->message, IPMIP_CLI_ITEM_NAME, ife->iff.ipmip.ifname); } break; case IPMIP_CLI_CONFIG_GET: if (data->conf == IP_NULL) return -IP_ERRNO_EPERM; rhdr = ipmip_attr_hdr_ack(&request->message, hdr); /* Send instant RtAdv on all active interfaces */ { /* Dump each configuration item we've currently got in human readable form */ Ipmipfa_iff_t *ife; const char *name = ipmip_attr_hdr_find_str(hdr, IPMIP_CLI_ITEM_NAME); if (name == IP_NULL || ipcom_strcasecmp("global", name) == 0) { for (f = 0; f < IPMIPFA_FUNCTION_MAX; f++) { for (si = 0; si < data->extensions[f].num; si++) { if (data->extensions[f].functions[si]->config_global != IP_NULL && data->conf->extdata[f][si] != IP_NULL) (*data->extensions[f].functions[si]->config_global) (data, proc, IPMIP_CALLBACK_CONFIG_DUMP, data->conf->extdata[f][si], request); } } } /* Clear any old interfaces */ for (ife = IPCOM_LIST_FIRST(&data->conf->if_head); ife; ife = IPCOM_LIST_NEXT(&ife->iff.ipmip.next)) { if (name != IP_NULL && ipcom_strcasecmp(ife->iff.ipmip.ifname, name) != 0) continue; /**/ ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.lifetime=%d", ife->iff.ipmip.ifname, ife->lifetime); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.foreignagent=%s", ife->iff.ipmip.ifname, ipmip_ntop_inet(proc, ife->iff.ifaddr)); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.mn_auth=%s", ife->iff.ipmip.ifname, ife->mn_auth? "enabled" : "disabled"); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.adv_lifetime=%d", ife->iff.ipmip.ifname, ife->adv_lifetime); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.adv_interval=%d", ife->iff.ipmip.ifname, ife->adv_interval); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.lifetime=%d", ife->iff.ipmip.ifname, ife->lifetime); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.adv_address=%s", ife->iff.ipmip.ifname, ipmip_ntop_inet(proc, ife->adv_address)); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.ext.fa_error=%s", ife->iff.ipmip.ifname, ife->ext.fa_error? "enabled" : "disabled"); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.ext.dhaa=%s", ife->iff.ipmip.ifname, ife->ext.dhaa? "enabled" : "disabled"); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.ext.dhaa.address=%s", ife->iff.ipmip.ifname, ipmip_ntop_inet(proc, ife->ext.dhaa_address)); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.challenge=%s", ife->iff.ipmip.ifname, ife->ext.challenge? "enabled" : "disabled"); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.revocation.enabled=%s", ife->iff.ipmip.ifname, ife->ext.revocation? "enabled" : "disabled"); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.revocation.inform=%s", ife->iff.ipmip.ifname, ipmip_sysvar_mode_desc[ife->ext.revocation_inform]); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.tunnel.reverse=%s", ife->iff.ipmip.ifname, ipmip_sysvar_mode_desc[ife->tunnel.reverse]); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.tunnel.reordering=%s", ife->iff.ipmip.ifname, ife->reordering? "enabled" : "disabled"); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.tunnel.ipip=%s", ife->iff.ipmip.ifname, ife->tunnel.enabled[IPMIP_TUNNELTYPE_IPIP]? "enabled" : "disabled"); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.tunnel.gre=%s", ife->iff.ipmip.ifname, ife->tunnel.enabled[IPMIP_TUNNELTYPE_GRE]? "enabled" : "disabled"); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.tunnel.minenc=%s", ife->iff.ipmip.ifname, ife->tunnel.enabled[IPMIP_TUNNELTYPE_MINENC]? "enabled" : "disabled"); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.nat_t.enabled=%s", ife->iff.ipmip.ifname, ife->nat_t? "enabled" : "disabled"); ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.nat_t.keepalive=%d", ife->iff.ipmip.ifname, ife->nat_t_keepalive); if (ife->link_layer != IP_NULL) ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.link.layer=%s", ife->iff.ipmip.ifname, ipmip_ntop_lladdr(proc, ife->link_layer)); if (ife->nat_t_tunnel != IPMIP_TUNNELTYPE_NONE) { ipmip_cli_config_printf(&request->message, "ipmipfa.if.%s.nat_t.tunnel_type=%s", ife->iff.ipmip.ifname, ipmip_util_tunnel_to_name(ife->nat_t_tunnel)); } ipmipfa_llh_config_dump(data, proc, ife, request); /* Dump security specs */ ipcom_snprintf(proc->ntop.ntop_name, sizeof(proc->ntop.ntop_name), "ipmipfa.if.%s.spi", ife->iff.ipmip.ifname); ipmip4_auth_spi_dump(proc, ife->security.spi_ctx, proc->ntop.ntop_name, IP_TRUE, request); ipcom_snprintf(proc->ntop.ntop_name, sizeof(proc->ntop.ntop_name), "ipmipfa.if.%s.ha.sa.address", ife->iff.ipmip.ifname); ipmip4_auth_spi_table_dump(proc, ife->security.spi_ha, proc->ntop.ntop_name, request); ipcom_snprintf(proc->ntop.ntop_name, sizeof(proc->ntop.ntop_name), "ipmipfa.if.%s.fa.sa.address", ife->iff.ipmip.ifname); ipmip4_auth_spi_table_dump(proc, ife->security.spi_fa, proc->ntop.ntop_name, request); for (f = 0; f < IPMIPFA_FUNCTION_MAX; f++) { for (si = 0; si < data->extensions[f].num; si++) { if (data->extensions[f].functions[si]->config_ifp != IP_NULL && ife->extdata[f][si] != IP_NULL) (*data->extensions[f].functions[si]->config_ifp) (data, proc, IPMIP_CALLBACK_CONFIG_DUMP, ife, data->conf->extdata[f][si], ife->extdata[f][si], request); } } } } /* */ break; default: /**/ if (data->conf != IP_NULL) { Ipmipfa_iff_t *ife; /* Clear any old interfaces */ for (ife = IPCOM_LIST_FIRST(&data->conf->if_head); ife; ife = IPCOM_LIST_NEXT(&ife->iff.ipmip.next)) { for (f = 0; f < IPMIPFA_FUNCTION_MAX; f++) { for (si = 0; si < data->extensions[f].num; si++) { if (data->extensions[f].functions[si]->attr_ifp != IP_NULL) { if ((*data->extensions[f].functions[si]->attr_ifp) (data, proc, ife, data->conf->extdata[f][si], ife->extdata[f][si], request)) return 0; } } } } } /**/ return ipmip4_attr_command(&data->ipmip4, proc, request); } /* If we have a reply header; terminate it */ ipmip_attr_hdr_finalize(&request->message, rhdr); /* Commit the reply */ ipmip_cli_message_commit(&data->ipmip4.ipmip, proc, request); return 0; } /* *=========================================================================== * ipmipfa_attr_mib_faVisitorEntry *=========================================================================== * Description: Returns a NULL terminated array of visitor entries. The data * is dynamically allocated and must be freed by the caller. * Parameters: * Returns: Returns a NULL terminated array of visitor entries. * */ IP_GLOBAL struct Ipmipfa_mib_faVisitorEntry ** ipmipfa_attr_mib_faVisitorEntry(void) { struct Ipmipfa_mib_faVisitorEntry **header = IP_NULL; struct Ipmipfa_mib_faVisitorEntry *array; char *data; Ip_size_t off = 0; Ipmip_cli_daemon_t daemon; Ipmip_cli_daemon_req_t req; /**/ daemon.fd = IP_INVALID_SOCKET; ipmip_cli_daemon_request_init(&req); /**/ if (!ipmipfa_cli_connect(&daemon)) return IP_FALSE; /**/ if (ipmipfa_cli_node_list(&daemon, &req, IP_NULL, IP_NULL, 0, 0) == IPCOM_SUCCESS) { Ip_u32 handle; Ipmip_attr_iter_t riter; /**/ ipmip_cli_daemon_iter_request_init(&req, &riter); while ((handle = ipmipfa_cli_handle_next(&riter)) != 0) off++; /* Need termination */ data = ipcom_malloc(sizeof(struct Ipmipfa_mib_faVisitorEntry*) * (off + 1) + sizeof(struct Ipmipfa_mib_faVisitorEntry) * off); if (data == IP_NULL) goto done_out; /* Setup the header & array */ header = (struct Ipmipfa_mib_faVisitorEntry**) data; array = (struct Ipmipfa_mib_faVisitorEntry*)(data + sizeof(struct Ipmipfa_mib_faVisitorEntry*) * (off + 1)); off = 0; ipmip_cli_daemon_iter_request_init(&req, &riter); while ((handle = ipmipfa_cli_handle_next(&riter)) != 0) { Ipmip_cli_daemon_req_t nreq; struct Ipmip_attr *node; ipmip_cli_daemon_request_init(&nreq); node = ipmipfa_cli_node_get(&daemon, &nreq, handle); if (node != IP_NULL) { header[off] = &array[off]; header[off]->faVisitorHomeAddress.s_addr = ipmipfa_cli_node_get_home_address(node); header[off]->faVisitorHomeAgentAddress.s_addr = ipmipfa_cli_node_get_home_agent(node); header[off]->faVisitorTimeGranted = ipmipfa_cli_node_get_time_granted(node); header[off]->faVisitorTimeRemaining = ipmipfa_cli_node_get_time_remaining(node); header[off]->faVisitorRegIsAccepted = ipmipfa_cli_node_get_registration_type(node) != IPMIPFA_CLI_ATTR_BC_X_REGTYPE_PENDING; header[off]->faVisitorRegFlags = ipmipfa_cli_node_get_registration_flags(node); header[off]->faVisitorRegIDHigh = ipmipfa_cli_node_get_RegIdHigh(node); header[off]->faVisitorRegIDLow = ipmipfa_cli_node_get_RegIdLow(node); header[off]->faVisitorIPAddress.s_addr = ipmipfa_cli_node_get_visitor_ip(node); } ipmip_cli_daemon_request_release(&req); } } done_out: ipmip_cli_daemon_request_release(&req); /* Destroy the connection */ ipmip_cli_daemon_disconnect(&daemon); return header; } /* *=========================================================================== * ipmipfa_attr_mib_RegistrationCounters *=========================================================================== * Description: Returns a dynamically allocated structure containing the registration * counters for the foreign agent. The memory is dynamically allocated * and must be freed by the caller. * Parameters: * Returns: Returns the registration counter data. * */ IP_GLOBAL struct Ipmipfa_mib_RegistrationCounters * ipmipfa_attr_mib_RegistrationCounters(void) { Ipmip_cli_daemon_t daemon; Ipmip_cli_daemon_req_t req; struct Ipmipfa_mib_RegistrationCounters *regcnt = IP_NULL; struct Ipmipfa_mib_RegistrationCounters *regcntp; /**/ daemon.fd = IP_INVALID_SOCKET; ipmip_cli_daemon_request_init(&req); /**/ if (!ipmipfa_cli_connect(&daemon)) return IP_FALSE; if ((regcntp = ipmipfa_cli_daemon_registration_counters(&daemon, &req)) != IP_NULL) { regcnt = ipcom_malloc(sizeof(*regcnt)); if (regcnt) ipcom_memcpy(regcnt, regcntp, sizeof(*regcnt)); } ipmip_cli_daemon_request_release(&req); /* Destroy the connection */ ipmip_cli_daemon_disconnect(&daemon); return regcnt; } /* **************************************************************************** * 11 PUBLIC FUNCTIONS **************************************************************************** */ /* **************************************************************************** * END OF FILE **************************************************************************** */