Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 532 by niro, Sat Sep 1 22:45:15 2007 UTC revision 816 by niro, Fri Apr 24 18:33:46 2009 UTC
# Line 12  Line 12 
12   */   */
13    
14  #include <resolv.h>  #include <resolv.h>
15  #include "busybox.h"  #include "libbb.h"
16    
17  /*  /*
18   *  I'm only implementing non-interactive mode;   * I'm only implementing non-interactive mode;
19   *  I totally forgot nslookup even had an interactive mode.   * 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   */   */
24    
25  /* Examples of 'standard' nslookup output  /* Examples of 'standard' nslookup output
# Line 47  Line 50 
50   * ns3.kernel.org  internet address = 204.152.191.36   * ns3.kernel.org  internet address = 204.152.191.36
51   */   */
52    
 static int sockaddr_to_dotted(struct sockaddr *saddr, char *buf, int buflen)  
 {  
  if (buflen <= 0) return -1;  
  buf[0] = '\0';  
  if (saddr->sa_family == AF_INET) {  
  inet_ntop(AF_INET, &((struct sockaddr_in*)saddr)->sin_addr, buf, buflen);  
  return 0;  
  }  
  if (saddr->sa_family == AF_INET6) {  
  inet_ntop(AF_INET6, &((struct sockaddr_in6*)saddr)->sin6_addr, buf, buflen);  
  return 0;  
  }  
  return -1;  
 }  
   
53  static int print_host(const char *hostname, const char *header)  static int print_host(const char *hostname, const char *header)
54  {  {
55   char str[128]; /* IPv6 address will fit, hostnames hopefully too */   /* We can't use xhost2sockaddr() - we want to get ALL addresses,
56     * not just one */
57   struct addrinfo *result = NULL;   struct addrinfo *result = NULL;
58   int rc;   int rc;
59   struct addrinfo hint;   struct addrinfo hint;
# Line 76  static int print_host(const char *hostna Line 65  static int print_host(const char *hostna
65   hint.ai_socktype = SOCK_STREAM;   hint.ai_socktype = SOCK_STREAM;
66   // hint.ai_flags = AI_CANONNAME;   // hint.ai_flags = AI_CANONNAME;
67   rc = getaddrinfo(hostname, NULL /*service*/, &hint, &result);   rc = getaddrinfo(hostname, NULL /*service*/, &hint, &result);
68    
69   if (!rc) {   if (!rc) {
70   struct addrinfo *cur = result;   struct addrinfo *cur = result;
71   // printf("%s\n", cur->ai_canonname); ?   unsigned cnt = 0;
72    
73     printf("%-10s %s\n", header, hostname);
74     // puts(cur->ai_canonname); ?
75   while (cur) {   while (cur) {
76   sockaddr_to_dotted(cur->ai_addr, str, sizeof(str));   char *dotted, *revhost;
77   printf("%s  %s\nAddress: %s", header, hostname, str);   dotted = xmalloc_sockaddr2dotted_noport(cur->ai_addr);
78   str[0] = ' ';   revhost = xmalloc_sockaddr2hostonly_noport(cur->ai_addr);
79   if (getnameinfo(cur->ai_addr, cur->ai_addrlen, str+1, sizeof(str)-1, NULL, 0, NI_NAMEREQD))  
80   str[0] = '\0';   printf("Address %u: %s%c", ++cnt, dotted, revhost ? ' ' : '\n');
81   puts(str);   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   cur = cur->ai_next;   cur = cur->ai_next;
89   }   }
90   } else {   } else {
91   bb_error_msg("getaddrinfo('%s') failed: %s", hostname, gai_strerror(rc));  #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   }   }
97   freeaddrinfo(result);   if (ENABLE_FEATURE_CLEAN_UP)
98     freeaddrinfo(result);
99   return (rc != 0);   return (rc != 0);
100  }  }
101    
102    /* lookup the default nameserver and display it */
103    static void server_print(void)
104    {
105     char *server;
106    
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     if (ENABLE_FEATURE_CLEAN_UP)
116     free(server);
117     bb_putchar('\n');
118    }
119    
120  /* alter the global _res nameserver structure to use  /* alter the global _res nameserver structure to use
121     an explicit dns server instead of what is in /etc/resolv.h */     an explicit dns server instead of what is in /etc/resolv.conf */
122  static void set_default_dns(char *server)  static void set_default_dns(char *server)
123  {  {
124   struct in_addr server_in_addr;   struct in_addr server_in_addr;
# Line 108  static void set_default_dns(char *server Line 129  static void set_default_dns(char *server
129   }   }
130  }  }
131    
132    int nslookup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 /* lookup the default nameserver and display it */  
 static void server_print(void)  
 {  
  char str[INET6_ADDRSTRLEN];  
   
  sockaddr_to_dotted((struct sockaddr*)&_res.nsaddr_list[0], str, sizeof(str));  
  print_host(str, "Server:");  
  puts("");  
 }  
   
   
133  int nslookup_main(int argc, char **argv)  int nslookup_main(int argc, char **argv)
134  {  {
135   /*   /* We allow 1 or 2 arguments.
136   * initialize DNS structure _res used in printing the default   * The first is the name to be looked up and the second is an
137   * name server and in the explicit name server option feature.   * 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    
143     /* initialize DNS structure _res used in printing the default
144     * name server and in the explicit name server option feature. */
145   res_init();   res_init();
146     /* 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    
150   /*   if (argv[2])
  * We allow 1 or 2 arguments.  
  * The first is the name to be looked up and the second is an  
  * optional DNS server with which to do the lookup.  
  * More than 3 arguments is an error to follow the pattern of the  
  * standard nslookup  
  */  
   
  if (argc < 2 || *argv[1] == '-' || argc > 3)  
  bb_show_usage();  
  else if(argc == 3)  
151   set_default_dns(argv[2]);   set_default_dns(argv[2]);
152    
153   server_print();   server_print();
154   return print_host(argv[1], "Name:  ");   return print_host(argv[1], "Name:");
155  }  }
   
 /* $Id: nslookup.c,v 1.1 2007-09-01 22:43:53 niro Exp $ */  

Legend:
Removed from v.532  
changed lines
  Added in v.816