summaryrefslogtreecommitdiff
path: root/networking/udhcp/dhcpc.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-11-27 23:43:28 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-11-27 23:43:28 +0000
commite2d3ded3549edd58fe3b39f2254c65f0808bcac2 (patch)
tree90e9aecef63439d80859ce43876e6a68001c8d14 /networking/udhcp/dhcpc.c
parent30d7a346e68bb7f0cb916e6c1e75dd75822d88a8 (diff)
downloadbusybox-w32-e2d3ded3549edd58fe3b39f2254c65f0808bcac2.tar.gz
busybox-w32-e2d3ded3549edd58fe3b39f2254c65f0808bcac2.tar.bz2
busybox-w32-e2d3ded3549edd58fe3b39f2254c65f0808bcac2.zip
udhcpc: convert to getopt32
Diffstat (limited to 'networking/udhcp/dhcpc.c')
-rw-r--r--networking/udhcp/dhcpc.c277
1 files changed, 124 insertions, 153 deletions
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index 4ccd8ec34..f69b687b2 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -33,25 +33,8 @@ static int fd = -1;
33#define LISTEN_RAW 2 33#define LISTEN_RAW 2
34static int listen_mode; 34static int listen_mode;
35 35
36struct client_config_t client_config = { 36struct client_config_t client_config;
37 /* Default options. */ 37
38 .abort_if_no_lease = 0,
39 .foreground = 0,
40 .quit_after_lease = 0,
41 .release_on_quit = 0,
42 .background_if_no_lease = 0,
43 .interface = "eth0",
44 .pidfile = NULL,
45 .script = DEFAULT_SCRIPT,
46 .clientid = NULL,
47 .vendorclass = NULL,
48 .hostname = NULL,
49 .fqdn = NULL,
50 .ifindex = 0,
51 .retries = 3,
52 .timeout = 3,
53 .arp = "\0\0\0\0\0\0", /* appease gcc-3.0 */
54};
55 38
56/* just a little helper */ 39/* just a little helper */
57static void change_mode(int new_mode) 40static void change_mode(int new_mode)
@@ -126,139 +109,137 @@ static void client_background(void)
126} 109}
127 110
128 111
112static uint8_t* alloc_dhcp_option(int code, const char *str, int extra)
113{
114 uint8_t *storage;
115 int len = strlen(str);
116 if (len > 255) len = 255;
117 storage = xzalloc(len + extra + OPT_DATA);
118 storage[OPT_CODE] = code;
119 storage[OPT_LEN] = len + extra;
120 memcpy(storage + extra + OPT_DATA, str, len);
121 return storage;
122}
123
124
129int udhcpc_main(int argc, char *argv[]) 125int udhcpc_main(int argc, char *argv[])
130{ 126{
131 uint8_t *temp, *message; 127 uint8_t *temp, *message;
128 char *str_c, *str_V, *str_h, *str_F, *str_r, *str_T, *str_t;
132 unsigned long t1 = 0, t2 = 0, xid = 0; 129 unsigned long t1 = 0, t2 = 0, xid = 0;
133 unsigned long start = 0, lease = 0; 130 unsigned long start = 0, lease = 0;
134 fd_set rfds;
135 int retval;
136 struct timeval tv;
137 int c, len;
138 struct dhcpMessage packet;
139 struct in_addr temp_addr;
140 long now; 131 long now;
132 unsigned opt;
141 int max_fd; 133 int max_fd;
142 int sig; 134 int sig;
135 int retval;
136 int len;
143 int no_clientid = 0; 137 int no_clientid = 0;
138 fd_set rfds;
139 struct timeval tv;
140 struct dhcpMessage packet;
141 struct in_addr temp_addr;
144 142
143 enum {
144 OPT_c = 1 << 0,
145 OPT_C = 1 << 1,
146 OPT_V = 1 << 2,
147 OPT_f = 1 << 3,
148 OPT_b = 1 << 4,
149 OPT_H = 1 << 5,
150 OPT_h = 1 << 6,
151 OPT_F = 1 << 7,
152 OPT_i = 1 << 8,
153 OPT_n = 1 << 9,
154 OPT_p = 1 << 10,
155 OPT_q = 1 << 11,
156 OPT_R = 1 << 12,
157 OPT_r = 1 << 13,
158 OPT_s = 1 << 14,
159 OPT_T = 1 << 15,
160 OPT_t = 1 << 16,
161 OPT_v = 1 << 17,
162 };
145 static const struct option arg_options[] = { 163 static const struct option arg_options[] = {
146 {"clientid", required_argument, 0, 'c'}, 164 { "clientid", required_argument, 0, 'c' },
147 {"clientid-none", no_argument, 0, 'C'}, 165 { "clientid-none", no_argument, 0, 'C' },
148 {"vendorclass", required_argument, 0, 'V'}, 166 { "vendorclass", required_argument, 0, 'V' },
149 {"foreground", no_argument, 0, 'f'}, 167 { "foreground", no_argument, 0, 'f' },
150 {"background", no_argument, 0, 'b'}, 168 { "background", no_argument, 0, 'b' },
151 {"hostname", required_argument, 0, 'H'}, 169 { "hostname", required_argument, 0, 'H' },
152 {"hostname", required_argument, 0, 'h'}, 170 { "hostname", required_argument, 0, 'h' },
153 {"fqdn", required_argument, 0, 'F'}, 171 { "fqdn", required_argument, 0, 'F' },
154 {"interface", required_argument, 0, 'i'}, 172 { "interface", required_argument, 0, 'i' },
155 {"now", no_argument, 0, 'n'}, 173 { "now", no_argument, 0, 'n' },
156 {"pidfile", required_argument, 0, 'p'}, 174 { "pidfile", required_argument, 0, 'p' },
157 {"quit", no_argument, 0, 'q'}, 175 { "quit", no_argument, 0, 'q' },
158 {"release", no_argument, 0, 'R'}, 176 { "release", no_argument, 0, 'R' },
159 {"request", required_argument, 0, 'r'}, 177 { "request", required_argument, 0, 'r' },
160 {"script", required_argument, 0, 's'}, 178 { "script", required_argument, 0, 's' },
161 {"timeout", required_argument, 0, 'T'}, 179 { "timeout", required_argument, 0, 'T' },
162 {"version", no_argument, 0, 'v'}, 180 { "version", no_argument, 0, 'v' },
163 {"retries", required_argument, 0, 't'}, 181 { "retries", required_argument, 0, 't' },
164 {0, 0, 0, 0} 182 { 0, 0, 0, 0 }
165 }; 183 };
166 184
167 /* get options */ 185 /* Default options. */
168 while (1) { 186 client_config.interface = "eth0";
169 int option_index = 0; 187 client_config.script = DEFAULT_SCRIPT;
170 c = getopt_long(argc, argv, "c:CV:fbH:h:F:i:np:qRr:s:T:t:v", arg_options, &option_index); 188 client_config.retries = 3;
171 if (c == -1) break; 189 client_config.timeout = 3;
172 190
173 switch (c) { 191 /* Parse command line */
174 case 'c': 192 opt_complementary = "?:c--C:C--c" // mutually exclusive
175 if (no_clientid) bb_show_usage(); 193 ":hH:Hh"; // -h and -H are the same
176 len = strlen(optarg) > 255 ? 255 : strlen(optarg); 194 applet_long_options = arg_options;
177 free(client_config.clientid); 195 opt = getopt32(argc, argv, "c:CV:fbH:h:F:i:np:qRr:s:T:t:v",
178 client_config.clientid = xmalloc(len + 2); 196 &str_c, &str_V, &str_h, &str_h, &str_F,
179 client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID; 197 &client_config.interface, &client_config.pidfile, &str_r,
180 client_config.clientid[OPT_LEN] = len; 198 &client_config.script, &str_T, &str_t
181 client_config.clientid[OPT_DATA] = '\0'; 199 );
182 strncpy((char*)client_config.clientid + OPT_DATA, optarg, len); 200
183 break; 201 if (opt & OPT_c)
184 case 'C': 202 client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, str_c, 0);
185 if (client_config.clientid) bb_show_usage(); 203 if (opt & OPT_C)
186 no_clientid = 1; 204 no_clientid = 1;
187 break; 205 if (opt & OPT_V)
188 case 'V': 206 client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0);
189 len = strlen(optarg) > 255 ? 255 : strlen(optarg); 207 if (opt & OPT_f)
190 free(client_config.vendorclass); 208 client_config.foreground = 1;
191 client_config.vendorclass = xmalloc(len + 2); 209 if (opt & OPT_b)
192 client_config.vendorclass[OPT_CODE] = DHCP_VENDOR; 210 client_config.background_if_no_lease = 1;
193 client_config.vendorclass[OPT_LEN] = len; 211 if (opt & OPT_h)
194 strncpy((char*)client_config.vendorclass + OPT_DATA, optarg, len); 212 client_config.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0);
195 break; 213 if (opt & OPT_F) {
196 case 'f': 214 client_config.fqdn = alloc_dhcp_option(DHCP_FQDN, str_F, 3);
197 client_config.foreground = 1; 215 /* Flags: 0000NEOS
198 break; 216 S: 1 => Client requests Server to update A RR in DNS as well as PTR
199 case 'b': 217 O: 1 => Server indicates to client that DNS has been updated regardless
200 client_config.background_if_no_lease = 1; 218 E: 1 => Name data is DNS format, i.e. <4>host<6>domain<4>com<0> not "host.domain.com"
201 break; 219 N: 1 => Client requests Server to not update DNS
202 case 'h': 220 */
203 case 'H': 221 client_config.fqdn[OPT_DATA + 0] = 0x1;
204 len = strlen(optarg) > 255 ? 255 : strlen(optarg); 222 /* client_config.fqdn[OPT_DATA + 1] = 0; - redundant */
205 free(client_config.hostname); 223 /* client_config.fqdn[OPT_DATA + 2] = 0; - redundant */
206 client_config.hostname = xmalloc(len + 2); 224 }
207 client_config.hostname[OPT_CODE] = DHCP_HOST_NAME; 225 // if (opt & OPT_i) client_config.interface = ...
208 client_config.hostname[OPT_LEN] = len; 226 if (opt & OPT_n)
209 strncpy((char*)client_config.hostname + 2, optarg, len); 227 client_config.abort_if_no_lease = 1;
210 break; 228 // if (opt & OPT_p) client_config.pidfile = ...
211 case 'F': 229 if (opt & OPT_q)
212 len = strlen(optarg) > 255 ? 255 : strlen(optarg); 230 client_config.quit_after_lease = 1;
213 free(client_config.fqdn); 231 if (opt & OPT_R)
214 client_config.fqdn = xmalloc(len + 5); 232 client_config.release_on_quit = 1;
215 client_config.fqdn[OPT_CODE] = DHCP_FQDN; 233 if (opt & OPT_r)
216 client_config.fqdn[OPT_LEN] = len + 3; 234 requested_ip = inet_addr(str_r);
217 /* Flags: 0000NEOS 235 // if (opt & OPT_s) client_config.script = ...
218 S: 1 => Client requests Server to update A RR in DNS as well as PTR 236 if (opt & OPT_T)
219 O: 1 => Server indicates to client that DNS has been updated regardless 237 client_config.timeout = xatoi_u(str_T);
220 E: 1 => Name data is DNS format, i.e. <4>host<6>domain<4>com<0> not "host.domain.com" 238 if (opt & OPT_t)
221 N: 1 => Client requests Server to not update DNS 239 client_config.retries = xatoi_u(str_t);
222 */ 240 if (opt & OPT_v) {
223 client_config.fqdn[OPT_LEN + 1] = 0x1; 241 printf("version %s\n\n", BB_VER);
224 client_config.fqdn[OPT_LEN + 2] = 0; 242 return 0;
225 client_config.fqdn[OPT_LEN + 3] = 0;
226 strncpy((char*)client_config.fqdn + 5, optarg, len);
227 break;
228 case 'i':
229 client_config.interface = optarg;
230 break;
231 case 'n':
232 client_config.abort_if_no_lease = 1;
233 break;
234 case 'p':
235 client_config.pidfile = optarg;
236 break;
237 case 'q':
238 client_config.quit_after_lease = 1;
239 break;
240 case 'R':
241 client_config.release_on_quit = 1;
242 break;
243 case 'r':
244 requested_ip = inet_addr(optarg);
245 break;
246 case 's':
247 client_config.script = optarg;
248 break;
249 case 'T':
250 client_config.timeout = xatoi_u(optarg);
251 break;
252 case 't':
253 client_config.retries = xatoi_u(optarg);
254 break;
255 case 'v':
256 printf("version %s\n\n", BB_VER);
257 return 0;
258 break;
259 default:
260 bb_show_usage();
261 }
262 } 243 }
263 244
264 /* Start the log, sanitize fd's, and write a pid file */ 245 /* Start the log, sanitize fd's, and write a pid file */
@@ -270,22 +251,13 @@ int udhcpc_main(int argc, char *argv[])
270 251
271 /* if not set, and not suppressed, setup the default client ID */ 252 /* if not set, and not suppressed, setup the default client ID */
272 if (!client_config.clientid && !no_clientid) { 253 if (!client_config.clientid && !no_clientid) {
273 client_config.clientid = xmalloc(6 + 3); 254 client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7);
274 client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID;
275 client_config.clientid[OPT_LEN] = 7;
276 client_config.clientid[OPT_DATA] = 1; 255 client_config.clientid[OPT_DATA] = 1;
277 memcpy(client_config.clientid + 3, client_config.arp, 6); 256 memcpy(client_config.clientid + OPT_DATA+1, client_config.arp, 6);
278 }
279
280 if (!client_config.vendorclass) {
281 client_config.vendorclass = xmalloc(sizeof("udhcp "BB_VER) + 2);
282 client_config.vendorclass[OPT_CODE] = DHCP_VENDOR;
283 client_config.vendorclass[OPT_LEN] = sizeof("udhcp "BB_VER) - 1;
284 client_config.vendorclass[OPT_DATA] = 1;
285 memcpy(&client_config.vendorclass[OPT_DATA],
286 "udhcp "BB_VER, sizeof("udhcp "BB_VER) - 1);
287 } 257 }
288 258
259 if (!client_config.vendorclass)
260 client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, "udhcp "BB_VER, 0);
289 261
290 /* setup the signal pipe */ 262 /* setup the signal pipe */
291 udhcp_sp_setup(); 263 udhcp_sp_setup();
@@ -295,7 +267,6 @@ int udhcpc_main(int argc, char *argv[])
295 change_mode(LISTEN_RAW); 267 change_mode(LISTEN_RAW);
296 268
297 for (;;) { 269 for (;;) {
298
299 tv.tv_sec = timeout - uptime(); 270 tv.tv_sec = timeout - uptime();
300 tv.tv_usec = 0; 271 tv.tv_usec = 0;
301 272