BusyBox v1.15.1 (2009-10-04 18:20:08 MSD) multi-call binary hardware is Asus wifi router wl-500g premium. $ cat /proc/cpuinfo system type : Broadcom BCM4704 chip rev 9 pkg 0 cpu model : BCM3302 V0.6 BogoMIPS : 263.78 ... firmware is from http://code.google.com/p/wl500g/ $ uname -a Linux my-test-router 2.4.37.6 #1 2009-10-04 18:23:22 MSD mips GNU/Linux nslookup syntax is $ nslookup BusyBox v1.15.1 (2009-10-04 18:20:08 MSD) multi-call binary Usage: nslookup [HOST] [SERVER] Query the nameserver for the IP address of the given HOST optionally using a specified DNS server ------- For my tasks i need use the second argument [SERVER], for example: nslookup www.ru 87.240.1.1 then nslookup show Server: 87.240.1.1 Address 1: 87.240.1.1 ns1.qwerty.ru Name: www.ru Address 1: 194.87.0.50 www.ru Looks as if it uses the second argument. But really the SERVER argument (87.240.1.1) is not used for dns lookups. It is seen from any sniffer, for example in tcpdump. I run tcpdump on my internet router: # tcpdump -nnpi eth0 port 53 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes 20:34:08.430492 IP 10.101.251.9.1073 > 10.101.251.1.53: 2+ PTR? 1.1.240.87.in-addr.arpa. (41) 20:34:08.433413 IP 10.101.251.1.53 > 10.101.251.9.1073: 2 1/0/0 PTR ns1.qwerty.ru. (68) 20:34:08.436927 IP 10.101.251.9.1073 > 10.101.251.1.53: 3+ AAAA? www.ru. (24) 20:34:08.438834 IP 10.101.251.1.53 > 10.101.251.9.1073: 3 0/0/0 (24) 20:34:08.439783 IP 10.101.251.9.1073 > 10.101.251.1.53: 4+ A? www.ru. (24) 20:34:08.455562 IP 10.101.251.1.53 > 10.101.251.9.1073: 4 1/0/0 A 194.87.0.50 (40) 20:34:08.458001 IP 10.101.251.9.1073 > 10.101.251.1.53: 5+ PTR? 50.0.87.194.in-addr.arpa. (42) 20:34:08.473415 IP 10.101.251.1.53 > 10.101.251.9.1073: 5 1/0/0 PTR www.ru. (62) ----------------- 10.101.251.9 - is host with busybox 10.101.251.1 - is main router It show that dns server 10.101.251.1 (from system /etc/resolv.conf) is used instead one in command line (87.240.1.1).
nslookup stores the address of the server into global _res structure, into _res.nsaddr_list[0]. Since _res is one of the worst designs in C library (it has so many flaws I don't know where to start), it's no wonder this does not work reliably. It works with uclibc. I need to look into glibc source to figure out how it is supposed to work there.
I did some looking into this bug. I posted to the glibc help mailing list to ask as a start: http://sourceware.org/ml/libc-help/2009-11/msg00011.html If I do not get an answer, I'll dig further into the glibc code and see if I can figure out what is going on.
# echo "" > /etc/resolv.conf # nslookup google.com nslookup: can't resolve '(null)' nslookup: can't resolve 'google.com' # nslookup google.com 8.8.8.8 Server: 8.8.8.8 Address 1: 8.8.8.8 nslookup: can't resolve 'google.com' # echo "nameserver 8.8.8.8" > /etc/resolv.conf # nslookup google.com nslookup: can't resolve '(null)' Name: google.com Address 1: 2a00:1450:4010:c04::66 lb-in-x66.1e100.net Address 2: 173.194.71.139 lb-in-f139.1e100.net Address 3: 173.194.71.102 lb-in-f102.1e100.net Address 4: 173.194.71.100 lb-in-f100.1e100.net Address 5: 173.194.71.101 lb-in-f101.1e100.net Address 6: 173.194.71.138 lb-in-f138.1e100.net Address 7: 173.194.71.113 lb-in-f113.1e100.net # nslookup google.com 8.8.8.8 Server: 8.8.8.8 Address 1: 8.8.8.8 google-public-dns-a.google.com Name: google.com Address 1: 2a00:1450:4010:c04::66 lb-in-x66.1e100.net Address 2: 74.125.143.113 la-in-f113.1e100.net Address 3: 74.125.143.138 la-in-f138.1e100.net Address 4: 74.125.143.101 la-in-f101.1e100.net Address 5: 74.125.143.102 la-in-f102.1e100.net Address 6: 74.125.143.100 la-in-f100.1e100.net Address 7: 74.125.143.139 la-in-f139.1e100.net So far nslookup always prints server info for 2nd argument, not for server being used, and always performs resolv using nameserver from resolv.conf even if 2nd argument is provided. BusyBox v1.20.2
Created attachment 4964 [details] Fix nslooup second argument use Using _res directly is a convenient hack but getaddrinfo and friends are free to request a resolver reinitialization. I think that without resorting too much to the libc internals a safe path is call set_default_dns again after the first getaddrinfo. I've attached a patch for busybox current that fixes the issue at least on Debian Wheezy and Openwrt AA (eglibc based).
Applied the patch, thanks!
This has not fixed the issue. I have tested on both Alpine Linux (Musl libc, latest release of busybox) and a fresh compile on Ubuntu, and neither respect the second argument to nslookup.
*** Bug 8241 has been marked as a duplicate of this bug. ***
I reproduced this on BusyBox v1.25.1 and BusyBox v1.23.1 with GNU C Library (GNU libc) stable release version 2.21
As of 1.27.1 it is still broken: root:~# nslookup google.com 0.0.0.0 Server: 0.0.0.0 Address 1: 0.0.0.0 Name: google.com Address 1: 2a00:1450:400e:807::200e ams15s30-in-x0e.1e100.net Address 2: 216.58.211.110 ams15s32-in-f14.1e100.net
Given how long this has been known and not resolved, what about simply printing that it won't use the server parameter? (and preferably also returning nonzero exit code) The current way is very confusing, doing something else than what it claims/appears to do, especially as I consider it a "debug tool".
I believe this is fixed with the FEATURE_NSLOOKUP_BIG: $ busybox nslookup google.com 0.0.0.0 nslookup: write to '0.0.0.0': Connection refused ;; connection timed out; no servers could be reached $ busybox nslookup google.com 1.1.1.1 Server: 1.1.1.1 Address: 1.1.1.1:53 Non-authoritative answer: Name: google.com Address: 172.217.17.110 Non-authoritative answer: Name: google.com Address: 2a00:1450:400e:806::200e
This is still an issue in 1.36.1. Entware uses busybox and I have this installed on my Asus routers. This is the result of trying to specify a server [asus2]: nslookup birdman.dynalias.org 8.8.8.8 Server: 8.8.8.8 Address 1: 8.8.8.8 dns.google Name: birdman.dynalias.org Address 1: 192.168.1.240 birdman.dynalias.org but that address is from the local resolver (hence the local address) not the one from Google's resolvers. The correct answer (at the moment) is: [asus2]: host birdman.dynalias.org 8.8.8.8 Using domain server: Name: 8.8.8.8 Address: 8.8.8.8#53 Aliases: birdman.dynalias.org has address 92.16.225.130 It does read resolv.conf, but even moving that out of the way or replacing the nameserver line in there with 8.8.8.8 doesn't stop it using the local address. And that is because it is reading the local hosts file, even though a specific server is given.