[git commit master] dnsd: add -s option. This allows (clumsy) operation with read dns servers

Denys Vlasenko vda.linux at googlemail.com
Sun Feb 7 01:45:03 UTC 2010


commit: http://git.busybox.net/busybox/commit/?id=343dfd7abe44a32b329379ec9039f2560543518d
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
packed_usage                                       26816   26886     +70
dnsd_main                                           1299    1303      +4

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 include/usage.h   |    7 ++++-
 networking/dnsd.c |   73 ++++++++++++++++++++++++++++------------------------
 2 files changed, 45 insertions(+), 35 deletions(-)

diff --git a/include/usage.h b/include/usage.h
index 109a35d..c2ffb6d 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -893,7 +893,7 @@
      "\n	-s SIZE		Buffer size" \
 
 #define dnsd_trivial_usage \
-       "[-c CONFFILE] [-t TTL_SEC] [-p PORT] [-i ADDR] [-d]"
+       "[-dvs] [-c CONFFILE] [-t TTL_SEC] [-p PORT] [-i ADDR]"
 #define dnsd_full_usage "\n\n" \
        "Small static DNS server daemon\n" \
      "\nOptions:" \
@@ -902,6 +902,11 @@
      "\n	-p PORT	Listen on PORT" \
      "\n	-i ADDR	Listen on ADDR" \
      "\n	-d	Daemonize" \
+     "\n	-v	Verbose" \
+     "\n	-s	Send successful replies only. Use this if you want" \
+     "\n		to use /etc/resolv.conf with two nameserver lines:" \
+     "\n			nameserver DNSD_SERVER" \
+     "\n			nameserver NORNAL_DNS_SERVER" \
 
 #define dos2unix_trivial_usage \
        "[OPTIONS] [FILE]"
diff --git a/networking/dnsd.c b/networking/dnsd.c
index 42deb1f..e73e244 100644
--- a/networking/dnsd.c
+++ b/networking/dnsd.c
@@ -56,7 +56,8 @@ struct dns_entry {
 	char name[1];
 };
 
-#define OPT_verbose (option_mask32)
+#define OPT_verbose (option_mask32 & 1)
+#define OPT_silent  (option_mask32 & 2)
 
 
 /*
@@ -351,10 +352,11 @@ static int process_packet(struct dns_entry *conf_data,
 		uint32_t conf_ttl,
 		uint8_t *buf)
 {
-	char *answstr;
 	struct dns_head *head;
 	struct type_and_class *unaligned_type_class;
+	const char *err_msg;
 	char *query_string;
+	char *answstr;
 	uint8_t *answb;
 	uint16_t outr_rlen;
 	uint16_t outr_flags;
@@ -365,12 +367,19 @@ static int process_packet(struct dns_entry *conf_data,
 	head = (struct dns_head *)buf;
 	if (head->nquer == 0) {
 		bb_error_msg("packet has 0 queries, ignored");
-		return -1;
+		return 0; /* don't reply */
 	}
-
 	if (head->flags & htons(0x8000)) { /* QR bit */
 		bb_error_msg("response packet, ignored");
-		return -1;
+		return 0; /* don't reply */
+	}
+	/* QR = 1 "response", RCODE = 4 "Not Implemented" */
+	outr_flags = htons(0x8000 | 4);
+	err_msg = NULL;
+	/* OPCODE != 0 "standard query" ? */
+	if ((head->flags & htons(0x7800)) != 0) {
+		err_msg = "opcode != 0";
+		goto empty_packet;
 	}
 
 	/* start of query string */
@@ -383,28 +392,16 @@ static int process_packet(struct dns_entry *conf_data,
 	/* where to append answer block */
 	answb = (void *)(unaligned_type_class + 1);
 
-	/* QR = 1 "response", RCODE = 4 "Not Implemented" */
-	outr_flags = htons(0x8000 | 4);
-
-	move_from_unaligned16(type, &unaligned_type_class->type);
-	if (type != htons(REQ_A) && type != htons(REQ_PTR)) {
-		/* we can't handle this query type */
-//TODO: handle REQ_AAAA (0x1c) requests
-		bb_error_msg("type %u is !REQ_A and !REQ_PTR%s",
-				(int)ntohs(type),
-				", returning Not Implemented reply");
-		goto empty_packet;
-	}
 	move_from_unaligned16(class, &unaligned_type_class->class);
 	if (class != htons(1)) { /* not class INET? */
-		bb_error_msg("class != 1%s",
-				", returning Not Implemented reply");
+		err_msg = "class != 1";
 		goto empty_packet;
 	}
-	/* OPCODE != 0 "standard query" ? */
-	if ((head->flags & htons(0x7800)) != 0) {
-		bb_error_msg("opcode != 0%s",
-				", returning Not Implemented reply");
+	move_from_unaligned16(type, &unaligned_type_class->type);
+	if (type != htons(REQ_A) && type != htons(REQ_PTR)) {
+		/* we can't handle this query type */
+//TODO: happens all the time with REQ_AAAA (0x1c) requests - implement those?
+		err_msg = "type is !REQ_A and !REQ_PTR";
 		goto empty_packet;
 	}
 
@@ -425,8 +422,7 @@ static int process_packet(struct dns_entry *conf_data,
 		/* QR = 1 "response"
 		 * AA = 1 "Authoritative Answer"
 		 * RCODE = 3 "Name Error" */
-		if (OPT_verbose)
-			bb_error_msg("returning Name Error reply");
+		err_msg = "name is not found";
 		outr_flags = htons(0x8000 | 0x0400 | 3);
 		goto empty_packet;
 	}
@@ -455,6 +451,16 @@ static int process_packet(struct dns_entry *conf_data,
 	head->nansw = htons(1);
 
  empty_packet:
+	if ((outr_flags & htons(0xf)) != 0) { /* not a positive response */
+		if (OPT_verbose) {
+			bb_error_msg("%s, %s",
+				err_msg,
+				OPT_silent ? "dropping query" : "sending error reply"
+			);
+		}
+		if (OPT_silent)
+			return 0;
+	}
 	head->flags |= outr_flags;
 	head->nauth = head->nadd = 0;
 	head->nquer = htons(1); // why???
@@ -476,21 +482,20 @@ int dnsd_main(int argc UNUSED_PARAM, char **argv)
 	uint16_t port = 53;
 	uint8_t buf[MAX_PACK_LEN + 1];
 
-	opts = getopt32(argv, "vi:c:t:p:d", &listen_interface, &fileconf, &sttl, &sport);
-	//if (opts & 0x1) // -v
-	//if (opts & 0x2) // -i
-	//if (opts & 0x4) // -c
-	if (opts & 0x8) // -t
+	opts = getopt32(argv, "vsi:c:t:p:d", &listen_interface, &fileconf, &sttl, &sport);
+	//if (opts & (1 << 0)) // -v
+	//if (opts & (1 << 1)) // -s
+	//if (opts & (1 << 2)) // -i
+	//if (opts & (1 << 3)) // -c
+	if (opts & (1 << 4)) // -t
 		conf_ttl = xatou_range(sttl, 1, 0xffffffff);
-	if (opts & 0x10) // -p
+	if (opts & (1 << 5)) // -p
 		port = xatou_range(sport, 1, 0xffff);
-	if (opts & 0x20) { // -d
+	if (opts & (1 << 6)) { // -d
 		bb_daemonize_or_rexec(DAEMON_CLOSE_EXTRA_FDS, argv);
 		openlog(applet_name, LOG_PID, LOG_DAEMON);
 		logmode = LOGMODE_SYSLOG;
 	}
-	/* Clear all except "verbose" bit */
-	option_mask32 &= 1;
 
 	conf_data = parse_conf_file(fileconf);
 
-- 
1.6.3.3



More information about the busybox-cvs mailing list