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
)
87 tmpbuf
= alloca (tmpbuflen
);
93 if (h
&& (c
= strchr (h
->h_name
, '.')))
94 domain
= __strdup (++c
);
97 /* The name contains no domain information. Use the name
98 now to get more information. */
99 while (__gethostname (tmpbuf
, tmpbuflen
))
102 tmpbuf
= alloca (tmpbuflen
);
105 if ((c
= strchr (tmpbuf
, '.')))
106 domain
= __strdup (++c
);
109 /* We need to preserve the hostname. */
110 const char *hstname
= strdupa (tmpbuf
);
112 while (__gethostbyname_r (hstname
, &th
, tmpbuf
, tmpbuflen
,
115 if (herror
== NETDB_INTERNAL
&& errno
== ERANGE
)
118 tmpbuf
= alloca (tmpbuflen
);
124 if (h
&& (c
= strchr(h
->h_name
, '.')))
125 domain
= __strdup (++c
);
128 struct in_addr in_addr
;
130 in_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
132 while (__gethostbyaddr_r ((const char *) &in_addr
,
133 sizeof (struct in_addr
),
134 AF_INET
, &th
, tmpbuf
,
135 tmpbuflen
, &h
, &herror
))
137 if (herror
== NETDB_INTERNAL
&& errno
== ERANGE
)
140 tmpbuf
= alloca (tmpbuflen
);
146 if (h
&& (c
= strchr (h
->h_name
, '.')))
147 domain
= __strdup (++c
);
153 __libc_lock_unlock (lock
);
161 getnameinfo (const struct sockaddr
*sa
, socklen_t addrlen
, char *host
,
162 socklen_t hostlen
, char *serv
, socklen_t servlen
,
166 int tmpbuflen
= 1024;
168 char *tmpbuf
= alloca (tmpbuflen
);
172 if (flags
& ~(NI_NUMERICHOST
|NI_NUMERICSERV
|NI_NOFQDN
|NI_NAMEREQD
|NI_DGRAM
))
175 if (sa
== NULL
|| addrlen
< sizeof (sa_family_t
))
178 switch (sa
->sa_family
)
181 if (addrlen
< (socklen_t
) (((struct sockaddr_un
*) NULL
)->sun_path
))
185 if (addrlen
< sizeof (struct sockaddr_in
))
189 if (addrlen
< sizeof (struct sockaddr_in6
))
196 if (host
!= NULL
&& hostlen
> 0)
197 switch (sa
->sa_family
)
201 if (!(flags
& NI_NUMERICHOST
))
203 struct hostent
*h
= NULL
;
206 if (sa
->sa_family
== AF_INET6
)
208 while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in6
*) sa
)->sin6_addr
),
209 sizeof(struct in6_addr
),
210 AF_INET6
, &th
, tmpbuf
, tmpbuflen
,
213 if (herrno
== NETDB_INTERNAL
)
218 tmpbuf
= alloca (tmpbuflen
);
222 __set_h_errno (herrno
);
223 __set_errno (serrno
);
235 while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in
*)sa
)->sin_addr
),
236 sizeof(struct in_addr
), AF_INET
,
237 &th
, tmpbuf
, tmpbuflen
,
243 tmpbuf
= alloca (tmpbuflen
);
256 if ((flags
& NI_NOFQDN
)
257 && (c
= nrl_domainname ())
258 && (c
= strstr (h
->h_name
, c
))
259 && (c
!= h
->h_name
) && (*(--c
) == '.'))
261 strncpy (host
, h
->h_name
,
262 min(hostlen
, (size_t) (c
- h
->h_name
)));
263 host
[min(hostlen
- 1, (size_t) (c
- h
->h_name
))]
269 strncpy (host
, h
->h_name
, hostlen
);
277 if (flags
& NI_NAMEREQD
)
279 __set_errno (serrno
);
285 if (sa
->sa_family
== AF_INET6
)
287 const struct sockaddr_in6
*sin6p
;
290 sin6p
= (const struct sockaddr_in6
*) sa
;
292 c
= inet_ntop (AF_INET6
,
293 (const void *) &sin6p
->sin6_addr
, host
, hostlen
);
294 scopeid
= sin6p
->sin6_scope_id
;
297 /* Buffer is >= IFNAMSIZ+1. */
298 char scopebuf
[IFNAMSIZ
+ 1];
300 int ni_numericscope
= 0;
301 size_t real_hostlen
= __strnlen (host
, hostlen
);
304 scopebuf
[0] = SCOPE_DELIMITER
;
306 scopeptr
= &scopebuf
[1];
308 if (IN6_IS_ADDR_LINKLOCAL (&sin6p
->sin6_addr
)
309 || IN6_IS_ADDR_MC_LINKLOCAL (&sin6p
->sin6_addr
))
311 if (if_indextoname (scopeid
, scopeptr
) == NULL
)
314 scopelen
= strlen (scopebuf
);
320 scopelen
= 1 + __snprintf (scopeptr
,
326 if (real_hostlen
+ scopelen
+ 1 > hostlen
)
327 /* XXX We should not fail here. Simply enlarge
328 the buffer or return with out of memory. */
330 memcpy (host
+ real_hostlen
, scopebuf
, scopelen
+ 1);
334 c
= inet_ntop (AF_INET
,
335 (const void *) &(((const struct sockaddr_in
*) sa
)->sin_addr
),
339 __set_errno (serrno
);
348 if (!(flags
& NI_NUMERICHOST
))
350 struct utsname utsname
;
352 if (!uname (&utsname
))
354 strncpy (host
, utsname
.nodename
, hostlen
);
359 if (flags
& NI_NAMEREQD
)
361 __set_errno (serrno
);
365 strncpy (host
, "localhost", hostlen
);
372 if (serv
&& (servlen
> 0))
373 switch (sa
->sa_family
)
377 if (!(flags
& NI_NUMERICSERV
))
379 struct servent
*s
, ts
;
380 while (__getservbyport_r (((const struct sockaddr_in
*) sa
)->sin_port
,
381 ((flags
& NI_DGRAM
) ? "udp" : "tcp"),
382 &ts
, tmpbuf
, tmpbuflen
, &s
))
384 if (herrno
== NETDB_INTERNAL
)
389 tmpbuf
= __alloca (tmpbuflen
);
393 __set_errno (serrno
);
404 strncpy (serv
, s
->s_name
, servlen
);
408 __snprintf (serv
, servlen
, "%d",
409 ntohs (((const struct sockaddr_in
*) sa
)->sin_port
));
413 strncpy (serv
, ((const struct sockaddr_un
*) sa
)->sun_path
, servlen
);
417 if (host
&& (hostlen
> 0))
419 if (serv
&& (servlen
> 0))
424 libc_hidden_def (getnameinfo
)