#pragma once // ip.hpp - classes to deal with IP addresses. // // Copyright © 2013 Ben Longbons // // 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 . #include "fwd.hpp" #include #include #include #include namespace tmwa { // TODO - in the long run ports belong here also // and of course, IPv6 stuff. // But what about unix socket addresses? /// Helper function template 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]} {} explicit IP4Address(struct in_addr addr) { static_assert(sizeof(addr) == sizeof(_addr), "4 bytes"); *this = IP4Address(reinterpret_cast(addr)); } explicit operator struct in_addr() const { return reinterpret_cast(_addr); } constexpr friend IP4Address operator & (IP4Address l, IP4Address r) { return IP4Address({ static_cast(l._addr[0] & r._addr[0]), static_cast(l._addr[1] & r._addr[1]), static_cast(l._addr[2] & r._addr[2]), static_cast(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 impl_extract(XString str, IP4Address *iv); bool impl_extract(XString str, IP4Mask *iv); bool impl_extract(XString str, std::vector *iv); } // namespace tmwa