summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul \"LeoNerd\" Evans <leonerd@leonerd.org.uk>2011-10-13 15:42:17 +0100
committerTony Cook <tony@develop-help.com>2011-10-24 18:39:08 +1100
commit4f5bb87fb7392b2cb5b17cec790ae462fba17162 (patch)
treebeae37d37277b707ed8faf21fe3b2e39f60522b3
parent3b8d3bdaa9d44177777ac34741bd9fd62bd7954e (diff)
downloadperl-4f5bb87fb7392b2cb5b17cec790ae462fba17162.tar.gz
Wrap some IPv6 sockopt constants and ipv6_mreq structure
-rw-r--r--ext/Socket/Makefile.PL3
-rw-r--r--ext/Socket/Socket.pm30
-rw-r--r--ext/Socket/Socket.xs47
3 files changed, 79 insertions, 1 deletions
diff --git a/ext/Socket/Makefile.PL b/ext/Socket/Makefile.PL
index f22a22b29a..83908116f3 100644
--- a/ext/Socket/Makefile.PL
+++ b/ext/Socket/Makefile.PL
@@ -19,6 +19,9 @@ my @names = (qw(AF_802 AF_AAL AF_APPLETALK AF_CCITT AF_CHAOS AF_CTF
EAI_NODATA EAI_NONAME EAI_SERVICE EAI_SOCKTYPE
IOV_MAX IP_OPTIONS IP_HDRINCL IP_TOS IP_TTL IP_RECVOPTS
IP_RECVRETOPTS IP_RETOPTS
+ IPV6_ADD_MEMBERSHIP IPV6_DROP_MEMBERSHIP IPV6_MTU
+ IPV6_MTU_DISCOVER IPV6_MULTICAST_HOPS IPV6_MULTICAST_IF
+ IPV6_MULTICAST_LOOP IPV6_UNICAST_HOPS IPV6_V6ONLY
MSG_BCAST MSG_BTAG MSG_CTLFLAGS MSG_CTLIGNORE MSG_DONTWAIT
MSG_EOF MSG_EOR MSG_ERRQUEUE MSG_ETAG MSG_FIN
MSG_MAXIOVLEN MSG_MCAST MSG_NOSIGNAL MSG_RST MSG_SYN
diff --git a/ext/Socket/Socket.pm b/ext/Socket/Socket.pm
index 9ba10bfb82..930b78be16 100644
--- a/ext/Socket/Socket.pm
+++ b/ext/Socket/Socket.pm
@@ -3,7 +3,7 @@ package Socket;
use strict;
our($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
-$VERSION = "1.94_01";
+$VERSION = "1.94_02";
=head1 NAME
@@ -305,6 +305,21 @@ names will be plain strings.
=back
+=over 8
+
+=item pack_ipv6_mreq IP6_MULTIADDR, INTERFACE
+
+Takes an IPv6 address and an interface number. Returns the ipv6_mreq structure
+with those arguments packed in. Suitable for use with the
+C<IPV6_ADD_MEMBERSHIP> and C<IPV6_DROP_MEMBERSHIP> sockopts.
+
+=item unpack_ipv6_mreq IPV6_MREQ
+
+Takes an ipv6_mreq structure and returns a list of two elements; the IPv6
+address and an interface number.
+
+=back
+
=cut
use Carp;
@@ -486,6 +501,9 @@ require XSLoader;
getaddrinfo
getnameinfo
+ pack_ipv6_mreq
+ unpack_ipv6_mreq
+
IN6ADDR_ANY IN6ADDR_LOOPBACK
AI_CANONNAME
@@ -510,6 +528,16 @@ require XSLoader;
IPPROTO_TCP
IPPROTO_UDP
+ IPV6_ADD_MEMBERSHIP
+ IPV6_DROP_MEMBERSHIP
+ IPV6_MTU
+ IPV6_MTU_DISCOVER
+ IPV6_MULTICAST_HOPS
+ IPV6_MULTICAST_IF
+ IPV6_MULTICAST_LOOP
+ IPV6_UNICAST_HOPS
+ IPV6_V6ONLY
+
NI_DGRAM
NI_NAMEREQD
NI_NUMERICHOST
diff --git a/ext/Socket/Socket.xs b/ext/Socket/Socket.xs
index 8bcfa0f476..2c67c3a381 100644
--- a/ext/Socket/Socket.xs
+++ b/ext/Socket/Socket.xs
@@ -798,3 +798,50 @@ inet_pton(af, host)
#else
ST(0) = (SV *)not_here("inet_pton");
#endif
+
+void
+pack_ipv6_mreq(addr, interface)
+ SV * addr
+ unsigned int interface
+ CODE:
+ {
+#ifdef AF_INET6
+ struct ipv6_mreq mreq;
+ char * addrbytes;
+ STRLEN addrlen;
+ if (DO_UTF8(addr) && !sv_utf8_downgrade(addr, 1))
+ croak("Wide character in %s", "Socket::pack_ipv6_mreq");
+ addrbytes = SvPVbyte(addr, addrlen);
+ if(addrlen != sizeof(mreq.ipv6mr_multiaddr))
+ croak("Bad arg length %s, length is %d, should be %d",
+ "Socket::pack_ipv6_mreq", addrlen, sizeof(mreq.ipv6mr_multiaddr));
+ Zero(&mreq, sizeof(mreq), char);
+ Copy(addrbytes, &mreq.ipv6mr_multiaddr, sizeof(mreq.ipv6mr_multiaddr), char);
+ mreq.ipv6mr_interface = interface;
+ ST(0) = newSVpvn_flags((char *)&mreq, sizeof(mreq), SVs_TEMP);
+#else
+ ST(0) = (SV*)not_here("pack_ipv6_mreq");
+#endif
+ }
+
+void
+unpack_ipv6_mreq(mreq_sv)
+ SV * mreq_sv
+ PPCODE:
+ {
+#ifdef AF_INET6
+ struct ipv6_mreq mreq;
+ STRLEN mreqlen;
+ char * mreqbytes = SvPVbyte(mreq_sv, mreqlen);
+ if (mreqlen != sizeof(mreq))
+ croak("Bad arg length for %s, length is %d, should be %d",
+ "Socket::unpack_ipv6_mreq",
+ mreqlen, sizeof(mreq));
+ Copy(mreqbytes, &mreq, sizeof(mreq), char);
+ EXTEND(SP, 2);
+ mPUSHp((char *)&mreq.ipv6mr_multiaddr, sizeof(mreq.ipv6mr_multiaddr));
+ mPUSHi(mreq.ipv6mr_interface);
+#else
+ not_here("unpack_ipv6_mreq");
+#endif
+ }