packetgen 3.3.3 → 4.0.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 +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 +29 -38
- 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,
|