diff options
author | Andreas Schneider <asn@samba.org> | 2014-06-03 14:55:49 +0200 |
---|---|---|
committer | Michael Adam <obnox@samba.org> | 2014-06-05 23:57:09 +0200 |
commit | d5b204cefd8f9981d20adfb9578636008daabc38 (patch) | |
tree | 3dfdda9895232007ec7b237def35a9c14a2c102d /lib | |
parent | 56d5bf9af86dfac5431ec9c12096a4a28d337c05 (diff) | |
download | samba-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.c | 65 |
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, |