Skip to content

Instantly share code, notes, and snippets.

@ackerleytng
Last active July 1, 2019 14:39
Show Gist options
  • Save ackerleytng/8b4192ac4eaa5945a7ede70eb3c0e41f to your computer and use it in GitHub Desktop.
Save ackerleytng/8b4192ac4eaa5945a7ede70eb3c0e41f to your computer and use it in GitHub Desktop.
(ns snort-parser.core
(:require [instaparse.core :as insta]))
(def variables-parser
(insta/parser
"variable-definitions = variable-definition (newline variable-definition)* newline?
variable-definition = var | portvar | ipvar
var = 'var' whitespace variable-name whitespace var-value
var-value = #'\\S+'
portvar = 'portvar' whitespace variable-name whitespace portvar-value
portvar-value = port-negation? ( port | port-group | port-any | variable-sub )
port-any = 'any'
port-group = '[' port-group-items ']'
<port-group-items> = portvar-value ( ',' portvar-value )*
port-range = #'\\d+' ':' #'\\d+'
port-negation = '!'
port = #'\\d+'
ipvar = 'ipvar' whitespace variable-name whitespace ipvar-value
ipvar-value = ip-negation? ( ipv4 | ipv4-cidr-block | ipv6 | ipv6-cidr-block | ip-group | ip-any | variable-sub )
ip-any = 'any'
ip-group = '[' ip-group-items ']'
<ip-group-items> = ipvar-value ( ',' ipvar-value )*
ip-negation = '!'
ipv4 = #'\\d+.\\d+.\\d+.\\d+'
ipv4-cidr-block = ipv4 '/' cidr-range
(* Looser regex than it can be *)
ipv6 = #'[a-fA-F0-9]{0,4}(:[a-fA-F0-9]{0,4}){1,7}'
ipv6-cidr-block = ipv6 '/' cidr-range
cidr-range = #'\\d+'
variable-sub = variable-sub-regular | variable-sub-paren | variable-sub-default | variable-sub-msg
variable-sub-regular = '$' variable-name
variable-sub-paren = '$(' variable-name ')'
variable-sub-default = '$(' variable-name ':-' #'[^)]' ')'
variable-sub-msg = '$(' variable-name ':?' #'[^)]' ')'
variable-name = #'[A-Za-z_]\\w*'
<newline> = '\\n' | '\\r\\n'
<whitespace> = #'\\s+'"))
(variables-parser "ipvar IPV6 1:1::1:1/80")
;; => [:variable-definitions [:variable-definition [:ipvar "ipvar" " " [:variable-name "IPV6"] " " [:ipvar-value [:ipv6-cidr-block [:ipv6 "1:1::1:1"] "/" [:cidr-range "80"]]]]]]
(variables-parser "ipvar IPV4 192.168.1.1")
;; => [:variable-definitions [:variable-definition [:ipvar "ipvar" " " [:variable-name "IPV4"] " " [:ipvar-value [:ipv4 "192.168.1.1"]]]]]
(variables-parser "ipvar IPV4 192.168.1.1\nportvar HTTP_PORTS [80,443]")
;; => [:variable-definitions [:variable-definition [:ipvar "ipvar" " " [:variable-name "IPV4"] " " [:ipvar-value [:ipv4 "192.168.1.1"]]]] "\n" [:variable-definition [:portvar "portvar" " " [:variable-name "HTTP_PORTS"] " " [:portvar-value [:port-group "[" [:portvar-value [:port "80"]] "," [:portvar-value [:port "443"]] "]"]]]]]
(variables-parser "ipvar IPV4 192.168.1.1\nportvar HTTP_PORTS [80,443]\nportvar HTTP_ZZZ [$HTTP_PORTS,23]")
;; => [:variable-definitions [:variable-definition [:ipvar "ipvar" " " [:variable-name "IPV4"] " " [:ipvar-value [:ipv4 "192.168.1.1"]]]] "\n" [:variable-definition [:portvar "portvar" " " [:variable-name "HTTP_PORTS"] " " [:portvar-value [:port-group "[" [:portvar-value [:port "80"]] "," [:portvar-value [:port "443"]] "]"]]]] "\n" [:variable-definition [:portvar "portvar" " " [:variable-name "HTTP_ZZZ"] " " [:portvar-value [:port-group "[" [:portvar-value [:variable-sub [:variable-sub-regular "$" [:variable-name "HTTP_PORTS"]]]] "," [:portvar-value [:port "23"]] "]"]]]]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment