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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/lib/packetgen/header/arp.rb +54 -125
  4. data/lib/packetgen/header/base.rb +175 -0
  5. data/lib/packetgen/header/dns/name.rb +110 -0
  6. data/lib/packetgen/header/dns/opt.rb +137 -0
  7. data/lib/packetgen/header/dns/option.rb +17 -0
  8. data/lib/packetgen/header/dns/qdsection.rb +39 -0
  9. data/lib/packetgen/header/dns/question.rb +129 -0
  10. data/lib/packetgen/header/dns/rr.rb +89 -0
  11. data/lib/packetgen/header/dns/rrsection.rb +72 -0
  12. data/lib/packetgen/header/dns.rb +276 -0
  13. data/lib/packetgen/header/esp.rb +38 -70
  14. data/lib/packetgen/header/eth.rb +35 -106
  15. data/lib/packetgen/header/icmp.rb +19 -70
  16. data/lib/packetgen/header/icmpv6.rb +3 -3
  17. data/lib/packetgen/header/ip.rb +54 -210
  18. data/lib/packetgen/header/ipv6.rb +73 -164
  19. data/lib/packetgen/header/tcp/option.rb +34 -50
  20. data/lib/packetgen/header/tcp/options.rb +19 -20
  21. data/lib/packetgen/header/tcp.rb +66 -129
  22. data/lib/packetgen/header/udp.rb +31 -88
  23. data/lib/packetgen/header.rb +5 -10
  24. data/lib/packetgen/inspect.rb +5 -4
  25. data/lib/packetgen/packet.rb +74 -57
  26. data/lib/packetgen/pcapng/block.rb +49 -7
  27. data/lib/packetgen/pcapng/epb.rb +36 -34
  28. data/lib/packetgen/pcapng/file.rb +24 -8
  29. data/lib/packetgen/pcapng/idb.rb +28 -33
  30. data/lib/packetgen/pcapng/shb.rb +35 -39
  31. data/lib/packetgen/pcapng/spb.rb +18 -27
  32. data/lib/packetgen/pcapng/unknown_block.rb +11 -21
  33. data/lib/packetgen/pcapng.rb +9 -7
  34. data/lib/packetgen/types/array.rb +56 -0
  35. data/lib/packetgen/types/fields.rb +325 -0
  36. data/lib/packetgen/types/int.rb +164 -0
  37. data/lib/packetgen/types/int_string.rb +69 -0
  38. data/lib/packetgen/types/string.rb +36 -0
  39. data/lib/packetgen/types/tlv.rb +41 -0
  40. data/lib/packetgen/types.rb +13 -0
  41. data/lib/packetgen/version.rb +1 -1
  42. data/lib/packetgen.rb +1 -1
  43. metadata +19 -6
  44. data/lib/packetgen/header/header_class_methods.rb +0 -106
  45. data/lib/packetgen/header/header_methods.rb +0 -73
  46. data/lib/packetgen/structfu.rb +0 -363
@@ -1,363 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- module PacketGen
3
- # Copied from PacketFu:
4
- #
5
- # StructFu, a nifty way to leverage Ruby's built in Struct class
6
- # to create meaningful binary data.
7
- #
8
- # Copyright (c) 2008-2014, Tod Beardsley
9
- # All rights reserved.
10
- #
11
- # Redistribution and use in source and binary forms, with or without
12
- # modification, are permitted provided that the following conditions are met:
13
- #
14
- # * Redistributions of source code must retain the above copyright
15
- # notice, this list of conditions and the following disclaimer.
16
- # * Redistributions in binary form must reproduce the above copyright
17
- # notice, this list of conditions and the following disclaimer in the
18
- # documentation and/or other materials provided with the distribution.
19
- # * Neither the name of Tod Beardsley nor the
20
- # names of its contributors may be used to endorse or promote products
21
- # derived from this software without specific prior written permission.
22
- #
23
- # THIS SOFTWARE IS PROVIDED BY TOD BEARDSLEY ''AS IS'' AND ANY
24
- # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26
- # DISCLAIMED. IN NO EVENT SHALL TOD BEARDSLEY BE LIABLE FOR ANY
27
- # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28
- # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29
- # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30
- # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31
- # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32
- # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
- # @author Tod Beardsley
34
- module StructFu
35
-
36
- # Normally, self.size and self.length will refer to the Struct
37
- # size as an array. It's a hassle to redefine, so this introduces some
38
- # shorthand to get at the size of the resultant string.
39
- def sz
40
- self.to_s.size
41
- end
42
-
43
- alias len sz
44
-
45
- # Typecast is used mostly by packet header classes, such as IPHeader,
46
- # TCPHeader, and the like. It takes an argument, and casts it to the
47
- # expected type for that element.
48
- def typecast(i)
49
- c = caller[0].match(/.*`([^']+)='/)[1]
50
- self[c.intern].read i
51
- end
52
-
53
- # Used like typecast(), but specifically for casting Strings to StructFu::Strings.
54
- def body=(i)
55
- if i.kind_of? ::String
56
- typecast(i)
57
- elsif i.kind_of? StructFu
58
- self[:body] = i
59
- elsif i.nil?
60
- self[:body] = StructFu::String.new.read("")
61
- else
62
- raise ArgumentError, "Can't cram a #{i.class} into a StructFu :body"
63
- end
64
- end
65
-
66
- # Handle deep copies correctly.
67
- def clone
68
- Marshal.load(Marshal.dump(self))
69
- end
70
-
71
- # Set the endianness for the various Int classes handled by self
72
- # @param [:little, :big] e
73
- # @return [:little, :big] returns e
74
- def set_endianness(e)
75
- unless [:little, :big].include? e
76
- raise ArgumentError, "unknown endianness for #{self.class}"
77
- end
78
- @int64 = e == :little ? Int64le : Int64be
79
- @int32 = e == :little ? Int32le : Int32be
80
- @int16 = e == :little ? Int16le : Int16be
81
- e
82
- end
83
-
84
- # Get binary string
85
- # @return [String]
86
- # @author Sylvain Daubert
87
- def to_s
88
- to_a.map { |field| field.to_s }.join
89
- end
90
-
91
- # Ints all have a value, an endianness, and a default value.
92
- # Note that the signedness of Int values are implicit as
93
- # far as the subclasses are concerned; to_i and to_f will
94
- # return Integer/Float versions of the input value, instead
95
- # of attempting to unpack the pack value. (This can be a useful
96
- # hint to other functions).
97
- #
98
- # ==== Header Definition
99
- #
100
- # Fixnum :value
101
- # Symbol :endian
102
- # Fixnum :width
103
- # Fixnum :default
104
- class Int < Struct.new(:value, :endian, :width, :default)
105
- alias :v= :value=
106
- alias :v :value
107
- alias :e= :endian=
108
- alias :e :endian
109
- alias :w= :width=
110
- alias :w :width
111
- alias :d= :default=
112
- alias :d :default
113
-
114
- # This is a parent class definition and should not be used directly.
115
- def to_s
116
- raise StandardError, "StructFu::Int#to_s accessed, must be redefined."
117
- end
118
-
119
- # Returns the Int as an Integer.
120
- def to_i
121
- (self.v || self.d).to_i
122
- end
123
-
124
- # Returns the Int as a Float.
125
- def to_f
126
- (self.v || self.d).to_f
127
- end
128
-
129
- def initialize(value=nil, endian=nil, width=nil, default=nil)
130
- super(value,endian,width,default=0)
131
- end
132
-
133
- # Reads either an Integer or a packed string, and populates the value accordingly.
134
- def read(i)
135
- self.v = i.kind_of?(Integer) ? i.to_i : i.to_s.unpack(@packstr).first
136
- self
137
- end
138
- end
139
-
140
- # Int8 is a one byte value.
141
- class Int8 < Int
142
-
143
- def initialize(v=nil)
144
- super(v,nil,w=1)
145
- @packstr = "C"
146
- end
147
-
148
- # Returns a one byte value as a packed string.
149
- def to_s
150
- [(self.v || self.d)].pack("C")
151
- end
152
- end
153
-
154
- # Int16 is a two byte value.
155
- class Int16 < Int
156
- def initialize(v=nil, e=:big)
157
- super(v,e,w=2)
158
- @packstr = (self.e == :big) ? "n" : "v"
159
- end
160
-
161
- # Returns a two byte value as a packed string.
162
- def to_s
163
- @packstr = (self.e == :big) ? "n" : "v"
164
- [(self.v || self.d)].pack(@packstr)
165
- end
166
- end
167
-
168
- # Int16be is a two byte value in big-endian format. The endianness cannot be altered.
169
- class Int16be < Int16
170
- undef :endian=
171
- end
172
-
173
- # Int16le is a two byte value in little-endian format. The endianness cannot be altered.
174
- class Int16le < Int16
175
- undef :endian=
176
- def initialize(v=nil, e=:little)
177
- super(v,e)
178
- @packstr = (self.e == :big) ? "n" : "v"
179
- end
180
- end
181
-
182
- # Int32 is a four byte value.
183
- class Int32 < Int
184
- def initialize(v=nil, e=:big)
185
- super(v,e,w=4)
186
- @packstr = (self.e == :big) ? "N" : "V"
187
- end
188
-
189
- # Returns a four byte value as a packed string.
190
- def to_s
191
- @packstr = (self.e == :big) ? "N" : "V"
192
- [(self.v || self.d)].pack(@packstr)
193
- end
194
- end
195
-
196
- # Int32be is a four byte value in big-endian format. The endianness cannot be altered.
197
- class Int32be < Int32
198
- undef :endian=
199
- end
200
-
201
- # Int32le is a four byte value in little-endian format. The endianness cannot be altered.
202
- class Int32le < Int32
203
- undef :endian=
204
- def initialize(v=nil, e=:little)
205
- super(v,e)
206
- end
207
- end
208
-
209
- # Int64 is a eight byte value.
210
- class Int64 < Int
211
- def initialize(v=nil, e=:big)
212
- super(v, e, w=4)
213
- @packstr = (self.e == :big) ? 'Q>' : 'Q<'
214
- end
215
-
216
- # Returns a eight byte value as a packed string.
217
- def to_s
218
- @packstr = (self.e == :big) ? 'Q>' : 'Q<'
219
- [(self.v || self.d)].pack(@packstr)
220
- end
221
- end
222
-
223
- # Int64be is a eight byte value in big-endian format. The endianness cannot be altered.
224
- class Int64be < Int64
225
- undef :endian=
226
- end
227
-
228
- # Int64le is a eight byte value in little-endian format. The endianness cannot be altered.
229
- class Int64le < Int64
230
- undef :endian=
231
- def initialize(v=nil, e=:little)
232
- super(v,e)
233
- end
234
- end
235
-
236
- # Strings are just like regular strings, except it comes with a read() function
237
- # so that it behaves like other StructFu elements.
238
- class String < ::String
239
- def read(str)
240
- str = str.to_s
241
- self.replace str
242
- self
243
- end
244
-
245
- # @author Sylvain Daubert
246
- # Added for consistency with Struct classes
247
- alias :sz :length
248
- end
249
-
250
- # Provides a primitive for creating strings, preceeded by
251
- # an Int type of length. By default, a string of length zero with
252
- # a one-byte length is presumed.
253
- #
254
- # Note that IntStrings aren't used for much, but it seemed like a good idea at the time.
255
- class IntString < Struct.new(:int, :string, :mode)
256
-
257
- def initialize(string='',int=Int8,mode=nil)
258
- if int < Int
259
- super(int.new,string,mode)
260
- calc
261
- else
262
- raise "IntStrings need a StructFu::Int for a length."
263
- end
264
- end
265
-
266
- # Calculates the size of a string, and sets it as the value.
267
- def calc
268
- int.v = string.to_s.size
269
- self.to_s
270
- end
271
-
272
- # Returns the object as a string, depending on the mode set upon object creation.
273
- def to_s
274
- if mode == :parse
275
- "#{int}" + [string].pack("a#{len}")
276
- elsif mode == :fix
277
- self.int.v = string.size
278
- "#{int}#{string}"
279
- else
280
- "#{int}#{string}"
281
- end
282
- end
283
-
284
- # By redefining #string=, we can ensure the correct value
285
- # is calculated upon assignment. If you'd prefer to have
286
- # an incorrect value, use the syntax, obj[:string]="value"
287
- # instead. Note, by using the alternate form, you must
288
- # #calc before you can trust the int's value. Think of the =
289
- # assignment as "set to equal," while the []= assignment
290
- # as "boxing in" the value. Maybe.
291
- def string=(s)
292
- self[:string] = s
293
- calc
294
- end
295
-
296
- # Shorthand for querying a length. Note that the usual "length"
297
- # and "size" refer to the number of elements of this struct.
298
- def len
299
- self[:int].value
300
- end
301
-
302
- # Override the size, if you must.
303
- def len=(i)
304
- self[:int].value=i
305
- end
306
-
307
- # Read takes a string, assumes an int width as previously
308
- # defined upon initialization, but makes no guarantees
309
- # the int value isn't lying. You're on your own to test
310
- # for that (or use parse() with a :mode set).
311
- def read(s)
312
- unless s[0,int.width].size == int.width
313
- raise StandardError, "String is too short for type #{int.class}"
314
- else
315
- int.read(s[0,int.width])
316
- self[:string] = s[int.width,s.size]
317
- end
318
- self.to_s
319
- end
320
-
321
- # parse() is like read(), except that it interprets the string, either
322
- # based on the declared length, or the actual length. Which strategy
323
- # is used is dependant on which :mode is set (with self.mode).
324
- #
325
- # :parse : Read the length, and then read in that many bytes of the string.
326
- # The string may be truncated or padded out with nulls, as dictated by the value.
327
- #
328
- # :fix : Skip the length, read the rest of the string, then set the length
329
- # to what it ought to be.
330
- #
331
- # else : If neither of these modes are set, just perfom a normal read().
332
- # This is the default.
333
- def parse(s)
334
- unless s[0,int.width].size == int.width
335
- raise StandardError, "String is too short for type #{int.class}"
336
- else
337
- case mode
338
- when :parse
339
- int.read(s[0,int.width])
340
- self[:string] = s[int.width,int.value]
341
- if string.size < int.value
342
- self[:string] += ("\x00" * (int.value - self[:string].size))
343
- end
344
- when :fix
345
- self.string = s[int.width,s.size]
346
- else
347
- return read(s)
348
- end
349
- end
350
- self.to_s
351
- end
352
- end
353
- end
354
- end
355
-
356
- class Struct
357
- # Monkeypatch for Struct to include some string safety -- anything that uses
358
- # Struct is going to presume binary strings anyway.
359
- # Modified by S. Daubert to not call PacketFu.force_binary
360
- def force_binary(str)
361
- str.force_encoding Encoding::BINARY
362
- end
363
- end