Magellan Linux

Annotation of /trunk/mkinitrd-magellan/busybox/networking/ipcalc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (hide annotations) (download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 4572 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd

1 niro 532 /* vi: set sw=4 ts=4: */
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 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
11     *
12     * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
13     */
14    
15     #include "busybox.h"
16     #include <ctype.h>
17     #include <getopt.h>
18     #include <sys/socket.h>
19     #include <arpa/inet.h>
20    
21     #define CLASS_A_NETMASK ntohl(0xFF000000)
22     #define CLASS_B_NETMASK ntohl(0xFFFF0000)
23     #define CLASS_C_NETMASK ntohl(0xFFFFFF00)
24    
25     static unsigned long get_netmask(unsigned long ipaddr)
26     {
27     ipaddr = htonl(ipaddr);
28    
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;
35     else
36     return 0;
37     }
38    
39     #ifdef CONFIG_FEATURE_IPCALC_FANCY
40     static int get_prefix(unsigned long netmask)
41     {
42     unsigned long msk = 0x80000000;
43     int ret = 0;
44    
45     netmask = htonl(netmask);
46     while (msk) {
47     if (netmask & msk)
48     ret++;
49     msk >>= 1;
50     }
51     return ret;
52     }
53     #else
54     int get_prefix(unsigned long netmask);
55     #endif
56    
57    
58     #define NETMASK 0x01
59     #define BROADCAST 0x02
60     #define NETWORK 0x04
61     #define NETPREFIX 0x08
62     #define HOSTNAME 0x10
63     #define SILENT 0x20
64    
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     # if ENABLE_FEATURE_IPCALC_FANCY
71     { "prefix", no_argument, NULL, 'p' },
72     { "hostname", no_argument, NULL, 'h' },
73     { "silent", no_argument, NULL, 's' },
74     # endif
75     { NULL, 0, NULL, 0 }
76     };
77     #endif
78    
79     int ipcalc_main(int argc, char **argv)
80     {
81     unsigned opt;
82     int have_netmask = 0;
83     in_addr_t netmask, broadcast, network, ipaddr;
84     struct in_addr a;
85     char *ipstr;
86    
87     #if ENABLE_FEATURE_IPCALC_LONG_OPTIONS
88     applet_long_options = long_options;
89     #endif
90     opt = getopt32(argc, argv, "mbn" USE_FEATURE_IPCALC_FANCY("phs"));
91     argc -= optind;
92     argv += optind;
93     if (opt & (BROADCAST | NETWORK | NETPREFIX)) {
94     if (argc > 2 || argc <= 0)
95     bb_show_usage();
96     } else {
97     if (argc != 1)
98     bb_show_usage();
99     }
100     if (opt & SILENT)
101     logmode = LOGMODE_NONE; /* Suppress error_msg() output */
102    
103     ipstr = argv[0];
104     if (ENABLE_FEATURE_IPCALC_FANCY) {
105     unsigned long netprefix = 0;
106     char *prefixstr;
107    
108     prefixstr = ipstr;
109    
110     while (*prefixstr) {
111     if (*prefixstr == '/') {
112     *prefixstr = (char)0;
113     prefixstr++;
114     if (*prefixstr) {
115     unsigned msk;
116     netprefix = xatoul_range(prefixstr, 0, 32);
117     netmask = 0;
118     msk = 0x80000000;
119     while (netprefix > 0) {
120     netmask |= msk;
121     msk >>= 1;
122     netprefix--;
123     }
124     netmask = htonl(netmask);
125     /* Even if it was 0, we will signify that we have a netmask. This allows */
126     /* for specification of default routes, etc which have a 0 netmask/prefix */
127     have_netmask = 1;
128     }
129     break;
130     }
131     prefixstr++;
132     }
133     }
134     ipaddr = inet_aton(ipstr, &a);
135    
136     if (ipaddr == 0) {
137     bb_error_msg_and_die("bad IP address: %s", argv[0]);
138     }
139     ipaddr = a.s_addr;
140    
141     if (argc == 2) {
142     if (ENABLE_FEATURE_IPCALC_FANCY && have_netmask) {
143     bb_error_msg_and_die("use prefix or netmask, not both");
144     }
145    
146     netmask = inet_aton(argv[1], &a);
147     if (netmask == 0) {
148     bb_error_msg_and_die("bad netmask: %s", argv[1]);
149     }
150     netmask = a.s_addr;
151     } else {
152    
153     /* JHC - If the netmask wasn't provided then calculate it */
154     if (!ENABLE_FEATURE_IPCALC_FANCY || !have_netmask)
155     netmask = get_netmask(ipaddr);
156     }
157    
158     if (opt & NETMASK) {
159     printf("NETMASK=%s\n", inet_ntoa((*(struct in_addr *) &netmask)));
160     }
161    
162     if (opt & BROADCAST) {
163     broadcast = (ipaddr & netmask) | ~netmask;
164     printf("BROADCAST=%s\n", inet_ntoa((*(struct in_addr *) &broadcast)));
165     }
166    
167     if (opt & NETWORK) {
168     network = ipaddr & netmask;
169     printf("NETWORK=%s\n", inet_ntoa((*(struct in_addr *) &network)));
170     }
171    
172     if (ENABLE_FEATURE_IPCALC_FANCY) {
173     if (opt & NETPREFIX) {
174     printf("PREFIX=%i\n", get_prefix(netmask));
175     }
176    
177     if (opt & HOSTNAME) {
178     struct hostent *hostinfo;
179     int x;
180    
181     hostinfo = gethostbyaddr((char *) &ipaddr, sizeof(ipaddr), AF_INET);
182     if (!hostinfo) {
183     bb_herror_msg_and_die("cannot find hostname for %s", argv[0]);
184     }
185     for (x = 0; hostinfo->h_name[x]; x++) {
186     hostinfo->h_name[x] = tolower(hostinfo->h_name[x]);
187     }
188    
189     printf("HOSTNAME=%s\n", hostinfo->h_name);
190     }
191     }
192    
193     return EXIT_SUCCESS;
194     }