#!/usr/local/bin/ruby # # == Synopsis # A Ruby HL7 Sniffer. # Uses the Pcap Module from RAA ( http://raa.ruby-lang.org/project/pcap/ ) # Uses the Ethernet.rb class from Paul Barry ( http://glasnost.itcarlow.ie/~barryp/pcap/Ethernet.rb ) # Uses ruby-hl7 by Mark Guzman ( http://hasno.info/2007/3/18/ruby-hl7-0-1-23-released ) # # == Why # To say I could do it I guess, I have needed something like this in the past, I fought with Wireshark # for awhile like this but writing a heuristic dissector would be a task for me. This is a hack. # Stripping the payload data was especially hackish... but once the msg could be passed to ruby-hl7 # as an object it was all good from there. # All kinds of uses come to mind... send to multiple endpoints off the wire, verify PHI off the wire # (or the absence of). Have fun # # == Version # .99, March 31, 2007. # # == Author # Ron Sweeney, Spectrum Health/ClubPACS Western Michigan. # # == Copyright # Copyright (c) 2007, Ron Sweeney. # Licensed under GPL v2 . # require 'pcap' require 'Ethernet' require 'rubygems' require 'ruby-hl7' def printable(str) return "" unless str str.strip.dump.gsub(/\\[0-9]/,'') end dev = Pcap.lookupdev capture = Pcap::Capture.open_live( dev ) capture.loop do |packet| eth = Ethernet.new( packet.raw_data ) if eth.payload =~ /\vMSH(.*)\r/ puts "==== HL7 Message Detected on Wire ====\n" puts "Src: #{eth.src} --=> Dest: #{eth.dest}\n" woot = printable(eth.payload.to_s) gar2 = woot.split("\\v") msg = gar2[1].split("\\r") msg.pop hl7msg = HL7::Message.new(msg) ele = hl7msg[:MSH].element_delim ite = hl7msg[:MSH].item_delim puts "Message type: %s\n" % hl7msg[:MSH].message_type puts "HL7 Version: %s\n\n" % hl7msg[:MSH].version_id hl7msg.each do |liner| puts liner #elements = liner.to_s.split(ele) #elements.each do |eleprint| #puts "\t" + eleprint end puts "\n" + "=" * 38 + "\n" end end capture.close