#include <stdio.h>
#include <stdint.h>
#include <assert.h>

typedef uint32_t guint32;

#define nm_utils_ip4_prefix_to_hostmask(prefix) (prefix < 32 ? htonl(0xffffffff >> prefix) : 0)
#define nm_utils_ip4_prefix_to_netmask(prefix) ~nm_utils_ip4_prefix_to_hostmask(prefix)

int
nm_utils_ip4_netmask_to_prefix (guint32 netmask)
{
	guint32 hostmask = 0xffffffff;
	int prefix = 0;

	netmask = ntohl(netmask);

	/* Optimizations */
	if (!netmask)
		return 0;
	while (!(netmask & 0xff)) {
		netmask >>= 8;
		hostmask >>= 8;
	}
	/* End of optimizations */

	while (hostmask & netmask) {
		hostmask >>= 1;
		prefix++;
	}

	return prefix;
}

int
main(int argc, char **argv)
{
	int prefix, newprefix;
	guint32 netmask, hostmask;

	for (prefix = 0; prefix <= 32; prefix++) {
		netmask = nm_utils_ip4_prefix_to_netmask(prefix);
		hostmask = nm_utils_ip4_prefix_to_hostmask(prefix);
		newprefix = nm_utils_ip4_netmask_to_prefix(netmask);

		printf("%2d %08x %08x %2d\n", prefix, ntohl(netmask), ntohl(hostmask), newprefix);

		assert(hostmask == ~netmask);
		assert(prefix == newprefix);
	}
}
