1 /* vi: set sw=4 ts=4: */
3 * Mini ipcalc implementation for busybox
5 * By Jordan Crouse <jordan@cosmicpenguin.net>
6 * Stephan Linz <linz@li-pro.net>
8 * This is a complete reimplementation of the ipcalc program
9 * from Red Hat. I didn't look at their source code, but there
10 * is no denying that this is a loving reimplementation
12 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
18 #include <sys/socket.h>
19 #include <arpa/inet.h>
21 #define CLASS_A_NETMASK ntohl(0xFF000000)
22 #define CLASS_B_NETMASK ntohl(0xFFFF0000)
23 #define CLASS_C_NETMASK ntohl(0xFFFFFF00)
25 static unsigned long get_netmask(unsigned long ipaddr)
27 ipaddr = htonl(ipaddr);
29 if ((ipaddr & 0xC0000000) == 0xC0000000)
30 return CLASS_C_NETMASK;
31 else if ((ipaddr & 0x80000000) == 0x80000000)
32 return CLASS_B_NETMASK;
33 else if ((ipaddr & 0x80000000) == 0)
34 return CLASS_A_NETMASK;
39 #ifdef CONFIG_FEATURE_IPCALC_FANCY
40 static int get_prefix(unsigned long netmask)
42 unsigned long msk = 0x80000000;
45 netmask = htonl(netmask);
54 int get_prefix(unsigned long netmask);
59 #define BROADCAST 0x02
61 #define NETPREFIX 0x08
65 #if ENABLE_FEATURE_IPCALC_LONG_OPTIONS
66 static const struct option long_options[] = {
67 {"netmask", no_argument, NULL, 'm'},
68 {"broadcast", no_argument, NULL, 'b'},
69 {"network", no_argument, NULL, 'n'},
70 #ifdef CONFIG_FEATURE_IPCALC_FANCY
71 {"prefix", no_argument, NULL, 'p'},
72 {"hostname", no_argument, NULL, 'h'},
73 {"silent", no_argument, NULL, 's'},
78 #define long_options 0
80 int ipcalc_main(int argc, char **argv)
84 in_addr_t netmask, broadcast, network, ipaddr;
88 if (ENABLE_FEATURE_IPCALC_LONG_OPTIONS)
89 applet_long_options = long_options;
91 opt = getopt32(argc, argv, "mbn" USE_FEATURE_IPCALC_FANCY("phs"));
94 if (opt & (BROADCAST | NETWORK | NETPREFIX)) {
95 if (argc > 2 || argc <= 0)
102 logmode = LOGMODE_NONE; /* Suppress error_msg() output */
105 if (ENABLE_FEATURE_IPCALC_FANCY) {
106 unsigned long netprefix = 0;
112 if (*prefixstr == '/') {
113 *prefixstr = (char)0;
117 netprefix = xatoul_range(prefixstr, 0, 32);
120 while (netprefix > 0) {
125 netmask = htonl(netmask);
126 /* Even if it was 0, we will signify that we have a netmask. This allows */
127 /* for specification of default routes, etc which have a 0 netmask/prefix */
135 ipaddr = inet_aton(ipstr, &a);
138 bb_error_msg_and_die("bad IP address: %s", argv[0]);
143 if (ENABLE_FEATURE_IPCALC_FANCY && have_netmask) {
144 bb_error_msg_and_die("use prefix or netmask, not both");
147 netmask = inet_aton(argv[1], &a);
149 bb_error_msg_and_die("bad netmask: %s", argv[1]);
154 /* JHC - If the netmask wasn't provided then calculate it */
155 if (!ENABLE_FEATURE_IPCALC_FANCY || !have_netmask)
156 netmask = get_netmask(ipaddr);
160 printf("NETMASK=%s\n", inet_ntoa((*(struct in_addr *) &netmask)));
163 if (opt & BROADCAST) {
164 broadcast = (ipaddr & netmask) | ~netmask;
165 printf("BROADCAST=%s\n", inet_ntoa((*(struct in_addr *) &broadcast)));
169 network = ipaddr & netmask;
170 printf("NETWORK=%s\n", inet_ntoa((*(struct in_addr *) &network)));
173 if (ENABLE_FEATURE_IPCALC_FANCY) {
174 if (opt & NETPREFIX) {
175 printf("PREFIX=%i\n", get_prefix(netmask));
178 if (opt & HOSTNAME) {
179 struct hostent *hostinfo;
182 hostinfo = gethostbyaddr((char *) &ipaddr, sizeof(ipaddr), AF_INET);
184 bb_herror_msg_and_die("cannot find hostname for %s", argv[0]);
186 for (x = 0; hostinfo->h_name[x]; x++) {
187 hostinfo->h_name[x] = tolower(hostinfo->h_name[x]);
190 printf("HOSTNAME=%s\n", hostinfo->h_name);