diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-12 14:57:37 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-12 14:57:37 +0000 |
commit | 2c91652bbcc82c794c26230806058b04f1711033 (patch) | |
tree | 1195f7c7fba68bdaf175d85432bf60a60a8c29f0 /networking/dnsd.c | |
parent | 6536a9b5833febe719988526a095a9cacb8a1042 (diff) | |
download | busybox-w32-2c91652bbcc82c794c26230806058b04f1711033.tar.gz busybox-w32-2c91652bbcc82c794c26230806058b04f1711033.tar.bz2 busybox-w32-2c91652bbcc82c794c26230806058b04f1711033.zip |
next part of ipv6-ization. dnsd code is "interesting"...
Diffstat (limited to 'networking/dnsd.c')
-rw-r--r-- | networking/dnsd.c | 110 |
1 files changed, 38 insertions, 72 deletions
diff --git a/networking/dnsd.c b/networking/dnsd.c index 1fb9ccfe5..c3bd1610b 100644 --- a/networking/dnsd.c +++ b/networking/dnsd.c | |||
@@ -19,15 +19,15 @@ | |||
19 | 19 | ||
20 | #include "busybox.h" | 20 | #include "busybox.h" |
21 | 21 | ||
22 | static char *fileconf = "/etc/dnsd.conf"; | 22 | static const char *fileconf = "/etc/dnsd.conf"; |
23 | #define LOCK_FILE "/var/run/dnsd.lock" | 23 | #define LOCK_FILE "/var/run/dnsd.lock" |
24 | #define LOG_FILE "/var/log/dnsd.log" | ||
25 | 24 | ||
26 | // Must matct getopt32 call | 25 | // Must match getopt32 call |
27 | #define OPT_daemon (option_mask32 & 0x10) | 26 | #define OPT_daemon (option_mask32 & 0x10) |
28 | #define OPT_verbose (option_mask32 & 0x20) | 27 | #define OPT_verbose (option_mask32 & 0x20) |
29 | 28 | ||
30 | //#define DEBUG 1 | 29 | //#define DEBUG 1 |
30 | #define DEBUG 0 | ||
31 | 31 | ||
32 | enum { | 32 | enum { |
33 | MAX_HOST_LEN = 16, // longest host name allowed is 15 | 33 | MAX_HOST_LEN = 16, // longest host name allowed is 15 |
@@ -76,8 +76,6 @@ struct dns_entry { // element of known name, ip address and reversed ip address | |||
76 | }; | 76 | }; |
77 | 77 | ||
78 | static struct dns_entry *dnsentry = NULL; | 78 | static struct dns_entry *dnsentry = NULL; |
79 | // FIXME! unused! :( | ||
80 | static int daemonmode; | ||
81 | static uint32_t ttl = DEFAULT_TTL; | 79 | static uint32_t ttl = DEFAULT_TTL; |
82 | 80 | ||
83 | /* | 81 | /* |
@@ -109,21 +107,6 @@ static void undot(uint8_t * rip) | |||
109 | } | 107 | } |
110 | 108 | ||
111 | /* | 109 | /* |
112 | * Append message to log file | ||
113 | */ | ||
114 | static void log_message(char *filename, char *message) | ||
115 | { | ||
116 | FILE *logfile; | ||
117 | if (!daemonmode) | ||
118 | return; | ||
119 | logfile = fopen(filename, "a"); | ||
120 | if (!logfile) | ||
121 | return; | ||
122 | fprintf(logfile, "%s\n", message); | ||
123 | fclose(logfile); | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * Read one line of hostname/IP from file | 110 | * Read one line of hostname/IP from file |
128 | * Returns 0 for each valid entry read, -1 at EOF | 111 | * Returns 0 for each valid entry read, -1 at EOF |
129 | * Assumes all host names are lower case only | 112 | * Assumes all host names are lower case only |
@@ -191,31 +174,6 @@ static void dnsentryinit(void) | |||
191 | fclose(fp); | 174 | fclose(fp); |
192 | } | 175 | } |
193 | 176 | ||
194 | |||
195 | /* | ||
196 | * Set up UDP socket | ||
197 | */ | ||
198 | static int listen_socket(char *iface_addr, int listen_port) | ||
199 | { | ||
200 | struct sockaddr_in a; | ||
201 | char msg[100]; | ||
202 | int sck; | ||
203 | sck = xsocket(PF_INET, SOCK_DGRAM, 0); | ||
204 | if (setsockopt_reuseaddr(sck) < 0) | ||
205 | bb_perror_msg_and_die("setsockopt() failed"); | ||
206 | memset(&a, 0, sizeof(a)); | ||
207 | a.sin_port = htons(listen_port); | ||
208 | a.sin_family = AF_INET; | ||
209 | if (!inet_aton(iface_addr, &a.sin_addr)) | ||
210 | bb_perror_msg_and_die("bad iface address"); | ||
211 | xbind(sck, (struct sockaddr *)&a, sizeof(a)); | ||
212 | xlisten(sck, 50); | ||
213 | sprintf(msg, "accepting UDP packets on addr:port %s:%d\n", | ||
214 | iface_addr, (int)listen_port); | ||
215 | log_message(LOG_FILE, msg); | ||
216 | return sck; | ||
217 | } | ||
218 | |||
219 | /* | 177 | /* |
220 | * Look query up in dns records and return answer if found | 178 | * Look query up in dns records and return answer if found |
221 | * qs is the query string, first byte the string length | 179 | * qs is the query string, first byte the string length |
@@ -309,7 +267,7 @@ static int process_packet(uint8_t * buf) | |||
309 | goto empty_packet; | 267 | goto empty_packet; |
310 | 268 | ||
311 | // We have a standard query | 269 | // We have a standard query |
312 | log_message(LOG_FILE, (char *)from); | 270 | bb_info_msg("%s", (char *)from); |
313 | lookup_result = table_lookup(type, answstr, (uint8_t*)from); | 271 | lookup_result = table_lookup(type, answstr, (uint8_t*)from); |
314 | if (lookup_result != 0) { | 272 | if (lookup_result != 0) { |
315 | outr.flags = 3 | 0x0400; //name do not exist and auth | 273 | outr.flags = 3 | 0x0400; //name do not exist and auth |
@@ -363,27 +321,26 @@ static int process_packet(uint8_t * buf) | |||
363 | static void interrupt(int x) | 321 | static void interrupt(int x) |
364 | { | 322 | { |
365 | unlink(LOCK_FILE); | 323 | unlink(LOCK_FILE); |
366 | write(2, "interrupt exiting\n", 18); | 324 | bb_error_msg("interrupt, exiting\n"); |
367 | exit(2); | 325 | exit(2); |
368 | } | 326 | } |
369 | 327 | ||
370 | int dnsd_main(int argc, char **argv) | 328 | int dnsd_main(int argc, char **argv) |
371 | { | 329 | { |
330 | char *listen_interface = NULL; | ||
331 | char *sttl, *sport; | ||
332 | len_and_sockaddr *lsa; | ||
372 | int udps; | 333 | int udps; |
373 | uint16_t port = 53; | 334 | uint16_t port = 53; |
374 | uint8_t buf[MAX_PACK_LEN]; | 335 | uint8_t buf[MAX_PACK_LEN]; |
375 | char *listen_interface = "0.0.0.0"; | ||
376 | char *sttl, *sport; | ||
377 | 336 | ||
378 | getopt32(argc, argv, "i:c:t:p:dv", &listen_interface, &fileconf, &sttl, &sport); | 337 | getopt32(argc, argv, "i:c:t:p:dv", &listen_interface, &fileconf, &sttl, &sport); |
379 | //if (option_mask32 & 0x1) // -i | 338 | //if (option_mask32 & 0x1) // -i |
380 | //if (option_mask32 & 0x2) // -c | 339 | //if (option_mask32 & 0x2) // -c |
381 | if (option_mask32 & 0x4) // -t | 340 | if (option_mask32 & 0x4) // -t |
382 | if (!(ttl = atol(sttl))) | 341 | ttl = xatou_range(sttl, 1, 0xffffffff); |
383 | bb_show_usage(); | ||
384 | if (option_mask32 & 0x8) // -p | 342 | if (option_mask32 & 0x8) // -p |
385 | if (!(port = atol(sport))) | 343 | port = xatou_range(sttl, 1, 0xffff); |
386 | bb_show_usage(); | ||
387 | 344 | ||
388 | if (OPT_verbose) { | 345 | if (OPT_verbose) { |
389 | bb_info_msg("listen_interface: %s", listen_interface); | 346 | bb_info_msg("listen_interface: %s", listen_interface); |
@@ -391,13 +348,16 @@ int dnsd_main(int argc, char **argv) | |||
391 | bb_info_msg("fileconf: %s", fileconf); | 348 | bb_info_msg("fileconf: %s", fileconf); |
392 | } | 349 | } |
393 | 350 | ||
394 | if (OPT_daemon) | 351 | if (OPT_daemon) { |
352 | //FIXME: NOMMU will NOT set LOGMODE_SYSLOG! | ||
395 | #ifdef BB_NOMMU | 353 | #ifdef BB_NOMMU |
396 | /* reexec for vfork() do continue parent */ | 354 | /* reexec for vfork() do continue parent */ |
397 | vfork_daemon_rexec(1, 0, argc, argv, "-d"); | 355 | vfork_daemon_rexec(1, 0, argc, argv, "-d"); |
398 | #else | 356 | #else |
399 | xdaemon(1, 0); | 357 | xdaemon(1, 0); |
400 | #endif | 358 | #endif |
359 | logmode = LOGMODE_SYSLOG; | ||
360 | } | ||
401 | 361 | ||
402 | dnsentryinit(); | 362 | dnsentryinit(); |
403 | 363 | ||
@@ -411,7 +371,12 @@ int dnsd_main(int argc, char **argv) | |||
411 | signal(SIGURG, SIG_IGN); | 371 | signal(SIGURG, SIG_IGN); |
412 | #endif | 372 | #endif |
413 | 373 | ||
414 | udps = listen_socket(listen_interface, port); | 374 | lsa = host2sockaddr(listen_interface, port); |
375 | udps = xsocket(lsa->sa.sa_family, SOCK_DGRAM, 0); | ||
376 | xbind(udps, &lsa->sa, lsa->len); | ||
377 | // xlisten(udps, 50); - ?!! DGRAM sockets are never listened on I think? | ||
378 | bb_info_msg("Accepting UDP packets on %s", | ||
379 | xmalloc_sockaddr2dotted(&lsa->sa, lsa->len)); | ||
415 | 380 | ||
416 | while (1) { | 381 | while (1) { |
417 | fd_set fdset; | 382 | fd_set fdset; |
@@ -420,6 +385,8 @@ int dnsd_main(int argc, char **argv) | |||
420 | FD_ZERO(&fdset); | 385 | FD_ZERO(&fdset); |
421 | FD_SET(udps, &fdset); | 386 | FD_SET(udps, &fdset); |
422 | // Block until a message arrives | 387 | // Block until a message arrives |
388 | // FIXME: Fantastic. select'ing on just one fd?? | ||
389 | // Why no just block on it doing recvfrom() ? | ||
423 | r = select(udps + 1, &fdset, NULL, NULL, NULL); | 390 | r = select(udps + 1, &fdset, NULL, NULL, NULL); |
424 | if (r < 0) | 391 | if (r < 0) |
425 | bb_perror_msg_and_die("select error"); | 392 | bb_perror_msg_and_die("select error"); |
@@ -428,27 +395,26 @@ int dnsd_main(int argc, char **argv) | |||
428 | 395 | ||
429 | /* Can this test ever be false? - yes */ | 396 | /* Can this test ever be false? - yes */ |
430 | if (FD_ISSET(udps, &fdset)) { | 397 | if (FD_ISSET(udps, &fdset)) { |
431 | struct sockaddr_in from; | 398 | socklen_t fromlen = lsa->len; |
432 | int fromlen = sizeof(from); | 399 | // FIXME: need to get *DEST* address (to which of our addresses |
433 | r = recvfrom(udps, buf, sizeof(buf), 0, | 400 | // this query was directed), and reply from the same address. |
434 | (struct sockaddr *)&from, | 401 | // Or else we can exhibit usual UDP ugliness: |
435 | (void *)&fromlen); | 402 | // [ip1.multihomed.ip2] <= query to ip1 <= peer |
403 | // [ip1.multihomed.ip2] => reply from ip2 => peer (confused) | ||
404 | r = recvfrom(udps, buf, sizeof(buf), 0, &lsa->sa, &fromlen); | ||
436 | if (OPT_verbose) | 405 | if (OPT_verbose) |
437 | fprintf(stderr, "\n--- Got UDP "); | 406 | bb_info_msg("Got UDP packet"); |
438 | log_message(LOG_FILE, "\n--- Got UDP "); | ||
439 | 407 | ||
440 | if (r < 12 || r > 512) { | 408 | if (r < 12 || r > 512) { |
441 | bb_error_msg("invalid packet size"); | 409 | bb_error_msg("invalid packet size"); |
442 | continue; | 410 | continue; |
443 | } | 411 | } |
444 | if (r > 0) { | 412 | if (r <= 0) |
445 | r = process_packet(buf); | 413 | continue; |
446 | if (r > 0) | 414 | r = process_packet(buf); |
447 | sendto(udps, buf, | 415 | if (r <= 0) |
448 | r, 0, (struct sockaddr *)&from, | 416 | continue; |
449 | fromlen); | 417 | sendto(udps, buf, r, 0, &lsa->sa, fromlen); |
450 | } | 418 | } |
451 | } // end if | 419 | } |
452 | } // end while | ||
453 | return 0; | ||
454 | } | 420 | } |