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
@@ -4,41 +4,59 @@ module PacketGen
4
4
 
5
5
  # Base class to describe a TCP option
6
6
  # @author Sylvain Daubert
7
- class Option < Struct.new(:kind, :length, :value)
8
- include StructFu
7
+ class Option < Base
9
8
 
9
+ # EOL option value
10
10
  EOL_KIND = 0
11
+ # NOP option value
11
12
  NOP_KIND = 1
13
+ # MSS option value
12
14
  MSS_KIND = 2
15
+ # WS option value
13
16
  WS_KIND = 3
17
+ # SACKOK option value
14
18
  SACKOK_KIND = 4
19
+ # SACK option value
15
20
  SACK_KIND = 5
21
+ # ECHO option value
16
22
  ECHO_KIND = 6
23
+ # ECHOREPLY option value
17
24
  ECHOREPLY_KIND = 7
25
+ # TS option value
18
26
  TS_KIND = 8
19
27
 
28
+ # @!attribute kind
29
+ # Option kind
30
+ # @return [Integer] 8-bit option kind
31
+ define_field :kind, Types::Int8
32
+ # @!attribute length
33
+ # Option length
34
+ # @return [Integer] 8-bit option length
35
+ define_field :length, Types::Int8
36
+ # @!attribute value
37
+ # @return [Integer,String] option value
38
+ define_field :value, Types::String
39
+
20
40
  # @param [hash] options
21
41
  # @option options [Integer] :kind
22
42
  # @option options [Integer] :length
23
43
  # @option options [Integer,String] :value
24
44
  def initialize(options={})
25
- super Int8.new(options[:kind]),
26
- Int8.new(options[:length])
27
-
45
+ super
28
46
  case options[:value]
29
47
  when Integer
30
48
  klass = case self[:length].to_i
31
- when 3; Int8
32
- when 4; Int16
33
- when 6; Int32
49
+ when 3; Types::Int8
50
+ when 4; Types::Int16
51
+ when 6; Types::Int32
34
52
  else
35
53
  raise ArgumentError, 'impossible length'
36
54
  end
37
55
  self[:value] = klass.new(options[:value])
38
56
  when NilClass
39
- self[:value] = StructFu::String.new
57
+ self[:value] = Types::String.new
40
58
  else
41
- self[:value] = StructFu::String.new.read(options[:value])
59
+ self[:value] = Types::String.new.read(options[:value])
42
60
  self[:length].read(self[:value].sz + 2) unless options[:length]
43
61
  end
44
62
  end
@@ -59,33 +77,6 @@ module PacketGen
59
77
  self
60
78
  end
61
79
 
62
- # Getter for kind attribute
63
- # @return [Integer]
64
- def kind
65
- self[:kind].to_i
66
- end
67
-
68
- # Setter for kind attribute
69
- # @param [Integer] i
70
- # @return [Integer]
71
- def kind=(i)
72
- self[:kind].read i
73
- end
74
-
75
- # Getter for length attribute
76
- # @return [Integer]
77
- def length
78
- self[:length].to_i
79
- end
80
-
81
- # Setter for length attribute
82
- # @param [Integer] i
83
- # @return [Integer]
84
- def length=(i)
85
- self[:length].read i
86
- end
87
-
88
- # Say if option has a length
89
80
  # @return [Boolean]
90
81
  def has_length?
91
82
  self[:kind].value && kind >= 2
@@ -95,20 +86,13 @@ module PacketGen
95
86
  # @return [String, Integer]
96
87
  def value
97
88
  case self[:value]
98
- when StructFu::Int
89
+ when Types::Int
99
90
  self[:value].to_i
100
91
  else
101
92
  self[:value].to_s
102
93
  end
103
94
  end
104
95
 
105
- # Setter for value attribute
106
- # @param [String, Integer] v
107
- # @return [String, Integer]
108
- def value=(v)
109
- self[:value].read v
110
- end
111
-
112
96
  # Get binary string
113
97
  # @return [String]
114
98
  def to_s
@@ -160,7 +144,7 @@ module PacketGen
160
144
  # @see Option#initialize
161
145
  def initialize(options={})
162
146
  super options.merge!(kind: MSS_KIND, length: 4)
163
- self[:value] = Int16.new(options[:value])
147
+ self[:value] = Types::Int16.new(options[:value])
164
148
  end
165
149
 
166
150
  # @return [String]
@@ -175,7 +159,7 @@ module PacketGen
175
159
  # @see Option#initialize
176
160
  def initialize(options={})
177
161
  super options.merge!(kind: WS_KIND, length: 3)
178
- self[:value] = Int8.new(options[:value])
162
+ self[:value] = Types::Int8.new(options[:value])
179
163
  end
180
164
 
181
165
  # @return [String]
@@ -209,7 +193,7 @@ module PacketGen
209
193
  # @see Option#initialize
210
194
  def initialize(options={})
211
195
  super options.merge!(kind: ECHO_KIND, length: 6)
212
- self[:value] = Int32.new(options[:value])
196
+ self[:value] = Types::Int32.new(options[:value])
213
197
  end
214
198
 
215
199
  # @return [String]
@@ -224,7 +208,7 @@ module PacketGen
224
208
  # @see Option#initialize
225
209
  def initialize(options={})
226
210
  super options.merge!(kind: ECHOREPLY_KIND, length: 6)
227
- self[:value] = Int32.new(options[:value])
211
+ self[:value] = Types::Int32.new(options[:value])
228
212
  end
229
213
 
230
214
  # @return [String]
@@ -239,7 +223,7 @@ module PacketGen
239
223
  # @see Option#initialize
240
224
  def initialize(options={})
241
225
  super options.merge!(kind: TS_KIND, length: 10)
242
- self[:value] = StructFu::String.new.read(options[:value] || "\0" * 8)
226
+ self[:value] = Types::String.new.read(options[:value] || "\0" * 8)
243
227
  end
244
228
 
245
229
  # @return [String]
@@ -4,7 +4,7 @@ module PacketGen
4
4
 
5
5
  # Container for TCP options in {TCP TCP header}.
6
6
  # @author Sylvain Daubert
7
- class Options < Array
7
+ class Options < Types::Array
8
8
 
9
9
  # Get {Option} subclasses
10
10
  # @return [Array<Class>]
@@ -47,36 +47,35 @@ module PacketGen
47
47
  self
48
48
  end
49
49
 
50
+ # @deprecated use {#push} or {#<<}
50
51
  # Add a well-known option
51
52
  # @param [String] opt option name
52
53
  # @param [Object] value
53
54
  # @return [self]
54
55
  # @raise [ArgumentError] unknown option
55
56
  def add(opt, value=nil)
56
- raise ArgumentError, "unknown option #{opt}" unless TCP.const_defined?(opt)
57
- klass = TCP.const_get(opt)
58
- raise ArgumentError "unknown option #{opt}" unless klass < Option
59
- option = klass.new(value: value)
57
+ option = record_from_hash(opt: opt, value: value)
60
58
  self << option
61
59
  self
62
60
  end
63
61
 
64
- # Get options binary string
65
- # @return [String]
66
- def to_s
67
- map(&:to_s).join
68
- end
69
-
70
- # Get a human readable string
71
- # @return [String]
72
- def to_human
73
- map(&:to_human).join(', ')
74
- end
62
+ private
75
63
 
76
- # Get options size in bytes
77
- # @return [Integer]
78
- def sz
79
- to_s.length
64
+ def record_from_hash(hsh)
65
+ if hsh.has_key? :opt
66
+ klassname = hsh.delete(:opt)
67
+ if TCP.const_defined?(klassname)
68
+ klass = TCP.const_get(klassname)
69
+ unless klass < Option
70
+ raise ArgumentError, 'opt should be a TCP::Option subclass'
71
+ end
72
+ klass.new(hsh)
73
+ else
74
+ raise ArgumentError, 'opt should be a TCP::Option subclass'
75
+ end
76
+ else
77
+ hsh
78
+ end
80
79
  end
81
80
  end
82
81
  end
@@ -2,9 +2,9 @@ module PacketGen
2
2
  module Header
3
3
 
4
4
  # A TCP header consists of:
5
- # * a source port ({#sport}, {Int16} type),
5
+ # * a source port ({#sport}, {Types::Int16} type),
6
6
  # * a destination port ({#dport}, +Int16+ type),
7
- # * a sequence number ({#seqnum}, {Int32} type),
7
+ # * a sequence number ({#seqnum}, {Types::Int32} type),
8
8
  # * an acknownledge number ({#acknum}, +Int32+ type),
9
9
  # * a 16-bit field ({#u16}, +Int16+ type) composed of:
10
10
  # * a 4-bit {#data_offset} value,
@@ -14,7 +14,7 @@ module PacketGen
14
14
  # * a {#checksum} field (+Int16+ type),
15
15
  # * a urgent pointer ({#urg_pointer}, +Int16+ type),
16
16
  # * an optional {#options} field ({Options} type),
17
- # * and a {#body} ({String} type).
17
+ # * and a {#body} ({Types::String} type).
18
18
  #
19
19
  # == Create a TCP header
20
20
  # # standalone
@@ -43,14 +43,10 @@ module PacketGen
43
43
  # == Options
44
44
  # {#options} TCP attribute is a {Options}. {Option} may added to it:
45
45
  # tcph.options << PacketGen::Header::TCP::MSS.new(1250)
46
- # Another way is to use {Options#add}:
47
- # tcph.options.add 'MSS', 1250
46
+ # or:
47
+ # tcph.options << { opt: 'MSS', value: 1250 }
48
48
  # @author Sylvain Daubert
49
- class TCP < Struct.new(:sport, :dport, :seqnum, :acknum, :u16,
50
- :window, :checksum, :urg_pointer, :options, :body)
51
- include StructFu
52
- include HeaderMethods
53
- extend HeaderClassMethods
49
+ class TCP < Base
54
50
  end
55
51
  end
56
52
  end
@@ -65,6 +61,61 @@ module PacketGen
65
61
  # IP protocol number for TCP
66
62
  IP_PROTOCOL = 6
67
63
 
64
+ # @!attribute sport
65
+ # 16-bit TCP source port
66
+ # @return [Integer]
67
+ define_field :sport, Types::Int16
68
+ # @!attribute dport
69
+ # 16-bit TCP destination port
70
+ # @return [Integer]
71
+ define_field :dport, Types::Int16
72
+ # @!attribute seqnum
73
+ # 32-bit TCP sequence number
74
+ # @return [Integer]
75
+ define_field :seqnum, Types::Int32, default: -> { rand(2**32) }
76
+ # @!attribute acknum
77
+ # 32-bit TCP acknowledgement number
78
+ # @return [Integer]
79
+ define_field :acknum, Types::Int32
80
+ # @!attribute u16
81
+ # @return [Integer] 16-bit word used by flags and bit fields
82
+ define_field :u16, Types::Int16
83
+ # @!attribute window
84
+ # 16-bit TCP window size
85
+ # @return [Integer]
86
+ define_field :window, Types::Int16
87
+ # @!attribute checksum
88
+ # 16-bit TCP checksum
89
+ # @return [Integer]
90
+ define_field :checksum, Types::Int16
91
+ # @!attribute urg_pointer
92
+ # 16-bit TCP urgent data pointer
93
+ # @return [Integer]
94
+ define_field :urg_pointer, Types::Int16
95
+ # @!attribute options
96
+ # TCP options
97
+ # @return [Options]
98
+ define_field :options, TCP::Options
99
+ # @!attribute body
100
+ # @return [Types::String,Header::Base]
101
+ define_field :body, Types::String
102
+
103
+ alias source_port sport
104
+ alias source_port= sport=
105
+ alias destination_port dport
106
+ alias destination_port= dport=
107
+ alias sequence_number seqnum
108
+ alias sequence_number= seqnum=
109
+ alias acknowledgement_number acknum
110
+ alias acknowledgement_number= acknum=
111
+ alias wsize window
112
+ alias wsize= window=
113
+
114
+ # Call {Base#initialize), then handle specific options to set +u16+ by part:
115
+ # * +:data_offset+
116
+ # * +:hlen+
117
+ # * +:reserved+
118
+ # * +:flags+
68
119
  # @param [Hash] options
69
120
  # @option options [Integer] :sport
70
121
  # @option options [Integer] :dport
@@ -78,21 +129,8 @@ module PacketGen
78
129
  # @option options [Integer] :urg_pointer
79
130
  # @option options [String] :body
80
131
  def initialize(options={})
81
- super Int16.new(options[:sport]),
82
- Int16.new(options[:dport]),
83
- Int32.new(options[:seqnum] || rand(2**32)),
84
- Int32.new(options[:acknum]),
85
- Int16.new,
86
- Int16.new(options[:window] || options[:wsize]),
87
- Int16.new(options[:checksum]),
88
- Int16.new(options[:urg_pointer]),
89
- Options.new,
90
- StructFu::String.new.read(options[:body])
91
-
92
- doff = options[:data_offset] || options[:hlen] || 5
93
- rsv = options[:reserved] || 0
94
- flgs = options[:flags] || 0
95
- self.u16.read (((doff << 3) | rsv) << 9) | flgs
132
+ opts = { data_offset: 5 }.merge!(options)
133
+ super(opts)
96
134
  end
97
135
 
98
136
  # @!attribute data_offset
@@ -130,7 +168,6 @@ module PacketGen
130
168
  # @return [self]
131
169
  def read(str)
132
170
  return self if str.nil?
133
- raise ParseError, 'string too short for TCP' if str.size < self.sz
134
171
  force_binary str
135
172
  self[:sport].read str[0, 2]
136
173
  self[:dport].read str[2, 2]
@@ -142,6 +179,7 @@ module PacketGen
142
179
  self[:urg_pointer].read str[18, 2]
143
180
  self[:options].read str[20, (self.data_offset - 5) * 4] if self.data_offset > 5
144
181
  self[:body].read str[self.data_offset * 4..-1]
182
+ self
145
183
  end
146
184
 
147
185
  # Compute checksum and set +checksum+ field
@@ -167,109 +205,8 @@ module PacketGen
167
205
  self[:data_offset] = 5 + self[:options].sz / 4
168
206
  end
169
207
 
170
- # Getter for source port
171
- # @return [Integer]
172
- def sport
173
- self[:sport].to_i
174
- end
175
- alias :source_port :sport
176
-
177
- # Setter for source port
178
- # @param [Integer] port
179
- # @return [Integer]
180
- def sport=(port)
181
- self[:sport].read port
182
- end
183
- alias :source_port= :sport=
184
-
185
- # Getter for destination port
186
- # @return [Integer]
187
- def dport
188
- self[:dport].to_i
189
- end
190
- alias :destination_port :dport
191
-
192
- # Setter for destination port
193
- # @param [Integer] port
194
- # @return [Integer]
195
- def dport=(port)
196
- self[:dport].read port
197
- end
198
- alias :destination_port= :dport=
199
-
200
- # Getter for seqnum attribuute
201
- # @return [Integer]
202
- def seqnum
203
- self[:seqnum].to_i
204
- end
205
- alias :sequence_number :seqnum
206
-
207
- # Setter for seqnum attribuute
208
- # @param [Integer] seq
209
- # @return [Integer]
210
- def seqnum=(seq)
211
- self[:seqnum].read seq
212
- end
213
- alias :sequence_number= :seqnum=
214
-
215
- # Getter for acknum attribuute
216
- # @return [Integer]
217
- def acknum
218
- self[:acknum].to_i
219
- end
220
- alias :acknowledgment_number :acknum
221
-
222
- # Setter for acknum attribuute
223
- # @param [Integer] ack
224
- # @return [Integer]
225
- def acknum=(ack)
226
- self[:acknum].read ack
227
- end
228
- alias :acknowledgment_number= :acknum=
229
-
230
- alias :hlen :data_offset
231
- alias :hlen= :data_offset=
232
-
233
- # Getter for window attribuute
234
- # @return [Integer]
235
- def window
236
- self[:window].to_i
237
- end
238
- alias :wsize :window
239
-
240
- # Setter for window attribuute
241
- # @param [Integer] window
242
- # @return [Integer]
243
- def window=(window)
244
- self[:window].read window
245
- end
246
- alias :wsize= :window=
247
-
248
- # Getter for checksum attribuute
249
- # @return [Integer]
250
- def checksum
251
- self[:checksum].to_i
252
- end
253
-
254
- # Setter for checksum attribuute
255
- # @param [Integer] sum
256
- # @return [Integer]
257
- def checksum=(sum)
258
- self[:checksum].read sum
259
- end
260
-
261
- # Getter for urg_pointer attribuute
262
- # @return [Integer]
263
- def urg_pointer
264
- self[:urg_pointer].to_i
265
- end
266
-
267
- # Setter for urg_pointer attribuute
268
- # @param [Integer] urg
269
- # @return [Integer]
270
- def urg_pointer=(urg)
271
- self[:urg_pointer].read urg
272
- end
208
+ alias hlen data_offset
209
+ alias hlen= data_offset=
273
210
 
274
211
  # @return [String]
275
212
  def inspect
@@ -7,7 +7,7 @@ module PacketGen
7
7
  module Header
8
8
 
9
9
  # A UDP header consists of:
10
- # * a source port field ({#sport}, {Int16} type),
10
+ # * a source port field ({#sport}, {Types::Int16} type),
11
11
  # * a destination port field ({#dport}, +Int16+ type),
12
12
  # * a UDP length field ({#length}, +Int16+ type),
13
13
  # * a {#checksum} field (+Int16+ type),
@@ -29,42 +29,41 @@ module PacketGen
29
29
  # udp.body.read 'this is a UDP body'
30
30
  #
31
31
  # @author Sylvain Daubert
32
- class UDP < Struct.new(:sport, :dport, :length, :checksum, :body)
33
- include StructFu
34
- include HeaderMethods
35
- extend HeaderClassMethods
32
+ class UDP < Base
36
33
 
37
34
  # IP protocol number for UDP
38
35
  IP_PROTOCOL = 17
39
36
 
40
- # @param [Hash] options
41
- # @option options [Integer] :sport source port
42
- # @option options [Integer] :dport destination port
43
- # @option options [Integer] :length UDP length. Default: calculated
44
- # @option options [Integer] :checksum. UDP checksum. Default: 0
37
+ # @!attribute sport
38
+ # 16-bit UDP source port
39
+ # @return [Integer]
40
+ define_field :sport, Types::Int16
41
+ # @!attribute dport
42
+ # 16-bit UDP destination port
43
+ # @return [Integer]
44
+ define_field :dport, Types::Int16
45
+ # @!attribute length
46
+ # 16-bit UDP length
47
+ # @return [Integer]
48
+ define_field :length, Types::Int16, default: 8
49
+ # @!attribute checksum
50
+ # 16-bit UDP checksum
51
+ # @return [Integer]
52
+ define_field :checksum, Types::Int16
53
+ # @!attribute body
54
+ # @return [Types::String,Header::Base]
55
+ define_field :body, Types::String
56
+
57
+ alias source_port sport
58
+ alias source_port= sport=
59
+ alias destination_port dport
60
+ alias destination_port= dport=
61
+
62
+ # Call {Base#initialize), and automagically compute +length+ if +:body+
63
+ # option is set.
45
64
  def initialize(options={})
46
- super Int16.new(options[:sport]),
47
- Int16.new(options[:dport]),
48
- Int16.new(options[:length]),
49
- Int16.new(options[:checksum]),
50
- StructFu::String.new.read(options[:body])
51
- unless options[:length]
52
- calc_length
53
- end
54
- end
55
-
56
- # Read a IP header from a string
57
- # @param [String] str binary string
58
- # @return [self]
59
- def read(str)
60
- return self if str.nil?
61
- raise ParseError, 'string too short for UDP' if str.size < self.sz
62
- force_binary str
63
- self[:sport].read str[0, 2]
64
- self[:dport].read str[2, 2]
65
- self[:length].read str[4, 2]
66
- self[:checksum].read str[6, 2]
67
- self[:body].read str[8..-1]
65
+ super
66
+ self.length += self[:body].sz if self[:body].sz > 0
68
67
  end
69
68
 
70
69
  # Compute checksum and set +checksum+ field
@@ -93,62 +92,6 @@ module PacketGen
93
92
  def calc_length
94
93
  self[:length].value = self.sz
95
94
  end
96
-
97
- # Getter for source port
98
- # @return [Integer]
99
- def sport
100
- self[:sport].to_i
101
- end
102
- alias :source_port :sport
103
-
104
- # Setter for source port
105
- # @param [Integer] port
106
- # @return [Integer]
107
- def sport=(port)
108
- self[:sport].read port
109
- end
110
- alias :source_port= :sport=
111
-
112
- # Getter for destination port
113
- # @return [Integer]
114
- def dport
115
- self[:dport].to_i
116
- end
117
- alias :destination_port :dport
118
-
119
- # Setter for destination port
120
- # @param [Integer] port
121
- # @return [Integer]
122
- def dport=(port)
123
- self[:dport].read port
124
- end
125
- alias :destination_port= :dport=
126
-
127
- # Getter for length attribuute
128
- # @return [Integer]
129
- def length
130
- self[:length].to_i
131
- end
132
-
133
- # Setter for length attribuute
134
- # @param [Integer] len
135
- # @return [Integer]
136
- def length=(len)
137
- self[:length].read len
138
- end
139
-
140
- # Getter for checksum attribuute
141
- # @return [Integer]
142
- def checksum
143
- self[:checksum].to_i
144
- end
145
-
146
- # Setter for checksum attribuute
147
- # @param [Integer] checksum
148
- # @return [Integer]
149
- def checksum=(checksum)
150
- self[:checksum].read checksum
151
- end
152
95
  end
153
96
 
154
97
  self.add_class UDP
@@ -10,11 +10,7 @@ module PacketGen
10
10
  # Since v1.1.0, PacketGen permits adding you own header classes.
11
11
  # First, define the new header class. By example:
12
12
  # module MyModule
13
- # class MyHeader < Struct.new(:field1, :field2)
14
- # include PacketGen::StructFu
15
- # include PacketGen::Header::HeaderMethods
16
- # extend PacketGen::Header::HeaderClassMethods
17
- #
13
+ # class MyHeader < PacketGen::Header::Base
18
14
  # def initialize(options={})
19
15
  # super Int32.new(options[:field1]), Int32.new(options[:field2])
20
16
  # end
@@ -47,8 +43,7 @@ module PacketGen
47
43
 
48
44
  # Add a foreign header class to known header classes. This is
49
45
  # needed by {Packet.gen} and {Packet#add}.
50
- # @param [Class] klass a header class, which should include
51
- # {Header::HeaderMethods} and {Header::HeaderClassMethods}
46
+ # @param [Class] klass a header class
52
47
  # @return [void]
53
48
  # @since 1.1.0
54
49
  def self.add_class(klass)
@@ -57,7 +52,7 @@ module PacketGen
57
52
  @header_classes = nil
58
53
  end
59
54
 
60
- # Remove a foreign header (previously added by {.add_header_class}à
55
+ # Remove a foreign header (previously added by {.add_header_class}
61
56
  # from known header classes.
62
57
  # @param [Class] klass
63
58
  # @return [void]
@@ -82,8 +77,7 @@ module PacketGen
82
77
  end
83
78
  end
84
79
 
85
- require_relative 'header/header_class_methods'
86
- require_relative 'header/header_methods'
80
+ require_relative 'header/base'
87
81
  require_relative 'header/eth'
88
82
  require_relative 'header/ip'
89
83
  require_relative 'header/icmp'
@@ -93,3 +87,4 @@ require_relative 'header/icmpv6'
93
87
  require_relative 'header/udp'
94
88
  require_relative 'header/tcp'
95
89
  require_relative 'header/esp'
90
+ require_relative 'header/dns'