preload
Using Word Spellcheck from Ruby Resetting the Oil Change light on a 2007 Saturn VUE
Mar 07

While doing a quick search for Ruby code that could catch and print out the Beacon packet that Tivo machines send out on the local network, I was shocked to not find anything….tons of stuff in Perl….but nothing Ruby! Unbelievable! So I went and figured out what the code would be in Ruby. Here’s what I got:

require 'socket'
require 'exo/xdump'

trap("INT") do
   puts "---[Ctrl-C: Exiting]---\n\n"
   Kernel.exit(0)
end

BasicSocket.do_not_reverse_lookup = true
s = UDPSocket.new
s.bind("0.0.0.0", 2190)

loop do
   flg = IO.select([s], nil, nil, 5)
   if flg
      text, sender = s.recvfrom_nonblock(1024)
      puts "[#{Time.now}] #{sender[3]} sent beacon packet:"
      puts "[#{Time.now}]\n#{text.hexdump}"
   end
end

Nothing too fancy. The beacon is sent out as a UDP packet to port 2190. The code looks for data on the socket, then retrieves the the data and prints it out in a hex dump format like so:

[Sun Mar 07 20:37:53 -0800 2010] 10.11.12.52 sent beacon packet:
[Sun Mar 07 20:37:53 -0800 2010]
000000: 7469 766f 636f 6e6e   6563 743d 310a 7377 |tivoconnect=1.sw|
000010: 7665 7273 696f 6e3d   392e 332e 3262 2d30 |version=9.3.2b-0|
000020: 312d 322d 3134 300a   6d65 7468 6f64 3d62 |1-2-140.method=b|
000030: 726f 6164 6361 7374   0a69 6465 6e74 6974 |roadcast.identit|
000040: 793d 3234 3030 3030   30Xx XxXx XxXx XxXx |y=2400000XXXXXXX|
000050: Xx0a 6d61 6368 696e   653d XxXx XxXx XxXx |X.machine=XXXXXX|
000060: 0a70 6c61 7466 6f72   6d3d 7463 642f 5365 |.platform=tcd/Se|
000070: 7269 6573 320a 7365   7276 6963 6573 3d54 |ries2.services=T|
000080: 6956 6f4d 6564 6961   5365 7276 6572 3a38 |iVoMediaServer:8|
000090: 302f 6874 7470 0000   0000 0000 0000 0000 |0/http.         |

The identity and the machine values have been changed just to be safe :)

A big issue that a lot of folks have with UDP sockets in Ruby is trying to get a non-blocking read working correctly. The use of the IO.select above seems to be the best answer that I’ve seen…but its still not perfect. Some folks have been trying out eventmachine (See the “Non-Blocking UDP” thread over on Ruby Forum), but for this simple test, the IO.select should work just fine.

I covered the hexdump function in a previous post.

SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon

Leave a Reply