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 again, but on a running , which I use as an bastion and has something like 6MB of free space after installing some tweaked kernel and packages.

Since I couldn’t fit into the available space I ended up writing some scripts for it, and ended up needing to do some very focused packet sniffing - I wanted to check for 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 .

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 , 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
  end
end

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

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.