aboutsummaryrefslogtreecommitdiff
path: root/networking/dnsd.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-01-12 14:57:37 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-01-12 14:57:37 +0000
commit2c91652bbcc82c794c26230806058b04f1711033 (patch)
tree1195f7c7fba68bdaf175d85432bf60a60a8c29f0 /networking/dnsd.c
parent6536a9b5833febe719988526a095a9cacb8a1042 (diff)
downloadbusybox-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.c110
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
22static char *fileconf = "/etc/dnsd.conf"; 22static 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
32enum { 32enum {
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
78static struct dns_entry *dnsentry = NULL; 78static struct dns_entry *dnsentry = NULL;
79// FIXME! unused! :(
80static int daemonmode;
81static uint32_t ttl = DEFAULT_TTL; 79static 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 */
114static 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 */
198static 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)
363static void interrupt(int x) 321static 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
370int dnsd_main(int argc, char **argv) 328int 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}