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] == ':'))
29 typedef unsigned char host_addr_t
[16];
30 host_addr_t
*host_addr
;
31 typedef char *host_addr_list_t
[2];
32 host_addr_list_t
*host_aliases
;
33 host_addr_list_t
*h_addr_ptrs
;
47 addr_size
= IN6ADDRSZ
;
51 af
= (_res
.options
& RES_USE_INET6
) ? AF_INET6
: AF_INET
;
52 addr_size
= (af
== AF_INET6
) ? IN6ADDRSZ
: INADDRSZ
;
56 size_needed
= (sizeof (*host
) + sizeof (*host_addr
)
57 + sizeof (*host_aliases
) + sizeof (*h_addr_ptrs
)
60 #ifdef HAVE_LOOKUP_BUFFER
61 if (buflen
< size_needed
)
67 if (buffer_size
< size_needed
)
70 buffer_size
= size_needed
;
71 new_buf
= realloc (buffer
, buffer_size
);
80 result
= (struct hostent
*) NULL
;
85 #endif /* HAVE_LOOKUP_BUFFER */
87 memset (buffer
, 0, size_needed
);
89 host
= (struct hostent
*) buffer
;
90 host_addr
= (host_addr_t
*) ((char *) host
+ sizeof (*host
));
91 host_aliases
= (host_addr_list_t
*)
92 ((char *) host_addr
+ sizeof (*host_addr
));
93 h_addr_ptrs
= (host_addr_list_t
*)
94 ((char *) host_aliases
+ sizeof (*host_aliases
));
95 hostname
= (char *) h_addr_ptrs
+ sizeof (*h_addr_ptrs
);
97 if (isdigit (name
[0]))
99 for (cp
= name
;; ++cp
)
103 if (*--cp
== '.') break;
105 /* All-numeric, no dot at the end. Fake up a hostent as if
106 we'd actually done a lookup. What if someone types
107 255.255.255.255? The test below will succeed
109 if (inet_pton (af
, name
, host_addr
) <= 0)
111 __set_h_errno (HOST_NOT_FOUND
);
112 #ifndef HAVE_LOOKUP_BUFFER
113 result
= (struct hostent
*) NULL
;
118 strcpy (hostname
, name
);
119 host
->h_name
= hostname
;
120 host
->h_aliases
= *host_aliases
;
121 (*host_aliases
)[0] = NULL
;
122 (*h_addr_ptrs
)[0] = (char *)host_addr
;
123 (*h_addr_ptrs
)[1] = (char *)0;
124 host
->h_addr_list
= *h_addr_ptrs
;
125 if (_res
.options
& RES_USE_INET6
&& af
== AF_INET
)
127 /* We need to change the IP v4 address into the
129 char tmp
[INADDRSZ
], *p
= (char *) host_addr
;
132 /* Save a copy of the IP v4 address. */
133 memcpy (tmp
, host_addr
, INADDRSZ
);
134 /* Mark this ipv6 addr as a mapped ipv4. */
135 for (i
= 0; i
< 10; i
++)
139 /* Copy the IP v4 address. */
140 memcpy (p
, tmp
, INADDRSZ
);
141 host
->h_addrtype
= AF_INET6
;
142 host
->h_length
= IN6ADDRSZ
;
146 host
->h_addrtype
= af
;
147 host
->h_length
= addr_size
;
149 __set_h_errno (NETDB_SUCCESS
);
150 #ifdef HAVE_LOOKUP_BUFFER
151 status
= NSS_STATUS_SUCCESS
;
158 if (!isdigit (*cp
) && *cp
!= '.') break;
162 if ((isxdigit (name
[0]) && strchr (name
, ':') != NULL
)
167 struct hostent
*host
;
168 typedef unsigned char host_addr_t
[16];
169 host_addr_t
*host_addr
;
170 typedef char *host_addr_list_t
[2];
171 host_addr_list_t
*host_aliases
;
172 host_addr_list_t
*h_addr_ptrs
;
182 addr_size
= INADDRSZ
;
186 addr_size
= IN6ADDRSZ
;
190 af
= (_res
.options
& RES_USE_INET6
) ? AF_INET6
: AF_INET
;
191 addr_size
= (af
== AF_INET6
) ? IN6ADDRSZ
: INADDRSZ
;
195 size_needed
= (sizeof (*host
) + sizeof (*host_addr
)
196 + sizeof (*host_aliases
) + sizeof (*h_addr_ptrs
)
197 + strlen (name
) + 1);
199 #ifdef HAVE_LOOKUP_BUFFER
200 if (buflen
< size_needed
)
202 __set_errno (ERANGE
);
206 if (buffer_size
< size_needed
)
209 buffer_size
= size_needed
;
210 new_buf
= realloc (buffer
, buffer_size
);
219 result
= (struct hostent
*) NULL
;
224 #endif /* HAVE_LOOKUP_BUFFER */
226 memset (buffer
, 0, size_needed
);
228 host
= (struct hostent
*) buffer
;
229 host_addr
= (host_addr_t
*) ((char *) host
+ sizeof (*host
));
230 host_aliases
= (host_addr_list_t
*)
231 ((char *) host_addr
+ sizeof (*host_addr
));
232 h_addr_ptrs
= (host_addr_list_t
*)
233 ((char *) host_aliases
+ sizeof (*host_aliases
));
234 hostname
= (char *) h_addr_ptrs
+ sizeof (*h_addr_ptrs
);
236 for (cp
= name
;; ++cp
)
243 /* All-IPv6-legal, no dot at the end. Fake up a
244 hostent as if we'd actually done a lookup. */
245 if (inet_pton (af
, name
, host_addr
) <= 0)
247 __set_h_errno (HOST_NOT_FOUND
);
248 #ifndef HAVE_LOOKUP_BUFFER
249 result
= (struct hostent
*) NULL
;
254 strcpy (hostname
, name
);
255 host
->h_name
= hostname
;
256 host
->h_aliases
= *host_aliases
;
257 (*host_aliases
)[0] = NULL
;
258 (*h_addr_ptrs
)[0] = (char *) host_addr
;
259 (*h_addr_ptrs
)[1] = (char *) 0;
260 host
->h_addr_list
= *h_addr_ptrs
;
261 host
->h_addrtype
= af
;
262 host
->h_length
= addr_size
;
263 __set_h_errno (NETDB_SUCCESS
);
264 #ifdef HAVE_LOOKUP_BUFFER
265 status
= NSS_STATUS_SUCCESS
;
272 if (!isxdigit (*cp
) && *cp
!= ':' && *cp
!= '.') break;