packetgen 4.0.0 → 4.1.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 +1 -1
- data/lib/packetgen/deprecation.rb +7 -1
- data/lib/packetgen/header/arp.rb +6 -7
- data/lib/packetgen/header/asn1_base.rb +2 -1
- data/lib/packetgen/header/base.rb +27 -24
- data/lib/packetgen/header/bootp.rb +14 -14
- data/lib/packetgen/header/dhcp/option.rb +8 -8
- data/lib/packetgen/header/dhcp/options.rb +2 -2
- data/lib/packetgen/header/dhcp.rb +6 -7
- data/lib/packetgen/header/dhcpv6/duid.rb +1 -1
- data/lib/packetgen/header/dhcpv6/option.rb +37 -15
- data/lib/packetgen/header/dhcpv6/options.rb +3 -3
- data/lib/packetgen/header/dhcpv6/relay.rb +1 -0
- data/lib/packetgen/header/dhcpv6.rb +13 -14
- data/lib/packetgen/header/dns/name.rb +9 -8
- data/lib/packetgen/header/dns/opt.rb +3 -0
- data/lib/packetgen/header/dns/option.rb +7 -7
- data/lib/packetgen/header/dns/qdsection.rb +2 -2
- data/lib/packetgen/header/dns/question.rb +1 -0
- data/lib/packetgen/header/dns/rrsection.rb +2 -2
- data/lib/packetgen/header/dns.rb +76 -60
- data/lib/packetgen/header/dot11/control.rb +5 -5
- data/lib/packetgen/header/dot11/data.rb +11 -10
- data/lib/packetgen/header/dot11/element.rb +1 -1
- data/lib/packetgen/header/dot11/management.rb +18 -15
- data/lib/packetgen/header/dot11/sub_mngt.rb +22 -21
- data/lib/packetgen/header/dot11.rb +38 -38
- data/lib/packetgen/header/dot1q.rb +5 -4
- data/lib/packetgen/header/dot1x.rb +8 -8
- data/lib/packetgen/header/eap/fast.rb +3 -3
- data/lib/packetgen/header/eap/md5.rb +11 -3
- data/lib/packetgen/header/eap/tls.rb +9 -8
- data/lib/packetgen/header/eap/ttls.rb +13 -10
- data/lib/packetgen/header/eap.rb +58 -33
- data/lib/packetgen/header/eth.rb +26 -12
- data/lib/packetgen/header/gre.rb +26 -2
- data/lib/packetgen/header/http/headers.rb +6 -5
- data/lib/packetgen/header/http/request.rb +24 -16
- data/lib/packetgen/header/http/response.rb +22 -15
- data/lib/packetgen/header/icmp.rb +10 -10
- data/lib/packetgen/header/icmpv6.rb +10 -9
- data/lib/packetgen/header/igmp.rb +21 -10
- data/lib/packetgen/header/igmpv3/group_record.rb +7 -2
- data/lib/packetgen/header/igmpv3/mq.rb +1 -1
- data/lib/packetgen/header/igmpv3/mr.rb +1 -1
- data/lib/packetgen/header/igmpv3.rb +11 -10
- data/lib/packetgen/header/ip/addr.rb +6 -2
- data/lib/packetgen/header/ip/option.rb +18 -5
- data/lib/packetgen/header/ip.rb +52 -35
- data/lib/packetgen/header/ipv6/addr.rb +14 -13
- data/lib/packetgen/header/ipv6/extension.rb +9 -7
- data/lib/packetgen/header/ipv6/hop_by_hop.rb +26 -7
- data/lib/packetgen/header/ipv6.rb +31 -22
- data/lib/packetgen/header/llc.rb +20 -13
- data/lib/packetgen/header/mdns.rb +9 -2
- data/lib/packetgen/header/mld.rb +11 -9
- data/lib/packetgen/header/mldv2/mcast_address_record.rb +6 -1
- data/lib/packetgen/header/mldv2/mlq.rb +8 -8
- data/lib/packetgen/header/mldv2/mlr.rb +4 -4
- data/lib/packetgen/header/mldv2.rb +1 -1
- data/lib/packetgen/header/ospfv2/db_description.rb +10 -10
- data/lib/packetgen/header/ospfv2/hello.rb +11 -10
- data/lib/packetgen/header/ospfv2/ls_ack.rb +5 -6
- data/lib/packetgen/header/ospfv2/ls_request.rb +7 -6
- data/lib/packetgen/header/ospfv2/ls_update.rb +7 -7
- data/lib/packetgen/header/ospfv2/lsa.rb +33 -10
- data/lib/packetgen/header/ospfv2/lsa_header.rb +3 -2
- data/lib/packetgen/header/ospfv2.rb +31 -26
- data/lib/packetgen/header/ospfv3/db_description.rb +12 -13
- data/lib/packetgen/header/ospfv3/hello.rb +10 -9
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +6 -2
- data/lib/packetgen/header/ospfv3/ls_ack.rb +5 -6
- data/lib/packetgen/header/ospfv3/ls_request.rb +10 -10
- data/lib/packetgen/header/ospfv3/ls_update.rb +7 -7
- data/lib/packetgen/header/ospfv3/lsa.rb +23 -9
- data/lib/packetgen/header/ospfv3/lsa_header.rb +3 -2
- data/lib/packetgen/header/ospfv3.rb +38 -34
- data/lib/packetgen/header/sctp/chunk.rb +38 -17
- data/lib/packetgen/header/sctp/error.rb +169 -197
- data/lib/packetgen/header/sctp/padded32.rb +3 -3
- data/lib/packetgen/header/sctp/parameter.rb +85 -132
- data/lib/packetgen/header/sctp.rb +14 -3
- data/lib/packetgen/header/snmp.rb +108 -7
- data/lib/packetgen/header/tcp/option.rb +7 -0
- data/lib/packetgen/header/tcp/options.rb +11 -3
- data/lib/packetgen/header/tcp.rb +33 -26
- data/lib/packetgen/header/tftp.rb +16 -10
- data/lib/packetgen/header/udp.rb +15 -13
- data/lib/packetgen/header.rb +19 -13
- data/lib/packetgen/headerable.rb +9 -3
- data/lib/packetgen/inspect.rb +2 -7
- data/lib/packetgen/packet.rb +94 -36
- data/lib/packetgen/pcapng/block.rb +2 -1
- data/lib/packetgen/pcapng/file.rb +41 -14
- data/lib/packetgen/pcapng/idb.rb +2 -1
- data/lib/packetgen/pcapng/shb.rb +2 -1
- data/lib/packetgen/pcapng/spb.rb +1 -1
- data/lib/packetgen/pcapng.rb +2 -0
- data/lib/packetgen/proto.rb +4 -0
- data/lib/packetgen/unknown_packet.rb +3 -3
- data/lib/packetgen/utils.rb +2 -1
- data/lib/packetgen/version.rb +1 -1
- data/lib/packetgen.rb +8 -2
- metadata +4 -4
data/lib/packetgen/header/ip.rb
CHANGED
@@ -27,32 +27,33 @@ module PacketGen
|
|
27
27
|
# | Options | Padding |
|
28
28
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
29
29
|
# A IP header consists of:
|
30
|
-
# * a first byte ({#u8} of
|
30
|
+
# * a first byte ({#u8} of +BinStruct::Int8+ type) composed of:
|
31
31
|
# * a 4-bit {#version} field,
|
32
32
|
# * a 4-bit IP header length ({#ihl}) field,
|
33
|
-
# * a Type of Service field ({#tos},
|
34
|
-
# * a total length ({#length},
|
35
|
-
# * a ID ({#id}, +Int16+ type),
|
36
|
-
# * a {#frag} worg (+Int16+) composed of:
|
33
|
+
# * a Type of Service field ({#tos}, +BinStruct::Int8+ type),
|
34
|
+
# * a total length ({#length}, +BinStruct::Int16+ type),
|
35
|
+
# * a ID ({#id}, +BinStruct::Int16+ type),
|
36
|
+
# * a {#frag} worg (+BinStruct::Int16+) composed of:
|
37
37
|
# * 3 1-bit flags ({#flag_rsv}, {#flag_df} and {#flag_mf}),
|
38
38
|
# * a 13-bit {#fragment_offset} field,
|
39
39
|
# * a Time-to-Live ({#ttl}) field (+Int8+),
|
40
|
-
# * a {#protocol} field (+Int8+),
|
41
|
-
# * a {#checksum} field (+Int16+),
|
40
|
+
# * a {#protocol} field (+BinStruct::Int8+),
|
41
|
+
# * a {#checksum} field (+BinStruct::Int16+),
|
42
42
|
# * a source IP address ({#src}, {Addr} type),
|
43
|
-
# * a destination IP address ({#dst},
|
43
|
+
# * a destination IP address ({#dst}, {Addr} type),
|
44
44
|
# * an optional {#options} field ({Options} type),
|
45
|
-
# * and a {#body} (
|
45
|
+
# * and a {#body} (+BinStruct::String+ type).
|
46
46
|
#
|
47
|
-
#
|
47
|
+
# @example Create a IP header
|
48
48
|
# # standalone
|
49
49
|
# ip = PacketGen::Header::IP.new
|
50
50
|
# # in a packet
|
51
51
|
# pkt = PacketGen.gen('IP')
|
52
52
|
# # access to IP header
|
53
|
-
# pkt.ip # => PacketGen::Header::IP
|
53
|
+
# pkt.ip.class # => PacketGen::Header::IP
|
54
54
|
#
|
55
|
-
#
|
55
|
+
# @example IP attributes
|
56
|
+
# ip = PacketGen::Header::IP.new
|
56
57
|
# ip.u8 = 0x45
|
57
58
|
# # the same as
|
58
59
|
# ip.version = 4
|
@@ -66,21 +67,20 @@ module PacketGen
|
|
66
67
|
# ip.flag_mf = true
|
67
68
|
# ip.fragment_offset = 0x31
|
68
69
|
#
|
69
|
-
# ip.flag_rsv? # =>
|
70
|
-
# ip.flag_df? # =>
|
71
|
-
# ip.flag_mf? # =>
|
70
|
+
# ip.flag_rsv? # => false
|
71
|
+
# ip.flag_df? # => false
|
72
|
+
# ip.flag_mf? # => true
|
72
73
|
#
|
73
74
|
# ip.ttl = 0x40
|
74
75
|
# ip.protocol = 6
|
75
76
|
# ip.checksum = 0xffff
|
76
77
|
# ip.src = '127.0.0.1'
|
77
78
|
# ip.src # => "127.0.0.1"
|
78
|
-
# ip[:src]
|
79
|
+
# ip[:src].class # => PacketGen::Header::IP::Addr
|
79
80
|
# ip.dst = '127.0.0.2'
|
80
|
-
# ip.body
|
81
|
+
# ip.body = 'this is a body'
|
81
82
|
#
|
82
|
-
#
|
83
|
-
# IP has an {#options} attribute used to store datagram options.
|
83
|
+
# @example Add IP options
|
84
84
|
# pkt = PacketGen.gen('IP')
|
85
85
|
# # add option from class
|
86
86
|
# pkt.ip.options << PacketGen::Header::IP::RA.new
|
@@ -101,52 +101,68 @@ module PacketGen
|
|
101
101
|
# First byte of IP header. May be accessed through {#version} and {#ihl}.
|
102
102
|
# @return [Integer] first byte of IP header.
|
103
103
|
# @!attribute version
|
104
|
-
#
|
104
|
+
# 4-bit version attribute
|
105
|
+
# @return [Integer]
|
105
106
|
# @!attribute ihl
|
106
|
-
#
|
107
|
+
# 4-bit IP header length attribute, as 32-bit word count.
|
108
|
+
# Default to 5 (IP header without option).
|
109
|
+
# @return [Integer]
|
107
110
|
define_bit_attr :u8, default: 0x45, version: 4, ihl: 4
|
108
111
|
# @!attribute tos
|
109
112
|
# @return [Integer] 8-bit Type of Service self[attr]
|
110
113
|
define_attr :tos, BinStruct::Int8, default: 0
|
111
114
|
# @!attribute length
|
112
|
-
#
|
115
|
+
# 16-bit IP total length, including this header.
|
116
|
+
# @return [Integer]
|
113
117
|
define_attr :length, BinStruct::Int16, default: 20
|
114
118
|
# @!attribute id
|
115
119
|
# @return [Integer] 16-bit ID
|
116
120
|
define_attr :id, BinStruct::Int16, default: ->(_) { rand(65_535) }
|
117
121
|
# @!attribute frag
|
118
|
-
#
|
122
|
+
# 16-bit frag word
|
123
|
+
# @return [Integer]
|
119
124
|
# @!attribute flag_rsv
|
120
|
-
#
|
125
|
+
# reserved bit from flags
|
126
|
+
# @return [Boolean]
|
121
127
|
# @!attribute flag_df
|
122
|
-
#
|
128
|
+
# Don't Fragment flag
|
129
|
+
# @return [Boolean]
|
123
130
|
# @!attribute flag_mf
|
124
|
-
#
|
131
|
+
# More Fragment flags
|
132
|
+
# @return [Boolean]
|
125
133
|
# @!attribute fragment_offset
|
126
|
-
#
|
134
|
+
# 13-bit fragment offset
|
135
|
+
# @return [Integer]
|
127
136
|
define_bit_attr :frag, flag_rsv: 1, flag_df: 1, flag_mf: 1, fragment_offset: 13
|
128
137
|
# @!attribute ttl
|
129
|
-
#
|
138
|
+
# 8-bit Time To Live
|
139
|
+
# @return [Integer]
|
130
140
|
define_attr :ttl, BinStruct::Int8, default: 64
|
131
141
|
# @!attribute protocol
|
132
|
-
#
|
142
|
+
# 8-bit upper protocol
|
143
|
+
# @return [Integer]
|
133
144
|
define_attr :protocol, BinStruct::Int8
|
134
145
|
# @!attribute checksum
|
135
|
-
#
|
146
|
+
# 16-bit IP header checksum
|
147
|
+
# @return [Integer]
|
136
148
|
define_attr :checksum, BinStruct::Int16, default: 0
|
137
149
|
# @!attribute src
|
138
|
-
#
|
150
|
+
# source IP address
|
151
|
+
# @return [Addr]
|
139
152
|
define_attr :src, Addr, default: '127.0.0.1'
|
140
153
|
# @!attribute dst
|
141
|
-
#
|
154
|
+
# destination IP address
|
155
|
+
# @return [Addr]
|
142
156
|
define_attr :dst, Addr, default: '127.0.0.1'
|
143
157
|
# @!attribute options
|
158
|
+
# IP options
|
144
159
|
# @since 2.2.0
|
145
|
-
# @return [
|
160
|
+
# @return [Options]
|
146
161
|
define_attr :options, Options, optional: ->(h) { h.ihl > 5 },
|
147
162
|
builder: ->(h, t) { t.new(length_from: -> { (h.ihl - 5) * 4 }) }
|
148
163
|
# @!attribute body
|
149
|
-
#
|
164
|
+
# IP body
|
165
|
+
# @return [BinStruct::String,Headerable]
|
150
166
|
define_attr :body, BinStruct::String
|
151
167
|
|
152
168
|
# Helper method to compute sum of 16-bit words. Used to compute IP-style
|
@@ -224,7 +240,8 @@ module PacketGen
|
|
224
240
|
end
|
225
241
|
|
226
242
|
# Check version field
|
227
|
-
# @see
|
243
|
+
# @see Base#parse?
|
244
|
+
# @return [Boolean]
|
228
245
|
def parse?
|
229
246
|
(version == 4) && (ihl >= 5)
|
230
247
|
end
|
@@ -14,6 +14,7 @@ module PacketGen
|
|
14
14
|
class IPv6
|
15
15
|
# IPv6 address, as a group of 8 2-byte words
|
16
16
|
# @author Sylvain Daubert
|
17
|
+
# @author LemonTree55
|
17
18
|
class Addr < BinStruct::Struct
|
18
19
|
include BinStruct::Structable
|
19
20
|
|
@@ -50,11 +51,10 @@ module PacketGen
|
|
50
51
|
# @return [Integer]
|
51
52
|
define_attr :a8, BinStruct::Int16
|
52
53
|
|
53
|
-
# rubocop:disable Metrics/AbcSize
|
54
|
-
|
55
54
|
# Read a colon-delimited address
|
56
55
|
# @param [String] str
|
57
56
|
# @return [self]
|
57
|
+
# @raise [ArgumentError] not a colon-delimited IPv6 address
|
58
58
|
def from_human(str)
|
59
59
|
return self if str.nil?
|
60
60
|
|
@@ -62,19 +62,13 @@ module PacketGen
|
|
62
62
|
raise ArgumentError, 'string is not a IPv6 address' unless addr.ipv6?
|
63
63
|
|
64
64
|
addri = addr.to_i
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
self.a4 = addri >> 64 & 0xffff
|
69
|
-
self.a5 = addri >> 48 & 0xffff
|
70
|
-
self.a6 = addri >> 32 & 0xffff
|
71
|
-
self.a7 = addri >> 16 & 0xffff
|
72
|
-
self.a8 = addri & 0xffff
|
65
|
+
8.times do |i|
|
66
|
+
self.send(:"a#{i + 1}=", addri >> (16 * (7 - i)) & 0xffff)
|
67
|
+
end
|
73
68
|
self
|
74
69
|
end
|
75
|
-
# rubocop:enable Metrics/AbcSize
|
76
70
|
|
77
|
-
#
|
71
|
+
# Return IPv6 address in human readable form (colon-delimited hex string)
|
78
72
|
# @return [String]
|
79
73
|
def to_human
|
80
74
|
IPAddr.new(to_a.map { |a| a.to_i.to_s(16) }.join(':')).to_s
|
@@ -92,6 +86,9 @@ module PacketGen
|
|
92
86
|
self.a1 & 0xff00 == 0xff00
|
93
87
|
end
|
94
88
|
|
89
|
+
# Check equaliy to +other+.
|
90
|
+
# Equal if other has the same class, and all attributes are equal
|
91
|
+
# @return [Boolean]
|
95
92
|
def ==(other)
|
96
93
|
other.is_a?(self.class) &&
|
97
94
|
attributes.all? { |attr| self[attr].value == other[attr].value }
|
@@ -106,7 +103,11 @@ module PacketGen
|
|
106
103
|
# Push a IPv6 address to the array
|
107
104
|
# @param [String,Addr] addr
|
108
105
|
# @return [self]
|
109
|
-
#
|
106
|
+
# @example
|
107
|
+
# array = PacketGen::Header::IPv6::ArrayOfAddr.new
|
108
|
+
# # #<< uses #push internally
|
109
|
+
# array << '2001::1'
|
110
|
+
# array.push(PacketGen::Header::IPv6::Addr.new.from_human('1:2:3:abcd::1'))
|
110
111
|
def push(addr)
|
111
112
|
addr = Addr.new.from_human(addr) unless addr.is_a?(Addr)
|
112
113
|
super
|
@@ -9,7 +9,7 @@
|
|
9
9
|
module PacketGen
|
10
10
|
module Header
|
11
11
|
class IPv6
|
12
|
-
# Base class to handle IPv6 extensions
|
12
|
+
# Base class to handle IPv6 extensions.
|
13
13
|
# @abstract You should not use this class but its subclasses.
|
14
14
|
# A IPv6 extension header has the following format:
|
15
15
|
# 0 1 2 3
|
@@ -25,11 +25,12 @@ module PacketGen
|
|
25
25
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
26
26
|
#
|
27
27
|
# Such a header consists of:
|
28
|
-
# * a {#next} header field (
|
29
|
-
# * a {#length} field (
|
30
|
-
# * an {#options} field (
|
28
|
+
# * a {#next} header field (+BinStruct::Int8+),
|
29
|
+
# * a {#length} field (+BinStruct::Int8+),
|
30
|
+
# * an {#options} field (+BinStruct::String+),
|
31
31
|
# * and a {#body}, containing next header.
|
32
32
|
# @author Sylvain Daubert
|
33
|
+
# @since 2.4.0
|
33
34
|
class Extension < Base
|
34
35
|
# @!attribute next
|
35
36
|
# 8-bit Next header field
|
@@ -44,9 +45,10 @@ module PacketGen
|
|
44
45
|
# Specific options of extension header
|
45
46
|
# @return [String]
|
46
47
|
define_attr :options, BinStruct::String,
|
47
|
-
builder: ->(h, t) { t.new(length_from: -> { h.real_length }) }
|
48
|
+
builder: ->(h, t) { t.new(length_from: -> { h.real_length - 2}) }
|
48
49
|
# @!attribute body
|
49
|
-
#
|
50
|
+
# Next header in IPv6 packet
|
51
|
+
# @return [String,Headerable]
|
50
52
|
define_attr :body, BinStruct::String
|
51
53
|
|
52
54
|
# Get real extension header length
|
@@ -55,7 +57,7 @@ module PacketGen
|
|
55
57
|
(length + 1) * 8
|
56
58
|
end
|
57
59
|
|
58
|
-
# Compute length and set +
|
60
|
+
# Compute length and set {#length}+ attribute
|
59
61
|
# @return [Integer]
|
60
62
|
def calc_length
|
61
63
|
self.length = (options.sz + 2) / 8 - 1
|
@@ -11,7 +11,8 @@ module PacketGen
|
|
11
11
|
class IPv6
|
12
12
|
# @!parse
|
13
13
|
# # Option for {HopByHop} IPv6 extension header.
|
14
|
-
# # @since
|
14
|
+
# # @since 2.4.0
|
15
|
+
# # @since 3.1.0 subclass of +BinStruct::AbstractTLV+
|
15
16
|
# class Option <AbstractTLV; end
|
16
17
|
# @private
|
17
18
|
Option = BinStruct::AbstractTLV.create
|
@@ -23,6 +24,7 @@ module PacketGen
|
|
23
24
|
5 => 'router_alert'
|
24
25
|
}.freeze
|
25
26
|
|
27
|
+
# Get human-readable string
|
26
28
|
# @return [String]
|
27
29
|
def to_human
|
28
30
|
case type
|
@@ -35,13 +37,16 @@ module PacketGen
|
|
35
37
|
end
|
36
38
|
Option.define_type_enum Option::TYPES.invert
|
37
39
|
|
38
|
-
# Special option pad1, for {HopByHop} IPv6 extension header
|
40
|
+
# Special option pad1 (one-byte option), for {HopByHop} IPv6 extension header
|
39
41
|
# @author Sylvain Daubert
|
42
|
+
# @since 2.4.0
|
40
43
|
class Pad1 < BinStruct::Struct
|
41
44
|
# @!attribute pad
|
42
|
-
#
|
45
|
+
# Pad1 option type
|
46
|
+
# @return [Integer]
|
43
47
|
define_attr :pad, BinStruct::Int8, default: 0
|
44
48
|
|
49
|
+
# Get human-readable string
|
45
50
|
# @return [String]
|
46
51
|
def to_human
|
47
52
|
'pad1'
|
@@ -50,6 +55,7 @@ module PacketGen
|
|
50
55
|
|
51
56
|
# Array of {Option}, for {HopByHop} IPv6 extension header
|
52
57
|
# @author Sylvain Daubert
|
58
|
+
# @since 2.4.0
|
53
59
|
class Options < BinStruct::Array
|
54
60
|
set_of Option
|
55
61
|
|
@@ -96,18 +102,31 @@ module PacketGen
|
|
96
102
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
97
103
|
#
|
98
104
|
# Hop-by-hop IPv6 extension header consists of:
|
99
|
-
# * a {#next} header field (
|
100
|
-
# * a {#length} field (
|
105
|
+
# * a {#next #next} header field (+BinStruct::Int8+),
|
106
|
+
# * a {#length #length} field (+BinStruct::Int8+),
|
101
107
|
# * an {#options} field ({Options}),
|
102
|
-
# * and a {#body}, containing next header.
|
108
|
+
# * and a {#body #body}, containing next header.
|
109
|
+
# @example
|
110
|
+
# pkt = PacketGen.gen('Eth').add('IPv6').add('IPv6::HopByHop').add('ICMPv6')
|
111
|
+
# pkt.ipv6_hopbyhop.options << { type: 'router_alert', value: "\x00\x00".b }
|
103
112
|
# @author Sylvain Daubert
|
113
|
+
# @since 2.4.0
|
104
114
|
class HopByHop < Extension
|
105
115
|
# redefine options field
|
106
116
|
remove_attr :options
|
107
117
|
# @!attribute options
|
108
|
-
# Specific options
|
118
|
+
# Specific HopByHop options
|
109
119
|
# @return [Options]
|
110
120
|
define_attr_before :body, :options, Options, builder: ->(h, t) { t.new(length_from: -> { h.real_length - 2 }) }
|
121
|
+
|
122
|
+
# Generate binary string. Add padding if needed in {#options}, and update {#length} accordingly.
|
123
|
+
# @return [String]
|
124
|
+
# @since 2.4.0
|
125
|
+
# @since 4.1.0 Set {Extension#length}.
|
126
|
+
def to_s
|
127
|
+
calc_length
|
128
|
+
super
|
129
|
+
end
|
111
130
|
end
|
112
131
|
end
|
113
132
|
|
@@ -37,26 +37,27 @@ module PacketGen
|
|
37
37
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
38
38
|
#
|
39
39
|
# A IPv6 header consists of:
|
40
|
-
# * a first 32-bit word ({#u32}, of
|
40
|
+
# * a first 32-bit word ({#u32}, of +BinStruct::Int32+ type) composed of:
|
41
41
|
# * a 4-bit {#version} field,
|
42
42
|
# * a 8-bit {#traffic_class} field,
|
43
43
|
# * a 20-bit {#flow_label} field,
|
44
|
-
# * a payload length field ({#length},
|
45
|
-
# * a next header field ({#next},
|
46
|
-
# * a hop-limit field ({#hop}, +Int8+ type),
|
44
|
+
# * a payload length field ({#length}, +BinStruct::Int16+ type}),
|
45
|
+
# * a next header field ({#next}, +BinStruct::Int8+ type),
|
46
|
+
# * a hop-limit field ({#hop}, +BinStruct::Int8+ type),
|
47
47
|
# * a source address field ({#src}, {IPv6::Addr} type),
|
48
|
-
# * a destination address field ({#dst},
|
49
|
-
# * and a {#body} (
|
48
|
+
# * a destination address field ({#dst}, {IPv6::Addr} type),
|
49
|
+
# * and a {#body} (+BinStruct::String+ type).
|
50
50
|
#
|
51
|
-
#
|
51
|
+
# @example Create a IPv6 header
|
52
52
|
# # standalone
|
53
53
|
# ipv6 = PacketGen::Header::IPv6.new
|
54
54
|
# # in a packet
|
55
55
|
# pkt = PacketGen.gen('IPv6')
|
56
56
|
# # access to IPv6 header
|
57
|
-
# pkt.ipv6 # => PacketGen::Header::IPv6
|
57
|
+
# pkt.ipv6.class # => PacketGen::Header::IPv6
|
58
58
|
#
|
59
|
-
#
|
59
|
+
# @example IPv6 attributes
|
60
|
+
# ipv6 = PacketGen::Header::IPv6.new
|
60
61
|
# ipv6.u32 = 0x60280001
|
61
62
|
# # the same as
|
62
63
|
# ipv6.version = 6
|
@@ -68,9 +69,9 @@ module PacketGen
|
|
68
69
|
# ipv6.next = 6
|
69
70
|
# ipv6.src = '::1'
|
70
71
|
# ipv6.src # => "::1"
|
71
|
-
# ipv6[:src]
|
72
|
+
# ipv6[:src].class # => PacketGen::Header::IPv6::Addr
|
72
73
|
# ipv6.dst = '2001:1234:5678:abcd::123'
|
73
|
-
# ipv6.body
|
74
|
+
# ipv6.body ='this is a body'
|
74
75
|
#
|
75
76
|
# == Add IPv6 extensions
|
76
77
|
# In IPv6, optional extensions are encoded in separate headers that
|
@@ -84,6 +85,7 @@ module PacketGen
|
|
84
85
|
# # Add another header
|
85
86
|
# pkt.add('UDP')
|
86
87
|
# @author Sylvain Daubert
|
88
|
+
# @author LemonTree55
|
87
89
|
class IPv6 < Base; end
|
88
90
|
|
89
91
|
require_relative 'ipv6/addr'
|
@@ -96,11 +98,14 @@ module PacketGen
|
|
96
98
|
# First 32-bit word of IPv6 header
|
97
99
|
# @return [Integer]
|
98
100
|
# @!attribute version
|
99
|
-
#
|
101
|
+
# 4-bit version attribute
|
102
|
+
# @return [Integer]
|
100
103
|
# @!attribute traffic_class
|
101
|
-
#
|
104
|
+
# 8-bit traffic_class attribute
|
105
|
+
# @return [Integer]
|
102
106
|
# @!attribute flow_label
|
103
|
-
#
|
107
|
+
# 20-bit flow_label attribute
|
108
|
+
# @return [Integer]
|
104
109
|
define_bit_attr :u32, default: 0x60000000, version: 4, traffic_class: 8, flow_label: 20
|
105
110
|
# @!attribute length
|
106
111
|
# 16-bit word of IPv6 payload length
|
@@ -123,10 +128,11 @@ module PacketGen
|
|
123
128
|
# @return [Addr]
|
124
129
|
define_attr :dst, Addr, default: '::1'
|
125
130
|
# @!attribute body
|
126
|
-
#
|
131
|
+
# IPv6 body
|
132
|
+
# @return [BinStruct::String,Headerable]
|
127
133
|
define_attr :body, BinStruct::String
|
128
134
|
|
129
|
-
# Compute length and set
|
135
|
+
# Compute length and set {#length} field
|
130
136
|
# @return [Integer]
|
131
137
|
def calc_length
|
132
138
|
Base.calculate_and_set_length self, header_in_size: false
|
@@ -141,7 +147,7 @@ module PacketGen
|
|
141
147
|
sum
|
142
148
|
end
|
143
149
|
|
144
|
-
# Send IPv6 packet on wire. All attributes
|
150
|
+
# Send IPv6 packet on wire. All attributes may be set (even {#version}).
|
145
151
|
# @param [String] _iface interface name (not used)
|
146
152
|
# @return [void]
|
147
153
|
# @since 3.0.0 no more limitations on +flow_label+, +length+ and +src+ fields.
|
@@ -168,7 +174,7 @@ module PacketGen
|
|
168
174
|
end
|
169
175
|
|
170
176
|
# Check version field
|
171
|
-
# @see
|
177
|
+
# @see Base#parse?
|
172
178
|
def parse?
|
173
179
|
version == 6
|
174
180
|
end
|
@@ -197,15 +203,18 @@ module PacketGen
|
|
197
203
|
module Header
|
198
204
|
class IPv6
|
199
205
|
class << self
|
206
|
+
# @private
|
200
207
|
alias old_bind bind
|
201
208
|
|
202
209
|
# Bind a upper header to IPv6 and its defined extension headers.
|
203
210
|
# @see Base.bind
|
211
|
+
# @author LemonTree55
|
204
212
|
def bind(header_klass, args={})
|
205
|
-
IPv6.old_bind
|
206
|
-
|
207
|
-
|
208
|
-
|
213
|
+
IPv6.old_bind(header_klass, args)
|
214
|
+
IPv6.constants
|
215
|
+
.map { |cname| IPv6.const_get(cname) }
|
216
|
+
.select { |klass| klass.is_a?(Class) && (klass < Extension) }
|
217
|
+
.each { |klass| klass.bind(header_klass, args) }
|
209
218
|
end
|
210
219
|
end
|
211
220
|
end
|
data/lib/packetgen/header/llc.rb
CHANGED
@@ -12,24 +12,28 @@ module PacketGen
|
|
12
12
|
# Logical-Link Control header
|
13
13
|
#
|
14
14
|
# A LLC header consists of:
|
15
|
-
# * a {#dsap} (
|
16
|
-
# * a {#ssap} (
|
17
|
-
# * a {#control} (
|
18
|
-
# * and a {#body} (a
|
15
|
+
# * a {#dsap} (+BinStruct::Int8+),
|
16
|
+
# * a {#ssap} (+BinStruct::Int8+),
|
17
|
+
# * a {#control} (+BinStruct::Int8+),
|
18
|
+
# * and a {#body} (a +BinStruct::String+ or another {Headerable} class).
|
19
19
|
# @author Sylvain Daubert
|
20
20
|
# @since 1.4.0
|
21
21
|
class LLC < Base
|
22
22
|
# @!attribute dsap
|
23
|
-
#
|
23
|
+
# 8-bit Destination Service Access Point value
|
24
|
+
# @return [Integer]
|
24
25
|
define_attr :dsap, BinStruct::Int8
|
25
26
|
# @!attribute ssap
|
26
|
-
#
|
27
|
+
# 8-bit Source Service Access Point value
|
28
|
+
# @return [Integer]
|
27
29
|
define_attr :ssap, BinStruct::Int8
|
28
30
|
# @!attribute control
|
29
|
-
#
|
31
|
+
# 8-bit control value
|
32
|
+
# @return [Integer]
|
30
33
|
define_attr :control, BinStruct::Int8
|
31
34
|
# @!attribute body
|
32
|
-
#
|
35
|
+
# LLC body
|
36
|
+
# @return [BinStruct::String,Headerable]
|
33
37
|
define_attr :body, BinStruct::String
|
34
38
|
end
|
35
39
|
self.add_class LLC
|
@@ -38,20 +42,23 @@ module PacketGen
|
|
38
42
|
# Sub-Network Access Protocol
|
39
43
|
#
|
40
44
|
# A SNAP header consists of:
|
41
|
-
# * a {#oui} (
|
42
|
-
# * a {#proto_id} (
|
43
|
-
# * and a {#body} (a
|
45
|
+
# * a {#oui} (+BinStruct::OUI+),
|
46
|
+
# * a {#proto_id} (+BinStruct::Int16+),
|
47
|
+
# * and a {#body} (a +BinStruct::String+ or another {Headerable} class).
|
44
48
|
# @author Sylvain Daubert
|
45
49
|
# @since 1.4.0
|
46
50
|
class SNAP < Base
|
47
51
|
# @!attribute oui
|
52
|
+
# If +00:00:00+, {#proto_id} is an EtherType. Else, {#proto_id} is specified by organization specified BY +OUI+.
|
48
53
|
# @return [BinStruct::OUI]
|
49
54
|
define_attr :oui, BinStruct::OUI
|
50
55
|
# @!attribute proto_id
|
51
|
-
#
|
56
|
+
# 16-bit protocol id
|
57
|
+
# @return [Integer]
|
52
58
|
define_attr :proto_id, BinStruct::Int16
|
53
59
|
# @!attribute body
|
54
|
-
#
|
60
|
+
# SNAP header
|
61
|
+
# @return [BinStruct::String,Headerable]
|
55
62
|
define_attr :body, BinStruct::String
|
56
63
|
end
|
57
64
|
self.add_class SNAP
|
@@ -21,12 +21,18 @@ module PacketGen
|
|
21
21
|
# Fixup IP header according to RFC 6762:
|
22
22
|
# * set ethernet multicast address to +01:00:5E:00:00:FB+ (for IPv4)
|
23
23
|
# or +33:33:00:00:00:FB+ (for IPv6),
|
24
|
-
# * set IPv4 address to 224.0.0.251 or IPv6 address to ff02::fb
|
24
|
+
# * set IPv4 address to +224.0.0.251+ or IPv6 address to +ff02::fb+.
|
25
25
|
# This method may be called as:
|
26
26
|
# # first way
|
27
27
|
# pkt.mdns.mdnsize
|
28
28
|
# # second way
|
29
|
-
# pkt.
|
29
|
+
# pkt.
|
30
|
+
# @example
|
31
|
+
# pkt = PacketGen.gen('Eth').add('IP').add('UDP').add('MDNS')
|
32
|
+
# pkt.mdnsize
|
33
|
+
# pkt.eth.dst #=> "01:00:5e:00:00:fb"
|
34
|
+
# pkt.ip.dst #=> "224.0.0.251"
|
35
|
+
# @return [void]
|
30
36
|
def mdnsize
|
31
37
|
iph = ip_header(self)
|
32
38
|
case iph
|
@@ -42,6 +48,7 @@ module PacketGen
|
|
42
48
|
# @api private
|
43
49
|
# @note This method is used internally by PacketGen and should not be
|
44
50
|
# directly called
|
51
|
+
# Add +#mdnsize+ method to +packet+. This method calls {#mdnsize}.
|
45
52
|
# @since 2.7.0 Set UDP sport according to bindings, only if sport is 0.
|
46
53
|
# Needed by new bind API.
|
47
54
|
def added_to_packet(packet)
|
data/lib/packetgen/header/mld.rb
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
|
9
9
|
module PacketGen
|
10
10
|
module Header
|
11
|
-
# This class supports
|
11
|
+
# This class supports Multicast Listener Discovery for IPv6 (RFC 2710).
|
12
12
|
#
|
13
13
|
# From RFC 2710, a MLD header has the following format:
|
14
14
|
# 0 1 2 3
|
@@ -26,23 +26,24 @@ module PacketGen
|
|
26
26
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
27
27
|
#
|
28
28
|
# A MLD header consists of:
|
29
|
-
# * a {#max_resp_delay} field (
|
30
|
-
# * a {#reserved} field (
|
29
|
+
# * a {#max_resp_delay} field (+BinStruct::Int16+ type),
|
30
|
+
# * a {#reserved} field (+BinStruct::Int16+ type),
|
31
31
|
# * a {#mcast_addr} field ({Header::IPv6::Addr} type),
|
32
32
|
# * and a {#body} (unused for MLDv1).
|
33
33
|
#
|
34
|
-
#
|
34
|
+
# @example Create a MLD header
|
35
35
|
# # standalone
|
36
36
|
# mld = PacketGen::Header::MLD.new
|
37
37
|
# # in a packet
|
38
38
|
# pkt = PacketGen.gen('IPv6').add('ICMPv6').add('MLD')
|
39
39
|
# # access to MLD header
|
40
|
-
# pkt.mld # => PacketGen::Header::MLD
|
40
|
+
# pkt.mld.class # => PacketGen::Header::MLD
|
41
41
|
#
|
42
|
-
#
|
43
|
-
# pkt
|
42
|
+
# @example MLD attributes
|
43
|
+
# pkt = PacketGen.gen('IPv6').add('ICMPv6').add('MLD')
|
44
|
+
# pkt.icmpv6.type = 130 # ICMPv6 type 130 is MLD Multicast Listener Query
|
44
45
|
# pkt.mld.max_resp_delay = 20
|
45
|
-
# pkt.mld.
|
46
|
+
# pkt.mld.mcast_addr = '::'
|
46
47
|
# @author Sylvain Daubert
|
47
48
|
# @since 2.4.0
|
48
49
|
class MLD < Base
|
@@ -61,12 +62,13 @@ module PacketGen
|
|
61
62
|
# @return [IPv6::Addr]
|
62
63
|
define_attr :mcast_addr, IPv6::Addr, default: '::'
|
63
64
|
# @!attribute body
|
64
|
-
# @return [String,
|
65
|
+
# @return [String,Headerable]
|
65
66
|
define_attr :body, BinStruct::String
|
66
67
|
|
67
68
|
# @api private
|
68
69
|
# @note This method is used internally by PacketGen and should not be
|
69
70
|
# directly called
|
71
|
+
# This method adds +#mldize+ method to +packet+. This method calls {#mldize}.
|
70
72
|
def added_to_packet(packet)
|
71
73
|
mld_idx = packet.headers.size
|
72
74
|
packet.instance_eval "def mldize() @headers[#{mld_idx}].mldize; end" # def mldize() @headers[3].mldize; end
|
@@ -81,14 +81,19 @@ module PacketGen
|
|
81
81
|
define_attr :source_addr, IPv6::ArrayOfAddr,
|
82
82
|
builder: ->(h, t) { t.new(counter: h[:number_of_sources]) }
|
83
83
|
# @!attribute aux_data
|
84
|
+
# Auxiliary data
|
84
85
|
# @return [String]
|
85
86
|
define_attr :aux_data, BinStruct::String,
|
86
87
|
builder: ->(h, t) { t.new(length_from: -> { h[:aux_data_len].to_i * 4 }) }
|
87
88
|
|
89
|
+
# Get human-readable type
|
90
|
+
# @return [String]
|
88
91
|
def human_type
|
89
92
|
self[:type].to_human
|
90
93
|
end
|
91
94
|
|
95
|
+
# Get human-readable description
|
96
|
+
# @return [String]
|
92
97
|
def to_human
|
93
98
|
"#{human_type}(ma:#{multicast_addr}|src:#{source_addr.to_human})"
|
94
99
|
end
|
@@ -99,7 +104,7 @@ module PacketGen
|
|
99
104
|
class McastAddressRecords < BinStruct::Array
|
100
105
|
set_of McastAddressRecord
|
101
106
|
|
102
|
-
# Separator used in
|
107
|
+
# Separator used in +#to_human+.
|
103
108
|
HUMAN_SEPARATOR = ';'
|
104
109
|
end
|
105
110
|
end
|