In a previous post I talked about updating Netcat to support both IPv4 and IPv6 in a single Windows executable. I added a lot of new features including multicast listener with source specific multicast in IPv4 only.
I added source specific multicast in IPv4 only because the Winsock API did not provide the required structures for IPv6 source specific multicast in a "standard" way. Berkeley sockets did it as you'd expect by adding IPv6 complements for the existing IPv4 functions and structures.
IPv4 | IPv6 |
---|---|
ip_mreq_source | ipv6_mreq_source |
Additionally, the address family independent structures and options are also available.
I recently looked at ssmping and found they did source specific multicast for IPv6 on Windows so I decided to look at the source for guidance and revisit my Netcat.
I still irks me that instead of:
struct ip_mreq_source mreq; mreq.imr_multiaddr = *mgroup; ... mreq.imr_sourceaddr = *rad;
I have to do:
#define MCAST_JOIN_SOURCE_GROUP 45 ... GROUP_SOURCE_REQ mreq; struct sockaddr_in6 g6; g6.sin6_addr = *mgroup6; memcpy(&mreq.gsr_group, &g6, sizeof(struct sockaddr_in6)); ... g6.sin6_addr = *rad; memcpy(&mreq.gsr_source, &g6, sizeof(struct sockaddr_in6));
Moving data back and forth with pointers and addresses, changing the storage structures and those memory copies - argh.
This is why I like Perl. I'm not a programmer by trade. This memory management is hidden from me in Perl and furthermore, Perl code will work across Windows and Linux. Instead in C, I have a bunch of '#ifdef' compiler directives to determine if I'm compiling on Win32 and if I have the proper version. The IPv6 source specific multicast routines aren't available and the address family independent ones are only available on Windows Vista or later (or maybe Windows Server 2008 - the documentation is pretty confusing). Not only do I need separate code for Windows or Linux within those compiler directive branches, I also need legacy and new Windows code if the Windows version is less than Vista.
Ultimately, it works. So I am happy. And since I'm not a "real" programmer and I only do this occasionally, I deal with it - and complain on my blog! Don't even get me started on support for QoS in 'setsockopt()'. How annoying is this for people who program for a living and need to support multiple platforms?