Annotation of /tags/mkinitrd-6_3_1/busybox/networking/ipcalc.c
Parent Directory | Revision Log
Revision 984 -
(hide annotations)
(download)
Sun May 30 11:32:42 2010 UTC (14 years, 4 months ago) by niro
Original Path: trunk/mkinitrd-magellan/busybox/networking/ipcalc.c
File MIME type: text/plain
File size: 4408 byte(s)
Sun May 30 11:32:42 2010 UTC (14 years, 4 months ago) by niro
Original Path: trunk/mkinitrd-magellan/busybox/networking/ipcalc.c
File MIME type: text/plain
File size: 4408 byte(s)
-updated to busybox-1.16.1 and enabled blkid/uuid support in default config
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 | 984 | opt = getopt32(argv, "mbn" IF_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 | niro | 984 | bb_herror_msg_and_die("can't find hostname for %s", argv[0]); |
182 | niro | 532 | } |
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 | } |