The device can't ping www.google.com but ping is okay. My OS is Android 6.0.1, the kernel is 4.1.15

I've tried the resolv.conf and /etc/hosts. But these methods seem can not work on Android.

And I couldn't figure out what the exact problem is.

eth0      Link encap:Ethernet  HWaddr EE:DE:17:79:BB:42
          inet addr:  Bcast:  Mask:
          inet6 addr: fe80::ecde:17ff:fe79:bb42/64 Scope: Link
          RX packets:7 errors:0 dropped:0 overruns:0 frame:0
          TX packets:15 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:600 TX bytes:1166

eth1      Link encap:Ethernet  HWaddr 00:0E:C6:81:79:01
          inet addr:  Bcast:  Mask:
          inet6 addr: fe80::20e:c6ff:fe81:7901/64 Scope: Link
          RX packets:41709 errors:0 dropped:0 overruns:0 frame:0
          TX packets:113 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2738793 TX bytes:8354

I closed the netd service so that it is able to configure eth0 and eth1 respectively.

Here is my IP rule

0:      from all lookup local
9998:   from all to lookup 4
9999:   from all to lookup 3
10000:  from all fwmark 0xc0000/0xd0000 lookup legacy_system
13000:  from all fwmark 0x10063/0x1ffff lookup local_network
15000:  from all fwmark 0x0/0x10000 lookup legacy_system
16000:  from all fwmark 0x0/0x10000 lookup legacy_network
17000:  from all fwmark 0x0/0x10000 lookup local_network
23000:  from all fwmark 0x0/0xffff uidrange 0-0 lookup main
32000:  from all unreachable

Here is a result of ping IP, you can see the response is fine.

root# ping
PING ( 56(84) bytes of data.
64 bytes from icmp_seq=1 ttl=64 time=1.08 ms
64 bytes from icmp_seq=2 ttl=64 time=0.986 ms
64 bytes from icmp_seq=3 ttl=64 time=1.00 ms

root# ping
PING ( 56(84) bytes of data.
64 bytes from icmp_seq=1 ttl=255 time=0.718 ms
64 bytes from icmp_seq=2 ttl=255 time=0.420 ms
64 bytes from icmp_seq=3 ttl=255 time=0.403 ms

But ping google always returns unknown.

ping: unknown host www.google.com

I expect I could ping IP and URL in my case.

BTW, the DNS from eth0 and the DNS from eth1 is


I'll try to explain my understanding of DNS on Android. It will help you troubleshoot related problems and serve me as future notes.

Most part is not applicable to non-root users.

Domain Name Resolver has traditionally been a part of OS's C library (commonly called libc). GNU libc (which is most common on Linux distros) implements a complicated name resolution mechanism named NSS which can prioritize in what order database services like LDAP / NIS, local files (/etc/hosts) and DNS have to be used in order to resolve host / domain names. DNS resolver then reads /etc/resolv.conf to get the name server address which is to be queried.

Unlike GNU libc, Android's Bionic libc doesn't regard /etc/resolv.conf unless ANDROID_CHANGES build variable is defined (that I haven't seen on production build ROMs; defined only when libc++ is built as static library???). However /etc/hosts entries are valued by Android's resolver when resolving names.
But if you are using a statically compiled / linked binary with some other - such as musl or uC or diet - libc, that must be reading /etc/resolv.conf to get Domain Name Server's IP address. Busybox ping could be a common example.

Within Android's Java runtime environment, either a DHCP provided or hard coded DNS server is used. Properties net.dns1 and net.dns2 are set with values of DNS servers received from DHCP server (on Wi-Fi or Mobile Data). These values are also changeable from IP Settings of a connected Wi-Fi. Starting with Android Oreo, these properties are no longer available through Android APIs, however being used by system as the references are still found.

DNS queries are cached on Android as NSCD does on Linux distros to speed up name resolution. Android has a commandline tool ndc that can be used to clear DNS cache:

# /system/bin/ndc resolver clearnetdns eth0

* Repeat same for other interfaces
* Commands syntax is a bit different on older versions

Previously different methods used to change default Domain Name Servers on Android don't seem to work now.
Changing properties net.dns* using setprop only affects the programs that explicitly read these properties. One such example I can recall is meefik's busybox.
Similarly setting name servers through ndc resolver setnetdns makes no difference at all. The only working option is iptables DNAT.

To test what name server is being used in Java runtime:

# /system/bin/dumpsys connectivity | grep CONNECTED | grep -o 'DnsAddresses: \[[^ ]*'

To see where the DNS queries are going, you may capture traffic destined for port 53:

# iptables -I OUTPUT -m udp -p udp --dport 53 -j LOG --log-prefix 'DNS_QUERIES '
# iptables -I OUTPUT -m tcp -p tcp --dport 53 -j LOG --log-prefix 'DNS_QUERIES '
# dmesg -w | grep 'DNS_QUERIES'


# tcpdump -n -i any port 53

* On Android Pie+, you need to set Private DNS off because by default DNS over TLS (DoT) sends encrypted DNS queries on port 853 as standardized in RFC7858

If the queries are not going to desired destination, there is some trouble with your DNS configuration, particularly if you use VPN. Dynamic nature of RPDB and routing tables (rt_tables keeps on changing, main table is not used) accompanied by fwmark (SO_MARK) make things complicated for manual control.

So there's nothing much you can do to fix DNS issues on Android devices. A Factory Reset or re-flashing of ROM may resolve the problem.

Additionally, if a local DNS server is provided by DHCP (server on Wi-Fi router), you may check if that's really listening on port 53:

# nmap -e eth0 -sUT -p53 --script=dns-recursion

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.