在Android系统中,想获取dns server的IP地址并不是一件容易的事,在bionic中,有关于获取dns IP地址的相关代码,但是你在native代码中却不能接调用相关的函数获取。
如在bionic/libc/include/resolv.h中有如下声明:
__BEGIN_DECLS #pragma GCC visibility push(default) struct res_state; extern struct __res_state *__res_state(void); #define _res (*__res_state()) #define b64_ntop __b64_ntop #define b64_pton __b64_pton extern int b64_ntop(u_char const*, size_t, char*, size_t); extern int b64_pton(char const*, u_char*, size_t); #define dn_comp __dn_comp extern int dn_comp(const char*, u_char*, int, u_char**, u_char**); extern int dn_expand(const u_char*, const u_char*, const u_char*, char*, int); #pragma GCC visibility pop __END_DECLS
文件中设置了编译条件:visibility为default, 而在bionic/libc/Android.mk文件中,将visibility设置为了hidden, 就是使得你在native代码中使用了_res或者是__res_state()函数时,在进行编译链接时,会报如下错误:
: error: undefined reference to '__res_state' collect2: error: ld returned 1 exit status
既然这条路行不通,那我们还有什么别的办法吗,先看一下与dns相关的系统属性:
$ adb shell getprop | grep dns [dhcp.wlan0.dns1]: [10.0.0.1] [dhcp.wlan0.dns2]: [] [dhcp.wlan0.dns3]: [] [dhcp.wlan0.dns4]: [] [net.change]: [net.dns1] [net.dns1]: [10.0.0.1]
这里我们可以看到当前连接的wifi网络的dns以及系统全局使用的dns(net.dns1),也许,我们只能从系统属性获取dns了。
在java代码中,我们可以通过LinkProperties即调用ConnectivityManager.getLinkProperties()得到特定网络的相关信息,当然这其中也包含了dns server的信息(LinkProperties.getDnsServers()):
Describes the properties of a network link. A link represents a connection to a network. It may have multiple addresses and multiple gateways, multiple dns servers but only one http proxy and one network interface. Note that this is just a holder of data. Modifying it does not affect live networks.
相关的代码如下:
// ... ConnectivityManager cm = (ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE); NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo(); for (Network network : cm.getAllNetworks()) { NetworkInfo networkInfo = cm.getNetworkInfo(network); if (networkInfo.getType() == activeNetworkInfo.getType()) { LinkProperties lp = cm.getLinkProperties(network); for (InetAddress addr : lp.getDnsServers()) { // Get DNS IP address here: } } } // ...