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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.rubocop.yml +13 -0
- data/.travis.yml +3 -0
- data/.yardopts +4 -0
- data/Gemfile +19 -0
- data/LICENSE.txt +22 -0
- data/README.md +132 -0
- data/Rakefile +78 -0
- data/acl_examples/err-acl.txt +49 -0
- data/acl_examples/named-ext-acl.txt +12 -0
- data/acl_examples/named-std-acl.txt +6 -0
- data/acl_examples/numd-acl.txt +21 -0
- data/cisco_acl_intp.gemspec +31 -0
- data/lib/cisco_acl_intp/ace.rb +432 -0
- data/lib/cisco_acl_intp/ace_ip.rb +136 -0
- data/lib/cisco_acl_intp/ace_other_qualifiers.rb +102 -0
- data/lib/cisco_acl_intp/ace_port.rb +146 -0
- data/lib/cisco_acl_intp/ace_proto.rb +319 -0
- data/lib/cisco_acl_intp/ace_srcdst.rb +114 -0
- data/lib/cisco_acl_intp/ace_tcp_flags.rb +65 -0
- data/lib/cisco_acl_intp/acl.rb +272 -0
- data/lib/cisco_acl_intp/acl_base.rb +111 -0
- data/lib/cisco_acl_intp/parser.rb +3509 -0
- data/lib/cisco_acl_intp/parser.ry +1397 -0
- data/lib/cisco_acl_intp/scanner.rb +176 -0
- data/lib/cisco_acl_intp/scanner_special_token_handler.rb +66 -0
- data/lib/cisco_acl_intp/version.rb +5 -0
- data/lib/cisco_acl_intp.rb +9 -0
- data/spec/cisco_acl_intp/ace_ip_spec.rb +111 -0
- data/spec/cisco_acl_intp/ace_other_qualifier_spec.rb +63 -0
- data/spec/cisco_acl_intp/ace_port_spec.rb +214 -0
- data/spec/cisco_acl_intp/ace_proto_spec.rb +200 -0
- data/spec/cisco_acl_intp/ace_spec.rb +605 -0
- data/spec/cisco_acl_intp/ace_srcdst_spec.rb +296 -0
- data/spec/cisco_acl_intp/ace_tcp_flags_spec.rb +38 -0
- data/spec/cisco_acl_intp/acl_spec.rb +523 -0
- data/spec/cisco_acl_intp/cisco_acl_intp_spec.rb +7 -0
- data/spec/cisco_acl_intp/parser_spec.rb +53 -0
- data/spec/cisco_acl_intp/scanner_spec.rb +122 -0
- data/spec/conf/extacl_objgrp_token_seq.yml +36 -0
- data/spec/conf/extacl_token_seq.yml +88 -0
- data/spec/conf/extended_acl.yml +226 -0
- data/spec/conf/scanner_spec_data.yml +120 -0
- data/spec/conf/single_tokens.yml +235 -0
- data/spec/conf/stdacl_token_seq.yml +8 -0
- data/spec/conf/tokens1.yml +158 -0
- data/spec/conf/tokens2.yml +206 -0
- data/spec/parser_fullfill_patterns.rb +145 -0
- data/spec/spec_helper.rb +54 -0
- data/tools/check_acl.rb +48 -0
- metadata +159 -0
@@ -0,0 +1,146 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'cisco_acl_intp/ace_proto'
|
4
|
+
|
5
|
+
module CiscoAclIntp
|
6
|
+
# TCP/UDP port number and operator container
|
7
|
+
class AcePortSpec < AclContainerBase
|
8
|
+
include AceTcpUdpPortValidation
|
9
|
+
|
10
|
+
# @param [String] value Operator of port (eq/neq/gt/lt/range)
|
11
|
+
# @return [String]
|
12
|
+
attr_accessor :operator
|
13
|
+
|
14
|
+
# @param [AceProtoSpecBase] value Port No. (single/lower)
|
15
|
+
# @return [AceProtoSpecBase]
|
16
|
+
attr_accessor :begin_port
|
17
|
+
|
18
|
+
# alias for unary operator
|
19
|
+
alias_method :port, :begin_port
|
20
|
+
|
21
|
+
# @param [AceProtoSpecBase] value Port No. (higher)
|
22
|
+
# @return [AceProtoSpecBase]
|
23
|
+
attr_accessor :end_port
|
24
|
+
|
25
|
+
# Constructor
|
26
|
+
# @param [Hash] opts Options
|
27
|
+
# @option opts [String] :operator Port operator, eq/neq/lt/gt/range
|
28
|
+
# @option opts [AceProtoSpecBase] :port Port No. (single/lower)
|
29
|
+
# (same as :begin_port, alias for unary operator)
|
30
|
+
# @option opts [AceProtoSpecBase] :begin_port Port No. (single/lower)
|
31
|
+
# @option opts [AceProtoSpecBase] :end_port Port No. (higher)
|
32
|
+
# @raise [AclArgumentError]
|
33
|
+
# @return [AcePortSpec]
|
34
|
+
# @note '@begin_port' and '@end_port' should managed
|
35
|
+
# with port number and protocol name.
|
36
|
+
# it need the number when operate/compare protocol number,
|
37
|
+
# and need the name when stringize the object.
|
38
|
+
def initialize(opts)
|
39
|
+
## TBD
|
40
|
+
## in ACL, can "eq/neq" receive port list?
|
41
|
+
## IOS15 later?
|
42
|
+
|
43
|
+
if opts.key?(:operator)
|
44
|
+
validate_operators(opts)
|
45
|
+
else
|
46
|
+
fail AclArgumentError, 'Not specified port operator'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# @param [AcePortSpec] other RHS Object
|
51
|
+
# @return [Boolean]
|
52
|
+
def ==(other)
|
53
|
+
@operator == other.operator &&
|
54
|
+
@begin_port == other.begin_port &&
|
55
|
+
@end_port == other.end_port
|
56
|
+
end
|
57
|
+
|
58
|
+
# Generate string for Cisco IOS access list
|
59
|
+
# @return [String]
|
60
|
+
def to_s
|
61
|
+
if @operator == 'any'
|
62
|
+
''
|
63
|
+
else
|
64
|
+
c_pp(sprintf('%s %s %s', @operator, @begin_port, @end_port))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Table of port match operator and operations
|
69
|
+
PORT_OPERATE = {
|
70
|
+
'any' => proc do |begin_port, end_port, port|
|
71
|
+
true
|
72
|
+
end,
|
73
|
+
'eq' => proc do |begin_port, end_port, port|
|
74
|
+
begin_port == port
|
75
|
+
end,
|
76
|
+
'neq' => proc do |begin_port, end_port, port|
|
77
|
+
begin_port != port
|
78
|
+
end,
|
79
|
+
'gt' => proc do |begin_port, end_port, port|
|
80
|
+
begin_port < port
|
81
|
+
end,
|
82
|
+
'lt' => proc do |begin_port, end_port, port|
|
83
|
+
begin_port > port
|
84
|
+
end,
|
85
|
+
'range' => proc do |begin_port, end_port, port|
|
86
|
+
(begin_port .. end_port).include?(port)
|
87
|
+
end,
|
88
|
+
}
|
89
|
+
|
90
|
+
# Check the port number matches this?
|
91
|
+
# @param [Integer] port TCP/UDP Port number
|
92
|
+
# @raise [AclArgumentError]
|
93
|
+
# @return [Boolean]
|
94
|
+
def matches?(port)
|
95
|
+
unless valid_range?(port)
|
96
|
+
fail AclArgumentError, "Port out of range: #{ port }"
|
97
|
+
end
|
98
|
+
# @operator was validated in constructor
|
99
|
+
PORT_OPERATE[@operator].call(@begin_port.to_i, @end_port.to_i, port)
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
# Set instance variables
|
105
|
+
# @param [Hash] opts Options of constructor
|
106
|
+
def define_operator_and_ports(opts)
|
107
|
+
@operator = opts[:operator] || 'any'
|
108
|
+
@begin_port = opts[:port] || opts[:begin_port] || nil
|
109
|
+
@end_port = opts[:end_port] || nil
|
110
|
+
end
|
111
|
+
|
112
|
+
# Varidate options
|
113
|
+
# @param [Hash] opts Options of constructor
|
114
|
+
# @raise [AclArgumentError]
|
115
|
+
def validate_operators(opts)
|
116
|
+
define_operator_and_ports(opts)
|
117
|
+
|
118
|
+
if !PORT_OPERATE.key?(@operator)
|
119
|
+
fail AclArgumentError, "Unknown operator: #{@operator}"
|
120
|
+
elsif !valid_operator_and_port?
|
121
|
+
fail AclArgumentError, 'Invalid port or ports sequence'
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Varidate combination operator and port number
|
126
|
+
# @return [Boolean]
|
127
|
+
def valid_operator_and_port?
|
128
|
+
case @operator
|
129
|
+
when 'any'
|
130
|
+
true
|
131
|
+
when 'range'
|
132
|
+
@begin_port &&
|
133
|
+
@end_port &&
|
134
|
+
@begin_port < @end_port
|
135
|
+
else
|
136
|
+
@begin_port
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end # module
|
141
|
+
|
142
|
+
### Local variables:
|
143
|
+
### mode: Ruby
|
144
|
+
### coding: utf-8-unix
|
145
|
+
### indent-tabs-mode: nil
|
146
|
+
### End:
|
@@ -0,0 +1,319 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'cisco_acl_intp/acl_base'
|
4
|
+
|
5
|
+
module CiscoAclIntp
|
6
|
+
# IP/TCP/UDP port number and protocol name container base
|
7
|
+
class AceProtoSpecBase < AclContainerBase
|
8
|
+
include Comparable
|
9
|
+
|
10
|
+
# @param [String] value Protocol name,
|
11
|
+
# it is literal used in Cisco IOS access-list
|
12
|
+
# @return [String]
|
13
|
+
attr_accessor :name
|
14
|
+
|
15
|
+
# @param [Integer] value Protocol/Port number
|
16
|
+
# @return [Integer]
|
17
|
+
attr_accessor :number
|
18
|
+
|
19
|
+
# @return [String, Symbol] L3/L4 protocol type
|
20
|
+
attr_reader :protocol
|
21
|
+
|
22
|
+
# Constructor
|
23
|
+
# @param [Hash] opts Options
|
24
|
+
# @option opts [String] :name Protocol name
|
25
|
+
# @option opts [Integer] :number Protocol/Port number
|
26
|
+
# @raise [AclArgumentError]
|
27
|
+
# @return [AceProtoSpecBase]
|
28
|
+
# @abstract
|
29
|
+
# @note Variable '@protocol'
|
30
|
+
# should be assigned in inherited class constructor,
|
31
|
+
# at first. (before call super class constructor)
|
32
|
+
def initialize(opts)
|
33
|
+
define_values(opts)
|
34
|
+
|
35
|
+
# arguments |
|
36
|
+
# :name :number | @name @number
|
37
|
+
# --------------+----------------------------
|
38
|
+
# set set | use arg use arg (*1)
|
39
|
+
# none | use arg nil (*2)
|
40
|
+
# none set | nil use arg (*3)
|
41
|
+
# none | [ raise error ] (*4)
|
42
|
+
#
|
43
|
+
# (*1) args are set in parser (assume correct args)
|
44
|
+
# check if :name and number_to_name(:number) are same.
|
45
|
+
# (*2) args are set in parser (assume correct args)
|
46
|
+
# (*3)
|
47
|
+
|
48
|
+
validate_protocol_number
|
49
|
+
validate_protocol_name_and_number
|
50
|
+
end
|
51
|
+
|
52
|
+
# Check the port number in valid range of port number
|
53
|
+
# @abstract
|
54
|
+
# @param [Integer] port IP/TCP/UDP port/protocol number
|
55
|
+
# @return [Boolean]
|
56
|
+
def valid_range?(port)
|
57
|
+
port.integer?
|
58
|
+
end
|
59
|
+
|
60
|
+
# Generate string for Cisco IOS access list
|
61
|
+
# @return [String]
|
62
|
+
def to_s
|
63
|
+
@name || number_to_name(@number)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Convert protocol/port number to string (its name)
|
67
|
+
# @abstract
|
68
|
+
# @param [Integer] number Protocol/Port number
|
69
|
+
# @return [String] Name of protocol/port number.
|
70
|
+
# If does not match the number in IOS proto/port literal,
|
71
|
+
# return number.to_s string
|
72
|
+
def number_to_name(number)
|
73
|
+
number.to_s
|
74
|
+
end
|
75
|
+
|
76
|
+
# @return [Integer] Protocol/Port number
|
77
|
+
def to_i
|
78
|
+
@number
|
79
|
+
end
|
80
|
+
|
81
|
+
# Compare by port number
|
82
|
+
# @note Using "Comparable" module, '==' operator is defined by
|
83
|
+
# '<=>' operator. But '==' is overriden to compare instance
|
84
|
+
# equivalence instead of port number comparison.
|
85
|
+
# @param [AceProtoSpecBase] other Compared instance
|
86
|
+
# @return [Fixnum] Compare with protocol/port number
|
87
|
+
def <=>(other)
|
88
|
+
@number <=> other.to_i
|
89
|
+
end
|
90
|
+
|
91
|
+
# @return [Boolean] Compare with protocol/port number
|
92
|
+
def ==(other)
|
93
|
+
@protocol == other.protocol &&
|
94
|
+
@name == other.name &&
|
95
|
+
@number == other.number
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
# Set instance variables with ip/default-netmask
|
101
|
+
# @param [Hash] opts Options of constructor
|
102
|
+
def define_values(opts)
|
103
|
+
@protocol = nil unless @protocol
|
104
|
+
@name = opts[:name] || nil
|
105
|
+
@number = opts[:number] || nil
|
106
|
+
end
|
107
|
+
|
108
|
+
# Validate protocol number
|
109
|
+
# @raise [AclArgumentError]
|
110
|
+
def validate_protocol_number
|
111
|
+
if @number && (!valid_range?(@number))
|
112
|
+
# Pattern (*1)(*3)
|
113
|
+
fail AclArgumentError, "Wrong protocol number: #{ @number }"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Validate protocol name and number (combination)
|
118
|
+
# @raise [AclArgumentError]
|
119
|
+
def validate_protocol_name_and_number
|
120
|
+
if @name && @number
|
121
|
+
# Case (*1): check parameter match
|
122
|
+
# Do not overwrite name by number converted name,
|
123
|
+
# because args are configured in parser,
|
124
|
+
# that name mismatch looks like a bug.
|
125
|
+
if @name != number_to_name(@number)
|
126
|
+
fail AclArgumentError, 'Specified protocol name and number not match'
|
127
|
+
end
|
128
|
+
elsif (!@name) && (!@number)
|
129
|
+
# Case (*4):
|
130
|
+
fail AclArgumentError, 'Not specified protocol name and number'
|
131
|
+
else
|
132
|
+
## condition: @name && (!@number)
|
133
|
+
# Case (*2): no-op
|
134
|
+
# Usually, args are configured in parser.
|
135
|
+
# If not specified the number, it is empty explicitly
|
136
|
+
## condition: (!@name) && @number
|
137
|
+
# Case (*3): no-op
|
138
|
+
# @name is used to stringify, convert @number to name in to_s
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# IP protocol number/name container
|
144
|
+
class AceIpProtoSpec < AceProtoSpecBase
|
145
|
+
# Minimum port/protocol number
|
146
|
+
MIN_PORT = 0
|
147
|
+
# Maximum port/protocol number
|
148
|
+
MAX_PORT = 255
|
149
|
+
|
150
|
+
# convert table of tcp port/name
|
151
|
+
IP_PROTO_NAME_TABLE = {
|
152
|
+
51 => 'ahp',
|
153
|
+
88 => 'eigrp',
|
154
|
+
50 => 'esp',
|
155
|
+
47 => 'gre',
|
156
|
+
2 => 'igmp',
|
157
|
+
9 => 'igrp',
|
158
|
+
94 => 'ipinip',
|
159
|
+
4 => 'nos',
|
160
|
+
89 => 'ospf',
|
161
|
+
108 => 'pcp',
|
162
|
+
103 => 'pim',
|
163
|
+
1 => 'icmp',
|
164
|
+
6 => 'tcp',
|
165
|
+
17 => 'udp'
|
166
|
+
}
|
167
|
+
|
168
|
+
# Constructor
|
169
|
+
# @param [Hash] opts Options of {AceProtoSpecBase}
|
170
|
+
# @return [AceIpProtoSpec]
|
171
|
+
def initialize(opts)
|
172
|
+
@protocol = :ip
|
173
|
+
super
|
174
|
+
end
|
175
|
+
|
176
|
+
# Check the port number in valid range of port number
|
177
|
+
# @param [Integer] port IP/TCP/UDP port/protocol number
|
178
|
+
# @return [Boolean]
|
179
|
+
def valid_range?(port)
|
180
|
+
(MIN_PORT .. MAX_PORT).include?(port.to_i)
|
181
|
+
end
|
182
|
+
|
183
|
+
# Convert protocol/port number to string (its name)
|
184
|
+
# @param [Integer] number Protocol/Port number
|
185
|
+
# @return [String] Name of protocol/port number.
|
186
|
+
def number_to_name(number)
|
187
|
+
IP_PROTO_NAME_TABLE[number] || number.to_s
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
# TCP/UDP port range validation feature
|
192
|
+
module AceTcpUdpPortValidation
|
193
|
+
# Minimum port/protocol number
|
194
|
+
MIN_PORT = 0
|
195
|
+
# Maximum port/protocol number
|
196
|
+
MAX_PORT = 65_535
|
197
|
+
|
198
|
+
# Check the port number in valid range of port number
|
199
|
+
# @param [Integer] port TCP/UDP port/protocol number
|
200
|
+
# @return [Boolean]
|
201
|
+
def valid_range?(port)
|
202
|
+
(MIN_PORT .. MAX_PORT).include?(port.to_i)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# TCP protocol number/name container
|
207
|
+
class AceTcpProtoSpec < AceProtoSpecBase
|
208
|
+
include AceTcpUdpPortValidation
|
209
|
+
|
210
|
+
# convert table of tcp port/name
|
211
|
+
TCP_PORT_NAME_TABLE = {
|
212
|
+
179 => 'bgp',
|
213
|
+
19 => 'chargen',
|
214
|
+
514 => 'cmd',
|
215
|
+
13 => 'daytime',
|
216
|
+
9 => 'discard',
|
217
|
+
53 => 'domain',
|
218
|
+
3949 => 'drip',
|
219
|
+
7 => 'echo',
|
220
|
+
512 => 'exec',
|
221
|
+
79 => 'finger',
|
222
|
+
21 => 'ftp',
|
223
|
+
20 => 'ftp-data',
|
224
|
+
70 => 'gopher',
|
225
|
+
101 => 'hostname',
|
226
|
+
113 => 'ident',
|
227
|
+
194 => 'irc',
|
228
|
+
543 => 'klogin',
|
229
|
+
544 => 'kshell',
|
230
|
+
513 => 'login',
|
231
|
+
515 => 'lpd',
|
232
|
+
119 => 'nntp',
|
233
|
+
496 => 'pim-auto-rp',
|
234
|
+
109 => 'pop2',
|
235
|
+
110 => 'pop3',
|
236
|
+
25 => 'smtp',
|
237
|
+
111 => 'sunrpc',
|
238
|
+
49 => 'tacacs',
|
239
|
+
517 => 'talk',
|
240
|
+
23 => 'telnet',
|
241
|
+
37 => 'time',
|
242
|
+
540 => 'uucp',
|
243
|
+
43 => 'whois',
|
244
|
+
80 => 'www'
|
245
|
+
}
|
246
|
+
|
247
|
+
# Constructor
|
248
|
+
# @param [Hash] opts Options of {AceProtoSpecBase}
|
249
|
+
# @return [AceTcpProtoSpec]
|
250
|
+
def initialize(opts)
|
251
|
+
@protocol = :tcp
|
252
|
+
super
|
253
|
+
end
|
254
|
+
|
255
|
+
# Convert protocol to port number by string (its name)
|
256
|
+
# @param [Integer] number Protocol/Port number
|
257
|
+
# @return [String] Name of protocol/port number.
|
258
|
+
def number_to_name(number)
|
259
|
+
TCP_PORT_NAME_TABLE[number] || number.to_s
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
# UDP protocol number/name container
|
264
|
+
class AceUdpProtoSpec < AceProtoSpecBase
|
265
|
+
include AceTcpUdpPortValidation
|
266
|
+
|
267
|
+
# convert table of UDP port/name
|
268
|
+
UDP_PORT_NAME_TABLE = {
|
269
|
+
512 => 'biff',
|
270
|
+
68 => 'bootpc',
|
271
|
+
67 => 'bootps',
|
272
|
+
9 => 'discard',
|
273
|
+
195 => 'dnsix',
|
274
|
+
53 => 'domain',
|
275
|
+
7 => 'echo',
|
276
|
+
500 => 'isakmp',
|
277
|
+
434 => 'mobile-ip',
|
278
|
+
42 => 'nameserver',
|
279
|
+
138 => 'netbios-dgm',
|
280
|
+
137 => 'netbios-ns',
|
281
|
+
139 => 'netbios-ss',
|
282
|
+
4500 => 'non500-isakmp',
|
283
|
+
123 => 'ntp',
|
284
|
+
496 => 'pim-auto-rp',
|
285
|
+
520 => 'rip',
|
286
|
+
161 => 'snmp',
|
287
|
+
162 => 'snmptrap',
|
288
|
+
111 => 'sunrpc',
|
289
|
+
514 => 'syslog',
|
290
|
+
49 => 'tacacs',
|
291
|
+
517 => 'talk',
|
292
|
+
69 => 'tftp',
|
293
|
+
37 => 'time',
|
294
|
+
513 => 'who',
|
295
|
+
177 => 'xdmcp'
|
296
|
+
}
|
297
|
+
|
298
|
+
# Constructor
|
299
|
+
# @param [Hash] opts Options of {AceProtoSpecBase}
|
300
|
+
# @return [AceUdpProtoSpec]
|
301
|
+
def initialize(opts)
|
302
|
+
@protocol = :udp
|
303
|
+
super
|
304
|
+
end
|
305
|
+
|
306
|
+
# Convert protocol/port number to string (its name)
|
307
|
+
# @param [Integer] number Protocol/Port number
|
308
|
+
# @return [String] Name of protocol/port number.
|
309
|
+
def number_to_name(number)
|
310
|
+
UDP_PORT_NAME_TABLE[number] || number.to_s
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end # module
|
314
|
+
|
315
|
+
### Local variables:
|
316
|
+
### mode: Ruby
|
317
|
+
### coding: utf-8-unix
|
318
|
+
### indent-tabs-mode: nil
|
319
|
+
### End:
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'netaddr'
|
4
|
+
require 'cisco_acl_intp/ace_ip'
|
5
|
+
require 'cisco_acl_intp/ace_port'
|
6
|
+
require 'cisco_acl_intp/ace_other_qualifiers'
|
7
|
+
require 'cisco_acl_intp/ace_tcp_flags'
|
8
|
+
|
9
|
+
module CiscoAclIntp
|
10
|
+
# IP Address and TCP/UDP Port Info
|
11
|
+
class AceSrcDstSpec < AclContainerBase
|
12
|
+
## TBD
|
13
|
+
## Src/Dst takes Network Object Group or IP/wildcard.
|
14
|
+
## object group is not implemented yet.
|
15
|
+
|
16
|
+
# @param [AceIpSpec] value IP address and Wildcard-mask
|
17
|
+
# @return [AceIpSpec]
|
18
|
+
attr_accessor :ip_spec
|
19
|
+
|
20
|
+
# @param [AcePortSpec] value Port number(s) and Operator
|
21
|
+
# @return [AcePortSpec]
|
22
|
+
attr_accessor :port_spec
|
23
|
+
|
24
|
+
# Constructor
|
25
|
+
# @param [Hash] opts Options
|
26
|
+
# @option opts [AceIpSpec] :ip_spec IP address/Mask object
|
27
|
+
# @option opts [String] :ipaddr IP Address (dotted notation)
|
28
|
+
# @option opts [String] :wildcard Wildcard mask
|
29
|
+
# (dotted/bit-flipped notation)
|
30
|
+
# @option opts [AcePortSpec] :port_spec Port/Operator object
|
31
|
+
# @option opts [String] :operator Port operator
|
32
|
+
# @option opts [AceProtoSpecBase] :port port number (single/lower)
|
33
|
+
# (same as :begin_port, alias for unary operator)
|
34
|
+
# @option opts [AceProtoSpecBase] :begin_port port number (single/lower)
|
35
|
+
# @option opts [AceProtoSpecBase] :end_port port number (higher)
|
36
|
+
# @raise [AclArgumentError]
|
37
|
+
# @return [AceSrcDstSpec]
|
38
|
+
# @note When it does not specified port in opts,
|
39
|
+
# (:port_spec or :operator, :begin_port, :end_port)
|
40
|
+
# it assumed with ANY port.
|
41
|
+
def initialize(opts)
|
42
|
+
@ip_spec = define_ipspec(opts)
|
43
|
+
@port_spec = define_portspec(opts)
|
44
|
+
end
|
45
|
+
|
46
|
+
# @param [AceSrcDstSpec] other RHS Object
|
47
|
+
# @return [Boolean]
|
48
|
+
def ==(other)
|
49
|
+
@port_spec == other.port_spec &&
|
50
|
+
@ip_spec == other.ip_spec
|
51
|
+
end
|
52
|
+
|
53
|
+
# Generate string for Cisco IOS access list
|
54
|
+
# @return [String]
|
55
|
+
def to_s
|
56
|
+
sprintf('%s %s', @ip_spec, @port_spec)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Check address and port number matche this object.
|
60
|
+
# @param [String] address IP address (dotted notation)
|
61
|
+
# @param [Integer] port Port No.
|
62
|
+
# @return [Boolean]
|
63
|
+
def matches?(address, port = nil)
|
64
|
+
ip_spec_match = @ip_spec.matches?(address)
|
65
|
+
ip_spec_match && @port_spec.matches?(port) if port
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
# Set instance variables
|
71
|
+
# @param [Hash] opts Options of constructor
|
72
|
+
# @raise [AclArgumentError]
|
73
|
+
# @return [AceIpSpec] IP address/Mask object
|
74
|
+
# @see #initialize
|
75
|
+
def define_ipspec(opts)
|
76
|
+
if opts.key?(:ip_spec)
|
77
|
+
opts[:ip_spec]
|
78
|
+
elsif opts.key?(:ipaddr)
|
79
|
+
AceIpSpec.new(
|
80
|
+
ipaddr: opts[:ipaddr],
|
81
|
+
wildcard: opts[:wildcard]
|
82
|
+
)
|
83
|
+
else
|
84
|
+
fail AclArgumentError, 'Not specified: ip spec'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Set instance variables
|
89
|
+
# @param [Hash] opts Options of constructor
|
90
|
+
# @return [AcePortSpec] Port/Operator object
|
91
|
+
# @see #initialize
|
92
|
+
def define_portspec(opts)
|
93
|
+
if opts.key?(:port_spec)
|
94
|
+
opts[:port_spec]
|
95
|
+
elsif opts.key?(:operator)
|
96
|
+
AcePortSpec.new(
|
97
|
+
operator: opts[:operator],
|
98
|
+
begin_port: opts[:port] || opts[:begin_port],
|
99
|
+
end_port: opts[:end_port]
|
100
|
+
)
|
101
|
+
else
|
102
|
+
# in standard acl, not used port_spec
|
103
|
+
# if not specified port spec: default: any port
|
104
|
+
AcePortSpec.new(operator: 'any')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end # module
|
109
|
+
|
110
|
+
### Local variables:
|
111
|
+
### mode: Ruby
|
112
|
+
### coding: utf-8-unix
|
113
|
+
### indent-tabs-mode: nil
|
114
|
+
### End:
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
require 'cisco_acl_intp/acl_base'
|
5
|
+
|
6
|
+
module CiscoAclIntp
|
7
|
+
# TCP flag container
|
8
|
+
class AceTcpFlag < AclContainerBase
|
9
|
+
# @param [String] value TCP flag name
|
10
|
+
# @return [String]
|
11
|
+
attr_accessor :flag
|
12
|
+
|
13
|
+
# Constructor
|
14
|
+
# @param [String] flag TCP flag name
|
15
|
+
# @return [AceTcpFlag]
|
16
|
+
def initialize(flag)
|
17
|
+
@flag = flag
|
18
|
+
end
|
19
|
+
|
20
|
+
# Generate string for Cisco IOS access list
|
21
|
+
# @return [String]
|
22
|
+
def to_s
|
23
|
+
@flag.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
# @param [AceTcpFlag] other RHS Object
|
27
|
+
# @return [Boolean]
|
28
|
+
def ==(other)
|
29
|
+
@flag == other.flag
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# TCP flag list container
|
34
|
+
class AceTcpFlagList < AclContainerBase
|
35
|
+
extend Forwardable
|
36
|
+
|
37
|
+
# @param [Array] value TCP Flags
|
38
|
+
# @return [Array]
|
39
|
+
attr_accessor :list
|
40
|
+
|
41
|
+
def_delegators :@list, :push, :pop, :shift, :unshift, :size, :length
|
42
|
+
|
43
|
+
def initialize
|
44
|
+
@list = []
|
45
|
+
end
|
46
|
+
|
47
|
+
# Generate string for Cisco IOS access list
|
48
|
+
# @return [String]
|
49
|
+
def to_s
|
50
|
+
c_pp(@list.map { | each | each.to_s }.join(' '))
|
51
|
+
end
|
52
|
+
|
53
|
+
# @param [AceTcpFlagList] other RHS Object
|
54
|
+
# @return [Boolean]
|
55
|
+
def ==(other)
|
56
|
+
@list == other.list
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end # module
|
60
|
+
|
61
|
+
### Local variables:
|
62
|
+
### mode: Ruby
|
63
|
+
### coding: utf-8-unix
|
64
|
+
### indent-tabs-mode: nil
|
65
|
+
### End:
|