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 | |
parent | 6536a9b5833febe719988526a095a9cacb8a1042 (diff) | |
download | busybox-2c91652bbcc82c794c26230806058b04f1711033.tar.gz |
next part of ipv6-ization. dnsd code is "interesting"...
-rw-r--r-- | networking/dnsd.c | 110 | ||||
-rw-r--r-- | networking/telnetd.c | 11 | ||||
-rw-r--r-- | networking/tftp.c | 40 |
3 files changed, 53 insertions, 108 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 @@ #include "busybox.h" -static char *fileconf = "/etc/dnsd.conf"; +static const char *fileconf = "/etc/dnsd.conf"; #define LOCK_FILE "/var/run/dnsd.lock" -#define LOG_FILE "/var/log/dnsd.log" -// Must matct getopt32 call +// Must match getopt32 call #define OPT_daemon (option_mask32 & 0x10) #define OPT_verbose (option_mask32 & 0x20) //#define DEBUG 1 +#define DEBUG 0 enum { 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 }; static struct dns_entry *dnsentry = NULL; -// FIXME! unused! :( -static int daemonmode; static uint32_t ttl = DEFAULT_TTL; /* @@ -109,21 +107,6 @@ static void undot(uint8_t * rip) } /* - * Append message to log file - */ -static void log_message(char *filename, char *message) -{ - FILE *logfile; - if (!daemonmode) - return; - logfile = fopen(filename, "a"); - if (!logfile) - return; - fprintf(logfile, "%s\n", message); - fclose(logfile); -} - -/* * Read one line of hostname/IP from file * Returns 0 for each valid entry read, -1 at EOF * Assumes all host names are lower case only @@ -191,31 +174,6 @@ static void dnsentryinit(void) fclose(fp); } - -/* - * Set up UDP socket - */ -static int listen_socket(char *iface_addr, int listen_port) -{ - struct sockaddr_in a; - char msg[100]; - int sck; - sck = xsocket(PF_INET, SOCK_DGRAM, 0); - if (setsockopt_reuseaddr(sck) < 0) - bb_perror_msg_and_die("setsockopt() failed"); - memset(&a, 0, sizeof(a)); - a.sin_port = htons(listen_port); - a.sin_family = AF_INET; - if (!inet_aton(iface_addr, &a.sin_addr)) - bb_perror_msg_and_die("bad iface address"); - xbind(sck, (struct sockaddr *)&a, sizeof(a)); - xlisten(sck, 50); - sprintf(msg, "accepting UDP packets on addr:port %s:%d\n", - iface_addr, (int)listen_port); - log_message(LOG_FILE, msg); - return sck; -} - /* * Look query up in dns records and return answer if found * qs is the query string, first byte the string length @@ -309,7 +267,7 @@ static int process_packet(uint8_t * buf) goto empty_packet; // We have a standard query - log_message(LOG_FILE, (char *)from); + bb_info_msg("%s", (char *)from); lookup_result = table_lookup(type, answstr, (uint8_t*)from); if (lookup_result != 0) { outr.flags = 3 | 0x0400; //name do not exist and auth @@ -363,27 +321,26 @@ static int process_packet(uint8_t * buf) static void interrupt(int x) { unlink(LOCK_FILE); - write(2, "interrupt exiting\n", 18); + bb_error_msg("interrupt, exiting\n"); exit(2); } int dnsd_main(int argc, char **argv) { + char *listen_interface = NULL; + char *sttl, *sport; + len_and_sockaddr *lsa; int udps; uint16_t port = 53; uint8_t buf[MAX_PACK_LEN]; - char *listen_interface = "0.0.0.0"; - char *sttl, *sport; getopt32(argc, argv, "i:c:t:p:dv", &listen_interface, &fileconf, &sttl, &sport); //if (option_mask32 & 0x1) // -i //if (option_mask32 & 0x2) // -c if (option_mask32 & 0x4) // -t - if (!(ttl = atol(sttl))) - bb_show_usage(); + ttl = xatou_range(sttl, 1, 0xffffffff); if (option_mask32 & 0x8) // -p - if (!(port = atol(sport))) - bb_show_usage(); + port = xatou_range(sttl, 1, 0xffff); if (OPT_verbose) { bb_info_msg("listen_interface: %s", listen_interface); @@ -391,13 +348,16 @@ int dnsd_main(int argc, char **argv) bb_info_msg("fileconf: %s", fileconf); } - if (OPT_daemon) + if (OPT_daemon) { +//FIXME: NOMMU will NOT set LOGMODE_SYSLOG! #ifdef BB_NOMMU /* reexec for vfork() do continue parent */ vfork_daemon_rexec(1, 0, argc, argv, "-d"); #else xdaemon(1, 0); #endif + logmode = LOGMODE_SYSLOG; + } dnsentryinit(); @@ -411,7 +371,12 @@ int dnsd_main(int argc, char **argv) signal(SIGURG, SIG_IGN); #endif - udps = listen_socket(listen_interface, port); + lsa = host2sockaddr(listen_interface, port); + udps = xsocket(lsa->sa.sa_family, SOCK_DGRAM, 0); + xbind(udps, &lsa->sa, lsa->len); + // xlisten(udps, 50); - ?!! DGRAM sockets are never listened on I think? + bb_info_msg("Accepting UDP packets on %s", + xmalloc_sockaddr2dotted(&lsa->sa, lsa->len)); while (1) { fd_set fdset; @@ -420,6 +385,8 @@ int dnsd_main(int argc, char **argv) FD_ZERO(&fdset); FD_SET(udps, &fdset); // Block until a message arrives +// FIXME: Fantastic. select'ing on just one fd?? +// Why no just block on it doing recvfrom() ? r = select(udps + 1, &fdset, NULL, NULL, NULL); if (r < 0) bb_perror_msg_and_die("select error"); @@ -428,27 +395,26 @@ int dnsd_main(int argc, char **argv) /* Can this test ever be false? - yes */ if (FD_ISSET(udps, &fdset)) { - struct sockaddr_in from; - int fromlen = sizeof(from); - r = recvfrom(udps, buf, sizeof(buf), 0, - (struct sockaddr *)&from, - (void *)&fromlen); + socklen_t fromlen = lsa->len; +// FIXME: need to get *DEST* address (to which of our addresses +// this query was directed), and reply from the same address. +// Or else we can exhibit usual UDP ugliness: +// [ip1.multihomed.ip2] <= query to ip1 <= peer +// [ip1.multihomed.ip2] => reply from ip2 => peer (confused) + r = recvfrom(udps, buf, sizeof(buf), 0, &lsa->sa, &fromlen); if (OPT_verbose) - fprintf(stderr, "\n--- Got UDP "); - log_message(LOG_FILE, "\n--- Got UDP "); + bb_info_msg("Got UDP packet"); if (r < 12 || r > 512) { bb_error_msg("invalid packet size"); continue; } - if (r > 0) { - r = process_packet(buf); - if (r > 0) - sendto(udps, buf, - r, 0, (struct sockaddr *)&from, - fromlen); - } - } // end if - } // end while - return 0; + if (r <= 0) + continue; + r = process_packet(buf); + if (r <= 0) + continue; + sendto(udps, buf, r, 0, &lsa->sa, fromlen); + } + } } diff --git a/networking/telnetd.c b/networking/telnetd.c index dd5d55de0..ff83c93da 100644 --- a/networking/telnetd.c +++ b/networking/telnetd.c @@ -36,12 +36,6 @@ #define BUFSIZE 4000 -#if ENABLE_FEATURE_IPV6 -typedef struct sockaddr_in6 sockaddr_type; -#else -typedef struct sockaddr_in sockaddr_type; -#endif - #if ENABLE_LOGIN static const char *loginpath = "/bin/login"; #else @@ -462,13 +456,10 @@ telnetd_main(int argc, char **argv) #if ENABLE_FEATURE_TELNETD_STANDALONE /* First check for and accept new sessions. */ if (!IS_INETD && FD_ISSET(master_fd, &rdfdset)) { - sockaddr_type sa; int fd; - socklen_t salen; struct tsession *new_ts; - salen = sizeof(sa); - fd = accept(master_fd, (struct sockaddr *)&sa, &salen); + fd = accept(master_fd, NULL, 0); if (fd < 0) goto again; /* Create a new session and link it into our active list */ diff --git a/networking/tftp.c b/networking/tftp.c index 43e835a5d..9aa87d57e 100644 --- a/networking/tftp.c +++ b/networking/tftp.c @@ -240,10 +240,8 @@ static int tftp( } } - /* send packet */ - timeout = TFTP_NUM_RETRIES; /* re-initialize */ do { len = cp - xbuf; @@ -260,13 +258,12 @@ static int tftp( break; } - if (finished && (opcode == TFTP_ACK)) { break; } /* receive packet */ - + recv_again: tv.tv_sec = TFTP_TIMEOUT; tv.tv_usec = 0; @@ -288,25 +285,16 @@ static int tftp( bb_perror_msg("recvfrom"); break; } - timeout = 0; - if (from->sa_family == peer_lsa->sa.sa_family) { #if ENABLE_FEATURE_IPV6 - if (from->sa_family == AF_INET6 - && ((struct sockaddr_in6*)from)->sin6_port == port - ) - break; + if (from->sa_family == AF_INET6) + if (((struct sockaddr_in6*)from)->sin6_port != port) + goto recv_again; #endif - /* Non-internet sockets are ok */ - if (from->sa_family != AF_INET) - break; - if (((struct sockaddr_in*)from)->sin_port == port) - break; - } - /* family doesn't match, or - * it is INET[v6] and port doesn't match - - * fall-through for bad packets! - * (discard the packet - treat as timeout) */ - timeout = TFTP_NUM_RETRIES; + if (from->sa_family == AF_INET) + if (((struct sockaddr_in*)from)->sin_port != port) + goto recv_again; + timeout = 0; + break; case 0: bb_error_msg("timeout"); timeout--; @@ -436,11 +424,11 @@ static int tftp( } } -#if ENABLE_FEATURE_CLEAN_UP - close(socketfd); - free(xbuf); - free(rbuf); -#endif + if (ENABLE_FEATURE_CLEAN_UP) { + close(socketfd); + free(xbuf); + free(rbuf); + } return finished ? EXIT_SUCCESS : EXIT_FAILURE; } |