339 lines
12 KiB
C
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
|
|
****************************************************************************
|
|
*/
|