Home ........ Blog ........ Travels ........ Software ........ Web 3D ........ LinkedIn

Monday, November 11, 2013

Fifth Annual RI 6 Hour Ultramarathon

On Sunday, November 10, 2013, I ran in the fifth annual RI 6 Hour Ultramarathon. My goal - as in past years, was to do at least as well as I did the previous year.

The official results place me 11/93 with an official total mileage of 40.515 miles in 5:57:28.1.

The table below documents my miles and times (by my watch).

RI 6 Hour Ultramarathon: November 10, 2013
Lap SplitCumm.
Lap PaceAvg. Pace

Friday, November 01, 2013

Trick or Treat - KitKat Halloween Candy

I didn't get a new Nexus 5, nor do I have Android KitKat 4.4 on my Samsung Galaxy S3. However, others have managed to get the APK's for some new Google apps off the Nexus 5. I didn't venture to load the Google Experience Launcher - I use Nova Launcher Prime in favor of standard Samsung TouchWiz. But I did have to test drive the new Hangouts app - now with integrated SMS.

At this point, the Play store did not have the updated Hangouts v2 (only version 1.2 which I had loaded). I grabbed the APK, did the standard side-load procedure through ES File Explorer and tested it out.

At first startup, it notified me that it can handle SMS and asked if I wanted to enable it. Hell yes! And 'BAM', there it was - all my existing SMS threads showing up (including MMS messages) in the Hangouts interface. I tested with some texting to/from the phone and received messages in both the Hangouts app and the default messaging app - as I expected (they're pulling data from the same store).

I did not get the standard messaging app notifications when texts arrived - only the Hangouts notification in the notification bar - excellent! So no double notifications, but message counts is the only thing missing. As I mentioned, I use Nova Launcher - more specifically, TeslaUnread - to put the unread count overlay on things like GMail and messaging. It never worked for MMS messages, and now it doesn't work for SMS either. No unread count overlaying the Hangouts icon in my dock. Not to worry, with the notification bar working, I'm sure I won't miss any texts.

So even though no KitKat (bars or software) were received for Halloween, I still did get a treat! Now just waiting on Google Voice VoIP calling so I don't have to use Talkatone.

Monday, October 14, 2013

I've Been Busy ... Box

I recently had a client where I did some wireless scanning and aside from the heavy PC tools, I used Wifi Analyzer on my Android phone. It's a nifty little tool, but didn't always show the detailed information I wanted. So I also installed Network Info II to get the detailed network information.

What I thought would be really helpful would be a terminal to access the Unix command line and I found that with Android Terminal Emulator. While a stellar app that provides a direct command line interface, it relies on the system installed commands - so we have some file manipulation tools (e.g., ls, cd, cat). It does not provide text manipulation tools (e.g., awk, cut, grep) and handy networking tools (e.g., nc, telnet, ssh). For that, you need to install busybox.

A lot of searching indicated most busybox installations for Android required root and I did not root my phone. This seemed odd since once installed, most command line utilities don't need root to run (except things like 'ping' which only required suid). I finally found some instructions to install a "non-root" busybox and tried it. I'm not linking to it because it only partially worked - the network tools couldn't perform name resolution; a partial success.

The solution I used was BusyBox Non-Root. This little application installs busybox, creates the necessary symlinks and provides a shortcut to copy/paste the install directory into a Unix $PATH statement. You can paste that into the "Initial command" under "Preferences" in the Android Terminal Emulation app. Now, from a command line I have access to working versions of 'nslookup', 'telnet', 'ssh' and many other text manipulation tools.

The only puzzling thing I found was netcat (nc) wasn't available. Running buxybox from the command line showed that 'nc' was available in the package, so a quick 'ln -s ./busybox ./nc' solved that problem. Of course I tested it and 'nc' works too!

Wednesday, October 09, 2013

A Window into porting BGPDump

After reading about injecting BGP prefixes into a GNS3 simulation, I was eager to test it. I went looking for BGPDump and found it was only available for Linux. The source files made no mention of building on Win32.

I've ported Linux "only" - that is, source that provides no Win32-specific directives, code and / or headers - to Windows by editing the source. Network applications - those that use the Linux network headers and the Winsock headers in Windows - are much more difficult. I wasn't going to try this one. I figured I could compile under Cygwin and just have the cygwin1.dll dependency.

I don't normally run Cygwin; instead, I use the Win32 native ports found at GnuWin32. I have them all in my C:\usr\bin directory - the first in my PATH - and also a copy of the cygwin1.dll in that directory for the few programs that need it (namely iperf.exe - again built under Cygwin due to the complex network headers and porting issues).

So I used my Windows Virtual PC that has Cygwin installed, downloaded the latest copy of BGPDump (version / 21-Oct-2010 11:30 / 82K) and set to compiling it. The './configure' step went well. The 'make' not so much. I was missing some libraries, but the error messages were pretty obvious which ones were needed so I quickly re-ran the Cygwin setup - which also functions as a package manager - and installed the missing development libraries. Namely:

  • libzip-devel
  • libbz2-devel

I re-ran the build process and was done! I copied my C:\cygwin\bin\cygwin1.dll to the build directory and ran bgpdump.exe and it failed! Because it linked with those compression libraries, I also needed those DLL's as well as the libc DLL for Cygwin (cyggcc_s-1.dll). This was going to require an extra step. I needed to statically link the compression and libc libraries so the only dynamic dependency would be cygwin1.dll.

Looking at the 'make' output, I simply needed to modify the last build instruction from:

gcc -fPIC -g -O3 -Wall -Wsystem-headers -Wno-format-y2k -Wno-sign-compare -Wcast-align -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wswitch -Wshadow  -o bgpdump bgpdump.c libbgpdump.a -lbz2 -lz


gcc -fPIC -g -O3 -Wall -Wsystem-headers -Wno-format-y2k -Wno-sign-compare -Wcast-align -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wswitch -Wshadow  -o bgpdump bgpdump.c libbgpdump.a -Wl,-Bstatic -lbz2 -lz -static-libgcc

I added the "-Wl,-Bstatic" option before the compression libraries and the "-static-libgcc" option to statically link libc. I ran that command and now bgpdump.exe works with only the cygwin1.dll dependency.

Monday, October 07, 2013

Wireless Worries Washed Away

For the amount of times we have people over the house that want to use my WIFI, giving out my super-secret hidden SSID and complex security passcode isn't a hassle. But I am giving out my super-secret hidden SSID and complex security passcode! Which means these people could at any time park inconspicuously outside my house on our dead-end cul-de-sac road and steal WIFI access siphoning off precious bandwidth and accessing nefarious web sites.

Of course, I'm not really worried about that, but with DD-WRT running, I can easily set up a second visible guest network ... so why not?

There are plenty of guides out there - some better than others. I won't create my own here. I did find the DD-WRT Wiki the most useful of all the links I visited.

I used the GUI to set it up. I created the second visible guest SSID. I used the same security - this time with an easy password. I created the bridge and assigned the bridge group. I created the secondary DHCP service. I tested and all was working well.

I was a bit confused about the DHCP setup, so I'll detail that here. I followed the step to create a secondary DHCP service for the guest network under "Setup" -> "Networking" tabs in the GUI. However, they mention DNSMasq and I knew I was running the primary DHCP service (found on "Setup" -> "Basic Setup") without DNSMasq enabled.

Ultimately, I enabled DNSMasq by going to "Setup" -> "Basic Setup" and clicking the check box for "Use DNSMasq for DHCP" and then enabling DNSMasq on the "Setup" -> "Services" tab by clicking the "Enable" radio button next to "DNSMasq". I did not enter the additional DNSMaq configuration into the text box like the Wiki shows. I didn't need to. A verification from the command line proved this:

root@DD-WRT:/tmp# more dnsmasq.conf

The above DNSMasq config shows my primary LAN (lan = and the new guest LAN (br1 = set up to hand out addresses, default gateways and DNS servers.

I didn't bother with any additional iptables rules. Tests revealed I could not connect from the guest LAN to the primary LAN and vice-versa - which is what I want.

Now we just need to invite some more Internet-savvy guests over!

Tuesday, September 17, 2013

Android Update Brings IPv6

I was disappointed with AT&T not providing the Android 4.1.2 update when other US-based carriers made it available, especially since we got the 4.1.1 update pretty early. Even more disappointing was when this was finally available - around the beginning of August - my device never upgraded. A Google search the other night showed it was available and when I manually checked for updates - sure enough, it was.

I will say I'm pleased with the update. Multiwindow is pretty cool even if not standard. It doesn't support all apps - and even some common ones I use that would be nice to use in multiwindow mode - like Google Keep.

The best part is that IPv6 now seems to work! At least over WIFI. I have IPv6 running at home and was (again) disappointed when my wife's iPad and iPhone could get to IPv6 sites and my Android couldn't. But after the update, I tried What Is My IPv6 Address from my Android and got an IPv6 address back (you'll see your IPv4 address if IPv6 isn't working)! I confirmed with my favorite IPv6-only site Loops of Zen.

Monday, September 16, 2013

Reach the Beach Relay - 2013

This year was a bit different. We only had 6 people, but only 2 of those 6 (Ashley and I) were willing to do the ultra. So we opted for a "half-team" option where RTB matched us with 6 people in a similar situation. As always, it was an adventure. We started counting and recording "pieces of flair" (i.e., "road kills") - number of people passed while running.

Massakruliks - Half Team

197/474 - 5/8

Distance Difficulty Gain Loss Net Flair Time Pace
Leg 8 6.61 Moderate 101 125 -24 +9 43:30 6:35
Leg 20 6.83 Hard 725 826 -101 +23 45:20 6:38
Leg 32 6.69 Moderate 324 413 -89 +15 45:55 6:52
20.13 +47 2:14:45 6:42

Monday, June 03, 2013

IPv6 to IPv4 Server Load Balancing Testing in GNS3

My last post talked about testing IPv4 / IPv6 web and proxy services using Qemu in GNS3. My next challenge was to understand the "easy" way to IPv6-enable an IPv4-only web site - configure your load balancer to do it.

The simple explanation for Server Load Balancing IPv6 to IPv4 (SLB64) is that it performs traditional server load balancing functions but additionally does address family translation from the requested IPv6 address to the real IPv4 address of the internal servers in the server farm.

I don't have a big name load balancer at my disposal nor does my laptop have the power needed to download a virtual image and spin up VMware connected to my GNS3 simulation. So I went looking for a linux software based alternative and found HAProxy. The site indicates IPv6 support came along in version 1.1 and of course there is a Tiny Core linux package available. That meant following the Qemu "installation" procedure I described in a previous post and doing the proper 'filetool' backup.

My lab looks like the following, including an Apache web server running on Qemu in GNS3 as described in the last post:

IPV6 = 2001:db8
IPV6:192:168::254  IPV6:192:168::1
     HOST      ------    R1    ------   Web Server

The HAProxy package didn't come with a configuration or startup script, so I had to create them. First, the configuration file was pretty simple to create in /usr/local/etc/haproxy.conf:

  user tc
  group staff
  mode tcp
  retries 3
  timeout connect 5000
  timeout client 50000
  timeout server 50000
listen ipv6proxy80 :::80
  server ipv4server80

A little translation: the 'global' and 'default' headings just set some standard parameters for HAProxy operation. The 'listen' heading is where I tell HAProxy to listen for all incoming IPv6 traffic to TCP port 80 (TCP comes from the 'mode tcp' command in the 'defaults' section). HAProxy should then distribute matched traffic to the listed servers - in this case only on port 80. Listening on IPv6 and distributing to an IPv4 server causes HAProxy to do the address family translation from IPv6 to IPv4. Note that you can make this configuration much more secure and/or selective, but this is perfect for my little test.

Next, the startup script in /etc/init.d/services/loadbal:

case "${1}" in
    /usr/local/sbin/haproxy -f /usr/local/etc/haproxy.conf -p /var/run/haproxy.pid -D
    pkill haproxy
    pidof haproxy
    exit 1

HAProxy is now started with "sudo /etc/init.d/services/loadbal start".

To test we need to remember that HAProxy is our load balancer and thus is advertising the "outside" (read: Internet) address of the web server. So on the HOST, I open a browser and point it to:


SUCCESS! I get the home page from the Apache web server complete with the link to the CGI script to print my environment variables as described in my last post. That certainly comes in handy to see where the web server thinks the connection is coming from as does a 'netstat -an' on the HAProxy Qemu linux console.

Thursday, May 30, 2013

IPv4 / IPv6 Web and Proxy Server Testing in GNS3

In a previous post, I described how I got some additional packages installed on Tiny Core linux to use with Qemu in my GNS3 simulations. While that post describes how I got a DHCPv6 client loaded on my Tiny Core image, at the time I also loaded Apache. This gave me an IPv4 / IPv6 web server to test with. Additionally, Apache can be run as a proxy server, so I could test IPv4 / IPv6 proxy services with the single Apache install.

The first step was to create a configuration file for both web server and proxy. The default is installed in /usr/local/apache2/conf/httpd.conf and is suitable for the web server configuration. I copied that file to /usr/local/apache2/conf/proxy.conf and edited it. I kept only the "LoadModule" commands and then added:

ServerRoot "/usr/local/apache2"
listen 8080
User tc
Group staff
ProxyRequests On

You can get fancier, but that's all you really need for testing in a closed GNS3 lab environment.

Next, a nice home page on the web server that automatically displays some information would be nice. Printing environment variables like client IP address and server IP address will come in handy when testing through a proxy server to see what address (IPv4 or IPv6, client or proxy server) the "world" will see. Thankfully, the default install has this file. Unfortunately, it didn't work for me.

I had a permission issue and since the CGI script was really a link to the file, I couldn't change the permissions. Easy solution was to simply copy the file to the CGI bin directory and make the appropriate edits.

So first I need an index.html in /usr/local/apache2/htdocs. That looks like this:

<h1>It works!</h1>
<a href = "cgi-bin/test-cgi-new">Environment</a>

Next, the actual /usr/local/apache2/cgi-bin/test-cgi-new script is create with:

cd /usr/local/apache2/cgi-bin
cp ./test-cgi ./test-cgi-new
chown tc test-cgi-new
chgrp staff test-cgi-new
chmod 755 test-cgi-new

Finally, a startup script for both web server and proxy server in /etc/init.d/services:


case "${1}" in
    pkill httpd
    pidof httpd
    exit 1


case "${1}" in
    /usr/local/apache2/bin/httpd -f /usr/local/apache2/conf/proxy.conf
    pkill httpd
    pidof httpd
    exit 1

Now I can start them with "sudo /etc/init.d/services/httpd start" and "sudo /etc/init.d/services/proxy start".

Of course, make sure you do this on Qemu outside of GNS3 and save your configurations by editing the appropriate "/opt/.filetool.lst" file and running "filetool" to backup as described in the previous post.

Then, I created a simple GNS3 lab with a router in the middle. I made one connection bridged to my host machine (loopback interface) and added some routes on the host to point towards the simulation networks. I made another router connection to one instance of Qemu where I run the proxy service. The final router connection goes to another instance of Qemu where I run the web server. Now I can test from my host browser on IPv4 and IPv6 to the test web server and I can also configure the simulation proxy server on my host to test out IPv4 / IPv6 proxy services to the web server in the simulation.

Next, I'll describe how I setup and tested Server Load Balancing 6 to 4 (SLB64) with HAProxy.

Tuesday, April 02, 2013

Open Source and Closed Protocols

There isn't a better way to learn a protocol for me than reading the RFC and watching Wireshark captures and decodes. However, it becomes difficult when we're talking about a closed proprietary protocol.

Recently, I've been creating new protocol modules for the Net::Frame Perl module suite. Hot Standby Router Protocol (HSRP) is a Cisco proprietary protocol but is detailed in RFC 2281. However, that's only version 1. Version 2 isn't in an open RFC. Another example is Cisco Discovery Protocol (CDP) which has no RFC for version 1 or version 2. Luckily, there is plenty of information on the Internet.

I couldn't get all the information for all the CDP message types, but I'm about 90% there. A more interesting note was in the CDP header itself. There is a checksum that's described as the "normal Internet checksum". However, when I implemented that in a Net::Frame::Layer::CDP module, it didn't work. What was the problem?

A Google search lead me to the source code for Wireshark and a file called packet-cdp.c. A comment beginning on line 230 explains:

"CDP doesn't adhere to RFC 1071 section 2. (B). It incorrectly assumes checksums are calculated on a big endian platform, therefore i.s.o. padding odd sized data with a zero byte _at the end_ it sets the last big endian _word_ to contain the last network _octet_. This byteswap has to be done on the last octet of network data before feeding it to the Internet checksum routine. CDP checksumming code has a bug in the addition of this last _word_ as a signed number into the long word intermediate checksum. When reducing this long to word size checksum an off-by-one error can be made. This off-by-one error is compensated for in the last _word_ of the network data."

That meant I needed some "massaging" of my payload before sending to my Internet checksum routine. A quick proof of concept proved correct and then some solicitation for simplification produced this:


   if (length( $payload )%2) {
      if (substr($payload, -1) ge "\x80") {
         substr $payload, -1, 1, chr(ord(substr $payload, -1) - 1);
         substr $payload, -1, 0, "\xff";
      } else {
         substr $payload, -1, 0, "\0";



I also found a very long thread in a mailing list archive that describes how some smart guys found this problem and came up with the Wireshark solution. Thanks for open source - even on closed protocols!

Tuesday, March 05, 2013

Thinking Outside the "Package" for Packets

I responded to a query on a community forum for Perl about creating a DNS update with a spoofed source address. I was ASSURED it was for a contest and the code was what was essential. The contest site recommended scapy, but the poster was looking for a Perl solution. I had the easy answer: Perl Packet Crafter.

The poster went on to detail some code that created the DNS update but when he sent the packet, he couldn't change the source IP address. Obviously. He used Net::DNS as follows:

use strict;
use warnings;
use Net::DNS;

my $update = Net::DNS::Update->new('evil.zz');
$update->push(prerequisite => nxrrset('hacker11.evil.zz. A'));
$update->push(update => rr_add('hacker11.evil.zz. 86400 A'));

my $res = Net::DNS::Resolver->new;

my $reply = $res->send($update);

The last line sends the update by taking the created DNS data and letting standard socket routines create the Layer 3 header. Perl Packet Crafter (PPC) can create the custom Layer 3 header and with Net::Frame::Layer::DNS (which I wrote), one can easily create the required packet. However, with most of the work done, is it necessary to recode the original script using Net::Frame::Layer::DNS? Turns out ... no.

Because of the layered nature of the Net::Frame suite of modules on which PPC is based, one can easily create any or all layers of a frame with the objects or simply by hand crafting an octet stream. Or ... even using another Perl module that can output the required stream.

For Net::DNS, there is an undocumented sub called make_query_packet() in the Net::DNS::Resolver::Base code that creates a Net::DNS::Packet object on which the data() method can be called to create the necessary octet stream. It may sound complicated, but all it means is replace the last line of code above with:

$dnsdata = $res->make_query_packet($update);

Now, in PPC, you can use the $dnsdata->data call to create the DNS payload in a UDP packet. It looks like the following:

VinsWorldcom@C:\tmp\> ppc.pl -i "Wireless Network Connection"
Welcome to Perl Packet Crafter (PPC)
Copyright (C) Michael Vincent 2012

Wireless Network Connection

ppc> use Net::DNS;
ppc> $update = Net::DNS::Update->new('evil.zz');
ppc> $update->push(prerequisite => nxrrset('hacker11.evil.zz. A'));
ppc> $update->push(update => rr_add('hacker11.evil.zz. 86400 A'));
ppc> $res = Net::DNS::Resolver->new;
ppc> $res->nameservers('');
ppc> $dnsdata = $res->make_query_packet($update);

We've used PPC to enter the original code with the modified last line - instead of send, use the make_query_packet() routine to create the Net::DNS::Packet object. Continuing, we create the packet in PPC:

ppc> $ether = ETHER;
ppc> $ipv4 = IPv4(src=>'',dst=>'',protocol=>NF_I+Pv4_PROTOCOL_UDP);
ppc> $udp = UDP(dst=>53,payload=>$dnsdata->data);
ppc> $packet = packet $ether,$ipv4,$udp;

And to be sure before we send it, we can use Net::Frame::Layer::DNS for a nice decode:

ppc> use Net::Frame::Layer::DNS qw(:consts);
ppc> decode $packet;
ETH: dst:55:66:88:78:aa:30  src:c0:c1:c2:08:46:56  type:0x0800
IPv4: version:4  hlen:5  tos:0x00  length:90  id:23417
IPv4: flags:0x00  offset:0  ttl:128  protocol:0x11  checksum:0x53fe
IPv4: src:  dst:
UDP: src:50281  dst:53  length:70  checksum:0x5661
DNS: id:5329  qr:0  opcode:5  flags:0x00  rcode:0
DNS: qdCount:1  anCount:1
DNS: nsCount:1  arCount:0
DNS::Question: name:evil.zz
DNS::Question: type:6  class:1
DNS::RR: name:hacker11.[@12(evil.zz)]
DNS::RR: type:1  class:254  ttl:0  rdlength:0
DNS::RR: name:[@25(hacker11.[@12(evil.zz)])]
DNS::RR: type:1  class:1  ttl:86400  rdlength:4
DNS::RR::A: address:

Job done!

Note this can also be done with other Perl modules like Net::DHCP::Packet with the new() and serialize() calls, for example.

Friday, March 01, 2013

Blog about NOT Logging

A question came across a mailing list I subscribe to about limiting the syslog messages sent from a Cisco router to a syslog server. The question arose since a certain Cisco blade switch has a known bug where it reports the redundant power supply is faulty even though it doesn't have one. The message - sent every 5 minutes - was becoming quite bother to the operations folks since there were 80 such devices all reporting the erroneous error.

The asker had already found the 'logging discriminator ...' command, but couldn't apply it. A quick test in Dynamips and I had the answer for him.

The 'discriminator' option as we applied it looked for a regular expression in the syslog message body and was configured to "drop" the message (not send it to the syslog server). It worked with the following configuration:

logging discriminator NOREPORT msg-body drops "Redundant power supply faulty or in standby mode"
logging host discriminator NOREPORT

Satisfied we had a working fix, it was time for some more investigation.

I've selectively enabled SNMP traps with the 'snmp-server enable traps XXX' commands, but I didn't know it was possible with syslog messages - I never really tried to be honest. In fact, all logging is enabled with a simple command:


There are options for which facility or severity to send, but not many options for creative tuning - they're all of certain class or nothing. The 'discriminator' option seemed pretty useful. However ...

The 'discriminator NAME' doesn't work like an access-list where you can add multiple lines. You get one (1) discriminator and you get one (1) time to apply it to the syslog host. So how long can the regular expression be? Not very - as soon as I started to get fancy with the regular expression to block multiple messages, I got errors:

R1(config)#$msg-body drops "((Configured from)|(Interface         ))"
R1(config)#$msg-body drops "((Configured from)|(Interface          ))"
% unmatched ()

With the grouping parenthesis and the logical or vertical bar (pipe), I could only get a maximum of 38 characters. When I tried 39, I started getting the "unmatched" error and looking at the 'show run', my configuration line was truncated at 38 characters:

R1(config)#do sh run | i logg
logging discriminator NOREPORT msg-body drops ((Configured from)|(Interface          )

Notice the last parenthesis is left off (should be two of them). This severely limits the creativity when trying to selectively block syslog messages. There are other alternatives, like 'mnemonic' which will block an entire category of syslog messages by regular expression. So less characters to fit within the 38, but entire classes of messages dropped.

Maybe there's a better way?

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.


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


    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.