This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Wrap some IPv6 sockopt constants and ipv6_mreq structure
authorPaul \"LeoNerd\" Evans <leonerd@leonerd.org.uk>
Thu, 13 Oct 2011 14:42:17 +0000 (15:42 +0100)
committerTony Cook <tony@develop-help.com>
Mon, 24 Oct 2011 07:39:08 +0000 (18:39 +1100)
ext/Socket/Makefile.PL
ext/Socket/Socket.pm
ext/Socket/Socket.xs

index f22a22b..8390811 100644 (file)
@@ -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
index 9ba10bf..930b78b 100644 (file)
@@ -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
index 8bcfa0f..2c67c3a 100644 (file)
@@ -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
+       }