1 /* The Inner Net License, Version 2.00
3 The author(s) grant permission for redistribution and use in source and
4 binary forms, with or without modification, of the software and documentation
5 provided that the following conditions are met:
7 0. If you receive a version of the software that is specifically labelled
8 as not being for redistribution (check the version message and/or README),
9 you are not permitted to redistribute that version of the software in any
11 1. All terms of the all other applicable copyrights and licenses must be
13 2. Redistributions of source code must retain the authors' copyright
14 notice(s), this list of conditions, and the following disclaimer.
15 3. Redistributions in binary form must reproduce the authors' copyright
16 notice(s), this list of conditions, and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18 4. [The copyright holder has authorized the removal of this clause.]
19 5. Neither the name(s) of the author(s) nor the names of its contributors
20 may be used to endorse or promote products derived from this software
21 without specific prior written permission.
23 THIS SOFTWARE IS PROVIDED BY ITS AUTHORS AND CONTRIBUTORS ``AS IS'' AND ANY
24 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY
27 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 If these license terms cause you a real problem, contact the author. */
36 /* This software is Copyright 1996 by Craig Metz, All Rights Reserved. */
44 #include <arpa/inet.h>
46 #include <netinet/in.h>
47 #include <sys/param.h>
48 #include <sys/socket.h>
49 #include <sys/types.h>
51 #include <sys/utsname.h>
52 #include <bits/libc-lock.h>
55 # define min(x,y) (((x) > (y)) ? (y) : (x))
68 __libc_lock_define_initialized (static, lock
);
69 __libc_lock_lock (lock
);
74 struct hostent
*h
, th
;
75 size_t tmpbuflen
= 1024;
76 char *tmpbuf
= alloca (tmpbuflen
);
81 while (__gethostbyname_r ("localhost", &th
, tmpbuf
, tmpbuflen
, &h
,
84 if (herror
== NETDB_INTERNAL
&& errno
== ERANGE
)
85 tmpbuf
= extend_alloca (tmpbuf
, tmpbuflen
, 2 * tmpbuflen
);
90 if (h
&& (c
= strchr (h
->h_name
, '.')))
91 domain
= __strdup (++c
);
94 /* The name contains no domain information. Use the name
95 now to get more information. */
96 while (__gethostname (tmpbuf
, tmpbuflen
))
97 tmpbuf
= extend_alloca (tmpbuf
, tmpbuflen
, 2 * tmpbuflen
);
99 if ((c
= strchr (tmpbuf
, '.')))
100 domain
= __strdup (++c
);
103 /* We need to preserve the hostname. */
104 const char *hstname
= strdupa (tmpbuf
);
106 while (__gethostbyname_r (hstname
, &th
, tmpbuf
, tmpbuflen
,
109 if (herror
== NETDB_INTERNAL
&& errno
== ERANGE
)
110 tmpbuf
= extend_alloca (tmpbuf
, tmpbuflen
,
116 if (h
&& (c
= strchr(h
->h_name
, '.')))
117 domain
= __strdup (++c
);
120 struct in_addr in_addr
;
122 in_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
124 while (__gethostbyaddr_r ((const char *) &in_addr
,
125 sizeof (struct in_addr
),
126 AF_INET
, &th
, tmpbuf
,
127 tmpbuflen
, &h
, &herror
))
129 if (herror
== NETDB_INTERNAL
&& errno
== ERANGE
)
130 tmpbuf
= extend_alloca (tmpbuf
, tmpbuflen
,
136 if (h
&& (c
= strchr (h
->h_name
, '.')))
137 domain
= __strdup (++c
);
143 __libc_lock_unlock (lock
);
151 getnameinfo (const struct sockaddr
*sa
, socklen_t addrlen
, char *host
,
152 socklen_t hostlen
, char *serv
, socklen_t servlen
,
156 int tmpbuflen
= 1024;
158 char *tmpbuf
= alloca (tmpbuflen
);
162 if (flags
& ~(NI_NUMERICHOST
|NI_NUMERICSERV
|NI_NOFQDN
|NI_NAMEREQD
|NI_DGRAM
))
165 if (sa
== NULL
|| addrlen
< sizeof (sa_family_t
))
168 switch (sa
->sa_family
)
171 if (addrlen
< (socklen_t
) (((struct sockaddr_un
*) NULL
)->sun_path
))
175 if (addrlen
< sizeof (struct sockaddr_in
))
179 if (addrlen
< sizeof (struct sockaddr_in6
))
186 if (host
!= NULL
&& hostlen
> 0)
187 switch (sa
->sa_family
)
191 if (!(flags
& NI_NUMERICHOST
))
193 struct hostent
*h
= NULL
;
196 if (sa
->sa_family
== AF_INET6
)
198 while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in6
*) sa
)->sin6_addr
),
199 sizeof(struct in6_addr
),
200 AF_INET6
, &th
, tmpbuf
, tmpbuflen
,
203 if (herrno
== NETDB_INTERNAL
)
206 tmpbuf
= extend_alloca (tmpbuf
, tmpbuflen
,
210 __set_h_errno (herrno
);
211 __set_errno (serrno
);
223 while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in
*)sa
)->sin_addr
),
224 sizeof(struct in_addr
), AF_INET
,
225 &th
, tmpbuf
, tmpbuflen
,
229 tmpbuf
= extend_alloca (tmpbuf
, tmpbuflen
,
242 if ((flags
& NI_NOFQDN
)
243 && (c
= nrl_domainname ())
244 && (c
= strstr (h
->h_name
, c
))
245 && (c
!= h
->h_name
) && (*(--c
) == '.'))
247 strncpy (host
, h
->h_name
,
248 min(hostlen
, (size_t) (c
- h
->h_name
)));
249 host
[min(hostlen
- 1, (size_t) (c
- h
->h_name
))]
255 strncpy (host
, h
->h_name
, hostlen
);
263 if (flags
& NI_NAMEREQD
)
265 __set_errno (serrno
);
271 if (sa
->sa_family
== AF_INET6
)
273 const struct sockaddr_in6
*sin6p
;
276 sin6p
= (const struct sockaddr_in6
*) sa
;
278 c
= inet_ntop (AF_INET6
,
279 (const void *) &sin6p
->sin6_addr
, host
, hostlen
);
280 scopeid
= sin6p
->sin6_scope_id
;
283 /* Buffer is >= IFNAMSIZ+1. */
284 char scopebuf
[IFNAMSIZ
+ 1];
286 int ni_numericscope
= 0;
287 size_t real_hostlen
= __strnlen (host
, hostlen
);
290 scopebuf
[0] = SCOPE_DELIMITER
;
292 scopeptr
= &scopebuf
[1];
294 if (IN6_IS_ADDR_LINKLOCAL (&sin6p
->sin6_addr
)
295 || IN6_IS_ADDR_MC_LINKLOCAL (&sin6p
->sin6_addr
))
297 if (if_indextoname (scopeid
, scopeptr
) == NULL
)
300 scopelen
= strlen (scopebuf
);
306 scopelen
= 1 + __snprintf (scopeptr
,
312 if (real_hostlen
+ scopelen
+ 1 > hostlen
)
313 /* XXX We should not fail here. Simply enlarge
314 the buffer or return with out of memory. */
316 memcpy (host
+ real_hostlen
, scopebuf
, scopelen
+ 1);
320 c
= inet_ntop (AF_INET
,
321 (const void *) &(((const struct sockaddr_in
*) sa
)->sin_addr
),
325 __set_errno (serrno
);
334 if (!(flags
& NI_NUMERICHOST
))
336 struct utsname utsname
;
338 if (!uname (&utsname
))
340 strncpy (host
, utsname
.nodename
, hostlen
);
345 if (flags
& NI_NAMEREQD
)
347 __set_errno (serrno
);
351 strncpy (host
, "localhost", hostlen
);
358 if (serv
&& (servlen
> 0))
359 switch (sa
->sa_family
)
363 if (!(flags
& NI_NUMERICSERV
))
365 struct servent
*s
, ts
;
366 while (__getservbyport_r (((const struct sockaddr_in
*) sa
)->sin_port
,
367 ((flags
& NI_DGRAM
) ? "udp" : "tcp"),
368 &ts
, tmpbuf
, tmpbuflen
, &s
))
370 if (herrno
== NETDB_INTERNAL
)
373 tmpbuf
= extend_alloca (tmpbuf
, tmpbuflen
,
377 __set_errno (serrno
);
388 strncpy (serv
, s
->s_name
, servlen
);
392 __snprintf (serv
, servlen
, "%d",
393 ntohs (((const struct sockaddr_in
*) sa
)->sin_port
));
397 strncpy (serv
, ((const struct sockaddr_un
*) sa
)->sun_path
, servlen
);
401 if (host
&& (hostlen
> 0))
403 if (serv
&& (servlen
> 0))
408 libc_hidden_def (getnameinfo
)