diff options
-rw-r--r-- | networking/Config.in | 4 | ||||
-rw-r--r-- | networking/ipcalc.c | 87 |
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 | ||
378 | config CONFIG_FEATURE_IPCALC_FANCY | 378 | config 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 | ||
385 | config CONFIG_IPADDR | 385 | config 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 | ||
44 | static 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 | ||
49 | int ipcalc_main(int argc, char **argv) | 67 | int 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; |