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

1102 lines
45 KiB
C

/*
******************************************************************************
* 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 <joel.hortelis@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include "ipmipfa_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_clib.h>
#include <ipcom_err.h>
#include <ipcom_inet.h>
#include <ipcom_ipd.h>
#include <ipcom_list.h>
#include <ipcom_hash.h>
#include <ipcom_os.h>
#include <ipcom_sock.h>
#include <ipcom_sock.h>
#include <ipcom_sock2.h>
#include <ipcom_sysctl.h>
#include <ipcom_syslog.h>
#include <ipcom_route.h>
#include <ipmip.h>
#include <private/ipmip_buffer.h>
#include <private/ipmip_sysvar.h>
#include <private/ipmip_cli.h>
#include <ipmip4.h>
#include <private/ipmip4_context.h>
#include <private/ipmip4_attr.h>
#include <private/ipmip4_auth.h>
#include <private/ipmip4_util.h>
#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
****************************************************************************
*/