diff options
Diffstat (limited to 'src/common/ip.hpp')
-rw-r--r-- | src/common/ip.hpp | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/src/common/ip.hpp b/src/common/ip.hpp new file mode 100644 index 0000000..e67056c --- /dev/null +++ b/src/common/ip.hpp @@ -0,0 +1,150 @@ +#ifndef TMWA_COMMON_IP_HPP +#define TMWA_COMMON_IP_HPP +// ip.hpp - classes to deal with IP addresses. +// +// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "sanity.hpp" + +#include "extract.hpp" +#include "strings.hpp" + +// TODO - in the long run ports belong here also +// and of course, IPv6 stuff. +// But what about unix socket addresses? + +/// Helper function +template<class T, size_t n> +constexpr +bool _ce_a_lt(T (&a)[n], T (&b)[n], size_t i=0) +{ + return (i != n + && (a[i] < b[i] + || (a[i] == b[i] + && _ce_a_lt(a, b, i + 1)))); +} + +/// A 32-bit Ipv4 address. Does not include a port. +/// Guaranteed to be laid out like the network wants. +class IP4Address +{ + uint8_t _addr[4]; +public: + constexpr + IP4Address() + : _addr{} + {} + constexpr explicit + IP4Address(const uint8_t (&a)[4]) + : _addr{a[0], a[1], a[2], a[3]} + {} + + constexpr friend + IP4Address operator & (IP4Address l, IP4Address r) + { + return IP4Address({ + static_cast<uint8_t>(l._addr[0] & r._addr[0]), + static_cast<uint8_t>(l._addr[1] & r._addr[1]), + static_cast<uint8_t>(l._addr[2] & r._addr[2]), + static_cast<uint8_t>(l._addr[3] & r._addr[3]), + }); + } + + IP4Address& operator &= (IP4Address m) + { return *this = *this & m; } + + const uint8_t *bytes() const + { return _addr; } + + constexpr friend + bool operator < (IP4Address l, IP4Address r) + { + return _ce_a_lt(l._addr, r._addr); + } + + constexpr friend + bool operator > (IP4Address l, IP4Address r) + { + return _ce_a_lt(r._addr, l._addr); + } + + constexpr friend + bool operator >= (IP4Address l, IP4Address r) + { + return !_ce_a_lt(l._addr, r._addr); + } + + constexpr friend + bool operator <= (IP4Address l, IP4Address r) + { + return !_ce_a_lt(r._addr, l._addr); + } + + constexpr friend + bool operator == (IP4Address l, IP4Address r) + { + return !(l < r || r < l); + } + + constexpr friend + bool operator != (IP4Address l, IP4Address r) + { + return (l < r || r < l); + } +}; + +class IP4Mask +{ + IP4Address _addr, _mask; +public: + constexpr + IP4Mask() : _addr(), _mask() + {} + constexpr + IP4Mask(IP4Address a, IP4Address m) : _addr(a & m), _mask(m) + {} + + constexpr + IP4Address addr() const + { return _addr; } + constexpr + IP4Address mask() const + { return _mask; } + + constexpr + bool covers(IP4Address a) const + { + return (a & _mask) == _addr; + } +}; + + +constexpr +IP4Address IP4_LOCALHOST({127, 0, 0, 1}); +constexpr +IP4Address IP4_BROADCAST({255, 255, 255, 255}); + + +VString<15> convert_for_printf(IP4Address a); +VString<31> convert_for_printf(IP4Mask m); + +bool extract(XString str, IP4Address *iv); + +bool extract(XString str, IP4Mask *iv); + +#endif // TMWA_COMMON_IP_HPP |