/* For terms of usage/redistribution/modification see the LICENSE file */
/* For authors and contributors see the AUTHORS file */
#include "iptraf-ng-compat.h"
// TODO: full rewrite
/*
* Returns a binary subnet mask based on the number of mask bits. The
* dotted-decimal notation may be obtained with inet_ntoa.
*/
unsigned long cidr_get_mask(unsigned int maskbits)
{
struct in_addr mask;
if (maskbits == 0)
return 0;
inet_aton("255.255.255.255", &mask);
mask.s_addr = htonl(mask.s_addr << (32 - maskbits));
return mask.s_addr;
}
/*
* Returns a subnet mask in dotted-decimal notation given the number of
* 1-bits in the mask.
*/
char *cidr_get_quad_mask(unsigned int maskbits)
{
struct in_addr addr;
addr.s_addr = cidr_get_mask(maskbits);
return inet_ntoa(addr);
}
/*
* Returns the number of 1-bits in the given binary subnet mask in
* network byte order.
*/
unsigned int cidr_get_maskbits(unsigned long mask)
{
unsigned int i = 32;
if (mask == 0)
return 0;
mask = ntohl(mask);
while (mask % 2 == 0) {
mask >>= 1;
i--;
}
return i;
}
/*
* Splits a CIDR-style address/mask string into its constituent address and
* mask parts. In case of absent or invalid input in the mask part, 255 is
* returned in *maskbits (255 is invalid for an IPv4 address).
*/
void cidr_split_address(char *cidr_addr, char *addresspart,
unsigned int *maskbits)
{
char maskpart[4];
char *endptr;
char *slashptr;
char address_buffer[80];
if (strchr(cidr_addr, '/') == NULL) {
strncpy(addresspart, cidr_addr, 80);
*maskbits = 255;
return;
}
memset(address_buffer, 0, 80);
memset(addresspart, 0, 80);
memset(maskpart, 0, 4);
strncpy(address_buffer, cidr_addr, 80);
slashptr = strchr(address_buffer, '/');
/*
* Cut out the mask part and move past the slash
*/
*slashptr = '\0';
slashptr++;
/*
* Copy out the address and mask parts into their buffers.
*/
strncpy(addresspart, address_buffer, 80);
strncpy(maskpart, slashptr, 4);
if (maskpart[0] != '\0') {
*maskbits = strtoul(maskpart, &endptr, 10);
if (*endptr != '\0')
*maskbits = 255;
} else
*maskbits = 255;
return;
}