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
;
33 struct dec_octet
: sor
<seq
<string
<'2','5'>, range
<'0','5'>>,
34 seq
<one
<'2'>, range
<'0','4'>, DIGIT
>,
35 seq
<one
<'1'>, rep
<2, DIGIT
>>,
36 seq
<range
<'1', '9'>, DIGIT
>,
41 : seq
<dec_octet
, dot
, dec_octet
, dot
, dec_octet
, dot
, dec_octet
, eof
> {
44 struct ipv4_address_lit
: seq
<one
<'['>,
58 template <typename Rule
>
59 struct action
: nothing
<Rule
> {
63 struct action
<dec_octet
> {
64 template <typename Input
>
65 static void apply(Input
const& in
, std::vector
<std::string
>& a
)
67 a
.push_back(in
.string());
71 // <https://en.wikipedia.org/wiki/Private_network#Private_IPv4_addresses>
73 auto is_private(std::string_view addr
) -> bool
75 std::vector
<std::string
> a
;
78 memory_input
<> in
{addr
.data(), addr
.size(), "addr"};
79 CHECK((parse
<ipv4_address
, action
>(in
, a
)));
81 // <https://tools.ietf.org/html/rfc1918#section-3>
83 // 10.0.0.0 - 10.255.255.255 (10/8 prefix)
84 // 172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
85 // 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
91 // auto const oct = atoi(a[1].c_str());
94 std::from_chars(a
[1].data(), a
[1].data() + a
[1].size(), oct
);
96 return (16 <= oct
) && (oct
<= 31);
99 return (a
[0] == "192") && (a
[1] == "168");
102 auto is_address(std::string_view addr
) -> bool
104 memory_input
<> in
{addr
.data(), addr
.size(), "addr"};
105 return parse
<ipv4_address
>(in
);
108 auto is_address_literal(std::string_view addr
) -> bool
110 memory_input
<> in
{addr
.data(), addr
.size(), "addr"};
111 return parse
<ipv4_address_lit
>(in
);
114 auto to_address_literal(std::string_view addr
) -> std::string
116 CHECK(is_address(addr
));
117 return fmt::format("{}{}{}", lit_pfx
, addr
, lit_sfx
);
120 std::string
reverse(std::string_view addr
)
122 std::vector
<std::string
> a
;
125 auto in
{memory_input
<>{addr
.data(), addr
.size(), "addr"}};
126 CHECK((parse
<ipv4_address
, action
>(in
, a
)));
128 return fmt::format("{}.{}.{}.{}.", a
[3], a
[2], a
[1], a
[0]);