Magellan Linux

Annotation of /trunk/mkinitrd-magellan/busybox/networking/nslookup.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 984 - (hide annotations) (download)
Sun May 30 11:32:42 2010 UTC (14 years ago) by niro
File MIME type: text/plain
File size: 5135 byte(s)
-updated to busybox-1.16.1 and enabled blkid/uuid support in default config
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 984 struct sockaddr *sa;
107 niro 532
108 niro 984 #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);
114    
115 niro 816 print_host(server, "Server:");
116     if (ENABLE_FEATURE_CLEAN_UP)
117     free(server);
118     bb_putchar('\n');
119     }
120    
121 niro 532 /* alter the global _res nameserver structure to use
122 niro 816 an explicit dns server instead of what is in /etc/resolv.conf */
123 niro 984 static void set_default_dns(const char *server)
124 niro 532 {
125 niro 984 len_and_sockaddr *lsa;
126 niro 532
127 niro 984 /* NB: this works even with, say, "[::1]:5353"! :) */
128     lsa = xhost2sockaddr(server, 53);
129    
130     if (lsa->u.sa.sa_family == AF_INET) {
131 niro 532 _res.nscount = 1;
132 niro 984 /* struct copy */
133     _res.nsaddr_list[0] = lsa->u.sin;
134 niro 532 }
135 niro 984 #if ENABLE_FEATURE_IPV6
136     /* Hoped libc can cope with IPv4 address there too.
137     * No such luck, glibc 2.4 segfaults even with IPv6,
138     * maybe I misunderstand how to make glibc use IPv6 addr?
139     * (uclibc 0.9.31+ should work) */
140     if (lsa->u.sa.sa_family == AF_INET6) {
141     // glibc neither SEGVs nor sends any dgrams with this
142     // (strace shows no socket ops):
143     //_res.nscount = 0;
144     _res._u._ext.nscount = 1;
145     /* store a pointer to part of malloc'ed lsa */
146     _res._u._ext.nsaddrs[0] = &lsa->u.sin6;
147     /* must not free(lsa)! */
148     }
149     #endif
150 niro 532 }
151    
152 niro 816 int nslookup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
153 niro 532 int nslookup_main(int argc, char **argv)
154     {
155 niro 816 /* We allow 1 or 2 arguments.
156     * The first is the name to be looked up and the second is an
157     * optional DNS server with which to do the lookup.
158     * More than 3 arguments is an error to follow the pattern of the
159     * standard nslookup */
160     if (!argv[1] || argv[1][0] == '-' || argc > 3)
161     bb_show_usage();
162 niro 532
163 niro 816 /* initialize DNS structure _res used in printing the default
164     * name server and in the explicit name server option feature. */
165 niro 532 res_init();
166 niro 816 /* rfc2133 says this enables IPv6 lookups */
167     /* (but it also says "may be enabled in /etc/resolv.conf") */
168     /*_res.options |= RES_USE_INET6;*/
169 niro 532
170 niro 816 if (argv[2])
171 niro 532 set_default_dns(argv[2]);
172    
173     server_print();
174 niro 816 return print_host(argv[1], "Name:");
175 niro 532 }