packetgen 1.2.0 → 1.3.0
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/README.md +2 -2
- data/lib/packetgen/header/arp.rb +54 -125
- data/lib/packetgen/header/base.rb +175 -0
- data/lib/packetgen/header/dns/name.rb +110 -0
- data/lib/packetgen/header/dns/opt.rb +137 -0
- data/lib/packetgen/header/dns/option.rb +17 -0
- data/lib/packetgen/header/dns/qdsection.rb +39 -0
- data/lib/packetgen/header/dns/question.rb +129 -0
- data/lib/packetgen/header/dns/rr.rb +89 -0
- data/lib/packetgen/header/dns/rrsection.rb +72 -0
- data/lib/packetgen/header/dns.rb +276 -0
- data/lib/packetgen/header/esp.rb +38 -70
- data/lib/packetgen/header/eth.rb +35 -106
- data/lib/packetgen/header/icmp.rb +19 -70
- data/lib/packetgen/header/icmpv6.rb +3 -3
- data/lib/packetgen/header/ip.rb +54 -210
- data/lib/packetgen/header/ipv6.rb +73 -164
- data/lib/packetgen/header/tcp/option.rb +34 -50
- data/lib/packetgen/header/tcp/options.rb +19 -20
- data/lib/packetgen/header/tcp.rb +66 -129
- data/lib/packetgen/header/udp.rb +31 -88
- data/lib/packetgen/header.rb +5 -10
- data/lib/packetgen/inspect.rb +5 -4
- data/lib/packetgen/packet.rb +74 -57
- data/lib/packetgen/pcapng/block.rb +49 -7
- data/lib/packetgen/pcapng/epb.rb +36 -34
- data/lib/packetgen/pcapng/file.rb +24 -8
- data/lib/packetgen/pcapng/idb.rb +28 -33
- data/lib/packetgen/pcapng/shb.rb +35 -39
- data/lib/packetgen/pcapng/spb.rb +18 -27
- data/lib/packetgen/pcapng/unknown_block.rb +11 -21
- data/lib/packetgen/pcapng.rb +9 -7
- data/lib/packetgen/types/array.rb +56 -0
- data/lib/packetgen/types/fields.rb +325 -0
- data/lib/packetgen/types/int.rb +164 -0
- data/lib/packetgen/types/int_string.rb +69 -0
- data/lib/packetgen/types/string.rb +36 -0
- data/lib/packetgen/types/tlv.rb +41 -0
- data/lib/packetgen/types.rb +13 -0
- data/lib/packetgen/version.rb +1 -1
- data/lib/packetgen.rb +1 -1
- metadata +19 -6
- data/lib/packetgen/header/header_class_methods.rb +0 -106
- data/lib/packetgen/header/header_methods.rb +0 -73
- data/lib/packetgen/structfu.rb +0 -363
data/lib/packetgen/header/esp.rb
CHANGED
@@ -5,12 +5,12 @@ module PacketGen
|
|
5
5
|
class CipherError < Error;end
|
6
6
|
|
7
7
|
# A ESP header consists of:
|
8
|
-
# * a Security Parameters Index (#{spi}, {Int32} type),
|
8
|
+
# * a Security Parameters Index (#{spi}, {Types::Int32} type),
|
9
9
|
# * a Sequence Number ({#sn}, +Int32+ type),
|
10
10
|
# * a {#body} (variable length),
|
11
11
|
# * an optional TFC padding ({#tfc}, variable length),
|
12
12
|
# * an optional {#padding} (to align ESP on 32-bit boundary, variable length),
|
13
|
-
# * a {#pad_length} ({Int8}),
|
13
|
+
# * a {#pad_length} ({Types::Int8}),
|
14
14
|
# * a Next header field ({#next}, +Int8+),
|
15
15
|
# * and an optional Integrity Check Value ({#icv}, variable length).
|
16
16
|
#
|
@@ -62,11 +62,7 @@ module PacketGen
|
|
62
62
|
#
|
63
63
|
# pkt.esp.decrypt! cipher, intmode: hmac # => true if ICV check OK
|
64
64
|
# @author Sylvain Daubert
|
65
|
-
class ESP <
|
66
|
-
:pad_length, :next, :icv)
|
67
|
-
include StructFu
|
68
|
-
include HeaderMethods
|
69
|
-
extend HeaderClassMethods
|
65
|
+
class ESP < Base
|
70
66
|
|
71
67
|
# IP protocol number for ESP
|
72
68
|
IP_PROTOCOL = 50
|
@@ -74,6 +70,38 @@ module PacketGen
|
|
74
70
|
# Well-known UDP port for ESP
|
75
71
|
UDP_PORT = 4500
|
76
72
|
|
73
|
+
# @!attribute spi
|
74
|
+
# 32-bit Security Parameter Index
|
75
|
+
# @return [Integer]
|
76
|
+
define_field :spi, Types::Int32
|
77
|
+
# @!attribute sn
|
78
|
+
# 32-bit Sequence Number
|
79
|
+
# @return [Integer]
|
80
|
+
define_field :sn, Types::Int32
|
81
|
+
# @!attribute body
|
82
|
+
# @return [Types::String,Header::Base]
|
83
|
+
define_field :body, Types::String
|
84
|
+
# @!attribute tfc
|
85
|
+
# Traffic Flow Confidentiality padding
|
86
|
+
# @return [Types::String,Header::Base]
|
87
|
+
define_field :tfc, Types::String
|
88
|
+
# @!attribute padding
|
89
|
+
# ESP padding
|
90
|
+
# @return [Types::String,Header::Base]
|
91
|
+
define_field :padding, Types::String
|
92
|
+
# @!attribute pad_length
|
93
|
+
# 8-bit padding length
|
94
|
+
# @return [Integer]
|
95
|
+
define_field :pad_length, Types::Int8
|
96
|
+
# @!attribute next
|
97
|
+
# 8-bit next protocol value
|
98
|
+
# @return [Integer]
|
99
|
+
define_field :next, Types::Int8
|
100
|
+
# @!attribute icv
|
101
|
+
# Integrity Check Value
|
102
|
+
# @return [Types::String,Header::Base]
|
103
|
+
define_field :icv, Types::String
|
104
|
+
|
77
105
|
# ICV (Integrity Check Value) length
|
78
106
|
# @return [Integer]
|
79
107
|
attr_accessor :icv_length
|
@@ -92,14 +120,7 @@ module PacketGen
|
|
92
120
|
# @option options [::String] :icv Integrity Check Value
|
93
121
|
def initialize(options={})
|
94
122
|
@icv_length = options[:icv_length] || 0
|
95
|
-
super
|
96
|
-
Int32.new(options[:sn]),
|
97
|
-
StructFu::String.new.read(options[:body]),
|
98
|
-
StructFu::String.new.read(options[:tfc]),
|
99
|
-
StructFu::String.new.read(options[:padding]),
|
100
|
-
Int8.new(options[:pad_length]),
|
101
|
-
Int8.new(options[:next]),
|
102
|
-
StructFu::String.new.read(options[:icv])
|
123
|
+
super
|
103
124
|
end
|
104
125
|
|
105
126
|
# Read a ESP packet from string.
|
@@ -111,7 +132,6 @@ module PacketGen
|
|
111
132
|
# @return [self]
|
112
133
|
def read(str)
|
113
134
|
return self if str.nil?
|
114
|
-
raise ParseError, 'string too short for ESP' if str.size < self.sz
|
115
135
|
force_binary str
|
116
136
|
self[:spi].read str[0, 4]
|
117
137
|
self[:sn].read str[4, 4]
|
@@ -124,58 +144,6 @@ module PacketGen
|
|
124
144
|
self
|
125
145
|
end
|
126
146
|
|
127
|
-
# Getter for SPI attribute
|
128
|
-
# @return [Integer]
|
129
|
-
def spi
|
130
|
-
self[:spi].to_i
|
131
|
-
end
|
132
|
-
|
133
|
-
# Setter for SPI attribute
|
134
|
-
# @param [Integer] val
|
135
|
-
# @return [Integer]
|
136
|
-
def spi=(val)
|
137
|
-
typecast val
|
138
|
-
end
|
139
|
-
|
140
|
-
# Getter for SN attribute
|
141
|
-
# @return [Integer]
|
142
|
-
def sn
|
143
|
-
self[:sn].to_i
|
144
|
-
end
|
145
|
-
|
146
|
-
# Setter for SN attribute
|
147
|
-
# @param [Integer] val
|
148
|
-
# @return [Integer]
|
149
|
-
def sn=(val)
|
150
|
-
typecast val
|
151
|
-
end
|
152
|
-
|
153
|
-
# Getter for +pad_length+ attribute
|
154
|
-
# @return [Integer]
|
155
|
-
def pad_length
|
156
|
-
self[:pad_length].to_i
|
157
|
-
end
|
158
|
-
|
159
|
-
# Setter for +pad_length+ attribute
|
160
|
-
# @param [Integer] val
|
161
|
-
# @return [Integer]
|
162
|
-
def pad_length=(val)
|
163
|
-
typecast val
|
164
|
-
end
|
165
|
-
|
166
|
-
# Getter for +next+ attribute
|
167
|
-
# @return [Integer]
|
168
|
-
def next
|
169
|
-
self[:next].to_i
|
170
|
-
end
|
171
|
-
|
172
|
-
# Setter for +next+ attribute
|
173
|
-
# @param [Integer] val
|
174
|
-
# @return [Integer]
|
175
|
-
def next=(val)
|
176
|
-
typecast val
|
177
|
-
end
|
178
|
-
|
179
147
|
# Encrypt in-place ESP payload and trailer.
|
180
148
|
#
|
181
149
|
# This method removes all data from +tfc+ and +padding+ fields, as their
|
@@ -252,7 +220,7 @@ module PacketGen
|
|
252
220
|
# as padding is used to pad for CBC mode, this is unused
|
253
221
|
cipher.final
|
254
222
|
|
255
|
-
self[:body] =
|
223
|
+
self[:body] = Types::String.new(iv) << enc_msg[0..-3]
|
256
224
|
self[:pad_length].read enc_msg[-2]
|
257
225
|
self[:next].read enc_msg[-1]
|
258
226
|
|
@@ -364,7 +332,7 @@ module PacketGen
|
|
364
332
|
def get_auth_data(opt)
|
365
333
|
ad = self[:spi].to_s
|
366
334
|
if opt[:esn]
|
367
|
-
@esn =
|
335
|
+
@esn = Types::Int32.new(opt[:esn])
|
368
336
|
ad << @esn.to_s if @conf.authenticated?
|
369
337
|
end
|
370
338
|
ad << self[:sn].to_s
|
data/lib/packetgen/header/eth.rb
CHANGED
@@ -9,8 +9,8 @@ module PacketGen
|
|
9
9
|
# An Ethernet header consists of:
|
10
10
|
# * a destination MAC address ({MacAddr}),
|
11
11
|
# * a source MAC address (MacAddr),
|
12
|
-
# * a {#ethertype} ({Int16}),
|
13
|
-
# * and a body (a {String} or another Header class).
|
12
|
+
# * a {#ethertype} ({Types::Int16}),
|
13
|
+
# * and a body (a {Types::String} or another Header class).
|
14
14
|
#
|
15
15
|
# == Create a Ethernet header
|
16
16
|
# # standalone
|
@@ -28,33 +28,30 @@ module PacketGen
|
|
28
28
|
# eth.body = "This is a body"
|
29
29
|
#
|
30
30
|
# @author Sylvain Daubert
|
31
|
-
class Eth <
|
32
|
-
include StructFu
|
33
|
-
include HeaderMethods
|
34
|
-
extend HeaderClassMethods
|
31
|
+
class Eth < Base
|
35
32
|
|
36
33
|
# Ethernet MAC address, as a group of 6 bytes
|
37
34
|
# @author Sylvain Daubert
|
38
|
-
class MacAddr <
|
39
|
-
|
35
|
+
class MacAddr < Base
|
36
|
+
# @!attribute a0
|
37
|
+
# @return [Integer] first byte from MacAddr
|
38
|
+
define_field :a0, Types::Int8
|
39
|
+
# @!attribute a1
|
40
|
+
# @return [Integer] second byte from MacAddr
|
41
|
+
define_field :a1, Types::Int8
|
42
|
+
# @!attribute a2
|
43
|
+
# @return [Integer] third byte from MacAddr
|
44
|
+
define_field :a2, Types::Int8
|
45
|
+
# @!attribute a3
|
46
|
+
# @return [Integer] fourth byte from MacAddr
|
47
|
+
define_field :a3, Types::Int8
|
48
|
+
# @!attribute a4
|
49
|
+
# @return [Integer] fifth byte from MacAddr
|
50
|
+
define_field :a4, Types::Int8
|
51
|
+
# @!attribute a5
|
52
|
+
# @return [Integer] sixth byte from MacAddr
|
53
|
+
define_field :a5, Types::Int8
|
40
54
|
|
41
|
-
# @param [Hash] options
|
42
|
-
# @option options [Integer] :a0
|
43
|
-
# @option options [Integer] :a1
|
44
|
-
# @option options [Integer] :a2
|
45
|
-
# @option options [Integer] :a3
|
46
|
-
# @option options [Integer] :a4
|
47
|
-
# @option options [Integer] :a5
|
48
|
-
def initialize(options={})
|
49
|
-
super Int8.new(options[:a0]),
|
50
|
-
Int8.new(options[:a1]),
|
51
|
-
Int8.new(options[:a2]),
|
52
|
-
Int8.new(options[:a3]),
|
53
|
-
Int8.new(options[:a4]),
|
54
|
-
Int8.new(options[:a5])
|
55
|
-
|
56
|
-
end
|
57
|
-
|
58
55
|
# Read a human-readable string to populate +MacAddr+
|
59
56
|
# @param [String] str
|
60
57
|
# @return [self]
|
@@ -73,27 +70,10 @@ module PacketGen
|
|
73
70
|
self
|
74
71
|
end
|
75
72
|
|
76
|
-
# Read a +MacAddr+ from a binary string
|
77
|
-
# @param [String] str binary string
|
78
|
-
# @return [self]
|
79
|
-
def read(str)
|
80
|
-
return self if str.nil?
|
81
|
-
raise ParseError, 'string too short for Eth' if str.size < self.sz
|
82
|
-
force_binary str
|
83
|
-
[:a0, :a1, :a2, :a3, :a4, :a5].each_with_index do |byte, i|
|
84
|
-
self[byte].read str[i, 1]
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
[:a0, :a1, :a2, :a3, :a4, :a5].each do |sym|
|
89
|
-
class_eval "def #{sym}; self[:#{sym}].to_i; end\n" \
|
90
|
-
"def #{sym}=(v); self[:#{sym}].read v; end"
|
91
|
-
end
|
92
|
-
|
93
73
|
# +MacAddr+ in human readable form (colon format)
|
94
74
|
# @return [String]
|
95
75
|
def to_human
|
96
|
-
|
76
|
+
fields.map { |m| "#{'%02x' % self[m]}" }.join(':')
|
97
77
|
end
|
98
78
|
end
|
99
79
|
|
@@ -104,69 +84,18 @@ module PacketGen
|
|
104
84
|
# @private timeout for PCAPRUB
|
105
85
|
PCAP_TIMEOUT = 1
|
106
86
|
|
107
|
-
#
|
108
|
-
#
|
109
|
-
|
110
|
-
#
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
# @param [String] str binary string
|
120
|
-
# @return [self]
|
121
|
-
def read(str)
|
122
|
-
return self if str.nil?
|
123
|
-
raise ParseError, 'string too short for Eth' if str.size < self.sz
|
124
|
-
force_binary str
|
125
|
-
self[:dst].read str[0, 6]
|
126
|
-
self[:src].read str[6, 6]
|
127
|
-
self[:ethertype].read str[12, 2]
|
128
|
-
self[:body].read str[14..-1]
|
129
|
-
self
|
130
|
-
end
|
131
|
-
|
132
|
-
# Get MAC destination address
|
133
|
-
# @return [String]
|
134
|
-
def dst
|
135
|
-
self[:dst].to_human
|
136
|
-
end
|
137
|
-
|
138
|
-
# Set MAC destination address
|
139
|
-
# @param [String] addr
|
140
|
-
# @return [String]
|
141
|
-
def dst=(addr)
|
142
|
-
self[:dst].from_human addr
|
143
|
-
end
|
144
|
-
|
145
|
-
# Get MAC source address
|
146
|
-
# @return [String]
|
147
|
-
def src
|
148
|
-
self[:src].to_human
|
149
|
-
end
|
150
|
-
|
151
|
-
# Set MAC source address
|
152
|
-
# @param [String] addr
|
153
|
-
# @return [String]
|
154
|
-
def src=(addr)
|
155
|
-
self[:src].from_human addr
|
156
|
-
end
|
157
|
-
|
158
|
-
# Get ethertype field
|
159
|
-
# @return [Integer]
|
160
|
-
def ethertype
|
161
|
-
self[:ethertype].to_i
|
162
|
-
end
|
163
|
-
|
164
|
-
# Set ethertype field
|
165
|
-
# @param [Integer] type
|
166
|
-
# @return [Integer]
|
167
|
-
def ethertype=(type)
|
168
|
-
self[:ethertype].value = type
|
169
|
-
end
|
87
|
+
# @!attribute dst
|
88
|
+
# @return [MacAddr] Destination MAC address
|
89
|
+
define_field :dst, MacAddr, default: '00:00:00:00:00:00'
|
90
|
+
# @!attribute src
|
91
|
+
# @return [MacAddr] Source MAC address
|
92
|
+
define_field :src, MacAddr, default: '00:00:00:00:00:00'
|
93
|
+
# @!attribute ethertype
|
94
|
+
# @return [Integer] 16-bit integer to determine payload type
|
95
|
+
define_field :ethertype, Types::Int16, default: 0
|
96
|
+
# @!attribute body
|
97
|
+
# @return [Types::String,Header::Base]
|
98
|
+
define_field :body, Types::String
|
170
99
|
|
171
100
|
# send Eth packet on wire.
|
172
101
|
# @param [String] iface interface name
|
@@ -7,9 +7,9 @@ module PacketGen
|
|
7
7
|
module Header
|
8
8
|
|
9
9
|
# A ICMP header consists of:
|
10
|
-
# * a {#type} field ({Int8} type),
|
11
|
-
# * a {#code} field ({Int8} type),
|
12
|
-
# * a {#checksum} field ({Int16} type),
|
10
|
+
# * a {#type} field ({Types::Int8} type),
|
11
|
+
# * a {#code} field ({Types::Int8} type),
|
12
|
+
# * a {#checksum} field ({Types::Int16} type),
|
13
13
|
# * and a {#body}.
|
14
14
|
#
|
15
15
|
# == Create a ICMP header
|
@@ -26,38 +26,26 @@ module PacketGen
|
|
26
26
|
# icmp.checksum = 0x248a
|
27
27
|
# icmp.body.read 'this is a body'
|
28
28
|
# @author Sylvain Daubert
|
29
|
-
class ICMP <
|
30
|
-
include StructFu
|
31
|
-
include HeaderMethods
|
32
|
-
extend HeaderClassMethods
|
29
|
+
class ICMP < Base
|
33
30
|
|
34
31
|
# ICMP internet protocol number
|
35
32
|
IP_PROTOCOL = 1
|
36
33
|
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
|
41
|
-
#
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
#
|
50
|
-
#
|
51
|
-
|
52
|
-
def read(str)
|
53
|
-
return self if str.nil?
|
54
|
-
raise ParseError, 'string too short for ICMP' if str.size < self.sz
|
55
|
-
force_binary str
|
56
|
-
self[:type].read str[0, 1]
|
57
|
-
self[:code].read str[1, 1]
|
58
|
-
self[:checksum].read str[2, 2]
|
59
|
-
self[:body].read str[4..-1]
|
60
|
-
end
|
34
|
+
# @!attribute type
|
35
|
+
# 8-bit ICMP type
|
36
|
+
# @return [Integer]
|
37
|
+
define_field :type, Types::Int8
|
38
|
+
# @!attribute code
|
39
|
+
# 8-bit ICMP code
|
40
|
+
# @return [Integer]
|
41
|
+
define_field :code, Types::Int8
|
42
|
+
# @!attribute checksum
|
43
|
+
# 16-bit ICMP checksum
|
44
|
+
# @return [Integer]
|
45
|
+
define_field :checksum, Types::Int16
|
46
|
+
# @!attribute body
|
47
|
+
# @return [Types::String,Header::Base]
|
48
|
+
define_field :body, Types::String
|
61
49
|
|
62
50
|
# Compute checksum and set +checksum+ field
|
63
51
|
# @return [Integer]
|
@@ -74,45 +62,6 @@ module PacketGen
|
|
74
62
|
sum = ~sum & 0xffff
|
75
63
|
self[:checksum].value = (sum == 0) ? 0xffff : sum
|
76
64
|
end
|
77
|
-
|
78
|
-
# Getter for type attribute
|
79
|
-
# @return [Integer]
|
80
|
-
def type
|
81
|
-
self[:type].to_i
|
82
|
-
end
|
83
|
-
|
84
|
-
# Setter for type attribute
|
85
|
-
# @param [Integer] type
|
86
|
-
# @return [Integer]
|
87
|
-
def type=(type)
|
88
|
-
self[:type].value = type
|
89
|
-
end
|
90
|
-
|
91
|
-
# Getter for code attribute
|
92
|
-
# @return [Integer]
|
93
|
-
def code
|
94
|
-
self[:code].to_i
|
95
|
-
end
|
96
|
-
|
97
|
-
# Setter for code attribute
|
98
|
-
# @param [Integer] code
|
99
|
-
# @return [Integer]
|
100
|
-
def code=(code)
|
101
|
-
self[:code].value = code
|
102
|
-
end
|
103
|
-
|
104
|
-
# Getter for checksum attribute
|
105
|
-
# @return [Integer]
|
106
|
-
def checksum
|
107
|
-
self[:checksum].to_i
|
108
|
-
end
|
109
|
-
|
110
|
-
# Setter for checksum attribute
|
111
|
-
# @param [Integer] sum
|
112
|
-
# @return [Integer]
|
113
|
-
def checksum=(sum)
|
114
|
-
self[:checksum].value = sum
|
115
|
-
end
|
116
65
|
end
|
117
66
|
|
118
67
|
self.add_class ICMP
|
@@ -7,9 +7,9 @@ module PacketGen
|
|
7
7
|
module Header
|
8
8
|
|
9
9
|
# A ICMPv6 header consists of:
|
10
|
-
# * a +type+ field ({Int8} type),
|
11
|
-
# * a +code+ field ({Int8} type),
|
12
|
-
# * a +checksum+ field ({Int16} type),
|
10
|
+
# * a +type+ field ({Types::Int8} type),
|
11
|
+
# * a +code+ field ({Types::Int8} type),
|
12
|
+
# * a +checksum+ field ({Types::Int16} type),
|
13
13
|
# * and a +body+.
|
14
14
|
#
|
15
15
|
# == Create a ICMPv6 header
|