5 #include <glog/logging.h>
7 #include <fmt/format.h>
9 #include <tao/pegtl.hpp>
10 #include <tao/pegtl/contrib/abnf.hpp>
12 using tao::pegtl::action
;
13 using tao::pegtl::eof
;
14 using tao::pegtl::memory_input
;
15 using tao::pegtl::nothing
;
16 using tao::pegtl::one
;
17 using tao::pegtl::parse
;
18 using tao::pegtl::range
;
19 using tao::pegtl::rep
;
20 using tao::pegtl::rep_min_max
;
21 using tao::pegtl::seq
;
22 using tao::pegtl::sor
;
23 using tao::pegtl::string
;
25 using tao::pegtl::abnf::DIGIT
;
32 struct dec_octet
: sor
<seq
<string
<'2','5'>, range
<'0','5'>>,
33 seq
<one
<'2'>, range
<'0','4'>, DIGIT
>,
34 seq
<range
<'0', '1'>, rep
<2, DIGIT
>>,
35 rep_min_max
<1, 2, DIGIT
>> {};
40 : seq
<dec_octet
, dot
, dec_octet
, dot
, dec_octet
, dot
, dec_octet
, eof
> {
43 struct ipv4_address_lit
: seq
<one
<'['>,
55 template <typename Rule
>
56 struct action
: nothing
<Rule
> {
60 struct action
<dec_octet
> {
61 template <typename Input
>
62 static void apply(Input
const& in
, std::vector
<std::string
>& a
)
64 a
.push_back(in
.string());
68 // <https://en.wikipedia.org/wiki/Private_network#Private_IPv4_addresses>
70 auto is_private(std::string_view addr
) -> bool
72 std::vector
<std::string
> a
;
75 memory_input
<> in
{addr
.data(), addr
.size(), "addr"};
76 CHECK((parse
<ipv4_address
, action
>(in
, a
)));
78 // <https://tools.ietf.org/html/rfc1918#section-3>
80 // 10.0.0.0 - 10.255.255.255 (10/8 prefix)
81 // 172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
82 // 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
88 // auto const oct = atoi(a[1].c_str());
91 std::from_chars(a
[1].data(), a
[1].data() + a
[1].size(), oct
);
93 return (16 <= oct
) && (oct
<= 31);
96 return (a
[0] == "192") && (a
[1] == "168");
99 auto is_address(std::string_view addr
) -> bool
101 memory_input
<> in
{addr
.data(), addr
.size(), "addr"};
102 return parse
<ipv4_address
>(in
);
105 auto is_address_literal(std::string_view addr
) -> bool
107 memory_input
<> in
{addr
.data(), addr
.size(), "addr"};
108 return parse
<ipv4_address_lit
>(in
);
111 auto to_address_literal(std::string_view addr
) -> std::string
113 // CHECK(is_address(addr));
114 return fmt::format("{}{}{}", lit_pfx
, addr
, lit_sfx
);
117 auto reverse(std::string_view addr
) -> std::string
119 std::vector
<std::string
> a
;
122 auto in
{memory_input
<>{addr
.data(), addr
.size(), "addr"}};
123 CHECK((parse
<ipv4_address
, action
>(in
, a
)));
125 return fmt::format("{}.{}.{}.{}.", a
[3], a
[2], a
[1], a
[0]);