Thursday, January 24, 2013

Winsock or Winsuck

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.

IPv4IPv6
ip_mreq_sourceipv6_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?

Wednesday, January 23, 2013

Testing DHCPv6: Part 2

In a previous post, I talked about getting a DHCPv6 client on a linux image to use with Qemu and GNS3. That post was mainly focused on documenting the steps to get the DHCPv6 client on the host and ultimately working. I neglected to talk about the DHCPv6 server that I configured on the Cisco router.

Of course, I was just bit by a minor configuration miss that I learned in that exercise and quickly forgot until gently reminded as I watched my DHCPv6 simulation NOT work.

The DHCPv6 server configuration on the router is pretty simple:

ipv6 dhcp pool DHCPv6
 address prefix 2001:DB8:A64:6800::/64
 dns-server 2001:4860:4860::8888
 domain-name dynamips.com

But what I forgot was that SLAAC is mandatory for IPv6 nodes and will work as long as router advertisements are present. So simply setting the M-bit in the router advertisements to force DHCPv6 is not enough. You need to NOT advertise the IPv6 prefix on the interface.

So the interface configuration looks like:

interface FastEthernet2/0
 ipv6 address 2001:DB8:A64:6800::1/64
 ipv6 enable
 ipv6 nd prefix 2001:DB8:A64:6800::/64 no-advertise
 ipv6 nd managed-config-flag
 no ipv6 redirects
 no ipv6 unreachables
 ipv6 dhcp relay destination 2001:DB8:A01:100::1

In the above example, I'm sending the DHCPv6 requests to the DHCPv6 server running on another Cisco router. I've set the M-bit and I've also stopped router advertisements of the prefix with the 'ipv6 nd prefix 2001:DB8:A64:6800::/64 no-advertise' command.

And now it works!

 

Copyright © VinsWorld. All Rights Reserved.