Bonjour a la Lune

My thriftiness is deeply related to my love of the challenges involved in using minimal hardware and software to accomplish what I want, so I end up doing some strange hacks now and then.

This time I’ve been messing around with Bonjour again, but on a WRT54G3G running OpenWRT, which I use as an SSH bastion and has something like 6MB of free space after installing some tweaked kernel and packages.

Since I couldn’t fit Python into the available space I ended up writing some Lua scripts for it, and ended up needing to do some very focused packet sniffing - I wanted to check for Bonjour announcements on my home LAN and act upon them, but there was apparently no readily available package for doing so, and I decided to have a go at it in Lua.

Turns out that multicast sockets seem to be somewhat under-documented, so in case you’re looking for a way to do UDP multicast in Lua, the following script should get you on your way:

local socket = require("socket")

function hex_dump(buf)
  for i=1,math.ceil(#buf/16) * 16 do
    if (i-1) % 16 == 0 then io.write(string.format('%08X  ', i-1)) end
    io.write( i > #buf and '   ' or string.format('%02X ', buf:byte(i)) )
    if i %  8 == 0 then io.write(' ') end
    if i % 16 == 0 then io.write( buf:sub(i-16+1, i):gsub('%c','.'), '\n' ) end

udp:setsockname("", 5353)
udp:setoption("ip-multicast-loop", false)
udp:setoption("ip-add-membership", {interface="", multiaddr=""})
ip, port = udp:getsockname()
assert(ip, port)
print("Waiting for packets...")
while 1 do
  dgram, ip, port = udp:receivefrom()
  if dgram then

I’ve been meaning to do the DNS-SD parsing for a while (as well as querying for some specific services), but this is immediately useful in many regards, so I’m putting it out there instead of having it languish in my drafts for another week.

See Also: