packetgen 3.3.2 → 4.0.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 +37 -21
- data/lib/packetgen/capture.rb +2 -2
- data/lib/packetgen/config.rb +0 -1
- data/lib/packetgen/deprecation.rb +7 -7
- data/lib/packetgen/header/arp.rb +13 -13
- data/lib/packetgen/header/asn1_base.rb +1 -1
- data/lib/packetgen/header/base.rb +17 -18
- data/lib/packetgen/header/bootp.rb +32 -34
- data/lib/packetgen/header/dhcp/option.rb +19 -19
- data/lib/packetgen/header/dhcp/options.rb +1 -1
- data/lib/packetgen/header/dhcp.rb +3 -3
- data/lib/packetgen/header/dhcpv6/duid.rb +16 -16
- data/lib/packetgen/header/dhcpv6/option.rb +53 -53
- data/lib/packetgen/header/dhcpv6/options.rb +1 -1
- data/lib/packetgen/header/dhcpv6/relay.rb +5 -5
- data/lib/packetgen/header/dhcpv6.rb +6 -6
- data/lib/packetgen/header/dns/name.rb +14 -10
- data/lib/packetgen/header/dns/opt.rb +2 -2
- data/lib/packetgen/header/dns/option.rb +11 -11
- data/lib/packetgen/header/dns/qdsection.rb +1 -1
- data/lib/packetgen/header/dns/question.rb +6 -8
- data/lib/packetgen/header/dns/rr.rb +56 -43
- data/lib/packetgen/header/dns/rrsection.rb +4 -4
- data/lib/packetgen/header/dns.rb +27 -30
- data/lib/packetgen/header/dot11/control.rb +11 -11
- data/lib/packetgen/header/dot11/data.rb +20 -20
- data/lib/packetgen/header/dot11/element.rb +4 -4
- data/lib/packetgen/header/dot11/management.rb +8 -8
- data/lib/packetgen/header/dot11/sub_mngt.rb +39 -53
- data/lib/packetgen/header/dot11.rb +88 -93
- data/lib/packetgen/header/dot1q.rb +10 -12
- data/lib/packetgen/header/dot1x.rb +9 -9
- data/lib/packetgen/header/eap/fast.rb +4 -4
- data/lib/packetgen/header/eap/md5.rb +6 -6
- data/lib/packetgen/header/eap/tls.rb +13 -15
- data/lib/packetgen/header/eap/ttls.rb +13 -15
- data/lib/packetgen/header/eap.rb +22 -22
- data/lib/packetgen/header/eth.rb +18 -18
- data/lib/packetgen/header/gre.rb +8 -10
- data/lib/packetgen/header/http/headers.rb +2 -2
- data/lib/packetgen/header/http/request.rb +17 -16
- data/lib/packetgen/header/http/response.rb +18 -17
- data/lib/packetgen/header/http/verbs.rb +1 -3
- data/lib/packetgen/header/icmp.rb +8 -8
- data/lib/packetgen/header/icmpv6.rb +3 -3
- data/lib/packetgen/header/igmp.rb +8 -8
- data/lib/packetgen/header/igmpv3/group_record.rb +12 -12
- data/lib/packetgen/header/igmpv3/mq.rb +16 -18
- data/lib/packetgen/header/igmpv3/mr.rb +4 -4
- data/lib/packetgen/header/igmpv3.rb +7 -7
- data/lib/packetgen/header/ip/addr.rb +13 -13
- data/lib/packetgen/header/ip/option.rb +31 -33
- data/lib/packetgen/header/ip/options.rb +1 -1
- data/lib/packetgen/header/ip.rb +37 -72
- data/lib/packetgen/header/ipv6/addr.rb +14 -14
- data/lib/packetgen/header/ipv6/extension.rb +8 -8
- data/lib/packetgen/header/ipv6/hop_by_hop.rb +9 -9
- data/lib/packetgen/header/ipv6.rb +20 -22
- data/lib/packetgen/header/llc.rb +17 -17
- data/lib/packetgen/header/mdns.rb +1 -1
- data/lib/packetgen/header/mld.rb +6 -6
- data/lib/packetgen/header/mldv2/mcast_address_record.rb +11 -11
- data/lib/packetgen/header/mldv2/mlq.rb +21 -23
- data/lib/packetgen/header/mldv2/mlr.rb +8 -8
- data/lib/packetgen/header/ospfv2/db_description.rb +11 -12
- data/lib/packetgen/header/ospfv2/hello.rb +11 -11
- data/lib/packetgen/header/ospfv2/ls_ack.rb +1 -1
- data/lib/packetgen/header/ospfv2/ls_request.rb +9 -9
- data/lib/packetgen/header/ospfv2/ls_update.rb +3 -3
- data/lib/packetgen/header/ospfv2/lsa.rb +54 -58
- data/lib/packetgen/header/ospfv2/lsa_header.rb +9 -9
- data/lib/packetgen/header/ospfv2.rb +27 -29
- data/lib/packetgen/header/ospfv3/db_description.rb +13 -14
- data/lib/packetgen/header/ospfv3/hello.rb +12 -12
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +17 -19
- data/lib/packetgen/header/ospfv3/ls_ack.rb +2 -2
- data/lib/packetgen/header/ospfv3/ls_request.rb +9 -9
- data/lib/packetgen/header/ospfv3/ls_update.rb +4 -4
- data/lib/packetgen/header/ospfv3/lsa.rb +48 -51
- data/lib/packetgen/header/ospfv3/lsa_header.rb +9 -9
- data/lib/packetgen/header/ospfv3.rb +25 -27
- data/lib/packetgen/header/sctp/chunk.rb +44 -41
- data/lib/packetgen/header/sctp/error.rb +52 -52
- data/lib/packetgen/header/sctp/parameter.rb +38 -38
- data/lib/packetgen/header/sctp.rb +5 -5
- data/lib/packetgen/header/snmp.rb +2 -2
- data/lib/packetgen/header/tcp/option.rb +45 -39
- data/lib/packetgen/header/tcp/options.rb +2 -2
- data/lib/packetgen/header/tcp.rb +55 -44
- data/lib/packetgen/header/tftp.rb +16 -16
- data/lib/packetgen/header/udp.rb +8 -8
- data/lib/packetgen/header.rb +9 -10
- data/lib/packetgen/headerable.rb +13 -3
- data/lib/packetgen/inspect.rb +2 -2
- data/lib/packetgen/packet.rb +54 -37
- data/lib/packetgen/pcap.rb +15 -4
- data/lib/packetgen/pcapng/block.rb +18 -17
- data/lib/packetgen/pcapng/epb.rb +13 -15
- data/lib/packetgen/pcapng/file.rb +3 -97
- data/lib/packetgen/pcapng/idb.rb +9 -11
- data/lib/packetgen/pcapng/shb.rb +13 -15
- data/lib/packetgen/pcapng/spb.rb +8 -10
- data/lib/packetgen/pcapng/unknown_block.rb +6 -17
- data/lib/packetgen/pcapng.rb +4 -4
- data/lib/packetgen/pcaprub_wrapper.rb +17 -1
- data/lib/packetgen/proto.rb +1 -1
- data/lib/packetgen/unknown_packet.rb +2 -2
- data/lib/packetgen/utils/arp_spoofer.rb +18 -19
- data/lib/packetgen/utils.rb +2 -2
- data/lib/packetgen/version.rb +1 -1
- data/lib/packetgen.rb +4 -3
- metadata +34 -29
- data/lib/packetgen/types/abstract_tlv.rb +0 -278
- data/lib/packetgen/types/array.rb +0 -287
- data/lib/packetgen/types/cstring.rb +0 -109
- data/lib/packetgen/types/enum.rb +0 -171
- data/lib/packetgen/types/fieldable.rb +0 -66
- data/lib/packetgen/types/fields.rb +0 -622
- data/lib/packetgen/types/int.rb +0 -473
- data/lib/packetgen/types/int_string.rb +0 -102
- data/lib/packetgen/types/length_from.rb +0 -54
- data/lib/packetgen/types/oui.rb +0 -52
- data/lib/packetgen/types/string.rb +0 -97
- data/lib/packetgen/types/tlv.rb +0 -161
- data/lib/packetgen/types.rb +0 -26
@@ -11,8 +11,8 @@ module PacketGen
|
|
11
11
|
class TCP
|
12
12
|
# Base class to describe a TCP option
|
13
13
|
# @author Sylvain Daubert
|
14
|
-
class Option <
|
15
|
-
include
|
14
|
+
class Option < BinStruct::Struct
|
15
|
+
include BinStruct::Structable
|
16
16
|
|
17
17
|
# EOL option value
|
18
18
|
EOL_KIND = 0
|
@@ -36,15 +36,15 @@ module PacketGen
|
|
36
36
|
# @!attribute kind
|
37
37
|
# Option kind
|
38
38
|
# @return [Integer] 8-bit option kind
|
39
|
-
|
39
|
+
define_attr :kind, BinStruct::Int8
|
40
40
|
# @!attribute length
|
41
41
|
# Option length
|
42
42
|
# @return [Integer] 8-bit option length
|
43
|
-
|
43
|
+
define_attr :length, BinStruct::Int8, optional: lambda(&:length?)
|
44
44
|
# @!attribute value
|
45
45
|
# @return [Integer,String] option value
|
46
|
-
|
47
|
-
|
46
|
+
define_attr :value, BinStruct::String, optional: ->(h) { h.length? && h.length > 2 },
|
47
|
+
builder: ->(h, t) { t.new(length_from: -> { h.length - 2 }) }
|
48
48
|
|
49
49
|
# @param [hash] options
|
50
50
|
# @option options [Integer] :kind
|
@@ -55,18 +55,18 @@ module PacketGen
|
|
55
55
|
case options[:value]
|
56
56
|
when Integer
|
57
57
|
klass = case self[:length].to_i
|
58
|
-
when 3 then
|
59
|
-
when 4 then
|
60
|
-
when 6 then
|
58
|
+
when 3 then BinStruct::Int8
|
59
|
+
when 4 then BinStruct::Int16
|
60
|
+
when 6 then BinStruct::Int32
|
61
61
|
else
|
62
62
|
raise ArgumentError, 'impossible length'
|
63
63
|
end
|
64
|
-
self[:value] = klass.new(options[:value])
|
64
|
+
self[:value] = klass.new(value: options[:value])
|
65
65
|
when NilClass
|
66
66
|
# Nothing to do
|
67
67
|
else
|
68
|
-
self[:value] =
|
69
|
-
self[:length].
|
68
|
+
self[:value] = BinStruct::String.new.read(options[:value])
|
69
|
+
self[:length].from_human(self[:value].sz + 2) unless options[:length]
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -83,7 +83,7 @@ module PacketGen
|
|
83
83
|
# @return [String, Integer]
|
84
84
|
def value
|
85
85
|
case self[:value]
|
86
|
-
when
|
86
|
+
when BinStruct::Int
|
87
87
|
self[:value].to_i
|
88
88
|
else
|
89
89
|
self[:value].to_s
|
@@ -92,16 +92,22 @@ module PacketGen
|
|
92
92
|
|
93
93
|
alias old_set_value value=
|
94
94
|
# Setter for value attribute
|
95
|
-
# @param[String,Integer]
|
95
|
+
# @param[String,Integer] val
|
96
96
|
# @return [String, Integer]
|
97
97
|
def value=(val)
|
98
98
|
case self[:value]
|
99
|
-
when
|
99
|
+
when BinStruct::Int
|
100
100
|
self.length = 2 + self[:value].sz
|
101
|
-
when
|
102
|
-
self.length = 2 +
|
101
|
+
when BinStruct::String
|
102
|
+
self.length = 2 + BinStruct::String.new.read(val).sz
|
103
|
+
end
|
104
|
+
|
105
|
+
case val
|
106
|
+
when Integer
|
107
|
+
self[:value].from_human(val)
|
108
|
+
else
|
109
|
+
self[:value].read(val)
|
103
110
|
end
|
104
|
-
self[:value].read val
|
105
111
|
val
|
106
112
|
end
|
107
113
|
|
@@ -115,14 +121,14 @@ module PacketGen
|
|
115
121
|
# Get option as a human readable string
|
116
122
|
# @return [String]
|
117
123
|
def to_human
|
118
|
-
str = self.instance_of?(Option) ?
|
124
|
+
str = self.instance_of?(Option) ? "unk-#{kind}" : self.class.to_s.sub(/.*::/, '')
|
119
125
|
str << ":#{self[:value].to_s.inspect}" if (length > 2) && !self[:value].to_s.empty?
|
120
126
|
str
|
121
127
|
end
|
122
128
|
|
123
129
|
# @return [String]
|
124
130
|
def inspect
|
125
|
-
str =
|
131
|
+
str = "#<#{self.class} kind=#{self[:kind].value.inspect} "
|
126
132
|
str << "length=#{self[:length].value.inspect} " if self[:length].value
|
127
133
|
str << "value=#{self[:value].inspect}>"
|
128
134
|
end
|
@@ -131,26 +137,26 @@ module PacketGen
|
|
131
137
|
# End Of Option TCP option
|
132
138
|
# @author Sylvain Daubert
|
133
139
|
class EOL < Option
|
134
|
-
|
140
|
+
update_attr :kind, default: EOL_KIND
|
135
141
|
end
|
136
142
|
|
137
143
|
# No OPeration TCP option
|
138
144
|
# @author Sylvain Daubert
|
139
145
|
class NOP < Option
|
140
146
|
# @see Option#initialize
|
141
|
-
|
147
|
+
update_attr :kind, default: NOP_KIND
|
142
148
|
end
|
143
149
|
|
144
150
|
# Maximum Segment Size TCP option
|
145
151
|
# @author Sylvain Daubert
|
146
152
|
class MSS < Option
|
147
|
-
|
148
|
-
|
153
|
+
update_attr :kind, default: MSS_KIND
|
154
|
+
update_attr :length, default: 4
|
149
155
|
|
150
156
|
# @see Option#initialize
|
151
157
|
def initialize(options={})
|
152
158
|
super
|
153
|
-
self[:value] =
|
159
|
+
self[:value] = BinStruct::Int16.new(value: options[:value])
|
154
160
|
end
|
155
161
|
|
156
162
|
# @return [String]
|
@@ -162,13 +168,13 @@ module PacketGen
|
|
162
168
|
# Window Size TCP option
|
163
169
|
# @author Sylvain Daubert
|
164
170
|
class WS < Option
|
165
|
-
|
166
|
-
|
171
|
+
update_attr :kind, default: WS_KIND
|
172
|
+
update_attr :length, default: 3
|
167
173
|
|
168
174
|
# @see Option#initialize
|
169
175
|
def initialize(options={})
|
170
176
|
super
|
171
|
-
self[:value] =
|
177
|
+
self[:value] = BinStruct::Int8.new(value: options[:value])
|
172
178
|
end
|
173
179
|
|
174
180
|
# @return [String]
|
@@ -180,26 +186,26 @@ module PacketGen
|
|
180
186
|
# Selective Acknowledgment OK TCP option
|
181
187
|
# @author Sylvain Daubert
|
182
188
|
class SACKOK < Option
|
183
|
-
|
184
|
-
|
189
|
+
update_attr :kind, default: SACKOK_KIND
|
190
|
+
update_attr :length, default: 2
|
185
191
|
end
|
186
192
|
|
187
193
|
# Selective Acknowledgment TCP option
|
188
194
|
# @author Sylvain Daubert
|
189
195
|
class SACK < Option
|
190
|
-
|
196
|
+
update_attr :kind, default: SACK_KIND
|
191
197
|
end
|
192
198
|
|
193
199
|
# Echo TCP option
|
194
200
|
# @author Sylvain Daubert
|
195
201
|
class ECHO < Option
|
196
|
-
|
197
|
-
|
202
|
+
update_attr :kind, default: ECHO_KIND
|
203
|
+
update_attr :length, default: 6
|
198
204
|
|
199
205
|
# @see Option#initialize
|
200
206
|
def initialize(options={})
|
201
207
|
super
|
202
|
-
self[:value] =
|
208
|
+
self[:value] = BinStruct::Int32.new(value: options[:value])
|
203
209
|
end
|
204
210
|
|
205
211
|
# @return [String]
|
@@ -211,13 +217,13 @@ module PacketGen
|
|
211
217
|
# Echo Reply TCP option
|
212
218
|
# @author Sylvain Daubert
|
213
219
|
class ECHOREPLY < Option
|
214
|
-
|
215
|
-
|
220
|
+
update_attr :kind, default: ECHOREPLY_KIND
|
221
|
+
update_attr :length, default: 6
|
216
222
|
|
217
223
|
# @see Option#initialize
|
218
224
|
def initialize(options={})
|
219
225
|
super
|
220
|
-
self[:value] =
|
226
|
+
self[:value] = BinStruct::Int32.new(value: options[:value])
|
221
227
|
end
|
222
228
|
|
223
229
|
# @return [String]
|
@@ -229,8 +235,8 @@ module PacketGen
|
|
229
235
|
# Timestamp TCP option
|
230
236
|
# @author Sylvain Daubert
|
231
237
|
class TS < Option
|
232
|
-
|
233
|
-
|
238
|
+
update_attr :kind, default: TS_KIND
|
239
|
+
update_attr :length, default: 10
|
234
240
|
|
235
241
|
# @see Option#initialize
|
236
242
|
def initialize(options={})
|
@@ -13,7 +13,7 @@ module PacketGen
|
|
13
13
|
class TCP
|
14
14
|
# Container for TCP options in {TCP TCP header}.
|
15
15
|
# @author Sylvain Daubert
|
16
|
-
class Options <
|
16
|
+
class Options < BinStruct::Array
|
17
17
|
set_of Option
|
18
18
|
|
19
19
|
# Get {Option} subclasses
|
@@ -23,7 +23,7 @@ module PacketGen
|
|
23
23
|
|
24
24
|
@klasses = []
|
25
25
|
Option.constants.each do |cst|
|
26
|
-
next unless cst.to_s.end_with?
|
26
|
+
next unless cst.to_s.end_with?('_KIND')
|
27
27
|
|
28
28
|
optname = cst.to_s.sub('_KIND', '')
|
29
29
|
@klasses[Option.const_get(cst)] = TCP.const_get(optname)
|
data/lib/packetgen/header/tcp.rb
CHANGED
@@ -29,9 +29,9 @@ module PacketGen
|
|
29
29
|
# | data |
|
30
30
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
31
31
|
# A TCP header consists of:
|
32
|
-
# * a source port ({#sport}, {
|
32
|
+
# * a source port ({#sport}, {BinStruct::Int16} type),
|
33
33
|
# * a destination port ({#dport}, +Int16+ type),
|
34
|
-
# * a sequence number ({#seqnum}, {
|
34
|
+
# * a sequence number ({#seqnum}, {BinStruct::Int32} type),
|
35
35
|
# * an acknownledge number ({#acknum}, +Int32+ type),
|
36
36
|
# * a 16-bit field ({#u16}, +Int16+ type) composed of:
|
37
37
|
# * a 4-bit {#data_offset} self[attr],
|
@@ -41,7 +41,7 @@ module PacketGen
|
|
41
41
|
# * a {#checksum} field (+Int16+ type),
|
42
42
|
# * a urgent pointer ({#urg_pointer}, +Int16+ type),
|
43
43
|
# * an optional {#options} field ({Options} type),
|
44
|
-
# * and a {#body} ({
|
44
|
+
# * and a {#body} ({BinStruct::String} type).
|
45
45
|
#
|
46
46
|
# == Create a TCP header
|
47
47
|
# # standalone
|
@@ -78,7 +78,7 @@ module PacketGen
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
-
# Need to load Options now, as this is used through
|
81
|
+
# Need to load Options now, as this is used through define_bit_attr,
|
82
82
|
# which make a call to TCP.new, which needs Options
|
83
83
|
require_relative 'tcp/options'
|
84
84
|
|
@@ -91,41 +91,68 @@ module PacketGen
|
|
91
91
|
# @!attribute sport
|
92
92
|
# 16-bit TCP source port
|
93
93
|
# @return [Integer]
|
94
|
-
|
94
|
+
define_attr :sport, BinStruct::Int16
|
95
95
|
# @!attribute dport
|
96
96
|
# 16-bit TCP destination port
|
97
97
|
# @return [Integer]
|
98
|
-
|
98
|
+
define_attr :dport, BinStruct::Int16
|
99
99
|
# @!attribute seqnum
|
100
100
|
# 32-bit TCP sequence number
|
101
101
|
# @return [Integer]
|
102
|
-
|
102
|
+
define_attr :seqnum, BinStruct::Int32, default: ->(_) { rand(2**32) }
|
103
103
|
# @!attribute acknum
|
104
104
|
# 32-bit TCP acknowledgement number
|
105
105
|
# @return [Integer]
|
106
|
-
|
106
|
+
define_attr :acknum, BinStruct::Int32
|
107
107
|
# @!attribute u16
|
108
108
|
# @return [Integer] 16-bit word used by flags and bit fields
|
109
|
-
|
109
|
+
# @!attribute data_offset
|
110
|
+
# @return [Integer] 4-bit data offset from {#u16}
|
111
|
+
# @!attribute reserved
|
112
|
+
# @return [Integer] 3-bit reserved from {#u16}
|
113
|
+
# @!attribute flags
|
114
|
+
# @return [Integer] 9-bit flags from {#u16}
|
115
|
+
# @!attribute flag_ns
|
116
|
+
# @return [Integer] 1-bit NS flag
|
117
|
+
# @!attribute flag_cwr
|
118
|
+
# @return [Integer] 1-bit CWR flag
|
119
|
+
# @!attribute flag_ece
|
120
|
+
# @return [Integer] 1-bit ECE flag
|
121
|
+
# @!attribute flag_urg
|
122
|
+
# @return [Integer] 1-bit URG flag
|
123
|
+
# @!attribute flag_ack
|
124
|
+
# @return [Integer] 1-bit ACK flag
|
125
|
+
# @!attribute flag_psh
|
126
|
+
# @return [Integer] 1-bit PSH flag
|
127
|
+
# @!attribute flag_rst
|
128
|
+
# @return [Integer] 1-bit RST flag
|
129
|
+
# @!attribute flag_syn
|
130
|
+
# @return [Integer] 1-bit SYN flag
|
131
|
+
# @!attribute flag_fin
|
132
|
+
# @return [Integer] 1-bit FIN flag
|
133
|
+
define_bit_attr :u16, data_offset: 4, reserved: 3, flag_ns: 1, flag_cwr: 1, flag_ece: 1, flag_urg: 1, flag_ack: 1, flag_psh: 1,
|
134
|
+
flag_rst: 1, flag_syn: 1, flag_fin: 1
|
135
|
+
alias hlen data_offset
|
136
|
+
alias hlen= data_offset=
|
110
137
|
# @!attribute window
|
111
138
|
# 16-bit TCP window size
|
112
139
|
# @return [Integer]
|
113
|
-
|
140
|
+
define_attr :window, BinStruct::Int16
|
114
141
|
# @!attribute checksum
|
115
142
|
# 16-bit TCP checksum
|
116
143
|
# @return [Integer]
|
117
|
-
|
144
|
+
define_attr :checksum, BinStruct::Int16
|
118
145
|
# @!attribute urg_pointer
|
119
146
|
# 16-bit TCP urgent data pointer
|
120
147
|
# @return [Integer]
|
121
|
-
|
148
|
+
define_attr :urg_pointer, BinStruct::Int16
|
122
149
|
# @!attribute options
|
123
150
|
# TCP options
|
124
151
|
# @return [Options]
|
125
|
-
|
152
|
+
define_attr :options, TCP::Options, builder: ->(h, t) { t.new(length_from: -> { h.data_offset > 5 ? (h.data_offset - 5) * 4 : 0 }) }
|
126
153
|
# @!attribute body
|
127
|
-
# @return [
|
128
|
-
|
154
|
+
# @return [BinStruct::String,Header::Base]
|
155
|
+
define_attr :body, BinStruct::String
|
129
156
|
|
130
157
|
alias source_port sport
|
131
158
|
alias source_port= sport=
|
@@ -158,38 +185,22 @@ module PacketGen
|
|
158
185
|
def initialize(options={})
|
159
186
|
opts = { data_offset: 5 }.merge!(options)
|
160
187
|
super(opts)
|
188
|
+
self.flags = opts[:flags] if opts.key?(:flags)
|
161
189
|
end
|
162
190
|
|
163
|
-
#
|
164
|
-
#
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
# @return [Integer] 9-bit flags from {#u16}
|
169
|
-
define_bit_fields_on :u16, :data_offset, 4, :reserved, 3, :flags, 9
|
170
|
-
alias hlen data_offset
|
171
|
-
alias hlen= data_offset=
|
191
|
+
# Get all flags value from [#u16]
|
192
|
+
# @return [Integer]
|
193
|
+
def flags
|
194
|
+
self.u16 & 0x1ff
|
195
|
+
end
|
172
196
|
|
173
|
-
#
|
174
|
-
#
|
175
|
-
#
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
# @return [Boolean] 1-bit URG flag
|
181
|
-
# @!attribute flag_ack
|
182
|
-
# @return [Boolean] 1-bit ACK flag
|
183
|
-
# @!attribute flag_psh
|
184
|
-
# @return [Boolean] 1-bit PSH flag
|
185
|
-
# @!attribute flag_rst
|
186
|
-
# @return [Boolean] 1-bit RST flag
|
187
|
-
# @!attribute flag_syn
|
188
|
-
# @return [Boolean] 1-bit SYN flag
|
189
|
-
# @!attribute flag_fin
|
190
|
-
# @return [Boolean] 1-bit FIN flag
|
191
|
-
define_bit_fields_on :u16, :_, 7, :flag_ns, :flag_cwr, :flag_ece, :flag_urg,
|
192
|
-
:flag_ack, :flag_psh, :flag_rst, :flag_syn, :flag_fin
|
197
|
+
# Set all flags at once
|
198
|
+
# @parameter [Integer] value
|
199
|
+
# @return [Integer]
|
200
|
+
def flags=(value)
|
201
|
+
new_u16 = (self.u16 & 0xfe00) | (value & 0x1ff)
|
202
|
+
self[:u16].from_human(new_u16)
|
203
|
+
end
|
193
204
|
|
194
205
|
# Compute checksum and set +checksum+ field
|
195
206
|
# @return [Integer]
|
@@ -10,7 +10,7 @@ module PacketGen
|
|
10
10
|
module Header
|
11
11
|
# A TFTP (Trivial File Transfer Protocol,
|
12
12
|
# {https://tools.ietf.org/html/rfc1350 RFC 1350}) header consists of:
|
13
|
-
# * a {#opcode} ({
|
13
|
+
# * a {#opcode} ({BinStruct::Int16Enum}),
|
14
14
|
# * and a body. Its content depends on opcode.
|
15
15
|
#
|
16
16
|
# Specialized subclasses exists to handle {TFTP::RRQ Read Request},
|
@@ -60,11 +60,11 @@ module PacketGen
|
|
60
60
|
# @!attribute opcode
|
61
61
|
# 16-bit operation code
|
62
62
|
# @return [Integer]
|
63
|
-
|
63
|
+
define_attr :opcode, BinStruct::Int16Enum, enum: OPCODES
|
64
64
|
|
65
65
|
# @!attribute body
|
66
66
|
# @return [String]
|
67
|
-
|
67
|
+
define_attr :body, BinStruct::String
|
68
68
|
|
69
69
|
def initialize(options={})
|
70
70
|
type = protocol_name.sub(/^.*::/, '')
|
@@ -86,12 +86,12 @@ module PacketGen
|
|
86
86
|
if self.instance_of? TFTP
|
87
87
|
super
|
88
88
|
if OPCODES.value? opcode
|
89
|
-
TFTP.const_get(human_opcode).new.read
|
89
|
+
TFTP.const_get(human_opcode).new.read(str)
|
90
90
|
else
|
91
91
|
self
|
92
92
|
end
|
93
93
|
else
|
94
|
-
old_read
|
94
|
+
old_read(str)
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
@@ -130,7 +130,7 @@ module PacketGen
|
|
130
130
|
# @param [Packet] packet
|
131
131
|
# @return [void]
|
132
132
|
def added_to_packet(packet)
|
133
|
-
return if packet.respond_to?
|
133
|
+
return if packet.respond_to?(:tftp)
|
134
134
|
|
135
135
|
packet.instance_eval("def tftp(arg=nil); header(#{self.class}, arg); end") # def tftp(arg=nil); header(TFTP, arg); end
|
136
136
|
end
|
@@ -140,24 +140,24 @@ module PacketGen
|
|
140
140
|
def decode_tftp_packet(pkt)
|
141
141
|
tftp = Packet.parse(pkt.body, first_header: 'TFTP')
|
142
142
|
udp_dport = pkt.udp.dport
|
143
|
-
pkt.encapsulate
|
143
|
+
pkt.encapsulate(tftp)
|
144
144
|
# need to fix it as #encapsulate force it to 69
|
145
145
|
pkt.udp.dport = udp_dport
|
146
146
|
end
|
147
147
|
|
148
148
|
# TFTP Read Request header
|
149
149
|
class RRQ < TFTP
|
150
|
-
|
150
|
+
remove_attr :body
|
151
151
|
|
152
152
|
# @!attribute filename
|
153
153
|
# Filename to access
|
154
154
|
# @return [String]
|
155
|
-
|
155
|
+
define_attr :filename, BinStruct::CString
|
156
156
|
|
157
157
|
# @!attribute mode
|
158
158
|
# Mode used. Should be +netascii+, +octet+ or +mail+
|
159
159
|
# @return [String]
|
160
|
-
|
160
|
+
define_attr :mode, BinStruct::CString
|
161
161
|
end
|
162
162
|
|
163
163
|
# TFTP Write Request header
|
@@ -168,32 +168,32 @@ module PacketGen
|
|
168
168
|
# @!attribute block_num
|
169
169
|
# 16-bit block number
|
170
170
|
# @return [Integer]
|
171
|
-
|
171
|
+
define_attr_before :body, :block_num, BinStruct::Int16
|
172
172
|
end
|
173
173
|
|
174
174
|
# TFTP ACK header
|
175
175
|
class ACK < TFTP
|
176
|
-
|
176
|
+
remove_attr :body
|
177
177
|
|
178
178
|
# @!attribute block_num
|
179
179
|
# 16-bit block number
|
180
180
|
# @return [Integer]
|
181
|
-
|
181
|
+
define_attr :block_num, BinStruct::Int16
|
182
182
|
end
|
183
183
|
|
184
184
|
# TFTP ERROR header
|
185
185
|
class ERROR < TFTP
|
186
|
-
|
186
|
+
remove_attr :body
|
187
187
|
|
188
188
|
# @!attribute error_code
|
189
189
|
# 16-bit error code
|
190
190
|
# @return [Integer]
|
191
|
-
|
191
|
+
define_attr :error_code, BinStruct::Int16
|
192
192
|
|
193
193
|
# @!attribute error_msg
|
194
194
|
# Error message
|
195
195
|
# @return [String]
|
196
|
-
|
196
|
+
define_attr :error_msg, BinStruct::CString
|
197
197
|
alias error_message error_msg
|
198
198
|
end
|
199
199
|
end
|
data/lib/packetgen/header/udp.rb
CHANGED
@@ -17,7 +17,7 @@ module PacketGen
|
|
17
17
|
# | Length | Checksum |
|
18
18
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
19
19
|
# A UDP header consists of:
|
20
|
-
# * a source port field ({#sport}, {
|
20
|
+
# * a source port field ({#sport}, {BinStruct::Int16} type),
|
21
21
|
# * a destination port field ({#dport}, +Int16+ type),
|
22
22
|
# * a UDP length field ({#length}, +Int16+ type),
|
23
23
|
# * a {#checksum} field (+Int16+ type),
|
@@ -46,22 +46,22 @@ module PacketGen
|
|
46
46
|
# @!attribute sport
|
47
47
|
# 16-bit UDP source port
|
48
48
|
# @return [Integer]
|
49
|
-
|
49
|
+
define_attr :sport, BinStruct::Int16
|
50
50
|
# @!attribute dport
|
51
51
|
# 16-bit UDP destination port
|
52
52
|
# @return [Integer]
|
53
|
-
|
53
|
+
define_attr :dport, BinStruct::Int16
|
54
54
|
# @!attribute length
|
55
55
|
# 16-bit UDP length
|
56
56
|
# @return [Integer]
|
57
|
-
|
57
|
+
define_attr :length, BinStruct::Int16, default: 8
|
58
58
|
# @!attribute checksum
|
59
59
|
# 16-bit UDP checksum
|
60
60
|
# @return [Integer]
|
61
|
-
|
61
|
+
define_attr :checksum, BinStruct::Int16
|
62
62
|
# @!attribute body
|
63
|
-
# @return [
|
64
|
-
|
63
|
+
# @return [BinStruct::String,Header::Base]
|
64
|
+
define_attr :body, BinStruct::String
|
65
65
|
|
66
66
|
alias source_port sport
|
67
67
|
alias source_port= sport=
|
@@ -89,7 +89,7 @@ module PacketGen
|
|
89
89
|
# Compute length and set +length+ field
|
90
90
|
# @return [Integer]
|
91
91
|
def calc_length
|
92
|
-
Base.calculate_and_set_length
|
92
|
+
Base.calculate_and_set_length(self)
|
93
93
|
end
|
94
94
|
|
95
95
|
# Invert source and destination port numbers
|
data/lib/packetgen/header.rb
CHANGED
@@ -13,22 +13,21 @@ module PacketGen
|
|
13
13
|
# This namespace handles all buitlin headers, such as {IP} or {TCP}.
|
14
14
|
#
|
15
15
|
# == Add a foreign header class
|
16
|
-
# PacketGen permits adding
|
16
|
+
# PacketGen permits adding your own header classes.
|
17
17
|
# First, define the new header class. By example:
|
18
18
|
# module MyModule
|
19
19
|
# class MyHeader < PacketGen::Header::Base
|
20
|
-
#
|
21
|
-
#
|
20
|
+
# define_attr :field1, BinStruct::Int32
|
21
|
+
# define_attr :field2, BinStruct::Int32
|
22
22
|
# end
|
23
23
|
# end
|
24
24
|
# Then, class must be declared to PacketGen:
|
25
|
-
# PacketGen::Header.add_class
|
25
|
+
# PacketGen::Header.add_class(MyModule::MyHeader)
|
26
26
|
# Finally, bindings must be declared:
|
27
27
|
# # bind MyHeader as IP protocol number 254 (needed by Packet#parse and Packet#add)
|
28
|
-
# PacketGen::Header::IP.bind_header
|
28
|
+
# PacketGen::Header::IP.bind_header(MyModule::MyHeader, protocol: 254)
|
29
29
|
# And use it:
|
30
|
-
# pkt = Packet.gen('IP').add('MyHeader', field1: 0x12345678)
|
31
|
-
# pkt.myheader.field2.read 0x01
|
30
|
+
# pkt = Packet.gen('IP').add('MyHeader', field1: 0x12345678, field3: 0x87654321)
|
32
31
|
# @author Sylvain Daubert
|
33
32
|
module Header
|
34
33
|
@added_header_classes = {}
|
@@ -54,7 +53,7 @@ module PacketGen
|
|
54
53
|
@header_classes = nil
|
55
54
|
end
|
56
55
|
|
57
|
-
# Remove a foreign header
|
56
|
+
# Remove a foreign header previously added by {.add_class}
|
58
57
|
# from known header classes.
|
59
58
|
# @param [Class] klass
|
60
59
|
# @return [void]
|
@@ -70,8 +69,8 @@ module PacketGen
|
|
70
69
|
# @return [Class,nil]
|
71
70
|
# @since 1.1.0
|
72
71
|
def get_header_class_by_name(name)
|
73
|
-
if Header.const_defined?
|
74
|
-
Header.const_get
|
72
|
+
if Header.const_defined?(name)
|
73
|
+
Header.const_get(name)
|
75
74
|
else
|
76
75
|
@added_header_classes[name]
|
77
76
|
end
|
data/lib/packetgen/headerable.rb
CHANGED
@@ -33,7 +33,7 @@ module PacketGen
|
|
33
33
|
# @param [Class] klass
|
34
34
|
# @return [void]
|
35
35
|
def self.included(klass)
|
36
|
-
klass.extend
|
36
|
+
klass.extend(ClassMethods)
|
37
37
|
end
|
38
38
|
|
39
39
|
# Return header protocol name
|
@@ -51,7 +51,7 @@ module PacketGen
|
|
51
51
|
end
|
52
52
|
|
53
53
|
# @abstract Should be redefined by subclasses. This method should check invariant
|
54
|
-
#
|
54
|
+
# attributes.from header.
|
55
55
|
# Called by {Packet#parse} when guessing first header to check if header is correct
|
56
56
|
# @return [Boolean]
|
57
57
|
def parse?
|
@@ -65,7 +65,7 @@ module PacketGen
|
|
65
65
|
end
|
66
66
|
|
67
67
|
# @api private
|
68
|
-
# Set packet to which this header belongs
|
68
|
+
# Set packet to which this header belongs to
|
69
69
|
# @param [Packet] packet
|
70
70
|
# @return [Packet] packet
|
71
71
|
def packet=(packet)
|
@@ -91,5 +91,15 @@ module PacketGen
|
|
91
91
|
|
92
92
|
super
|
93
93
|
end
|
94
|
+
|
95
|
+
# @abstract This method MUST be redefined by subclasses.
|
96
|
+
# Generate binary string from header
|
97
|
+
# @return [String]
|
98
|
+
# @raise [NotImplementedError]
|
99
|
+
def to_s
|
100
|
+
raise NotImplementedError, "#{self.class} should implement #to_s" if method(:to_s).super_method.nil?
|
101
|
+
|
102
|
+
super
|
103
|
+
end
|
94
104
|
end
|
95
105
|
end
|
data/lib/packetgen/inspect.rb
CHANGED
@@ -63,7 +63,7 @@ module PacketGen
|
|
63
63
|
|
64
64
|
# Format an attribute for +#inspect+.
|
65
65
|
# 3 cases are handled:
|
66
|
-
# * attribute value is a {
|
66
|
+
# * attribute value is a {BinStruct::Int}: show value as integer and in
|
67
67
|
# hexdecimal format,
|
68
68
|
# * attribute value responds to +#to_human+: call it,
|
69
69
|
# * else, +#to_s+ is used to format attribute value.
|
@@ -78,7 +78,7 @@ module PacketGen
|
|
78
78
|
|
79
79
|
# Format a ASN.1 attribute for +#inspect+.
|
80
80
|
# 4 cases are handled:
|
81
|
-
# * attribute value is a =RANS1::
|
81
|
+
# * attribute value is a =RANS1::BinStruct::Enumerated+: show named value and
|
82
82
|
# its integer value as hexdecimal format,
|
83
83
|
# * attribute value is a +RASN1::Types::Integer+: show value as integer and in
|
84
84
|
# hexdecimal format,
|