grammars/capirca.cson (210 lines of code) (raw):
#
# Copyright (c) Facebook, Inc. and its affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.
#
'scopeName': 'source.capirca'
'name': 'Capirca'
'fileTypes': [
'pol',
'svc',
'net',
'inc'
]
'patterns': [
{
# Number sign comments
'begin': '(^[ \\t]+)?(?=#(?!include))'
'beginCaptures':
'1':
'name': 'punctuation.whitespace.comment.leading.capirca'
'end': '(?!\\G)'
'patterns': [
{
'begin': '#'
'beginCaptures':
'0':
'name': 'punctuation.definition.comment.capirca'
'end': '\\n'
'name': 'comment.line.number-sign.capirca'
}
]
}
# comment:: or file-comment lines
{
'match': '^(?:\\s+)?((?:file-)?comment\\:\\: ?.*)'
'name': 'comment.line.number.capirca'
}
# pound include statements
{
'begin': '#include'
'end': '\\n'
'name': 'string.quoted.capirca'
}
# generic double colon keywords supported by all platforms
{
'match': '^(?:\\s+)?((?:protocol(?:-except)?|option|action|counter|logging|(?:source|destination)-(?:port|address|exclude)|target|verbatim|platform-exclude|platform))(::)'
'captures':
'1':
'name': 'support.function.capirca'
'2':
'name': 'keyword.operator.capirca'
}
# cisco specific double colon keywords
{
'match': '^(?:\\s+)?((?:dscp-match|owner|address|logging))(::)'
'captures':
'1':
'name': 'support.function.capirca'
'2':
'name': 'keyword.operator.capirca'
}
# juniper/srx specific double colon keywords
{
'match': '^(?:\\s+)?((?:address|application|apply-groups|counter|(?:source|destination)-(?:prefix(?:-except)?|tag)|dscp-(?:match|except|set)|ether-type|fragment-offset|flexible-match-range|forwarding-class(?:-except)?|hop-limit|icmp-type|logging|loss-priority|next-ip|owner|packet-length|precedence|policer|port|qos|routing-instance|(?:source|destination)-interface|timeout|traffic-(?:type|class-count)|vpn))(::)'
'captures':
'1':
'name': 'support.function.capirca'
'2':
'name': 'keyword.operator.capirca'
}
# Palo Alto specific double colon keywords
{
'match': '^(?:\\s+)?((?:name|pan-application|translated|export-log))(::)'
'captures':
'1':
'name': 'support.function.capirca'
'2':
'name': 'keyword.operator.capirca'
}
# squid specific double colon keywords
{
'match': '^(?:\\s+)?((?:(?:source|destination)-domain(?:-regex)?|urlpath-regex|method))(::)'
'captures':
'1':
'name': 'support.function.capirca'
'2':
'name': 'keyword.operator.capirca'
}
# squid method:: constants
{
'match': '(?<=method::)\\s*((?:GET|get|POST|post|HEAD|head|PUT|put|DELETE|delete|OPTIONS|options|CONNECT|connect)\\b\\s?)+'
'captures':
# intentionally zero, to get the entire matched capture group, as we could
# have multiple methods on one line, like so:
# method:: connect get post
# |<- captured ->|
'0':
'name': 'constant.language.capirca'
'name': ''
}
# option:: constants
{
'match': '(?<=option::)\\s*(established|tcp-established|sample|(?:tcp-)?initial|(first|is)-fragment|(?:source|destination)-is-user|negate|syn|ack|fin|rst|urg|psh|all|none)'
'captures':
'1':
'name': 'constant.language.capirca'
'name': ''
}
# action:: constants that are acceptance (deny/rejects get shown as invalid below)
{
'match': '(?<=action::)\\s*(accept|next|dscp|log|count)'
'captures':
'1':
'name': 'constant.language.capirca'
'name': ''
}
# target:: / platform:: constants
{
'match': '(?<=target::|platform::|platform-exclude::)\\s*(arista|aruba|brocade|cisco(?:-?xr|-xe|asa)?|gce|ipset|(?:ip|nf)tables|juniper(?:qfx)?|nsxv|panfw|paloalto|pcap|speedway|srx(?:lo)?|squid|vshield|windows(?:_advfirewall|_ipsec)?)'
'captures':
'1':
'name': 'constant.language.capirca'
'name': ''
}
# logging:: constants
{
'match': '(?<=logging::)\\s*(true)'
'captures':
'1':
'name': 'constant.language.capirca'
'name': ''
}
# protocol:: constants - matches any number 0-255, or specific named protocols that capirca accepts
{
'match': '(?<=protocol::)\\s*((\\d\\d?|1\\d\\d|2[0-5][0-5]|ah|egp|esp|fragment|ggp|gre|icmp(?:v6)?|igmp|igp|ipencap|ipip|ipv6(?:-frag|-nonxt|-opts|-route)?|l2tp|ospf|pim|rdp|rsvp|sctp|tcp|udp|vrrp)\\s*)+(?:\\n|#|})'
'captures':
'0':
'name': 'constant.language.capirca'
'name': ''
}
# user defined names, network/port groups in terms, counter names, etc
{
'match': '(?<=counter::|qos::|policer::|source-port::|destination-port::|source-address::|destination-address::|source-prefix::|destination-prefix::|source-exclude::|destination-exclude::)\\s*([\\w\\-\\.\\s]+)(?=\\n|#|})'
'captures':
'1':
'name': 'variable.language.capirca'
'name': ''
}
# term names
{
'begin': '^\\s*(term)\\s+([\\w\\-\\.]+) ?'
'beginCaptures':
'1':
'name': 'storage.type.capirca'
'2':
'name': 'entity.name.function.capirca'
'end': '{'
'name': 'meta.function.capirca'
}
# headers
{
'begin': '^\\s*(header)(\\s+)?'
'beginCaptures':
'1':
'name': 'storage.type.capirca'
'end': '{'
'name': 'meta.function.capirca'
}
# make deny statements pop as invalid
{
'match': '(?<=action::)(?:\\s*)(deny|reject(-with-tcp-rst)?)'
'captures':
'1':
'name': 'invalid.illegal.capirca'
'name': ''
}
# make expiration statements pop as invalid
{
'match': '\\b(expiration)(::)'
'captures':
'1':
'name': 'invalid.illegal.capirca'
'2':
'name': 'keyword.operator.capirca'
'name': ''
}
# Service and network definitions
{
'match': '^\\s*([\\w\\-\\.]+)\\s*(=)'
'captures':
'1':
'name': 'variable.language.capirca'
'2':
'name': 'keyword.operator.capirca'
'name': 'meta.function.capirca'
}
# IPv4 addresses
{
'match': '\\b((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))([/]\\d{1,2})?\\b'
'name': 'constant.numeric.integer.long.octal.capirca'
}
# IPv6 addresses
{
'comment': 'This will not fully validate the structure of the IP, so some invalid IPv6 addresses might be false positives.',
'name': 'constant.numeric.integer.long.octal.capirca',
'match': '(?:\\b)((?=.*::)(?!.*::.+::)(::)?([\\dA-Fa-f]{1,4}:(:|\\b)|){5}|([\\dA-Fa-f]{1,4}:){6})((([\\dA-Fa-f]{1,4}(::|:\\b|[/]\\d+|))|(?!\\3\\4)){2}|(((2[0-4]|1\\d|[1-9])?\\d|25[0-5])\\.?){4})([/]\\d{1,3})?(?:\\s)'
}
]