require 'pcaplet'
require 'bit-struct'
# Fake protocol I made up for this example
class CustomProtocol < BitStruct
char :header, 64, :endian => :native
unsigned :length, 8, :endian => :native
unsigned :next_hdr, 16, :endian => :little
unsigned :next_tag, 16, :endian => :network
unsigned :type, 32, :endian => :native
rest :data
end
# Capture up to 1533 bytes
sniff = Pcaplet.new('-s 1533')
# Specific pcap filter so we only grab the protocol we are dissecting
pcap_filter = Pcap::Filter.new('tcp && port 34504 && src 192.168.1.10', sniff.capture)
sniff.add_filter(pcap_filter)
for pkt in sniff
if pcap_filter =~ pkt
puts pkt
struct = CustomProtocol.new(pkt.tcp_data)
puts sprintf("ASCII Header: %s\tLength: %x\tNext Hdr: %x\tNext Tag: %x\tType: %x\tData: %s",
struct.header, struct.length, struct.next_hdr, struct.next_tag, struct.type, struct.data)
end
end
Wednesday, June 25, 2008
BitStruct is great
If you code in Ruby and do any binary parsing then you need to be using BitStruct. It makes C style structs in Ruby very easy. Sometimes you have to sniff a custom binary protocol the quick and dirty way, these are times I turn to Ruby instead of C. The Bitstruct release has some good examples of parsing network protocols but using raw sockets in Ruby is ugly. I prefer to use the LibPcap wrappers instead for the awesomeness of pcap filters.
Subscribe to:
Post Comments (Atom)
3 comments:
Neat! Looks similar in construct to its Python equivalent, dpkt:
http://code.google.com/p/dpkt/
Example of ARP module:
http://code.google.com/p/dpkt/source/browse/trunk/dpkt/arp.py
I used a lot of bit-struct early. But I kept bumping my head against variable length fields.
I ended up moving to BinData for lots of things. It's much further along in this regard.
http://bindata.rubyforge.org/
http://kenai.com/projects/ruby-ffi is usefull too
Post a Comment