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.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/lib/packetgen/header/arp.rb +54 -125
- data/lib/packetgen/header/base.rb +175 -0
- data/lib/packetgen/header/dns/name.rb +110 -0
- data/lib/packetgen/header/dns/opt.rb +137 -0
- data/lib/packetgen/header/dns/option.rb +17 -0
- data/lib/packetgen/header/dns/qdsection.rb +39 -0
- data/lib/packetgen/header/dns/question.rb +129 -0
- data/lib/packetgen/header/dns/rr.rb +89 -0
- data/lib/packetgen/header/dns/rrsection.rb +72 -0
- data/lib/packetgen/header/dns.rb +276 -0
- data/lib/packetgen/header/esp.rb +38 -70
- data/lib/packetgen/header/eth.rb +35 -106
- data/lib/packetgen/header/icmp.rb +19 -70
- data/lib/packetgen/header/icmpv6.rb +3 -3
- data/lib/packetgen/header/ip.rb +54 -210
- data/lib/packetgen/header/ipv6.rb +73 -164
- data/lib/packetgen/header/tcp/option.rb +34 -50
- data/lib/packetgen/header/tcp/options.rb +19 -20
- data/lib/packetgen/header/tcp.rb +66 -129
- data/lib/packetgen/header/udp.rb +31 -88
- data/lib/packetgen/header.rb +5 -10
- data/lib/packetgen/inspect.rb +5 -4
- data/lib/packetgen/packet.rb +74 -57
- data/lib/packetgen/pcapng/block.rb +49 -7
- data/lib/packetgen/pcapng/epb.rb +36 -34
- data/lib/packetgen/pcapng/file.rb +24 -8
- data/lib/packetgen/pcapng/idb.rb +28 -33
- data/lib/packetgen/pcapng/shb.rb +35 -39
- data/lib/packetgen/pcapng/spb.rb +18 -27
- data/lib/packetgen/pcapng/unknown_block.rb +11 -21
- data/lib/packetgen/pcapng.rb +9 -7
- data/lib/packetgen/types/array.rb +56 -0
- data/lib/packetgen/types/fields.rb +325 -0
- data/lib/packetgen/types/int.rb +164 -0
- data/lib/packetgen/types/int_string.rb +69 -0
- data/lib/packetgen/types/string.rb +36 -0
- data/lib/packetgen/types/tlv.rb +41 -0
- data/lib/packetgen/types.rb +13 -0
- data/lib/packetgen/version.rb +1 -1
- data/lib/packetgen.rb +1 -1
- metadata +19 -6
- data/lib/packetgen/header/header_class_methods.rb +0 -106
- data/lib/packetgen/header/header_methods.rb +0 -73
- data/lib/packetgen/structfu.rb +0 -363
@@ -0,0 +1,164 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# This file is part of PacketGen
|
3
|
+
# See https://github.com/sdaubert/packetgen for more informations
|
4
|
+
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
5
|
+
# This program is published under MIT license.
|
6
|
+
|
7
|
+
module PacketGen
|
8
|
+
module Types
|
9
|
+
|
10
|
+
# Base integer class to handle binary integers
|
11
|
+
# @abstract
|
12
|
+
# @author Sylvain Daubert
|
13
|
+
class Int
|
14
|
+
|
15
|
+
# Integer value
|
16
|
+
# @return [Integer]
|
17
|
+
attr_accessor :value
|
18
|
+
# Integer endianness
|
19
|
+
# @return [:little,:big]
|
20
|
+
attr_accessor :endian
|
21
|
+
# Integer size, in bytes
|
22
|
+
# @return [Integer]
|
23
|
+
attr_accessor :width
|
24
|
+
# Integer default value
|
25
|
+
# @return [Integer]
|
26
|
+
attr_accessor :default
|
27
|
+
|
28
|
+
# @param [Integer,nil] value
|
29
|
+
# @param [:little,:big,nil] endian
|
30
|
+
# @param [Integer,nil] width
|
31
|
+
# @param [Integer] default
|
32
|
+
def initialize(value=nil, endian=nil, width=nil, default=0)
|
33
|
+
@value = value
|
34
|
+
@endian = endian
|
35
|
+
@width = width
|
36
|
+
@default = default
|
37
|
+
end
|
38
|
+
|
39
|
+
def read(value)
|
40
|
+
@value = if value.is_a?(Integer)
|
41
|
+
value.to_i
|
42
|
+
else
|
43
|
+
value.to_s.unpack(@packstr[@endian]).first
|
44
|
+
end
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
# @abstract
|
49
|
+
# @return [::String]
|
50
|
+
# @raise [StandardError] This is an abstrat method and must be redefined
|
51
|
+
def to_s
|
52
|
+
unless defined? @packstr
|
53
|
+
raise StandardError, 'PacketGen::Types::Int#to_s is an abstract method'
|
54
|
+
end
|
55
|
+
[to_i].pack(@packstr[@endian])
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_i
|
59
|
+
@value || @default
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_f
|
63
|
+
to_i.to_f
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# One byte integer
|
68
|
+
# @author Sylvain Daubert
|
69
|
+
class Int8 < Int
|
70
|
+
# @param [Integer,nil] value
|
71
|
+
def initialize(value=nil)
|
72
|
+
super(value, nil, 1)
|
73
|
+
@packstr = { nil => 'C' }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# 2-byte integer
|
78
|
+
# @author Sylvain Daubert
|
79
|
+
class Int16 < Int
|
80
|
+
# @param [Integer,nil] value
|
81
|
+
# @param [:big, :little] endian
|
82
|
+
def initialize(value=nil, endian=:big)
|
83
|
+
super(value, endian, 2)
|
84
|
+
@packstr = { big: 'n', little: 'v' }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# big endian 2-byte integer
|
89
|
+
# @author Sylvain Daubert
|
90
|
+
class Int16be < Int16
|
91
|
+
undef endian=
|
92
|
+
end
|
93
|
+
|
94
|
+
# little endian 2-byte integer
|
95
|
+
# @author Sylvain Daubert
|
96
|
+
class Int16le < Int16
|
97
|
+
# @param [Integer,nil] value
|
98
|
+
undef endian=
|
99
|
+
|
100
|
+
# @param [Integer, nil] value
|
101
|
+
def initialize(value=nil)
|
102
|
+
super(value, :little)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# 4-byte integer
|
107
|
+
# @author Sylvain Daubert
|
108
|
+
class Int32 < Int
|
109
|
+
# @param [Integer,nil] value
|
110
|
+
# @param [:big, :little] endian
|
111
|
+
def initialize(value=nil, endian=:big)
|
112
|
+
super(value, endian, 4)
|
113
|
+
@packstr = { big: 'N', little: 'V' }
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# big endian 4-byte integer
|
118
|
+
# @author Sylvain Daubert
|
119
|
+
class Int32be < Int32
|
120
|
+
undef endian=
|
121
|
+
end
|
122
|
+
|
123
|
+
# little endian 4-byte integer
|
124
|
+
# @author Sylvain Daubert
|
125
|
+
class Int32le < Int32
|
126
|
+
# @param [Integer,nil] value
|
127
|
+
undef endian=
|
128
|
+
|
129
|
+
# @param [Integer, nil] value
|
130
|
+
def initialize(value=nil)
|
131
|
+
super(value, :little)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# 8-byte integer
|
136
|
+
# @author Sylvain Daubert
|
137
|
+
class Int64 < Int
|
138
|
+
# @param [Integer,nil] value
|
139
|
+
# @param [:big, :little] endian
|
140
|
+
def initialize(value=nil, endian=:big)
|
141
|
+
super(value, endian, 8)
|
142
|
+
@packstr = { big: 'Q>', little: 'Q<' }
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# big endian 8-byte integer
|
147
|
+
# @author Sylvain Daubert
|
148
|
+
class Int64be < Int64
|
149
|
+
undef endian=
|
150
|
+
end
|
151
|
+
|
152
|
+
# little endian 8-byte integer
|
153
|
+
# @author Sylvain Daubert
|
154
|
+
class Int64le < Int64
|
155
|
+
# @param [Integer,nil] value
|
156
|
+
undef endian=
|
157
|
+
|
158
|
+
# @param [Integer, nil] value
|
159
|
+
def initialize(value=nil)
|
160
|
+
super(value, :little)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# This file is part of PacketGen
|
3
|
+
# See https://github.com/sdaubert/packetgen for more informations
|
4
|
+
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
5
|
+
# This program is published under MIT license.
|
6
|
+
|
7
|
+
module PacketGen
|
8
|
+
module Types
|
9
|
+
|
10
|
+
# Provides a class for creating strings preceeded by their length as a {Int}.
|
11
|
+
# By default, a null string will have one byte length (length byte set to 0).
|
12
|
+
# @author Sylvain Daubert
|
13
|
+
class IntString
|
14
|
+
|
15
|
+
# internal string
|
16
|
+
# @return [String]
|
17
|
+
attr_accessor :string
|
18
|
+
|
19
|
+
# @param [::String] str
|
20
|
+
# @param [Class] len_type should be a {Int} subclass
|
21
|
+
def initialize(str='', len_type=Int8)
|
22
|
+
@string = Types::String.new(str)
|
23
|
+
@length = len_type.new
|
24
|
+
calc_length
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param [::String] str
|
28
|
+
# @return [IntString] self
|
29
|
+
def read(str)
|
30
|
+
unless str[0, @length.width].size == @length.width
|
31
|
+
raise ParseError, "String too short for type #{@length.type}"
|
32
|
+
end
|
33
|
+
@length.read str[0, @length.width]
|
34
|
+
@string.read str[@length.width, @length.to_i]
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
# @param [Integer] l
|
39
|
+
# @return [Integer]
|
40
|
+
def length=(l)
|
41
|
+
@length.read l
|
42
|
+
l
|
43
|
+
end
|
44
|
+
|
45
|
+
# @return [Integer]
|
46
|
+
def length
|
47
|
+
@length.to_i
|
48
|
+
end
|
49
|
+
|
50
|
+
# Get binary string
|
51
|
+
# @return [::String]
|
52
|
+
def to_s
|
53
|
+
@length.to_s << @string.to_s
|
54
|
+
end
|
55
|
+
|
56
|
+
# Set length from internal string length
|
57
|
+
# @return [Integer]
|
58
|
+
def calc_length
|
59
|
+
@length.read @string.length
|
60
|
+
end
|
61
|
+
|
62
|
+
# Give binary string length
|
63
|
+
# @return [Integer]
|
64
|
+
def sz
|
65
|
+
to_s.size
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# This file is part of PacketGen
|
3
|
+
# See https://github.com/sdaubert/packetgen for more informations
|
4
|
+
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
5
|
+
# This program is published under MIT license.
|
6
|
+
|
7
|
+
module PacketGen
|
8
|
+
module Types
|
9
|
+
|
10
|
+
# This class is just like regular String. It only adds #read and #sz methods
|
11
|
+
# to be compatible with others {Types}.
|
12
|
+
# @author Sylvain Daubert
|
13
|
+
class String < ::String
|
14
|
+
|
15
|
+
# @param [String] str
|
16
|
+
# @param [Hash] options
|
17
|
+
# @option options [Types::Int] :length_from object from which takes length when
|
18
|
+
# reading
|
19
|
+
def initialize(str='', options={})
|
20
|
+
super(str)
|
21
|
+
@length_from = options[:length_from]
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param [::String] str
|
25
|
+
# @return [String] self
|
26
|
+
def read(str)
|
27
|
+
s = str.to_s
|
28
|
+
s = s[0, @length_from.to_i] unless @length_from.nil?
|
29
|
+
self.replace s
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
alias sz length
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module PacketGen
|
2
|
+
module Types
|
3
|
+
|
4
|
+
# Class to handle Type-Length-Value attributes
|
5
|
+
# @author Sylvain Daubert
|
6
|
+
class TLV < Fields
|
7
|
+
# @!attribute type
|
8
|
+
# @return [Integer]
|
9
|
+
define_field :type, Int8
|
10
|
+
# @!attribute length
|
11
|
+
# @return [Integer]
|
12
|
+
define_field :length, Int8
|
13
|
+
# @!attribute value
|
14
|
+
# @return [String]
|
15
|
+
define_field :value, String,
|
16
|
+
builder: ->(tlv) { String.new('', length_from: tlv[:length]) }
|
17
|
+
|
18
|
+
# @param [Hash] options
|
19
|
+
# @option options [Integer] :type
|
20
|
+
# @option options [Integer] :length
|
21
|
+
# @option options [String] :value
|
22
|
+
# @option options [Class] :t {Int} subclass for +:type+ attribute.
|
23
|
+
# Default: {Int8}.
|
24
|
+
# @option options [Class] :l {Int} subclass for +:length+ attribute.
|
25
|
+
# Default: {Int8}.
|
26
|
+
def initialize(options={})
|
27
|
+
super
|
28
|
+
self[:type] = options[:t].new(type) if options[:t]
|
29
|
+
if options[:l]
|
30
|
+
self[:length] = options[:l].new(length)
|
31
|
+
self[:value] = String.new('', length_from: self[:length])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [String]
|
36
|
+
def to_human
|
37
|
+
"type=#{type},len=#{length},value=#{value.inspect}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module PacketGen
|
2
|
+
|
3
|
+
# Module to group all type definitions
|
4
|
+
module Types
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
require_relative 'types/int'
|
9
|
+
require_relative 'types/string'
|
10
|
+
require_relative 'types/int_string'
|
11
|
+
require_relative 'types/fields'
|
12
|
+
require_relative 'types/array'
|
13
|
+
require_relative 'types/tlv'
|
data/lib/packetgen/version.rb
CHANGED
data/lib/packetgen.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: packetgen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sylvain Daubert
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01-
|
11
|
+
date: 2017-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pcaprub
|
@@ -111,10 +111,17 @@ files:
|
|
111
111
|
- lib/packetgen/capture.rb
|
112
112
|
- lib/packetgen/header.rb
|
113
113
|
- lib/packetgen/header/arp.rb
|
114
|
+
- lib/packetgen/header/base.rb
|
115
|
+
- lib/packetgen/header/dns.rb
|
116
|
+
- lib/packetgen/header/dns/name.rb
|
117
|
+
- lib/packetgen/header/dns/opt.rb
|
118
|
+
- lib/packetgen/header/dns/option.rb
|
119
|
+
- lib/packetgen/header/dns/qdsection.rb
|
120
|
+
- lib/packetgen/header/dns/question.rb
|
121
|
+
- lib/packetgen/header/dns/rr.rb
|
122
|
+
- lib/packetgen/header/dns/rrsection.rb
|
114
123
|
- lib/packetgen/header/esp.rb
|
115
124
|
- lib/packetgen/header/eth.rb
|
116
|
-
- lib/packetgen/header/header_class_methods.rb
|
117
|
-
- lib/packetgen/header/header_methods.rb
|
118
125
|
- lib/packetgen/header/icmp.rb
|
119
126
|
- lib/packetgen/header/icmpv6.rb
|
120
127
|
- lib/packetgen/header/ip.rb
|
@@ -133,7 +140,13 @@ files:
|
|
133
140
|
- lib/packetgen/pcapng/shb.rb
|
134
141
|
- lib/packetgen/pcapng/spb.rb
|
135
142
|
- lib/packetgen/pcapng/unknown_block.rb
|
136
|
-
- lib/packetgen/
|
143
|
+
- lib/packetgen/types.rb
|
144
|
+
- lib/packetgen/types/array.rb
|
145
|
+
- lib/packetgen/types/fields.rb
|
146
|
+
- lib/packetgen/types/int.rb
|
147
|
+
- lib/packetgen/types/int_string.rb
|
148
|
+
- lib/packetgen/types/string.rb
|
149
|
+
- lib/packetgen/types/tlv.rb
|
137
150
|
- lib/packetgen/version.rb
|
138
151
|
- packetgen.gemspec
|
139
152
|
homepage: https://github.com/sdaubert/packetgen
|
@@ -155,7 +168,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
155
168
|
version: '0'
|
156
169
|
requirements: []
|
157
170
|
rubyforge_project:
|
158
|
-
rubygems_version: 2.
|
171
|
+
rubygems_version: 2.5.2
|
159
172
|
signing_key:
|
160
173
|
specification_version: 4
|
161
174
|
summary: Network packet generator and analyzor
|
@@ -1,106 +0,0 @@
|
|
1
|
-
# This file is part of PacketGen
|
2
|
-
# See https://github.com/sdaubert/packetgen for more informations
|
3
|
-
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
|
-
# This program is published under MIT license.
|
5
|
-
|
6
|
-
module PacketGen
|
7
|
-
module Header
|
8
|
-
|
9
|
-
module HeaderClassMethods
|
10
|
-
|
11
|
-
# @api private
|
12
|
-
# Simple class to handle header association
|
13
|
-
Binding = Struct.new(:key, :value)
|
14
|
-
|
15
|
-
# Bind a upper header to current class
|
16
|
-
# @param [Class] header_klass header class to bind to current class
|
17
|
-
# @param [Hash] args current class fields and their value when +header_klass+
|
18
|
-
# is embedded in current class
|
19
|
-
# @return [void]
|
20
|
-
def bind_header(header_klass, args={})
|
21
|
-
@known_headers ||= {}
|
22
|
-
@known_headers[header_klass] ||= []
|
23
|
-
args.each do |key, value|
|
24
|
-
@known_headers[header_klass] << Binding.new(key, value)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
# @api private
|
29
|
-
# Get knwon headers
|
30
|
-
# @return [Hash] keys: header classes, values: array of {Binding}
|
31
|
-
def known_headers
|
32
|
-
@known_headers ||= {}
|
33
|
-
end
|
34
|
-
|
35
|
-
# Define a bitfield on given attribute
|
36
|
-
# class MyHeader < Struct.new(:flags)
|
37
|
-
#
|
38
|
-
# def initialize(options={})
|
39
|
-
# super Int16.new(options[:flags])
|
40
|
-
# end
|
41
|
-
#
|
42
|
-
# # define a bit field on :flag attribute:
|
43
|
-
# # flag1, flag2 and flag3 are 1-bit fields
|
44
|
-
# # type and stype are 3-bit fields. reserved is a 6-bit field
|
45
|
-
# define_bit_fields_on :flags, :flag1, :flag2, :flag3, :type, 3, :stype, 3, :reserved: 6
|
46
|
-
# end
|
47
|
-
# A bitfield of size 1 bit defines 2 methods:
|
48
|
-
# * +#field?+ which returns a Boolean,
|
49
|
-
# * +#field=+ which takes and returns a Boolean.
|
50
|
-
# A bitfield of more bits defines 2 methods:
|
51
|
-
# * +#field+ which returns an Integer,
|
52
|
-
# * +#field=+ which takes and returns an Integer.
|
53
|
-
# @param [Symbol] attr attribute name (attribute should a {StructFu::Int}
|
54
|
-
# subclass)
|
55
|
-
# @param [Array] args list of bitfield names. Name may be followed
|
56
|
-
# by bitfield size. If no size is given, 1 bit is assumed.
|
57
|
-
# @return [void]
|
58
|
-
def define_bit_fields_on(attr, *args)
|
59
|
-
total_size = self.new[attr].width * 8
|
60
|
-
idx = total_size - 1
|
61
|
-
|
62
|
-
field = args.shift
|
63
|
-
while field
|
64
|
-
next unless field.is_a? Symbol
|
65
|
-
size = if args.first.is_a? Integer
|
66
|
-
args.shift
|
67
|
-
else
|
68
|
-
1
|
69
|
-
end
|
70
|
-
unless field == :_
|
71
|
-
shift = idx - (size - 1)
|
72
|
-
field_mask = (2**size - 1) << shift
|
73
|
-
clear_mask = (2**total_size - 1) & (~field_mask & (2**total_size - 1))
|
74
|
-
|
75
|
-
if size == 1
|
76
|
-
class_eval <<-EOM
|
77
|
-
def #{field}?
|
78
|
-
val = (self[:#{attr}].to_i & #{field_mask}) >> #{shift}
|
79
|
-
val != 0
|
80
|
-
end
|
81
|
-
def #{field}=(v)
|
82
|
-
val = v ? 1 : 0
|
83
|
-
self[:#{attr}].value = self[:#{attr}].to_i & #{clear_mask}
|
84
|
-
self[:#{attr}].value |= val << #{shift}
|
85
|
-
end
|
86
|
-
EOM
|
87
|
-
else
|
88
|
-
class_eval <<-EOM
|
89
|
-
def #{field}
|
90
|
-
(self[:#{attr}].to_i & #{field_mask}) >> #{shift}
|
91
|
-
end
|
92
|
-
def #{field}=(v)
|
93
|
-
self[:#{attr}].value = self[:#{attr}].to_i & #{clear_mask}
|
94
|
-
self[:#{attr}].value |= (v & #{2**size - 1}) << #{shift}
|
95
|
-
end
|
96
|
-
EOM
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
idx -= size
|
101
|
-
field = args.shift
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
# This file is part of PacketGen
|
2
|
-
# See https://github.com/sdaubert/packetgen for more informations
|
3
|
-
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
|
-
# This program is published under MIT license.
|
5
|
-
|
6
|
-
module PacketGen
|
7
|
-
module Header
|
8
|
-
|
9
|
-
# Mixin for various headers
|
10
|
-
# @author Sylvain Daubert
|
11
|
-
module HeaderMethods
|
12
|
-
|
13
|
-
# @api private
|
14
|
-
# Set reference of packet which owns this header
|
15
|
-
# @param [Packet] packet
|
16
|
-
# @return [void]
|
17
|
-
def packet=(packet)
|
18
|
-
@packet = packet
|
19
|
-
end
|
20
|
-
|
21
|
-
# @api private
|
22
|
-
# Get rference on packet which owns this header
|
23
|
-
# @return [Packet]
|
24
|
-
def packet
|
25
|
-
@packet
|
26
|
-
end
|
27
|
-
|
28
|
-
# @api private
|
29
|
-
# Get +header+ id in packet headers array
|
30
|
-
# @param [Header] header
|
31
|
-
# @return [Integer]
|
32
|
-
# @raise FormatError +header+ not in a packet
|
33
|
-
def header_id(header)
|
34
|
-
raise FormatError, "header of type #{header.class} not in a packet" if packet.nil?
|
35
|
-
id = packet.headers.index(header)
|
36
|
-
if id.nil?
|
37
|
-
raise FormatError, "header of type #{header.class} not in packet #{packet}"
|
38
|
-
end
|
39
|
-
id
|
40
|
-
end
|
41
|
-
|
42
|
-
# @api private
|
43
|
-
# Get IP or IPv6 previous header from +header+
|
44
|
-
# @param [Header] header
|
45
|
-
# @return [Header]
|
46
|
-
# @raise FormatError no IP or IPv6 header previous +header+ in packet
|
47
|
-
# @raise FormatError +header+ not in a packet
|
48
|
-
def ip_header(header)
|
49
|
-
hid = header_id(header)
|
50
|
-
iph = packet.headers[0...hid].reverse.find { |h| h.is_a? IP or h.is_a? IPv6 }
|
51
|
-
raise FormatError, 'no IP or IPv6 header in packet' if iph.nil?
|
52
|
-
iph
|
53
|
-
end
|
54
|
-
|
55
|
-
# Return header protocol name
|
56
|
-
# @return [String]
|
57
|
-
def protocol_name
|
58
|
-
self.class.to_s.sub(/.*::/, '')
|
59
|
-
end
|
60
|
-
|
61
|
-
# Common inspect method for headers
|
62
|
-
# @return [String]
|
63
|
-
def inspect
|
64
|
-
str = Inspect.dashed_line(self.class, 2)
|
65
|
-
to_h.each do |attr, value|
|
66
|
-
next if attr == :body
|
67
|
-
str << Inspect.inspect_attribute(attr, value, 2)
|
68
|
-
end
|
69
|
-
str
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|