packetgen 2.3.0 → 2.4.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/.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
|