Magellan Linux

Annotation of /tags/mkinitrd-6_1_11/busybox/networking/nslookup.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 928 - (hide annotations) (download)
Wed Oct 28 13:31:19 2009 UTC (14 years, 7 months ago) by niro
File MIME type: text/plain
File size: 4746 byte(s)
tagged 'mkinitrd-6_1_11'
1 niro 532 /* vi: set sw=4 ts=4: */
2     /*
3     * Mini nslookup implementation for busybox
4     *
5     * Copyright (C) 1999,2000 by Lineo, inc. and John Beppu
6     * Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org>
7     *
8     * Correct default name server display and explicit name server option
9     * added by Ben Zeckel <bzeckel@hmc.edu> June 2001
10     *
11     * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
12     */
13    
14     #include <resolv.h>
15 niro 816 #include "libbb.h"
16 niro 532
17     /*
18 niro 816 * I'm only implementing non-interactive mode;
19     * I totally forgot nslookup even had an interactive mode.
20     *
21     * This applet is the only user of res_init(). Without it,
22     * you may avoid pulling in _res global from libc.
23 niro 532 */
24    
25     /* Examples of 'standard' nslookup output
26     * $ nslookup yahoo.com
27     * Server: 128.193.0.10
28     * Address: 128.193.0.10#53
29     *
30     * Non-authoritative answer:
31     * Name: yahoo.com
32     * Address: 216.109.112.135
33     * Name: yahoo.com
34     * Address: 66.94.234.13
35     *
36     * $ nslookup 204.152.191.37
37     * Server: 128.193.4.20
38     * Address: 128.193.4.20#53
39     *
40     * Non-authoritative answer:
41     * 37.191.152.204.in-addr.arpa canonical name = 37.32-27.191.152.204.in-addr.arpa.
42     * 37.32-27.191.152.204.in-addr.arpa name = zeus-pub2.kernel.org.
43     *
44     * Authoritative answers can be found from:
45     * 32-27.191.152.204.in-addr.arpa nameserver = ns1.kernel.org.
46     * 32-27.191.152.204.in-addr.arpa nameserver = ns2.kernel.org.
47     * 32-27.191.152.204.in-addr.arpa nameserver = ns3.kernel.org.
48     * ns1.kernel.org internet address = 140.211.167.34
49     * ns2.kernel.org internet address = 204.152.191.4
50     * ns3.kernel.org internet address = 204.152.191.36
51     */
52    
53     static int print_host(const char *hostname, const char *header)
54     {
55 niro 816 /* We can't use xhost2sockaddr() - we want to get ALL addresses,
56     * not just one */
57 niro 532 struct addrinfo *result = NULL;
58     int rc;
59     struct addrinfo hint;
60    
61     memset(&hint, 0 , sizeof(hint));
62     /* hint.ai_family = AF_UNSPEC; - zero anyway */
63     /* Needed. Or else we will get each address thrice (or more)
64     * for each possible socket type (tcp,udp,raw...): */
65     hint.ai_socktype = SOCK_STREAM;
66     // hint.ai_flags = AI_CANONNAME;
67     rc = getaddrinfo(hostname, NULL /*service*/, &hint, &result);
68 niro 816
69 niro 532 if (!rc) {
70     struct addrinfo *cur = result;
71 niro 816 unsigned cnt = 0;
72    
73     printf("%-10s %s\n", header, hostname);
74     // puts(cur->ai_canonname); ?
75 niro 532 while (cur) {
76 niro 816 char *dotted, *revhost;
77     dotted = xmalloc_sockaddr2dotted_noport(cur->ai_addr);
78     revhost = xmalloc_sockaddr2hostonly_noport(cur->ai_addr);
79    
80     printf("Address %u: %s%c", ++cnt, dotted, revhost ? ' ' : '\n');
81     if (revhost) {
82     puts(revhost);
83     if (ENABLE_FEATURE_CLEAN_UP)
84     free(revhost);
85     }
86     if (ENABLE_FEATURE_CLEAN_UP)
87     free(dotted);
88 niro 532 cur = cur->ai_next;
89     }
90     } else {
91 niro 816 #if ENABLE_VERBOSE_RESOLUTION_ERRORS
92     bb_error_msg("can't resolve '%s': %s", hostname, gai_strerror(rc));
93     #else
94     bb_error_msg("can't resolve '%s'", hostname);
95     #endif
96 niro 532 }
97 niro 816 if (ENABLE_FEATURE_CLEAN_UP)
98     freeaddrinfo(result);
99 niro 532 return (rc != 0);
100     }
101    
102 niro 816 /* lookup the default nameserver and display it */
103     static void server_print(void)
104     {
105     char *server;
106 niro 532
107 niro 816 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     if (ENABLE_FEATURE_CLEAN_UP)
116     free(server);
117     bb_putchar('\n');
118     }
119    
120 niro 532 /* alter the global _res nameserver structure to use
121 niro 816 an explicit dns server instead of what is in /etc/resolv.conf */
122 niro 532 static void set_default_dns(char *server)
123     {
124     struct in_addr server_in_addr;
125    
126     if (inet_pton(AF_INET, server, &server_in_addr) > 0) {
127     _res.nscount = 1;
128     _res.nsaddr_list[0].sin_addr = server_in_addr;
129     }
130     }
131    
132 niro 816 int nslookup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
133 niro 532 int nslookup_main(int argc, char **argv)
134     {
135 niro 816 /* We allow 1 or 2 arguments.
136     * The first is the name to be looked up and the second is an
137     * optional DNS server with which to do the lookup.
138     * More than 3 arguments is an error to follow the pattern of the
139     * standard nslookup */
140     if (!argv[1] || argv[1][0] == '-' || argc > 3)
141     bb_show_usage();
142 niro 532
143 niro 816 /* initialize DNS structure _res used in printing the default
144     * name server and in the explicit name server option feature. */
145 niro 532 res_init();
146 niro 816 /* rfc2133 says this enables IPv6 lookups */
147     /* (but it also says "may be enabled in /etc/resolv.conf") */
148     /*_res.options |= RES_USE_INET6;*/
149 niro 532
150 niro 816 if (argv[2])
151 niro 532 set_default_dns(argv[2]);
152    
153     server_print();
154 niro 816 return print_host(argv[1], "Name:");
155 niro 532 }