diff options
-rw-r--r-- | networking/nslookup.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/networking/nslookup.c b/networking/nslookup.c index 73ccb0ddd..8a820ce37 100644 --- a/networking/nslookup.c +++ b/networking/nslookup.c | |||
@@ -103,14 +103,15 @@ static int print_host(const char *hostname, const char *header) | |||
103 | static void server_print(void) | 103 | static void server_print(void) |
104 | { | 104 | { |
105 | char *server; | 105 | char *server; |
106 | struct sockaddr *sa; | ||
107 | |||
108 | #if ENABLE_FEATURE_IPV6 | ||
109 | sa = (struct sockaddr*)_res._u._ext.nsaddrs[0]; | ||
110 | if (!sa) | ||
111 | #endif | ||
112 | sa = (struct sockaddr*)&_res.nsaddr_list[0]; | ||
113 | server = xmalloc_sockaddr2dotted_noport(sa); | ||
106 | 114 | ||
107 | server = xmalloc_sockaddr2dotted_noport((struct sockaddr*)&_res.nsaddr_list[0]); | ||
108 | /* I honestly don't know what to do if DNS server has _IPv6 address_. | ||
109 | * Probably it is listed in | ||
110 | * _res._u._ext_.nsaddrs[MAXNS] (of type "struct sockaddr_in6*" each) | ||
111 | * but how to find out whether resolver uses | ||
112 | * _res.nsaddr_list[] or _res._u._ext_.nsaddrs[], or both? | ||
113 | * Looks like classic design from hell, BIND-grade. Hard to surpass. */ | ||
114 | print_host(server, "Server:"); | 115 | print_host(server, "Server:"); |
115 | if (ENABLE_FEATURE_CLEAN_UP) | 116 | if (ENABLE_FEATURE_CLEAN_UP) |
116 | free(server); | 117 | free(server); |
@@ -119,14 +120,28 @@ static void server_print(void) | |||
119 | 120 | ||
120 | /* alter the global _res nameserver structure to use | 121 | /* alter the global _res nameserver structure to use |
121 | an explicit dns server instead of what is in /etc/resolv.conf */ | 122 | an explicit dns server instead of what is in /etc/resolv.conf */ |
122 | static void set_default_dns(char *server) | 123 | static void set_default_dns(const char *server) |
123 | { | 124 | { |
124 | struct in_addr server_in_addr; | 125 | len_and_sockaddr *lsa; |
125 | 126 | ||
126 | if (inet_pton(AF_INET, server, &server_in_addr) > 0) { | 127 | /* NB: this works even with, say, "[::1]:5353"! :) */ |
128 | lsa = xhost2sockaddr(server, 53); | ||
129 | |||
130 | if (lsa->u.sa.sa_family == AF_INET) { | ||
127 | _res.nscount = 1; | 131 | _res.nscount = 1; |
128 | _res.nsaddr_list[0].sin_addr = server_in_addr; | 132 | /* struct copy */ |
133 | _res.nsaddr_list[0] = lsa->u.sin; | ||
129 | } | 134 | } |
135 | #if ENABLE_FEATURE_IPV6 | ||
136 | // Hoping libc will handle an IPv4 address there too, | ||
137 | // if it so happens that family is indeed AF_INET | ||
138 | // if (lsa->u.sa.sa_family == AF_INET6) { | ||
139 | _res._u._ext.nscount = 1; | ||
140 | /* store a pointer to part of malloc'ed lsa */ | ||
141 | _res._u._ext.nsaddrs[0] = &lsa->u.sin6; | ||
142 | /* must not free(lsa)! */ | ||
143 | // } | ||
144 | #endif | ||
130 | } | 145 | } |
131 | 146 | ||
132 | int nslookup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 147 | int nslookup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |