cisco_acl_intp 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: