packetgen 1.2.0 → 1.3.0

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