packetfu 1.0.3.pre → 1.0.4.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +1 -2
 - data/README +35 -3
 - data/examples/new-simple-stats.rb +51 -0
 - data/examples/simple-stats.rb +8 -0
 - data/lib/packetfu/packet.rb +6 -7
 - data/lib/packetfu/pcap.rb +100 -10
 - data/lib/packetfu/protos/tcp.rb +28 -8
 - data/lib/packetfu/structfu.rb +13 -9
 - data/lib/packetfu/version.rb +3 -2
 - data/lib/packetfu.rb +21 -14
 - data/test/icmp_test.pcap +0 -0
 - data/test/ip_test.pcap +0 -0
 - data/test/packetfu_spec.rb +6 -1
 - data/test/tcp_spec.rb +100 -0
 - data/test/tcp_test.pcap +0 -0
 - data/test/test_arp.rb +1 -1
 - data/test/test_hsrp.rb +0 -51
 - data/test/test_icmp.rb +1 -1
 - data/test/test_ip.rb +1 -1
 - data/test/test_ip6.rb +1 -1
 - data/test/test_tcp.rb +1 -1
 - data/test/test_udp.rb +1 -1
 - data/test/udp_test.pcap +0 -0
 - metadata +5 -5
 - data/CHANGES +0 -36
 - data/test/dissect_thinger.rb +0 -15
 
    
        data/.document
    CHANGED
    
    
    
        data/README
    CHANGED
    
    | 
         @@ -1,11 +1,12 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            = PacketFu
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            A library for reading a writing packets to an interface or to a libpcap-formatted file.
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            It is maintained at http://code.google.com/p/packetfu and https://github.com/todb/packetfu (which repository will win?)
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
7 
     | 
    
         
             
            == Documentation
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
            PacketFu is rdoc- 
     | 
| 
      
 9 
     | 
    
         
            +
            PacketFu is rdoc-compatible, which means it's sdoc compatible. In the same directory as this file, run "sdoc" by itself (gem install sdoc), and then view doc/index.html with your favored browser. Once that's done, navigate at the top, and read up on how to create a Packet or Capture from an interface with show_live or whatever.
         
     | 
| 
       9 
10 
     | 
    
         | 
| 
       10 
11 
     | 
    
         
             
            == Requirements
         
     | 
| 
       11 
12 
     | 
    
         | 
| 
         @@ -19,10 +20,41 @@ $ rvm gem install pcaprub 
     | 
|
| 
       19 
20 
     | 
    
         | 
| 
       20 
21 
     | 
    
         
             
            Marshall Beddoe's PcapRub is required only for packet reading and writing from a network interfaces (which is a pretty big only). PcapRub itself relies on libpcap 0.9.8 or later for packet injection. PcapRub also requires root privilieges to access the interface directly. 
         
     | 
| 
       21 
22 
     | 
    
         | 
| 
      
 23 
     | 
    
         
            +
            === Platforms
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            I tend to test with the following (with bash):
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                date > /tmp/tests.txt; for i in default 1.8.6-p420 1.8.7-p334 1.9.1-p431 1.9.2-p180 1.9.3-head
         
     | 
| 
      
 28 
     | 
    
         
            +
                do rvm use $i >> /tmp/tests.txt
         
     | 
| 
      
 29 
     | 
    
         
            +
                echo Testing with $i
         
     | 
| 
      
 30 
     | 
    
         
            +
                echo $i >> /tmp/tests.txt; echo +++++++++++++++++++++++ >> /tmp/tests.txt
         
     | 
| 
      
 31 
     | 
    
         
            +
                rvmsudo ./all_tests.rb >> /tmp/tests.txt; rspec . >> /tmp/tests.txt
         
     | 
| 
      
 32 
     | 
    
         
            +
                done
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            ==== Passing Platforms
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            * 1.9.1-p378 -- my favorite and my best
         
     | 
| 
      
 37 
     | 
    
         
            +
            * 1.8.7-p334
         
     | 
| 
      
 38 
     | 
    
         
            +
            * 1.9.2-p180
         
     | 
| 
      
 39 
     | 
    
         
            +
            * 1.9.3-head
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            ==== Problem Platforms
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            * 1.8.6-p420 -- Has problems with pcaprub and capture/inject
         
     | 
| 
      
 44 
     | 
    
         
            +
            * 1.9.1-p431 -- Has problems with loading gems in general, see http://redmine.ruby-lang.org/issues/2404
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            Technically, these are pcaprub problems and not PacketFu problems, but PacketFu should at least fail better at them.
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            Incidentally, I suspect these Ruby problems are the crux of the Mac OSX problems that people report. Try a different Ruby build and please let me know what works for you.
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
       22 
51 
     | 
    
         
             
            == Examples
         
     | 
| 
       23 
52 
     | 
    
         | 
| 
       24 
53 
     | 
    
         
             
            PacketFu ships with dozens and dozens of tests, built on Test::Unit. These should give good pointers on how you're expected to use it. See the /tests directory. Furthermore, PacketFu also ships with packetfu-shell.rb, which should be run via IRB (as root, if you intend to use your interfaces).
         
     | 
| 
       25 
54 
     | 
    
         | 
| 
       26 
55 
     | 
    
         
             
            == Author
         
     | 
| 
       27 
56 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
            PacketFu is maintained primarily by Tod Beardsley  
     | 
| 
      
 57 
     | 
    
         
            +
            PacketFu is maintained primarily by Tod Beardsley todb@planb-security.net, with help from Open Source Land.
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            See LICENSE for licensing details.
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,51 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # new-simple-stats.rb demonstrates the performance difference
         
     | 
| 
      
 4 
     | 
    
         
            +
            # between the old and busted way to parse pcap files and the
         
     | 
| 
      
 5 
     | 
    
         
            +
            # new hotness of stream parsing. Spoiler alert: Against a pcap
         
     | 
| 
      
 6 
     | 
    
         
            +
            # file of 1GB, the old way would eat all your memory and take
         
     | 
| 
      
 7 
     | 
    
         
            +
            # forever. This still takes kinda forever, but at 5000 packets
         
     | 
| 
      
 8 
     | 
    
         
            +
            # every 11 seconds (my own benchmark) for this script, at least
         
     | 
| 
      
 9 
     | 
    
         
            +
            # it doesn't hog up all your memory.
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            require 'examples' # For path setting slight-of-hand
         
     | 
| 
      
 12 
     | 
    
         
            +
            require 'packetfu'
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            def print_results(stats)
         
     | 
| 
      
 15 
     | 
    
         
            +
            	stats.each_pair { |k,v| puts "%-12s: %10d" % [k,v] }
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            # Takes a file name, parses the packets, and records the packet
         
     | 
| 
      
 19 
     | 
    
         
            +
            # type based on its PacketFu class.
         
     | 
| 
      
 20 
     | 
    
         
            +
            def count_packet_types(file)
         
     | 
| 
      
 21 
     | 
    
         
            +
            	stats = {}
         
     | 
| 
      
 22 
     | 
    
         
            +
            	count = 0
         
     | 
| 
      
 23 
     | 
    
         
            +
            	start_time = Time.now
         
     | 
| 
      
 24 
     | 
    
         
            +
            	PacketFu::PcapFile.read_packets(file) do |pkt|
         
     | 
| 
      
 25 
     | 
    
         
            +
            		kind = pkt.proto.last.to_sym
         
     | 
| 
      
 26 
     | 
    
         
            +
            		stats[kind] ? stats[kind] += 1 : stats[kind] = 1
         
     | 
| 
      
 27 
     | 
    
         
            +
            		count += 1
         
     | 
| 
      
 28 
     | 
    
         
            +
            		elapsed = (Time.now - start_time).to_i
         
     | 
| 
      
 29 
     | 
    
         
            +
            		if count % 5_000 == 0
         
     | 
| 
      
 30 
     | 
    
         
            +
            			puts "After #{count} packets (#{elapsed} seconds elapsed):"
         
     | 
| 
      
 31 
     | 
    
         
            +
            			print_results(stats)
         
     | 
| 
      
 32 
     | 
    
         
            +
            		end
         
     | 
| 
      
 33 
     | 
    
         
            +
            	end
         
     | 
| 
      
 34 
     | 
    
         
            +
            	puts "Final results for #{count} packets (#{elapsed} seconds elapsed):"
         
     | 
| 
      
 35 
     | 
    
         
            +
            	print_results(stats)
         
     | 
| 
      
 36 
     | 
    
         
            +
            end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            if File.readable?(infile = (ARGV[0] || 'in.pcap'))
         
     | 
| 
      
 39 
     | 
    
         
            +
            	title = "Packets by packet type in '#{infile}'"
         
     | 
| 
      
 40 
     | 
    
         
            +
            	puts "-" * title.size
         
     | 
| 
      
 41 
     | 
    
         
            +
            	puts title
         
     | 
| 
      
 42 
     | 
    
         
            +
            	puts "-" * title.size
         
     | 
| 
      
 43 
     | 
    
         
            +
            	count_packet_types(infile)
         
     | 
| 
      
 44 
     | 
    
         
            +
            else
         
     | 
| 
      
 45 
     | 
    
         
            +
            	raise RuntimeError, "Need an infile, like so: #{$0} in.pcap"
         
     | 
| 
      
 46 
     | 
    
         
            +
            end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
    
        data/examples/simple-stats.rb
    CHANGED
    
    | 
         @@ -3,6 +3,11 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            # Simple-stats.rb takes a pcap file, and gives some simple 
         
     | 
| 
       4 
4 
     | 
    
         
             
            # stastics on the protocols found. It's mainly used to
         
     | 
| 
       5 
5 
     | 
    
         
             
            # demonstrate a method to parse pcap files.
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            # XXX: DO NOT USE THIS METHOD TO READ PCAP FILES.
         
     | 
| 
      
 8 
     | 
    
         
            +
            #
         
     | 
| 
      
 9 
     | 
    
         
            +
            # See new-simple-stats.rb for an example of the streaming
         
     | 
| 
      
 10 
     | 
    
         
            +
            # parsing method.
         
     | 
| 
       6 
11 
     | 
    
         | 
| 
       7 
12 
     | 
    
         
             
            require 'examples' # For path setting slight-of-hand
         
     | 
| 
       8 
13 
     | 
    
         
             
            require 'packetfu'
         
     | 
| 
         @@ -12,6 +17,7 @@ require 'packetfu' 
     | 
|
| 
       12 
17 
     | 
    
         
             
            def count_packet_types(file)
         
     | 
| 
       13 
18 
     | 
    
         
             
            	file = File.open(file) {|f| f.read}
         
     | 
| 
       14 
19 
     | 
    
         
             
            	stats = {}
         
     | 
| 
      
 20 
     | 
    
         
            +
            	count = 0
         
     | 
| 
       15 
21 
     | 
    
         
             
            	pcapfile = PacketFu::PcapPackets.new
         
     | 
| 
       16 
22 
     | 
    
         
             
            	pcapfile.read(file)
         
     | 
| 
       17 
23 
     | 
    
         
             
            	pcapfile.each do |p|
         
     | 
| 
         @@ -23,6 +29,8 @@ def count_packet_types(file) 
     | 
|
| 
       23 
29 
     | 
    
         
             
            		else
         
     | 
| 
       24 
30 
     | 
    
         
             
            			stats[kind] = 0
         
     | 
| 
       25 
31 
     | 
    
         
             
            		end
         
     | 
| 
      
 32 
     | 
    
         
            +
            		count += 1
         
     | 
| 
      
 33 
     | 
    
         
            +
            		break if count >= 1_000
         
     | 
| 
       26 
34 
     | 
    
         
             
            	end
         
     | 
| 
       27 
35 
     | 
    
         
             
            	stats.each_pair { |k,v| puts "%-12s: %4d" % [k,v] }
         
     | 
| 
       28 
36 
     | 
    
         
             
            end
         
     | 
    
        data/lib/packetfu/packet.rb
    CHANGED
    
    | 
         @@ -173,7 +173,7 @@ module PacketFu 
     | 
|
| 
       173 
173 
     | 
    
         
             
            		# different ones off of (like a fuzzer might), you'll want
         
     | 
| 
       174 
174 
     | 
    
         
             
            		# to use clone()
         
     | 
| 
       175 
175 
     | 
    
         
             
            		def clone
         
     | 
| 
       176 
     | 
    
         
            -
            			 
     | 
| 
      
 176 
     | 
    
         
            +
            			Packet.parse(self.to_s)
         
     | 
| 
       177 
177 
     | 
    
         
             
            		end
         
     | 
| 
       178 
178 
     | 
    
         | 
| 
       179 
179 
     | 
    
         
             
            		# If two packets are represented as the same binary string, and
         
     | 
| 
         @@ -209,7 +209,7 @@ module PacketFu 
     | 
|
| 
       209 
209 
     | 
    
         
             
            		# peek traverses the @header list in reverse to find a suitable
         
     | 
| 
       210 
210 
     | 
    
         
             
            		# format.
         
     | 
| 
       211 
211 
     | 
    
         
             
            		#
         
     | 
| 
       212 
     | 
    
         
            -
            		#  
     | 
| 
      
 212 
     | 
    
         
            +
            		# === Format
         
     | 
| 
       213 
213 
     | 
    
         
             
            		# 
         
     | 
| 
       214 
214 
     | 
    
         
             
            		#   * A one or two character protocol initial. It should be unique
         
     | 
| 
       215 
215 
     | 
    
         
             
            		#   * The packet size
         
     | 
| 
         @@ -218,7 +218,7 @@ module PacketFu 
     | 
|
| 
       218 
218 
     | 
    
         
             
            		# Ideally, related peek_formats will all line up with each other
         
     | 
| 
       219 
219 
     | 
    
         
             
            		# when printed to the screen.
         
     | 
| 
       220 
220 
     | 
    
         
             
            		#
         
     | 
| 
       221 
     | 
    
         
            -
            		#  
     | 
| 
      
 221 
     | 
    
         
            +
            		# === Example
         
     | 
| 
       222 
222 
     | 
    
         
             
            		#
         
     | 
| 
       223 
223 
     | 
    
         
             
            		#    tcp_packet.peek
         
     | 
| 
       224 
224 
     | 
    
         
             
            		#    #=> "T  1054 10.10.10.105:55000   ->   192.168.145.105:80 [......] S:adc7155b|I:8dd0"
         
     | 
| 
         @@ -283,11 +283,10 @@ module PacketFu 
     | 
|
| 
       283 
283 
     | 
    
         | 
| 
       284 
284 
     | 
    
         
             
            		# Hexify provides a neatly-formatted dump of binary data, familar to hex readers.
         
     | 
| 
       285 
285 
     | 
    
         
             
            		def hexify(str)
         
     | 
| 
       286 
     | 
    
         
            -
            			if str.respond_to? :force_encoding
         
     | 
| 
       287 
     | 
    
         
            -
            				str.force_encoding("ASCII-8BIT")
         
     | 
| 
       288 
     | 
    
         
            -
            			end
         
     | 
| 
      
 286 
     | 
    
         
            +
            			str.force_encoding("ASCII-8BIT") if str.respond_to? :force_encoding
         
     | 
| 
       289 
287 
     | 
    
         
             
            			hexascii_lines = str.to_s.unpack("H*")[0].scan(/.{1,32}/)
         
     | 
| 
       290 
     | 
    
         
            -
            			 
     | 
| 
      
 288 
     | 
    
         
            +
            			regex = Regexp.new('[\x00-\x1f\x7f-\xff]', nil, 'n')
         
     | 
| 
      
 289 
     | 
    
         
            +
            			chars = str.to_s.gsub(regex,'.')
         
     | 
| 
       291 
290 
     | 
    
         
             
            			chars_lines = chars.scan(/.{1,16}/)
         
     | 
| 
       292 
291 
     | 
    
         
             
            			ret = []
         
     | 
| 
       293 
292 
     | 
    
         
             
            			hexascii_lines.size.times {|i| ret << "%-48s  %s" % [hexascii_lines[i].gsub(/(.{2})/,"\\1 "),chars_lines[i]]}
         
     | 
    
        data/lib/packetfu/pcap.rb
    CHANGED
    
    | 
         @@ -44,6 +44,10 @@ module PacketFu 
     | 
|
| 
       44 
44 
     | 
    
         
             
            																:thiszone, :sigfigs, :snaplen, :network)
         
     | 
| 
       45 
45 
     | 
    
         
             
            		include StructFu
         
     | 
| 
       46 
46 
     | 
    
         | 
| 
      
 47 
     | 
    
         
            +
            		MAGIC_INT32  = 0xa1b2c3d4
         
     | 
| 
      
 48 
     | 
    
         
            +
            		MAGIC_LITTLE = [MAGIC_INT32].pack("V")
         
     | 
| 
      
 49 
     | 
    
         
            +
            		MAGIC_BIG    = [MAGIC_INT32].pack("N")
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
       47 
51 
     | 
    
         
             
            		def initialize(args={})
         
     | 
| 
       48 
52 
     | 
    
         
             
            			set_endianness(args[:endian] ||= :little)
         
     | 
| 
       49 
53 
     | 
    
         
             
            			init_fields(args) 
         
     | 
| 
         @@ -54,7 +58,7 @@ module PacketFu 
     | 
|
| 
       54 
58 
     | 
    
         | 
| 
       55 
59 
     | 
    
         
             
            		# Called by initialize to set the initial fields. 
         
     | 
| 
       56 
60 
     | 
    
         
             
            		def init_fields(args={})
         
     | 
| 
       57 
     | 
    
         
            -
            			args[:magic] = @int32.new(args[:magic] ||  
     | 
| 
      
 61 
     | 
    
         
            +
            			args[:magic] = @int32.new(args[:magic] || PcapHeader::MAGIC_INT32)
         
     | 
| 
       58 
62 
     | 
    
         
             
            			args[:ver_major] = @int16.new(args[:ver_major] || 2)
         
     | 
| 
       59 
63 
     | 
    
         
             
            			args[:ver_minor] ||= @int16.new(args[:ver_minor] || 4)
         
     | 
| 
       60 
64 
     | 
    
         
             
            			args[:thiszone] ||= @int32.new(args[:thiszone])
         
     | 
| 
         @@ -76,7 +80,7 @@ module PacketFu 
     | 
|
| 
       76 
80 
     | 
    
         
             
            			force_binary(str)
         
     | 
| 
       77 
81 
     | 
    
         
             
            			return self if str.nil?
         
     | 
| 
       78 
82 
     | 
    
         
             
            			str.force_encoding("binary") if str.respond_to? :force_encoding
         
     | 
| 
       79 
     | 
    
         
            -
            			if str[0,4] == self[:magic].to_s  
     | 
| 
      
 83 
     | 
    
         
            +
            			if str[0,4] == self[:magic].to_s 
         
     | 
| 
       80 
84 
     | 
    
         
             
            				self[:magic].read str[0,4]
         
     | 
| 
       81 
85 
     | 
    
         
             
            				self[:ver_major].read str[4,2]
         
     | 
| 
       82 
86 
     | 
    
         
             
            				self[:ver_minor].read str[6,2]
         
     | 
| 
         @@ -84,6 +88,8 @@ module PacketFu 
     | 
|
| 
       84 
88 
     | 
    
         
             
            				self[:sigfigs].read str[12,4]
         
     | 
| 
       85 
89 
     | 
    
         
             
            				self[:snaplen].read str[16,4]
         
     | 
| 
       86 
90 
     | 
    
         
             
            				self[:network].read str[20,4]
         
     | 
| 
      
 91 
     | 
    
         
            +
            			else
         
     | 
| 
      
 92 
     | 
    
         
            +
            				raise "Incorrect magic for libpcap"
         
     | 
| 
       87 
93 
     | 
    
         
             
            			end
         
     | 
| 
       88 
94 
     | 
    
         
             
            			self
         
     | 
| 
       89 
95 
     | 
    
         
             
            		end
         
     | 
| 
         @@ -163,6 +169,7 @@ module PacketFu 
     | 
|
| 
       163 
169 
     | 
    
         | 
| 
       164 
170 
     | 
    
         
             
            		# Reads a string to populate the object.
         
     | 
| 
       165 
171 
     | 
    
         
             
            		def read(str)
         
     | 
| 
      
 172 
     | 
    
         
            +
            			return unless str
         
     | 
| 
       166 
173 
     | 
    
         
             
            			force_binary(str)
         
     | 
| 
       167 
174 
     | 
    
         
             
            			self[:timestamp].read str[0,8]
         
     | 
| 
       168 
175 
     | 
    
         
             
            			self[:incl_len].read str[8,4]
         
     | 
| 
         @@ -194,10 +201,9 @@ module PacketFu 
     | 
|
| 
       194 
201 
     | 
    
         
             
            		def read(str)
         
     | 
| 
       195 
202 
     | 
    
         
             
            			force_binary(str)
         
     | 
| 
       196 
203 
     | 
    
         
             
            			return self if str.nil?
         
     | 
| 
       197 
     | 
    
         
            -
            			 
     | 
| 
       198 
     | 
    
         
            -
            			if str[0,4] == magic
         
     | 
| 
      
 204 
     | 
    
         
            +
            			if str[0,4] == PcapHeader::MAGIC_BIG
         
     | 
| 
       199 
205 
     | 
    
         
             
            				@endian = :big
         
     | 
| 
       200 
     | 
    
         
            -
            			elsif str[0,4] ==  
     | 
| 
      
 206 
     | 
    
         
            +
            			elsif str[0,4] == PcapHeader::MAGIC_LITTLE
         
     | 
| 
       201 
207 
     | 
    
         
             
            				@endian = :little
         
     | 
| 
       202 
208 
     | 
    
         
             
            			else
         
     | 
| 
       203 
209 
     | 
    
         
             
            				raise ArgumentError, "Unknown file format for #{self.class}"
         
     | 
| 
         @@ -288,10 +294,6 @@ module PacketFu 
     | 
|
| 
       288 
294 
     | 
    
         | 
| 
       289 
295 
     | 
    
         
             
            		alias_method :f2a, :file_to_array
         
     | 
| 
       290 
296 
     | 
    
         | 
| 
       291 
     | 
    
         
            -
            		def self.file_to_array(fname)
         
     | 
| 
       292 
     | 
    
         
            -
            			PcapFile.new.file_to_array(:f => fname)
         
     | 
| 
       293 
     | 
    
         
            -
            		end
         
     | 
| 
       294 
     | 
    
         
            -
             
     | 
| 
       295 
297 
     | 
    
         
             
            		# Takes an array of packets (as generated by file_to_array), and writes them
         
     | 
| 
       296 
298 
     | 
    
         
             
            		# to a file. Valid arguments are:
         
     | 
| 
       297 
299 
     | 
    
         
             
            		#
         
     | 
| 
         @@ -397,6 +399,94 @@ module PacketFu 
     | 
|
| 
       397 
399 
     | 
    
         | 
| 
       398 
400 
     | 
    
         
             
            	end
         
     | 
| 
       399 
401 
     | 
    
         | 
| 
      
 402 
     | 
    
         
            +
            	# PcapFile also can behave as a singleton class, which is usually the better
         
     | 
| 
      
 403 
     | 
    
         
            +
            	# way to handle pcap files of really any size, since it doesn't require
         
     | 
| 
      
 404 
     | 
    
         
            +
            	# storing packets before handing them off to a given block. This is really
         
     | 
| 
      
 405 
     | 
    
         
            +
            	# the way to go.
         
     | 
| 
      
 406 
     | 
    
         
            +
            	class PcapFile
         
     | 
| 
      
 407 
     | 
    
         
            +
            		class << self
         
     | 
| 
      
 408 
     | 
    
         
            +
             
     | 
| 
      
 409 
     | 
    
         
            +
            			# Takes a given file and returns an array of the packet bytes. Here 
         
     | 
| 
      
 410 
     | 
    
         
            +
            			# for backwards compatibilty.
         
     | 
| 
      
 411 
     | 
    
         
            +
            			def file_to_array(fname)
         
     | 
| 
      
 412 
     | 
    
         
            +
            				PcapFile.new.file_to_array(:f => fname)
         
     | 
| 
      
 413 
     | 
    
         
            +
            			end
         
     | 
| 
      
 414 
     | 
    
         
            +
             
     | 
| 
      
 415 
     | 
    
         
            +
            			# Takes a given file name, and reads out the packets. If given a block,
         
     | 
| 
      
 416 
     | 
    
         
            +
            			# it will yield back a PcapPacket object per packet found.
         
     | 
| 
      
 417 
     | 
    
         
            +
            			def read(fname,&block)
         
     | 
| 
      
 418 
     | 
    
         
            +
            				begin
         
     | 
| 
      
 419 
     | 
    
         
            +
            					file_handle = File.open(fname, "rb")
         
     | 
| 
      
 420 
     | 
    
         
            +
            					pcap_packets = PcapPackets.new unless block
         
     | 
| 
      
 421 
     | 
    
         
            +
            					file_header = PcapHeader.new
         
     | 
| 
      
 422 
     | 
    
         
            +
            					file_header.read file_handle.read(24)
         
     | 
| 
      
 423 
     | 
    
         
            +
            					packet_count = 0
         
     | 
| 
      
 424 
     | 
    
         
            +
            					pcap_packet = PcapPacket.new(:endian => file_header.endian)
         
     | 
| 
      
 425 
     | 
    
         
            +
            					while pcap_packet.read file_handle.read(16) do
         
     | 
| 
      
 426 
     | 
    
         
            +
            						len = pcap_packet.incl_len
         
     | 
| 
      
 427 
     | 
    
         
            +
            						pcap_packet.data = StructFu::String.new.read(file_handle.read(len.to_i))
         
     | 
| 
      
 428 
     | 
    
         
            +
            						packet_count += 1
         
     | 
| 
      
 429 
     | 
    
         
            +
            						if pcap_packet.data.size < len.to_i
         
     | 
| 
      
 430 
     | 
    
         
            +
            							warn "Packet ##{packet_count} is corrupted: expected #{len.to_i}, got #{pcap_packet.data.size}. Exiting."
         
     | 
| 
      
 431 
     | 
    
         
            +
            							break
         
     | 
| 
      
 432 
     | 
    
         
            +
            						end
         
     | 
| 
      
 433 
     | 
    
         
            +
            						if block
         
     | 
| 
      
 434 
     | 
    
         
            +
            							yield pcap_packet
         
     | 
| 
      
 435 
     | 
    
         
            +
            						else
         
     | 
| 
      
 436 
     | 
    
         
            +
            							pcap_packets << pcap_packet
         
     | 
| 
      
 437 
     | 
    
         
            +
            						end
         
     | 
| 
      
 438 
     | 
    
         
            +
            					end
         
     | 
| 
      
 439 
     | 
    
         
            +
            					unless block
         
     | 
| 
      
 440 
     | 
    
         
            +
            						return pcap_packets 
         
     | 
| 
      
 441 
     | 
    
         
            +
            					end
         
     | 
| 
      
 442 
     | 
    
         
            +
            				ensure
         
     | 
| 
      
 443 
     | 
    
         
            +
            					file_handle.close
         
     | 
| 
      
 444 
     | 
    
         
            +
            				end
         
     | 
| 
      
 445 
     | 
    
         
            +
            			end
         
     | 
| 
      
 446 
     | 
    
         
            +
             
     | 
| 
      
 447 
     | 
    
         
            +
            			# Takes a filename, and an optional block. If a block is given, 
         
     | 
| 
      
 448 
     | 
    
         
            +
            			# yield back the raw packet data from the given file. Otherwise,
         
     | 
| 
      
 449 
     | 
    
         
            +
            			# return an array of parsed packets.
         
     | 
| 
      
 450 
     | 
    
         
            +
            			def read_packet_bytes(fname,&block)
         
     | 
| 
      
 451 
     | 
    
         
            +
            				count = 0
         
     | 
| 
      
 452 
     | 
    
         
            +
            				packets = [] unless block
         
     | 
| 
      
 453 
     | 
    
         
            +
            				read(fname) do |packet| 
         
     | 
| 
      
 454 
     | 
    
         
            +
            					if block
         
     | 
| 
      
 455 
     | 
    
         
            +
            						count += 1
         
     | 
| 
      
 456 
     | 
    
         
            +
            						yield packet.data.to_s
         
     | 
| 
      
 457 
     | 
    
         
            +
            					else
         
     | 
| 
      
 458 
     | 
    
         
            +
            						packets << packet.data.to_s
         
     | 
| 
      
 459 
     | 
    
         
            +
            					end
         
     | 
| 
      
 460 
     | 
    
         
            +
            				end
         
     | 
| 
      
 461 
     | 
    
         
            +
            				block ? count : packets
         
     | 
| 
      
 462 
     | 
    
         
            +
            			end
         
     | 
| 
      
 463 
     | 
    
         
            +
             
     | 
| 
      
 464 
     | 
    
         
            +
            			alias :file_to_array :read_packet_bytes 
         
     | 
| 
      
 465 
     | 
    
         
            +
             
     | 
| 
      
 466 
     | 
    
         
            +
            			# Takes a filename, and an optional block. If a block is given,
         
     | 
| 
      
 467 
     | 
    
         
            +
            			# yield back parsed packets from the given file. Otherwise, return
         
     | 
| 
      
 468 
     | 
    
         
            +
            			# an array of parsed packets.
         
     | 
| 
      
 469 
     | 
    
         
            +
            			#
         
     | 
| 
      
 470 
     | 
    
         
            +
            			# This is a brazillian times faster than the old methods of extracting
         
     | 
| 
      
 471 
     | 
    
         
            +
            			# packets from files.
         
     | 
| 
      
 472 
     | 
    
         
            +
            			def read_packets(fname,&block)
         
     | 
| 
      
 473 
     | 
    
         
            +
            				count = 0
         
     | 
| 
      
 474 
     | 
    
         
            +
            				packets = [] unless block
         
     | 
| 
      
 475 
     | 
    
         
            +
            				read_packet_bytes(fname) do |packet| 
         
     | 
| 
      
 476 
     | 
    
         
            +
            					if block
         
     | 
| 
      
 477 
     | 
    
         
            +
            						count += 1
         
     | 
| 
      
 478 
     | 
    
         
            +
            						yield Packet.parse(packet)
         
     | 
| 
      
 479 
     | 
    
         
            +
            					else
         
     | 
| 
      
 480 
     | 
    
         
            +
            						packets << Packet.parse(packet)
         
     | 
| 
      
 481 
     | 
    
         
            +
            					end
         
     | 
| 
      
 482 
     | 
    
         
            +
            				end
         
     | 
| 
      
 483 
     | 
    
         
            +
            				block ? count : packets
         
     | 
| 
      
 484 
     | 
    
         
            +
            			end
         
     | 
| 
      
 485 
     | 
    
         
            +
             
     | 
| 
      
 486 
     | 
    
         
            +
            		end
         
     | 
| 
      
 487 
     | 
    
         
            +
             
     | 
| 
      
 488 
     | 
    
         
            +
            	end
         
     | 
| 
      
 489 
     | 
    
         
            +
             
     | 
| 
       400 
490 
     | 
    
         
             
            end
         
     | 
| 
       401 
491 
     | 
    
         | 
| 
       402 
492 
     | 
    
         
             
            module PacketFu
         
     | 
| 
         @@ -411,7 +501,7 @@ module PacketFu 
     | 
|
| 
       411 
501 
     | 
    
         
             
            			# Reads the magic string of a pcap file, and determines
         
     | 
| 
       412 
502 
     | 
    
         
             
            			# if it's :little or :big endian.
         
     | 
| 
       413 
503 
     | 
    
         
             
            			def get_byte_order(pcap_file)
         
     | 
| 
       414 
     | 
    
         
            -
            				byte_order = ((pcap_file[0,4] ==  
     | 
| 
      
 504 
     | 
    
         
            +
            				byte_order = ((pcap_file[0,4] == PcapHeader::MAGIC_LITTLE) ? :little : :big)
         
     | 
| 
       415 
505 
     | 
    
         
             
            				return byte_order
         
     | 
| 
       416 
506 
     | 
    
         
             
            			end
         
     | 
| 
       417 
507 
     | 
    
         | 
    
        data/lib/packetfu/protos/tcp.rb
    CHANGED
    
    | 
         @@ -609,7 +609,7 @@ module PacketFu 
     | 
|
| 
       609 
609 
     | 
    
         
             
            		# Note that by using TcpOptions#encode, strings supplied as values which
         
     | 
| 
       610 
610 
     | 
    
         
             
            		# can be converted to numbers will be converted first.
         
     | 
| 
       611 
611 
     | 
    
         
             
            		#
         
     | 
| 
       612 
     | 
    
         
            -
            		#  
     | 
| 
      
 612 
     | 
    
         
            +
            		# === Example
         
     | 
| 
       613 
613 
     | 
    
         
             
            		#
         
     | 
| 
       614 
614 
     | 
    
         
             
            		#   t = TcpOptions.new
         
     | 
| 
       615 
615 
     | 
    
         
             
            		#   t.encode("MS:1460,WS:6")
         
     | 
| 
         @@ -774,10 +774,15 @@ module PacketFu 
     | 
|
| 
       774 
774 
     | 
    
         | 
| 
       775 
775 
     | 
    
         
             
            		# Getter for the TCP Header Length value.
         
     | 
| 
       776 
776 
     | 
    
         
             
            		def tcp_hlen; self[:tcp_hlen].to_i; end
         
     | 
| 
       777 
     | 
    
         
            -
            		# Setter for the TCP Header Length value.
         
     | 
| 
      
 777 
     | 
    
         
            +
            		# Setter for the TCP Header Length value. Can take
         
     | 
| 
      
 778 
     | 
    
         
            +
            		# either a string or an integer. Note that if it's
         
     | 
| 
      
 779 
     | 
    
         
            +
            		# a string, the top four bits are used.
         
     | 
| 
       778 
780 
     | 
    
         
             
            		def tcp_hlen=(i)
         
     | 
| 
       779 
     | 
    
         
            -
            			 
     | 
| 
       780 
     | 
    
         
            -
             
     | 
| 
      
 781 
     | 
    
         
            +
            			case i
         
     | 
| 
      
 782 
     | 
    
         
            +
            			when PacketFu::TcpHlen
         
     | 
| 
      
 783 
     | 
    
         
            +
            				self[:tcp_hlen] = i
         
     | 
| 
      
 784 
     | 
    
         
            +
            			when Numeric
         
     | 
| 
      
 785 
     | 
    
         
            +
            				self[:tcp_hlen] = TcpHlen.new(:hlen => i.to_i)
         
     | 
| 
       781 
786 
     | 
    
         
             
            			else
         
     | 
| 
       782 
787 
     | 
    
         
             
            				self[:tcp_hlen].read(i)
         
     | 
| 
       783 
788 
     | 
    
         
             
            			end
         
     | 
| 
         @@ -787,8 +792,15 @@ module PacketFu 
     | 
|
| 
       787 
792 
     | 
    
         
             
            		def tcp_reserved; self[:tcp_reserved].to_i; end
         
     | 
| 
       788 
793 
     | 
    
         
             
            		# Setter for the TCP Reserved field.
         
     | 
| 
       789 
794 
     | 
    
         
             
            		def tcp_reserved=(i)
         
     | 
| 
       790 
     | 
    
         
            -
            			 
     | 
| 
      
 795 
     | 
    
         
            +
            			case i
         
     | 
| 
      
 796 
     | 
    
         
            +
            			when PacketFu::TcpReserved
         
     | 
| 
       791 
797 
     | 
    
         
             
            				self[:tcp_reserved]=i
         
     | 
| 
      
 798 
     | 
    
         
            +
            			when Numeric
         
     | 
| 
      
 799 
     | 
    
         
            +
            				args = {}
         
     | 
| 
      
 800 
     | 
    
         
            +
            				args[:r1] = (i & 0b100) >> 2
         
     | 
| 
      
 801 
     | 
    
         
            +
            				args[:r2] = (i & 0b010) >> 1
         
     | 
| 
      
 802 
     | 
    
         
            +
            				args[:r3] = (i & 0b001)
         
     | 
| 
      
 803 
     | 
    
         
            +
            				self[:tcp_reserved] = TcpReserved.new(args)
         
     | 
| 
       792 
804 
     | 
    
         
             
            			else
         
     | 
| 
       793 
805 
     | 
    
         
             
            				self[:tcp_reserved].read(i)
         
     | 
| 
       794 
806 
     | 
    
         
             
            			end
         
     | 
| 
         @@ -798,8 +810,15 @@ module PacketFu 
     | 
|
| 
       798 
810 
     | 
    
         
             
            		def tcp_ecn; self[:tcp_ecn].to_i; end
         
     | 
| 
       799 
811 
     | 
    
         
             
            		# Setter for the ECN bits. 
         
     | 
| 
       800 
812 
     | 
    
         
             
            		def tcp_ecn=(i)
         
     | 
| 
       801 
     | 
    
         
            -
            			 
     | 
| 
      
 813 
     | 
    
         
            +
            			case i
         
     | 
| 
      
 814 
     | 
    
         
            +
            			when PacketFu::TcpEcn
         
     | 
| 
       802 
815 
     | 
    
         
             
            				self[:tcp_ecn]=i
         
     | 
| 
      
 816 
     | 
    
         
            +
            			when Numeric
         
     | 
| 
      
 817 
     | 
    
         
            +
            				args = {}
         
     | 
| 
      
 818 
     | 
    
         
            +
            				args[:n] = (i & 0b100) >> 2
         
     | 
| 
      
 819 
     | 
    
         
            +
            				args[:c] = (i & 0b010) >> 1
         
     | 
| 
      
 820 
     | 
    
         
            +
            				args[:e] = (i & 0b001)
         
     | 
| 
      
 821 
     | 
    
         
            +
            				self[:tcp_ecn] = TcpEcn.new(args)
         
     | 
| 
       803 
822 
     | 
    
         
             
            			else
         
     | 
| 
       804 
823 
     | 
    
         
             
            				self[:tcp_ecn].read(i)
         
     | 
| 
       805 
824 
     | 
    
         
             
            			end
         
     | 
| 
         @@ -809,7 +828,8 @@ module PacketFu 
     | 
|
| 
       809 
828 
     | 
    
         
             
            		def tcp_opts; self[:tcp_opts].to_s; end
         
     | 
| 
       810 
829 
     | 
    
         
             
            		# Setter for TCP Options.
         
     | 
| 
       811 
830 
     | 
    
         
             
            		def tcp_opts=(i)
         
     | 
| 
       812 
     | 
    
         
            -
            			 
     | 
| 
      
 831 
     | 
    
         
            +
            			case i
         
     | 
| 
      
 832 
     | 
    
         
            +
            			when PacketFu::TcpOptions
         
     | 
| 
       813 
833 
     | 
    
         
             
            				self[:tcp_opts]=i
         
     | 
| 
       814 
834 
     | 
    
         
             
            			else
         
     | 
| 
       815 
835 
     | 
    
         
             
            				self[:tcp_opts].read(i)
         
     | 
| 
         @@ -846,7 +866,7 @@ module PacketFu 
     | 
|
| 
       846 
866 
     | 
    
         
             
            		def tcp_flags_dotmap
         
     | 
| 
       847 
867 
     | 
    
         
             
            			dotmap = tcp_flags.members.map do |flag|
         
     | 
| 
       848 
868 
     | 
    
         
             
            				status = self.tcp_flags.send flag
         
     | 
| 
       849 
     | 
    
         
            -
            				status == 0 ? "." : flag.to_s.upcase[0]
         
     | 
| 
      
 869 
     | 
    
         
            +
            				status == 0 ? "." : flag.to_s.upcase[0].chr
         
     | 
| 
       850 
870 
     | 
    
         
             
            			end
         
     | 
| 
       851 
871 
     | 
    
         
             
            			dotmap.join
         
     | 
| 
       852 
872 
     | 
    
         
             
            		end
         
     | 
    
        data/lib/packetfu/structfu.rb
    CHANGED
    
    | 
         @@ -118,12 +118,12 @@ module StructFu 
     | 
|
| 
       118 
118 
     | 
    
         | 
| 
       119 
119 
     | 
    
         
             
            	end
         
     | 
| 
       120 
120 
     | 
    
         | 
| 
       121 
     | 
    
         
            -
            	# Int16be is a two byte value in big-endian format.
         
     | 
| 
      
 121 
     | 
    
         
            +
            	# Int16be is a two byte value in big-endian format. The endianness cannot be altered.
         
     | 
| 
       122 
122 
     | 
    
         
             
            	class Int16be < Int16
         
     | 
| 
       123 
123 
     | 
    
         
             
            		undef :endian=
         
     | 
| 
       124 
124 
     | 
    
         
             
            	end
         
     | 
| 
       125 
125 
     | 
    
         | 
| 
       126 
     | 
    
         
            -
            	# Int16le is a two byte value in little-endian format.
         
     | 
| 
      
 126 
     | 
    
         
            +
            	# Int16le is a two byte value in little-endian format. The endianness cannot be altered.
         
     | 
| 
       127 
127 
     | 
    
         
             
            	class Int16le < Int16
         
     | 
| 
       128 
128 
     | 
    
         
             
            		undef :endian=
         
     | 
| 
       129 
129 
     | 
    
         
             
            		def initialize(v=nil, e=:little)
         
     | 
| 
         @@ -147,12 +147,12 @@ module StructFu 
     | 
|
| 
       147 
147 
     | 
    
         | 
| 
       148 
148 
     | 
    
         
             
            	end
         
     | 
| 
       149 
149 
     | 
    
         | 
| 
       150 
     | 
    
         
            -
            	# Int32be is a four byte value in big-endian format.
         
     | 
| 
      
 150 
     | 
    
         
            +
            	# Int32be is a four byte value in big-endian format. The endianness cannot be altered.
         
     | 
| 
       151 
151 
     | 
    
         
             
            	class Int32be < Int32
         
     | 
| 
       152 
152 
     | 
    
         
             
            		undef :endian=
         
     | 
| 
       153 
153 
     | 
    
         
             
            	end
         
     | 
| 
       154 
154 
     | 
    
         | 
| 
       155 
     | 
    
         
            -
            	# Int32le is a four byte value in little-endian format.
         
     | 
| 
      
 155 
     | 
    
         
            +
            	# Int32le is a four byte value in little-endian format. The endianness cannot be altered.
         
     | 
| 
       156 
156 
     | 
    
         
             
            	class Int32le < Int32
         
     | 
| 
       157 
157 
     | 
    
         
             
            		undef :endian=
         
     | 
| 
       158 
158 
     | 
    
         
             
            		def initialize(v=nil, e=:little)
         
     | 
| 
         @@ -208,8 +208,8 @@ module StructFu 
     | 
|
| 
       208 
208 
     | 
    
         
             
            		# is calculated upon assignment. If you'd prefer to have
         
     | 
| 
       209 
209 
     | 
    
         
             
            		# an incorrect value, use the syntax, obj[:string]="value"
         
     | 
| 
       210 
210 
     | 
    
         
             
            		# instead. Note, by using the alternate form, you must
         
     | 
| 
       211 
     | 
    
         
            -
            		# #calc before you can trust the int's value. Think of the
         
     | 
| 
       212 
     | 
    
         
            -
            		#  
     | 
| 
      
 211 
     | 
    
         
            +
            		# #calc before you can trust the int's value. Think of the = 
         
     | 
| 
      
 212 
     | 
    
         
            +
            		# assignment as "set to equal," while the []= assignment
         
     | 
| 
       213 
213 
     | 
    
         
             
            		# as "boxing in" the value. Maybe.
         
     | 
| 
       214 
214 
     | 
    
         
             
            		def string=(s)
         
     | 
| 
       215 
215 
     | 
    
         
             
            			self[:string] = s
         
     | 
| 
         @@ -246,9 +246,13 @@ module StructFu 
     | 
|
| 
       246 
246 
     | 
    
         
             
            		# is used is dependant on which :mode is set (with self.mode).
         
     | 
| 
       247 
247 
     | 
    
         
             
            		#
         
     | 
| 
       248 
248 
     | 
    
         
             
            		# :parse : Read the length, and then read in that many bytes of the string. 
         
     | 
| 
       249 
     | 
    
         
            -
            		# 
     | 
| 
       250 
     | 
    
         
            -
            		# 
     | 
| 
       251 
     | 
    
         
            -
            		#  
     | 
| 
      
 249 
     | 
    
         
            +
            		# The string may be truncated or padded out with nulls, as dictated by the value.
         
     | 
| 
      
 250 
     | 
    
         
            +
            		#
         
     | 
| 
      
 251 
     | 
    
         
            +
            		# :fix   : Skip the length, read the rest of the string, then set the length 
         
     | 
| 
      
 252 
     | 
    
         
            +
            		# to what it ought to be.
         
     | 
| 
      
 253 
     | 
    
         
            +
            		#
         
     | 
| 
      
 254 
     | 
    
         
            +
            		# else   : If neither of these modes are set, just perfom a normal read().
         
     | 
| 
      
 255 
     | 
    
         
            +
            		# This is the default.
         
     | 
| 
       252 
256 
     | 
    
         
             
            		def parse(s)
         
     | 
| 
       253 
257 
     | 
    
         
             
            			unless s[0,int.width].size == int.width
         
     | 
| 
       254 
258 
     | 
    
         
             
            				raise StandardError, "String is too short for type #{int.class}"
         
     | 
    
        data/lib/packetfu/version.rb
    CHANGED
    
    | 
         @@ -1,13 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module PacketFu
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            	# Check the repo's for version release histories
         
     | 
| 
       4 
     | 
    
         
            -
            	VERSION = "1.0. 
     | 
| 
      
 4 
     | 
    
         
            +
            	VERSION = "1.0.4" 
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
      
 6 
     | 
    
         
            +
            	# Returns PacketFu::VERSION
         
     | 
| 
       6 
7 
     | 
    
         
             
            	def self.version
         
     | 
| 
       7 
8 
     | 
    
         
             
            		VERSION
         
     | 
| 
       8 
9 
     | 
    
         
             
            	end
         
     | 
| 
       9 
10 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
            	# Returns  
     | 
| 
      
 11 
     | 
    
         
            +
            	# Returns a version string in a binary format for easy comparisons.
         
     | 
| 
       11 
12 
     | 
    
         
             
            	def self.binarize_version(str)
         
     | 
| 
       12 
13 
     | 
    
         
             
            		if(str.respond_to?(:split) && str =~ /^[0-9]+(\.([0-9]+)(\.[0-9]+)?)?\..+$/)
         
     | 
| 
       13 
14 
     | 
    
         
             
            			bin_major,bin_minor,bin_teeny = str.split(/\x2e/).map {|x| x.to_i}
         
     | 
    
        data/lib/packetfu.rb
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         | 
| 
       2 
2 
     | 
    
         
             
            # :title: PacketFu Documentation
         
     | 
| 
      
 3 
     | 
    
         
            +
            # :main: ../README
         
     | 
| 
       3 
4 
     | 
    
         
             
            # :include: ../README
         
     | 
| 
       4 
     | 
    
         
            -
            # :include: ../INSTALL
         
     | 
| 
       5 
5 
     | 
    
         
             
            # :include: ../LICENSE
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            cwd = File.expand_path(File.dirname(__FILE__))
         
     | 
| 
         @@ -14,6 +14,19 @@ require 'rubygems' if RUBY_VERSION =~ /^1\.[0-8]/ 
     | 
|
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
            module PacketFu
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
      
 17 
     | 
    
         
            +
            	# Picks up all the protocols defined in the protos subdirectory
         
     | 
| 
      
 18 
     | 
    
         
            +
            	def self.require_protos(cwd)
         
     | 
| 
      
 19 
     | 
    
         
            +
            		protos_dir = File.join(cwd, "packetfu", "protos")
         
     | 
| 
      
 20 
     | 
    
         
            +
            		Dir.new(protos_dir).each do |fname|
         
     | 
| 
      
 21 
     | 
    
         
            +
            			next unless fname[/\.rb$/]
         
     | 
| 
      
 22 
     | 
    
         
            +
            			begin 
         
     | 
| 
      
 23 
     | 
    
         
            +
            				require File.join(protos_dir,fname)
         
     | 
| 
      
 24 
     | 
    
         
            +
            			rescue
         
     | 
| 
      
 25 
     | 
    
         
            +
            				warn "Warning: Could not load `#{fname}'. Skipping."
         
     | 
| 
      
 26 
     | 
    
         
            +
            			end
         
     | 
| 
      
 27 
     | 
    
         
            +
            		end
         
     | 
| 
      
 28 
     | 
    
         
            +
            	end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
       17 
30 
     | 
    
         
             
            	# Sets the expected byte order for a pcap file. See PacketFu::Read.set_byte_order
         
     | 
| 
       18 
31 
     | 
    
         
             
            	@byte_order = :little
         
     | 
| 
       19 
32 
     | 
    
         | 
| 
         @@ -32,6 +45,7 @@ module PacketFu 
     | 
|
| 
       32 
45 
     | 
    
         
             
            	end
         
     | 
| 
       33 
46 
     | 
    
         | 
| 
       34 
47 
     | 
    
         
             
            	pcaprub_platform_require
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
       35 
49 
     | 
    
         
             
            	if @pcaprub_loaded
         
     | 
| 
       36 
50 
     | 
    
         
             
            		if Pcap.version !~ /[0-9]\.[7-9][0-9]?(-dev)?/ # Regex for 0.7-dev and beyond.
         
     | 
| 
       37 
51 
     | 
    
         
             
            			@pcaprub_loaded = false # Don't bother with broken versions
         
     | 
| 
         @@ -41,6 +55,7 @@ module PacketFu 
     | 
|
| 
       41 
55 
     | 
    
         
             
            		require "packetfu/inject"
         
     | 
| 
       42 
56 
     | 
    
         
             
            	end
         
     | 
| 
       43 
57 
     | 
    
         | 
| 
      
 58 
     | 
    
         
            +
            	# Returns the status of pcaprub
         
     | 
| 
       44 
59 
     | 
    
         
             
            	def self.pcaprub_loaded?
         
     | 
| 
       45 
60 
     | 
    
         
             
            		@pcaprub_loaded
         
     | 
| 
       46 
61 
     | 
    
         
             
            	end
         
     | 
| 
         @@ -50,6 +65,7 @@ module PacketFu 
     | 
|
| 
       50 
65 
     | 
    
         
             
            		constants.map { |const| const_get(const) if const_get(const).kind_of? Class}.compact
         
     | 
| 
       51 
66 
     | 
    
         
             
            	end
         
     | 
| 
       52 
67 
     | 
    
         | 
| 
      
 68 
     | 
    
         
            +
            	# Adds the class to PacketFu's list of packet classes -- used in packet parsing.
         
     | 
| 
       53 
69 
     | 
    
         
             
            	def self.add_packet_class(klass)
         
     | 
| 
       54 
70 
     | 
    
         
             
            		raise "Need a class" unless klass.kind_of? Class
         
     | 
| 
       55 
71 
     | 
    
         
             
            		if klass.name !~ /[A-Za-z0-9]Packet/
         
     | 
| 
         @@ -60,6 +76,7 @@ module PacketFu 
     | 
|
| 
       60 
76 
     | 
    
         
             
            		@packet_classes.sort! {|x,y| x.name <=> y.name}
         
     | 
| 
       61 
77 
     | 
    
         
             
            	end
         
     | 
| 
       62 
78 
     | 
    
         | 
| 
      
 79 
     | 
    
         
            +
            	# Presumably, there may be a time where you'd like to remove a packet class.
         
     | 
| 
       63 
80 
     | 
    
         
             
            	def self.remove_packet_class(klass)
         
     | 
| 
       64 
81 
     | 
    
         
             
            		raise "Need a class" unless klass.kind_of? Class
         
     | 
| 
       65 
82 
     | 
    
         
             
            		@packet_classes ||= []
         
     | 
| 
         @@ -67,10 +84,12 @@ module PacketFu 
     | 
|
| 
       67 
84 
     | 
    
         
             
            		@packet_classes 
         
     | 
| 
       68 
85 
     | 
    
         
             
            	end
         
     | 
| 
       69 
86 
     | 
    
         | 
| 
      
 87 
     | 
    
         
            +
            	# Returns an array of packet classes
         
     | 
| 
       70 
88 
     | 
    
         
             
            	def self.packet_classes
         
     | 
| 
       71 
89 
     | 
    
         
             
            		@packet_classes || []
         
     | 
| 
       72 
90 
     | 
    
         
             
            	end
         
     | 
| 
       73 
91 
     | 
    
         | 
| 
      
 92 
     | 
    
         
            +
            	# Returns an array of packet types by packet prefix.
         
     | 
| 
       74 
93 
     | 
    
         
             
            	def self.packet_prefixes
         
     | 
| 
       75 
94 
     | 
    
         
             
            		return [] unless @packet_classes
         
     | 
| 
       76 
95 
     | 
    
         
             
            		@packet_classes.map {|p| p.to_s.split("::").last.to_s.downcase.gsub(/packet$/,"")}
         
     | 
| 
         @@ -78,22 +97,10 @@ module PacketFu 
     | 
|
| 
       78 
97 
     | 
    
         | 
| 
       79 
98 
     | 
    
         
             
            end
         
     | 
| 
       80 
99 
     | 
    
         | 
| 
       81 
     | 
    
         
            -
            def require_protos(cwd)
         
     | 
| 
       82 
     | 
    
         
            -
            	protos_dir = File.join(cwd, "packetfu", "protos")
         
     | 
| 
       83 
     | 
    
         
            -
            	Dir.new(protos_dir).each do |fname|
         
     | 
| 
       84 
     | 
    
         
            -
            		next unless fname[/\.rb$/]
         
     | 
| 
       85 
     | 
    
         
            -
            		begin 
         
     | 
| 
       86 
     | 
    
         
            -
            			require File.join(protos_dir,fname)
         
     | 
| 
       87 
     | 
    
         
            -
            		rescue
         
     | 
| 
       88 
     | 
    
         
            -
            			warn "Warning: Could not load `#{fname}'. Skipping."
         
     | 
| 
       89 
     | 
    
         
            -
            		end
         
     | 
| 
       90 
     | 
    
         
            -
            	end
         
     | 
| 
       91 
     | 
    
         
            -
            end
         
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
100 
     | 
    
         
             
            require File.join(cwd,"packetfu","version")
         
     | 
| 
       94 
101 
     | 
    
         
             
            require File.join(cwd,"packetfu","pcap")
         
     | 
| 
       95 
102 
     | 
    
         
             
            require File.join(cwd,"packetfu","packet")
         
     | 
| 
       96 
     | 
    
         
            -
            require_protos(cwd)
         
     | 
| 
      
 103 
     | 
    
         
            +
            PacketFu.require_protos(cwd)
         
     | 
| 
       97 
104 
     | 
    
         
             
            require File.join(cwd,"packetfu","utils")
         
     | 
| 
       98 
105 
     | 
    
         
             
            require File.join(cwd,"packetfu","config")
         
     | 
| 
       99 
106 
     | 
    
         | 
    
        data/test/icmp_test.pcap
    CHANGED
    
    | 
         Binary file 
     | 
    
        data/test/ip_test.pcap
    CHANGED
    
    | 
         Binary file 
     | 
    
        data/test/packetfu_spec.rb
    CHANGED
    
    | 
         @@ -1,8 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require File.join("..","lib","packetfu")
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            unless %x{#{$0} --version} =~ /^2\.6/
         
     | 
| 
      
 4 
     | 
    
         
            +
            	puts "PacketFu needs rspec 2.6 or so."
         
     | 
| 
      
 5 
     | 
    
         
            +
            	exit 1
         
     | 
| 
      
 6 
     | 
    
         
            +
            end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
       3 
8 
     | 
    
         
             
            describe PacketFu, "version information" do
         
     | 
| 
       4 
9 
     | 
    
         
             
            	it "reports a version number" do
         
     | 
| 
       5 
     | 
    
         
            -
            		PacketFu::VERSION.should  
     | 
| 
      
 10 
     | 
    
         
            +
            		PacketFu::VERSION.should match /^1\.[0-9]\.[0-9]$/
         
     | 
| 
       6 
11 
     | 
    
         
             
            	end
         
     | 
| 
       7 
12 
     | 
    
         
             
            	its(:version) {should eq PacketFu::VERSION} 
         
     | 
| 
       8 
13 
     | 
    
         | 
    
        data/test/tcp_spec.rb
    ADDED
    
    | 
         @@ -0,0 +1,100 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.join("..","lib","packetfu")
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            include PacketFu
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            def unusual_numeric_handling_headers(header,i)
         
     | 
| 
      
 6 
     | 
    
         
            +
            	camelized_header = header.to_s.split("_").map {|x| x.capitalize}.join
         
     | 
| 
      
 7 
     | 
    
         
            +
            	header_class = PacketFu.const_get camelized_header
         
     | 
| 
      
 8 
     | 
    
         
            +
            	specify { subject.send(header).should == i }
         
     | 
| 
      
 9 
     | 
    
         
            +
            	specify { subject.send(header).should be_kind_of Integer }
         
     | 
| 
      
 10 
     | 
    
         
            +
            	specify { subject.headers.last[header].should be_kind_of header_class }
         
     | 
| 
      
 11 
     | 
    
         
            +
            end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            def tcp_hlen_numeric(i)
         
     | 
| 
      
 14 
     | 
    
         
            +
            	unusual_numeric_handling_headers(:tcp_hlen,i)
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            def tcp_reserved_numeric(i)
         
     | 
| 
      
 18 
     | 
    
         
            +
            	unusual_numeric_handling_headers(:tcp_reserved,i)
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            def tcp_ecn_numeric(i)
         
     | 
| 
      
 22 
     | 
    
         
            +
            	unusual_numeric_handling_headers(:tcp_ecn,i)
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            describe TCPPacket do
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            	subject do
         
     | 
| 
      
 29 
     | 
    
         
            +
            		bytes = PcapFile.file_to_array("sample2.pcap")[2]
         
     | 
| 
      
 30 
     | 
    
         
            +
            		packet = Packet.parse(bytes)
         
     | 
| 
      
 31 
     | 
    
         
            +
            	end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            	context "TcpHlen reading and setting" do
         
     | 
| 
      
 34 
     | 
    
         
            +
            		context "TcpHlen set via #read" do
         
     | 
| 
      
 35 
     | 
    
         
            +
            			tcp_hlen_numeric(8)
         
     | 
| 
      
 36 
     | 
    
         
            +
            		end
         
     | 
| 
      
 37 
     | 
    
         
            +
            		context "TcpHlen set via an Integer for the setter" do
         
     | 
| 
      
 38 
     | 
    
         
            +
            			(0..15).each do |i|
         
     | 
| 
      
 39 
     | 
    
         
            +
            				context "i is #{i}" do
         
     | 
| 
      
 40 
     | 
    
         
            +
            					before { subject.tcp_hlen = i }
         
     | 
| 
      
 41 
     | 
    
         
            +
            					tcp_hlen_numeric(i)
         
     | 
| 
      
 42 
     | 
    
         
            +
            				end
         
     | 
| 
      
 43 
     | 
    
         
            +
            			end
         
     | 
| 
      
 44 
     | 
    
         
            +
            		end
         
     | 
| 
      
 45 
     | 
    
         
            +
            		context "TcpHlen set via a String for the setter" do
         
     | 
| 
      
 46 
     | 
    
         
            +
            			before { subject.tcp_hlen = "\x60" }
         
     | 
| 
      
 47 
     | 
    
         
            +
            			tcp_hlen_numeric(6)
         
     | 
| 
      
 48 
     | 
    
         
            +
            		end
         
     | 
| 
      
 49 
     | 
    
         
            +
            		context "TcpHlen set via a TcpHlen for the setter" do
         
     | 
| 
      
 50 
     | 
    
         
            +
            			before { subject.tcp_hlen = TcpHlen.new(:hlen => 7) }
         
     | 
| 
      
 51 
     | 
    
         
            +
            			tcp_hlen_numeric(7)
         
     | 
| 
      
 52 
     | 
    
         
            +
            		end
         
     | 
| 
      
 53 
     | 
    
         
            +
            	end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            	context "TcpReserved reading and setting" do
         
     | 
| 
      
 56 
     | 
    
         
            +
            		context "TcpReserved set via #read" do
         
     | 
| 
      
 57 
     | 
    
         
            +
            			tcp_reserved_numeric(0)
         
     | 
| 
      
 58 
     | 
    
         
            +
            		end
         
     | 
| 
      
 59 
     | 
    
         
            +
            		context "TcpReserved set via an Integer for the setter" do
         
     | 
| 
      
 60 
     | 
    
         
            +
            			(0..7).each do |i|
         
     | 
| 
      
 61 
     | 
    
         
            +
            				context "i is #{i}" do
         
     | 
| 
      
 62 
     | 
    
         
            +
            					before { subject.tcp_reserved = i }
         
     | 
| 
      
 63 
     | 
    
         
            +
            					tcp_reserved_numeric(i)
         
     | 
| 
      
 64 
     | 
    
         
            +
            				end
         
     | 
| 
      
 65 
     | 
    
         
            +
            			end
         
     | 
| 
      
 66 
     | 
    
         
            +
            		end
         
     | 
| 
      
 67 
     | 
    
         
            +
            		context "TcpReserved set via a String for the setter" do
         
     | 
| 
      
 68 
     | 
    
         
            +
            			before { subject.tcp_reserved = "\x03" }
         
     | 
| 
      
 69 
     | 
    
         
            +
            			tcp_reserved_numeric(3)
         
     | 
| 
      
 70 
     | 
    
         
            +
            		end
         
     | 
| 
      
 71 
     | 
    
         
            +
            		context "TcpReserved set via a TcpReserved for the setter" do
         
     | 
| 
      
 72 
     | 
    
         
            +
            			before { subject.tcp_reserved = TcpReserved.new(:r1 => 1, :r2 => 0, :r3 => 1) }
         
     | 
| 
      
 73 
     | 
    
         
            +
            			tcp_reserved_numeric(5)
         
     | 
| 
      
 74 
     | 
    
         
            +
            		end
         
     | 
| 
      
 75 
     | 
    
         
            +
            	end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
            	context "TcpEcn reading and setting" do
         
     | 
| 
      
 78 
     | 
    
         
            +
            		context "TcpEcn set via #read" do
         
     | 
| 
      
 79 
     | 
    
         
            +
            			tcp_ecn_numeric(0)
         
     | 
| 
      
 80 
     | 
    
         
            +
            		end
         
     | 
| 
      
 81 
     | 
    
         
            +
            		context "TcpEcn set via an Integer for the setter" do
         
     | 
| 
      
 82 
     | 
    
         
            +
            			(0..7).each do |i|
         
     | 
| 
      
 83 
     | 
    
         
            +
            				context "i is #{i}" do
         
     | 
| 
      
 84 
     | 
    
         
            +
            					before { subject.tcp_ecn = i }
         
     | 
| 
      
 85 
     | 
    
         
            +
            					tcp_ecn_numeric(i)
         
     | 
| 
      
 86 
     | 
    
         
            +
            				end
         
     | 
| 
      
 87 
     | 
    
         
            +
            			end
         
     | 
| 
      
 88 
     | 
    
         
            +
            		end
         
     | 
| 
      
 89 
     | 
    
         
            +
            		context "TcpEcn set via a String for the setter" do
         
     | 
| 
      
 90 
     | 
    
         
            +
            			before { subject.tcp_ecn = "\x00\xc0" }
         
     | 
| 
      
 91 
     | 
    
         
            +
            			tcp_ecn_numeric(3)
         
     | 
| 
      
 92 
     | 
    
         
            +
            		end
         
     | 
| 
      
 93 
     | 
    
         
            +
            		context "TcpEcn set via a TcpEcn for the setter" do
         
     | 
| 
      
 94 
     | 
    
         
            +
            			before { subject.tcp_ecn = TcpEcn.new(:n => 1, :c => 0, :e => 1) }
         
     | 
| 
      
 95 
     | 
    
         
            +
            			tcp_ecn_numeric(5)
         
     | 
| 
      
 96 
     | 
    
         
            +
            		end
         
     | 
| 
      
 97 
     | 
    
         
            +
            	end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
            end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
    
        data/test/tcp_test.pcap
    CHANGED
    
    | 
         Binary file 
     | 
    
        data/test/test_arp.rb
    CHANGED
    
    
    
        data/test/test_hsrp.rb
    CHANGED
    
    | 
         @@ -15,57 +15,6 @@ class HSRPTest < Test::Unit::TestCase 
     | 
|
| 
       15 
15 
     | 
    
         
             
            		# pkt.to_f('udp_test.pcap','a')
         
     | 
| 
       16 
16 
     | 
    
         
             
            	end
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
            =begin
         
     | 
| 
       19 
     | 
    
         
            -
            # The rest of these tests are snarfed from UDP. TODO: need to update
         
     | 
| 
       20 
     | 
    
         
            -
            # these for hsrp, shouldn't be long.
         
     | 
| 
       21 
     | 
    
         
            -
            	def test_hsrp_pcap
         
     | 
| 
       22 
     | 
    
         
            -
            		u = UDPPacket.new
         
     | 
| 
       23 
     | 
    
         
            -
            		assert_kind_of UDPPacket, u
         
     | 
| 
       24 
     | 
    
         
            -
            		u.recalc
         
     | 
| 
       25 
     | 
    
         
            -
            		u.to_f('udp_test.pcap','a')
         
     | 
| 
       26 
     | 
    
         
            -
            		u.ip_saddr = "10.20.30.40"
         
     | 
| 
       27 
     | 
    
         
            -
            		u.ip_daddr = "50.60.70.80"
         
     | 
| 
       28 
     | 
    
         
            -
            		u.payload = "+some fakey-fake udp packet"
         
     | 
| 
       29 
     | 
    
         
            -
            		u.udp_src = 1205
         
     | 
| 
       30 
     | 
    
         
            -
            		u.udp_dst = 13013
         
     | 
| 
       31 
     | 
    
         
            -
            		u.recalc
         
     | 
| 
       32 
     | 
    
         
            -
            		u.to_f('udp_test.pcap','a')
         
     | 
| 
       33 
     | 
    
         
            -
            	end
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
            	def test_udp_peek
         
     | 
| 
       36 
     | 
    
         
            -
            		u = UDPPacket.new
         
     | 
| 
       37 
     | 
    
         
            -
            		u.ip_saddr = "10.20.30.40"
         
     | 
| 
       38 
     | 
    
         
            -
            		u.ip_daddr = "50.60.70.80"
         
     | 
| 
       39 
     | 
    
         
            -
            		u.udp_src = 53
         
     | 
| 
       40 
     | 
    
         
            -
            		u.udp_dport = 1305
         
     | 
| 
       41 
     | 
    
         
            -
            		u.payload = "abcdefghijklmnopqrstuvwxyz"
         
     | 
| 
       42 
     | 
    
         
            -
            		u.recalc
         
     | 
| 
       43 
     | 
    
         
            -
            		puts "\n"
         
     | 
| 
       44 
     | 
    
         
            -
            		puts "UDP Peek format: "
         
     | 
| 
       45 
     | 
    
         
            -
            		puts u.peek
         
     | 
| 
       46 
     | 
    
         
            -
            		assert_equal 78,u.peek.size
         
     | 
| 
       47 
     | 
    
         
            -
            	end
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
            	def test_udp_checksum
         
     | 
| 
       50 
     | 
    
         
            -
            		sample_packet = PcapFile.new.file_to_array(:f => 'sample.pcap')[0]
         
     | 
| 
       51 
     | 
    
         
            -
            		pkt = Packet.parse(sample_packet)
         
     | 
| 
       52 
     | 
    
         
            -
            		assert_kind_of UDPPacket, pkt
         
     | 
| 
       53 
     | 
    
         
            -
            		pkt.recalc
         
     | 
| 
       54 
     | 
    
         
            -
            		assert_equal(0x8bf8, pkt.udp_sum.to_i)
         
     | 
| 
       55 
     | 
    
         
            -
            		pkt.to_f('udp_test.pcap','a')
         
     | 
| 
       56 
     | 
    
         
            -
            	end
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
            	def test_udp_alter
         
     | 
| 
       59 
     | 
    
         
            -
            		sample_packet = PcapFile.new.file_to_array(:f => 'sample.pcap')[0]
         
     | 
| 
       60 
     | 
    
         
            -
            		pkt = Packet.parse(sample_packet)
         
     | 
| 
       61 
     | 
    
         
            -
            		assert_kind_of UDPPacket, pkt
         
     | 
| 
       62 
     | 
    
         
            -
            		pkt.payload = pkt.payload.gsub(/metasploit/,"MeatPistol")
         
     | 
| 
       63 
     | 
    
         
            -
            		pkt.recalc
         
     | 
| 
       64 
     | 
    
         
            -
            		assert_equal(0x8341, pkt.udp_sum)
         
     | 
| 
       65 
     | 
    
         
            -
            		pkt.to_f('udp_test.pcap','a')
         
     | 
| 
       66 
     | 
    
         
            -
            	end
         
     | 
| 
       67 
     | 
    
         
            -
            =end
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
18 
     | 
    
         
             
            end
         
     | 
| 
       70 
19 
     | 
    
         | 
| 
       71 
20 
     | 
    
         
             
            # vim: nowrap sw=2 sts=0 ts=2 ff=unix ft=ruby
         
     | 
    
        data/test/test_icmp.rb
    CHANGED
    
    
    
        data/test/test_ip.rb
    CHANGED
    
    
    
        data/test/test_ip6.rb
    CHANGED
    
    
    
        data/test/test_tcp.rb
    CHANGED
    
    
    
        data/test/test_udp.rb
    CHANGED
    
    
    
        data/test/udp_test.pcap
    CHANGED
    
    | 
         Binary file 
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification 
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: packetfu
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version 
         
     | 
| 
       4 
     | 
    
         
            -
              hash:  
     | 
| 
      
 4 
     | 
    
         
            +
              hash: 199653271
         
     | 
| 
       5 
5 
     | 
    
         
             
              prerelease: 6
         
     | 
| 
       6 
6 
     | 
    
         
             
              segments: 
         
     | 
| 
       7 
7 
     | 
    
         
             
              - 1
         
     | 
| 
       8 
8 
     | 
    
         
             
              - 0
         
     | 
| 
       9 
     | 
    
         
            -
              -  
     | 
| 
      
 9 
     | 
    
         
            +
              - 4
         
     | 
| 
       10 
10 
     | 
    
         
             
              - pre
         
     | 
| 
       11 
     | 
    
         
            -
              version: 1.0. 
     | 
| 
      
 11 
     | 
    
         
            +
              version: 1.0.4.pre
         
     | 
| 
       12 
12 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       13 
13 
     | 
    
         
             
            authors: 
         
     | 
| 
       14 
14 
     | 
    
         
             
            - Tod Beardsley
         
     | 
| 
         @@ -78,7 +78,6 @@ files: 
     | 
|
| 
       78 
78 
     | 
    
         
             
            - lib/packetfu/protos/hsrp.rb
         
     | 
| 
       79 
79 
     | 
    
         
             
            - lib/packetfu/utils.rb
         
     | 
| 
       80 
80 
     | 
    
         
             
            - lib/packetfu/packet.rb
         
     | 
| 
       81 
     | 
    
         
            -
            - CHANGES
         
     | 
| 
       82 
81 
     | 
    
         
             
            - INSTALL
         
     | 
| 
       83 
82 
     | 
    
         
             
            - LICENSE
         
     | 
| 
       84 
83 
     | 
    
         
             
            - README
         
     | 
| 
         @@ -88,7 +87,6 @@ files: 
     | 
|
| 
       88 
87 
     | 
    
         
             
            - test/udp_test.pcap
         
     | 
| 
       89 
88 
     | 
    
         
             
            - test/sample2.pcap
         
     | 
| 
       90 
89 
     | 
    
         
             
            - test/sample.pcap
         
     | 
| 
       91 
     | 
    
         
            -
            - test/dissect_thinger.rb
         
     | 
| 
       92 
90 
     | 
    
         
             
            - test/test_ip6.rb
         
     | 
| 
       93 
91 
     | 
    
         
             
            - test/all_tests.rb
         
     | 
| 
       94 
92 
     | 
    
         
             
            - test/test_invalid.rb
         
     | 
| 
         @@ -98,6 +96,7 @@ files: 
     | 
|
| 
       98 
96 
     | 
    
         
             
            - test/icmp_test.pcap
         
     | 
| 
       99 
97 
     | 
    
         
             
            - test/test_udp.rb
         
     | 
| 
       100 
98 
     | 
    
         
             
            - test/sample_hsrp_pcapr.cap
         
     | 
| 
      
 99 
     | 
    
         
            +
            - test/tcp_spec.rb
         
     | 
| 
       101 
100 
     | 
    
         
             
            - test/test_tcp.rb
         
     | 
| 
       102 
101 
     | 
    
         
             
            - test/tcp_test.pcap
         
     | 
| 
       103 
102 
     | 
    
         
             
            - test/test_arp.rb
         
     | 
| 
         @@ -127,6 +126,7 @@ files: 
     | 
|
| 
       127 
126 
     | 
    
         
             
            - examples/idsv2.rb
         
     | 
| 
       128 
127 
     | 
    
         
             
            - examples/ackscan.rb
         
     | 
| 
       129 
128 
     | 
    
         
             
            - examples/ids.rb
         
     | 
| 
      
 129 
     | 
    
         
            +
            - examples/new-simple-stats.rb
         
     | 
| 
       130 
130 
     | 
    
         
             
            has_rdoc: true
         
     | 
| 
       131 
131 
     | 
    
         
             
            homepage: http://code.google.com/p/packetfu/
         
     | 
| 
       132 
132 
     | 
    
         
             
            licenses: []
         
     | 
    
        data/CHANGES
    DELETED
    
    | 
         @@ -1,36 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            = Changelog
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            == Version 1.0.0 # to be released July 29, 2010
         
     | 
| 
       4 
     | 
    
         
            -
            	Missed a bunch of updates in the Changelog. Mea culpa.
         
     | 
| 
       5 
     | 
    
         
            -
            	Squashed all Ruby version bugs -- works now on 1.8.6, 1.8.7, 1.9.1, and 1.9.2-head.
         
     | 
| 
       6 
     | 
    
         
            -
            	Added ENV['IFACE'] parsing for interface selection. Sadly, rvmsudo doesn't preserve ENV by default, but system ruby should work fine. 
         
     | 
| 
       7 
     | 
    
         
            -
            	Removed my own distros of pcaprub. You're on your own, now, but shadowbq's or Metasploit's versions should do just fine.
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            == Version 0.1.1 # February 18, 2009
         
     | 
| 
       10 
     | 
    
         
            -
            	Added .is_proto? functions, self.proto function, Packet.headers attr_accessor across the board.
         
     | 
| 
       11 
     | 
    
         
            -
            	Removed dependency on pcaprub to read pcap-formatted files. (r54)
         
     | 
| 
       12 
     | 
    
         
            -
            	Added ability to preserve timestamps when reading files using :keep_ts => true argument on Read#f2a and Write honors both saved timestamp or invented timestamps. (r55)
         
     | 
| 
       13 
     | 
    
         
            -
              Various minor bugs. (r56)
         
     | 
| 
       14 
     | 
    
         
            -
            	Relaxed the requirement for PcapRub to 0.7-dev now that I handle packet reading on my own. Windows users and threading will be broke without 0.8-dev, though. (r57)
         
     | 
| 
       15 
     | 
    
         
            -
            	Endianness of pcap files (for both reading and writing) is now supported (r58).
         
     | 
| 
       16 
     | 
    
         
            -
            	Handle non-version-4 IP packets correctlier (r59) (thanks tmanning!).
         
     | 
| 
       17 
     | 
    
         
            -
            	Merge of Metasploit-local patches, including Write.append (byte-order safe). (r60)
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
            == Version 0.1.0 # September 13, 2008
         
     | 
| 
       20 
     | 
    
         
            -
              Various minor bugs fixed.
         
     | 
| 
       21 
     | 
    
         
            -
              Added a Windows compatability mode via a compiled pcaprub.
         
     | 
| 
       22 
     | 
    
         
            -
                Note: Works fine on XP, works okay on Vista. Users are encouraged to compile their own pcaprub installations.
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
            == Verison 0.0.3 # September 3, 2008 # r25
         
     | 
| 
       25 
     | 
    
         
            -
              First tagged version. Naturally, bugs were found that moment.
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
            == Version 0.3.0 # January 11, 2010 # r129
         
     | 
| 
       28 
     | 
    
         
            -
              Rewrote pretty much everything using Struct instead of BinData. Huge success.
         
     | 
| 
       29 
     | 
    
         
            -
              Start to get back in the habit of documentation changes.
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
            == Version 0.3.1 # FUTURE
         
     | 
| 
       32 
     | 
    
         
            -
              r130: Add convenience methods for checking the version.
         
     | 
| 
       33 
     | 
    
         
            -
              r131: Fix TCP option setting.
         
     | 
| 
       34 
     | 
    
         
            -
            	r132: pcaprub to 0.9-dev.
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
    
        data/test/dissect_thinger.rb
    DELETED
    
    | 
         @@ -1,15 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # This just allows you to eyeball the dissection stuff to make sure it's all right.
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            require File.join("..","lib","packetfu")
         
     | 
| 
       4 
     | 
    
         
            -
            puts "Loaded: PacketFu v#{PacketFu.version}"
         
     | 
| 
       5 
     | 
    
         
            -
            # $: << File.join(File.expand_path(File.dirname(__FILE__)),"..","lib")
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
            include PacketFu
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            packets = PcapFile.file_to_array "test/sample2.pcap"
         
     | 
| 
       10 
     | 
    
         
            -
            packets.each do |packet|
         
     | 
| 
       11 
     | 
    
         
            -
            	puts packet.inspect
         
     | 
| 
       12 
     | 
    
         
            -
            	pkt = Packet.parse(packet)
         
     | 
| 
       13 
     | 
    
         
            -
            	puts pkt.dissect
         
     | 
| 
       14 
     | 
    
         
            -
            	sleep 1
         
     | 
| 
       15 
     | 
    
         
            -
            end
         
     |