/* ****************************************************************************** * 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 ****************************************************************************** */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #include "ipmip_config.h" #ifdef IPMIP_USE_INET6 /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #define IPCOM_USE_CLIB_PROTO #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* **************************************************************************** * 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 **************************************************************************** */