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

339 lines
12 KiB
C

/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmip6_nd_proxy.c,v $ $Revision: 1.15 $
* $Source: /home/interpeak/CVSRoot/ipmip6/src/ipmip6_nd_proxy.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 "ipmip6_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_clib.h>
#include <ipcom_os.h>
#include <ipcom_list.h>
#include <ipcom_sock.h>
#include <ipcom_sock6.h>
#include <ipcom_inet.h>
#include <ipcom_err.h>
#include <ipcom_syslog.h>
#include <ipcom_netif.h>
#include <ipmip.h>
#include <private/ipmip_util.h>
#include "ipmip6_h.h"
#include <private/ipmip6_context.h>
#include <private/ipmip6_nd_proxy.h>
#include <private/ipmip6_nd_nud.h>
#include <private/ipmip6_if.h>
#include <private/ipmip6_icmp.h>
#include <private/ipmip6_icmp_pkt.h>
#include <private/ipmip6_util.h>
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipmip6_nd_proxy_unsolicited_timeout
*===========================================================================
* Description: Send a new unsolicited message
* Parameters: cookie - The proxy structure.
* Returns: IP_TRUE if we're not done yet, IP_FALSE otherwise
*
*/
IP_STATIC int
ipmip6_nd_proxy_unsolicited_timeout_iflocked(int event,
Ipmip6_context_t *ctx,
Ipmip_proc_t *proc,
Ipmip6_nd_proxy_t *proxy,
void *unused)
{
IPMIP_UNUSED_PARAMETER(unused);
if (event == IPMIP_TIMER_EVENT_RUN)
{
/* */
++proxy->sent;
/* Send an unsolicited neighbor advertisement */
ipmip6_icmp_neighbor_advertisement(ctx, proc, proxy, IP_NULL, IP_TRUE);
/**/
return proxy->sent < 3? IPMIP_TIMER_RET_REINSERT : IPMIP_TIMER_RET_DONE;
}
return IPMIP_TIMER_RET_DONE;
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipmip6_nd_proxy_start_solicited_iflocked
*===========================================================================
* Description: Start passive proxying for a given address
* Parameters: proxy - The proxy object
* Returns:
*
*/
IP_GLOBAL void
ipmip6_nd_proxy_start_solicited_iflocked(Ipmip6_context_t *ctx,
Ipmip_proc_t *proc,
struct Ipmip6_if *ife,
Ipmip6_nd_proxy_t *proxy)
{
/* Stop any previous proxy registrations */
ipmip6_nd_proxy_stop_iflocked(ctx, proc, proxy);
/* Set solicited mode */
proxy->ifp = ife;
/* Add to the list */
ipcom_list_insert_first(&proxy->ifp->iff_nd_proxy, &proxy->next);
/* Join the solicitated address */
ipmip6_icmp_mc_solicitated_address(ctx,
proc,
IP_TRUE,
proxy->ifp,
proxy->addr);
}
/*
*===========================================================================
* ipmip6_nd_proxy_start_unsolicited_iflocked
*===========================================================================
* Description: Start unsolicited neighbor advertisements
* Parameters: proxy - The proxy object
* Returns:
*
*/
IP_GLOBAL void
ipmip6_nd_proxy_start_unsolicited_iflocked(Ipmip6_context_t *ctx,
Ipmip_proc_t *proc,
struct Ipmip6_if *ife,
Ipmip6_nd_proxy_t *proxy)
{
/* Stop any previous proxy registrations */
ipmip6_nd_proxy_stop_iflocked(ctx, proc, proxy);
/* Set unsolicted mode */
proxy->ifp = ife;
/* Add to the list */
ipcom_list_insert_first(&proxy->ifp->iff_nd_proxy, &proxy->next);
/* Join the solicitated address */
ipmip6_icmp_mc_solicitated_address(ctx,
proc,
IP_TRUE,
proxy->ifp,
proxy->addr);
/* */
proxy->sent = 1;
/* Send an unsolicited neighbor advertisement */
ipmip6_icmp_neighbor_advertisement(ctx, proc, proxy, IP_NULL, IP_TRUE);
/* Insert a timeout */
ipmip_timer_cancel(&ctx->ipmip, proc, &proxy->unsolicited);
ipmip_timer_request(&ctx->ipmip,
proc,
&proxy->unsolicited,
proxy->ifp->iff_lock,
(Ipmip_timer_func_t)ipmip6_nd_proxy_unsolicited_timeout_iflocked,
proxy,
IP_NULL,
IPMIP6_ND_NUD_RETRANS_TIMER);
}
/*
*===========================================================================
* ipmip6_nd_proxy_stop_iflocked
*===========================================================================
* Description: Start passive proxying for a given address
* Parameters: proxy - The proxy object
* Returns:
*
*/
IP_GLOBAL void
ipmip6_nd_proxy_stop_iflocked(Ipmip6_context_t *ctx,
Ipmip_proc_t *proc,
Ipmip6_nd_proxy_t *proxy)
{
/* Stop any previous proxy registrations */
if (proxy->next.head != IP_NULL)
{
/* Remove this element from the proxy */
ipcom_list_remove(&proxy->next);
/* Leave the solicitated address */
ipmip6_icmp_mc_solicitated_address(ctx,
proc,
IP_FALSE,
proxy->ifp,
proxy->addr);
/* Remove the unsolicited timeout */
ipmip_timer_cancel(&ctx->ipmip, proc, &proxy->unsolicited);
}
}
/*
*===========================================================================
* ipmip6_nd_proxy_ns_recv
*===========================================================================
* Description: Receives a neighbor solicitation.
* Parameters: context - The context
* icmp - The icmp header.
* len - The total length of the icmp packet.
* name - The name of the interface it arrived on.
* src - The source address it want sent from.
* Returns:
*
*/
IP_GLOBAL void
ipmip6_nd_proxy_ns_recv(Ipmip6_context_t *ctx,
Ipmip_proc_t *proc,
Ipmip6_pktbuf_t *pbuf)
{
Ipmip6_if_t *ife = ipmip6_if_lockbyindex(ctx, proc, pbuf->ipmip.srcinfo.dst->ifindex);
char buf[1024];
IPMIP6_EVENT_IF(WARNING, proc,
ipmip_log_event_add(&ctx->ipmip,
proc,
"Neighbor Solicitation received on %s",
ipcom_if_indextoname(pbuf->ipmip.srcinfo.dst->ifindex, buf)));
/* Located the required interface? */
if (ife != IP_NULL)
{
Ipmip6_nd_proxy_t *proxy;
Ipmip6_pkt_nd_neighbor_solicitation_t *ns = (Ipmip6_pkt_nd_neighbor_solicitation_t *) IPMIP_BUFFER_PTR(&pbuf->ipmip.packet);
/* Sanity check */
if (ns->nd_ns_hdr.icmp6_code != 0 || (Ip_size_t)IPMIP_BUFFER_SIZE(&pbuf->ipmip.packet) < sizeof(Ipmip6_pkt_nd_neighbor_solicitation_t))
{
IPMIP6_EVENT_IF(WARNING, proc,
ipmip_log_event_add(&ctx->ipmip,
proc,
"Neighbor Solicitation received on %s is truncated or erronous",
ife->iff.ifname));
goto unlock_out;
}
for (proxy = IPCOM_LIST_FIRST(&ife->iff_nd_proxy); proxy != IP_NULL; proxy = IPCOM_LIST_NEXT(&proxy->next))
if (IP_IN6_ARE_ADDR_EQUAL(proxy->addr, &ns->nd_ns_target))
break;
/* Found it? */
if (proxy != IP_NULL)
/* Send a solicited neighbor advertisement */
ipmip6_icmp_neighbor_advertisement(ctx, proc, proxy, &pbuf->ipmip.srcinfo.src->sin6.sin6_addr, IP_FALSE);
}
unlock_out:
if (ife)
ipmip6_if_release_iflocked(ctx,proc,ife);
ipmip_pktbuf_free(&ctx->ipmip, proc, &pbuf->ipmip);
}
/*
*===========================================================================
* ipmip6_nd_proxy_init
*===========================================================================
* Description: Initialize a proxy structure
* Parameters: proxy - The proxy object
* name - The name of the proxy structure
* Returns:
*
*/
IP_GLOBAL void
ipmip6_nd_proxy_init(Ipmip6_nd_proxy_t *proxy)
{
/* Initialize the timeout */
IPMIP_TIMER_INIT(&proxy->unsolicited);
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/