cisco_acl_intp 0.0.1

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 (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +13 -0
  5. data/.travis.yml +3 -0
  6. data/.yardopts +4 -0
  7. data/Gemfile +19 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +132 -0
  10. data/Rakefile +78 -0
  11. data/acl_examples/err-acl.txt +49 -0
  12. data/acl_examples/named-ext-acl.txt +12 -0
  13. data/acl_examples/named-std-acl.txt +6 -0
  14. data/acl_examples/numd-acl.txt +21 -0
  15. data/cisco_acl_intp.gemspec +31 -0
  16. data/lib/cisco_acl_intp/ace.rb +432 -0
  17. data/lib/cisco_acl_intp/ace_ip.rb +136 -0
  18. data/lib/cisco_acl_intp/ace_other_qualifiers.rb +102 -0
  19. data/lib/cisco_acl_intp/ace_port.rb +146 -0
  20. data/lib/cisco_acl_intp/ace_proto.rb +319 -0
  21. data/lib/cisco_acl_intp/ace_srcdst.rb +114 -0
  22. data/lib/cisco_acl_intp/ace_tcp_flags.rb +65 -0
  23. data/lib/cisco_acl_intp/acl.rb +272 -0
  24. data/lib/cisco_acl_intp/acl_base.rb +111 -0
  25. data/lib/cisco_acl_intp/parser.rb +3509 -0
  26. data/lib/cisco_acl_intp/parser.ry +1397 -0
  27. data/lib/cisco_acl_intp/scanner.rb +176 -0
  28. data/lib/cisco_acl_intp/scanner_special_token_handler.rb +66 -0
  29. data/lib/cisco_acl_intp/version.rb +5 -0
  30. data/lib/cisco_acl_intp.rb +9 -0
  31. data/spec/cisco_acl_intp/ace_ip_spec.rb +111 -0
  32. data/spec/cisco_acl_intp/ace_other_qualifier_spec.rb +63 -0
  33. data/spec/cisco_acl_intp/ace_port_spec.rb +214 -0
  34. data/spec/cisco_acl_intp/ace_proto_spec.rb +200 -0
  35. data/spec/cisco_acl_intp/ace_spec.rb +605 -0
  36. data/spec/cisco_acl_intp/ace_srcdst_spec.rb +296 -0
  37. data/spec/cisco_acl_intp/ace_tcp_flags_spec.rb +38 -0
  38. data/spec/cisco_acl_intp/acl_spec.rb +523 -0
  39. data/spec/cisco_acl_intp/cisco_acl_intp_spec.rb +7 -0
  40. data/spec/cisco_acl_intp/parser_spec.rb +53 -0
  41. data/spec/cisco_acl_intp/scanner_spec.rb +122 -0
  42. data/spec/conf/extacl_objgrp_token_seq.yml +36 -0
  43. data/spec/conf/extacl_token_seq.yml +88 -0
  44. data/spec/conf/extended_acl.yml +226 -0
  45. data/spec/conf/scanner_spec_data.yml +120 -0
  46. data/spec/conf/single_tokens.yml +235 -0
  47. data/spec/conf/stdacl_token_seq.yml +8 -0
  48. data/spec/conf/tokens1.yml +158 -0
  49. data/spec/conf/tokens2.yml +206 -0
  50. data/spec/parser_fullfill_patterns.rb +145 -0
  51. data/spec/spec_helper.rb +54 -0
  52. data/tools/check_acl.rb +48 -0
  53. metadata +159 -0
@@ -0,0 +1,176 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'strscan'
3
+ require 'cisco_acl_intp/scanner_special_token_handler'
4
+
5
+ module CiscoAclIntp
6
+ # Lexical analyzer (Scanner)
7
+ class Scanner
8
+ # include special tokens data and its handlers
9
+ include SpecialTokenHandler
10
+
11
+ # Constructor
12
+ # @return [Scanner]
13
+ def initialize
14
+ @arg_tokens = gen_arg_token_lists
15
+ end
16
+
17
+ # Scan ACL from file to parse
18
+ # @param [File] file File name
19
+ # @return [Array] Scanned tokens array (Queue)
20
+ def scan_file(file)
21
+ queue = []
22
+ file.each_line do |each|
23
+ queue.concat(scan_one_line(each))
24
+ end
25
+ queue.push [false, 'EOF']
26
+ end
27
+
28
+ # Scan ACL from variable
29
+ # @param [String] str Access list string
30
+ # @return [Array] Scanned tokens array (Queue)
31
+ def scan_line(str)
32
+ queue = []
33
+ str.split(/$/).each do |each|
34
+ each.chomp!
35
+ # add word separator at end of line
36
+ each.concat(' ')
37
+ queue.concat(scan_one_line(each))
38
+ end
39
+ queue.push [false, 'EOF']
40
+ end
41
+
42
+ # Scan ACL
43
+ # @param [String] line Access list string
44
+ # @return [Array] Scanned tokens array (Queue)
45
+ def scan_one_line(line)
46
+ run_scanning(line)
47
+ end
48
+
49
+ private
50
+
51
+ # Scan a line
52
+ # @param [String] line ACL String
53
+ # @param [Array] queue Queue
54
+ # @return [Array] Scanned tokens array (Queue)
55
+ def run_scanning(line, queue = [])
56
+ ss = StringScanner.new(line)
57
+ until ss.eos?
58
+ case
59
+ when scan_match_arg_tokens(ss, queue)
60
+ when scan_match_acl_header(ss, queue)
61
+ when scan_match_ipaddr(ss, queue)
62
+ else scan_match_common(ss, queue)
63
+ end
64
+ end
65
+ queue.push [:EOS, nil] # Add end-of-string
66
+ end
67
+
68
+ # Numbered ACL header checker
69
+ # @param [Integer] aclnum ACL number
70
+ # @return [Array] Token list
71
+ def check_numd_acl_type(aclnum)
72
+ if (1..99).include?(aclnum) || (1300..1999).include?(aclnum)
73
+ [:NUMD_STD_ACL, aclnum]
74
+ elsif (100..199).include?(aclnum) || (2000..2699).include?(aclnum)
75
+ [:NUMD_EXT_ACL, aclnum]
76
+ else
77
+ [:UNKNOWN, "access-list #{aclnum}"]
78
+ end
79
+ end
80
+
81
+ # Scanner of acl header
82
+ # @param [StringScanner] ss Scanned ACL line
83
+ # @param [Array] queue Queue
84
+ # @return [Boolean] if line matched acl header
85
+ def scan_match_acl_header(ss, queue)
86
+ case
87
+ when ss.scan(/\s*!.*$/), ss.scan(/\s*#.*$/)
88
+ ## "!/# comment" and whitespace line, NO-OP
89
+ when ss.scan(/\s+/), ss.scan(/\A\s*\Z/)
90
+ ## whitespace, NO-OP
91
+ # queue.push [:WHITESPACE, ""] # for debug
92
+ when ss.scan(/(?:access-list)\s+(\d+)\s/)
93
+ ## Numbered ACL Header
94
+ ## numbered acl has no difference
95
+ ## in format between Standard and Extended...
96
+ queue.push check_numd_acl_type(ss[1].to_i)
97
+ when ss.scan(/(ip\s+access\-list)\s/)
98
+ ## Named ACL Header
99
+ queue.push [:NAMED_ACL, ss[1]]
100
+ end
101
+ ss.matched?
102
+ end
103
+
104
+ # Scanner of IP address
105
+ # @param [StringScanner] ss Scanned ACL line
106
+ # @param [Array] queue Queue
107
+ # @return [Boolean] if line matched IP address
108
+ def scan_match_ipaddr(ss, queue)
109
+ case
110
+ when ss.scan(/(\d+\.\d+\.\d+\.\d+)\s/)
111
+ ## IP Address
112
+ queue.push [:IPV4_ADDR, ss[1]]
113
+ when ss.scan(/(\d+\.\d+\.\d+\.\d+)(\/)(\d+)\s/)
114
+ ## IP Address of 'ip/mask' notation
115
+ queue.push [:IPV4_ADDR, ss[1]]
116
+ queue.push ['/', ss[2]]
117
+ queue.push [:NUMBER, ss[3].to_i]
118
+ end
119
+ ss.matched?
120
+ end
121
+
122
+ # Scanner of common tokens
123
+ # @param [StringScanner] ss Scanned ACL line
124
+ # @param [Array] queue Queue
125
+ # @return [Boolean] if line matched tokens
126
+ def scan_match_common(ss, queue)
127
+ case
128
+ when ss.scan(/(\d+)\s/)
129
+ ## Number
130
+ queue.push [:NUMBER, ss[1].to_i]
131
+ when ss.scan(/([\+\-]?#{STR_REGEXP})/)
132
+ ## Tokens (echo back)
133
+ ## defined in module SpecialTokenHandler
134
+ ## plus/minus used in tcp flag token e.g. +syn -ack
135
+ queue.push token_list(ss[1])
136
+ else
137
+ ## do not match any?
138
+ ## then scanned whole line and
139
+ ## put in queue as unknown.
140
+ ss.scan(/(.*)$/) # match all
141
+ queue.push [:UNKNOWN, ss[1]]
142
+ end
143
+ ss.matched?
144
+ end
145
+
146
+ # Scanner of special tokens
147
+ # @param [StringScanner] ss Scanned ACL line
148
+ # @param [Array] queue Queue
149
+ # @return [Boolean] if line matched tokens
150
+ def scan_match_arg_tokens(ss, queue)
151
+ @arg_tokens.each do |(str, length)|
152
+ if ss.scan(/#{str}/)
153
+ (1...length).each do |idx|
154
+ queue.push token_list(ss[idx])
155
+ end
156
+ queue.push [:STRING, ss[length]] # last element
157
+ break
158
+ end
159
+ end
160
+ ss.matched?
161
+ end
162
+
163
+ # Generate echo-backed token array
164
+ # @param [String] token Token
165
+ # @return [Array] Token array for scanner queue
166
+ def token_list(token)
167
+ [token, token]
168
+ end
169
+ end # class Scanner
170
+ end # module
171
+
172
+ ### Local variables:
173
+ ### mode: Ruby
174
+ ### coding: utf-8-unix
175
+ ### indent-tabs-mode: nil
176
+ ### End:
@@ -0,0 +1,66 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'strscan'
3
+
4
+ module CiscoAclIntp
5
+ # Data and Handler functions of special tokens
6
+ module SpecialTokenHandler
7
+ # STRING token regexp:
8
+ # first letter is alphabet or digit
9
+ STR_REGEXP = '[a-zA-Z\d]\S*'
10
+
11
+ # Tokens that takes string parameter
12
+ STRING_ARG_TOKENS = [
13
+ ['remark', :leftover],
14
+ ['description', :leftover],
15
+ ['extended', :word],
16
+ ['standard', :word],
17
+ ['dynamic', :word],
18
+ ['log-input', :word],
19
+ ['log', :word],
20
+ ['time-range', :word],
21
+ ['reflect', :word],
22
+ ['evaluate', :word],
23
+ ['object-group', 'network', :word],
24
+ ['object-group', 'service', :word],
25
+ ['object-group', :word], # longest match
26
+ ['group-object', :word],
27
+ ]
28
+
29
+ # Conversion table of string-tokens
30
+ SYMBOL_TO_REGEXPSTR = {
31
+ word: ['(', STR_REGEXP, ')'].join,
32
+ leftover: '(.*)$'
33
+ }
34
+
35
+ # Convert STRING_ARG_TOKENS to Regexp string
36
+ # @param [Array] set Special tokens set
37
+ # @returns [String] Regexp string
38
+ def convert_tokens_to_regexpstr(set)
39
+ # puts "## set #{set}"
40
+ set.map do |each|
41
+ case each
42
+ when String
43
+ '(' + each + ')'
44
+ when Symbol
45
+ SYMBOL_TO_REGEXPSTR[each]
46
+ end
47
+ end
48
+ end
49
+
50
+ # Generate regexp string list for scanner
51
+ # @return [Array] set of regexp and number of token
52
+ def gen_arg_token_lists
53
+ STRING_ARG_TOKENS.map do |each|
54
+ re_str_list = convert_tokens_to_regexpstr(each)
55
+ # puts "### #{re_str_list}"
56
+ [re_str_list.join('\s+'), each.length]
57
+ end
58
+ end
59
+ end # module SpecialTokenMgr
60
+ end # module CiscoAclIntp
61
+
62
+ ### Local variables:
63
+ ### mode: Ruby
64
+ ### coding: utf-8-unix
65
+ ### indent-tabs-mode: nil
66
+ ### End:
@@ -0,0 +1,5 @@
1
+ # CiscoAclIntp Module, version definition
2
+ module CiscoAclIntp
3
+ # Version number
4
+ VERSION = '0.0.1'
5
+ end
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'cisco_acl_intp/acl'
3
+ require 'cisco_acl_intp/parser'
4
+ require 'cisco_acl_intp/version'
5
+
6
+ # Cisco Access List Interpreter,
7
+ # define scanner functions and ACL container classes
8
+ module CiscoAclIntp
9
+ end
@@ -0,0 +1,111 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe AceIpSpec do
5
+ describe '#to_s' do
6
+ it 'should be "192.168.15.15 0.0.7.6"' do
7
+ ip = AceIpSpec.new(
8
+ ipaddr: '192.168.15.15',
9
+ wildcard: '0.0.7.6'
10
+ )
11
+ ip.to_s.should be_aclstr('192.168.8.9 0.0.7.6')
12
+ end
13
+
14
+ it 'should be "any"' do
15
+ ip = AceIpSpec.new(
16
+ ipaddr: '0.0.0.0',
17
+ wildcard: '255.255.255.255'
18
+ )
19
+ ip.to_s.should be_aclstr('any')
20
+ end
21
+
22
+ it 'should be "any" with full-bit wildcard mask' do
23
+ ip = AceIpSpec.new(
24
+ ipaddr: '192.168.15.15',
25
+ wildcard: '255.255.255.255'
26
+ )
27
+ ip.to_s.should be_aclstr('any')
28
+ end
29
+
30
+ it 'should be "any" with zero-ip' do
31
+ ip = AceIpSpec.new(
32
+ ipaddr: '0.0.0.0',
33
+ wildcard: '0.0.7.6'
34
+ )
35
+ ip.to_s.should be_aclstr('any')
36
+ end
37
+
38
+ it 'should be "host 192.168.15.15"' do
39
+ ip = AceIpSpec.new(
40
+ ipaddr: '192.168.15.15',
41
+ wildcard: '0.0.0.0'
42
+ )
43
+ ip.to_s.should be_aclstr('host 192.168.15.15')
44
+ end
45
+
46
+ it 'should be "192.168.14.0 0.0.1.255" with netmask /23' do
47
+ ip = AceIpSpec.new(
48
+ ipaddr: '192.168.15.15',
49
+ netmask: 23
50
+ )
51
+ ip.to_s.should be_aclstr('192.168.14.0 0.0.1.255')
52
+ end
53
+
54
+ it 'should be "any" with netmask /0' do
55
+ ip = AceIpSpec.new(
56
+ ipaddr: '192.168.15.15',
57
+ netmask: 0
58
+ )
59
+ ip.to_s.should be_aclstr('any')
60
+ end
61
+
62
+ it 'should be "host 192.168.15.15" with netmask /32' do
63
+ ip = AceIpSpec.new(
64
+ ipaddr: '192.168.15.15',
65
+ netmask: 32
66
+ )
67
+ ip.to_s.should be_aclstr('host 192.168.15.15')
68
+ end
69
+
70
+ it 'should be "host 192.168.15.15" in default' do
71
+ ip = AceIpSpec.new(
72
+ ipaddr: '192.168.15.15'
73
+ )
74
+ ip.to_s.should be_aclstr('host 192.168.15.15')
75
+ end
76
+
77
+ context 'Argument Error Case' do
78
+ it 'raise error without ipaddr' do
79
+ lambda do
80
+ AceIpSpec.new(
81
+ netmask: 32
82
+ )
83
+ end.should raise_error(AclArgumentError)
84
+ end
85
+
86
+ it 'raise error with invalid ipaddr' do
87
+ lambda do
88
+ AceIpSpec.new(
89
+ ipaddr: '192.168.15.256'
90
+ )
91
+ end.should raise_error
92
+ lambda do
93
+ AceIpSpec.new(
94
+ ipaddr: '192.168.250.3.3'
95
+ )
96
+ end.should raise_error
97
+ lambda do
98
+ AceIpSpec.new(
99
+ ipaddr: '192,168.250.3'
100
+ )
101
+ end.should raise_error
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ ### Local variables:
108
+ ### mode: Ruby
109
+ ### coding: utf-8-unix
110
+ ### indent-tabs-mode: nil
111
+ ### End:
@@ -0,0 +1,63 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe AceLogSpec do
5
+ describe '#to_s' do
6
+ it 'should be log without cookie' do
7
+ log = AceLogSpec.new
8
+ log.to_s.should be_aclstr('log')
9
+ end
10
+
11
+ it 'should be log-input without cookie string' do
12
+ log = AceLogSpec.new('', true)
13
+ log.to_s.should be_aclstr('log-input')
14
+ end
15
+
16
+ it 'should be log with cookie' do
17
+ log = AceLogSpec.new('Cookie0123')
18
+ log.to_s.should be_aclstr('log Cookie0123')
19
+ end
20
+
21
+ it 'should be log-input with cookie string' do
22
+ log = AceLogSpec.new('log', true)
23
+ log.to_s.should be_aclstr('log-input log')
24
+ end
25
+ end
26
+ end
27
+
28
+ describe AceRecursiveQualifier do
29
+ describe '#to_s' do
30
+ it 'should be reflect spec string' do
31
+ rcsv = AceRecursiveQualifier.new('established')
32
+ rcsv.to_s.should be_aclstr('reflect established')
33
+ end
34
+
35
+ it 'should be raised error' do
36
+ lambda do
37
+ AceRecursiveQualifier.new('')
38
+ end.should raise_error(AclArgumentError)
39
+ end
40
+ end
41
+ end
42
+
43
+ describe AceOtherQualifierList do
44
+ describe '#to_s' do
45
+ before do
46
+ @oq1 = AceLogSpec.new
47
+ @oq2 = AceRecursiveQualifier.new('iptraffic')
48
+ @list = AceOtherQualifierList.new
49
+ end
50
+
51
+ it 'should be size 0 when empty list'do
52
+ @list.size.should be_zero
53
+ end
54
+
55
+ it 'should count-up size when added AceTcpFlag objects' do
56
+ @list.push @oq1
57
+ @list.size.should eq 1
58
+ @list.push @oq2
59
+ @list.size.should eq 2
60
+ @list.to_s.should be_aclstr('log reflect iptraffic')
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,214 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe AcePortSpec do
5
+ describe '#new' do
6
+ it 'shoud be error with unknown operator' do
7
+ lambda do
8
+ AcePortSpec.new(
9
+ operator: 'equal',
10
+ port: 443
11
+ )
12
+ end.should raise_error(AclArgumentError)
13
+ end
14
+
15
+ it 'should be error with invalid ports' do
16
+ lambda do
17
+ AcePortSpec.new(
18
+ operator: 'range',
19
+ begin_port: 443,
20
+ end_port: 139
21
+ )
22
+ end.should raise_error(AclArgumentError)
23
+ end
24
+ end
25
+
26
+ describe '#to_s' do
27
+ before do
28
+ @p1 = AceTcpProtoSpec.new(number: 22)
29
+ @p2 = AceTcpProtoSpec.new(number: 80)
30
+ end
31
+
32
+ context 'Normal case' do
33
+ it 'should be "eq 22"' do
34
+ p = AcePortSpec.new(
35
+ operator: 'eq', port: @p1
36
+ )
37
+ p.to_s.should be_aclstr('eq 22')
38
+ end
39
+
40
+ it 'should be "lt www"' do
41
+ p = AcePortSpec.new(
42
+ operator: 'lt', port: @p2
43
+ )
44
+ p.to_s.should be_aclstr('lt www')
45
+ end
46
+
47
+ it 'should be "gt www"' do
48
+ p = AcePortSpec.new(
49
+ operator: 'gt', port: @p2
50
+ )
51
+ p.to_s.should be_aclstr('gt www')
52
+ end
53
+
54
+ it 'should be "range 22 www"' do
55
+ p = AcePortSpec.new(
56
+ operator: 'range',
57
+ begin_port: @p1, end_port: @p2
58
+ )
59
+ p.to_s.should be_aclstr('range 22 www')
60
+ end
61
+
62
+ it 'should be empty when any port' do
63
+ p = AcePortSpec.new(
64
+ operator: 'any',
65
+ begin_port: @p1, end_port: @p2
66
+ )
67
+ p.to_s.should be_empty
68
+ end
69
+
70
+ end
71
+ context 'Argument error case' do
72
+ it 'raise error when not specified operator' do
73
+ lambda do
74
+ AcePortSpec.new(
75
+ end_port: @p1
76
+ )
77
+ end.should raise_error(AclArgumentError)
78
+ end
79
+
80
+ it 'raise error when not specified begin_port' do
81
+ lambda do
82
+ AcePortSpec.new(
83
+ operator: 'eq',
84
+ end_port: @p1
85
+ )
86
+ end.should raise_error(AclArgumentError)
87
+ end
88
+
89
+ it 'raise error when wrong port sequence' do
90
+ lambda do
91
+ AcePortSpec.new(
92
+ operator: 'range',
93
+ begin_port: @p2, end_port: @p1
94
+ )
95
+ end.should raise_error(AclArgumentError)
96
+ end
97
+ end
98
+ end
99
+
100
+ describe '#matches?' do
101
+ before do
102
+ @p1 = AceTcpProtoSpec.new(number: 22)
103
+ @p2 = AceTcpProtoSpec.new(number: 32_768)
104
+
105
+ @any = AcePortSpec.new(
106
+ operator: 'any'
107
+ )
108
+ @eq1 = AcePortSpec.new(
109
+ operator: 'eq', begin_port: @p1
110
+ )
111
+ @neq1 = AcePortSpec.new(
112
+ operator: 'neq', port: @p1
113
+ )
114
+ @lt1 = AcePortSpec.new(
115
+ operator: 'lt', port: @p1
116
+ )
117
+ @gt1 = AcePortSpec.new(
118
+ operator: 'gt', port: @p1
119
+ )
120
+ @range = AcePortSpec.new(
121
+ operator: 'range',
122
+ port: @p1, end_port: @p2
123
+ )
124
+ end
125
+
126
+ it 'match any if valid port range' do
127
+ lambda do
128
+ @any.matches?(-1)
129
+ end.should raise_error(AclArgumentError)
130
+ @any.matches?(0).should be_true
131
+ @any.matches?(21).should be_true
132
+ @any.matches?(22).should be_true
133
+ @any.matches?(23).should be_true
134
+ @any.matches?(65_535).should be_true
135
+ lambda do
136
+ @any.matches?(65_536)
137
+ end.should raise_error(AclArgumentError)
138
+ end
139
+
140
+ it 'match correct number by op:eq' do
141
+ lambda do
142
+ @eq1.matches?(-1)
143
+ end.should raise_error(AclArgumentError)
144
+ @eq1.matches?(0).should be_false
145
+ @eq1.matches?(21).should be_false
146
+ @eq1.matches?(22).should be_true
147
+ @eq1.matches?(23).should be_false
148
+ @eq1.matches?(65_535).should be_false
149
+ lambda do
150
+ @eq1.matches?(65_536)
151
+ end.should raise_error(AclArgumentError)
152
+ end
153
+
154
+ it 'match correct number by op:neq' do
155
+ lambda do
156
+ @neq1.matches?(-1)
157
+ end.should raise_error(AclArgumentError)
158
+ @neq1.matches?(0).should be_true
159
+ @neq1.matches?(21).should be_true
160
+ @neq1.matches?(22).should be_false
161
+ @neq1.matches?(23).should be_true
162
+ @neq1.matches?(65_535).should be_true
163
+ lambda do
164
+ @neq1.matches?(65_536)
165
+ end.should raise_error(AclArgumentError)
166
+ end
167
+
168
+ it 'match lower number by op:lt' do
169
+ lambda do
170
+ @lt1.matches?(-1)
171
+ end.should raise_error(AclArgumentError)
172
+ @lt1.matches?(0).should be_true
173
+ @lt1.matches?(21).should be_true
174
+ @lt1.matches?(22).should be_false
175
+ @lt1.matches?(23).should be_false
176
+ @lt1.matches?(65_535).should be_false
177
+ lambda do
178
+ @lt1.matches?(65_536)
179
+ end.should raise_error(AclArgumentError)
180
+ end
181
+
182
+ it 'match lower number by op:gt' do
183
+ lambda do
184
+ @gt1.matches?(-1)
185
+ end.should raise_error(AclArgumentError)
186
+ @gt1.matches?(0).should be_false
187
+ @gt1.matches?(21).should be_false
188
+ @gt1.matches?(22).should be_false
189
+ @gt1.matches?(23).should be_true
190
+ @gt1.matches?(65_535).should be_true
191
+ lambda do
192
+ @gt1.matches?(65_536)
193
+ end.should raise_error(AclArgumentError)
194
+ end
195
+
196
+ it 'match lower number by op:range' do
197
+ lambda do
198
+ @range.matches?(-1)
199
+ end.should raise_error(AclArgumentError)
200
+ @range.matches?(0).should be_false
201
+ @range.matches?(21).should be_false
202
+ @range.matches?(22).should be_true
203
+ @range.matches?(23).should be_true
204
+ @range.matches?(32_767).should be_true
205
+ @range.matches?(32_768).should be_true
206
+ @range.matches?(32_769).should be_false
207
+ @range.matches?(65_535).should be_false
208
+ lambda do
209
+ @range.matches?(65_536)
210
+ end.should raise_error(AclArgumentError)
211
+ end
212
+
213
+ end
214
+ end