#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" #include #include #ifdef WIN32 // winsock.h is for winsock <= 1.1 // #include // ws2tcpip.h is for winsock >= 2.0 #include #endif #include "const-c.inc" MODULE = Socket::Multicast6 PACKAGE = Socket::Multicast6 INCLUDE: const-xs.inc PROTOTYPES: ENABLE void pack_ip_mreq(imr_multiaddr_sv, imr_interface_sv) SV* imr_multiaddr_sv SV* imr_interface_sv CODE: { struct ip_mreq mreq; STRLEN addrlen; char * addr; // Clear out final struct Zero( &mreq, 1, struct ip_mreq ); // Byte load multicast address addr = SvPVbyte(imr_multiaddr_sv, addrlen); if (addrlen == sizeof(mreq.imr_multiaddr) || addrlen == 4) // Copy across the multicast address Copy( addr, &mreq.imr_multiaddr, 1, struct in_addr ); else croak("Bad arg length for %s, length is %d, should be %d", "Socket::Multicast6::pack_ip_mreq", addrlen, sizeof(mreq.imr_multiaddr)); // Byte load interface address addr = SvPVbyte(imr_interface_sv, addrlen); if (addrlen == sizeof(mreq.imr_interface) || addrlen == 4) // Copy across the interface address Copy( addr, &mreq.imr_interface, 1, struct in_addr ); else croak("Bad arg length for %s, length is %d, should be %d", "Socket::Multicast6::pack_ip_mreq", addrlen, sizeof(mreq.imr_interface)); // new mortal string, return it. ST(0) = sv_2mortal(newSVpvn((char *)&mreq, sizeof(mreq))); } void pack_ip_mreq_source(imr_multiaddr_sv, imr_source_sv, imr_interface_sv) SV* imr_multiaddr_sv SV* imr_source_sv SV* imr_interface_sv CODE: { #ifdef IP_ADD_SOURCE_MEMBERSHIP struct ip_mreq_source mreq; STRLEN addrlen; char * addr; // Clear out final struct Zero( &mreq, 1, struct ip_mreq_source ); // Byte load multicast address addr = SvPVbyte(imr_multiaddr_sv, addrlen); if (addrlen == sizeof(mreq.imr_multiaddr) || addrlen == 4) // Copy across the multicast address Copy( addr, &mreq.imr_multiaddr, 1, struct in_addr ); else croak("Bad arg length for %s, length is %d, should be %d", "Socket::Multicast6::ip_mreq_source", addrlen, sizeof(mreq.imr_multiaddr)); // Byte load source address addr = SvPVbyte(imr_source_sv, addrlen); if (addrlen == sizeof(mreq.imr_sourceaddr) || addrlen == 4) // Copy across the source address Copy( addr, &mreq.imr_sourceaddr, 1, struct in_addr ); else croak("Bad arg length for %s, length is %d, should be %d", "Socket::Multicast6::ip_mreq_source", addrlen, sizeof(mreq.imr_sourceaddr)); // Byte load interface address addr = SvPVbyte(imr_interface_sv, addrlen); if (addrlen == sizeof(mreq.imr_interface) || addrlen == 4) // Copy across the interface address Copy( addr, &mreq.imr_interface, 1, struct in_addr ); else croak("Bad arg length for %s, length is %d, should be %d", "Socket::Multicast6::ip_mreq_source", addrlen, sizeof(mreq.imr_interface)); // new mortal string, return it. ST(0) = sv_2mortal(newSVpvn((char *)&mreq, sizeof(mreq))); #else XSRETURN_UNDEF; #endif } void pack_ipv6_mreq(imr_multiaddr_sv, imr_interface_idx) SV* imr_multiaddr_sv unsigned int imr_interface_idx CODE: { struct ipv6_mreq mreq; STRLEN addrlen; char * addr; // Clear out final struct Zero( &mreq, sizeof mreq, char ); // Copy across the interface number mreq.ipv6mr_interface = imr_interface_idx; // Byte load multicast address addr = SvPVbyte(imr_multiaddr_sv, addrlen); if (addrlen == sizeof(mreq.ipv6mr_multiaddr) || addrlen == 16) // Copy accross the multicast address Copy( addr, &mreq.ipv6mr_multiaddr, 1, struct in6_addr ); else croak("Bad arg length for %s, length is %d, should be %d", "Socket::Multicast6::pack_ipv6_mreq", addrlen, sizeof(mreq.ipv6mr_multiaddr)); // new mortal string, return it. ST(0) = sv_2mortal(newSVpvn((char *)&mreq, sizeof(mreq))); }