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,1397 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
# cisco IOS access list parser
|
4
|
+
class Parser
|
5
|
+
|
6
|
+
start expr
|
7
|
+
|
8
|
+
rule
|
9
|
+
expr: ipacl
|
10
|
+
| ipacl expr
|
11
|
+
|
12
|
+
ipacl: numbered_acl
|
13
|
+
| named_acl
|
14
|
+
| objgrp
|
15
|
+
|
16
|
+
eos: EOS
|
17
|
+
{
|
18
|
+
# end of line or "empty line"
|
19
|
+
yyerrok
|
20
|
+
}
|
21
|
+
|
22
|
+
# standard access-list
|
23
|
+
|
24
|
+
numbered_acl: NUMD_STD_ACL std_acl eos
|
25
|
+
{
|
26
|
+
dputs "## numd std acl: #{val[0]}/#{val[1]}"
|
27
|
+
@curr_acl_name = val[0]
|
28
|
+
unless @acl_table[@curr_acl_name]
|
29
|
+
@acl_table[@curr_acl_name] = NumberedStdAcl.new(@curr_acl_name)
|
30
|
+
@line_number = 0
|
31
|
+
end
|
32
|
+
@acl_table[@curr_acl_name].add_entry(val[1])
|
33
|
+
@line_number += 1
|
34
|
+
}
|
35
|
+
| NUMD_EXT_ACL ext_acl eos
|
36
|
+
{
|
37
|
+
dputs "## numd ext acl: #{val[0]}/#{val[1]}"
|
38
|
+
@curr_acl_name = val[0]
|
39
|
+
unless @acl_table[@curr_acl_name]
|
40
|
+
@acl_table[@curr_acl_name] = NumberedExtAcl.new(@curr_acl_name)
|
41
|
+
@line_number = 0
|
42
|
+
end
|
43
|
+
@acl_table[@curr_acl_name].add_entry(val[1])
|
44
|
+
@line_number += 1
|
45
|
+
}
|
46
|
+
| error eos
|
47
|
+
| numbered_acl eos
|
48
|
+
|
49
|
+
std_acl: action ip_spec std_acl_log_spec
|
50
|
+
{
|
51
|
+
dputs "## std_acl: #{val[0]}/#{val[1]}/#{val[2]}"
|
52
|
+
result = StandardAce.new(
|
53
|
+
:action => val[0],
|
54
|
+
:src => AceSrcDstSpec.new(:ip_spec => val[1]),
|
55
|
+
:log => val[2]
|
56
|
+
)
|
57
|
+
}
|
58
|
+
| 'remark' STRING
|
59
|
+
{
|
60
|
+
dputs "## std_acl: remark/#{val[1]}"
|
61
|
+
result = RemarkAce.new(val[1])
|
62
|
+
}
|
63
|
+
|
64
|
+
std_acl_log_spec:
|
65
|
+
| 'log' log_cookie
|
66
|
+
{
|
67
|
+
result = AceLogSpec.new(val[1])
|
68
|
+
}
|
69
|
+
|
70
|
+
# extended access-list
|
71
|
+
|
72
|
+
ext_acl: dynamic_spec ext_acl_body other_qualifier_list
|
73
|
+
{
|
74
|
+
## NOT implemented yet:
|
75
|
+
## dynamic_spec,
|
76
|
+
## other_qualifier_list (partially implemented)
|
77
|
+
dputs '## ext_acl'
|
78
|
+
val[1].tcp_other_qualifiers = val[2]
|
79
|
+
result = val[1]
|
80
|
+
}
|
81
|
+
| 'remark' STRING
|
82
|
+
{
|
83
|
+
dputs "## ext_acl: remark/#{val[1]}"
|
84
|
+
result = RemarkAce.new(val[1])
|
85
|
+
}
|
86
|
+
|
87
|
+
ext_acl_body: action ip_proto ip_spec ip_spec
|
88
|
+
{
|
89
|
+
dputs "## ext_acl_body ip: #{val[0]}/#{val[1]}/#{val[2]}/#{val[3]}"
|
90
|
+
result = ExtendedAce.new(
|
91
|
+
:action => val[0],
|
92
|
+
:protocol => val[1],
|
93
|
+
:src => AceSrcDstSpec.new(:ip_spec => val[2]),
|
94
|
+
:dst => AceSrcDstSpec.new(:ip_spec => val[3])
|
95
|
+
)
|
96
|
+
}
|
97
|
+
| action icmp_proto ip_spec ip_spec icmp_qualifier
|
98
|
+
{
|
99
|
+
result = ExtendedAce.new(
|
100
|
+
:action => val[0],
|
101
|
+
:protocol => val[1],
|
102
|
+
:src => AceSrcDstSpec.new(:ip_spec => val[2]),
|
103
|
+
:dst => AceSrcDstSpec.new(:ip_spec => val[3])
|
104
|
+
## TBD: icmp_qualifier: val[4]
|
105
|
+
)
|
106
|
+
}
|
107
|
+
| action tcp_proto tcp_srcdst_spec tcp_srcdst_spec tcp_flags_qualifier
|
108
|
+
{
|
109
|
+
result = ExtendedAce.new(
|
110
|
+
:action => val[0],
|
111
|
+
:protocol => val[1],
|
112
|
+
:src => val[2],
|
113
|
+
:dst => val[3],
|
114
|
+
:tcp_flags_qualifier => val[4]
|
115
|
+
)
|
116
|
+
}
|
117
|
+
| action udp_proto udp_srcdst_spec udp_srcdst_spec
|
118
|
+
{
|
119
|
+
result = ExtendedAce.new(
|
120
|
+
:action => val[0],
|
121
|
+
:protocol => val[1],
|
122
|
+
:src => val[2],
|
123
|
+
:dst => val[3]
|
124
|
+
)
|
125
|
+
}
|
126
|
+
| action objgrp_service_spec objgrp_srcdst_spec objgrp_srcdst_spec
|
127
|
+
{
|
128
|
+
## TBD: object group
|
129
|
+
}
|
130
|
+
|
131
|
+
# protocols
|
132
|
+
|
133
|
+
ip_proto: 'ahp'
|
134
|
+
{
|
135
|
+
result = AceIpProtoSpec.new(
|
136
|
+
:name => val[0], :number => 51
|
137
|
+
)
|
138
|
+
}
|
139
|
+
| 'eigrp'
|
140
|
+
{
|
141
|
+
result = AceIpProtoSpec.new(
|
142
|
+
:name => val[0], :number => 88
|
143
|
+
)
|
144
|
+
}
|
145
|
+
| 'esp'
|
146
|
+
{
|
147
|
+
result = AceIpProtoSpec.new(
|
148
|
+
:name => val[0], :number => 50
|
149
|
+
)
|
150
|
+
}
|
151
|
+
| 'gre'
|
152
|
+
{
|
153
|
+
result = AceIpProtoSpec.new(
|
154
|
+
:name => val[0], :number => 47
|
155
|
+
)
|
156
|
+
}
|
157
|
+
| 'igmp'
|
158
|
+
{
|
159
|
+
result = AceIpProtoSpec.new(
|
160
|
+
:name => val[0], :number => 2
|
161
|
+
)
|
162
|
+
}
|
163
|
+
| 'igrp'
|
164
|
+
{
|
165
|
+
result = AceIpProtoSpec.new(
|
166
|
+
:name => val[0], :number => 9
|
167
|
+
)
|
168
|
+
}
|
169
|
+
| 'ip'
|
170
|
+
{
|
171
|
+
result = AceIpProtoSpec.new(
|
172
|
+
:name => val[0]
|
173
|
+
)
|
174
|
+
} # IS NOT 0! (no number)
|
175
|
+
| 'ipinip'
|
176
|
+
{
|
177
|
+
result = AceIpProtoSpec.new(
|
178
|
+
:name => val[0], :number => 94
|
179
|
+
)
|
180
|
+
}
|
181
|
+
| 'nos'
|
182
|
+
{
|
183
|
+
result = AceIpProtoSpec.new(
|
184
|
+
:name => val[0], :number => 4
|
185
|
+
)
|
186
|
+
}
|
187
|
+
| 'ospf'
|
188
|
+
{
|
189
|
+
result = AceIpProtoSpec.new(
|
190
|
+
:name => val[0], :number => 89
|
191
|
+
)
|
192
|
+
}
|
193
|
+
| 'pcp'
|
194
|
+
{
|
195
|
+
result = AceIpProtoSpec.new(
|
196
|
+
:name => val[0], :number => 108
|
197
|
+
)
|
198
|
+
}
|
199
|
+
| 'pim'
|
200
|
+
{
|
201
|
+
result = AceIpProtoSpec.new(
|
202
|
+
:name => val[0], :number => 103
|
203
|
+
)
|
204
|
+
}
|
205
|
+
| NUMBER # ip protocol number (0-255)
|
206
|
+
{
|
207
|
+
begin
|
208
|
+
dputs "## ip_proto number: #{val[0]}"
|
209
|
+
result = AceIpProtoSpec.new(
|
210
|
+
:number => val[0].to_i
|
211
|
+
)
|
212
|
+
rescue => err
|
213
|
+
yyerror_with err.message
|
214
|
+
end
|
215
|
+
}
|
216
|
+
|
217
|
+
icmp_proto: 'icmp'
|
218
|
+
{
|
219
|
+
dputs '## icmp_proto'
|
220
|
+
result = AceIpProtoSpec.new(
|
221
|
+
:name => val[0], :number => 1
|
222
|
+
)
|
223
|
+
}
|
224
|
+
|
225
|
+
tcp_proto: 'tcp'
|
226
|
+
{
|
227
|
+
dputs '## tcp_proto'
|
228
|
+
result = AceIpProtoSpec.new(
|
229
|
+
:name => val[0], :number => 6
|
230
|
+
)
|
231
|
+
}
|
232
|
+
|
233
|
+
udp_proto: 'udp'
|
234
|
+
{
|
235
|
+
dputs '## udp_proto'
|
236
|
+
result = AceIpProtoSpec.new(
|
237
|
+
:name => val[0], :number => 17
|
238
|
+
)
|
239
|
+
}
|
240
|
+
|
241
|
+
tcp_srcdst_spec: objgrp_srcdst_spec tcp_port_spec
|
242
|
+
{
|
243
|
+
result = AceSrcDstSpec.new(
|
244
|
+
:ip_spec => val[0],
|
245
|
+
:port_spec => val[1]
|
246
|
+
)
|
247
|
+
}
|
248
|
+
|
249
|
+
udp_srcdst_spec: objgrp_srcdst_spec udp_port_spec
|
250
|
+
{
|
251
|
+
result = AceSrcDstSpec.new(
|
252
|
+
:ip_spec => val[0],
|
253
|
+
:port_spec => val[1]
|
254
|
+
)
|
255
|
+
}
|
256
|
+
|
257
|
+
# ip named access-list
|
258
|
+
|
259
|
+
named_acl: std_named_acl_header std_named_acl_entry_list
|
260
|
+
| ext_named_acl_header ext_named_acl_entry_list
|
261
|
+
# Notice:
|
262
|
+
# acl header でエラーがあると、そのあとのエントリ追加用のハコ(object)が
|
263
|
+
# つくれないので、エラーリカバリしようがない。
|
264
|
+
# acl_entry_list の中身については可能な範囲で parse して追加。
|
265
|
+
|
266
|
+
std_named_acl_header: NAMED_ACL 'standard' STRING eos
|
267
|
+
{
|
268
|
+
dputs "## std named acl: #{val[2]}"
|
269
|
+
@curr_acl_name = val[2]
|
270
|
+
@acl_table[@curr_acl_name] = NamedStdAcl.new(@curr_acl_name)
|
271
|
+
dputs "## make NamedStdAcl obj, name = #{ @curr_acl_name }"
|
272
|
+
}
|
273
|
+
|
274
|
+
std_named_acl_entry_list:
|
275
|
+
| std_named_acl_entry_list std_named_acl_entry
|
276
|
+
{
|
277
|
+
@acl_table[@curr_acl_name].add_entry(val[1])
|
278
|
+
@line_number += 1
|
279
|
+
}
|
280
|
+
| std_named_acl_entry_list error eos
|
281
|
+
# when a line contains syntax error (error recovery)
|
282
|
+
| std_named_acl_entry_list eos
|
283
|
+
# acl ends when empty-line "eos"
|
284
|
+
|
285
|
+
std_named_acl_entry: seq_number std_acl eos
|
286
|
+
{
|
287
|
+
# std_acl returns StandardAce/RemarkAce object
|
288
|
+
val[1].seq_number = val[0].to_i
|
289
|
+
result = val[1]
|
290
|
+
}
|
291
|
+
|
292
|
+
ext_named_acl_header: NAMED_ACL 'extended' STRING eos
|
293
|
+
{
|
294
|
+
dputs "## ext named acl: #{val[2]}"
|
295
|
+
@curr_acl_name = val[2]
|
296
|
+
@acl_table[@curr_acl_name] = NamedExtAcl.new(@curr_acl_name)
|
297
|
+
dputs "## make NamedExtAcl obj, name = #{ @curr_acl_name }"
|
298
|
+
}
|
299
|
+
|
300
|
+
ext_named_acl_entry_list:
|
301
|
+
| ext_named_acl_entry_list ext_named_acl_entry
|
302
|
+
{
|
303
|
+
@acl_table[@curr_acl_name].add_entry(val[1])
|
304
|
+
@line_number += 1
|
305
|
+
}
|
306
|
+
| ext_named_acl_entry_list error eos
|
307
|
+
# when a line contains syntax error (error recovery)
|
308
|
+
| ext_named_acl_entry_list eos
|
309
|
+
# acl ends when empty-line "eos"
|
310
|
+
|
311
|
+
ext_named_acl_entry: seq_number ext_acl eos
|
312
|
+
{
|
313
|
+
# ext_acl returns ExtendedAce/RemarkAce object
|
314
|
+
val[1].seq_number = val[0].to_i
|
315
|
+
result = val[1]
|
316
|
+
}
|
317
|
+
| seq_number 'evaluate' STRING eos
|
318
|
+
{
|
319
|
+
result = EvaluateAce.new(
|
320
|
+
:number => val[0].to_i,
|
321
|
+
:recursive_name => val[2]
|
322
|
+
)
|
323
|
+
}
|
324
|
+
|
325
|
+
seq_number:
|
326
|
+
| NUMBER # (1-2147483647)
|
327
|
+
{
|
328
|
+
result = val[0].to_i
|
329
|
+
}
|
330
|
+
|
331
|
+
# access-list common components
|
332
|
+
|
333
|
+
action: 'permit'
|
334
|
+
{
|
335
|
+
result = val[0]
|
336
|
+
}
|
337
|
+
| 'deny'
|
338
|
+
{
|
339
|
+
result = val[0]
|
340
|
+
}
|
341
|
+
|
342
|
+
|
343
|
+
ip_spec: 'host' IPV4_ADDR
|
344
|
+
{
|
345
|
+
begin
|
346
|
+
dputs "## ip_spec host: #{val[0]}/#{val[1]}"
|
347
|
+
result = AceIpSpec.new(
|
348
|
+
:ipaddr => val[1], :wildcard => '0.0.0.0'
|
349
|
+
)
|
350
|
+
rescue => err
|
351
|
+
yyerror_with err.message
|
352
|
+
end
|
353
|
+
}
|
354
|
+
| IPV4_ADDR IPV4_ADDR # ipaddr wildcard
|
355
|
+
{
|
356
|
+
begin
|
357
|
+
dputs "## ip_spec #{val[0]}/#{val[1]}"
|
358
|
+
result = AceIpSpec.new(
|
359
|
+
:ipaddr => val[0], :wildcard => val[1]
|
360
|
+
)
|
361
|
+
rescue => err
|
362
|
+
yyerror_with err.message
|
363
|
+
end
|
364
|
+
}
|
365
|
+
| 'any'
|
366
|
+
{
|
367
|
+
dputs "## ip_spec any: #{val[0]}"
|
368
|
+
result = AceIpSpec.new(
|
369
|
+
:ipaddr => '0.0.0.0', :wildcard => '255.255.255.255'
|
370
|
+
)
|
371
|
+
}
|
372
|
+
|
373
|
+
dynamic_spec:
|
374
|
+
| 'dynamic' STRING timeout_spec
|
375
|
+
|
376
|
+
timeout_spec:
|
377
|
+
| 'timeout' NUMBER
|
378
|
+
|
379
|
+
# object-group
|
380
|
+
|
381
|
+
## TBD
|
382
|
+
# object group syntax was not implemented
|
383
|
+
# 'eos' termination
|
384
|
+
|
385
|
+
objgrp: objgrp_service
|
386
|
+
| objgrp_network
|
387
|
+
|
388
|
+
objgrp_service_spec: 'object-group' STRING # service object group
|
389
|
+
{
|
390
|
+
}
|
391
|
+
|
392
|
+
objgrp_srcdst_spec: objgrp_network_spec
|
393
|
+
| ip_spec
|
394
|
+
{
|
395
|
+
result = val[0]
|
396
|
+
}
|
397
|
+
|
398
|
+
objgrp_network_spec: 'object-group' STRING # network object group
|
399
|
+
{
|
400
|
+
}
|
401
|
+
|
402
|
+
objgrp_network: objgrp_network_header objgrp_network_entry_list
|
403
|
+
|
404
|
+
objgrp_network_header: 'object-group' 'network' STRING
|
405
|
+
{
|
406
|
+
}
|
407
|
+
|
408
|
+
objgrp_network_entry_list:
|
409
|
+
| objgrp_network_entry_list objgrp_network_entry
|
410
|
+
{
|
411
|
+
}
|
412
|
+
|
413
|
+
objgrp_network_entry: 'description' STRING
|
414
|
+
{
|
415
|
+
}
|
416
|
+
| 'host' IPV4_ADDR
|
417
|
+
{
|
418
|
+
}
|
419
|
+
| IPV4_ADDR IPV4_ADDR
|
420
|
+
{
|
421
|
+
}
|
422
|
+
| IPV4_ADDR '/' NUMBER # 0-32
|
423
|
+
{
|
424
|
+
}
|
425
|
+
| 'range' IPV4_ADDR IPV4_ADDR
|
426
|
+
{
|
427
|
+
}
|
428
|
+
| 'group-object' STRING # nested object-group
|
429
|
+
{
|
430
|
+
}
|
431
|
+
|
432
|
+
objgrp_service: objgrp_service_header objgrp_service_entry_list
|
433
|
+
|
434
|
+
objgrp_service_header: 'object-group' 'service' STRING
|
435
|
+
{
|
436
|
+
}
|
437
|
+
|
438
|
+
objgrp_service_entry_list:
|
439
|
+
| objgrp_service_entry_list objgrp_service_entry
|
440
|
+
{
|
441
|
+
}
|
442
|
+
|
443
|
+
objgrp_service_entry: 'description' STRING
|
444
|
+
| ip_proto
|
445
|
+
{
|
446
|
+
}
|
447
|
+
| icmp_proto icmp_qualifier
|
448
|
+
{
|
449
|
+
}
|
450
|
+
| tcp_proto objgrp_tcp_proto
|
451
|
+
{
|
452
|
+
}
|
453
|
+
| udp_proto objgrp_udp_proto
|
454
|
+
{
|
455
|
+
}
|
456
|
+
| 'tcp-udp' objgrp_tcpudp_proto
|
457
|
+
{
|
458
|
+
}
|
459
|
+
| 'group-object' STRING # nested object-group
|
460
|
+
{
|
461
|
+
}
|
462
|
+
|
463
|
+
objgrp_tcp_proto: objgrp_tcp_proto_spec
|
464
|
+
{
|
465
|
+
}
|
466
|
+
| 'source' objgrp_tcp_proto_spec
|
467
|
+
{
|
468
|
+
}
|
469
|
+
|
470
|
+
objgrp_tcp_proto_spec:
|
471
|
+
| unary_operator tcp_port_qualifier
|
472
|
+
{
|
473
|
+
}
|
474
|
+
| 'range' tcp_port_qualifier tcp_port_qualifier
|
475
|
+
{
|
476
|
+
}
|
477
|
+
| tcp_port_qualifier
|
478
|
+
{
|
479
|
+
}
|
480
|
+
|
481
|
+
objgrp_udp_proto: objgrp_udp_proto_spec
|
482
|
+
{
|
483
|
+
}
|
484
|
+
| 'source' objgrp_udp_proto_spec
|
485
|
+
{
|
486
|
+
}
|
487
|
+
|
488
|
+
objgrp_udp_proto_spec:
|
489
|
+
| unary_operator udp_port_qualifier
|
490
|
+
{
|
491
|
+
}
|
492
|
+
| 'range' udp_port_qualifier udp_port_qualifier
|
493
|
+
{
|
494
|
+
}
|
495
|
+
| udp_port_qualifier
|
496
|
+
{
|
497
|
+
}
|
498
|
+
|
499
|
+
objgrp_tcpudp_proto: objgrp_tcpudp_proto_spec
|
500
|
+
{
|
501
|
+
}
|
502
|
+
| 'source' objgrp_tcpudp_proto_spec
|
503
|
+
{
|
504
|
+
}
|
505
|
+
|
506
|
+
objgrp_tcpudp_proto_spec:
|
507
|
+
| unary_operator tcpudp_port_qualifier
|
508
|
+
{
|
509
|
+
}
|
510
|
+
| 'range' tcpudp_port_qualifier tcpudp_port_qualifier
|
511
|
+
{
|
512
|
+
}
|
513
|
+
| tcpudp_port_qualifier
|
514
|
+
{
|
515
|
+
}
|
516
|
+
|
517
|
+
tcpudp_port_qualifier: NUMBER # port number (0-65535)
|
518
|
+
| 'discard'
|
519
|
+
| 'domain'
|
520
|
+
| 'echo'
|
521
|
+
| 'pim-auto-rp'
|
522
|
+
| 'sunrpc'
|
523
|
+
| 'syslog'
|
524
|
+
| 'tacacs'
|
525
|
+
| 'talk'
|
526
|
+
|
527
|
+
# icmp qualifier
|
528
|
+
|
529
|
+
icmp_qualifier:
|
530
|
+
| 'administratively-prohibited'
|
531
|
+
| 'alternate-address'
|
532
|
+
| 'conversion-error'
|
533
|
+
| 'dod-host-prohibited'
|
534
|
+
| 'dod-net-prohibited'
|
535
|
+
| 'echo'
|
536
|
+
| 'echo-reply'
|
537
|
+
| 'general-parameter-problem'
|
538
|
+
| 'host-isolated'
|
539
|
+
| 'mobile-redirect'
|
540
|
+
| 'net-redirect'
|
541
|
+
| 'net-tos-redirect'
|
542
|
+
| 'net-unreachable'
|
543
|
+
| 'net-unknown'
|
544
|
+
| 'no-room-for-option'
|
545
|
+
| 'option-missing'
|
546
|
+
| 'packet-too-big'
|
547
|
+
| 'parameter-problem'
|
548
|
+
| 'port-unreachable'
|
549
|
+
| 'precedence-unreachable'
|
550
|
+
| 'protocol-unreachable'
|
551
|
+
| 'host-precedence-unreachable'
|
552
|
+
| 'host-redirect'
|
553
|
+
| 'host-tos-redirect'
|
554
|
+
| 'host-unknown'
|
555
|
+
| 'host-unreachable'
|
556
|
+
| 'information-reply'
|
557
|
+
| 'information-request'
|
558
|
+
| 'mask-reply'
|
559
|
+
| 'mask-request'
|
560
|
+
| 'reassembly-timeout'
|
561
|
+
| 'redirect'
|
562
|
+
| 'router-advertisement'
|
563
|
+
| 'router-solicitation'
|
564
|
+
| 'source-quench'
|
565
|
+
| 'source-route-failed'
|
566
|
+
| 'time-exceeded'
|
567
|
+
| 'timestamp-reply'
|
568
|
+
| 'timestamp-request'
|
569
|
+
| 'traceroute'
|
570
|
+
| 'ttl-exceeded'
|
571
|
+
| 'unreachable'
|
572
|
+
| icmp_numtype icmp_numcode
|
573
|
+
|
574
|
+
icmp_numtype: NUMBER # icmp message type (0-255)
|
575
|
+
|
576
|
+
icmp_numcode:
|
577
|
+
| NUMBER # icmp message code (0-255)
|
578
|
+
|
579
|
+
|
580
|
+
|
581
|
+
# tcp/udp port spec
|
582
|
+
|
583
|
+
tcp_port_spec:
|
584
|
+
{
|
585
|
+
# tcp any
|
586
|
+
dputs '## tcp port any'
|
587
|
+
result = AcePortSpec.new(:operator => 'any')
|
588
|
+
}
|
589
|
+
| unary_operator tcp_port_qualifier
|
590
|
+
{
|
591
|
+
dputs "## tcp port spec: #{val[0]}/#{val[1]}"
|
592
|
+
result = AcePortSpec.new(
|
593
|
+
:operator => val[0],
|
594
|
+
:port => val[1]
|
595
|
+
)
|
596
|
+
}
|
597
|
+
| 'range' tcp_port_qualifier tcp_port_qualifier
|
598
|
+
{
|
599
|
+
dputs "## tcp port spec: #{val[0]}/#{val[1]}/#{val[2]}"
|
600
|
+
result = AcePortSpec.new(
|
601
|
+
:operator => val[0],
|
602
|
+
:begin_port => val[1],
|
603
|
+
:end_port => val[2]
|
604
|
+
)
|
605
|
+
}
|
606
|
+
|
607
|
+
udp_port_spec:
|
608
|
+
{
|
609
|
+
# udp any
|
610
|
+
dputs '## udp port: any'
|
611
|
+
result = AcePortSpec.new(:operator => 'any')
|
612
|
+
}
|
613
|
+
| unary_operator udp_port_qualifier
|
614
|
+
{
|
615
|
+
dputs "## udp port spec: #{val[0]}/#{val[1]}"
|
616
|
+
result = AcePortSpec.new(
|
617
|
+
:operator => val[0],
|
618
|
+
:port => val[1]
|
619
|
+
)
|
620
|
+
}
|
621
|
+
| 'range' udp_port_qualifier udp_port_qualifier
|
622
|
+
{
|
623
|
+
dputs "## udp port spec: #{val[0]}/#{val[1]}/#{val[2]}"
|
624
|
+
result = AcePortSpec.new(
|
625
|
+
:operator => val[0],
|
626
|
+
:begin_port => val[1],
|
627
|
+
:end_port => val[2]
|
628
|
+
)
|
629
|
+
}
|
630
|
+
|
631
|
+
unary_operator: 'gt'
|
632
|
+
| 'lt'
|
633
|
+
| 'eq'
|
634
|
+
| 'neq'
|
635
|
+
|
636
|
+
tcp_port_qualifier: NUMBER
|
637
|
+
{
|
638
|
+
begin
|
639
|
+
# port number (0-65535)
|
640
|
+
result = AceTcpProtoSpec.new(
|
641
|
+
:number => val[0]
|
642
|
+
)
|
643
|
+
rescue => err
|
644
|
+
yyerror_with err.message
|
645
|
+
end
|
646
|
+
}
|
647
|
+
| 'bgp'
|
648
|
+
{
|
649
|
+
result = AceTcpProtoSpec.new(
|
650
|
+
:name => val[0], :number => 179
|
651
|
+
)
|
652
|
+
}
|
653
|
+
| 'chargen'
|
654
|
+
{
|
655
|
+
result = AceTcpProtoSpec.new(
|
656
|
+
:name => val[0], :number => 19
|
657
|
+
)
|
658
|
+
}
|
659
|
+
| 'cmd'
|
660
|
+
{
|
661
|
+
result = AceTcpProtoSpec.new(
|
662
|
+
:name => val[0], :number => 514
|
663
|
+
)
|
664
|
+
}
|
665
|
+
| 'daytime'
|
666
|
+
{
|
667
|
+
result = AceTcpProtoSpec.new(
|
668
|
+
:name => val[0], :number => 13
|
669
|
+
)
|
670
|
+
}
|
671
|
+
| 'discard'
|
672
|
+
{
|
673
|
+
result = AceTcpProtoSpec.new(
|
674
|
+
:name => val[0], :number => 9
|
675
|
+
)
|
676
|
+
}
|
677
|
+
| 'domain'
|
678
|
+
{
|
679
|
+
result = AceTcpProtoSpec.new(
|
680
|
+
:name => val[0], :number => 53
|
681
|
+
)
|
682
|
+
}
|
683
|
+
| 'drip'
|
684
|
+
{
|
685
|
+
result = AceTcpProtoSpec.new(
|
686
|
+
:name => val[0], :number => 3949
|
687
|
+
)
|
688
|
+
}
|
689
|
+
| 'echo'
|
690
|
+
{
|
691
|
+
result = AceTcpProtoSpec.new(
|
692
|
+
:name => val[0], :number => 7
|
693
|
+
)
|
694
|
+
}
|
695
|
+
| 'exec'
|
696
|
+
{
|
697
|
+
result = AceTcpProtoSpec.new(
|
698
|
+
:name => val[0], :number => 512
|
699
|
+
)
|
700
|
+
}
|
701
|
+
| 'finger'
|
702
|
+
{
|
703
|
+
result = AceTcpProtoSpec.new(
|
704
|
+
:name => val[0], :number => 79
|
705
|
+
)
|
706
|
+
}
|
707
|
+
| 'ftp'
|
708
|
+
{
|
709
|
+
result = AceTcpProtoSpec.new(
|
710
|
+
:name => val[0], :number => 21
|
711
|
+
)
|
712
|
+
}
|
713
|
+
| 'ftp-data'
|
714
|
+
{
|
715
|
+
result = AceTcpProtoSpec.new(
|
716
|
+
:name => val[0], :number => 20
|
717
|
+
)
|
718
|
+
}
|
719
|
+
| 'gopher'
|
720
|
+
{
|
721
|
+
result = AceTcpProtoSpec.new(
|
722
|
+
:name => val[0], :number => 70
|
723
|
+
)
|
724
|
+
}
|
725
|
+
| 'hostname'
|
726
|
+
{
|
727
|
+
result = AceTcpProtoSpec.new(
|
728
|
+
:name => val[0], :number => 101
|
729
|
+
)
|
730
|
+
}
|
731
|
+
| 'ident'
|
732
|
+
{
|
733
|
+
result = AceTcpProtoSpec.new(
|
734
|
+
:name => val[0], :number => 113
|
735
|
+
)
|
736
|
+
}
|
737
|
+
| 'irc'
|
738
|
+
{
|
739
|
+
result = AceTcpProtoSpec.new(
|
740
|
+
:name => val[0], :number => 194
|
741
|
+
)
|
742
|
+
}
|
743
|
+
| 'klogin'
|
744
|
+
{
|
745
|
+
result = AceTcpProtoSpec.new(
|
746
|
+
:name => val[0], :number => 543
|
747
|
+
)
|
748
|
+
}
|
749
|
+
| 'kshell'
|
750
|
+
{
|
751
|
+
result = AceTcpProtoSpec.new(
|
752
|
+
:name => val[0], :number => 544
|
753
|
+
)
|
754
|
+
}
|
755
|
+
| 'login'
|
756
|
+
{
|
757
|
+
result = AceTcpProtoSpec.new(
|
758
|
+
:name => val[0], :number => 513
|
759
|
+
)
|
760
|
+
}
|
761
|
+
| 'lpd'
|
762
|
+
{
|
763
|
+
result = AceTcpProtoSpec.new(
|
764
|
+
:name => val[0], :number => 515
|
765
|
+
)
|
766
|
+
}
|
767
|
+
| 'nntp'
|
768
|
+
{
|
769
|
+
result = AceTcpProtoSpec.new(
|
770
|
+
:name => val[0], :number => 119
|
771
|
+
)
|
772
|
+
}
|
773
|
+
| 'pim-auto-rp'
|
774
|
+
{
|
775
|
+
result = AceTcpProtoSpec.new(
|
776
|
+
:name => val[0], :number => 496
|
777
|
+
)
|
778
|
+
}
|
779
|
+
| 'pop2'
|
780
|
+
{
|
781
|
+
result = AceTcpProtoSpec.new(
|
782
|
+
:name => val[0], :number => 109
|
783
|
+
)
|
784
|
+
}
|
785
|
+
| 'pop3'
|
786
|
+
{
|
787
|
+
result = AceTcpProtoSpec.new(
|
788
|
+
:name => val[0], :number => 110
|
789
|
+
)
|
790
|
+
}
|
791
|
+
| 'smtp'
|
792
|
+
{
|
793
|
+
result = AceTcpProtoSpec.new(
|
794
|
+
:name => val[0], :number => 25
|
795
|
+
)
|
796
|
+
}
|
797
|
+
| 'sunrpc'
|
798
|
+
{
|
799
|
+
result = AceTcpProtoSpec.new(
|
800
|
+
:name => val[0], :number => 111
|
801
|
+
)
|
802
|
+
}
|
803
|
+
| 'syslog'
|
804
|
+
{
|
805
|
+
result = AceTcpProtoSpec.new(
|
806
|
+
:name => val[0], :number => 514
|
807
|
+
)
|
808
|
+
}
|
809
|
+
| 'tacacs'
|
810
|
+
{
|
811
|
+
result = AceTcpProtoSpec.new(
|
812
|
+
:name => val[0], :number => 49
|
813
|
+
)
|
814
|
+
}
|
815
|
+
| 'talk'
|
816
|
+
{
|
817
|
+
result = AceTcpProtoSpec.new(
|
818
|
+
:name => val[0], :number => 517
|
819
|
+
)
|
820
|
+
}
|
821
|
+
| 'telnet'
|
822
|
+
{
|
823
|
+
result = AceTcpProtoSpec.new(
|
824
|
+
:name => val[0], :number => 23
|
825
|
+
)
|
826
|
+
}
|
827
|
+
| 'time'
|
828
|
+
{
|
829
|
+
result = AceTcpProtoSpec.new(
|
830
|
+
:name => val[0], :number => 37
|
831
|
+
)
|
832
|
+
}
|
833
|
+
| 'uucp'
|
834
|
+
{
|
835
|
+
result = AceTcpProtoSpec.new(
|
836
|
+
:name => val[0], :number => 540
|
837
|
+
)
|
838
|
+
}
|
839
|
+
| 'whois'
|
840
|
+
{
|
841
|
+
result = AceTcpProtoSpec.new(
|
842
|
+
:name => val[0], :number => 43
|
843
|
+
)
|
844
|
+
}
|
845
|
+
| 'www'
|
846
|
+
{
|
847
|
+
result = AceTcpProtoSpec.new(
|
848
|
+
:name => val[0], :number => 80
|
849
|
+
)
|
850
|
+
}
|
851
|
+
|
852
|
+
udp_port_qualifier: NUMBER
|
853
|
+
{
|
854
|
+
# port number (0-65535)
|
855
|
+
result = AceUdpProtoSpec.new(
|
856
|
+
:number => val[0]
|
857
|
+
)
|
858
|
+
}
|
859
|
+
| 'biff'
|
860
|
+
{
|
861
|
+
result = AceUdpProtoSpec.new(
|
862
|
+
:name => val[0], :number => 512
|
863
|
+
)
|
864
|
+
}
|
865
|
+
| 'bootpc'
|
866
|
+
{
|
867
|
+
result = AceUdpProtoSpec.new(
|
868
|
+
:name => val[0], :number => 68
|
869
|
+
)
|
870
|
+
}
|
871
|
+
| 'bootps'
|
872
|
+
{
|
873
|
+
result = AceUdpProtoSpec.new(
|
874
|
+
:name => val[0], :number => 67
|
875
|
+
)
|
876
|
+
}
|
877
|
+
| 'discard'
|
878
|
+
{
|
879
|
+
result = AceUdpProtoSpec.new(
|
880
|
+
:name => val[0], :number => 9
|
881
|
+
)
|
882
|
+
}
|
883
|
+
| 'dnsix'
|
884
|
+
{
|
885
|
+
result = AceUdpProtoSpec.new(
|
886
|
+
:name => val[0], :number => 195
|
887
|
+
)
|
888
|
+
}
|
889
|
+
| 'domain'
|
890
|
+
{
|
891
|
+
result = AceUdpProtoSpec.new(
|
892
|
+
:name => val[0], :number => 53
|
893
|
+
)
|
894
|
+
}
|
895
|
+
| 'echo'
|
896
|
+
{
|
897
|
+
result = AceUdpProtoSpec.new(
|
898
|
+
:name => val[0], :number => 7
|
899
|
+
)
|
900
|
+
}
|
901
|
+
| 'isakmp'
|
902
|
+
{
|
903
|
+
result = AceUdpProtoSpec.new(
|
904
|
+
:name => val[0], :number => 500
|
905
|
+
)
|
906
|
+
}
|
907
|
+
| 'mobile-ip'
|
908
|
+
{
|
909
|
+
result = AceUdpProtoSpec.new(
|
910
|
+
:name => val[0], :number => 434
|
911
|
+
)
|
912
|
+
}
|
913
|
+
| 'nameserver'
|
914
|
+
{
|
915
|
+
result = AceUdpProtoSpec.new(
|
916
|
+
:name => val[0], :number => 42
|
917
|
+
)
|
918
|
+
}
|
919
|
+
| 'netbios-dgm'
|
920
|
+
{
|
921
|
+
result = AceUdpProtoSpec.new(
|
922
|
+
:name => val[0], :number => 138
|
923
|
+
)
|
924
|
+
}
|
925
|
+
| 'netbios-ns'
|
926
|
+
{
|
927
|
+
result = AceUdpProtoSpec.new(
|
928
|
+
:name => val[0], :number => 137
|
929
|
+
)
|
930
|
+
}
|
931
|
+
| 'netbios-ss'
|
932
|
+
{
|
933
|
+
result = AceUdpProtoSpec.new(
|
934
|
+
:name => val[0], :number => 139
|
935
|
+
)
|
936
|
+
}
|
937
|
+
| 'non500-isakmp'
|
938
|
+
{
|
939
|
+
result = AceUdpProtoSpec.new(
|
940
|
+
:name => val[0], :number => 4500
|
941
|
+
)
|
942
|
+
}
|
943
|
+
| 'ntp'
|
944
|
+
{
|
945
|
+
result = AceUdpProtoSpec.new(
|
946
|
+
:name => val[0], :number => 123
|
947
|
+
)
|
948
|
+
}
|
949
|
+
| 'pim-auto-rp'
|
950
|
+
{
|
951
|
+
result = AceUdpProtoSpec.new(
|
952
|
+
:name => val[0], :number => 496
|
953
|
+
)
|
954
|
+
}
|
955
|
+
| 'rip'
|
956
|
+
{
|
957
|
+
result = AceUdpProtoSpec.new(
|
958
|
+
:name => val[0], :number => 520
|
959
|
+
)
|
960
|
+
}
|
961
|
+
| 'snmp'
|
962
|
+
{
|
963
|
+
result = AceUdpProtoSpec.new(
|
964
|
+
:name => val[0], :number => 161
|
965
|
+
)
|
966
|
+
}
|
967
|
+
| 'snmptrap'
|
968
|
+
{
|
969
|
+
result = AceUdpProtoSpec.new(
|
970
|
+
:name => val[0], :number => 162
|
971
|
+
)
|
972
|
+
}
|
973
|
+
| 'sunrpc'
|
974
|
+
{
|
975
|
+
result = AceUdpProtoSpec.new(
|
976
|
+
:name => val[0], :number => 111
|
977
|
+
)
|
978
|
+
}
|
979
|
+
| 'syslog'
|
980
|
+
{
|
981
|
+
result = AceUdpProtoSpec.new(
|
982
|
+
:name => val[0], :number => 514
|
983
|
+
)
|
984
|
+
}
|
985
|
+
| 'tacacs'
|
986
|
+
{
|
987
|
+
result = AceUdpProtoSpec.new(
|
988
|
+
:name => val[0], :number => 49
|
989
|
+
)
|
990
|
+
}
|
991
|
+
| 'talk'
|
992
|
+
{
|
993
|
+
result = AceUdpProtoSpec.new(
|
994
|
+
:name => val[0], :number => 517
|
995
|
+
)
|
996
|
+
}
|
997
|
+
| 'tftp'
|
998
|
+
{
|
999
|
+
result = AceUdpProtoSpec.new(
|
1000
|
+
:name => val[0], :number => 69
|
1001
|
+
)
|
1002
|
+
}
|
1003
|
+
| 'time'
|
1004
|
+
{
|
1005
|
+
result = AceUdpProtoSpec.new(
|
1006
|
+
:name => val[0], :number => 37
|
1007
|
+
)
|
1008
|
+
}
|
1009
|
+
| 'who'
|
1010
|
+
{
|
1011
|
+
result = AceUdpProtoSpec.new(
|
1012
|
+
:name => val[0], :number => 513
|
1013
|
+
)
|
1014
|
+
}
|
1015
|
+
| 'xdmcp'
|
1016
|
+
{
|
1017
|
+
result = AceUdpProtoSpec.new(
|
1018
|
+
:name => val[0], :number => 177
|
1019
|
+
)
|
1020
|
+
}
|
1021
|
+
|
1022
|
+
# tcp flags list
|
1023
|
+
|
1024
|
+
tcp_flags_qualifier:
|
1025
|
+
| tcp_flags_list
|
1026
|
+
| 'match-all' pm_tcp_flags_list
|
1027
|
+
| 'match-any' pm_tcp_flags_list
|
1028
|
+
|
1029
|
+
tcp_flags_list: tcp_flags
|
1030
|
+
{
|
1031
|
+
list = AceTcpFlagList.new
|
1032
|
+
list.push(val[0])
|
1033
|
+
result = list
|
1034
|
+
}
|
1035
|
+
| tcp_flags_list tcp_flags
|
1036
|
+
{
|
1037
|
+
val[0].push(val[1])
|
1038
|
+
result = val[0]
|
1039
|
+
}
|
1040
|
+
|
1041
|
+
tcp_flags: 'established'
|
1042
|
+
{
|
1043
|
+
dputs "## tcp_flags, established: #{val[0]}"
|
1044
|
+
result = AceTcpFlag.new(val[0])
|
1045
|
+
}
|
1046
|
+
| 'ack'
|
1047
|
+
{
|
1048
|
+
result = AceTcpFlag.new(val[0])
|
1049
|
+
}
|
1050
|
+
| 'syn'
|
1051
|
+
{
|
1052
|
+
result = AceTcpFlag.new(val[0])
|
1053
|
+
}
|
1054
|
+
| 'fin'
|
1055
|
+
{
|
1056
|
+
result = AceTcpFlag.new(val[0])
|
1057
|
+
}
|
1058
|
+
| 'psh'
|
1059
|
+
{
|
1060
|
+
result = AceTcpFlag.new(val[0])
|
1061
|
+
}
|
1062
|
+
| 'urg'
|
1063
|
+
{
|
1064
|
+
result = AceTcpFlag.new(val[0])
|
1065
|
+
}
|
1066
|
+
| 'rst'
|
1067
|
+
{
|
1068
|
+
result = AceTcpFlag.new(val[0])
|
1069
|
+
}
|
1070
|
+
|
1071
|
+
pm_tcp_flags_list: pm_tcp_flags
|
1072
|
+
| pm_tcp_flags_list pm_tcp_flags
|
1073
|
+
|
1074
|
+
pm_tcp_flags: '+ack'
|
1075
|
+
| '-ack'
|
1076
|
+
| '+syn'
|
1077
|
+
| '-syn'
|
1078
|
+
| '+fin'
|
1079
|
+
| '-fin'
|
1080
|
+
| '+psh'
|
1081
|
+
| '-psh'
|
1082
|
+
| '+urg'
|
1083
|
+
| '-urg'
|
1084
|
+
| '+rst'
|
1085
|
+
| '-rst'
|
1086
|
+
|
1087
|
+
# oether qualifier list
|
1088
|
+
|
1089
|
+
other_qualifier_list:
|
1090
|
+
| other_qualifier_list other_qualifier
|
1091
|
+
{
|
1092
|
+
dputs "## other qualifier list, #{val[0]}/#{val[1]}"
|
1093
|
+
if val[0]
|
1094
|
+
list = val[0]
|
1095
|
+
else
|
1096
|
+
list = AceOtherQualifierList.new
|
1097
|
+
end
|
1098
|
+
list.push(val[1])
|
1099
|
+
result = list
|
1100
|
+
}
|
1101
|
+
|
1102
|
+
other_qualifier: dscp_rule
|
1103
|
+
| 'fragments'
|
1104
|
+
| logging
|
1105
|
+
{
|
1106
|
+
dputs "## other qualifier, logging, #{val[0]})"
|
1107
|
+
result = val[0]
|
1108
|
+
}
|
1109
|
+
| tos_qualifier
|
1110
|
+
| precedence_qualifier
|
1111
|
+
| time_range_spec
|
1112
|
+
| recursive_qualifier
|
1113
|
+
{
|
1114
|
+
result = val[0]
|
1115
|
+
}
|
1116
|
+
| ttl_qualifier # IOS 12.4
|
1117
|
+
| option_qualifier # IOS 12.3(4)T,12.2(25)S, IP Options
|
1118
|
+
|
1119
|
+
dscp_rule: 'dscp' dscp_spec
|
1120
|
+
;
|
1121
|
+
|
1122
|
+
dscp_spec: NUMBER # 0-63
|
1123
|
+
| 'af11' # 001010
|
1124
|
+
| 'af12' # 001100
|
1125
|
+
| 'af13' # 001110
|
1126
|
+
| 'af21' # 010010
|
1127
|
+
| 'af22' # 010100
|
1128
|
+
| 'af23' # 010110
|
1129
|
+
| 'af31' # 011010
|
1130
|
+
| 'af32' # 011100
|
1131
|
+
| 'af33' # 011110
|
1132
|
+
| 'af41' # 100010
|
1133
|
+
| 'af42' # 100100
|
1134
|
+
| 'af43' # 100110
|
1135
|
+
| 'CS1' # 001000
|
1136
|
+
| 'CS2' # 010000
|
1137
|
+
| 'CS3' # 011000
|
1138
|
+
| 'CS4' # 100000
|
1139
|
+
| 'CS5' # 101000
|
1140
|
+
| 'CS6' # 110000
|
1141
|
+
| 'CS7' # 111000
|
1142
|
+
| 'default' # 000000
|
1143
|
+
| 'ef' # 101110
|
1144
|
+
|
1145
|
+
logging: 'log-input' log_cookie
|
1146
|
+
{
|
1147
|
+
result = AceLogSpec.new(val[1], true)
|
1148
|
+
}
|
1149
|
+
| 'log' log_cookie
|
1150
|
+
{
|
1151
|
+
result = AceLogSpec.new(val[1])
|
1152
|
+
}
|
1153
|
+
|
1154
|
+
log_cookie:
|
1155
|
+
| STRING
|
1156
|
+
{
|
1157
|
+
result = val[0]
|
1158
|
+
}
|
1159
|
+
|
1160
|
+
tos_qualifier: 'tos' tos_string
|
1161
|
+
| 'tos' NUMBER
|
1162
|
+
|
1163
|
+
tos_string: 'max-reliability'
|
1164
|
+
| 'max-throughput'
|
1165
|
+
| 'min-delay'
|
1166
|
+
| 'min-monetary-cost'
|
1167
|
+
| 'normal'
|
1168
|
+
|
1169
|
+
precedence_qualifier: 'precedence' precedence_string
|
1170
|
+
| 'precedence' NUMBER # 0-7
|
1171
|
+
|
1172
|
+
precedence_string: 'critical' # 5
|
1173
|
+
| 'flash' # 3
|
1174
|
+
| 'flash-override' # 4
|
1175
|
+
| 'immediate' # 2
|
1176
|
+
| 'internet' # 6
|
1177
|
+
| 'network' # 7
|
1178
|
+
| 'priority' # 1
|
1179
|
+
| 'routine' # 0
|
1180
|
+
|
1181
|
+
time_range_spec: 'time-range' STRING
|
1182
|
+
|
1183
|
+
recursive_qualifier: 'reflect' STRING timeout_spec
|
1184
|
+
{
|
1185
|
+
## TBD: timeout_spec not implemented yet.
|
1186
|
+
result = AceRecursiveQualifier.new(val[1])
|
1187
|
+
}
|
1188
|
+
|
1189
|
+
ttl_qualifier: 'ttl' unary_operator NUMBER # 0-255
|
1190
|
+
| 'ttl' 'range' NUMBER NUMBER
|
1191
|
+
|
1192
|
+
option_qualifier: 'option' option_spec
|
1193
|
+
|
1194
|
+
option_spec: 'add-ext' # opt 147
|
1195
|
+
| 'any-options'
|
1196
|
+
| 'com-security' # opt 134
|
1197
|
+
| 'dps' # opt 151
|
1198
|
+
| 'encode' # opt 15
|
1199
|
+
| 'eool' # opt 0
|
1200
|
+
| 'ext-ip' # opt 145
|
1201
|
+
| 'ext-security' # opt 133
|
1202
|
+
| 'finn' # opt 205
|
1203
|
+
| 'imitd' # opt 144
|
1204
|
+
| 'lsr' # opt 131
|
1205
|
+
| 'mtup' # opt 11
|
1206
|
+
| 'mtur' # opt 12
|
1207
|
+
| 'no-op' # opt 1
|
1208
|
+
| 'nsapa' # opt 150
|
1209
|
+
| 'record-route' # opt 7
|
1210
|
+
| 'route-alert' # opt 148
|
1211
|
+
| 'sdb' # opt 149
|
1212
|
+
| 'security' # opt 130
|
1213
|
+
| 'ssr' # opt 137
|
1214
|
+
| 'stream-id' # opt 136
|
1215
|
+
| 'timestamp' # opt 68
|
1216
|
+
| 'traceroute' # opt 82
|
1217
|
+
| 'ump' # opt 152
|
1218
|
+
| 'visa' # opt 142
|
1219
|
+
| 'zsu' # opt 10
|
1220
|
+
| NUMBER # ip options vlaue (0-255)
|
1221
|
+
|
1222
|
+
---- header
|
1223
|
+
|
1224
|
+
require 'term/ansicolor'
|
1225
|
+
require 'cisco_acl_intp/scanner'
|
1226
|
+
require 'cisco_acl_intp/acl'
|
1227
|
+
|
1228
|
+
module CiscoAclIntp
|
1229
|
+
|
1230
|
+
---- inner
|
1231
|
+
|
1232
|
+
# @return [Hash] ACL Table by ACL name key
|
1233
|
+
attr_reader :acl_table, :error_count
|
1234
|
+
|
1235
|
+
# Constructor
|
1236
|
+
# @param [Hash] opts Options
|
1237
|
+
# @option [Boolean] :yydebug Enable Racc debug print.
|
1238
|
+
# (default: false)
|
1239
|
+
# @option [Boolean] :debug Enable debug print.
|
1240
|
+
# (default: false)
|
1241
|
+
# @option [Boolean] :color Enable Term ANSI Color.
|
1242
|
+
# (default: false)
|
1243
|
+
# @option [Boolean] :silent Enable all parser syntax error
|
1244
|
+
# (default: false)
|
1245
|
+
# @return [CiscoACLParser]
|
1246
|
+
def initialize opts
|
1247
|
+
@yydebug = opts[:yydebug] || false
|
1248
|
+
@debug_print = opts[:debug] || false
|
1249
|
+
@color_mode = opts[:color] || false
|
1250
|
+
@silent_mode = @debug_print || opts[:silent] || false
|
1251
|
+
|
1252
|
+
if @color_mode
|
1253
|
+
AclContainerBase.enable_color
|
1254
|
+
else
|
1255
|
+
AclContainerBase.disable_color
|
1256
|
+
end
|
1257
|
+
|
1258
|
+
@acl_table = {}
|
1259
|
+
@curr_acl_name = ''
|
1260
|
+
@line_number = 0
|
1261
|
+
@error_count = 0
|
1262
|
+
end
|
1263
|
+
|
1264
|
+
# Scan ACL from file to parse
|
1265
|
+
# @param [String] file File name
|
1266
|
+
# @param [IO] file IO Object
|
1267
|
+
# @return [Hash] ACL Table
|
1268
|
+
def parse_file filename
|
1269
|
+
begin
|
1270
|
+
file = nil
|
1271
|
+
case filename
|
1272
|
+
when String
|
1273
|
+
file = File.new(filename)
|
1274
|
+
when IO, StringIO
|
1275
|
+
file = filename
|
1276
|
+
end
|
1277
|
+
|
1278
|
+
if file
|
1279
|
+
scanner = Scanner.new
|
1280
|
+
@queue = scanner.scan_file(file)
|
1281
|
+
@error_count = 0 # reset error count
|
1282
|
+
do_parse
|
1283
|
+
else
|
1284
|
+
@error_count = 1
|
1285
|
+
fail AclError, "File: #{filename} not found."
|
1286
|
+
end
|
1287
|
+
rescue Racc::ParseError => err
|
1288
|
+
eputs(
|
1289
|
+
["Parse aborted. Found syntax error:",
|
1290
|
+
" #{err.message}"
|
1291
|
+
].join("\n")
|
1292
|
+
)
|
1293
|
+
rescue AclArgumentError => err
|
1294
|
+
eputs(
|
1295
|
+
["Parse aborted. Found acl argment error:",
|
1296
|
+
" #{err.message}",
|
1297
|
+
" #{err_pos_str}"
|
1298
|
+
].join("\n")
|
1299
|
+
)
|
1300
|
+
rescue AclError => err
|
1301
|
+
eputs(
|
1302
|
+
["Parse aborted. Found acl error:",
|
1303
|
+
" #{err.message}"
|
1304
|
+
].join("\n")
|
1305
|
+
)
|
1306
|
+
rescue => err
|
1307
|
+
eputs(
|
1308
|
+
[ "Parse aborted. Found unknown error:",
|
1309
|
+
" #{err.message}"
|
1310
|
+
].join("\n")
|
1311
|
+
)
|
1312
|
+
end
|
1313
|
+
@acl_table
|
1314
|
+
end
|
1315
|
+
|
1316
|
+
# Syntax error handler
|
1317
|
+
# @raise [Racc::ParseError]
|
1318
|
+
def on_error tok, val, vstack
|
1319
|
+
errstr = [
|
1320
|
+
err_pos_str,
|
1321
|
+
"near value: #{val}",
|
1322
|
+
"(token: #{token_to_str(tok)})",
|
1323
|
+
].join(', ')
|
1324
|
+
|
1325
|
+
# raise Racc::ParseError, errstr
|
1326
|
+
eputs errstr
|
1327
|
+
end
|
1328
|
+
|
1329
|
+
# Parsed data contains error or not?
|
1330
|
+
# @return [Boolean]
|
1331
|
+
def contains_error?
|
1332
|
+
@error_count > 0 ? true : false
|
1333
|
+
end
|
1334
|
+
|
1335
|
+
private
|
1336
|
+
|
1337
|
+
# count syntax error
|
1338
|
+
def count_error
|
1339
|
+
@error_count = @error_count + 1
|
1340
|
+
end
|
1341
|
+
|
1342
|
+
# print error message and enter error recovery mode
|
1343
|
+
# @param [String] str Error message
|
1344
|
+
def yyerror_with str
|
1345
|
+
eputs [err_pos_str, str].join(', ')
|
1346
|
+
yyerror
|
1347
|
+
end
|
1348
|
+
|
1349
|
+
# normal err print
|
1350
|
+
# @param [String] str Message string
|
1351
|
+
def eputs str
|
1352
|
+
count_error
|
1353
|
+
puts c_err(str) unless @silent_mode
|
1354
|
+
end
|
1355
|
+
|
1356
|
+
# debug print
|
1357
|
+
# @param [String] str String to print
|
1358
|
+
def dputs str
|
1359
|
+
puts str if @debug_print
|
1360
|
+
end
|
1361
|
+
|
1362
|
+
# Get next token
|
1363
|
+
# @return [Array] Next token array
|
1364
|
+
def next_token
|
1365
|
+
@queue.shift
|
1366
|
+
end
|
1367
|
+
|
1368
|
+
# Coloring error string
|
1369
|
+
# @param [String] str Message string
|
1370
|
+
# @return [String] Colored message string
|
1371
|
+
def c_err str
|
1372
|
+
if @color_mode
|
1373
|
+
c = Term::ANSIColor
|
1374
|
+
str = [c.red, c.bold, str, c.clear].join
|
1375
|
+
end
|
1376
|
+
str
|
1377
|
+
end
|
1378
|
+
|
1379
|
+
# Generate error string
|
1380
|
+
# @return [String] error position string
|
1381
|
+
def err_pos_str
|
1382
|
+
line_num = @acl_table[@curr_acl_name] ?
|
1383
|
+
@acl_table[@curr_acl_name].length + 1 : ''
|
1384
|
+
["in acl: #{@curr_acl_name}",
|
1385
|
+
"line: #{line_num}"
|
1386
|
+
].join(', ')
|
1387
|
+
end
|
1388
|
+
|
1389
|
+
---- footer
|
1390
|
+
|
1391
|
+
end # module
|
1392
|
+
|
1393
|
+
### Local variables:
|
1394
|
+
### mode: Racc
|
1395
|
+
### coding: utf-8-unix
|
1396
|
+
### indent-tabs-mode: nil
|
1397
|
+
### End:
|