/* vi: set sw=4 ts=4: */
/*
 * Mini ipcalc implementation for busybox
 *
 * By Jordan Crouse <jordan@cosmicpenguin.net>
 *    Stephan Linz  <linz@li-pro.net>
 *
 * This is a complete reimplementation of the ipcalc program
 * from Red Hat.  I didn't look at their source code, but there
 * is no denying that this is a loving reimplementation
 *
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 */
//config:config IPCALC
//config:	bool "ipcalc (4.4 kb)"
//config:	default y
//config:	help
//config:	ipcalc takes an IP address and netmask and calculates the
//config:	resulting broadcast, network, and host range.
//config:
//config:config FEATURE_IPCALC_LONG_OPTIONS
//config:	bool "Enable long options"
//config:	default y
//config:	depends on IPCALC && LONG_OPTS
//config:
//config:config FEATURE_IPCALC_FANCY
//config:	bool "Fancy IPCALC, more options, adds 1 kbyte"
//config:	default y
//config:	depends on IPCALC
//config:	help
//config:	Adds the options hostname, prefix and silent to the output of
//config:	"ipcalc".

//applet:IF_IPCALC(APPLET_NOEXEC(ipcalc, ipcalc, BB_DIR_BIN, BB_SUID_DROP, ipcalc))

//kbuild:lib-$(CONFIG_IPCALC) += ipcalc.o

//usage:#define ipcalc_trivial_usage
//usage:       "[-bnm"IF_FEATURE_IPCALC_FANCY("phs")"] ADDRESS"
//usage:       IF_FEATURE_IPCALC_FANCY("[/PREFIX]") " [NETMASK]"
//usage:#define ipcalc_full_usage "\n\n"
//usage:       "Calculate and display network settings from IP address\n"
//usage:     "\n	-b	Broadcast address"
//usage:     "\n	-n	Network address"
//usage:     "\n	-m	Default netmask for IP"
//usage:	IF_FEATURE_IPCALC_FANCY(
//usage:     "\n	-p	Prefix for IP/NETMASK"
//usage:     "\n	-h	Resolved host name"
//usage:     "\n	-s	No error messages"
//usage:	)

#include "libbb.h"
/* After libbb.h, because on some systems it needs other includes */
#include <arpa/inet.h>

#define CLASS_A_NETMASK ntohl(0xFF000000)
#define CLASS_B_NETMASK ntohl(0xFFFF0000)
#define CLASS_C_NETMASK ntohl(0xFFFFFF00)

static unsigned long get_netmask(unsigned long ipaddr)
{
	ipaddr = htonl(ipaddr);

	if ((ipaddr & 0xC0000000) == 0xC0000000)
		return CLASS_C_NETMASK;
	else if ((ipaddr & 0x80000000) == 0x80000000)
		return CLASS_B_NETMASK;
	else if ((ipaddr & 0x80000000) == 0)
		return CLASS_A_NETMASK;
	else
		return 0;
}

#if ENABLE_FEATURE_IPCALC_FANCY
static int get_prefix(unsigned long netmask)
{
	unsigned long msk = 0x80000000;
	int ret = 0;

	netmask = htonl(netmask);
	while (msk) {
		if (netmask & msk)
			ret++;
		msk >>= 1;
	}
	return ret;
}
#else
int get_prefix(unsigned long netmask);
#endif


#define NETMASK   0x01
#define BROADCAST 0x02
#define NETWORK   0x04
#define NETPREFIX 0x08
#define HOSTNAME  0x10
#define SILENT    0x20

#if ENABLE_FEATURE_IPCALC_LONG_OPTIONS
	static const char ipcalc_longopts[] ALIGN1 =
		"netmask\0"   No_argument "m" // netmask from IP (assuming complete class A, B, or C network)
		"broadcast\0" No_argument "b" // broadcast from IP [netmask]
		"network\0"   No_argument "n" // network from IP [netmask]
# if ENABLE_FEATURE_IPCALC_FANCY
		"prefix\0"    No_argument "p" // prefix from IP[/prefix] [netmask]
		"hostname\0"  No_argument "h" // hostname from IP
		"silent\0"    No_argument "s" // don’t ever display error messages
# endif
		;
# define GETOPT32 getopt32long
# define LONGOPTS ,ipcalc_longopts
#else
# define GETOPT32 getopt32
# define LONGOPTS
#endif

int ipcalc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int ipcalc_main(int argc UNUSED_PARAM, char **argv)
{
	unsigned opt;
	bool have_netmask = 0;
	struct in_addr s_netmask, s_broadcast, s_network, s_ipaddr;
	/* struct in_addr { in_addr_t s_addr; }  and  in_addr_t
	 * (which in turn is just a typedef to uint32_t)
	 * are essentially the same type. A few macros for less verbosity: */
#define netmask   (s_netmask.s_addr)
#define broadcast (s_broadcast.s_addr)
#define network   (s_network.s_addr)
#define ipaddr    (s_ipaddr.s_addr)
	char *ipstr;

	opt = GETOPT32(argv, "^"
			"mbn" IF_FEATURE_IPCALC_FANCY("phs")
			"\0" "-1:?2"/*min 1, max 2 args*/
			LONGOPTS
	);
	argv += optind;
	if (opt & SILENT)
		logmode = LOGMODE_NONE; /* suppress error_msg() output */
	opt &= ~SILENT;
	if (!(opt & (BROADCAST | NETWORK | NETPREFIX))) {
		/* if no options at all or
		 * (no broadcast,network,prefix) and (two args)... */
		if (!opt || argv[1])
			bb_show_usage();
	}

	ipstr = argv[0];
	if (ENABLE_FEATURE_IPCALC_FANCY) {
		unsigned long netprefix = 0;
		char *prefixstr;

		prefixstr = ipstr;

		while (*prefixstr) {
			if (*prefixstr == '/') {
				*prefixstr++ = '\0';
				if (*prefixstr) {
					unsigned msk;
					netprefix = xatoul_range(prefixstr, 0, 32);
					netmask = 0;
					msk = 0x80000000;
					while (netprefix > 0) {
						netmask |= msk;
						msk >>= 1;
						netprefix--;
					}
					netmask = htonl(netmask);
					/* Even if it was 0, we will signify that we have a netmask. This allows */
					/* for specification of default routes, etc which have a 0 netmask/prefix */
					have_netmask = 1;
				}
				break;
			}
			prefixstr++;
		}
	}

	if (inet_aton(ipstr, &s_ipaddr) == 0) {
		bb_error_msg_and_die("bad IP address: %s", argv[0]);
	}

	if (argv[1]) {
		if (ENABLE_FEATURE_IPCALC_FANCY && have_netmask) {
			bb_simple_error_msg_and_die("use prefix or netmask, not both");
		}
		if (inet_aton(argv[1], &s_netmask) == 0) {
			bb_error_msg_and_die("bad netmask: %s", argv[1]);
		}
	} else {
		/* JHC - If the netmask wasn't provided then calculate it */
		if (!ENABLE_FEATURE_IPCALC_FANCY || !have_netmask)
			netmask = get_netmask(ipaddr);
	}

	if (opt & NETMASK) {
		printf("NETMASK=%s\n", inet_ntoa(s_netmask));
	}

	if (opt & BROADCAST) {
		broadcast = (ipaddr & netmask) | ~netmask;
		printf("BROADCAST=%s\n", inet_ntoa(s_broadcast));
	}

	if (opt & NETWORK) {
		network = ipaddr & netmask;
		printf("NETWORK=%s\n", inet_ntoa(s_network));
	}

	if (ENABLE_FEATURE_IPCALC_FANCY) {
		if (opt & NETPREFIX) {
			printf("PREFIX=%i\n", get_prefix(netmask));
		}

		if (opt & HOSTNAME) {
			struct hostent *hostinfo;

			hostinfo = gethostbyaddr((char *) &ipaddr, sizeof(ipaddr), AF_INET);
			if (!hostinfo) {
				bb_herror_msg_and_die("can't find hostname for %s", argv[0]);
			}
			str_tolower(hostinfo->h_name);

			printf("HOSTNAME=%s\n", hostinfo->h_name);
		}
	}

	return EXIT_SUCCESS;
}
