packetgen-plugin-ipsec 1.0.2 → 1.0.3

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