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,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: