packetfu 1.1.11 → 1.1.12.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/.rspec +2 -0
- data/.travis.yml +2 -3
- data/README.md +127 -0
- data/examples/100kpackets.rb +11 -10
- data/examples/ackscan.rb +4 -1
- data/examples/arp.rb +4 -5
- data/examples/arphood.rb +5 -4
- data/examples/dissect_thinger.rb +10 -7
- data/examples/ethernet.rb +8 -3
- data/examples/ids.rb +22 -4
- data/examples/idsv2.rb +25 -6
- data/examples/ifconfig.rb +6 -3
- data/examples/new-simple-stats.rb +5 -6
- data/examples/packetfu-shell.rb +11 -48
- data/examples/pcap2pcapng.rb +32 -0
- data/examples/simple-sniffer.rb +9 -4
- data/examples/simple-stats.rb +7 -8
- data/examples/slammer.rb +2 -2
- data/examples/uniqpcap.rb +17 -7
- data/lib/packetfu.rb +10 -175
- data/lib/packetfu/capture.rb +2 -2
- data/lib/packetfu/common.rb +142 -0
- data/lib/packetfu/config.rb +8 -8
- data/lib/packetfu/inject.rb +3 -3
- data/lib/packetfu/packet.rb +22 -18
- data/lib/packetfu/pcap.rb +2 -1
- data/lib/packetfu/pcapng.rb +37 -0
- data/lib/packetfu/pcapng/block.rb +25 -0
- data/lib/packetfu/pcapng/epb.rb +112 -0
- data/lib/packetfu/pcapng/file.rb +316 -0
- data/lib/packetfu/pcapng/idb.rb +125 -0
- data/lib/packetfu/pcapng/shb.rb +146 -0
- data/lib/packetfu/pcapng/spb.rb +83 -0
- data/lib/packetfu/pcapng/unknown_block.rb +60 -0
- data/lib/packetfu/protos.rb +3 -0
- data/lib/packetfu/protos/arp.rb +10 -10
- data/lib/packetfu/protos/icmpv6.rb +131 -0
- data/lib/packetfu/protos/icmpv6/header.rb +69 -0
- data/lib/packetfu/protos/icmpv6/mixin.rb +14 -0
- data/lib/packetfu/protos/ip.rb +4 -5
- data/lib/packetfu/protos/ipv6/header.rb +2 -0
- data/lib/packetfu/protos/udp.rb +24 -12
- data/lib/packetfu/structfu.rb +27 -0
- data/lib/packetfu/utils.rb +55 -9
- data/lib/packetfu/version.rb +1 -1
- data/packetfu.gemspec +13 -7
- data/spec/arp_spec.rb +11 -5
- data/spec/eth_spec.rb +20 -11
- data/spec/fake_packets.rb +28 -0
- data/spec/hsrp_spec.rb +15 -0
- data/spec/icmp_spec.rb +12 -5
- data/spec/icmpv6_spec.rb +98 -0
- data/spec/invalid_spec.rb +28 -0
- data/spec/ip_spec.rb +10 -5
- data/spec/ipv4_icmp.pcap +0 -0
- data/spec/ipv4_udp.pcap +0 -0
- data/spec/ipv6_icmp.pcap +0 -0
- data/spec/ipv6_spec.rb +4 -0
- data/spec/ipv6_udp.pcap +0 -0
- data/spec/lldp_spec.rb +36 -0
- data/spec/octets_spec.rb +43 -0
- data/spec/packet_spec.rb +24 -0
- data/spec/packetfu_spec.rb +6 -1
- data/spec/pcap_spec.rb +286 -0
- data/spec/pcapng/epb_spec.rb +81 -0
- data/spec/pcapng/file_spec.rb +295 -0
- data/spec/pcapng/file_spec_helper.rb +45 -0
- data/spec/pcapng/idb_spec.rb +53 -0
- data/spec/pcapng/shb_spec.rb +42 -0
- data/spec/pcapng/spb_spec.rb +43 -0
- data/spec/pcapng/unknown_block_spec.rb +36 -0
- data/spec/spec_helper.rb +3 -31
- data/spec/tcp_spec.rb +4 -1
- data/spec/udp_spec.rb +149 -1
- data/spec/utils_spec.rb +98 -15
- data/test/pcapng-test/output_be/advanced/test100.pcapng +0 -0
- data/test/pcapng-test/output_be/advanced/test100.txt +11 -0
- data/test/pcapng-test/output_be/advanced/test101.pcapng +0 -0
- data/test/pcapng-test/output_be/advanced/test101.txt +11 -0
- data/test/pcapng-test/output_be/advanced/test102.pcapng +0 -0
- data/test/pcapng-test/output_be/advanced/test102.txt +14 -0
- data/test/pcapng-test/output_be/basic/test001.pcapng +0 -0
- data/test/pcapng-test/output_be/basic/test001.txt +9 -0
- data/test/pcapng-test/output_be/basic/test002.pcapng +0 -0
- data/test/pcapng-test/output_be/basic/test002.txt +7 -0
- data/test/pcapng-test/output_be/basic/test003.pcapng +0 -0
- data/test/pcapng-test/output_be/basic/test003.txt +8 -0
- data/test/pcapng-test/output_be/basic/test004.pcapng +0 -0
- data/test/pcapng-test/output_be/basic/test004.txt +9 -0
- data/test/pcapng-test/output_be/basic/test005.pcapng +0 -0
- data/test/pcapng-test/output_be/basic/test005.txt +9 -0
- data/test/pcapng-test/output_be/basic/test006.pcapng +0 -0
- data/test/pcapng-test/output_be/basic/test006.txt +9 -0
- data/test/pcapng-test/output_be/basic/test007.pcapng +0 -0
- data/test/pcapng-test/output_be/basic/test007.txt +9 -0
- data/test/pcapng-test/output_be/basic/test008.pcapng +0 -0
- data/test/pcapng-test/output_be/basic/test008.txt +9 -0
- data/test/pcapng-test/output_be/basic/test009.pcapng +0 -0
- data/test/pcapng-test/output_be/basic/test009.txt +9 -0
- data/test/pcapng-test/output_be/basic/test010.pcapng +0 -0
- data/test/pcapng-test/output_be/basic/test010.txt +9 -0
- data/test/pcapng-test/output_be/basic/test011.pcapng +0 -0
- data/test/pcapng-test/output_be/basic/test011.txt +10 -0
- data/test/pcapng-test/output_be/basic/test012.pcapng +0 -0
- data/test/pcapng-test/output_be/basic/test012.txt +10 -0
- data/test/pcapng-test/output_be/basic/test013.pcapng +0 -0
- data/test/pcapng-test/output_be/basic/test013.txt +9 -0
- data/test/pcapng-test/output_be/basic/test014.pcapng +0 -0
- data/test/pcapng-test/output_be/basic/test014.txt +9 -0
- data/test/pcapng-test/output_be/basic/test015.pcapng +0 -0
- data/test/pcapng-test/output_be/basic/test015.txt +9 -0
- data/test/pcapng-test/output_be/basic/test016.pcapng +0 -0
- data/test/pcapng-test/output_be/basic/test016.txt +11 -0
- data/test/pcapng-test/output_be/basic/test017.pcapng +0 -0
- data/test/pcapng-test/output_be/basic/test017.txt +9 -0
- data/test/pcapng-test/output_be/basic/test018.pcapng +0 -0
- data/test/pcapng-test/output_be/basic/test018.txt +12 -0
- data/test/pcapng-test/output_be/difficult/test200.pcapng +0 -0
- data/test/pcapng-test/output_be/difficult/test200.txt +8 -0
- data/test/pcapng-test/output_be/difficult/test201.pcapng +0 -0
- data/test/pcapng-test/output_be/difficult/test201.txt +11 -0
- data/test/pcapng-test/output_be/difficult/test202.pcapng +0 -0
- data/test/pcapng-test/output_be/difficult/test202.txt +14 -0
- data/test/pcapng-test/output_le/advanced/test100.pcapng +0 -0
- data/test/pcapng-test/output_le/advanced/test100.txt +11 -0
- data/test/pcapng-test/output_le/advanced/test101.pcapng +0 -0
- data/test/pcapng-test/output_le/advanced/test101.txt +11 -0
- data/test/pcapng-test/output_le/advanced/test102.pcapng +0 -0
- data/test/pcapng-test/output_le/advanced/test102.txt +14 -0
- data/test/pcapng-test/output_le/basic/test001.pcapng +0 -0
- data/test/pcapng-test/output_le/basic/test001.txt +9 -0
- data/test/pcapng-test/output_le/basic/test002.pcapng +0 -0
- data/test/pcapng-test/output_le/basic/test002.txt +7 -0
- data/test/pcapng-test/output_le/basic/test003.pcapng +0 -0
- data/test/pcapng-test/output_le/basic/test003.txt +8 -0
- data/test/pcapng-test/output_le/basic/test004.pcapng +0 -0
- data/test/pcapng-test/output_le/basic/test004.txt +9 -0
- data/test/pcapng-test/output_le/basic/test005.pcapng +0 -0
- data/test/pcapng-test/output_le/basic/test005.txt +9 -0
- data/test/pcapng-test/output_le/basic/test006.pcapng +0 -0
- data/test/pcapng-test/output_le/basic/test006.txt +9 -0
- data/test/pcapng-test/output_le/basic/test007.pcapng +0 -0
- data/test/pcapng-test/output_le/basic/test007.txt +9 -0
- data/test/pcapng-test/output_le/basic/test008.pcapng +0 -0
- data/test/pcapng-test/output_le/basic/test008.txt +9 -0
- data/test/pcapng-test/output_le/basic/test009.pcapng +0 -0
- data/test/pcapng-test/output_le/basic/test009.txt +9 -0
- data/test/pcapng-test/output_le/basic/test010.pcapng +0 -0
- data/test/pcapng-test/output_le/basic/test010.txt +9 -0
- data/test/pcapng-test/output_le/basic/test011.pcapng +0 -0
- data/test/pcapng-test/output_le/basic/test011.txt +10 -0
- data/test/pcapng-test/output_le/basic/test012.pcapng +0 -0
- data/test/pcapng-test/output_le/basic/test012.txt +10 -0
- data/test/pcapng-test/output_le/basic/test013.pcapng +0 -0
- data/test/pcapng-test/output_le/basic/test013.txt +9 -0
- data/test/pcapng-test/output_le/basic/test014.pcapng +0 -0
- data/test/pcapng-test/output_le/basic/test014.txt +9 -0
- data/test/pcapng-test/output_le/basic/test015.pcapng +0 -0
- data/test/pcapng-test/output_le/basic/test015.txt +9 -0
- data/test/pcapng-test/output_le/basic/test016.pcapng +0 -0
- data/test/pcapng-test/output_le/basic/test016.txt +11 -0
- data/test/pcapng-test/output_le/basic/test017.pcapng +0 -0
- data/test/pcapng-test/output_le/basic/test017.txt +9 -0
- data/test/pcapng-test/output_le/basic/test018.pcapng +0 -0
- data/test/pcapng-test/output_le/basic/test018.txt +12 -0
- data/test/pcapng-test/output_le/difficult/test200.pcapng +0 -0
- data/test/pcapng-test/output_le/difficult/test200.txt +8 -0
- data/test/pcapng-test/output_le/difficult/test201.pcapng +0 -0
- data/test/pcapng-test/output_le/difficult/test201.txt +11 -0
- data/test/pcapng-test/output_le/difficult/test202.pcapng +0 -0
- data/test/pcapng-test/output_le/difficult/test202.txt +14 -0
- data/test/sample-ipv6.pcapng +0 -0
- data/test/sample-spb.pcapng +0 -0
- data/test/sample.pcapng +0 -0
- data/test/sample2.pcapng +0 -0
- metadata +190 -68
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -2
- data/INSTALL.rdoc +0 -40
- data/README.rdoc +0 -64
- data/examples/examples.rb +0 -4
- data/setup.rb +0 -1586
- data/test/func_lldp.rb +0 -25
- data/test/ptest.rb +0 -16
- data/test/test_eth.rb +0 -93
- data/test/test_hsrp.rb +0 -20
- data/test/test_invalid.rb +0 -28
- data/test/test_octets.rb +0 -36
- data/test/test_pcap.rb +0 -211
- data/test/test_udp.rb +0 -100
- metadata.gz.sig +0 -2
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
3
|
+
module PacketFu
|
4
|
+
module PcapNG
|
5
|
+
|
6
|
+
# Pcapng::IDB represents a Interface Description Block (IDB) of a pcapng file.
|
7
|
+
#
|
8
|
+
# == Pcapng::IDB Definition
|
9
|
+
# Int32 :type Default: 0x00000001
|
10
|
+
# Int32 :block_len
|
11
|
+
# Int16 :link_type Default: 1
|
12
|
+
# Int16 :reserved Default: 0
|
13
|
+
# Int64 :snaplen Default: 0 (no limit)
|
14
|
+
# String :options
|
15
|
+
# Int32 :block_len2
|
16
|
+
class IDB < Struct.new(:type, :block_len, :link_type, :reserved,
|
17
|
+
:snaplen, :options, :block_len2)
|
18
|
+
include StructFu
|
19
|
+
include Block
|
20
|
+
attr_accessor :endian
|
21
|
+
attr_accessor :section
|
22
|
+
attr_accessor :packets
|
23
|
+
|
24
|
+
MIN_SIZE = 5*4
|
25
|
+
|
26
|
+
# Option code for if_tsresol option
|
27
|
+
OPTION_IF_TSRESOL = 9
|
28
|
+
|
29
|
+
def initialize(args={})
|
30
|
+
@endian = set_endianness(args[:endian] || :little)
|
31
|
+
@packets = []
|
32
|
+
@options_decoded = false
|
33
|
+
init_fields(args)
|
34
|
+
super(args[:type], args[:block_len], args[:link_type], args[:reserved],
|
35
|
+
args[:snaplen], args[:options], args[:block_len2])
|
36
|
+
end
|
37
|
+
|
38
|
+
# Used by #initialize to set the initial fields
|
39
|
+
def init_fields(args={})
|
40
|
+
args[:type] = @int32.new(args[:type] || PcapNG::IDB_TYPE.to_i)
|
41
|
+
args[:block_len] = @int32.new(args[:block_len] || MIN_SIZE)
|
42
|
+
args[:link_type] = @int16.new(args[:link_type] || 1)
|
43
|
+
args[:reserved] = @int16.new(args[:reserved] || 0)
|
44
|
+
args[:snaplen] = @int32.new(args[:snaplen] || 0)
|
45
|
+
args[:options] = StructFu::String.new(args[:options] || '')
|
46
|
+
args[:block_len2] = @int32.new(args[:block_len2] || MIN_SIZE)
|
47
|
+
args
|
48
|
+
end
|
49
|
+
|
50
|
+
def has_options?
|
51
|
+
self[:options].size > 0
|
52
|
+
end
|
53
|
+
|
54
|
+
# Reads a String or a IO to populate the object
|
55
|
+
def read(str_or_io)
|
56
|
+
if str_or_io.respond_to? :read
|
57
|
+
io = str_or_io
|
58
|
+
else
|
59
|
+
io = StringIO.new(force_binary(str_or_io.to_s))
|
60
|
+
end
|
61
|
+
return self if io.eof?
|
62
|
+
|
63
|
+
self[:type].read io.read(4)
|
64
|
+
self[:block_len].read io.read(4)
|
65
|
+
self[:link_type].read io.read(2)
|
66
|
+
self[:reserved].read io.read(2)
|
67
|
+
self[:snaplen].read io.read(4)
|
68
|
+
self[:options].read io.read(self[:block_len].to_i - MIN_SIZE)
|
69
|
+
self[:block_len2].read io.read(4)
|
70
|
+
|
71
|
+
unless self[:block_len].to_i == self[:block_len2].to_i
|
72
|
+
raise InvalidFileError, 'Incoherency in Interface Description Block'
|
73
|
+
end
|
74
|
+
|
75
|
+
self
|
76
|
+
end
|
77
|
+
|
78
|
+
# Add a xPB to this section
|
79
|
+
def <<(xpb)
|
80
|
+
@packets << xpb
|
81
|
+
end
|
82
|
+
|
83
|
+
# Give timestamp resolution for this interface
|
84
|
+
def ts_resol(force=false)
|
85
|
+
if @options_decoded and not force
|
86
|
+
@ts_resol
|
87
|
+
else
|
88
|
+
packstr = (@endian == :little) ? 'v' : 'n'
|
89
|
+
idx = 0
|
90
|
+
options = self[:options]
|
91
|
+
opt_code = opt_len = 0
|
92
|
+
|
93
|
+
while idx < options.length do
|
94
|
+
opt_code, opt_len = options[idx, 4].unpack("#{packstr}2")
|
95
|
+
if opt_code == OPTION_IF_TSRESOL and opt_len == 1
|
96
|
+
tsresol = options[idx+4, 1].unpack('C').first
|
97
|
+
if tsresol & 0x80 == 0
|
98
|
+
@ts_resol = 10 ** -tsresol
|
99
|
+
else
|
100
|
+
@ts_resol = 2 ** -(tsresol & 0x7f)
|
101
|
+
end
|
102
|
+
|
103
|
+
@options_decoded = true
|
104
|
+
return @ts_resol
|
105
|
+
else
|
106
|
+
idx += 4 + opt_len
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
@options_decoded = true
|
111
|
+
@ts_resol = 1E-6 # default value
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Return the object as a String
|
116
|
+
def to_s
|
117
|
+
pad_field :options
|
118
|
+
recalc_block_len
|
119
|
+
to_a.map(&:to_s).join + @packets.map(&:to_s).join
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
3
|
+
module PacketFu
|
4
|
+
module PcapNG
|
5
|
+
|
6
|
+
# PcapngSHB represents a Section Header Block (SHB) of a pcapng file.
|
7
|
+
#
|
8
|
+
# == PcapngSHB Definition
|
9
|
+
# Int32 :type Default: 0x0A0D0D0A
|
10
|
+
# Int32 :block_len
|
11
|
+
# Int32 :magic Default: 0x1A2B3C4D # :big is 0x4D3C2C1A
|
12
|
+
# Int16 :ver_major Default: 1
|
13
|
+
# Int16 :ver_minor Default: 0
|
14
|
+
# Int64 :section_len
|
15
|
+
# String :options Default: ''
|
16
|
+
# Int32 :block_len2
|
17
|
+
class SHB < Struct.new(:type, :block_len, :magic, :ver_major, :ver_minor,
|
18
|
+
:section_len, :options, :block_len2)
|
19
|
+
include StructFu
|
20
|
+
include Block
|
21
|
+
attr_accessor :endian
|
22
|
+
attr_reader :interfaces
|
23
|
+
# Get unsupported blocks given in pcapng file as raw data
|
24
|
+
attr_reader :unknown_blocks
|
25
|
+
|
26
|
+
MAGIC_INT32 = 0x1A2B3C4D
|
27
|
+
MAGIC_LITTLE = [MAGIC_INT32].pack('V')
|
28
|
+
MAGIC_BIG = [MAGIC_INT32].pack('N')
|
29
|
+
|
30
|
+
MIN_SIZE = 7*4
|
31
|
+
SECTION_LEN_UNDEFINED = 0xffffffff_ffffffff
|
32
|
+
|
33
|
+
def initialize(args={})
|
34
|
+
@endian = set_endianness(args[:endian] || :little)
|
35
|
+
@interfaces = []
|
36
|
+
@unknown_blocks = []
|
37
|
+
init_fields(args)
|
38
|
+
super(args[:type], args[:block_len], args[:magic], args[:ver_major],
|
39
|
+
args[:ver_minor], args[:section_len], args[:options], args[:block_len2])
|
40
|
+
end
|
41
|
+
|
42
|
+
# Used by #initialize to set the initial fields
|
43
|
+
def init_fields(args={})
|
44
|
+
args[:type] = @int32.new(args[:type] || PcapNG::SHB_TYPE.to_i)
|
45
|
+
args[:block_len] = @int32.new(args[:block_len] || MIN_SIZE)
|
46
|
+
args[:magic] = @int32.new(args[:magic] || MAGIC_INT32)
|
47
|
+
args[:ver_major] = @int16.new(args[:ver_major] || 1)
|
48
|
+
args[:ver_minor] = @int16.new(args[:ver_minor] || 0)
|
49
|
+
args[:section_len] = @int64.new(args[:section_len] || SECTION_LEN_UNDEFINED)
|
50
|
+
args[:options] = StructFu::String.new(args[:options] || '')
|
51
|
+
args[:block_len2] = @int32.new(args[:block_len2] || MIN_SIZE)
|
52
|
+
args
|
53
|
+
end
|
54
|
+
|
55
|
+
def has_options?
|
56
|
+
self[:options].size > 0
|
57
|
+
end
|
58
|
+
|
59
|
+
# Reads a String or a IO to populate the object
|
60
|
+
def read(str_or_io)
|
61
|
+
if str_or_io.respond_to? :read
|
62
|
+
io = str_or_io
|
63
|
+
else
|
64
|
+
io = StringIO.new(force_binary(str_or_io.to_s))
|
65
|
+
end
|
66
|
+
return self if io.eof?
|
67
|
+
|
68
|
+
type_str = io.read(4)
|
69
|
+
unless type_str == PcapNG::SHB_TYPE.to_s
|
70
|
+
type = type_str.unpack('H*').join
|
71
|
+
raise InvalidFileError, "Incorrect type (#{type})for Section Header Block"
|
72
|
+
end
|
73
|
+
|
74
|
+
block_len_str = io.read(4)
|
75
|
+
|
76
|
+
magic_str = io.read(4)
|
77
|
+
case @endian
|
78
|
+
when :little
|
79
|
+
case magic_str
|
80
|
+
when MAGIC_LITTLE
|
81
|
+
when MAGIC_BIG
|
82
|
+
force_endianness :big
|
83
|
+
else
|
84
|
+
raise InvalidFileError, 'Incorrect magic for Section Header Block'
|
85
|
+
end
|
86
|
+
when :big
|
87
|
+
case magic_str
|
88
|
+
when MAGIC_BIG
|
89
|
+
when MAGIC_LITTLE
|
90
|
+
force_endianness :little
|
91
|
+
else
|
92
|
+
raise InvalidFileError, 'Incorrect magic for Section Header Block'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
self[:type].read type_str
|
97
|
+
self[:block_len].read block_len_str
|
98
|
+
self[:magic].read magic_str
|
99
|
+
self[:ver_major].read io.read(2)
|
100
|
+
self[:ver_minor].read io.read(2)
|
101
|
+
self[:section_len].read io.read(8)
|
102
|
+
self[:options].read io.read(self[:block_len].to_i - MIN_SIZE)
|
103
|
+
self[:block_len2].read io.read(4)
|
104
|
+
|
105
|
+
unless self[:block_len].to_i == self[:block_len2].to_i
|
106
|
+
raise InvalidFileError, 'Incoherency in Section Header Block'
|
107
|
+
end
|
108
|
+
|
109
|
+
self
|
110
|
+
end
|
111
|
+
|
112
|
+
# Add a IDB to this section
|
113
|
+
def <<(idb)
|
114
|
+
@interfaces << idb
|
115
|
+
end
|
116
|
+
|
117
|
+
# Return the object as a String
|
118
|
+
def to_s
|
119
|
+
body = @interfaces.map(&:to_s).join
|
120
|
+
unless self[:section_len].to_i == SECTION_LEN_UNDEFINED
|
121
|
+
self.section_len.value = body.size
|
122
|
+
end
|
123
|
+
pad_field :options
|
124
|
+
recalc_block_len
|
125
|
+
to_a.map(&:to_s).join + body
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
def force_endianness(endian)
|
132
|
+
set_endianness endian
|
133
|
+
@endian = endian
|
134
|
+
self[:type] = @int32.new(self[:type].to_i)
|
135
|
+
self[:block_len] = @int32.new(self[:block_len].to_i)
|
136
|
+
self[:magic] = @int32.new(self[:magic].to_i)
|
137
|
+
self[:ver_major] = @int16.new(self[:ver_major].to_i)
|
138
|
+
self[:ver_minor] = @int16.new(self[:ver_minor].to_i)
|
139
|
+
self[:section_len] = @int64.new(self[:section_len].to_i)
|
140
|
+
self[:block_len2] = @int32.new(self[:block_len2].to_i)
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
3
|
+
module PacketFu
|
4
|
+
module PcapNG
|
5
|
+
|
6
|
+
# Pcapng::SPB represents a Section Simple Packet Block (SPB) of a pcapng file.
|
7
|
+
#
|
8
|
+
# == Pcapng::SPB Definition
|
9
|
+
# Int32 :type Default: 0x00000003
|
10
|
+
# Int32 :block_len
|
11
|
+
# Int32 :orig_len
|
12
|
+
# String :data
|
13
|
+
# Int32 :block_len2
|
14
|
+
class SPB < Struct.new(:type, :block_len, :orig_len, :data, :block_len2)
|
15
|
+
include StructFu
|
16
|
+
include Block
|
17
|
+
attr_accessor :endian
|
18
|
+
attr_accessor :interface
|
19
|
+
|
20
|
+
MIN_SIZE = 4*4
|
21
|
+
|
22
|
+
def initialize(args={})
|
23
|
+
@endian = set_endianness(args[:endian] || :little)
|
24
|
+
init_fields(args)
|
25
|
+
super(args[:type], args[:block_len], args[:orig_len], args[:data],
|
26
|
+
args[:block_len2])
|
27
|
+
end
|
28
|
+
|
29
|
+
# Used by #initialize to set the initial fields
|
30
|
+
def init_fields(args={})
|
31
|
+
args[:type] = @int32.new(args[:type] || PcapNG::SPB_TYPE.to_i)
|
32
|
+
args[:block_len] = @int32.new(args[:block_len] || MIN_SIZE)
|
33
|
+
args[:orig_len] = @int32.new(args[:orig_len] || 0)
|
34
|
+
args[:data] = StructFu::String.new(args[:data] || '')
|
35
|
+
args[:block_len2] = @int32.new(args[:block_len2] || MIN_SIZE)
|
36
|
+
args
|
37
|
+
end
|
38
|
+
|
39
|
+
def has_options?
|
40
|
+
false
|
41
|
+
end
|
42
|
+
|
43
|
+
def read(str_or_io)
|
44
|
+
if str_or_io.respond_to? :read
|
45
|
+
io = str_or_io
|
46
|
+
else
|
47
|
+
io = StringIO.new(force_binary(str_or_io.to_s))
|
48
|
+
end
|
49
|
+
return self if io.eof?
|
50
|
+
|
51
|
+
self[:type].read io.read(4)
|
52
|
+
self[:block_len].read io.read(4)
|
53
|
+
self[:orig_len].read io.read(4)
|
54
|
+
# Take care of IDB snaplen
|
55
|
+
# CAUTION: snaplen == 0 -> no capture limit
|
56
|
+
if interface and interface.snaplen.to_i > 0
|
57
|
+
data_len = [self[:orig_len].to_i, interface.snaplen.to_i].min
|
58
|
+
else
|
59
|
+
data_len = self[:orig_len].to_i
|
60
|
+
end
|
61
|
+
data_pad_len = (4 - (data_len % 4)) % 4
|
62
|
+
self[:data].read io.read(data_len)
|
63
|
+
io.read data_pad_len
|
64
|
+
self[:block_len2].read io.read(4)
|
65
|
+
|
66
|
+
unless self[:block_len].to_i == self[:block_len2].to_i
|
67
|
+
raise InvalidFileError, 'Incoherency in Simple Packet Block'
|
68
|
+
end
|
69
|
+
|
70
|
+
self
|
71
|
+
end
|
72
|
+
|
73
|
+
# Return the object as a String
|
74
|
+
def to_s
|
75
|
+
pad_field :data
|
76
|
+
recalc_block_len
|
77
|
+
to_a.map(&:to_s).join
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
3
|
+
module PacketFu
|
4
|
+
module PcapNG
|
5
|
+
|
6
|
+
# Pcapng::UnknownBlock is used to handle unsupported blocks of a pcapng file.
|
7
|
+
class UnknownBlock < Struct.new(:type, :block_len, :body, :block_len2)
|
8
|
+
include StructFu
|
9
|
+
include Block
|
10
|
+
attr_accessor :endian
|
11
|
+
attr_accessor :section
|
12
|
+
|
13
|
+
MIN_SIZE = 12
|
14
|
+
|
15
|
+
def initialize(args={})
|
16
|
+
@endian = set_endianness(args[:endian] || :little)
|
17
|
+
init_fields(args)
|
18
|
+
super(args[:type], args[:block_len], args[:body], args[:block_len2])
|
19
|
+
end
|
20
|
+
|
21
|
+
# Used by #initialize to set the initial fields
|
22
|
+
def init_fields(args={})
|
23
|
+
args[:type] = @int32.new(args[:type] || 0)
|
24
|
+
args[:block_len] = @int32.new(args[:block_len] || MIN_SIZE)
|
25
|
+
args[:body] = StructFu::String.new(args[:body] || '')
|
26
|
+
args[:block_len2] = @int32.new(args[:block_len2] || MIN_SIZE)
|
27
|
+
args
|
28
|
+
end
|
29
|
+
|
30
|
+
def read(str_or_io)
|
31
|
+
if str_or_io.respond_to? :read
|
32
|
+
io = str_or_io
|
33
|
+
else
|
34
|
+
io = StringIO.new(force_binary(str_or_io.to_s))
|
35
|
+
end
|
36
|
+
return self if io.eof?
|
37
|
+
|
38
|
+
self[:type].read io.read(4)
|
39
|
+
self[:block_len].read io.read(4)
|
40
|
+
self[:body].read io.read(self[:block_len].to_i - MIN_SIZE)
|
41
|
+
self[:block_len2].read io.read(4)
|
42
|
+
|
43
|
+
unless self[:block_len].to_i == self[:block_len2].to_i
|
44
|
+
raise InvalidFileError, 'Incoherency in Header Block'
|
45
|
+
end
|
46
|
+
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
# Return the object as a String
|
51
|
+
def to_s
|
52
|
+
pad_field :body
|
53
|
+
recalc_block_len
|
54
|
+
to_a.map(&:to_s).join
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
data/lib/packetfu/protos/arp.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- coding: binary -*-
|
2
|
+
require 'packetfu/common'
|
2
3
|
require 'packetfu/protos/eth/header'
|
3
4
|
require 'packetfu/protos/eth/mixin'
|
4
|
-
|
5
5
|
require 'packetfu/protos/arp/header'
|
6
6
|
require 'packetfu/protos/arp/mixin'
|
7
7
|
|
@@ -16,7 +16,7 @@ module PacketFu
|
|
16
16
|
# arp_pkt.arp_saddr_ip="10.10.10.17" # Your IP address
|
17
17
|
# arp_pkt.arp_daddr_ip="10.10.10.1" # Target IP address
|
18
18
|
# arp_pkt.arp_opcode=1 # Request
|
19
|
-
#
|
19
|
+
#
|
20
20
|
# arp_pkt.to_w('eth0') # Inject on the wire. (requires root)
|
21
21
|
# arp_pkt.to_f('/tmp/arp.pcap') # Write to a file.
|
22
22
|
#
|
@@ -24,7 +24,7 @@ module PacketFu
|
|
24
24
|
#
|
25
25
|
# :flavor
|
26
26
|
# Sets the "flavor" of the ARP packet. Choices are currently:
|
27
|
-
# :windows, :linux, :hp_deskjet
|
27
|
+
# :windows, :linux, :hp_deskjet
|
28
28
|
# :eth
|
29
29
|
# A pre-generated EthHeader object. If not specified, a new one will be created.
|
30
30
|
# :arp
|
@@ -53,23 +53,23 @@ module PacketFu
|
|
53
53
|
|
54
54
|
def initialize(args={})
|
55
55
|
@eth_header = EthHeader.new(args).read(args[:eth])
|
56
|
-
@arp_header = ARPHeader.new(args).read(args[:arp])
|
56
|
+
@arp_header = ARPHeader.new(args).read(args[:arp])
|
57
57
|
@eth_header.eth_proto = "\x08\x06"
|
58
58
|
@eth_header.body=@arp_header
|
59
59
|
|
60
60
|
# Please send more flavors to todb+packetfu@planb-security.net.
|
61
61
|
# Most of these initial fingerprints come from one (1) sample.
|
62
62
|
case (args[:flavor].nil?) ? :nil : args[:flavor].to_s.downcase.intern
|
63
|
-
when :windows; @arp_header.body = "\x00" * 64 # 64 bytes of padding
|
64
|
-
when :linux; @arp_header.body = "\x00" * 4 + # 32 bytes of padding
|
63
|
+
when :windows; @arp_header.body = "\x00" * 64 # 64 bytes of padding
|
64
|
+
when :linux; @arp_header.body = "\x00" * 4 + # 32 bytes of padding
|
65
65
|
"\x00\x07\x5c\x14" + "\x00" * 4 +
|
66
66
|
"\x00\x0f\x83\x34" + "\x00\x0f\x83\x74" +
|
67
|
-
"\x01\x11\x83\x78" + "\x00\x00\x00\x0c" +
|
67
|
+
"\x01\x11\x83\x78" + "\x00\x00\x00\x0c" +
|
68
68
|
"\x00\x00\x00\x00"
|
69
69
|
when :hp_deskjet; # Pads up to 60 bytes.
|
70
|
-
@arp_header.body = "\xe0\x90\x0d\x6c" +
|
71
|
-
"\xff\xff\xee\xee" + "\x00" * 4 +
|
72
|
-
"\xe0\x8f\xfa\x18\x00\x20"
|
70
|
+
@arp_header.body = "\xe0\x90\x0d\x6c" +
|
71
|
+
"\xff\xff\xee\xee" + "\x00" * 4 +
|
72
|
+
"\xe0\x8f\xfa\x18\x00\x20"
|
73
73
|
else; @arp_header.body = "\x00" * 18 # Pads up to 60 bytes.
|
74
74
|
end
|
75
75
|
|