497 lines
21 KiB
C
497 lines
21 KiB
C
|
|
/*
|
|
******************************************************************************
|
|
* INTERPEAK SOURCE FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmippm_pmipv4.c,v $ $Revision: 1.6 $
|
|
* $Source: /home/interpeak/CVSRoot/ipmippm/config/ipmippm_pmipv4.c,v $
|
|
* $Author: jhorteli $
|
|
* $State: Exp $ $Locker: $
|
|
*
|
|
* INTERPEAK_COPYRIGHT_STRING
|
|
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
|
|
******************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
|
|
#include "ipmippm_config.h"
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
#define IPCOM_USE_CLIB_PROTO
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_os.h>
|
|
#include <ipcom_sock.h>
|
|
#include <ipcom_sock6.h>
|
|
#include <ipcom_inet.h>
|
|
#include <ipcom_list.h>
|
|
#include <ipcom_hash.h>
|
|
#include <ipcom_err.h>
|
|
#include <ipcom_sysvar.h>
|
|
#include <ipcom_syslog.h>
|
|
#include <ipcom_shell.h>
|
|
#include <ipcom_route.h>
|
|
|
|
#include <ipnet.h>
|
|
#include <ipnet_radvd.h>
|
|
|
|
#include <ipmip.h>
|
|
#include <private/ipmip_util.h>
|
|
#include <private/ipmip_sysvar.h>
|
|
#include <private/ipmip_inet.h>
|
|
|
|
#include <ipmip4.h>
|
|
#include <private/ipmip4_context.h>
|
|
#include <private/ipmip4_util.h>
|
|
#include <private/ipmip4_sysext.h>
|
|
#include <private/ipmip4_pkt.h>
|
|
|
|
#include "ipmippm.h"
|
|
#include "ipmippm_h.h"
|
|
#include "ipmippm_attr_h.h"
|
|
#include "ipmippm_pktbuf.h"
|
|
#include "ipmippm_if.h"
|
|
#include "ipmippm_client.h"
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
#define IPMIPPM_PMIPV4_SERVICE "PMIPv4-UDP"
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
typedef struct Ipmippm_pmipv4_config_instance
|
|
{
|
|
Ipmip4_pkt_udp_register_t udpr;
|
|
Ip_u16 port;
|
|
struct Ip_sockaddr_in sin4;
|
|
struct Ipmippm_client_conf *conf;
|
|
} Ipmippm_pmipv4_config_instance_t;
|
|
|
|
typedef struct Ipmippm_pmipv4_output
|
|
{
|
|
struct Ip_sockaddr_in dst_output;
|
|
Ipmippm_pmipv4_config_instance_t *inst_config;
|
|
} Ipmippm_pmipv4_output_t;
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
static Ipmipmn_api_extension_t ipmippm_pmipv4_srv;
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 STATIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_STATIC int
|
|
ipmippm_pmipv4_reg_output_send(Ipmippm_context_t *data,
|
|
Ipmip_proc_t *proc,
|
|
Ipmippm_client_t *node,
|
|
Ipmippm_pktbuf_t *pbuf,
|
|
struct Ipmipmn_api_coa *coa,
|
|
Ip_bool deregister,
|
|
Ip_u32 src,
|
|
Ip_u32 dst,
|
|
Ipmippm_pmipv4_output_t *s_output)
|
|
{
|
|
Ipmip_buffer_t prrp;
|
|
Ip_size_t rhdr;
|
|
|
|
|
|
IPMIP_UNUSED_PARAMETER(deregister);
|
|
IPMIP_UNUSED_PARAMETER(src);
|
|
IPMIP_UNUSED_PARAMETER(dst);
|
|
IPMIP_UNUSED_PARAMETER(coa);
|
|
|
|
ipmip_buffer_init(&prrp);
|
|
rhdr = ipmip_attr_hdr_req_create(&prrp, 0, 0, IPMIP4_CLI_PMIPV4_PRRQ);
|
|
ipmip_attr_put(&prrp, IPMIP4_CLI_PMIPV4_ATTR_MESSAGE, IPMIP_BUFFER_SIZE(&pbuf->api.ipmip4.ipmip.packet), IPMIP_BUFFER_DATA(&pbuf->api.ipmip4.ipmip.packet));
|
|
ipmip_attr_hdr_finalize(&prrp, rhdr);
|
|
|
|
if (ipcom_sendto(s_output->inst_config->udpr.fd, IPMIP_BUFFER_DATA(&prrp), IPMIP_BUFFER_SIZE(&prrp), 0, (struct Ip_sockaddr *)&s_output->dst_output, sizeof(s_output->dst_output)) < 0)
|
|
{
|
|
IPMIP4_EVENT_IF(WARNING, proc,
|
|
ipmip_log_event_add(&data->api.ipmip4.ipmip,
|
|
proc,
|
|
"%s unable to write request errno=%d",
|
|
IPMIPMN_API_NODE_NAME(&data->api, proc, &node->api),
|
|
ipcom_errno));
|
|
ipmip_buffer_release(&prrp);
|
|
return -1;
|
|
}
|
|
|
|
ipmip_buffer_release(&prrp);
|
|
return 0;
|
|
}
|
|
|
|
|
|
IP_STATIC void
|
|
ipmippm_pmipv4_trigger_complete(Ipmippm_context_t *data,
|
|
Ipmip_proc_t *proc,
|
|
Ipmippm_client_t *node,
|
|
Ipmippm_pktbuf_t *pbuf,
|
|
Ip_u8 status)
|
|
{
|
|
struct Ipmip_attr_header *hdr = (struct Ipmip_attr_header *)IPMIP_BUFFER_DATA(&pbuf->api.ipmip4.ipmip.packet);
|
|
Ipmippm_pmipv4_config_instance_t *conf = pbuf->trigger.pmTriggerCompletionData;
|
|
Ip_size_t rhdr;
|
|
Ipmip_buffer_t trigger;
|
|
|
|
ipmip_buffer_init(&trigger);
|
|
|
|
rhdr = ipmip_attr_hdr_err(&trigger, hdr, status, IP_NULL);
|
|
if (node != IP_NULL)
|
|
{
|
|
if (node->api.params.mnRegCoA)
|
|
ipmip_attr_put_inet(&trigger, IPMIP4_CLI_PMIPV4_ATTR_NFA_COA, node->api.params.mnRegCoA->addr);
|
|
ipmip_attr_put_inet(&trigger, IPMIP4_CLI_PMIPV4_ATTR_HOA, node->api.params.assigned_home_address);
|
|
ipmip_attr_put_inet(&trigger, IPMIP4_CLI_PMIPV4_ATTR_HA, node->api.params.assigned_home_agent);
|
|
ipmip_attr_put(&trigger, IPMIP4_CLI_PMIPV4_ATTR_MN_NAI, IPMIP4_MSGEXT_SHDR_EXT_SIZE(node->api.params.nai_mn), IPMIP4_MSGEXT_SHDR_EXT_DATA(node->api.params.nai_mn));
|
|
ipmip_attr_put_u32(&trigger, IPMIP4_CLI_PMIPV4_ATTR_HA, node->api.params.assigned_home_agent);
|
|
ipmip_attr_put_u32(&trigger, IPMIP4_CLI_PMIPV4_ATTR_LIFETIME, node->api.params.mnRegTimeGranted);
|
|
}
|
|
ipmip_attr_hdr_finalize(&trigger, rhdr);
|
|
|
|
if (ipcom_sendto(conf->udpr.fd, IPMIP_BUFFER_DATA(&trigger), IPMIP_BUFFER_SIZE(&trigger), 0, (struct Ip_sockaddr *)pbuf->api.ipmip4.ipmip.srcinfo.src, sizeof(struct Ip_sockaddr_in)) < 0)
|
|
{
|
|
IPMIP4_EVENT_IF(WARNING, proc,
|
|
ipmip_log_event_add(&data->api.ipmip4.ipmip,
|
|
proc,
|
|
"%s unable to write request errno=%d",
|
|
IPMIPMN_API_NODE_NAME(&data->api, proc, &node->api),
|
|
ipcom_errno));
|
|
}
|
|
|
|
/* Remove the reference */
|
|
ipmip_buffer_release(&trigger);
|
|
ipmip_pktbuf_release(&data->api.ipmip4.ipmip, proc, &pbuf->api.ipmip4.ipmip);
|
|
}
|
|
|
|
|
|
IP_STATIC void
|
|
ipmippm_pmipv4_req_mobile_home(struct Ipmippm_context *ctx,
|
|
struct Ipmip_proc *proc,
|
|
struct Ipmippm_client_conf *conf,
|
|
Ipmippm_pmipv4_config_instance_t *inst_config,
|
|
void *node_config,
|
|
struct Ipmippm_client *node,
|
|
Ip_bool deregister,
|
|
struct Ipmippm_pktbuf *pbuf)
|
|
{
|
|
|
|
IPMIP_UNUSED_PARAMETER(ctx);
|
|
IPMIP_UNUSED_PARAMETER(proc);
|
|
IPMIP_UNUSED_PARAMETER(conf);
|
|
IPMIP_UNUSED_PARAMETER(deregister);
|
|
IPMIP_UNUSED_PARAMETER(node_config);
|
|
IPMIP_UNUSED_PARAMETER(inst_config);
|
|
IPMIP_UNUSED_PARAMETER(node);
|
|
IPMIP_UNUSED_PARAMETER(pbuf);
|
|
|
|
}
|
|
|
|
IP_STATIC void
|
|
ipmippm_pmipv4_req_mobile_foreign(struct Ipmippm_context *ctx,
|
|
struct Ipmip_proc *proc,
|
|
struct Ipmippm_client_conf *conf,
|
|
Ipmippm_pmipv4_config_instance_t *inst_config,
|
|
void *node_config,
|
|
struct Ipmippm_client *node,
|
|
Ip_bool deregister,
|
|
struct Ipmippm_pktbuf *pbuf)
|
|
{
|
|
|
|
IPMIP_UNUSED_PARAMETER(ctx);
|
|
IPMIP_UNUSED_PARAMETER(proc);
|
|
IPMIP_UNUSED_PARAMETER(conf);
|
|
IPMIP_UNUSED_PARAMETER(deregister);
|
|
IPMIP_UNUSED_PARAMETER(node_config);
|
|
IPMIP_UNUSED_PARAMETER(inst_config);
|
|
|
|
if (node->pmAccessType)
|
|
ipmip4_msgext_buffer_append_shdr(&pbuf->api.ipmip4.ipmip.packet, node->pmAccessType);
|
|
if (node->pmDeviceID)
|
|
ipmip4_msgext_buffer_append_shdr(&pbuf->api.ipmip4.ipmip.packet, node->pmDeviceID);
|
|
if (node->pmInterfaceID)
|
|
ipmip4_msgext_buffer_append_shdr(&pbuf->api.ipmip4.ipmip.packet, node->pmInterfaceID);
|
|
if (node->pmSubscriberID)
|
|
ipmip4_msgext_buffer_append_shdr(&pbuf->api.ipmip4.ipmip.packet, node->pmSubscriberID);
|
|
if (node->pmPerNodeAuthMethod)
|
|
ipmip4_msgext_buffer_append_lhdr(&pbuf->api.ipmip4.ipmip.packet, node->pmPerNodeAuthMethod);
|
|
}
|
|
|
|
IP_STATIC void
|
|
ipmippm_pmipv4_udp_prtrigger(Ipmippm_context_t *ctx,
|
|
Ipmip_proc_t *proc,
|
|
Ipmippm_pmipv4_config_instance_t *conf,
|
|
Ipmippm_pktbuf_t *pbuf)
|
|
{
|
|
Ipmippm_pmipv4_output_t s_output;
|
|
struct Ipmip_attr_header *hdr = (struct Ipmip_attr_header *)IPMIP_BUFFER_DATA(&pbuf->api.ipmip4.ipmip.packet);
|
|
|
|
ipmip_attr_hdr_parse(IPMIP4_CLI_PMIPV4_ATTR_MAX, hdr, pbuf->trigger.pmTriggerAttr);
|
|
|
|
pbuf->trigger.pmTriggerType = IPMIP_ATTR_HDR_TYPE(hdr);
|
|
/**/
|
|
pbuf->api.iff.priv = conf->conf->iff;
|
|
|
|
ipcom_memcpy(&s_output.dst_output, &pbuf->api.ipmip4.ipmip.srcinfo.src->sin, sizeof(s_output.dst_output));
|
|
s_output.inst_config = conf;
|
|
|
|
pbuf->trigger.pmTriggerCOAOutput = (Ipmipmn_api_coa_output_t)ipmippm_pmipv4_reg_output_send;
|
|
pbuf->trigger.pmTriggerCOAOutputAuxData = &s_output;
|
|
pbuf->trigger.pmTriggerCOAOutputAuxSize = sizeof(s_output);
|
|
pbuf->trigger.pmTriggerCompletion = (Ipmippm_pktbuf_trigger_complete_t)ipmippm_pmipv4_trigger_complete;
|
|
pbuf->trigger.pmTriggerCompletionData = conf;
|
|
|
|
/* Need to do lookup */
|
|
ipmippm_client_trigger_handoff(ctx, proc, pbuf);
|
|
return;
|
|
}
|
|
|
|
|
|
IP_STATIC void
|
|
ipmippm_pmipv4_udp_prrq(Ipmippm_context_t *ctx,
|
|
Ipmip_proc_t *proc,
|
|
Ipmippm_pmipv4_config_instance_t *conf,
|
|
Ipmippm_pktbuf_t *pbuf)
|
|
{
|
|
Ipmip_buffer_t prrq;
|
|
struct Ipmip_attr_header *hdr = (struct Ipmip_attr_header *)IPMIP_BUFFER_DATA(&pbuf->api.ipmip4.ipmip.packet);
|
|
|
|
ipmip_attr_hdr_parse(IPMIP4_CLI_PMIPV4_ATTR_MAX, hdr, pbuf->trigger.pmTriggerAttr);
|
|
|
|
/**/
|
|
pbuf->api.iff.priv = conf->conf->iff;
|
|
|
|
/**/
|
|
if (pbuf->trigger.pmTriggerAttr[IPMIP4_CLI_PMIPV4_ATTR_MESSAGE] == IP_NULL)
|
|
{
|
|
IPMIP4_EVENT_IF(ERR, proc,
|
|
ipmip_log_event_add(&ctx->api.ipmip4.ipmip,
|
|
proc,
|
|
"Received PMIPv4 PRRQ -- missing message"));
|
|
goto done_out;
|
|
}
|
|
|
|
ipmip_buffer_init(&prrq);
|
|
ipmip_buffer_append(&prrq, IPMIP_ATTR_DATA(pbuf->trigger.pmTriggerAttr[IPMIP4_CLI_PMIPV4_ATTR_MESSAGE]), IPMIP_ATTR_PAYLOAD(pbuf->trigger.pmTriggerAttr[IPMIP4_CLI_PMIPV4_ATTR_MESSAGE]));
|
|
ipmip_buffer_assign(&pbuf->api.ipmip4.ipmip.packet, &prrq);
|
|
|
|
ipmipmn_api_reg_recv(&ctx->api, proc, &pbuf->api);
|
|
return;
|
|
|
|
done_out:
|
|
ipmip_pktbuf_release(&ctx->api.ipmip4.ipmip, proc, &pbuf->api.ipmip4.ipmip);
|
|
}
|
|
|
|
IP_STATIC void
|
|
ipmippm_pmipv4_udp_recvmsg(Ipmippm_context_t *ctx,
|
|
Ipmip_proc_t *proc,
|
|
Ipmippm_pktbuf_t *pbuf,
|
|
Ipmippm_pmipv4_config_instance_t *conf)
|
|
{
|
|
struct Ipmip_attr_header *hdr = (struct Ipmip_attr_header *)IPMIP_BUFFER_DATA(&pbuf->api.ipmip4.ipmip.packet);
|
|
|
|
if (IPMIP_BUFFER_SIZE(&pbuf->api.ipmip4.ipmip.packet) < sizeof(struct Ipmip_attr_header))
|
|
{
|
|
IPMIP4_EVENT_IF(ERR, proc,
|
|
ipmip_log_event_add(&ctx->api.ipmip4.ipmip,
|
|
proc,
|
|
"Received PMIPv4 Trigger Message -- Truncated"));
|
|
goto done_out;
|
|
}
|
|
|
|
switch (IPMIP_ATTR_HDR_TYPE(hdr))
|
|
{
|
|
case IPMIP4_CLI_PMIPV4_PREVRQ:
|
|
IPMIP4_EVENT_IF(INFO, proc,
|
|
ipmip_log_event_add(&ctx->api.ipmip4.ipmip,
|
|
proc,
|
|
"Received PMIPv4 PREVRQ"));
|
|
ipmippm_pmipv4_udp_prtrigger(ctx, proc, conf, pbuf);
|
|
return;
|
|
case IPMIP4_CLI_PMIPV4_PTRQ:
|
|
IPMIP4_EVENT_IF(INFO, proc,
|
|
ipmip_log_event_add(&ctx->api.ipmip4.ipmip,
|
|
proc,
|
|
"Received PMIPv4 PTRQ"));
|
|
ipmippm_pmipv4_udp_prtrigger(ctx, proc, conf, pbuf);
|
|
return;
|
|
case IPMIP4_CLI_PMIPV4_PRRQ:
|
|
IPMIP4_EVENT_IF(INFO, proc,
|
|
ipmip_log_event_add(&ctx->api.ipmip4.ipmip,
|
|
proc,
|
|
"Received PMIPv4 PRRQ"));
|
|
ipmippm_pmipv4_udp_prrq(ctx, proc, conf, pbuf);
|
|
return;
|
|
}
|
|
|
|
done_out:
|
|
ipmip_pktbuf_release(&ctx->api.ipmip4.ipmip, proc, &pbuf->api.ipmip4.ipmip);
|
|
}
|
|
|
|
IP_STATIC void
|
|
ipmippm_pmipv4_config(struct Ipmippm_context *ctx,
|
|
struct Ipmip_proc *proc,
|
|
int action,
|
|
const char *pre,
|
|
const char *spec,
|
|
struct Ipmippm_client_conf *conf,
|
|
Ipmippm_pmipv4_config_instance_t *inst_config,
|
|
Ipmip_cli_message_t *request)
|
|
{
|
|
IPMIP_UNUSED_PARAMETER(ctx);
|
|
IPMIP_UNUSED_PARAMETER(proc);
|
|
IPMIP_UNUSED_PARAMETER(conf);
|
|
IPMIP_UNUSED_PARAMETER(request);
|
|
IPMIP_UNUSED_PARAMETER(pre);
|
|
IPMIP_UNUSED_PARAMETER(spec);
|
|
|
|
if (action == IPMIP_CALLBACK_CONFIG_READ)
|
|
{
|
|
inst_config->udpr.fd = IP_INVALID_SOCKET;
|
|
if (ipmip_sysvar_bool(ipmip_sysvar_bool(IP_FALSE, "%s.pmipv4.dhcp.enable", pre), "%s.%spmipv4.dhcp.enable", pre, spec))
|
|
{
|
|
inst_config->port = (Ip_u16)ipmip_sysvar_ulong(ipmip_sysvar_ulong(IPMIP4_PORT, "%s.pmipv4.dhcp.port", pre), "%s.%spmipv4.dhcp.port", pre, spec);
|
|
|
|
ipcom_memset(&inst_config->sin4, 0, sizeof(inst_config->sin4));
|
|
inst_config->sin4.sin_family = IP_AF_INET;
|
|
IPCOM_SA_LEN_SET(&inst_config->sin4, sizeof(inst_config->sin4));
|
|
inst_config->sin4.sin_port = ip_htons(inst_config->port);
|
|
inst_config->sin4.sin_addr.s_addr = conf->iff->iff.ifaddr;
|
|
|
|
inst_config->udpr.fd = ipmip_inet_udp_socket(&inst_config->sin4);
|
|
if (inst_config->udpr.fd != IP_INVALID_SOCKET)
|
|
{
|
|
inst_config->udpr.udp_callback = (Ipmip4_pkt_udp_cb_t)ipmippm_pmipv4_udp_recvmsg;
|
|
inst_config->udpr.opaque = inst_config;
|
|
|
|
/* Start the process */
|
|
inst_config->conf = conf;
|
|
|
|
/**/
|
|
ipmip4_pkt_udp_register(&ctx->api.ipmip4, proc, &inst_config->udpr);
|
|
|
|
IPMIP4_EVENT_IF(WARNING, proc,
|
|
ipmip_log_event_add(&ctx->api.ipmip4.ipmip,
|
|
proc,
|
|
"Created PMIPv4 UDP socket for %s %s:%u",
|
|
inst_config->conf->iff->iff.ipmip.ifname,
|
|
ipmip_ntop_inet(proc, inst_config->conf->iff->iff.ifaddr),
|
|
inst_config->port));
|
|
}
|
|
else
|
|
{
|
|
IPMIP4_EVENT_IF(WARNING, proc,
|
|
ipmip_log_event_add(&ctx->api.ipmip4.ipmip,
|
|
proc,
|
|
"Unable to create PMIPv4 UDP socket for %s %s:%u",
|
|
inst_config->conf->iff->iff.ipmip.ifname,
|
|
ipmip_ntop_inet(proc, inst_config->conf->iff->iff.ifaddr),
|
|
inst_config->port));
|
|
}
|
|
}
|
|
}
|
|
else if (action == IPMIP_CALLBACK_CONFIG_FREE)
|
|
{
|
|
ipmip4_pkt_udp_unregister(&ctx->api.ipmip4, proc, &inst_config->udpr);
|
|
if (inst_config->udpr.fd != IP_INVALID_SOCKET)
|
|
ipcom_socketclose(inst_config->udpr.fd);
|
|
|
|
/* Clear */
|
|
inst_config->udpr.fd = IP_INVALID_SOCKET;
|
|
}
|
|
else if (action == IPMIP_CALLBACK_CONFIG_DUMP)
|
|
{
|
|
/* Could dump, but dont bother */
|
|
if (inst_config->udpr.fd != IP_INVALID_SOCKET)
|
|
{
|
|
ipmip_cli_config_printf(&request->message,
|
|
"%s.%spmipv4.dhcp.enable=enabled",
|
|
pre, spec);
|
|
ipmip_cli_config_printf(&request->message,
|
|
"%s.%spmipv4.dhcp.port=%u",
|
|
pre, spec, inst_config->port);
|
|
}
|
|
else
|
|
{
|
|
ipmip_cli_config_printf(&request->message,
|
|
"%s.%spmipv4.dhcp.enable=disabled",
|
|
pre, spec);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 GLOBAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_GLOBAL void ipmippm_pmipv4_install(void);
|
|
IP_GLOBAL void
|
|
ipmippm_pmipv4_install(void)
|
|
{
|
|
ipcom_memset(&ipmippm_pmipv4_srv, 0, sizeof(ipmippm_pmipv4_srv));
|
|
|
|
ipmippm_pmipv4_srv.name = IPMIPPM_PMIPV4_SERVICE;
|
|
ipmippm_pmipv4_srv.instance_data_size = sizeof(Ipmippm_pmipv4_config_instance_t);
|
|
ipmippm_pmipv4_srv.config_instance = (Ipmipmn_api_extension_config_instance_t)ipmippm_pmipv4_config;
|
|
|
|
ipmippm_pmipv4_srv.pkt_req_mobile_home = (Ipmipmn_api_extension_pkt_req_mobile_home_t)ipmippm_pmipv4_req_mobile_home;
|
|
ipmippm_pmipv4_srv.pkt_req_mobile_foreign = (Ipmipmn_api_extension_pkt_req_mobile_foreign_t)ipmippm_pmipv4_req_mobile_foreign;
|
|
|
|
ipmippm_context_register_function(&ipmippm_pmipv4_srv);
|
|
}
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 11 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|