2011-09-13 21:26:12 +02:00
|
|
|
// ndppd - NDP Proxy Daemon
|
2012-01-26 11:21:07 +01:00
|
|
|
// Copyright (C) 2011 Daniel Adolfsson <daniel@priv.nu>
|
2011-09-13 21:26:12 +02:00
|
|
|
//
|
|
|
|
// 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 <string>
|
|
|
|
#include <vector>
|
|
|
|
#include <map>
|
|
|
|
|
|
|
|
#include <cstring>
|
|
|
|
#include <cstdio>
|
|
|
|
#include <cstdlib>
|
2012-01-26 11:38:54 +01:00
|
|
|
#include <cctype>
|
2011-09-13 21:26:12 +02:00
|
|
|
|
|
|
|
#include <netinet/ip6.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
|
|
|
#include "ndppd.h"
|
|
|
|
#include "address.h"
|
|
|
|
|
|
|
|
__NDPPD_NS_BEGIN
|
|
|
|
|
|
|
|
address::address()
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
reset();
|
2011-09-13 21:26:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
address::address(const address& addr)
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
_addr.s6_addr32[0] = addr._addr.s6_addr32[0];
|
|
|
|
_addr.s6_addr32[1] = addr._addr.s6_addr32[1];
|
|
|
|
_addr.s6_addr32[2] = addr._addr.s6_addr32[2];
|
|
|
|
_addr.s6_addr32[3] = addr._addr.s6_addr32[3];
|
|
|
|
|
|
|
|
_mask.s6_addr32[0] = addr._mask.s6_addr32[0];
|
|
|
|
_mask.s6_addr32[1] = addr._mask.s6_addr32[1];
|
|
|
|
_mask.s6_addr32[2] = addr._mask.s6_addr32[2];
|
|
|
|
_mask.s6_addr32[3] = addr._mask.s6_addr32[3];
|
2011-09-13 21:26:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
address::address(const std::string& str)
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
parse_string(str);
|
2011-09-13 21:26:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
address::address(const char *str)
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
parse_string(str);
|
2011-09-13 21:26:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
address::address(const in6_addr& addr)
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
_addr.s6_addr32[0] = addr.s6_addr32[0];
|
|
|
|
_addr.s6_addr32[1] = addr.s6_addr32[1];
|
|
|
|
_addr.s6_addr32[2] = addr.s6_addr32[2];
|
|
|
|
_addr.s6_addr32[3] = addr.s6_addr32[3];
|
|
|
|
|
|
|
|
_mask.s6_addr32[0] = 0xffffffff;
|
|
|
|
_mask.s6_addr32[1] = 0xffffffff;
|
|
|
|
_mask.s6_addr32[2] = 0xffffffff;
|
|
|
|
_mask.s6_addr32[3] = 0xffffffff;
|
2011-09-13 21:26:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
address::address(const in6_addr& addr, const in6_addr& mask)
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
_addr.s6_addr32[0] = addr.s6_addr32[0];
|
|
|
|
_addr.s6_addr32[1] = addr.s6_addr32[1];
|
|
|
|
_addr.s6_addr32[2] = addr.s6_addr32[2];
|
|
|
|
_addr.s6_addr32[3] = addr.s6_addr32[3];
|
|
|
|
|
|
|
|
_mask.s6_addr32[0] = mask.s6_addr32[0];
|
|
|
|
_mask.s6_addr32[1] = mask.s6_addr32[1];
|
|
|
|
_mask.s6_addr32[2] = mask.s6_addr32[2];
|
|
|
|
_mask.s6_addr32[3] = mask.s6_addr32[3];
|
2011-09-13 21:26:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
address::address(const in6_addr& addr, int pf)
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
_addr.s6_addr32[0] = addr.s6_addr32[0];
|
|
|
|
_addr.s6_addr32[1] = addr.s6_addr32[1];
|
|
|
|
_addr.s6_addr32[2] = addr.s6_addr32[2];
|
|
|
|
_addr.s6_addr32[3] = addr.s6_addr32[3];
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
prefix(pf);
|
2011-09-13 21:26:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool address::operator==(const address& addr) const
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
return !(((_addr.s6_addr32[0] ^ addr._addr.s6_addr32[0]) & _mask.s6_addr32[0]) |
|
|
|
|
((_addr.s6_addr32[1] ^ addr._addr.s6_addr32[1]) & _mask.s6_addr32[1]) |
|
|
|
|
((_addr.s6_addr32[2] ^ addr._addr.s6_addr32[2]) & _mask.s6_addr32[2]) |
|
|
|
|
((_addr.s6_addr32[3] ^ addr._addr.s6_addr32[3]) & _mask.s6_addr32[3]));
|
2011-09-13 21:26:12 +02:00
|
|
|
}
|
|
|
|
|
2011-09-18 01:31:27 +02:00
|
|
|
bool address::operator!=(const address& addr) const
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
return !!(((_addr.s6_addr32[0] ^ addr._addr.s6_addr32[0]) & _mask.s6_addr32[0]) |
|
|
|
|
((_addr.s6_addr32[1] ^ addr._addr.s6_addr32[1]) & _mask.s6_addr32[1]) |
|
|
|
|
((_addr.s6_addr32[2] ^ addr._addr.s6_addr32[2]) & _mask.s6_addr32[2]) |
|
|
|
|
((_addr.s6_addr32[3] ^ addr._addr.s6_addr32[3]) & _mask.s6_addr32[3]));
|
|
|
|
}
|
|
|
|
|
|
|
|
void address::reset()
|
|
|
|
{
|
|
|
|
_addr.s6_addr32[0] = 0;
|
|
|
|
_addr.s6_addr32[1] = 0;
|
|
|
|
_addr.s6_addr32[2] = 0;
|
|
|
|
_addr.s6_addr32[3] = 0;
|
|
|
|
|
|
|
|
_mask.s6_addr32[0] = 0xffffffff;
|
|
|
|
_mask.s6_addr32[1] = 0xffffffff;
|
|
|
|
_mask.s6_addr32[2] = 0xffffffff;
|
|
|
|
_mask.s6_addr32[3] = 0xffffffff;
|
2011-09-18 01:31:27 +02:00
|
|
|
}
|
|
|
|
|
2011-09-13 21:26:12 +02:00
|
|
|
int address::prefix() const
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
if (!_mask.s6_addr[0])
|
|
|
|
return 0;
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
for (int p = 0; p < 128; p++) {
|
|
|
|
int byi = p / 8, bii = 7 - (p % 8);
|
|
|
|
if (!(_mask.s6_addr[byi] & (1 << bii)))
|
|
|
|
return p;
|
|
|
|
}
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
return 128;
|
2011-09-13 21:26:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void address::prefix(int pf)
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
if ((pf < 0) || (pf > 128))
|
|
|
|
return;
|
|
|
|
|
|
|
|
_mask.s6_addr32[0] = 0;
|
|
|
|
_mask.s6_addr32[1] = 0;
|
|
|
|
_mask.s6_addr32[2] = 0;
|
|
|
|
_mask.s6_addr32[3] = 0;
|
|
|
|
|
|
|
|
while (pf--) {
|
|
|
|
int byi = pf / 8, bii = 7 - (pf % 8);
|
|
|
|
_mask.s6_addr[byi] |= 1 << bii;
|
|
|
|
}
|
2011-09-13 21:26:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const std::string address::to_string() const
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
char buf[INET6_ADDRSTRLEN + 8];
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
if (!inet_ntop(AF_INET6, &_addr, buf, INET6_ADDRSTRLEN))
|
|
|
|
return "::1";
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
// TODO: What to do about invalid ip?
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
int p;
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
if ((p = prefix()) < 128)
|
|
|
|
sprintf(buf + strlen(buf), "/%d", p);
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
return buf;
|
2011-09-13 21:26:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool address::parse_string(const std::string& str)
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
char buf[INET6_ADDRSTRLEN], *b;
|
|
|
|
int sz, pfx;
|
|
|
|
|
|
|
|
sz = 0;
|
|
|
|
b = buf;
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
reset();
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
const char *p = str.c_str();
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
while (*p && isspace(*p))
|
|
|
|
p++;
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
while (*p) {
|
|
|
|
if ((*p == '/') || isspace(*p))
|
|
|
|
break;
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
if ((*p != ':') && !isxdigit(*p))
|
|
|
|
return false;
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
if (sz >= (INET6_ADDRSTRLEN - 1))
|
|
|
|
return false;
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
*b++ = *p++;
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
sz++;
|
|
|
|
}
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
*b = '\0';
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
if (inet_pton(AF_INET6, buf, &_addr) <= 0)
|
|
|
|
return false;
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
while (*p && isspace(*p))
|
|
|
|
p++;
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
if (*p == '\0') {
|
|
|
|
_mask.s6_addr32[0] = 0xffffffff;
|
|
|
|
_mask.s6_addr32[1] = 0xffffffff;
|
|
|
|
_mask.s6_addr32[2] = 0xffffffff;
|
|
|
|
_mask.s6_addr32[3] = 0xffffffff;
|
|
|
|
return true;
|
|
|
|
}
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
if (*p++ != '/')
|
|
|
|
return false;
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
while (*p && isspace(*p))
|
|
|
|
p++;
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
sz = 0;
|
|
|
|
b = buf;
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
while (*p) {
|
|
|
|
if (!isdigit(*p))
|
|
|
|
return false;
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
if (sz > 3)
|
|
|
|
return false;
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
*b++ = *p++;
|
|
|
|
sz++;
|
|
|
|
}
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
*b = '\0';
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
prefix(atoi(buf));
|
2011-09-13 21:26:12 +02:00
|
|
|
|
2012-01-28 20:25:57 +01:00
|
|
|
return true;
|
2011-09-13 21:26:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
address::operator std::string() const
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
return to_string();
|
2011-09-13 21:26:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
struct in6_addr& address::addr()
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
return _addr;
|
2011-09-13 21:26:12 +02:00
|
|
|
}
|
|
|
|
|
2011-09-14 10:53:21 +02:00
|
|
|
const struct in6_addr& address::const_addr() const
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
return _addr;
|
2011-09-14 10:53:21 +02:00
|
|
|
}
|
|
|
|
|
2011-09-13 21:26:12 +02:00
|
|
|
struct in6_addr& address::mask()
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
return _mask;
|
2011-09-13 21:26:12 +02:00
|
|
|
}
|
|
|
|
|
2011-09-18 01:31:27 +02:00
|
|
|
bool address::is_multicast() const
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
return _addr.s6_addr[0] == 0xff;
|
2011-09-18 01:31:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool address::is_unicast() const
|
|
|
|
{
|
2012-01-28 20:25:57 +01:00
|
|
|
return _addr.s6_addr[0] != 0xff;
|
2011-09-18 01:31:27 +02:00
|
|
|
}
|
|
|
|
|
2011-09-13 21:26:12 +02:00
|
|
|
__NDPPD_NS_END
|