packetfu 1.1.11 → 1.1.12.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.
- 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
|
|