blob: f130f3b7c941785d279ec41418c4784d3fe99731 [file] [log] [blame]
Glenn L McGrathc11986d2002-11-10 23:42:27 +00001/* vi: set sw=4 ts=4 ai: */
2/*
3 * Mini ipcalc implementation for busybox
4 *
5 * By Jordan Crouse <jordan@cosmicpenguin.net>
6 * Stephan Linz <linz@li-pro.net>
7 *
8 * This is a complete reimplentation of the ipcalc program
9 * from Redhat. I didn't look at their source code, but there
10 * is no denying that this is a loving reimplementation
11 */
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <ctype.h>
16#include <getopt.h>
17#include <sys/socket.h>
18#include <netinet/in.h>
19#include <arpa/inet.h>
20
21#include "busybox.h"
22
23#define IPCALC_MSG(CMD,ALTCMD) if (mode & SILENT) {ALTCMD;} else {CMD;}
24
25static unsigned long get_netmask(unsigned long ipaddr)
26{
27 if (ipaddr & 0xC0) {
28 return 0x00FFFFFF; /* Class C */
29 }
30 if (ipaddr & 0x10) {
31 return 0x0000FFFF; /* Class B */
32 }
33 return 0x000000FF; /* Class A */
34}
35
36#define NETMASK 0x01
37#define BROADCAST 0x02
38#define NETWORK 0x04
39#define HOSTNAME 0x08
40#define SILENT 0x80
41
42int ipcalc_main(int argc, char **argv)
43{
44 unsigned char mode = 0;
45
46 unsigned long netmask = 0;
47 unsigned long broadcast = 0;
48 unsigned long network = 0;
49 unsigned long ipaddr = 0;
50
51 int opt = 0;
52
53 struct option long_options[] = {
54 {"netmask", no_argument, NULL, 'n'},
55 {"broadcast", no_argument, NULL, 'b'},
56 {"network", no_argument, NULL, 'w'},
57#ifdef CONFIG_FEATURE_IPCALC_FANCY
58 {"hostname", no_argument, NULL, 'h'},
59 {"silent", no_argument, NULL, 's'},
60#endif
61 {NULL, 0, NULL, 0}
62 };
63
64
65 while ((opt = getopt_long(argc, argv,
66#ifdef CONFIG_FEATURE_IPCALC_FANCY
67 "nbwhs",
68#else
69 "nbw",
70#endif
71 long_options, NULL)) != EOF) {
72 if (opt == 'n')
73 mode |= NETMASK;
74 else if (opt == 'b')
75 mode |= BROADCAST;
76 else if (opt == 'w')
77 mode |= NETWORK;
78#ifdef CONFIG_FEATURE_IPCALC_FANCY
79 else if (opt == 'h')
80 mode |= HOSTNAME;
81 else if (opt == 's')
82 mode |= SILENT;
83#endif
84 else {
85 show_usage();
86 }
87 }
88
89 if (mode & (BROADCAST | NETWORK)) {
90 if (argc - optind > 2) {
91 show_usage();
92 }
93 } else {
94 if (argc - optind != 1) {
95 show_usage();
96 }
97 }
98
99 ipaddr = inet_addr(argv[optind]);
100
101 if (ipaddr == INADDR_NONE) {
102 IPCALC_MSG(error_msg_and_die("bad IP address: %s\n", argv[optind]),
103 exit(EXIT_FAILURE));
104 }
105
106
107 if (argc - optind == 2) {
108 netmask = inet_addr(argv[optind + 1]);
109 }
110
111 if (ipaddr == INADDR_NONE) {
112 IPCALC_MSG(error_msg_and_die("bad netmask: %s\n", argv[optind + 1]),
113 exit(EXIT_FAILURE));
114 }
115
116 /* JHC - If the netmask wasn't provided then calculate it */
117 if (!netmask) {
118 netmask = get_netmask(ipaddr);
119 }
120
121 if (mode & NETMASK) {
122 printf("NETMASK=%s\n", inet_ntoa((*(struct in_addr *) &netmask)));
123 }
124
125 if (mode & BROADCAST) {
126 broadcast = (ipaddr & netmask) | ~netmask;
127 printf("BROADCAST=%s\n", inet_ntoa((*(struct in_addr *) &broadcast)));
128 }
129
130 if (mode & NETWORK) {
131 network = ipaddr & netmask;
132 printf("NETWORK=%s\n", inet_ntoa((*(struct in_addr *) &network)));
133 }
134#ifdef CONFIG_FEATURE_IPCALC_FANCY
135 if (mode & HOSTNAME) {
136 struct hostent *hostinfo;
137 int x;
138
139 hostinfo = gethostbyaddr((char *) &ipaddr, sizeof(ipaddr), AF_INET);
140 if (!hostinfo) {
141 IPCALC_MSG(error_msg("cannot find hostname for %s", argv[optind]);
142 herror(NULL);
143 putc('\n', stderr);,);
144 exit(EXIT_FAILURE);
145 }
146 for (x = 0; hostinfo->h_name[x]; x++) {
147 hostinfo->h_name[x] = tolower(hostinfo->h_name[x]);
148 }
149
150 printf("HOSTNAME=%s\n", hostinfo->h_name);
151 }
152#endif
153
154 return EXIT_SUCCESS;
155}
156
157/* END CODE */
158/*
159Local Variables:
160c-file-style: "linux"
161c-basic-offset: 4
162tab-width: 4
163End:
164*/