My Hackergotchi

Updated: Never — Philip's Blog

Now featuring regular updates!

Thu, 22 Oct 2009

11:33 – Fixing strange DHCP behaviour

Someone -- I thought it was Kristof, but he claims not to have this problem so it must be someone else -- told me a while ago that Telenet's DHCP server "exhibits weird behaviour". That sort of mystery certainly gets the hyperactive mind interested.

For totally unrelated reasons, I found myself looking at a packet capture of DHCP traffic on a Telenet connection. Indeed, there was something very strange in there. The DHCP client would get a perfectly fine lease with perfectly reasonably renewing and rebinding times. When the renewing timer (T1) expired, the client would unicast a DHCPREQEST to the server and expect a unicast DHCPACK back. Only the DHCPACK would never arrive, and the client would retransmit the unicast DHCPREQUEST messages until the rebinding timer (T2) expired. At that time, the client would broadcast a DHCPREQUEST after which the DHCPACK would arrive.

The fact that the DHCPACK messages came through the DHCP relay server put me on a side-track briefly. I discovered that the DHCP server (mentioned in option 54) would not respond to my DHCP requests. While it makes perfect sense to protect a DHCP server from clients, you do want your clients to be able to get packets to them somehow.

I sent some packet captures to a contact inside Telenet (thanks ;-) I couldn't imagine trying to explain this to a helldesk!) wondering if they'd put too sharp an access control list between me and the DHCP server (recently -- because I hadn't seen the problem before). After some digging, they found that I was sending my unicast DHCPREQUEST messages with a random source port number. From my reading of the RFC, this is "allowed", but no one else does it. It turns out that Telenet does some sanity checking (sensible precaution) on DHCP messages before allowing them to go to the DHCP server. This sanity checking does not like (or recognize, presumably) DHCP messages with a source port other than bootpc (68).

FreeBSD's dhclient is a rather old version of ISC's reference implementation, simplified by OpenBSD. I found that OpenBSD has had a patch for a couple of years that purported to fix this behaviour. When I ported this patch to FreeBSD however, I found that sendmsg would return EINVAL, which was not documented to ever happen.

Again I wondered how people without source code to their operating systems get through the day? Do they resort to alcohol and panic at this stage? I used DDB to set a breakpoint on sendmsg and stepped through briefly, expecting it to blow up somewhere quickly when copying in the iovec or so. No such luck however, and I found myself in sosend_generic, which is not so much fun to step through without symbol information, so I set up remote debugging so I could use ddd.

Eventually, I found my way to rip_output and found that my EINVAL came from here:

if (((ip->ip_hl != (sizeof (*ip) >> 2)) && inp->inp_options)
    || (ip->ip_len > m->m_pkthdr.len)
    || (ip->ip_len < (ip->ip_hl << 2))) {
        INP_RUNLOCK(inp);
        m_freem(m);
        return (EINVAL);
}

Oh dear...:

(gdb) p m->M_dat.MH.MH_pkthdr.len
$6 = 328
(gdb) p ip->ip_len
$7 = 18433

Obviously (to the trained -- or strained -- eye which sees this kind of thing often), 18433 and 328 are strikingly similar. Indeed - it helps if you put the bytes in the right order!

For hysterical raisins, the raw socket interface on BSD-derived network stacks expects the ip_len field of the IP header included when IP_HDRINCL is sent to be in host byte order. dhclient used to only send packets with headers through the BPF, which will put the packet on the wire exactly as given (ie: the ip_len needs to be in the right order). For reasons which don't seem to be explained in CVS history, OpenBSD decided to change this behaviour in their network stack (making it differ from every other network stack and many books written about sockets).

To make a very long story short: I committed revision 198352 to make dhclient on FreeBSD work in networks which put sharp teeth between DHCP clients and servers. Debugging the problem also kept me out of trouble for a couple of hours.

I'm told that finding the cause of weird errors in the protocol stack is now significantly easier with DTrace. I will have to find some time to play with that. While ddd "works", it's not exactly the most pleasant tool to work with.

Entirely aside: I'm still not convinced that "sharp teeth" should care about the source port of unicast DHCPREQUEST messages, but I'm happy to accept that if everyone uses port 68, there's no reason to gratuitously differ from that. Thanks to the Telenetists for helping me look into this.

Wed, 14 Oct 2009

14:46 – Android Bluetooth "tethering"

[I had never heard of the word "tethering" in this context until I started fiddling with this. Who came up with that silly word?]

After spending an inordinate amount of time getting my contacts into my HTC Hero phone without sharing the contact details of everyone I know with Google, I now want to start doing other useful things with it. Like reading my email.

Unlike "web 2.0" denizens, I'm not prepared to put my brain through a blender or take other drastic measures to reduce its functionality to convince myself that a tiny touchscreen interface is a good way to read email, let alone try to force email through a webserver or a crippled IMAP client. I have a lot of email and a perfectly functional mail client running in a screen somewhere reliable to get to it.

It's been a while since I had to pair a new device with my laptop and I discovered that the dbus-damaged Linux Bluetooth stack has become even more broken of late. It now requires me to run an undocumented bluetooth-agent application, which takes my pin in argv where it can conveniently be seen by anyone else who happens to be using my machine (which is no one, but still, you wonder what kind of people design software like this).

When I finally got the HTC Hero paired with my laptop, I discovered that its Bluetooth stack is more than a little handicapped:

[635] (luggage:/home/philip)# sdptool records 00:23:D4:xx:xx:xx
Service Name: Voice gateway
Service RecHandle: 0x10000
Service Class ID List:
  "Handsfree Audio Gateway" (0x111f)
  "Generic Audio" (0x1203)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 1
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "Handsfree" (0x111e)
    Version: 0x0105

Failed to connect to SDP server on 00:23:D4:xx:xx:xx: Connection refused

Note the conspicuous absense of "Dialup Networking" (0x1103).

How can they sell a (very expensive) "smart phone" in 2009 which doesn't even support the very basics of Bluetooth? I have a feeling they may be running the same tooth-decaying Bluetooth stack as my laptop. How very disingenious.

Time to void my warranty and figure out how to fix this.

Frustration.

Tue, 13 Oct 2009

14:30 – Carry-on or not

Spending way too much time on airplanes, I can very much relate to this comic:

Carry-on

sigh

Sun, 11 Oct 2009

17:14 – Import contacts to Android?

I gave in and bought an HTC Hero phone this weekend. Everyone I know seems to be lyrical about it. It seems capable of making phone calls and all the features one would expect from a "smart" phone are there.

I am a bit disturbed by the amount of data the phone seems to want to share with Google though. So far, I have not been able to find a way of importing my contacts without going through GMail (which I don't use), short of typing them in by hand - an error-prone process I'm not willing to try. The phone does not appear to support vcard-over-bluetooth.

None of the people who have given me their phone number have allowed me to share this data with Google and I would prefer not to ask all of them.

So, dear Lazyweb: how do I import approximately 300 phone numbers into this Hero contraption?