From 343dfd7abe44a32b329379ec9039f2560543518d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 7 Feb 2010 02:45:03 +0100 Subject: [PATCH] dnsd: add -s option. This allows (clumsy) operation with read dns servers function old new delta packed_usage 26816 26886 +70 dnsd_main 1299 1303 +4 Signed-off-by: Denys Vlasenko --- include/usage.h | 7 ++++- networking/dnsd.c | 75 +++++++++++++++++++++++++---------------------- 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/include/usage.h b/include/usage.h index 109a35d05..c2ffb6d6e 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 42deb1f35..e73e244b0 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(class, &unaligned_type_class->class); + if (class != htons(1)) { /* not class INET? */ + err_msg = "class != 1"; + goto empty_packet; + } 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"); - goto empty_packet; - } - /* OPCODE != 0 "standard query" ? */ - if ((head->flags & htons(0x7800)) != 0) { - bb_error_msg("opcode != 0%s", - ", returning Not Implemented reply"); +//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);