aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--networking/Config.in4
-rw-r--r--networking/ipcalc.c87
2 files changed, 80 insertions, 11 deletions
diff --git a/networking/Config.in b/networking/Config.in
index 754d8d9f9..2705980bb 100644
--- a/networking/Config.in
+++ b/networking/Config.in
@@ -376,11 +376,11 @@ config CONFIG_IPCALC
376 resulting broadcast, network, and host range. 376 resulting broadcast, network, and host range.
377 377
378config CONFIG_FEATURE_IPCALC_FANCY 378config CONFIG_FEATURE_IPCALC_FANCY
379 bool " Fancy IPCALC, more options, adds 300 bytes" 379 bool " Fancy IPCALC, more options, adds 1 kbyte"
380 default y 380 default y
381 depends on CONFIG_IPCALC 381 depends on CONFIG_IPCALC
382 help 382 help
383 Adds the fields hostname and silent to the output of "ipcalc". 383 Adds the options hostname, prefix and silent to the output of "ipcalc".
384 384
385config CONFIG_IPADDR 385config CONFIG_IPADDR
386 bool "ipaddr" 386 bool "ipaddr"
diff --git a/networking/ipcalc.c b/networking/ipcalc.c
index 94b747ef6..9578c8266 100644
--- a/networking/ipcalc.c
+++ b/networking/ipcalc.c
@@ -40,11 +40,29 @@ static unsigned long get_netmask(unsigned long ipaddr)
40 return 0; 40 return 0;
41} 41}
42 42
43#ifdef CONFIG_FEATURE_IPCALC_FANCY
44static int get_prefix(unsigned long netmask)
45{
46 unsigned long t;
47 int ret = 0;
48
49 for (t = 0; t < 32; t++) {
50 if (htonl(netmask) & (0x80000000 >> t)) {
51 ret ++;
52 } else {
53 break;
54 }
55 }
56 return ret;
57}
58#endif
59
43#define NETMASK 0x01 60#define NETMASK 0x01
44#define BROADCAST 0x02 61#define BROADCAST 0x02
45#define NETWORK 0x04 62#define NETWORK 0x04
46#define HOSTNAME 0x08 63#define NETPREFIX 0x08
47#define SILENT 0x10 64#define HOSTNAME 0x10
65#define SILENT 0x80
48 66
49int ipcalc_main(int argc, char **argv) 67int ipcalc_main(int argc, char **argv)
50{ 68{
@@ -55,11 +73,18 @@ int ipcalc_main(int argc, char **argv)
55 unsigned long network; 73 unsigned long network;
56 unsigned long ipaddr; 74 unsigned long ipaddr;
57 75
76#ifdef CONFIG_FEATURE_IPCALC_FANCY
77 unsigned long netprefix = 0;
78 int have_netmask = 0;
79 char *ipstr, *prefixstr;
80#endif
81
58 static const struct option long_options[] = { 82 static const struct option long_options[] = {
59 {"netmask", no_argument, NULL, 'n'}, 83 {"netmask", no_argument, NULL, 'm'},
60 {"broadcast", no_argument, NULL, 'b'}, 84 {"broadcast", no_argument, NULL, 'b'},
61 {"network", no_argument, NULL, 'w'}, 85 {"network", no_argument, NULL, 'n'},
62#ifdef CONFIG_FEATURE_IPCALC_FANCY 86#ifdef CONFIG_FEATURE_IPCALC_FANCY
87 {"prefix", no_argument, NULL, 'p'},
63 {"hostname", no_argument, NULL, 'h'}, 88 {"hostname", no_argument, NULL, 'h'},
64 {"silent", no_argument, NULL, 's'}, 89 {"silent", no_argument, NULL, 's'},
65#endif 90#endif
@@ -69,11 +94,11 @@ int ipcalc_main(int argc, char **argv)
69 bb_applet_long_options = long_options; 94 bb_applet_long_options = long_options;
70 mode = bb_getopt_ulflags(argc, argv, 95 mode = bb_getopt_ulflags(argc, argv,
71#ifdef CONFIG_FEATURE_IPCALC_FANCY 96#ifdef CONFIG_FEATURE_IPCALC_FANCY
72 "nbwhs"); 97 "mbnphs");
73#else 98#else
74 "nbw"); 99 "mbn");
75#endif 100#endif
76 if (mode & (BROADCAST | NETWORK)) { 101 if (mode & (BROADCAST | NETWORK | NETPREFIX)) {
77 if (argc - optind > 2) { 102 if (argc - optind > 2) {
78 bb_show_usage(); 103 bb_show_usage();
79 } 104 }
@@ -83,16 +108,55 @@ int ipcalc_main(int argc, char **argv)
83 } 108 }
84 } 109 }
85 110
111#ifdef CONFIG_FEATURE_IPCALC_FANCY
112 prefixstr = ipstr = argv[optind];
113
114 while(*prefixstr) {
115 if (*prefixstr == '/') {
116 *prefixstr = (char)0;
117 prefixstr++;
118 if (*prefixstr) {
119 netprefix = atol(prefixstr);
120 if (netprefix > 32) {
121 IPCALC_MSG(bb_error_msg_and_die("bad IP prefix: %s\n", prefixstr),
122 exit(EXIT_FAILURE));
123 }
124 if (netprefix) {
125 netmask = 0x80000000;
126 netprefix--;
127 while(netprefix) {
128 netmask = 0x80000000 | (netmask >> 1);
129 netprefix--;
130 }
131 netmask = htonl(netmask);
132 }
133 /* Even if it was 0, we will signify that we have a netmask. This allows */
134 /* for specification of default routes, etc which have a 0 netmask/prefix */
135 have_netmask = 1;
136 }
137 break;
138 }
139 prefixstr++;
140 }
141 ipaddr = inet_addr(ipstr);
142#else
86 ipaddr = inet_addr(argv[optind]); 143 ipaddr = inet_addr(argv[optind]);
144#endif
87 145
88 if (ipaddr == INADDR_NONE) { 146 if (ipaddr == INADDR_NONE) {
89 IPCALC_MSG(bb_error_msg_and_die("bad IP address: %s", argv[optind]), 147 IPCALC_MSG(bb_error_msg_and_die("bad IP address: %s", argv[optind]),
90 exit(EXIT_FAILURE)); 148 exit(EXIT_FAILURE));
91 } 149 }
92 150
93
94 if (argc - optind == 2) { 151 if (argc - optind == 2) {
95 netmask = inet_addr(argv[optind + 1]); 152#ifdef CONFIG_FEATURE_IPCALC_FANCY
153 if (have_netmask == 1) {
154 IPCALC_MSG(bb_error_msg_and_die("Both prefix and netmask were specified, use one or the other.\n"),
155 exit(EXIT_FAILURE));
156 }
157 have_netmask = 1;
158#endif
159 netmask = inet_addr(argv[optind + 1]);
96 } 160 }
97 161
98 if (ipaddr == INADDR_NONE) { 162 if (ipaddr == INADDR_NONE) {
@@ -118,7 +182,12 @@ int ipcalc_main(int argc, char **argv)
118 network = ipaddr & netmask; 182 network = ipaddr & netmask;
119 printf("NETWORK=%s\n", inet_ntoa((*(struct in_addr *) &network))); 183 printf("NETWORK=%s\n", inet_ntoa((*(struct in_addr *) &network)));
120 } 184 }
185
121#ifdef CONFIG_FEATURE_IPCALC_FANCY 186#ifdef CONFIG_FEATURE_IPCALC_FANCY
187 if (mode & NETPREFIX) {
188 printf("PREFIX=%i\n", get_prefix(netmask));
189 }
190
122 if (mode & HOSTNAME) { 191 if (mode & HOSTNAME) {
123 struct hostent *hostinfo; 192 struct hostent *hostinfo;
124 int x; 193 int x;