packetgen 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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