[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/app/busybox/src/networking/ipcalc.c b/ap/app/busybox/src/networking/ipcalc.c
new file mode 100644
index 0000000..3c8b8bf
--- /dev/null
+++ b/ap/app/busybox/src/networking/ipcalc.c
@@ -0,0 +1,213 @@
+/* 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.
+ */
+
+//usage:#define ipcalc_trivial_usage
+//usage:       "[OPTIONS] ADDRESS[[/]NETMASK] [NETMASK]"
+//usage:#define ipcalc_full_usage "\n\n"
+//usage:       "Calculate IP network settings from a IP address\n"
+//usage:	IF_FEATURE_IPCALC_LONG_OPTIONS(
+//usage:     "\n	-b,--broadcast	Display calculated broadcast address"
+//usage:     "\n	-n,--network	Display calculated network address"
+//usage:     "\n	-m,--netmask	Display default netmask for IP"
+//usage:	IF_FEATURE_IPCALC_FANCY(
+//usage:     "\n	-p,--prefix	Display the prefix for IP/NETMASK"
+//usage:     "\n	-h,--hostname	Display first resolved host name"
+//usage:     "\n	-s,--silent	Don't ever display error messages"
+//usage:	)
+//usage:	)
+//usage:	IF_NOT_FEATURE_IPCALC_LONG_OPTIONS(
+//usage:     "\n	-b	Display calculated broadcast address"
+//usage:     "\n	-n	Display calculated network address"
+//usage:     "\n	-m	Display default netmask for IP"
+//usage:	IF_FEATURE_IPCALC_FANCY(
+//usage:     "\n	-p	Display the prefix for IP/NETMASK"
+//usage:     "\n	-h	Display first resolved host name"
+//usage:     "\n	-s	Don't ever display error messages"
+//usage:	)
+//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
+		;
+#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;
+
+#if ENABLE_FEATURE_IPCALC_LONG_OPTIONS
+	applet_long_options = ipcalc_longopts;
+#endif
+	opt_complementary = "-1:?2"; /* minimum 1 arg, maximum 2 args */
+	opt = getopt32(argv, "mbn" IF_FEATURE_IPCALC_FANCY("phs"));
+	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_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;
+}