cisco_acl_intp 0.0.2 → 0.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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/README.md +64 -3
  4. data/cisco_acl_intp.gemspec +2 -2
  5. data/lib/cisco_acl_intp/ace.rb +9 -286
  6. data/lib/cisco_acl_intp/ace_ip.rb +24 -22
  7. data/lib/cisco_acl_intp/ace_other_qualifiers.rb +23 -6
  8. data/lib/cisco_acl_intp/ace_port.rb +37 -182
  9. data/lib/cisco_acl_intp/ace_port_opr.rb +251 -0
  10. data/lib/cisco_acl_intp/ace_port_opr_base.rb +138 -0
  11. data/lib/cisco_acl_intp/ace_proto.rb +133 -328
  12. data/lib/cisco_acl_intp/ace_proto_base.rb +163 -0
  13. data/lib/cisco_acl_intp/ace_srcdst.rb +30 -40
  14. data/lib/cisco_acl_intp/ace_tcp_flags.rb +9 -3
  15. data/lib/cisco_acl_intp/acl.rb +1 -251
  16. data/lib/cisco_acl_intp/acl_base.rb +1 -1
  17. data/lib/cisco_acl_intp/acl_utils.rb +120 -0
  18. data/lib/cisco_acl_intp/extended_ace.rb +149 -0
  19. data/lib/cisco_acl_intp/mono_function_acl.rb +161 -0
  20. data/lib/cisco_acl_intp/parser.rb +237 -395
  21. data/lib/cisco_acl_intp/parser.ry +85 -243
  22. data/lib/cisco_acl_intp/parser_api.rb +2 -2
  23. data/lib/cisco_acl_intp/single_acl_base.rb +137 -0
  24. data/lib/cisco_acl_intp/standard_ace.rb +105 -0
  25. data/lib/cisco_acl_intp/version.rb +1 -1
  26. data/spec/cisco_acl_intp/ace_ip_spec.rb +63 -0
  27. data/spec/cisco_acl_intp/ace_other_qualifier_spec.rb +52 -1
  28. data/spec/cisco_acl_intp/ace_port_operator_spec.rb +340 -0
  29. data/spec/cisco_acl_intp/ace_port_spec.rb +67 -217
  30. data/spec/cisco_acl_intp/ace_proto_spec.rb +118 -41
  31. data/spec/cisco_acl_intp/ace_spec.rb +38 -547
  32. data/spec/cisco_acl_intp/ace_srcdst_spec.rb +115 -226
  33. data/spec/cisco_acl_intp/ace_tcp_flags_spec.rb +36 -4
  34. data/spec/cisco_acl_intp/acl_base_spec.rb +2 -2
  35. data/spec/cisco_acl_intp/extended_ace_spec.rb +411 -0
  36. data/spec/cisco_acl_intp/extended_acl_spec.rb +265 -0
  37. data/spec/cisco_acl_intp/scanner_spec.rb +13 -12
  38. data/spec/cisco_acl_intp/standard_ace_spec.rb +77 -0
  39. data/spec/cisco_acl_intp/standard_acl_spec.rb +245 -0
  40. data/spec/conf/scanner_spec_data.yml +32 -0
  41. data/spec/spec_helper.rb +2 -2
  42. metadata +20 -4
  43. data/spec/cisco_acl_intp/acl_spec.rb +0 -525
@@ -0,0 +1,411 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ def _build_taget(opts)
5
+ ExtendedAce.new(
6
+ action: (opts[:target] || 'permit'),
7
+ protocol: (opts[:protocol] || 'tcp'),
8
+ src: AceSrcDstSpec.new(
9
+ ipaddr: opts[:src_ip], netmask: 32,
10
+ operator: :eq, port: AceTcpProtoSpec.new(opts[:src_port])
11
+ ),
12
+ dst: AceSrcDstSpec.new(
13
+ ipaddr: opts[:dst_ip], netmask: 32,
14
+ operator: :eq, port: AceTcpProtoSpec.new(opts[:dst_port])
15
+ )
16
+ )
17
+ end
18
+
19
+ describe ExtendedAce do
20
+ describe '#to_s' do
21
+ context 'Normal case' do
22
+ before do
23
+ @src = AceSrcDstSpec.new(
24
+ ipaddr: '192.168.15.15',
25
+ wildcard: '0.0.7.6'
26
+ )
27
+ @dst = AceSrcDstSpec.new(
28
+ ipaddr: '192.168.30.3',
29
+ wildcard: '0.0.0.0',
30
+ operator: 'range',
31
+ begin_port: AceTcpProtoSpec.new(1_024),
32
+ end_port: AceTcpProtoSpec.new(65_535)
33
+ )
34
+ end
35
+
36
+ it 'should be protocol tcp, action permit' do
37
+ ea = ExtendedAce.new(
38
+ action: 'permit',
39
+ protocol: 'tcp',
40
+ src: @src,
41
+ dst: @dst
42
+ )
43
+ ea.to_s.should be_aclstr(
44
+ 'permit tcp 192.168.8.9 0.0.7.6 host 192.168.30.3 range 1024 65535'
45
+ )
46
+ end
47
+
48
+ it 'should be protocol tcp, action deny' do
49
+ ea = ExtendedAce.new(
50
+ action: 'deny',
51
+ protocol: 'tcp',
52
+ src: @src,
53
+ dst: @dst
54
+ )
55
+ ea.to_s.should be_aclstr(
56
+ 'deny tcp 192.168.8.9 0.0.7.6 host 192.168.30.3 range 1024 65535'
57
+ )
58
+ end
59
+
60
+ end
61
+
62
+ context 'Argument error case' do
63
+ before do
64
+ @src = AceSrcDstSpec.new(
65
+ ipaddr: '192.168.15.15',
66
+ wildcard: '0.0.7.6'
67
+ )
68
+ @dst = AceSrcDstSpec.new(
69
+ ipaddr: '192.168.30.3',
70
+ wildcard: '0.0.0.0',
71
+ operator: 'range',
72
+ begin_port: AceTcpProtoSpec.new(1_024),
73
+ end_port: AceTcpProtoSpec.new(65_535)
74
+ )
75
+ end
76
+
77
+ it 'should be rased exception when :action not specified' do
78
+ lambda do
79
+ ExtendedAce.new(
80
+ protocol: 'tcp',
81
+ src: @src,
82
+ dst: @dst
83
+ )
84
+ end.should raise_error(AclArgumentError)
85
+ end
86
+
87
+ it 'should be rased exception when :protocol not specified' do
88
+ lambda do
89
+ ExtendedAce.new(
90
+ action: 'deny',
91
+ src: @src,
92
+ dst: @dst
93
+ )
94
+ end.should raise_error(AclArgumentError)
95
+ end
96
+
97
+ it 'should be rased exception when :src not specified' do
98
+ lambda do
99
+ ExtendedAce.new(
100
+ action: 'deny',
101
+ protocol: 'tcp',
102
+ dst: @dst
103
+ )
104
+ end.should raise_error(AclArgumentError)
105
+ end
106
+
107
+ it 'should be rased exception when :dst not specified' do
108
+ lambda do
109
+ ExtendedAce.new(
110
+ action: 'deny',
111
+ protocol: 'tcp',
112
+ src: @src
113
+ )
114
+ end.should raise_error(AclArgumentError)
115
+ end
116
+
117
+ end
118
+ end
119
+
120
+ describe '#contains?' do
121
+ context 'tcp src/dst ip/port full spec test' do
122
+ before do
123
+ src = AceSrcDstSpec.new(
124
+ ipaddr: '192.168.15.15',
125
+ wildcard: '0.0.7.6',
126
+ operator: 'gt',
127
+ port: AceTcpProtoSpec.new(32_767)
128
+ )
129
+ dst = AceSrcDstSpec.new(
130
+ ipaddr: '192.168.30.3',
131
+ wildcard: '0.0.0.0',
132
+ operator: 'range',
133
+ begin_port: AceTcpProtoSpec.new(1_024),
134
+ end_port: AceTcpProtoSpec.new(65_535)
135
+ )
136
+ @ea = ExtendedAce.new(
137
+ action: 'permit',
138
+ protocol: 'tcp',
139
+ src: src,
140
+ dst: dst
141
+ )
142
+ end # before
143
+
144
+ ## generate test pattern data
145
+ data_table = {
146
+ protocol_match: 'tcp',
147
+ protocol_unmatch: 'udp',
148
+ src_ip_match: '192.168.9.11',
149
+ src_ip_unmatch: '192.168.9.12',
150
+ src_port_match: 32_768,
151
+ src_port_unmatch: 8_080,
152
+ dst_ip_match: '192.168.30.3',
153
+ dst_ip_unmatch: '192.168.30.4',
154
+ dst_port_match: 3_366,
155
+ dst_port_unmatch: 100
156
+ }
157
+
158
+ bit = 5
159
+ test_data = [
160
+ :dst_port,
161
+ :dst_ip,
162
+ :src_port,
163
+ :src_ip,
164
+ :protocol
165
+ ]
166
+
167
+ tests = []
168
+ (0..(2**bit - 1)).each do |num|
169
+ opts = {}
170
+ flag = 1
171
+ (0...bit).each do |b|
172
+ pstr = ((num & flag) == 0 ? '_match' : '_unmatch')
173
+ key = test_data[b].to_s.concat(pstr)
174
+ opts[test_data[b]] = data_table[key.to_sym]
175
+ flag = flag << 1
176
+ end
177
+ tests.push(
178
+ opts: opts,
179
+ res: num > 0 ? false : true
180
+ )
181
+ end
182
+
183
+ tests.each do |each|
184
+ # test params
185
+ eres = each[:res]
186
+ eopts = each[:opts]
187
+ teststr = [
188
+ "should be #{eres}",
189
+ "when #{eopts[:protocol]};",
190
+ "#{eopts[:src_ip]}:#{eopts[:src_port]} >",
191
+ "#{eopts[:dst_ip]}:#{eopts[:dst_port]}"
192
+ ].join(' ')
193
+ # run test
194
+ it teststr do
195
+ if eres
196
+ @ea.contains?(_build_taget(eopts)).should be_true
197
+ else
198
+ @ea.contains?(_build_taget(eopts)).should be_false
199
+ end
200
+ end # it
201
+ end # tests.each
202
+
203
+ end # context full spec test
204
+
205
+ context 'ANY ip/port port exists case' do
206
+ before do
207
+ ip_any = AceIpSpec.new(
208
+ ipaddr: '0.0.0.0', wildcard: '255.255.255.255'
209
+ )
210
+ port_any = AcePortSpec.new(operator: 'any')
211
+ src_ip = AceIpSpec.new(
212
+ ipaddr: '192.168.15.15', wildcard: '0.0.7.6'
213
+ )
214
+ src_port = AcePortSpec.new(
215
+ operator: 'gt', port: AceTcpProtoSpec.new(32_767)
216
+ )
217
+
218
+ dst_ip = AceIpSpec.new(
219
+ ipaddr: '192.168.30.3', wildcard: '0.0.0.0'
220
+ )
221
+ dst_port = AcePortSpec.new(
222
+ operator: 'range',
223
+ begin_port: AceTcpProtoSpec.new(1_024),
224
+ end_port: AceTcpProtoSpec.new(65_535)
225
+ )
226
+
227
+ @src0 = AceSrcDstSpec.new(ip_spec: src_ip, port_spec: src_port)
228
+ @src1 = AceSrcDstSpec.new(ip_spec: ip_any, port_spec: src_port)
229
+ @src2 = AceSrcDstSpec.new(ip_spec: src_ip, port_spec: port_any)
230
+ @dst0 = AceSrcDstSpec.new(ip_spec: dst_ip, port_spec: dst_port)
231
+ @dst1 = AceSrcDstSpec.new(ip_spec: ip_any, port_spec: dst_port)
232
+ @dst2 = AceSrcDstSpec.new(ip_spec: dst_ip, port_spec: port_any)
233
+
234
+ @src_ip_match = '192.168.9.11'
235
+ @src_ip_unmatch = '192.168.9.12'
236
+ @src_port_match = 32_768
237
+ @src_port_unmatch = 8_080
238
+ @dst_ip_match = '192.168.30.3'
239
+ @dst_ip_unmatch = '192.168.30.4'
240
+ @dst_port_match = 3_366
241
+ @dst_port_unmatch = 100
242
+ end
243
+
244
+ it 'should be true when any source ip' do
245
+ ea = ExtendedAce.new(
246
+ action: 'permit', protocol: 'tcp', src: @src1, dst: @dst0
247
+ )
248
+ ea.contains?(_build_taget(
249
+ protocol: 'tcp',
250
+ src_operator: :eq,
251
+ src_ip: @src_ip_match, src_port: @src_port_match,
252
+ dst_operator: :eq,
253
+ dst_ip: @dst_ip_match, dst_port: @dst_port_match
254
+ )).should be_true
255
+ ea.contains?(_build_taget(
256
+ protocol: 'tcp',
257
+ src_operator: :eq,
258
+ src_ip: @src_ip_unmatch, src_port: @src_port_match,
259
+ dst_operator: :eq,
260
+ dst_ip: @dst_ip_match, dst_port: @dst_port_match
261
+ )).should be_true
262
+ end
263
+
264
+ it 'should be false when any source ip and unmatch port' do
265
+ ea = ExtendedAce.new(
266
+ action: 'permit', protocol: 'tcp', src: @src1, dst: @dst0
267
+ )
268
+ ea.contains?(_build_taget(
269
+ protocol: 'tcp',
270
+ src_operator: :eq,
271
+ src_ip: @src_ip_match, src_port: @src_port_unmatch,
272
+ dst_operator: :eq,
273
+ dst_ip: @dst_ip_match, dst_port: @dst_port_match
274
+ )).should be_false
275
+ ea.contains?(_build_taget(
276
+ protocol: 'tcp',
277
+ src_operator: :eq,
278
+ src_ip: @src_ip_unmatch, src_port: @src_port_unmatch,
279
+ dst_operator: :eq,
280
+ dst_ip: @dst_ip_match, dst_port: @dst_port_match
281
+ )).should be_false
282
+ end
283
+
284
+ it 'should be true when any source port' do
285
+ ea = ExtendedAce.new(
286
+ action: 'permit', protocol: 'tcp', src: @src2, dst: @dst0
287
+ )
288
+ ea.contains?(_build_taget(
289
+ protocol: 'tcp',
290
+ src_operator: :eq,
291
+ src_ip: @src_ip_match, src_port: @src_port_match,
292
+ dst_operator: :eq,
293
+ dst_ip: @dst_ip_match, dst_port: @dst_port_match
294
+ )).should be_true
295
+ ea.contains?(_build_taget(
296
+ protocol: 'tcp',
297
+ src_operator: :eq,
298
+ src_ip: @src_ip_match, src_port: @src_port_unmatch,
299
+ dst_operator: :eq,
300
+ dst_ip: @dst_ip_match, dst_port: @dst_port_match
301
+ )).should be_true
302
+ end
303
+
304
+ it 'should be false when any source port and unmatch ip' do
305
+ ea = ExtendedAce.new(
306
+ action: 'permit', protocol: 'tcp', src: @src2, dst: @dst0
307
+ )
308
+ ea.contains?(_build_taget(
309
+ protocol: 'tcp',
310
+ src_operator: :eq,
311
+ src_ip: @src_ip_unmatch, src_port: @src_port_match,
312
+ dst_operator: :eq,
313
+ dst_ip: @dst_ip_match, dst_port: @dst_port_match
314
+ )).should be_false
315
+ ea.contains?(_build_taget(
316
+ protocol: 'tcp',
317
+ src_operator: :eq,
318
+ src_ip: @src_ip_unmatch, src_port: @src_port_unmatch,
319
+ dst_operator: :eq,
320
+ dst_ip: @dst_ip_match, dst_port: @dst_port_match
321
+ )).should be_false
322
+ end
323
+
324
+ it 'should be true when any destination ip' do
325
+ ea = ExtendedAce.new(
326
+ action: 'permit', protocol: 'tcp', src: @src0, dst: @dst1
327
+ )
328
+ ea.contains?(_build_taget(
329
+ protocol: 'tcp',
330
+ src_operator: :eq,
331
+ src_ip: @src_ip_match, src_port: @src_port_match,
332
+ dst_operator: :eq,
333
+ dst_ip: @dst_ip_match, dst_port: @dst_port_match
334
+ )).should be_true
335
+ ea.contains?(_build_taget(
336
+ protocol: 'tcp',
337
+ src_operator: :eq,
338
+ src_ip: @src_ip_match, src_port: @src_port_match,
339
+ dst_operator: :eq,
340
+ dst_ip: @dst_ip_unmatch, dst_port: @dst_port_match
341
+ )).should be_true
342
+ end
343
+
344
+ it 'should be false when any destination ip and unmatch port' do
345
+ ea = ExtendedAce.new(
346
+ action: 'permit', protocol: 'tcp', src: @src0, dst: @dst1
347
+ )
348
+ ea.contains?(_build_taget(
349
+ protocol: 'tcp',
350
+ src_operator: :eq,
351
+ src_ip: @src_ip_match, src_port: @src_port_match,
352
+ dst_operator: :eq,
353
+ dst_ip: @dst_ip_match, dst_port: @dst_port_unmatch
354
+ )).should be_false
355
+ ea.contains?(_build_taget(
356
+ protocol: 'tcp',
357
+ src_operator: :eq,
358
+ src_ip: @src_ip_match, src_port: @src_port_match,
359
+ dst_operator: :eq,
360
+ dst_ip: @dst_ip_unmatch, dst_port: @dst_port_unmatch
361
+ )).should be_false
362
+ end
363
+
364
+ it 'should be true when any destination port' do
365
+ ea = ExtendedAce.new(
366
+ action: 'permit', protocol: 'tcp', src: @src0, dst: @dst2
367
+ )
368
+ ea.contains?(_build_taget(
369
+ protocol: 'tcp',
370
+ src_operator: :eq,
371
+ src_ip: @src_ip_match, src_port: @src_port_match,
372
+ dst_operator: :eq,
373
+ dst_ip: @dst_ip_match, dst_port: @dst_port_match
374
+ )).should be_true
375
+ ea.contains?(_build_taget(
376
+ protocol: 'tcp',
377
+ src_operator: :eq,
378
+ src_ip: @src_ip_match, src_port: @src_port_match,
379
+ dst_operator: :eq,
380
+ dst_ip: @dst_ip_match, dst_port: @dst_port_unmatch
381
+ )).should be_true
382
+ end
383
+
384
+ it 'should be false when any destination port and unmatch ip' do
385
+ ea = ExtendedAce.new(
386
+ action: 'permit', protocol: 'tcp', src: @src0, dst: @dst2
387
+ )
388
+ ea.contains?(_build_taget(
389
+ protocol: 'tcp',
390
+ src_operator: :eq,
391
+ src_ip: @src_ip_match, src_port: @src_port_match,
392
+ dst_operator: :eq,
393
+ dst_ip: @dst_ip_unmatch, dst_port: @dst_port_match
394
+ )).should be_false
395
+ ea.contains?(_build_taget(
396
+ protocol: 'tcp',
397
+ src_operator: :eq,
398
+ src_ip: @src_ip_match, src_port: @src_port_match,
399
+ dst_operator: :eq,
400
+ dst_ip: @dst_ip_unmatch, dst_port: @dst_port_unmatch
401
+ )).should be_false
402
+ end
403
+ end # context exists any ip/port
404
+ end # describe contains?
405
+ end # describe ExtendedAce
406
+
407
+ ### Local variables:
408
+ ### mode: Ruby
409
+ ### coding: utf-8-unix
410
+ ### indent-tabs-mode: nil
411
+ ### End:
@@ -0,0 +1,265 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe NamedExtAcl do
5
+ describe '#add_entry' do
6
+ before(:all) do
7
+ @acl = NamedExtAcl.new 'test-ext-acl'
8
+ end
9
+
10
+ it 'should be zero when initialized' do
11
+ @acl.size.should be_zero
12
+ @acl.named_acl?.should be_true
13
+ @acl.numbered_acl?.should be_false
14
+ end
15
+
16
+ it 'should be size 1 and matches aclstr when added a acl entry' do
17
+ ea = ExtendedAce.new(
18
+ action: 'permit',
19
+ protocol: 'udp',
20
+ src: {
21
+ ipaddr: '192.168.3.3',
22
+ wildcard: '0.0.0.127'
23
+ },
24
+ dst: {
25
+ ipaddr: '192.168.4.4',
26
+ wildcard: '0.0.0.255'
27
+ }
28
+ )
29
+ @acl.add_entry ea
30
+ @acl.size.should eq 1
31
+ aclstr = <<'EOL'
32
+ ip access-list extended test-ext-acl
33
+ permit udp 192.168.3.0 0.0.0.127 192.168.4.0 0.0.0.255
34
+ EOL
35
+ @acl.to_s.should be_aclstr(aclstr)
36
+ end
37
+ end
38
+
39
+ describe '#add_entry_by_params' do
40
+ before(:all) do
41
+ @acl = NamedExtAcl.new 'test-ext-acl2'
42
+ @acl.add_entry_by_params(
43
+ action: 'permit',
44
+ protocol: 'udp',
45
+ src: {
46
+ ipaddr: '192.168.3.3',
47
+ wildcard: '0.0.0.127'
48
+ },
49
+ dst: {
50
+ ipaddr: '192.168.4.4',
51
+ wildcard: '0.0.0.255'
52
+ }
53
+ )
54
+ @acl.add_entry_by_params(
55
+ action: 'deny',
56
+ protocol: 'tcp',
57
+ src: {
58
+ ipaddr: '192.168.3.3',
59
+ wildcard: '0.0.0.0'
60
+ },
61
+ dst: {
62
+ ipaddr: '192.168.4.4',
63
+ wildcard: '0.0.0.255',
64
+ operator: 'gt',
65
+ port: AceUdpProtoSpec.new(32_768)
66
+ }
67
+ )
68
+ end
69
+
70
+ it 'should be size 2' do
71
+ @acl.size.should eq 2
72
+ end
73
+
74
+ it 'mutches aclstr' do
75
+ aclstr = <<'EOL'
76
+ ip access-list extended test-ext-acl2
77
+ permit udp 192.168.3.0 0.0.0.127 192.168.4.0 0.0.0.255
78
+ deny tcp host 192.168.3.3 192.168.4.0 0.0.0.255 gt 32768
79
+ EOL
80
+ @acl.to_s.should be_aclstr(aclstr)
81
+ end
82
+
83
+ it 'mutches aclstr with remark' do
84
+ rmk = RemarkAce.new ' this is remark!!'
85
+ @acl.add_entry rmk
86
+ aclstr = <<'EOL'
87
+ ip access-list extended test-ext-acl2
88
+ permit udp 192.168.3.0 0.0.0.127 192.168.4.0 0.0.0.255
89
+ deny tcp host 192.168.3.3 192.168.4.0 0.0.0.255 gt 32768
90
+ remark this is remark!!
91
+ EOL
92
+ @acl.to_s.should be_aclstr(aclstr)
93
+ end
94
+
95
+ end
96
+
97
+ describe '#find_aces_contains' do
98
+ # for extended ace, it is same as named/numbered ace.
99
+ # so that, tests only named-extended-ace
100
+ # and omit numbered-extended-acl
101
+ before(:all) do
102
+ @acl = NamedExtAcl.new 'test-ext-acl2'
103
+ @acl.add_entry_by_params(
104
+ action: 'permit',
105
+ protocol: 'udp',
106
+ src: { ipaddr: '192.168.3.3', wildcard: '0.0.0.127' },
107
+ dst: { ipaddr: '192.168.4.4', wildcard: '0.0.0.255' }
108
+ )
109
+ @acl.add_entry_by_params(
110
+ action: 'deny',
111
+ protocol: 'tcp',
112
+ src: { ipaddr: '192.168.10.3', wildcard: '0.0.0.0' },
113
+ dst: {
114
+ ipaddr: '192.168.4.4', wildcard: '0.0.0.255', operator: 'gt',
115
+ port: AceUdpProtoSpec.new(32_768)
116
+ }
117
+ )
118
+ @acl.add_entry_by_params(
119
+ action: 'deny',
120
+ protocol: 'ip',
121
+ src: { ipaddr: '0.0.0.0', wildcard: '255.255.255.255' },
122
+ dst: { ipaddr: '10.0.0.0', wildcard: '0.0.0.255' }
123
+ )
124
+ end
125
+
126
+ it 'should be match 2nd entry' do
127
+ ace = @acl.find_aces_contains(
128
+ protocol: 'tcp',
129
+ src_operator: :eq, src_ip: '192.168.10.3', src_port: 64_332,
130
+ dst_operator: :eq, dst_ip: '192.168.4.5', dst_port: 32_889
131
+ )
132
+ ace.to_s.should be_aclstr(
133
+ 'deny tcp host 192.168.10.3 192.168.4.0 0.0.0.255 gt 32768'
134
+ )
135
+ end
136
+
137
+ it 'should be last entry' do
138
+ ace = @acl.find_aces_contains(
139
+ protocol: 'udp',
140
+ src_operator: :eq, src_ip: '192.168.10.3', src_port: 64_332,
141
+ dst_operator: :eq, dst_ip: '10.0.0.3', dst_port: 33_890
142
+ )
143
+ ace.to_s.should be_aclstr('deny ip any 10.0.0.0 0.0.0.255')
144
+ end
145
+
146
+ it 'should be nil if not found match entry' do
147
+ @acl.find_aces_contains(
148
+ protocol: 'udp',
149
+ src_operator: :eq, src_ip: '192.168.10.3', src_port: 62_223,
150
+ dst_operator: :eq, dst_ip: '11.0.0.3', dst_port: 33_333
151
+ ).should be_nil
152
+ end
153
+ end
154
+ end
155
+
156
+ describe NumberedAcl do
157
+ describe '#initialize' do
158
+ it 'should be error with acl no-integer-acl-number' do
159
+ lambda do
160
+ @acl = NumberedAcl.new('a70')
161
+ end.should raise_error(AclArgumentError)
162
+ end
163
+ it 'should be error with invalid number' do
164
+ lambda do
165
+ @acl = NumberedAcl.new(33.3)
166
+ end.should raise_error(AclArgumentError)
167
+ end
168
+ end
169
+ end
170
+
171
+ describe NumberedExtAcl do
172
+ describe '#add_entry' do
173
+ before(:all) do
174
+ @acl = NumberedExtAcl.new 102
175
+ end
176
+
177
+ it 'should be zero when initialized' do
178
+ @acl.size.should be_zero
179
+ @acl.named_acl?.should be_false
180
+ @acl.numbered_acl?.should be_true
181
+ end
182
+
183
+ it 'should be size 1 and matches aclstr when added a acl entry' do
184
+ ea = ExtendedAce.new(
185
+ action: 'permit',
186
+ protocol: 'udp',
187
+ src: {
188
+ ipaddr: '192.168.3.3',
189
+ wildcard: '0.0.0.127'
190
+ },
191
+ dst: {
192
+ ipaddr: '192.168.4.4',
193
+ wildcard: '0.0.0.255'
194
+ }
195
+ )
196
+ @acl.add_entry ea
197
+ @acl.size.should eq 1
198
+ aclstr = <<'EOL'
199
+ access-list 102 permit udp 192.168.3.0 0.0.0.127 192.168.4.0 0.0.0.255
200
+ EOL
201
+ @acl.to_s.should be_aclstr(aclstr)
202
+ end
203
+ end
204
+
205
+ describe '#add_entry_by_params' do
206
+ before(:all) do
207
+ @acl = NumberedExtAcl.new 104
208
+ @acl.add_entry_by_params(
209
+ action: 'permit',
210
+ protocol: 'udp',
211
+ src: {
212
+ ipaddr: '192.168.3.3',
213
+ wildcard: '0.0.0.127'
214
+ },
215
+ dst: {
216
+ ipaddr: '192.168.4.4',
217
+ wildcard: '0.0.0.255'
218
+ }
219
+ )
220
+ @acl.add_entry_by_params(
221
+ action: 'deny',
222
+ protocol: 'tcp',
223
+ src: {
224
+ ipaddr: '192.168.3.3',
225
+ wildcard: '0.0.0.0'
226
+ },
227
+ dst: {
228
+ ipaddr: '192.168.4.4',
229
+ wildcard: '0.0.0.255',
230
+ operator: 'gt',
231
+ port: AceUdpProtoSpec.new(32_768)
232
+ }
233
+ )
234
+ end
235
+
236
+ it 'should be size 2' do
237
+ @acl.size.should eq 2
238
+ end
239
+
240
+ it 'mutches aclstr' do
241
+ aclstr = <<'EOL'
242
+ access-list 104 permit udp 192.168.3.0 0.0.0.127 192.168.4.0 0.0.0.255
243
+ access-list 104 deny tcp host 192.168.3.3 192.168.4.0 0.0.0.255 gt 32768
244
+ EOL
245
+ @acl.to_s.should be_aclstr(aclstr)
246
+ end
247
+
248
+ it 'mutches aclstr with remark' do
249
+ rmk = RemarkAce.new ' this is remark!!'
250
+ @acl.add_entry rmk
251
+ aclstr = <<'EOL'
252
+ access-list 104 permit udp 192.168.3.0 0.0.0.127 192.168.4.0 0.0.0.255
253
+ access-list 104 deny tcp host 192.168.3.3 192.168.4.0 0.0.0.255 gt 32768
254
+ access-list 104 remark this is remark!!
255
+ EOL
256
+ @acl.to_s.should be_aclstr(aclstr)
257
+ end
258
+ end
259
+ end
260
+
261
+ ### Local variables:
262
+ ### mode: Ruby
263
+ ### coding: utf-8-unix
264
+ ### indent-tabs-mode: nil
265
+ ### End: