summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2014-06-03 14:55:49 +0200
committerMichael Adam <obnox@samba.org>2014-06-05 23:57:09 +0200
commitd5b204cefd8f9981d20adfb9578636008daabc38 (patch)
tree3dfdda9895232007ec7b237def35a9c14a2c102d /lib
parent56d5bf9af86dfac5431ec9c12096a4a28d337c05 (diff)
downloadsamba-d5b204cefd8f9981d20adfb9578636008daabc38.tar.gz
samba-d5b204cefd8f9981d20adfb9578636008daabc38.tar.xz
samba-d5b204cefd8f9981d20adfb9578636008daabc38.zip
swrap: Add swrap_msghdr_add_pktinfo().
Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> Pair-Programmed-With: Michael Adam <obnox@samba.org> Signed-off-by: Andreas Schneider <asn@samba.org> Signed-off-by: Stefan Metzmacher <metze@samba.org> Signed-off-by: Michael Adam <obnox@samba.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/socket_wrapper/socket_wrapper.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c
index d3824597810..288ca13c83a 100644
--- a/lib/socket_wrapper/socket_wrapper.c
+++ b/lib/socket_wrapper/socket_wrapper.c
@@ -3033,6 +3033,71 @@ static void swrap_msghdr_add_cmsghdr(struct msghdr *msg,
return;
}
+
+static int swrap_msghdr_add_pktinfo(struct socket_info *si,
+ struct msghdr *msg)
+{
+ /* Add packet info */
+ switch (si->pktinfo) {
+#ifdef IP_PKTINFO
+ case AF_INET: {
+ struct sockaddr_in *sin;
+ struct in_pktinfo pkt;
+
+ if (si->bindname_len == sizeof(struct sockaddr_in)) {
+ sin = (struct sockaddr_in*)si->bindname;
+ } else {
+ if (si->myname_len != sizeof(struct sockaddr_in)) {
+ return 0;
+ }
+ sin = (struct sockaddr_in*)si->myname;
+ }
+
+ ZERO_STRUCT(pkt);
+
+ pkt.ipi_ifindex = socket_wrapper_default_iface();
+ pkt.ipi_addr.s_addr = sin->sin_addr.s_addr;
+
+ swrap_msghdr_add_cmsghdr(msg, IPPROTO_IP, IP_PKTINFO,
+ &pkt, sizeof(pkt));
+
+ break;
+ }
+#endif /* IP_PKTINFO */
+#if defined(HAVE_IPV6)
+ case AF_INET6: {
+#if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO)
+ struct sockaddr_in6 *sin6;
+ struct in6_pktinfo pkt6;
+
+ if (si->bindname_len == sizeof(struct sockaddr_in6)) {
+ sin6 = (struct sockaddr_in6*)si->bindname;
+ } else {
+ if (si->myname_len != sizeof(struct sockaddr_in6)) {
+ return 0;
+ }
+ sin6 = (struct sockaddr_in6*)si->myname;
+ }
+
+ ZERO_STRUCT(pkt6);
+
+ pkt6.ipi6_ifindex = socket_wrapper_default_iface();
+ pkt6.ipi6_addr = sin6->sin6_addr;
+
+ swrap_msghdr_add_cmsghdr(msg, IPPROTO_IPV6, IPV6_PKTINFO,
+ &pkt6, sizeof(pkt6));
+#endif /* HAVE_STRUCT_IN6_PKTINFO */
+
+ break;
+ }
+#endif /* IPV6_PKTINFO */
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
#endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
static ssize_t swrap_sendmsg_before(int fd,