Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


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