/***
This file is part of systemd.
Copyright 2014 Lennart Poettering
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <endian.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include "alloc-util.h"
#include "in-addr-util.h"
#include "macro.h"
#include "util.h"
assert(u);
return
return -EAFNOSUPPORT;
}
assert(u);
return (be32toh(u->in.s_addr) & UINT32_C(0xFFFF0000)) == (UINT32_C(169) << 24 | UINT32_C(254) << 16);
return IN6_IS_ADDR_LINKLOCAL(&u->in6);
return -EAFNOSUPPORT;
}
assert(u);
/* All of 127.x.x.x is localhost. */
return IN6_IS_ADDR_LOOPBACK(&u->in6);
return -EAFNOSUPPORT;
}
assert(a);
assert(b);
return
return -EAFNOSUPPORT;
}
int family,
const union in_addr_union *a,
unsigned aprefixlen,
const union in_addr_union *b,
unsigned bprefixlen) {
unsigned m;
assert(a);
assert(b);
/* Checks whether there are any addresses that are in both
* networks */
return (x & nm) == 0;
}
unsigned i;
if (m > 128)
m = 128;
for (i = 0; i < 16; i++) {
if (m < 8)
else
nm = 0xFF;
if ((x & nm) != 0)
return 0;
if (m > 8)
m -= 8;
else
m = 0;
}
return 1;
}
return -EAFNOSUPPORT;
}
assert(u);
/* Increases the network part of an address by one. Returns
* positive it that succeeds, or 0 if this overflows. */
if (prefixlen <= 0)
return 0;
uint32_t c, n;
if (prefixlen > 32)
prefixlen = 32;
if (n < c)
return 0;
return 1;
}
unsigned i;
if (prefixlen > 128)
prefixlen = 128;
/* First calculate what we have to add */
for (i = 16; i > 0; i--) {
unsigned j = i - 1;
}
if (overflow)
return 0;
return 1;
}
return -EAFNOSUPPORT;
}
char *x;
size_t l;
assert(u);
l = INET_ADDRSTRLEN;
l = INET6_ADDRSTRLEN;
else
return -EAFNOSUPPORT;
x = new(char, l);
if (!x)
return -ENOMEM;
errno = 0;
free(x);
}
*ret = x;
return 0;
}
assert(s);
return -EAFNOSUPPORT;
errno = 0;
return 0;
}
int r;
assert(s);
if (r >= 0) {
return 0;
}
if (r >= 0) {
return 0;
}
return -EINVAL;
}
}
/* Shifting beyond 32 is not defined, handle this specially. */
if (prefixlen == 0)
else
return addr;
}
/* addr may not be aligned, so make sure we only access it byte-wise */
if (msb_octet < 128)
/* class A, leading bits: 0 */
*prefixlen = 8;
else if (msb_octet < 192)
/* class B, leading bits 10 */
*prefixlen = 16;
else if (msb_octet < 224)
/* class C, leading bits 110 */
*prefixlen = 24;
else
/* class D or E, no default prefixlen */
return -ERANGE;
return 0;
}
unsigned char prefixlen;
int r;
if (r < 0)
return r;
return 0;
}
return -EINVAL;
return 0;
}
unsigned i;
for (i = 0; i < 16; i++) {
if (prefixlen >= 8) {
mask = 0xFF;
prefixlen -= 8;
} else {
prefixlen = 0;
}
}
return 0;
}
return -EAFNOSUPPORT;
}