/*
* Copyright (c) 2019 Nikos Mavrogiannopoulos
*
* 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 2 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
#include
#include
#include
#include
#include
#include
#include
#include "ipcalc.h"
#include "ipv6.h"
static void deaggregate_v4(const char *ip1s, const char *ip2s, unsigned flags);
static void deaggregate_v6(const char *ip1s, const char *ip2s, unsigned flags);
static char *trim(char *str)
{
int len, i;
char *out;
len = strlen(str);
for (i=len-1;i>=0;i--) {
if (isspace(str[i]))
str[i] = 0;
else
break;
}
out = str;
for (i=0;i end) {
if (!beSilent)
fprintf(stderr, "ipcalc: bad range\n");
exit(1);
}
output_start(&jsonchain);
array_start(&jsonchain, "Deaggregated networks", "DEAGGREGATEDNETWORK");
while (base <= end) {
step = 0;
while ((base | (1 << step)) != base) {
if ((base | (UINT32_MAX >> (31-step))) > end)
break;
step++;
}
print_ipv4_net(&jsonchain, base, 32-step, flags);
base += (1 << step);
}
array_stop(&jsonchain);
output_stop(&jsonchain);
return;
}
static void print_ipv6_net(unsigned *jsonchain, struct in6_addr *ip, unsigned prefix, unsigned flags)
{
char namebuf[INET6_ADDRSTRLEN + 1] = {0};
if (inet_ntop(AF_INET6, ip, namebuf, sizeof(namebuf)) == NULL) {
fprintf(stderr, "inet_ntop failure at line %d\n",
__LINE__);
exit(1);
}
default_printf(jsonchain, "Network:\t", NULL, "%s/%u", namebuf, prefix);
}
static unsigned ipv6_base_ok(struct in6_addr *base, unsigned step)
{
struct in6_addr b2;
memcpy(&b2, base, sizeof(b2));
ipv6_or1(&b2, step);
return memcmp(base->s6_addr, &b2.s6_addr, 16);
}
void deaggregate_v6(const char *ip1s, const char *ip2s, unsigned flags)
{
struct in6_addr ip1, ip2;
unsigned step;
struct in6_addr base, end;
struct in6_addr tmp;
unsigned jsonchain;
if (inet_pton(AF_INET6, ip1s, &ip1) <= 0) {
if (!beSilent)
fprintf(stderr, "ipcalc: bad IPv6 address: %s\n",
ip1s);
exit(1);
}
if (inet_pton(AF_INET6, ip2s, &ip2) <= 0) {
if (!beSilent)
fprintf(stderr, "ipcalc: bad IPv6 address: %s\n",
ip2s);
exit(1);
}
memcpy(&base, &ip1, sizeof(base));
memcpy(&end, &ip2, sizeof(end));
if (ipv6_cmp(&base, &end) > 0) {
if (!beSilent)
fprintf(stderr, "ipcalc: bad IPv6 range\n");
exit(1);
}
output_start(&jsonchain);
array_start(&jsonchain, "Deaggregated networks", "DEAGGREGATEDNETWORK");
while (ipv6_cmp(&base, &end) <= 0) {
step = 0;
while (ipv6_base_ok(&base, step)) {
memcpy(&tmp, &base, sizeof(tmp));
ipv6_orm(&tmp, step+1);
if (ipv6_cmp(&tmp, &end) > 0)
break;
step++;
}
print_ipv6_net(&jsonchain, &base, 128-step, flags);
memset(&tmp, 0, sizeof(tmp));
ipv6_or1(&tmp, step);
/* v6add */
ipv6_add(&base, &tmp);
}
array_stop(&jsonchain);
output_stop(&jsonchain);
return;
}