packetgen-plugin-ipsec 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,260 +1,260 @@
1
1
  # coding: utf-8
2
+ # frozen_string_literal: true
3
+
2
4
  # This file is part of IPsec packetgen plugin.
3
5
  # See https://github.com/sdaubert/packetgen-plugin-ipsec for more informations
4
6
  # Copyright (c) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
5
7
  # This program is published under MIT license.
6
8
 
7
- # frozen_string_literal: true
9
+ module PacketGen::Plugin
10
+ class IKE
11
+ # TrafficSelector substructure, as defined in RFC 7296, §3.13.1:
12
+ # 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
+ # | TS Type |IP Protocol ID*| Selector Length |
16
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
17
+ # | Start Port* | End Port* |
18
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
19
+ # | |
20
+ # ~ Starting Address* ~
21
+ # | |
22
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23
+ # | |
24
+ # ~ Ending Address* ~
25
+ # | |
26
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
27
+ # @author Sylvain Daubert
28
+ class TrafficSelector < PacketGen::Types::Fields
29
+ # IPv4 traffic selector type
30
+ TS_IPV4_ADDR_RANGE = 7
31
+ # IPv6 traffic selector type
32
+ TS_IPV6_ADDR_RANGE = 8
8
33
 
9
- module PacketGen
10
- module Plugin
11
- class IKE
12
- # TrafficSelector substructure, as defined in RFC 7296, §3.13.1:
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
- # | TS Type |IP Protocol ID*| Selector Length |
17
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
18
- # | Start Port* | End Port* |
19
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20
- # | |
21
- # ~ Starting Address* ~
22
- # | |
23
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24
- # | |
25
- # ~ Ending Address* ~
26
- # | |
27
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
28
- # @author Sylvain Daubert
29
- class TrafficSelector < PacketGen::Types::Fields
30
- # IPv4 traffic selector type
31
- TS_IPV4_ADDR_RANGE = 7
32
- # IPv6 traffic selector type
33
- TS_IPV6_ADDR_RANGE = 8
34
+ # @!attribute [r] type
35
+ # 8-bit TS type
36
+ # @return [Integer]
37
+ define_field :type, PacketGen::Types::Int8, default: 7
38
+ # @!attribute [r] protocol
39
+ # 8-bit protocol ID
40
+ # @return [Integer]
41
+ define_field :protocol, PacketGen::Types::Int8, default: 0
42
+ # @!attribute length
43
+ # 16-bit Selector Length
44
+ # @return [Integer]
45
+ define_field :length, PacketGen::Types::Int16
46
+ # @!attribute start_port
47
+ # 16-bit Start port
48
+ # @return [Integer]
49
+ define_field :start_port, PacketGen::Types::Int16, default: 0
50
+ # @!attribute end_port
51
+ # 16-bit End port
52
+ # @return [Integer]
53
+ define_field :end_port, PacketGen::Types::Int16, default: 65_535
54
+ # @!attribute start_addr
55
+ # starting address
56
+ # @return [IP::Addr, IPv6::Addr]
57
+ define_field :start_addr, PacketGen::Header::IP::Addr
58
+ # @!attribute end_addr
59
+ # starting address
60
+ # @return [IP::Addr, IPv6::Addr]
61
+ define_field :end_addr, PacketGen::Header::IP::Addr
34
62
 
35
- # @!attribute [r] type
36
- # 8-bit TS type
37
- # @return [Integer]
38
- define_field :type, PacketGen::Types::Int8, default: 7
39
- # @!attribute [r] protocol
40
- # 8-bit protocol ID
41
- # @return [Integer]
42
- define_field :protocol, PacketGen::Types::Int8, default: 0
43
- # @!attribute length
44
- # 16-bit Selector Length
45
- # @return [Integer]
46
- define_field :length, PacketGen::Types::Int16
47
- # @!attribute start_port
48
- # 16-bit Start port
49
- # @return [Integer]
50
- define_field :start_port, PacketGen::Types::Int16, default: 0
51
- # @!attribute end_port
52
- # 16-bit End port
53
- # @return [Integer]
54
- define_field :end_port, PacketGen::Types::Int16, default: 65_535
55
- # @!attribute start_addr
56
- # starting address
57
- # @return [IP::Addr, IPv6::Addr]
58
- define_field :start_addr, PacketGen::Header::IP::Addr
59
- # @!attribute end_addr
60
- # starting address
61
- # @return [IP::Addr, IPv6::Addr]
62
- define_field :end_addr, PacketGen::Header::IP::Addr
63
+ # @param [Hash] options
64
+ # @option [Range] :ports port range
65
+ # @option [Integer] :start_port start port
66
+ # @option [Integer] :end_port end port
67
+ def initialize(options={})
68
+ super
69
+ select_addr options
70
+ self[:start_addr].from_human(options[:start_addr]) if options[:start_addr]
71
+ self[:end_addr].from_human(options[:end_addr]) if options[:end_addr]
72
+ self.type = options[:type] if options[:type]
73
+ self.protocol = options[:protocol] if options[:protocol]
74
+ self[:length].value = sz unless options[:length]
75
+ return unless options[:ports]
63
76
 
64
- # @param [Hash] options
65
- # @option [Range] :ports port range
66
- # @option [Integer] :start_port start port
67
- # @option [Integer] :end_port end port
68
- def initialize(options={})
69
- super
70
- select_addr options
71
- self[:start_addr].from_human(options[:start_addr]) if options[:start_addr]
72
- self[:end_addr].from_human(options[:end_addr]) if options[:end_addr]
73
- self.type = options[:type] if options[:type]
74
- self.protocol = options[:protocol] if options[:protocol]
75
- self[:length].value = sz unless options[:length]
77
+ self.start_port = options[:ports].begin
78
+ self.end_port = options[:ports].end
79
+ end
76
80
 
77
- return unless options[:ports]
78
- self.start_port = options[:ports].begin
79
- self.end_port = options[:ports].end
80
- end
81
+ # Populate object from a string
82
+ # @param [String] str
83
+ # @return [self]
84
+ def read(str)
85
+ super
86
+ select_addr_from_type type
87
+ super
88
+ end
81
89
 
82
- # Populate object from a string
83
- # @param [String] str
84
- # @return [self]
85
- def read(str)
86
- super
87
- select_addr_from_type type
88
- super
89
- end
90
+ undef type=, protocol=
90
91
 
91
- undef type=, protocol=
92
+ # Set type
93
+ # @param [Integer,String] value
94
+ # @return [Integer]
95
+ def type=(value)
96
+ type = case value
97
+ when Integer
98
+ value
99
+ else
100
+ c = self.class.constants.grep(/TS_#{value.upcase}/).first
101
+ c ? self.class.const_get(c) : nil
102
+ end
103
+ raise ArgumentError, "unknown type #{value.inspect}" unless type
92
104
 
93
- # Set type
94
- # @param [Integer,String] value
95
- # @return [Integer]
96
- def type=(value)
97
- type = case value
98
- when Integer
99
- value
100
- else
101
- c = self.class.constants.grep(/TS_#{value.upcase}/).first
102
- c ? self.class.const_get(c) : nil
103
- end
104
- raise ArgumentError, "unknown type #{value.inspect}" unless type
105
- select_addr_from_type type
106
- self[:type].value = type
107
- end
105
+ select_addr_from_type type
106
+ self[:type].value = type
107
+ end
108
108
 
109
- # Set protocol
110
- # @param [Integer,String] value
111
- # @return [Integer]
112
- def protocol=(value)
113
- protocol = case value
114
- when Integer
115
- value
116
- else
117
- Proto.getprotobyname(value)
118
- end
119
- raise ArgumentError, "unknown protocol #{value.inspect}" unless protocol
120
- self[:protocol].value = protocol
121
- end
109
+ # Set protocol
110
+ # @param [Integer,String] value
111
+ # @return [Integer]
112
+ def protocol=(value)
113
+ protocol = case value
114
+ when Integer
115
+ value
116
+ else
117
+ PacketGen::Proto.getprotobyname(value)
118
+ end
119
+ raise ArgumentError, "unknown protocol #{value.inspect}" unless protocol
122
120
 
123
- # Get a human readable string
124
- # @return [String]
125
- def to_human
126
- h = start_addr << '-' << end_addr
127
- unless human_protocol.empty?
128
- h << "/#{human_protocol}"
129
- h << "[#{start_port}-#{end_port}]" if (start_port..end_port) != (0..65_535)
130
- end
131
- h
132
- end
121
+ self[:protocol].value = protocol
122
+ end
133
123
 
134
- # Get human readable protocol name. If protocol ID is 0, an empty string
135
- # is returned.
136
- # @return [String]
137
- def human_protocol
138
- if protocol.zero?
139
- ''
140
- else
141
- Proto.getprotobynumber(protocol) || protocol.to_s
142
- end
124
+ # Get a human readable string
125
+ # @return [String]
126
+ def to_human
127
+ h = start_addr << '-' << end_addr
128
+ unless human_protocol.empty?
129
+ h << "/#{human_protocol}"
130
+ h << "[#{start_port}-#{end_port}]" if (start_port..end_port) != (0..65_535)
143
131
  end
132
+ h
133
+ end
144
134
 
145
- # Get human readable TS type
146
- # @return [String]
147
- def human_type
148
- case type
149
- when TS_IPV4_ADDR_RANGE
150
- 'IPv4'
151
- when TS_IPV6_ADDR_RANGE
152
- 'IPv6'
153
- else
154
- "type #{type}"
155
- end
135
+ # Get human readable protocol name. If protocol ID is 0, an empty string
136
+ # is returned.
137
+ # @return [String]
138
+ def human_protocol
139
+ if protocol.zero?
140
+ ''
141
+ else
142
+ PacketGen::Proto.getprotobynumber(protocol) || protocol.to_s
156
143
  end
144
+ end
157
145
 
158
- private
159
-
160
- def select_addr_from_type(type)
161
- case type
162
- when TS_IPV4_ADDR_RANGE, 'IPV4', 'IPv4', 'ipv4', nil
163
- self[:start_addr] = PacketGen::Header::IP::Addr.new unless self[:start_addr].is_a?(PacketGen::Header::IP::Addr)
164
- self[:end_addr] = PacketGen::Header::IP::Addr.new unless self[:end_addr].is_a?(PacketGen::Header::IP::Addr)
165
- when TS_IPV6_ADDR_RANGE, 'IPV6', 'IPv6', 'ipv6'
166
- self[:start_addr] = PacketGen::Header::IPv6::Addr.new unless self[:start_addr].is_a?(PacketGen::Header::IPv6::Addr)
167
- self[:end_addr] = PacketGen::Header::IPv6::Addr.new unless self[:end_addr].is_a?(PacketGen::Header::IPv6::Addr)
168
- else
169
- raise ArgumentError, "unknown type #{type}"
170
- end
146
+ # Get human readable TS type
147
+ # @return [String]
148
+ def human_type
149
+ case type
150
+ when TS_IPV4_ADDR_RANGE
151
+ 'IPv4'
152
+ when TS_IPV6_ADDR_RANGE
153
+ 'IPv6'
154
+ else
155
+ "type #{type}"
171
156
  end
157
+ end
158
+
159
+ private
172
160
 
173
- def select_addr(options)
174
- if options[:type]
175
- select_addr_from_type options[:type]
176
- elsif options[:start_addr]
177
- ipv4 = IPAddr.new(options[:start_addr]).ipv4?
178
- self.type = ipv4 ? TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE
179
- elsif options[:end_addr]
180
- ipv4 = IPAddr.new(options[:end_addr]).ipv4?
181
- self.type = ipv4 ? TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE
182
- end
161
+ def select_addr_from_type(type)
162
+ case type
163
+ when TS_IPV4_ADDR_RANGE, 'IPV4', 'IPv4', 'ipv4', nil
164
+ self[:start_addr] = PacketGen::Header::IP::Addr.new unless self[:start_addr].is_a?(PacketGen::Header::IP::Addr)
165
+ self[:end_addr] = PacketGen::Header::IP::Addr.new unless self[:end_addr].is_a?(PacketGen::Header::IP::Addr)
166
+ when TS_IPV6_ADDR_RANGE, 'IPV6', 'IPv6', 'ipv6'
167
+ self[:start_addr] = PacketGen::Header::IPv6::Addr.new unless self[:start_addr].is_a?(PacketGen::Header::IPv6::Addr)
168
+ self[:end_addr] = PacketGen::Header::IPv6::Addr.new unless self[:end_addr].is_a?(PacketGen::Header::IPv6::Addr)
169
+ else
170
+ raise ArgumentError, "unknown type #{type}"
183
171
  end
184
172
  end
185
173
 
186
- # Set of {TrafficSelector}, used by {TSi} and {TSr}.
187
- # @author Sylvain Daubert
188
- class TrafficSelectors < PacketGen::Types::Array
189
- set_of TrafficSelector
174
+ def select_addr(options)
175
+ if options[:type]
176
+ select_addr_from_type options[:type]
177
+ elsif options[:start_addr]
178
+ ipv4 = IPAddr.new(options[:start_addr]).ipv4?
179
+ self.type = ipv4 ? TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE
180
+ elsif options[:end_addr]
181
+ ipv4 = IPAddr.new(options[:end_addr]).ipv4?
182
+ self.type = ipv4 ? TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE
183
+ end
190
184
  end
185
+ end
191
186
 
192
- # This class handles Traffic Selector - Initiator payloads, denoted TSi.
193
- #
194
- # A TSi payload consists of the IKE generic payload Plugin (see {Payload})
195
- # and some specific fields:
196
- # 1 2 3
197
- # 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
198
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
199
- # | Next Payload |C| RESERVED | Payload Length |
200
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
201
- # | Number of TSs | RESERVED |
202
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
203
- # | |
204
- # ~ <Traffic Selectors> ~
205
- # | |
206
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
207
- # These specific fields are:
208
- # * {#num_ts},
209
- # * {#rsv1},
210
- # * {#rsv2},
211
- # * and {#traffic_selectors}.
212
- #
213
- # == Create a TSi payload
214
- # # Create a IKE packet with a TSi payload
215
- # pkt = PacketGen.gen('IP').add('UDP').add('IKE').add('IKE::TSi')
216
- # # add a traffic selector to this payload
217
- # pkt.ike_tsi.traffic_selectors << { protocol: 'tcp', ports: 1..1024, start_addr: '20.0.0.1', end_addr: '21.255.255.254' }
218
- # # add another traffic selector (IPv6, all protocols)
219
- # pkt.ike_tsi.traffic_selectors << { start_addr: '2001::1', end_addr: '200a:ffff:ffff:ffff:ffff:ffff:ffff:ffff' }
220
- # @author Sylvain Daubert
221
- class TSi < Payload
222
- # Payload type number
223
- PAYLOAD_TYPE = 44
187
+ # Set of {TrafficSelector}, used by {TSi} and {TSr}.
188
+ # @author Sylvain Daubert
189
+ class TrafficSelectors < PacketGen::Types::Array
190
+ set_of TrafficSelector
191
+ end
224
192
 
225
- remove_field :content
193
+ # This class handles Traffic Selector - Initiator payloads, denoted TSi.
194
+ #
195
+ # A TSi payload consists of the IKE generic payload Plugin (see {Payload})
196
+ # and some specific fields:
197
+ # 1 2 3
198
+ # 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
199
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
200
+ # | Next Payload |C| RESERVED | Payload Length |
201
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
202
+ # | Number of TSs | RESERVED |
203
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
204
+ # | |
205
+ # ~ <Traffic Selectors> ~
206
+ # | |
207
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
208
+ # These specific fields are:
209
+ # * {#num_ts},
210
+ # * {#rsv1},
211
+ # * {#rsv2},
212
+ # * and {#traffic_selectors}.
213
+ #
214
+ # == Create a TSi payload
215
+ # # Create a IKE packet with a TSi payload
216
+ # pkt = PacketGen.gen('IP').add('UDP').add('IKE').add('IKE::TSi')
217
+ # # add a traffic selector to this payload
218
+ # pkt.ike_tsi.traffic_selectors << { protocol: 'tcp', ports: 1..1024, start_addr: '20.0.0.1', end_addr: '21.255.255.254' }
219
+ # # add another traffic selector (IPv6, all protocols)
220
+ # pkt.ike_tsi.traffic_selectors << { start_addr: '2001::1', end_addr: '200a:ffff:ffff:ffff:ffff:ffff:ffff:ffff' }
221
+ # @author Sylvain Daubert
222
+ class TSi < Payload
223
+ # Payload type number
224
+ PAYLOAD_TYPE = 44
226
225
 
227
- # @!attribute num_ts
228
- # 8-bit Number of TSs
229
- # @return [Integer]
230
- define_field_before :body, :num_ts, PacketGen::Types::Int8
231
- # @!attribute rsv
232
- # 24-bit RESERVED field
233
- # @return [Integer]
234
- define_field_before :body, :rsv, PacketGen::Types::Int24
226
+ remove_field :content
235
227
 
236
- # @!attribute traffic_selectors
237
- # Set of {TrafficSelector}
238
- # @return {TrafficSelectors}
239
- define_field_before :body, :traffic_selectors, TrafficSelectors,
240
- builder: ->(h, t) { t.new(counter: h[:num_ts]) }
241
- alias selectors traffic_selectors
228
+ # @!attribute num_ts
229
+ # 8-bit Number of TSs
230
+ # @return [Integer]
231
+ define_field_before :body, :num_ts, PacketGen::Types::Int8
232
+ # @!attribute rsv
233
+ # 24-bit RESERVED field
234
+ # @return [Integer]
235
+ define_field_before :body, :rsv, PacketGen::Types::Int24
242
236
 
243
- # Compute length and set {#length} field
244
- # @return [Integer] new length
245
- def calc_length
246
- selectors.each(&:calc_length)
247
- super
248
- end
249
- end
237
+ # @!attribute traffic_selectors
238
+ # Set of {TrafficSelector}
239
+ # @return {TrafficSelectors}
240
+ define_field_before :body, :traffic_selectors, TrafficSelectors,
241
+ builder: ->(h, t) { t.new(counter: h[:num_ts]) }
242
+ alias selectors traffic_selectors
250
243
 
251
- class TSr < TSi
252
- # Payload type number
253
- PAYLOAD_TYPE = 45
244
+ # Compute length and set {#length} field
245
+ # @return [Integer] new length
246
+ def calc_length
247
+ selectors.each(&:calc_length)
248
+ super
254
249
  end
255
250
  end
256
251
 
257
- Header.add_class IKE::TSi
258
- Header.add_class IKE::TSr
252
+ class TSr < TSi
253
+ # Payload type number
254
+ PAYLOAD_TYPE = 45
255
+ end
259
256
  end
257
+
258
+ PacketGen::Header.add_class IKE::TSi
259
+ PacketGen::Header.add_class IKE::TSr
260
260
  end