adds the ability to use and calculate network prefix specifications instead
authorGlenn L McGrath <bug1@ihug.co.nz>
Tue, 2 Sep 2003 06:59:57 +0000 (06:59 -0000)
committerGlenn L McGrath <bug1@ihug.co.nz>
Tue, 2 Sep 2003 06:59:57 +0000 (06:59 -0000)
of netmasks. It also fixes the parameters for network and netmask to match
that of the official Red Hat version (-n for network and -m for netmask).
Patch by Joshua Jackson

networking/Config.in
networking/ipcalc.c

index 754d8d9f9f460d21ace939a598e577f2c6c575e2..2705980bbcffe95ead38f18b5769034b5c0c0448 100644 (file)
@@ -376,11 +376,11 @@ config CONFIG_IPCALC
          resulting broadcast, network, and host range.
 
 config CONFIG_FEATURE_IPCALC_FANCY
-       bool "  Fancy IPCALC, more options, adds 300 bytes"
+       bool "  Fancy IPCALC, more options, adds 1 kbyte"
        default y
        depends on CONFIG_IPCALC
        help
-         Adds the fields hostname and silent to the output of "ipcalc".
+         Adds the options hostname, prefix and silent to the output of "ipcalc".
 
 config CONFIG_IPADDR
        bool "ipaddr"
index 94b747ef69beec5cc1b5e83ea39dceca90e5d1dd..9578c8266ab2ab2cb86180741366215e8742ea15 100644 (file)
@@ -40,11 +40,29 @@ static unsigned long get_netmask(unsigned long ipaddr)
                return 0;
 }
 
+#ifdef CONFIG_FEATURE_IPCALC_FANCY
+static int get_prefix(unsigned long netmask)
+{
+        unsigned long t;
+        int ret = 0;
+
+        for (t = 0; t < 32; t++) {
+                if (htonl(netmask) & (0x80000000 >> t)) {
+                        ret ++;
+                } else {
+                        break;
+                }
+        }
+        return ret;
+}
+#endif
+
 #define NETMASK   0x01
 #define BROADCAST 0x02
 #define NETWORK   0x04
-#define HOSTNAME  0x08
-#define SILENT    0x10
+#define NETPREFIX 0x08
+#define HOSTNAME  0x10
+#define SILENT    0x80
 
 int ipcalc_main(int argc, char **argv)
 {
@@ -55,11 +73,18 @@ int ipcalc_main(int argc, char **argv)
        unsigned long network;
        unsigned long ipaddr;
 
+#ifdef CONFIG_FEATURE_IPCALC_FANCY
+       unsigned long netprefix = 0;
+       int have_netmask = 0;
+       char *ipstr, *prefixstr;
+#endif
+
        static const struct option long_options[] = {
-               {"netmask", no_argument, NULL, 'n'},
+               {"netmask", no_argument, NULL, 'm'},
                {"broadcast", no_argument, NULL, 'b'},
-               {"network", no_argument, NULL, 'w'},
+               {"network", no_argument, NULL, 'n'},
 #ifdef CONFIG_FEATURE_IPCALC_FANCY
+                {"prefix", no_argument, NULL, 'p'},
                {"hostname", no_argument, NULL, 'h'},
                {"silent", no_argument, NULL, 's'},
 #endif
@@ -69,11 +94,11 @@ int ipcalc_main(int argc, char **argv)
        bb_applet_long_options = long_options;
        mode = bb_getopt_ulflags(argc, argv,
 #ifdef CONFIG_FEATURE_IPCALC_FANCY
-                                                         "nbwhs");
+                                                         "mbnphs");
 #else
-                                                         "nbw");
+                                                         "mbn");
 #endif
-       if (mode & (BROADCAST | NETWORK)) {
+       if (mode & (BROADCAST | NETWORK | NETPREFIX)) {
                if (argc - optind > 2) {
                        bb_show_usage();
                }
@@ -83,16 +108,55 @@ int ipcalc_main(int argc, char **argv)
                }
        }
 
+#ifdef CONFIG_FEATURE_IPCALC_FANCY
+        prefixstr = ipstr = argv[optind];
+
+        while(*prefixstr) {
+                if (*prefixstr == '/') {
+                        *prefixstr = (char)0;
+                        prefixstr++;
+                        if (*prefixstr) {
+                                netprefix = atol(prefixstr);
+                                if (netprefix > 32) {
+                                        IPCALC_MSG(bb_error_msg_and_die("bad IP prefix: %s\n", prefixstr),
+                                                exit(EXIT_FAILURE));
+                                }
+                                if (netprefix) {
+                                        netmask = 0x80000000;
+                                        netprefix--;
+                                        while(netprefix) {
+                                                netmask = 0x80000000 | (netmask >> 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++;
+        }
+       ipaddr = inet_addr(ipstr);
+#else
        ipaddr = inet_addr(argv[optind]);
+#endif
 
        if (ipaddr == INADDR_NONE) {
                IPCALC_MSG(bb_error_msg_and_die("bad IP address: %s", argv[optind]),
                                   exit(EXIT_FAILURE));
        }
 
-
        if (argc - optind == 2) {
-               netmask = inet_addr(argv[optind + 1]);
+#ifdef CONFIG_FEATURE_IPCALC_FANCY
+               if (have_netmask == 1) {
+                        IPCALC_MSG(bb_error_msg_and_die("Both prefix and netmask were specified, use one or the other.\n"),
+                                exit(EXIT_FAILURE));
+                }
+                have_netmask = 1;
+#endif
+                netmask = inet_addr(argv[optind + 1]);
        }
 
        if (ipaddr == INADDR_NONE) {
@@ -118,7 +182,12 @@ int ipcalc_main(int argc, char **argv)
                network = ipaddr & netmask;
                printf("NETWORK=%s\n", inet_ntoa((*(struct in_addr *) &network)));
        }
+
 #ifdef CONFIG_FEATURE_IPCALC_FANCY
+        if (mode & NETPREFIX) {
+                printf("PREFIX=%i\n", get_prefix(netmask));
+        }
+
        if (mode & HOSTNAME) {
                struct hostent *hostinfo;
                int x;