packetgen 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|