1 /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 /* Resolves IP's to hostname and hostnames to IP's */
24 
25 #define RESOLVE_VERSION "2.3"
26 
27 #include <my_global.h>
28 #include <m_ctype.h>
29 #include <my_sys.h>
30 #include <m_string.h>
31 #ifndef WIN32
32 #  include <sys/types.h>
33 #  include <sys/socket.h>
34 #  ifndef HAVE_BROKEN_NETINET_INCLUDES
35 #    include <netinet/in.h>
36 #  endif
37 #  include <arpa/inet.h>
38 #  include <netdb.h>
39 #endif
40 #include <my_net.h>
41 #include <my_getopt.h>
42 
43 #if !defined(_AIX) && !defined(h_errno)
44 extern int h_errno;
45 #endif
46 
47 static my_bool silent;
48 
49 static struct my_option my_long_options[] =
50 {
51   {"help", '?', "Displays this help and exits.",
52    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
53   {"info", 'I', "Synonym for --help.",
54    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
55   {"silent", 's', "Be more silent.", &silent, &silent,
56    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
57   {"version", 'V', "Displays version information and exits.",
58    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
59   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
60 };
61 
62 
print_version(void)63 static void print_version(void)
64 {
65   printf("%s Ver %s, for %s (%s)\n",my_progname,RESOLVE_VERSION,
66 	 SYSTEM_TYPE,MACHINE_TYPE);
67 }
68 
69 
usage(void)70 static void usage(void)
71 {
72   print_version();
73   puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
74   puts("Get hostname based on IP-address or IP-address based on hostname.\n");
75   printf("Usage: %s [OPTIONS] hostname or IP-address\n",my_progname);
76   my_print_help(my_long_options);
77   my_print_variables(my_long_options);
78 }
79 
80 
81 static my_bool
get_one_option(int optid,const struct my_option * opt MY_ATTRIBUTE ((unused)),char * argument MY_ATTRIBUTE ((unused)))82 get_one_option(int optid, const struct my_option *opt MY_ATTRIBUTE((unused)),
83 	       char *argument MY_ATTRIBUTE((unused)))
84 {
85   switch (optid) {
86   case 'V': print_version(); exit(0);
87   case 'I':
88   case '?':
89     usage();
90     exit(0);
91   }
92   return 0;
93 }
94 
95 /*static char * load_default_groups[]= { "resolveip","client",0 }; */
96 
get_options(int * argc,char *** argv)97 static int get_options(int *argc,char ***argv)
98 {
99   int ho_error;
100 
101   if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
102     exit(ho_error);
103 
104   if (*argc == 0)
105   {
106     usage();
107     return 1;
108   }
109   return 0;
110 } /* get_options */
111 
112 
113 
main(int argc,char ** argv)114 int main(int argc, char **argv)
115 {
116   struct hostent *hpaddr;
117   in_addr_t taddr;
118   char *ip,**q;
119   int error=0;
120 
121   MY_INIT(argv[0]);
122 
123   if (get_options(&argc,&argv))
124     exit(1);
125 
126   while (argc--)
127   {
128 #ifndef WIN32
129     struct in_addr addr;
130 #endif
131     ip = *argv++;
132 
133     /* Not compatible with IPv6!  Probably should use getnameinfo(). */
134 #ifdef WIN32
135     taddr = inet_addr(ip);
136     if(taddr != INADDR_NONE)
137     {
138 #else
139     if (inet_aton(ip, &addr) != 0)
140     {
141       taddr= addr.s_addr;
142 #endif
143       if (taddr == htonl(INADDR_BROADCAST))
144       {
145 	puts("Broadcast");
146 	continue;
147       }
148       if (taddr == htonl(INADDR_ANY))
149       {
150 	if (!taddr)
151 	  puts("Null-IP-Addr");
152 	else
153 	  puts("Old-Bcast");
154 	continue;
155       }
156 
157       hpaddr = gethostbyaddr((char*) &(taddr), sizeof(struct in_addr),AF_INET);
158       if (hpaddr)
159       {
160 	if (silent)
161 	  puts(hpaddr->h_name);
162 	else
163 	{
164 	  printf ("Host name of %s is %s", ip,hpaddr->h_name);
165 	  for (q = hpaddr->h_aliases; *q != 0; q++)
166 	    (void) printf(", %s", *q);
167 	  puts("");
168 	}
169       }
170       else
171       {
172 	error=2;
173 	fprintf(stderr,"%s: Unable to find hostname for '%s'\n",my_progname,
174 		ip);
175       }
176     }
177     else
178     {
179       hpaddr = gethostbyname(ip);
180       if (!hpaddr)
181       {
182 	const char *err;
183 	fprintf(stderr,"%s: Unable to find hostid for '%s'",my_progname,ip);
184 	switch (h_errno) {
185 	case HOST_NOT_FOUND: err="host not found"; break;
186 	case TRY_AGAIN: err="try again"; break;
187 	case NO_RECOVERY: err="no recovery"; break;
188 	case NO_DATA: err="no_data"; break;
189 	default: err=0;
190 	}
191 	if (err)
192 	  fprintf(stderr,": %s\n",err);
193 	else
194 	  fprintf(stderr,"\n");
195 	error=2;
196       }
197       else if (silent)
198       {
199 	struct in_addr in;
200 	memcpy((char*) &in.s_addr, (char*) *hpaddr->h_addr_list,
201 	       sizeof (in.s_addr));
202 	puts(inet_ntoa(in));
203       }
204       else
205       {
206 	char **p;
207 	for (p = hpaddr->h_addr_list; *p != 0; p++)
208 	{
209 	  struct in_addr in;
210 	  memcpy(&in.s_addr, *p, sizeof (in.s_addr));
211 	  printf ("IP address of %s is %s\n",ip,inet_ntoa(in));
212 	}
213       }
214     }
215   }
216   exit(error);
217 }
218