mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-12-22 08:58:00 +01:00
145 lines
5 KiB
Elixir
145 lines
5 KiB
Elixir
defmodule PhilomenaQuery.Parse.IpParser do
|
|
@moduledoc false
|
|
|
|
import NimbleParsec
|
|
|
|
ipv4_octet =
|
|
choice([
|
|
ascii_char(~c"2") |> ascii_char(~c"5") |> ascii_char([?0..?5]),
|
|
ascii_char(~c"2") |> ascii_char([?0..?4]) |> ascii_char([?0..?9]),
|
|
ascii_char(~c"1") |> ascii_char([?0..?9]) |> ascii_char([?0..?9]),
|
|
ascii_char([?1..?9]) |> ascii_char([?0..?9]),
|
|
ascii_char([?0..?9])
|
|
])
|
|
|> reduce({List, :to_string, []})
|
|
|
|
ipv4_address =
|
|
times(ipv4_octet |> string("."), 3)
|
|
|> concat(ipv4_octet)
|
|
|
|
ipv4_prefix =
|
|
ascii_char(~c"/")
|
|
|> choice([
|
|
ascii_char(~c"3") |> ascii_char([?0..?2]),
|
|
ascii_char([?1..?2]) |> ascii_char([?0..?9]),
|
|
ascii_char([?0..?9])
|
|
])
|
|
|> reduce({List, :to_string, []})
|
|
|
|
ipv6_hexadectet = ascii_string(~c"0123456789abcdefABCDEF", min: 1, max: 4)
|
|
|
|
ipv6_ls32 =
|
|
choice([
|
|
ipv6_hexadectet |> string(":") |> concat(ipv6_hexadectet),
|
|
ipv4_address
|
|
])
|
|
|
|
ipv6_fragment = ipv6_hexadectet |> string(":")
|
|
|
|
ipv6_address =
|
|
choice([
|
|
times(ipv6_fragment, 6) |> concat(ipv6_ls32),
|
|
string("::") |> times(ipv6_fragment, 5) |> concat(ipv6_ls32),
|
|
ipv6_hexadectet |> string("::") |> times(ipv6_fragment, 4) |> concat(ipv6_ls32),
|
|
string("::") |> times(ipv6_fragment, 4) |> concat(ipv6_ls32),
|
|
times(ipv6_fragment, 1)
|
|
|> concat(ipv6_hexadectet)
|
|
|> string("::")
|
|
|> times(ipv6_fragment, 3)
|
|
|> concat(ipv6_ls32),
|
|
ipv6_hexadectet |> string("::") |> times(ipv6_fragment, 3) |> concat(ipv6_ls32),
|
|
string("::") |> times(ipv6_fragment, 3) |> concat(ipv6_ls32),
|
|
times(ipv6_fragment, 2)
|
|
|> concat(ipv6_hexadectet)
|
|
|> string("::")
|
|
|> times(ipv6_fragment, 2)
|
|
|> concat(ipv6_ls32),
|
|
times(ipv6_fragment, 1)
|
|
|> concat(ipv6_hexadectet)
|
|
|> string("::")
|
|
|> times(ipv6_fragment, 2)
|
|
|> concat(ipv6_ls32),
|
|
ipv6_hexadectet |> string("::") |> times(ipv6_fragment, 2) |> concat(ipv6_ls32),
|
|
string("::") |> times(ipv6_fragment, 2) |> concat(ipv6_ls32),
|
|
times(ipv6_fragment, 3)
|
|
|> concat(ipv6_hexadectet)
|
|
|> string("::")
|
|
|> concat(ipv6_fragment)
|
|
|> concat(ipv6_ls32),
|
|
times(ipv6_fragment, 2)
|
|
|> concat(ipv6_hexadectet)
|
|
|> string("::")
|
|
|> concat(ipv6_fragment)
|
|
|> concat(ipv6_ls32),
|
|
times(ipv6_fragment, 1)
|
|
|> concat(ipv6_hexadectet)
|
|
|> string("::")
|
|
|> concat(ipv6_fragment)
|
|
|> concat(ipv6_ls32),
|
|
ipv6_hexadectet |> string("::") |> concat(ipv6_fragment) |> concat(ipv6_ls32),
|
|
string("::") |> concat(ipv6_fragment) |> concat(ipv6_ls32),
|
|
times(ipv6_fragment, 4) |> concat(ipv6_hexadectet) |> string("::") |> concat(ipv6_ls32),
|
|
times(ipv6_fragment, 3) |> concat(ipv6_hexadectet) |> string("::") |> concat(ipv6_ls32),
|
|
times(ipv6_fragment, 2) |> concat(ipv6_hexadectet) |> string("::") |> concat(ipv6_ls32),
|
|
times(ipv6_fragment, 1) |> concat(ipv6_hexadectet) |> string("::") |> concat(ipv6_ls32),
|
|
ipv6_hexadectet |> string("::") |> concat(ipv6_ls32),
|
|
string("::") |> concat(ipv6_ls32),
|
|
times(ipv6_fragment, 5)
|
|
|> concat(ipv6_hexadectet)
|
|
|> string("::")
|
|
|> concat(ipv6_hexadectet),
|
|
times(ipv6_fragment, 4)
|
|
|> concat(ipv6_hexadectet)
|
|
|> string("::")
|
|
|> concat(ipv6_hexadectet),
|
|
times(ipv6_fragment, 3)
|
|
|> concat(ipv6_hexadectet)
|
|
|> string("::")
|
|
|> concat(ipv6_hexadectet),
|
|
times(ipv6_fragment, 2)
|
|
|> concat(ipv6_hexadectet)
|
|
|> string("::")
|
|
|> concat(ipv6_hexadectet),
|
|
times(ipv6_fragment, 1)
|
|
|> concat(ipv6_hexadectet)
|
|
|> string("::")
|
|
|> concat(ipv6_hexadectet),
|
|
ipv6_hexadectet |> string("::") |> concat(ipv6_hexadectet),
|
|
string("::") |> concat(ipv6_hexadectet),
|
|
times(ipv6_fragment, 6) |> concat(ipv6_hexadectet) |> string("::"),
|
|
times(ipv6_fragment, 5) |> concat(ipv6_hexadectet) |> string("::"),
|
|
times(ipv6_fragment, 4) |> concat(ipv6_hexadectet) |> string("::"),
|
|
times(ipv6_fragment, 3) |> concat(ipv6_hexadectet) |> string("::"),
|
|
times(ipv6_fragment, 2) |> concat(ipv6_hexadectet) |> string("::"),
|
|
times(ipv6_fragment, 1) |> concat(ipv6_hexadectet) |> string("::"),
|
|
ipv6_hexadectet |> string("::"),
|
|
string("::")
|
|
])
|
|
|
|
ipv6_prefix =
|
|
ascii_char(~c"/")
|
|
|> choice([
|
|
ascii_char(~c"1") |> ascii_char(~c"2") |> ascii_char([?0..?8]),
|
|
ascii_char(~c"1") |> ascii_char([?0..?1]) |> ascii_char([?0..?9]),
|
|
ascii_char([?1..?9]) |> ascii_char([?0..?9]),
|
|
ascii_char([?0..?9])
|
|
])
|
|
|> reduce({List, :to_string, []})
|
|
|
|
space =
|
|
choice([string(" "), string("\t"), string("\n"), string("\r"), string("\v"), string("\f")])
|
|
|> ignore()
|
|
|
|
ip =
|
|
choice([
|
|
ipv4_address |> optional(ipv4_prefix),
|
|
ipv6_address |> optional(ipv6_prefix)
|
|
])
|
|
|> reduce({Enum, :join, []})
|
|
|> repeat(space)
|
|
|> unwrap_and_tag(:ip)
|
|
|> eos()
|
|
|> label("a valid IPv4 or IPv6 address and optional CIDR prefix")
|
|
|
|
defparsec(:parse, ip)
|
|
end
|