#!/usr/bin/ruby class Unified attr_accessor :fh, :type, :endian, :record_size, :fields, :pack_header, :pack_record attr_accessor :version_minor, :version_major, :tz, :sig_flag, :snaplen, :link LOG_FIELDS = [ 'gid', 'sid', 'rev', 'classtype', 'priority', 'event_id', 'reference', 'tv_sec', 'tv_usec', 'flags', 'pkt_sec', 'pkt_usec', 'caplen', 'pktlen', 'pkt' ] ALERT_FIELDS = [ 'gid', 'sid', 'rev', 'classtype', 'priority', 'event_id', 'reference', 'tv_sec', 'tv_usec', 'tv_sec2', 'tv_usec2', 'source_ip', 'destination_ip', 'source_port', 'destination_port', 'protocol', 'flags' ] def initialize(file) self.fh = File.open("#{file}", 'r') magic = self.fh.read(4) case magic when "\x80\x10\xad\xde" self.type = 'log' self.endian = 'little' when "\xde\xad\x10\x80" self.type = 'log' self.endian = 'big' when "\x37\x41\xad\xde" self.type = 'alert' self.endian = 'little' when "\xde\xad\x41\x37" self.type = 'alert' self.endian = 'big' else raise "Invalid file (#{ magic.unpack('H*')[0]})" end case self.type when 'log' self.record_size = 14 * 4 self.pack_record = 'N14' self.pack_header = 'nnNNNN' self.fields = LOG_FIELDS when 'alert' self.record_size = (4 * 13) + (2 * 2) + (4 * 2) self.pack_record = 'N13n2N2' self.pack_header = 'NNN' self.fields = ALERT_FIELDS else raise 'invalid type' end self.header() end def fixpack(pack) if self.endian == 'little' pack.gsub!('N','V') pack.gsub!('n','v') end return pack end def header() case self.type when 'log' self.version_minor, self.version_major, self.tz, self.sig_flag, self.snaplen, self.link = self.fh.read(20).unpack(self.fixpack(self.pack_header)) when 'alert' self.version_minor, self.version_major, self.tz = self.fh.read(12).unpack(self.fixpack(self.pack_header)) else raise 'unknown header' end end def record() record = {} data = self.fh.read(self.record_size) if data.nil? || data.size != self.record_size return nil end tmp = data.unpack(self.fixpack(self.pack_record)) self.fields.each_with_index { |field, index| record[field] = tmp[index] } if record['caplen'] record['pkt'] = self.fh.read(record['caplen']) end return record end end #ARGV.each { |file| # unified = Unified.new(file) # print "FILE #{ file } #{ unified.version_major }.#{ unified.version_minor }\n" # begin # while (record = unified.record()) # print [record['sig_gen'], record['sig_id'], record['sig_rev']].join(':') + "\n" ## if record['sip'] ## p [record['sip']].pack('N').unpack('CCCC').join('.') ## end # end # rescue # end #}