packetgen 2.3.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/README.md +5 -1
- data/lib/packetgen/header.rb +4 -0
- data/lib/packetgen/header/icmpv6.rb +0 -1
- data/lib/packetgen/header/igmp.rb +126 -0
- data/lib/packetgen/header/igmpv3.rb +150 -0
- data/lib/packetgen/header/igmpv3/group_record.rb +98 -0
- data/lib/packetgen/header/igmpv3/mq.rb +96 -0
- data/lib/packetgen/header/igmpv3/mr.rb +65 -0
- data/lib/packetgen/header/ip.rb +40 -70
- data/lib/packetgen/header/ip/addr.rb +58 -0
- data/lib/packetgen/header/ip/option.rb +194 -0
- data/lib/packetgen/header/ip/options.rb +53 -0
- data/lib/packetgen/header/ipv6.rb +24 -69
- data/lib/packetgen/header/ipv6/addr.rb +96 -0
- data/lib/packetgen/header/ipv6/extension.rb +65 -0
- data/lib/packetgen/header/ipv6/hop_by_hop.rb +132 -0
- data/lib/packetgen/header/mld.rb +100 -0
- data/lib/packetgen/header/mldv2.rb +50 -0
- data/lib/packetgen/header/mldv2/mcast_address_record.rb +103 -0
- data/lib/packetgen/header/mldv2/mlq.rb +144 -0
- data/lib/packetgen/header/mldv2/mlr.rb +65 -0
- data/lib/packetgen/packet.rb +18 -0
- data/lib/packetgen/types/array.rb +1 -0
- data/lib/packetgen/types/string.rb +14 -13
- data/lib/packetgen/version.rb +1 -1
- metadata +18 -2
@@ -0,0 +1,100 @@
|
|
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
|
+
# This class supports MLDv1 (RFC 2710).
|
10
|
+
#
|
11
|
+
# From RFC 2710, a MLD header has the following format:
|
12
|
+
# 0 1 2 3
|
13
|
+
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
14
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
15
|
+
# | Maximum Response delay | Reserved |
|
16
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
17
|
+
# | |
|
18
|
+
# + +
|
19
|
+
# | |
|
20
|
+
# + Multicast Address +
|
21
|
+
# | |
|
22
|
+
# + +
|
23
|
+
# | |
|
24
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
25
|
+
#
|
26
|
+
# A MLD header consists of:
|
27
|
+
# * a {#max_resp_delay} field ({Types::Int16} type),
|
28
|
+
# * a {#reserved} field ({Types::Int16} type),
|
29
|
+
# * a {#mcast_addr} field ({Header::IPv6::Addr} type),
|
30
|
+
# * and a {#body} (unused for MLDv1).
|
31
|
+
#
|
32
|
+
# == Create a MLD header
|
33
|
+
# # standalone
|
34
|
+
# mld = PacketGen::Header::MLD.new
|
35
|
+
# # in a packet
|
36
|
+
# pkt = PacketGen.gen('IPv6').add('ICMPv6').add('MLD')
|
37
|
+
# # access to MLD header
|
38
|
+
# pkt.mld # => PacketGen::Header::MLD
|
39
|
+
#
|
40
|
+
# == MLD attributes
|
41
|
+
# pkt.icmpv6.type = 130 # ICMPv6 type 130 is MLD Multicast Listener Query
|
42
|
+
# pkt.mld.max_resp_delay = 20
|
43
|
+
# pkt.mld.group_addr = '::'
|
44
|
+
# @author Sylvain Daubert
|
45
|
+
class MLD < Base
|
46
|
+
# @!attribute max_resp_delay
|
47
|
+
# 16-bit MLD Max Response Delay
|
48
|
+
# @return [Integer]
|
49
|
+
define_field :max_resp_delay, Types::Int16
|
50
|
+
alias max_resp_code max_resp_delay
|
51
|
+
alias max_resp_code= max_resp_delay=
|
52
|
+
# @!attribute reserved
|
53
|
+
# 16-bit Reserved field
|
54
|
+
# @return [Integer]
|
55
|
+
define_field :reserved, Types::Int16
|
56
|
+
# @!attribute mcast_addr
|
57
|
+
# IPv6 Multicast address
|
58
|
+
# @return [IPv6::Addr]
|
59
|
+
define_field :mcast_addr, IPv6::Addr, default: '::'
|
60
|
+
# @!attribute body
|
61
|
+
# @return [String,Base]
|
62
|
+
define_field :body, Types::String
|
63
|
+
|
64
|
+
# @api private
|
65
|
+
# @note This method is used internally by PacketGen and should not be
|
66
|
+
# directly called
|
67
|
+
def added_to_packet(packet)
|
68
|
+
mld_idx = packet.headers.size
|
69
|
+
packet.instance_eval "def mldize() @headers[#{mld_idx}].mldize; end"
|
70
|
+
end
|
71
|
+
|
72
|
+
# Fixup IP header according to RFC 2710:
|
73
|
+
# * set Hop limit to 1,
|
74
|
+
# * add Router Alert option,
|
75
|
+
# * recalculate checksum and length.
|
76
|
+
# This method may be called as:
|
77
|
+
# # first method
|
78
|
+
# pkt.mld.mldize
|
79
|
+
# # second method
|
80
|
+
# pkt.mldize
|
81
|
+
# @return [void]
|
82
|
+
def mldize
|
83
|
+
ipv6 = ip_header(self)
|
84
|
+
ipv6.hop = 1
|
85
|
+
ipv6.next = 0
|
86
|
+
packet.insert(ipv6, 'IPv6::HopByHop', next: ICMPv6::IP_PROTOCOL)
|
87
|
+
packet.ipv6_hopbyhop.options << { type: 'router_alert', value: [0].pack('n') }
|
88
|
+
packet.calc
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Add MLDv2::MLQ before MLD to priorize its decoding
|
95
|
+
require_relative 'mldv2'
|
96
|
+
|
97
|
+
PacketGen::Header.add_class PacketGen::Header::MLD
|
98
|
+
PacketGen::Header::ICMPv6.bind_header PacketGen::Header::MLD, type: 130
|
99
|
+
PacketGen::Header::ICMPv6.bind_header PacketGen::Header::MLD, type: 131
|
100
|
+
PacketGen::Header::ICMPv6.bind_header PacketGen::Header::MLD, type: 132
|
@@ -0,0 +1,50 @@
|
|
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
|
+
# This module contains all MLDv2 specific classes.
|
9
|
+
# @author Sylvain Daubert
|
10
|
+
module MLDv2
|
11
|
+
# Encode value for MLDv2 Max Resp Code.
|
12
|
+
# Value may be encoded as a float, so some error may occur.
|
13
|
+
# See RFC 3810 §5.1.3
|
14
|
+
# @param [Integer] value3
|
15
|
+
# @return [Integer]
|
16
|
+
def self.encode(value)
|
17
|
+
if value < 32768
|
18
|
+
value
|
19
|
+
elsif value > 8_387_583
|
20
|
+
0xffff
|
21
|
+
else
|
22
|
+
exp = 0
|
23
|
+
value >>= 3
|
24
|
+
while value > 8191 do
|
25
|
+
exp += 1
|
26
|
+
value >>= 1
|
27
|
+
end
|
28
|
+
0x8000 | ((exp & 7) << 12) | (value & 0xfff)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Decode value for MLDv2 Max Resp Code.
|
33
|
+
# See RFC 3810 §5.1.3
|
34
|
+
# @param [Integer] value
|
35
|
+
# @return [Integer]
|
36
|
+
def self.decode(value)
|
37
|
+
if value < 32768
|
38
|
+
value
|
39
|
+
else
|
40
|
+
mant = value & 0xfff
|
41
|
+
exp = (value >> 12) & 0x7
|
42
|
+
(0x1000 | mant) << (exp + 3)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
require_relative 'mldv2/mlq'
|
50
|
+
require_relative 'mldv2/mlr'
|
@@ -0,0 +1,103 @@
|
|
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
|
+
module MLDv2
|
9
|
+
# Class to handle MLDv2 Mcast Address Records (MAR).
|
10
|
+
#
|
11
|
+
# A Mcast Address Record has the following format:
|
12
|
+
# 0 1 2 3
|
13
|
+
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
14
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
15
|
+
# | Record Type | Aux Data Len | Number of Sources (N) |
|
16
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
17
|
+
# | |
|
18
|
+
# * *
|
19
|
+
# | |
|
20
|
+
# * Multicast Address *
|
21
|
+
# | |
|
22
|
+
# * *
|
23
|
+
# | |
|
24
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
25
|
+
# | |
|
26
|
+
# * *
|
27
|
+
# | |
|
28
|
+
# * Source Address [1] *
|
29
|
+
# | |
|
30
|
+
# * *
|
31
|
+
# | |
|
32
|
+
# +- -+
|
33
|
+
# . . .
|
34
|
+
# . . .
|
35
|
+
# . . .
|
36
|
+
# +- -+
|
37
|
+
# | |
|
38
|
+
# * *
|
39
|
+
# | |
|
40
|
+
# * Source Address [N] *
|
41
|
+
# | |
|
42
|
+
# * *
|
43
|
+
# | |
|
44
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
45
|
+
# | |
|
46
|
+
# . .
|
47
|
+
# . Auxiliary Data .
|
48
|
+
# . .
|
49
|
+
# | |
|
50
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
51
|
+
# @author Sylvain Daubert
|
52
|
+
class McastAddressRecord < Types::Fields
|
53
|
+
|
54
|
+
# Known record types
|
55
|
+
RECORD_TYPES = IGMPv3::GroupRecord::RECORD_TYPES
|
56
|
+
|
57
|
+
# @!attribute type
|
58
|
+
# 8-bit record type
|
59
|
+
# @return [Integer]
|
60
|
+
define_field :type, Types::Int8Enum, enum: RECORD_TYPES
|
61
|
+
# @!attribute aux_data_len
|
62
|
+
# 8-bit length of of the Auxiliary Data field ({#aux_data}), in unit of
|
63
|
+
# 32-bit words
|
64
|
+
# @return [Integer]
|
65
|
+
define_field :aux_data_len, Types::Int8, default: 0
|
66
|
+
# @!attribute number_of_sources
|
67
|
+
# 16-bit Number of source addresses in {#source_addr}
|
68
|
+
# @return [Integer]
|
69
|
+
define_field :number_of_sources, Types::Int16, default: 0
|
70
|
+
# @!attribute multicast_addr
|
71
|
+
# IP multicast address to which this Multicast Address Record pertains
|
72
|
+
# @return [IPv6::Addr]
|
73
|
+
define_field :multicast_addr, IPv6::Addr, default: '::'
|
74
|
+
# @!attribute source_addr
|
75
|
+
# Array of source addresses
|
76
|
+
# @return [IPv6::ArrayOfAddr]
|
77
|
+
define_field :source_addr, IPv6::ArrayOfAddr,
|
78
|
+
builder: ->(h, t) { t.new(counter: h[:number_of_sources]) }
|
79
|
+
# @!attribute aux_data
|
80
|
+
# @return [String]
|
81
|
+
define_field :aux_data, Types::String,
|
82
|
+
builder: ->(h, t) { t.new(length_from: ->() { h[:aux_data_len].to_i * 4 }) }
|
83
|
+
|
84
|
+
def human_type
|
85
|
+
self[:type].to_human
|
86
|
+
end
|
87
|
+
|
88
|
+
def to_human
|
89
|
+
"#{human_type}(ma:#{multicast_addr}|src:#{source_addr.to_human})"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Class to handle series of {MAR}.
|
94
|
+
# @author Sylvain Daubert
|
95
|
+
class McastAddressRecords < Types::Array
|
96
|
+
set_of McastAddressRecord
|
97
|
+
|
98
|
+
# Separator used in {#to_human}.
|
99
|
+
HUMAN_SEPARATOR = ';'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,144 @@
|
|
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
|
+
module MLDv2
|
9
|
+
# This class supports MLDv2 Multicast Listener Query messages.
|
10
|
+
#
|
11
|
+
# From RFC 3810, a MLDv2 Multicast Listener Query message has the
|
12
|
+
# following format:
|
13
|
+
# 1 2 3
|
14
|
+
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
15
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
16
|
+
# | Type = 130 | Code | Checksum |
|
17
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
18
|
+
# | Maximum Response Code | Reserved |
|
19
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
20
|
+
# | |
|
21
|
+
# * *
|
22
|
+
# | |
|
23
|
+
# * Multicast Address *
|
24
|
+
# | |
|
25
|
+
# * *
|
26
|
+
# | |
|
27
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
28
|
+
# | Resv |S| QRV | QQIC | Number of Sources (N) |
|
29
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
30
|
+
# | |
|
31
|
+
# * *
|
32
|
+
# | |
|
33
|
+
# * Source Address [1] *
|
34
|
+
# | |
|
35
|
+
# * *
|
36
|
+
# | |
|
37
|
+
# +- -+
|
38
|
+
# | |
|
39
|
+
# * *
|
40
|
+
# | |
|
41
|
+
# * Source Address [2] *
|
42
|
+
# | |
|
43
|
+
# * *
|
44
|
+
# | |
|
45
|
+
# +- . -+
|
46
|
+
# . . .
|
47
|
+
# . . .
|
48
|
+
# +- -+
|
49
|
+
# | |
|
50
|
+
# * *
|
51
|
+
# | |
|
52
|
+
# * Source Address [N] *
|
53
|
+
# | |
|
54
|
+
# * *
|
55
|
+
# | |
|
56
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
57
|
+
# +type+, +code+ and +checksum+ are fields from {ICMPv6} header.
|
58
|
+
#
|
59
|
+
# MLQ fields are:
|
60
|
+
# * {#max_resp_code #max_resp_code} ({Types::Int16}),
|
61
|
+
# * {#reserved #reserved} ({Types::Int16}),
|
62
|
+
# * {#mcast_addr #mcast_addr} ({IPv6::Addr}),
|
63
|
+
# * {#flags} ({Types::Int8}), with sub-fields:
|
64
|
+
# * a 4-bit {#flag_resv} field,
|
65
|
+
# * a 1-bit {#flag_s} boolean,
|
66
|
+
# * a 3-bit {#flag_qrv} field,
|
67
|
+
# * {#qqic} ({Types::Int8}),
|
68
|
+
# * {#number_of_sources} ({Types::Int16}),
|
69
|
+
# * and {#source_addr}, a {IPv6::ArrayOfAddr}.
|
70
|
+
#
|
71
|
+
# == Max Resp Delay
|
72
|
+
# Max Resp Delay is the real delay value. Max Resp Code is the encoded
|
73
|
+
# delay. So {#max_resp_delay} and {#max_resp_code} attributes reflect this
|
74
|
+
# difference.
|
75
|
+
# @author Sylvain Daubert
|
76
|
+
class MLQ < MLD
|
77
|
+
# @!attribute flags
|
78
|
+
# 8-bit flags
|
79
|
+
# @return [Integer]
|
80
|
+
define_field_before :body, :flags, Types::Int8
|
81
|
+
# @!attribute qqic
|
82
|
+
# 8-bit QQIC
|
83
|
+
# @return [Integer]
|
84
|
+
define_field_before :body, :qqic, Types::Int8
|
85
|
+
# @!attribute number_of_sources
|
86
|
+
# 16-bit number of sources
|
87
|
+
# @return [Integer]
|
88
|
+
define_field_before :body, :number_of_sources, Types::Int16
|
89
|
+
# @!attribute source_addr
|
90
|
+
# Array of IPv6 source addresses
|
91
|
+
# @return [IPv6::ArrayOfAddr]
|
92
|
+
define_field_before :body, :source_addr, IPv6::ArrayOfAddr,
|
93
|
+
builder: ->(h,t) { t.new(counter: h[:number_of_sources]) }
|
94
|
+
|
95
|
+
# @!attribute flag_resv
|
96
|
+
# 4-bit reserved field in {#flags}
|
97
|
+
# @return [Integer]
|
98
|
+
# @!attribute flag_s
|
99
|
+
# S Flag (Suppress Router-Side Processing)
|
100
|
+
# @return [Boolean]
|
101
|
+
# @!attribute flag_qrv
|
102
|
+
# 3-bit QRV (Querier's Robustness Variable)
|
103
|
+
# @return [Integer]
|
104
|
+
define_bit_fields_on :flags, :flag_resv, 4, :flag_s, :flag_qrv, 3
|
105
|
+
|
106
|
+
# Getter for +max_resp_code+ for MLDv2 packets. Use {MLDv2.decode}.
|
107
|
+
# @return [Integer]
|
108
|
+
# @note May return a different value from value previously set, as a
|
109
|
+
# float encoding is used to encode big values. See {MLDv2.decode}.
|
110
|
+
def max_resp_delay
|
111
|
+
MLDv2.decode(self[:max_resp_delay].to_i)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Setter for +max_resp_code+ for MLDv2 packets. Use {MLDv2.encode}.
|
115
|
+
# @param [Integer] value
|
116
|
+
# @return [Integer]
|
117
|
+
# @note See {MLDv2.encode}.
|
118
|
+
def max_resp_delay=(value)
|
119
|
+
self[:max_resp_delay].value = MLDv2.encode(value)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Get QQIC value
|
123
|
+
# @note May return a different value from value previously set, as a
|
124
|
+
# float encoding is used to encode big values. See {IGMPv3.decode}.
|
125
|
+
# @return [Integer]
|
126
|
+
def qqic
|
127
|
+
IGMPv3.decode self[:qqic].to_i
|
128
|
+
end
|
129
|
+
|
130
|
+
# Set QQIC value
|
131
|
+
# @note See {IGMPv3.encode}.
|
132
|
+
# @param [Integer] value
|
133
|
+
# @return [Integer]
|
134
|
+
def qqic=(value)
|
135
|
+
self[:qqic].value = IGMPv3.encode(value)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
self.add_class MLDv2::MLQ
|
141
|
+
ICMPv6.bind_header MLDv2::MLQ, op: :and, type: 130, body: ->(b) { b.nil? ? '' : b.length > 23 }
|
142
|
+
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,65 @@
|
|
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
|
+
require_relative 'mcast_address_record'
|
6
|
+
|
7
|
+
module PacketGen
|
8
|
+
module Header
|
9
|
+
module MLDv2
|
10
|
+
# This class supports MLDv2 Multicast Listener Report messages.
|
11
|
+
#
|
12
|
+
# From RFC 3810, a MLDv2 Multicast Listener Report message has the
|
13
|
+
# following format:
|
14
|
+
# 0 1 2 3
|
15
|
+
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
16
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
17
|
+
# | Type = 143 | Reserved | Checksum |
|
18
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
19
|
+
# | Reserved |Nr of Mcast Address Records (M)|
|
20
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
21
|
+
# | |
|
22
|
+
# . .
|
23
|
+
# . Multicast Address Record [1] .
|
24
|
+
# . .
|
25
|
+
# | |
|
26
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
27
|
+
# | . |
|
28
|
+
# . . .
|
29
|
+
# | . |
|
30
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
31
|
+
# | |
|
32
|
+
# . .
|
33
|
+
# . Multicast Address Record [M] .
|
34
|
+
# . .
|
35
|
+
# | |
|
36
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
37
|
+
# +type+, +code+ and +checksum+ are fields from {ICMPv6} header.
|
38
|
+
#
|
39
|
+
# MLR fields are:
|
40
|
+
# * {#reserved} ({Types::Int16}),
|
41
|
+
# * {#number_of_mar} (number of mcast address records, {Types::Int16}),
|
42
|
+
# * {#records} ({McastAddrRecords}).
|
43
|
+
# @author Sylvain Daubert
|
44
|
+
class MLR < Base
|
45
|
+
# @!attribute reserved
|
46
|
+
# 16-bit reserved field
|
47
|
+
# @return [Integer]
|
48
|
+
define_field :reserved, Types::Int16, default: 0
|
49
|
+
# @!attribute number_of_mar
|
50
|
+
# 16-bit Number of group records in {#group_records}
|
51
|
+
# @return [Integer]
|
52
|
+
define_field :number_of_mar, Types::Int16, default: 0
|
53
|
+
|
54
|
+
# @!attribute records
|
55
|
+
# Array of Mcast Address Records
|
56
|
+
# @return [McastAddressRecords]
|
57
|
+
define_field :records, McastAddressRecords,
|
58
|
+
builder: ->(h, t) { t.new(counter: h[:number_of_mar]) }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
self.add_class MLDv2::MLR
|
63
|
+
ICMPv6.bind_header MLDv2::MLR, type: 143
|
64
|
+
end
|
65
|
+
end
|