1 /* Copyright (C) 1997 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by H.J. Lu <hjl@gnu.ai.mit.edu>, 1997.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
21 * disallow names consisting only of digits/dots, unless
24 if (isdigit (name
[0]) || (isxdigit (name
[0]) || name
[0] == ':'))
28 typedef unsigned char host_addr_t
[16];
29 host_addr_t
*host_addr
;
30 typedef char *host_addr_list_t
[2];
31 host_addr_list_t
*host_aliases
;
32 host_addr_list_t
*h_addr_ptrs
;
46 addr_size
= IN6ADDRSZ
;
50 af
= (_res
.options
& RES_USE_INET6
) ? AF_INET6
: AF_INET
;
51 addr_size
= (af
== AF_INET6
) ? IN6ADDRSZ
: INADDRSZ
;
55 size_needed
= (sizeof (*host_addr
)
56 + sizeof (*host_aliases
) + sizeof (*h_addr_ptrs
)
59 #ifdef HAVE_LOOKUP_BUFFER
60 if (buflen
< size_needed
)
66 if (buffer_size
< size_needed
)
69 buffer_size
= size_needed
;
70 new_buf
= realloc (buffer
, buffer_size
);
79 result
= (struct hostent
*) NULL
;
84 #endif /* HAVE_LOOKUP_BUFFER */
86 memset (buffer
, 0, size_needed
);
88 host_addr
= (host_addr_t
*) buffer
;
89 host_aliases
= (host_addr_list_t
*)
90 ((char *) host_addr
+ sizeof (*host_addr
));
91 h_addr_ptrs
= (host_addr_list_t
*)
92 ((char *) host_aliases
+ sizeof (*host_aliases
));
93 hostname
= (char *) h_addr_ptrs
+ sizeof (*h_addr_ptrs
);
95 if (isdigit (name
[0]))
97 for (cp
= name
;; ++cp
)
101 if (*--cp
== '.') break;
103 /* All-numeric, no dot at the end. Fake up a hostent as if
104 we'd actually done a lookup. What if someone types
105 255.255.255.255? The test below will succeed
107 if (inet_pton (af
, name
, host_addr
) <= 0)
109 __set_h_errno (HOST_NOT_FOUND
);
110 #ifndef HAVE_LOOKUP_BUFFER
111 result
= (struct hostent
*) NULL
;
116 resbuf
.h_name
= strcpy (hostname
, name
);
117 resbuf
.h_aliases
= *host_aliases
;
118 (*host_aliases
)[0] = NULL
;
119 (*h_addr_ptrs
)[0] = (char *)host_addr
;
120 (*h_addr_ptrs
)[1] = (char *)0;
121 resbuf
.h_addr_list
= *h_addr_ptrs
;
122 if (_res
.options
& RES_USE_INET6
&& af
== AF_INET
)
124 /* We need to change the IP v4 address into the
126 char tmp
[INADDRSZ
], *p
= (char *) host_addr
;
129 /* Save a copy of the IP v4 address. */
130 memcpy (tmp
, host_addr
, INADDRSZ
);
131 /* Mark this ipv6 addr as a mapped ipv4. */
132 for (i
= 0; i
< 10; i
++)
136 /* Copy the IP v4 address. */
137 memcpy (p
, tmp
, INADDRSZ
);
138 resbuf
.h_addrtype
= AF_INET6
;
139 resbuf
.h_length
= IN6ADDRSZ
;
143 resbuf
.h_addrtype
= af
;
144 resbuf
.h_length
= addr_size
;
146 __set_h_errno (NETDB_SUCCESS
);
147 #ifdef HAVE_LOOKUP_BUFFER
148 status
= NSS_STATUS_SUCCESS
;
155 if (!isdigit (*cp
) && *cp
!= '.') break;
159 if ((isxdigit (name
[0]) && strchr (name
, ':') != NULL
)
164 typedef unsigned char host_addr_t
[16];
165 host_addr_t
*host_addr
;
166 typedef char *host_addr_list_t
[2];
167 host_addr_list_t
*host_aliases
;
168 host_addr_list_t
*h_addr_ptrs
;
178 addr_size
= INADDRSZ
;
182 addr_size
= IN6ADDRSZ
;
186 af
= (_res
.options
& RES_USE_INET6
) ? AF_INET6
: AF_INET
;
187 addr_size
= (af
== AF_INET6
) ? IN6ADDRSZ
: INADDRSZ
;
191 size_needed
= (sizeof (*host_addr
)
192 + sizeof (*host_aliases
) + sizeof (*h_addr_ptrs
)
193 + strlen (name
) + 1);
195 #ifdef HAVE_LOOKUP_BUFFER
196 if (buflen
< size_needed
)
198 __set_errno (ERANGE
);
202 if (buffer_size
< size_needed
)
205 buffer_size
= size_needed
;
206 new_buf
= realloc (buffer
, buffer_size
);
215 result
= (struct hostent
*) NULL
;
220 #endif /* HAVE_LOOKUP_BUFFER */
222 memset (buffer
, 0, size_needed
);
224 host_addr
= (host_addr_t
*) buffer
;
225 host_aliases
= (host_addr_list_t
*)
226 ((char *) host_addr
+ sizeof (*host_addr
));
227 h_addr_ptrs
= (host_addr_list_t
*)
228 ((char *) host_aliases
+ sizeof (*host_aliases
));
229 hostname
= (char *) h_addr_ptrs
+ sizeof (*h_addr_ptrs
);
231 for (cp
= name
;; ++cp
)
238 /* All-IPv6-legal, no dot at the end. Fake up a
239 hostent as if we'd actually done a lookup. */
240 if (inet_pton (af
, name
, host_addr
) <= 0)
242 __set_h_errno (HOST_NOT_FOUND
);
243 #ifndef HAVE_LOOKUP_BUFFER
244 result
= (struct hostent
*) NULL
;
249 resbuf
.h_name
= strcpy (hostname
, name
);
250 resbuf
.h_aliases
= *host_aliases
;
251 (*host_aliases
)[0] = NULL
;
252 (*h_addr_ptrs
)[0] = (char *) host_addr
;
253 (*h_addr_ptrs
)[1] = (char *) 0;
254 resbuf
.h_addr_list
= *h_addr_ptrs
;
255 resbuf
.h_addrtype
= af
;
256 resbuf
.h_length
= addr_size
;
257 __set_h_errno (NETDB_SUCCESS
);
258 #ifdef HAVE_LOOKUP_BUFFER
259 status
= NSS_STATUS_SUCCESS
;
266 if (!isxdigit (*cp
) && *cp
!= ':' && *cp
!= '.') break;