332 lines
9.9 KiB
C
332 lines
9.9 KiB
C
|
|
/*
|
|
******************************************************************************
|
|
* INTERPEAK SOURCE FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmip_inet6.c,v $ $Revision: 1.2 $
|
|
* $Source: /home/interpeak/CVSRoot/ipmip/src/ipmip_inet6.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 "ipmip_config.h"
|
|
|
|
#ifdef IPMIP_USE_INET6
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#define IPCOM_USE_CLIB_PROTO
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_clib2.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_sysvar.h>
|
|
#include <ipcom_cmd.h>
|
|
#include <ipcom_getopt.h>
|
|
#include <ipcom_netif.h>
|
|
|
|
|
|
#include <ipmip.h>
|
|
#include <private/ipmip_buffer.h>
|
|
#include <private/ipmip_context.h>
|
|
#include <private/ipmip_pktbuf.h>
|
|
#include <private/ipmip_cli.h>
|
|
#include <private/ipmip_util.h>
|
|
#include <private/ipmip_sysvar.h>
|
|
#include <private/ipmip_inet6.h>
|
|
#include <private/ipmip_lladdr.h>
|
|
#include <private/ipmip_if.h>
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
#define IPMIP_INET6_PKT_CLEN 128
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 STATIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 GLOBAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_GLOBAL Ip_bool
|
|
ipmip_inet6_multicast_join(Ipmip_context_t *ctx,
|
|
Ipmip_proc_t *proc,
|
|
Ip_fd fd,
|
|
Ip_u32 ifindex,
|
|
struct Ip_in6_addr *mcast)
|
|
{
|
|
struct Ip_ipv6_mreq mreq;
|
|
|
|
IPMIP_UNUSED_PARAMETER(ctx);
|
|
IPMIP_UNUSED_PARAMETER(proc);
|
|
|
|
/* Clear it all */
|
|
ipcom_memset(&mreq, 0, sizeof(mreq));
|
|
|
|
/* Set the correct solicited address */
|
|
ipcom_memcpy(&mreq.ipv6mr_multiaddr, mcast, sizeof(*mcast));
|
|
mreq.ipv6mr_interface = ifindex;
|
|
|
|
if (ipcom_setsockopt(fd, IP_IPPROTO_IPV6, IP_IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) < 0)
|
|
return IP_FALSE;
|
|
|
|
return IP_TRUE;
|
|
}
|
|
|
|
IP_GLOBAL Ip_bool
|
|
ipmip_inet6_multicast_leave(Ipmip_context_t *ctx,
|
|
Ipmip_proc_t *proc,
|
|
Ip_fd fd,
|
|
Ip_u32 ifindex,
|
|
struct Ip_in6_addr *mcast)
|
|
{
|
|
struct Ip_ipv6_mreq mreq;
|
|
|
|
IPMIP_UNUSED_PARAMETER(ctx);
|
|
IPMIP_UNUSED_PARAMETER(proc);
|
|
|
|
/* Clear it all */
|
|
ipcom_memset(&mreq, 0, sizeof(mreq));
|
|
|
|
/* Set the correct solicited address */
|
|
ipcom_memcpy(&mreq.ipv6mr_multiaddr, mcast, sizeof(*mcast));
|
|
mreq.ipv6mr_interface = ifindex;
|
|
if (ipcom_setsockopt(fd, IP_IPPROTO_IPV6, IP_IPV6_LEAVE_GROUP, &mreq, sizeof(mreq)) < 0)
|
|
return IP_FALSE;
|
|
|
|
return IP_TRUE;
|
|
}
|
|
|
|
|
|
IP_GLOBAL Ip_bool
|
|
ipmip_inet6_anycast_join(Ipmip_context_t *ctx,
|
|
Ipmip_proc_t *proc,
|
|
Ip_fd fd,
|
|
Ip_u32 ifindex,
|
|
struct Ip_in6_addr *anycast)
|
|
{
|
|
struct Ip_ipv6_mreq mreq;
|
|
|
|
IPMIP_UNUSED_PARAMETER(ctx);
|
|
IPMIP_UNUSED_PARAMETER(proc);
|
|
|
|
/* Clear it all */
|
|
ipcom_memset(&mreq, 0, sizeof(mreq));
|
|
|
|
/* Set the correct solicited address */
|
|
ipcom_memcpy(&mreq.ipv6mr_multiaddr, anycast, sizeof(*anycast));
|
|
mreq.ipv6mr_interface = ifindex;
|
|
|
|
if (ipcom_setsockopt(fd, IP_IPPROTO_IPV6, IP_IPV6_JOIN_ANYCAST, &mreq, sizeof(mreq)) < 0)
|
|
return IP_FALSE;
|
|
|
|
return IP_TRUE;
|
|
}
|
|
|
|
IP_GLOBAL Ip_bool
|
|
ipmip_inet6_anycast_leave(Ipmip_context_t *ctx,
|
|
Ipmip_proc_t *proc,
|
|
Ip_fd fd,
|
|
Ip_u32 ifindex,
|
|
struct Ip_in6_addr *anycast)
|
|
{
|
|
struct Ip_ipv6_mreq mreq;
|
|
|
|
IPMIP_UNUSED_PARAMETER(ctx);
|
|
IPMIP_UNUSED_PARAMETER(proc);
|
|
|
|
/* Clear it all */
|
|
ipcom_memset(&mreq, 0, sizeof(mreq));
|
|
|
|
/* Set the correct solicited address */
|
|
ipcom_memcpy(&mreq.ipv6mr_multiaddr, anycast, sizeof(*anycast));
|
|
mreq.ipv6mr_interface = ifindex;
|
|
if (ipcom_setsockopt(fd, IP_IPPROTO_IPV6, IP_IPV6_LEAVE_ANYCAST, &mreq, sizeof(mreq)) < 0)
|
|
return IP_FALSE;
|
|
|
|
return IP_TRUE;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmip6_icmp_recv
|
|
*===========================================================================
|
|
* Description: Receive and process an ICMP message.
|
|
* Parameters: context - The context
|
|
* Returns: IP_TRUE if successful.
|
|
*
|
|
*/
|
|
IP_GLOBAL Ipmip_pktbuf_t *
|
|
ipmip_inet6_udp_recvmsg(Ipmip_context_t *ctx,
|
|
Ipmip_proc_t *proc,
|
|
Ip_size_t vlen,
|
|
Ip_fd fd)
|
|
{
|
|
struct Ip_cmsghdr *cmsghdr;
|
|
int len;
|
|
struct Ip_sockaddr_in6 src;
|
|
struct Ip_msghdr msg;
|
|
struct Ip_iovec vec;
|
|
|
|
/* Set when the option is located */
|
|
Ipmip_pktbuf_t *pbuf = IP_NULL;
|
|
|
|
/* Allocate pktbuf */
|
|
pbuf = (Ipmip_pktbuf_t *)ipmip_pktbuf_alloc(ctx, proc, vlen + IPMIP_INET6_PKT_CLEN);
|
|
|
|
/* Failed to allocate buffer? */
|
|
if (pbuf == IP_NULL)
|
|
return IP_NULL;
|
|
|
|
/* Initialize vector */
|
|
vec.iov_base = IPMIP_BUFFER_DATA(&pbuf->packet);
|
|
vec.iov_len = vlen;
|
|
|
|
/* Initialize name */
|
|
msg.msg_name = &src;
|
|
msg.msg_namelen = sizeof(src);
|
|
|
|
/* Initialize io */
|
|
msg.msg_iov = &vec;
|
|
msg.msg_iovlen = 1;
|
|
|
|
/* Initialize control */
|
|
msg.msg_control = ipmip_buffer_offset(&pbuf->packet, vlen);
|
|
msg.msg_controllen = IPMIP_INET6_PKT_CLEN;
|
|
|
|
/* Clear flags */
|
|
msg.msg_flags = 0;
|
|
|
|
/* Read and process a Mobile Header message */
|
|
if ((len = ipcom_recvmsg(fd, &msg, 0)) < 0)
|
|
{
|
|
ipmip_util_sock_clear(fd);
|
|
goto error_out;
|
|
}
|
|
|
|
/* We've gotten something */
|
|
if ((msg.msg_flags & (IP_MSG_TRUNC | IP_MSG_CTRUNC)) != 0)
|
|
goto error_out;
|
|
|
|
/* Store value */
|
|
ipmip_util_dup(&pbuf->srcinfo.src, &src, sizeof(src));
|
|
|
|
/* Move past the read length */
|
|
ipmip_buffer_append(&pbuf->packet, IP_NULL, len);
|
|
|
|
/* Did we get any ancillary data? */
|
|
if (msg.msg_controllen > 0)
|
|
{
|
|
/* Loop the ancillary data, see what we find */
|
|
for (cmsghdr = IP_CMSG_FIRSTHDR(&msg); cmsghdr != 0;
|
|
cmsghdr = IP_CMSG_NXTHDR(&msg, cmsghdr))
|
|
{
|
|
/* Correct level? */
|
|
if (cmsghdr->cmsg_level == IP_IPPROTO_IPV6)
|
|
{
|
|
/* Type? */
|
|
switch (cmsghdr->cmsg_type)
|
|
{
|
|
case IP_IPV6_RECVPKTINFO: /* LKM */
|
|
case IP_IPV6_PKTINFO: /* IPNET */
|
|
ipmip_pktbuf_srcinfo_dst_inet6(pbuf, (struct Ip_in6_pktinfo *)IP_CMSG_DATA(cmsghdr));
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Do sanity */
|
|
if (pbuf->srcinfo.dst == IP_NULL)
|
|
goto error_out;
|
|
|
|
/* */
|
|
return pbuf;
|
|
|
|
error_out:
|
|
ipmip_pktbuf_release(ctx, proc, pbuf);
|
|
return IP_NULL;
|
|
}
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 11 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
|
|
#else /* IPMIP_USE_INET6 */
|
|
|
|
int ipmip_inet6_empty_file = 0;
|
|
|
|
#endif /* IPMIP_USE_INET6 */
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|