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.
@@ -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