summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcmetz <>1999-06-23 21:55:29 +0000
committercmetz <>1999-06-23 21:55:29 +0000
commitbdf7624d67f3bba1a3faed9abf0d2d27291c1cce (patch)
tree5cb85a83aaa8913b4f148b657a99b1fb4982d71d
parent119cda95bf950cdcba7a16178e7f48fdf84f58d0 (diff)
downloadopenbsd-bdf7624d67f3bba1a3faed9abf0d2d27291c1cce.tar.gz
openbsd-bdf7624d67f3bba1a3faed9abf0d2d27291c1cce.tar.bz2
openbsd-bdf7624d67f3bba1a3faed9abf0d2d27291c1cce.zip
Added some protocol independent interfaces (supposedly IPv6 support APIs, but
ones that are useful for all protocols, not just IPv6).
-rw-r--r--src/lib/libc/net/Makefile.inc22
-rw-r--r--src/lib/libc/net/__siocgifconf.c131
-rw-r--r--src/lib/libc/net/freeaddrinfo.c45
-rw-r--r--src/lib/libc/net/gai_strerror.c116
-rw-r--r--src/lib/libc/net/getaddrinfo.c1127
-rw-r--r--src/lib/libc/net/getnameinfo.c562
-rw-r--r--src/lib/libc/net/if_indextoname.c181
-rw-r--r--src/lib/libc/net/if_indextoname.obin0 -> 16022 bytes
-rw-r--r--src/lib/libc/net/if_nameindex.c212
-rw-r--r--src/lib/libc/net/if_nameindex.obin0 -> 17733 bytes
-rw-r--r--src/lib/libc/net/if_nametoindex.c173
-rw-r--r--src/lib/libc/net/if_nametoindex.obin0 -> 15886 bytes
12 files changed, 2559 insertions, 10 deletions
diff --git a/src/lib/libc/net/Makefile.inc b/src/lib/libc/net/Makefile.inc
index 35a9632a94..b4b94ad763 100644
--- a/src/lib/libc/net/Makefile.inc
+++ b/src/lib/libc/net/Makefile.inc
@@ -1,19 +1,21 @@
1# $OpenBSD: Makefile.inc,v 1.17 1998/11/20 11:18:43 d Exp $ 1# $OpenBSD: Makefile.inc,v 1.18 1999/06/23 21:55:28 cmetz Exp $
2 2
3# net sources 3# net sources
4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/net ${LIBCSRCDIR}/net 4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/net ${LIBCSRCDIR}/net
5 5
6CFLAGS+=-DRESOLVSORT 6CFLAGS+=-DRESOLVSORT
7 7
8SRCS+= base64.c gethostnamadr.c getnetbyaddr.c getnetbyname.c getnetent.c \ 8SRCS+= __siocgifconf.c base64.c freeaddrinfo.c gai_strerror.c getaddrinfo.c \
9 getnetnamadr.c getproto.c getprotoent.c getprotoname.c getservbyname.c \ 9 gethostnamadr.c getnameinfo.c getnetbyaddr.c getnetbyname.c \
10 getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \ 10 getnetent.c getnetnamadr.c getproto.c getprotoent.c getprotoname.c \
11 inet_makeaddr.c inet_neta.c inet_netof.c inet_network.c \ 11 getservbyname.c getservbyport.c getservent.c herror.c \
12 inet_net_ntop.c inet_net_pton.c inet_ntoa.c inet_ntop.c \ 12 if_indextoname.c if_nameindex.c if_nametoindex.c inet_addr.c \
13 inet_pton.c ipx_addr.c ipx_ntoa.c \ 13 inet_lnaof.c inet_makeaddr.c inet_neta.c inet_netof.c inet_network.c \
14 iso_addr.c linkaddr.c ns_addr.c ns_ntoa.c nsap_addr.c rcmd.c recv.c \ 14 inet_net_ntop.c inet_net_pton.c inet_ntoa.c inet_ntop.c inet_pton.c \
15 res_comp.c res_data.c res_debug.c res_init.c res_mkquery.c res_query.c \ 15 ipx_addr.c ipx_ntoa.c iso_addr.c linkaddr.c ns_addr.c ns_ntoa.c \
16 res_random.c res_send.c send.c sethostent.c ethers.c rcmdsh.c 16 nsap_addr.c rcmd.c recv.c res_comp.c res_data.c res_debug.c \
17 res_init.c res_mkquery.c res_query.c res_random.c res_send.c send.c \
18 sethostent.c ethers.c rcmdsh.c
17 19
18# machine-dependent net sources 20# machine-dependent net sources
19# m-d Makefile.inc must include sources for: 21# m-d Makefile.inc must include sources for:
diff --git a/src/lib/libc/net/__siocgifconf.c b/src/lib/libc/net/__siocgifconf.c
new file mode 100644
index 0000000000..4dac955f56
--- /dev/null
+++ b/src/lib/libc/net/__siocgifconf.c
@@ -0,0 +1,131 @@
1/*
2 * %%% copyright-cmetz-98-bsd
3 * Copyright (c) 1998-1999, Craig Metz, All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Craig Metz and
16 * by other contributors.
17 * 4. Neither the name of the author nor the names of contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. All advertising materials mentioning features or use of this software
42 * must display the following acknowledgement:
43 * This product includes software developed by Craig Metz and
44 * by other contributors.
45 * 4. Neither the name of the author nor the names of contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 * 1. Redistributions of source code must retain the above copyright
65 * notice, this list of conditions and the following disclaimer.
66 * 2. Redistributions in binary form must reproduce the above copyright
67 * notice, this list of conditions and the following disclaimer in the
68 * documentation and/or other materials provided with the distribution.
69 * 3. All advertising materials mentioning features or use of this software
70 * must display the following acknowledgement:
71 * This product includes software developed by Craig Metz and
72 * by other contributors.
73 * 4. Neither the name of the author nor the names of contributors
74 * may be used to endorse or promote products derived from this software
75 * without specific prior written permission.
76 *
77 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
78 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
79 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
80 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
81 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
82 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
83 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
84 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
85 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
86 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
87 * SUCH DAMAGE.
88 */
89
90#include <sys/types.h>
91#include <stdlib.h>
92#include <sys/socket.h>
93#include <net/if.h>
94#include <sys/ioctl.h>
95#include <errno.h>
96
97int __siocgifconf(int fd, struct ifconf *ifconf)
98{
99 int i, j;
100
101 ifconf->ifc_len = 0;
102 ifconf->ifc_buf = 0;
103 if (!ioctl(fd, SIOCGIFCONF, (void *)ifconf) && ifconf->ifc_len) {
104 if (!(ifconf->ifc_buf = malloc(ifconf->ifc_len))) {
105 errno = ENOMEM;
106 return -1;
107 };
108 if (ioctl(fd, SIOCGIFCONF, (void *)ifconf)) {
109 free(ifconf->ifc_buf);
110 return -1;
111 };
112 return 0;
113 };
114
115 for (i = 5; i < 12; i++) {
116 if (!(ifconf->ifc_buf = malloc(ifconf->ifc_len = j = sizeof(struct ifconf) * (1 << i)))) {
117 errno = ENOMEM;
118 return -1;
119 };
120 if (ioctl(fd, SIOCGIFCONF, (void *)ifconf)) {
121 free(ifconf->ifc_buf);
122 return -1;
123 };
124 if ((ifconf->ifc_len > IFNAMSIZ + sizeof(struct sockaddr))
125 && (ifconf->ifc_len < j))
126 return 0;
127 free(ifconf->ifc_buf);
128 };
129 return -1;
130};
131
diff --git a/src/lib/libc/net/freeaddrinfo.c b/src/lib/libc/net/freeaddrinfo.c
new file mode 100644
index 0000000000..a327ffb391
--- /dev/null
+++ b/src/lib/libc/net/freeaddrinfo.c
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 1996, 1997, 1998, 1999, Craig Metz, All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement:
14 * This product includes software developed by Craig Metz and
15 * by other contributors.
16 * 4. Neither the name of the author nor the names of contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include <stdlib.h>
34#include <netdb.h>
35
36void freeaddrinfo(struct addrinfo *ai)
37{
38 struct addrinfo *p;
39
40 while(ai) {
41 p = ai;
42 ai = ai->ai_next;
43 free((void *)p);
44 }
45}
diff --git a/src/lib/libc/net/gai_strerror.c b/src/lib/libc/net/gai_strerror.c
new file mode 100644
index 0000000000..a758b7449b
--- /dev/null
+++ b/src/lib/libc/net/gai_strerror.c
@@ -0,0 +1,116 @@
1/*
2 * %%% copyright-cmetz-97-bsd
3 * Copyright (c) 1997-1999, Craig Metz, All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Craig Metz and
16 * by other contributors.
17 * 4. Neither the name of the author nor the names of contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. All advertising materials mentioning features or use of this software
42 * must display the following acknowledgement:
43 * This product includes software developed by Craig Metz and
44 * by other contributors.
45 * 4. Neither the name of the author nor the names of contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 */
61
62/* gai_strerror() v1.38 */
63
64#include <sys/types.h>
65#include <netdb.h>
66#include <errno.h>
67
68#define THREAD_SAFE 0
69
70#if !THREAD_SAFE
71static char buffer[256];
72#endif /* !THREAD_SAFE */
73
74char *gai_strerror(int errnum)
75{
76 switch(errnum) {
77 case 0:
78 return "no error";
79 case EAI_BADFLAGS:
80 return "invalid value for ai_flags";
81 case EAI_NONAME:
82 return "name or service is not known";
83 case EAI_AGAIN:
84 return "temporary failure in name resolution";
85 case EAI_FAIL:
86 return "non-recoverable failure in name resolution";
87 case EAI_NODATA:
88 return "no address associated with name";
89 case EAI_FAMILY:
90 return "ai_family not supported";
91 case EAI_SOCKTYPE:
92 return "ai_socktype not supported";
93 case EAI_SERVICE:
94 return "service not supported for ai_socktype";
95 case EAI_ADDRFAMILY:
96 return "address family for name not supported";
97 case EAI_MEMORY:
98 return "memory allocation failure";
99 case EAI_SYSTEM:
100#if THREAD_SAFE
101 return "system error";
102#else /* THREAD_SAFE */
103 snprintf(buffer, sizeof(buffer)-1, "system error: %s(%d)", strerror(errno), errno);
104 buffer[sizeof(buffer)-1] = 0;
105 return buffer;
106#endif /* THREAD_SAFE */
107 default:
108#if THREAD_SAFE
109 return "unknown/invalid error";
110#else /* THREAD_SAFE */
111 snprintf(buffer, sizeof(buffer)-1, "unknown/invalid error %d", errnum);
112 buffer[sizeof(buffer)-1] = 0;
113 return buffer;
114#endif /* THREAD_SAFE */
115 };
116};
diff --git a/src/lib/libc/net/getaddrinfo.c b/src/lib/libc/net/getaddrinfo.c
new file mode 100644
index 0000000000..a572dbcde0
--- /dev/null
+++ b/src/lib/libc/net/getaddrinfo.c
@@ -0,0 +1,1127 @@
1/*
2 * %%% copyright-cmetz-96-bsd
3 * Copyright (c) 1996-1999, Craig Metz, All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Craig Metz and
16 * by other contributors.
17 * 4. Neither the name of the author nor the names of contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. All advertising materials mentioning features or use of this software
42 * must display the following acknowledgement:
43 * This product includes software developed by Craig Metz and
44 * by other contributors.
45 * 4. Neither the name of the author nor the names of contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 *
61 */
62
63/* getaddrinfo() v1.38 */
64
65/*
66 I'd like to thank Matti Aarnio for finding some bugs in this code and
67 sending me patches, as well as everyone else who has contributed to this
68 code (by reporting bugs, suggesting improvements, and commented on its
69 behavior and proposed changes).
70*/
71
72/*
73 Someone merged an earlier version of this code into the GNU libc and
74 added support for getservbyname_r and gethostbyname2_r. The support for
75 those functions in this version of the code was written using that work
76 as a reference. I may have improved on it, or I may have broken it.
77*/
78
79/* To do what POSIX says, even when it's broken, define: */
80/* #define BROKEN_LIKE_POSIX 1 */
81/* Note: real apps will break if you define this, while nothing other than a
82 conformance test suite should have a problem with it undefined. */
83
84/* If your C runtime library provides the POSIX p1003.1g D6.6 bit types
85 of the form u?int(16|32)_t, define: */
86/* #define HAVE_POSIX1G_TYPES 1 */
87/* Note: this implementation tries to guess what the correct values are for
88 your compiler+processor combination but might not always get it right. */
89
90/* To enable debugging support (REQUIRES NRL support library), define: */
91/* #define DEBUG 1 */
92
93#if FOR_GNULIBC
94#define HAVE_POSIX1G_TYPES 1
95#define INET6 1
96#define LOCAL 1
97#define NETDB 1
98#undef RESOLVER
99#undef HOSTTABLE
100#undef DEBUG
101#define HAVE_GETSERVBYNAME_R 1
102#define HAVE_GETHOSTBYNAME2_R 1
103#define getservbyname_r __getservbyname_r
104#define gethostbyname2_r __gethostbyname2_r
105#endif /* FOR_GNULIBC */
106
107#ifdef __OpenBSD__
108#define HAVE_POSIX1G_TYPES 1
109#define INET6 1
110#define LOCAL 1
111#define NETDB 1
112#define SALEN 1
113#undef RESOLVER
114#undef HOSTTABLE
115#undef DEBUG
116#undef HAVE_GETSERVBYNAME_R
117#undef HAVE_GETHOSTBYNAME2_R
118#endif /* __OpenBSD__ */
119
120#include <sys/types.h>
121#include <stdlib.h>
122#include <unistd.h>
123#include <sys/socket.h>
124#include <string.h>
125#if LOCAL
126#include <stdio.h>
127#include <sys/utsname.h>
128#include <sys/un.h>
129#endif /* LOCAL */
130#include <netinet/in.h>
131#include <netdb.h>
132#include <errno.h>
133#if RESOLVER
134#include <arpa/nameser.h>
135#include <resolv.h>
136#endif /* RESOLVER */
137#if DEBUG
138#include <syslog.h>
139#endif /* DEBUG */
140
141#ifndef AF_LOCAL
142#define AF_LOCAL AF_UNIX
143#endif /* AF_LOCAL */
144#ifndef PF_LOCAL
145#define PF_LOCAL PF_UNIX
146#endif /* PF_LOCAL */
147#ifndef UNIX_PATH_MAX
148#define UNIX_PATH_MAX 108
149#endif /* UNIX_PATH_MAX */
150
151#if !HAVE_POSIX1G_TYPES
152#if (~0UL) == 0xffffffff
153#define uint8_t unsigned char
154#define int16_t short
155#define uint16_t unsigned short
156#define int32_t long
157#define uint32_t unsigned long
158#else /* (~0UL) == 0xffffffff */
159#if (~0UL) == 0xffffffffffffffff
160#define uint8_t unsigned char
161#define int16_t short
162#define uint16_t unsigned short
163#define int32_t int
164#define uint32_t unsigned int
165#else /* (~0UL) == 0xffffffffffffffff */
166#error Neither 32 bit nor 64 bit word size detected.
167#error You need to define the bit types manually.
168#endif /* (~0UL) == 0xffffffffffffffff */
169#endif /* (~0UL) == 0xffffffff */
170#endif /* !HAVE_POSIX1G_TYPES */
171
172#if defined(INET6) && !defined(AF_INET6)
173#error Without a definition of AF_INET6, this system cannot support IPv6
174#error addresses.
175#endif /* defined(INET6) && !defined(AF_INET6) */
176
177#if INET6
178#ifndef T_AAAA
179#define T_AAAA 28
180#endif /* T_AAAA */
181#endif /* INET6 */
182
183#if DEBUG
184#if RESOLVER
185#define DEBUG_MESSAGES (_res.options & RES_DEBUG)
186#else /* RESOLVER */
187int __getaddrinfo_debug = 0;
188#define DEBUG_MESSAGES (__getaddrinfo_debug)
189#endif /* RESOLVER */
190#endif /* DEBUG */
191
192#define GAIH_OKIFUNSPEC 0x0100
193#define GAIH_EAI ~(GAIH_OKIFUNSPEC)
194
195static struct addrinfo nullreq =
196{ 0, PF_UNSPEC, 0, 0, 0, NULL, NULL, NULL };
197
198struct gaih_service {
199 char *name;
200 int num;
201};
202
203struct gaih_servtuple {
204 struct gaih_servtuple *next;
205 int socktype;
206 int protocol;
207 int port;
208};
209
210static struct gaih_servtuple nullserv = {
211 NULL, 0, 0, 0
212};
213
214struct gaih_addrtuple {
215 struct gaih_addrtuple *next;
216 int family;
217 char addr[16];
218 char *cname;
219};
220
221struct gaih_typeproto {
222 int socktype;
223 int protocol;
224 char *name;
225};
226
227#if DEBUG
228#define RETURN_ERROR(x) do { \
229 if (DEBUG_MESSAGES) \
230 fprintf(stderr, "%s:%d: returning %s\n", __FILE__, __LINE__, #x); \
231 rval = (x); \
232 goto ret; \
233 } while(0)
234#else /* DEBUG */
235#define RETURN_ERROR(x) do { \
236 rval = (x); \
237 goto ret; \
238 } while(0)
239#endif /* DEBUG */
240
241#if HOSTTABLE
242static int hosttable_lookup_addr(const char *name, const struct addrinfo *req, struct gaih_addrtuple **pat)
243{
244 FILE *f;
245 char buffer[1024];
246 char *c, *c2;
247 int rval = 1;
248 char *prevcname = NULL;
249 struct gaih_addrtuple at;
250
251 if (!(f = fopen("/etc/hosts", "r")))
252 RETURN_ERROR(-EAI_SYSTEM);
253
254 while(fgets(buffer, sizeof(buffer), f)) {
255 if (c = strchr(buffer, '#'))
256 *c = 0;
257
258 c = buffer;
259 while(*c && !isspace(*c)) c++;
260 if (!*c)
261 continue;
262
263 *(c++) = 0;
264
265 while(*c && isspace(*c)) c++;
266 if (!*c)
267 continue;
268
269 if (!(c2 = strstr(c, name)))
270 continue;
271
272 if (*(c2 - 1) && !isspace(*(c2 - 1)))
273 continue;
274
275 c2 += strlen(name);
276 if (*c2 && !isspace(*c2))
277 continue;
278
279 c2 = c;
280 while(*c2 && !isspace(*c2)) c2++;
281 if (!*c2)
282 continue;
283 *c2 = 0;
284
285 memset(&at, 0, sizeof(struct gaih_addrtuple));
286
287 if (!req->ai_family || (req->ai_family == AF_INET))
288 if (inet_pton(AF_INET, buffer, (char *)&at.addr) > 0) {
289 at.family = AF_INET;
290 goto build;
291 };
292
293#if INET6
294 if (!req->ai_family || (req->ai_family == AF_INET6))
295 if (inet_pton(AF_INET6, buffer, (char *)&at.addr) > 0) {
296 at.family = AF_INET6;
297 goto build;
298 };
299#endif /* INET6 */
300
301 continue;
302
303build:
304 if (!(*pat = malloc(sizeof(struct gaih_addrtuple))))
305 RETURN_ERROR(-EAI_MEMORY);
306
307 memcpy(*pat, &at, sizeof(struct gaih_addrtuple));
308
309 if (req->ai_flags & AI_CANONNAME)
310 if (prevcname && !strcmp(prevcname, c))
311 (*pat)->cname = prevcname;
312 else
313 prevcname = (*pat)->cname = strdup(c);
314
315 pat = &((*pat)->next);
316
317 rval = 0;
318 };
319
320ret:
321 if (f)
322 fclose(f);
323 return rval;
324};
325#endif /* HOSTTABLE */
326
327#if NETDB
328int netdb_lookup_addr(const char *name, int af, const struct addrinfo *req, struct gaih_addrtuple **pat)
329{
330 int rval, herrno, i;
331 char *prevcname = NULL;
332 struct hostent *h;
333
334#if HAVE_GETHOSTBYNAME2_R
335 void *buf;
336 int buflen = 1024;
337 struct hostent th;
338 int herrno, j;
339
340 do {
341 if (!(buf = malloc(buflen)))
342 RETURN_ERROR(-EAI_MEMORY);
343
344 if (!gethostbyname2_r(name, af, &th, buf, buflen, &h, &herrno))
345 break;
346
347 free(buf);
348 buf = NULL;
349
350 if ((herrno == NETDB_INTERNAL) && (errno == ERANGE)) {
351 if (buflen >= 65536)
352 RETURN_ERROR(-EAI_MEMORY);
353
354 buflen = buflen << 1;
355 continue;
356 };
357 } while(0);
358#else /* HAVE_GETHOSTBYNAME2_R */
359 h = gethostbyname2(name, af);
360 herrno = h_errno;
361#endif /* HAVE_GETHOSTBYNAME2_R */
362
363 if (!h) {
364#if DEBUG
365 if (DEBUG_MESSAGES)
366 fprintf(stderr, "getaddrinfo: gethostbyname2 failed, h_errno=%d\n", herrno);
367#endif /* DEBUG */
368 switch(herrno) {
369 case NETDB_INTERNAL:
370 RETURN_ERROR(-EAI_SYSTEM);
371 case HOST_NOT_FOUND:
372 RETURN_ERROR(1);
373 case TRY_AGAIN:
374 RETURN_ERROR(-EAI_AGAIN);
375 case NO_RECOVERY:
376 RETURN_ERROR(-EAI_FAIL);
377 case NO_DATA:
378 RETURN_ERROR(1);
379 default:
380 RETURN_ERROR(-EAI_FAIL);
381 };
382 };
383
384 for (i = 0; h->h_addr_list[i]; i++) {
385 while(*pat)
386 pat = &((*pat)->next);
387
388 if (!(*pat = malloc(sizeof(struct gaih_addrtuple))))
389 RETURN_ERROR(-EAI_MEMORY);
390
391 memset(*pat, 0, sizeof(struct gaih_addrtuple));
392
393 switch((*pat)->family = af) {
394 case AF_INET:
395 memcpy((*pat)->addr, h->h_addr_list[i], sizeof(struct in_addr));
396 break;
397#if INET6
398 case AF_INET6:
399 memcpy((*pat)->addr, h->h_addr_list[i], sizeof(struct in6_addr));
400 break;
401#endif /* INET6 */
402 default:
403 RETURN_ERROR(-EAI_FAIL);
404 };
405
406 if (req->ai_flags & AI_CANONNAME) {
407 if (prevcname && !strcmp(prevcname, h->h_name))
408 (*pat)->cname = prevcname;
409 else
410 prevcname = (*pat)->cname = strdup(h->h_name);
411 };
412
413 pat = &((*pat)->next);
414 }
415
416 rval = 0;
417
418ret:
419#if HAVE_GETHOSTBYNAME2_R
420 free(buf);
421#endif /* HAVE_GETHOSTBYNAME2_R */
422 return rval;
423};
424#endif /* NETDB */
425
426#if RESOLVER
427#define RRHEADER_SZ 10
428
429int resolver_lookup_addr(const char *name, int type, const struct addrinfo *req, struct gaih_addrtuple **pat)
430{
431 int rval;
432 char answer[PACKETSZ];
433 int answerlen;
434 char dn[MAXDNAME];
435 char *prevcname = NULL;
436 void *p, *ep;
437 int answers, i, j;
438 uint16_t rtype, rclass;
439
440 if ((answerlen = res_search(name, C_IN, type, answer, sizeof(answer))) < 0) {
441#if DEBUG
442 if (DEBUG_MESSAGES)
443 fprintf(stderr, "getaddrinfo: res_search failed, h_errno=%d\n", h_errno);
444#endif /* DEBUG */
445 switch(h_errno) {
446 case NETDB_INTERNAL:
447 RETURN_ERROR(-EAI_SYSTEM);
448 case HOST_NOT_FOUND:
449 RETURN_ERROR(1);
450 case TRY_AGAIN:
451 RETURN_ERROR(-EAI_AGAIN);
452 case NO_RECOVERY:
453 RETURN_ERROR(-EAI_FAIL);
454 case NO_DATA:
455 RETURN_ERROR(1);
456 default:
457 RETURN_ERROR(-EAI_FAIL);
458 };
459 };
460
461 p = answer;
462 ep = answer + answerlen;
463
464 if (answerlen < RRHEADER_SZ)
465 RETURN_ERROR(-EAI_FAIL);
466
467 {
468 HEADER *h = (HEADER *)p;
469 if (!h->qr || (h->opcode != QUERY) || (h->qdcount != htons(1)) ||
470 !h->ancount)
471 RETURN_ERROR(-EAI_FAIL);
472 answers = ntohs(h->ancount);
473 };
474 p += sizeof(HEADER);
475
476 if ((i = dn_expand(answer, ep, p, dn, sizeof(dn))) < 0)
477 RETURN_ERROR(-EAI_FAIL);
478 p += i;
479
480 if (p + 2*sizeof(uint16_t) >= ep)
481 RETURN_ERROR(-EAI_FAIL);
482
483 GETSHORT(rtype, p);
484 GETSHORT(rclass, p);
485
486 if ((rtype != type) || (rclass != C_IN))
487 RETURN_ERROR(-EAI_FAIL);
488
489 while(answers--) {
490 if ((i = dn_expand(answer, ep, p, dn, sizeof(dn))) < 0)
491 RETURN_ERROR(-EAI_FAIL);
492 p += i;
493
494 if (p + RRHEADER_SZ >= ep)
495 RETURN_ERROR(-EAI_FAIL);
496
497 GETSHORT(rtype, p);
498 GETSHORT(rclass, p);
499 p += sizeof(uint32_t);
500 if (rclass != C_IN)
501 RETURN_ERROR(-EAI_FAIL);
502 GETSHORT(rclass, p);
503 i = rclass;
504
505 if (p + i > ep)
506 RETURN_ERROR(-EAI_FAIL);
507
508 if (rtype == type) {
509 while(*pat)
510 pat = &((*pat)->next);
511
512 if (!(*pat = malloc(sizeof(struct gaih_addrtuple))))
513 RETURN_ERROR(-EAI_MEMORY);
514
515 memset(*pat, 0, sizeof(struct gaih_addrtuple));
516
517 switch(type) {
518 case T_A:
519 if (i != sizeof(struct in_addr))
520 RETURN_ERROR(-EAI_FAIL);
521 (*pat)->family = AF_INET;
522 break;
523#if INET6
524 case T_AAAA:
525 if (i != sizeof(struct in6_addr))
526 RETURN_ERROR(-EAI_FAIL);
527 (*pat)->family = AF_INET6;
528 break;
529#endif /* INET6 */
530 default:
531 RETURN_ERROR(-EAI_FAIL);
532 };
533
534 memcpy((*pat)->addr, p, i);
535
536 if (req->ai_flags & AI_CANONNAME)
537 if (prevcname && !strcmp(prevcname, dn))
538 (*pat)->cname = prevcname;
539 else
540 prevcname = (*pat)->cname = strdup(dn);
541 };
542 p += i;
543 };
544
545 rval = 0;
546
547ret:
548 return rval;
549};
550#endif /* RESOLVER */
551
552#if LOCAL
553static int gaih_local(const char *name, const struct gaih_service *service,
554 const struct addrinfo *req, struct addrinfo **pai)
555{
556 int rval;
557 struct utsname utsname;
558
559 if (name || (req->ai_flags & AI_CANONNAME))
560 if (uname(&utsname) < 0)
561 RETURN_ERROR(-EAI_SYSTEM);
562 if (name) {
563 if (strcmp(name, "localhost") && strcmp(name, "local") && strcmp(name, "unix") && strcmp(name, utsname.nodename))
564 RETURN_ERROR(GAIH_OKIFUNSPEC | -EAI_NONAME);
565 };
566
567 if (!(*pai = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_un) + ((req->ai_flags & AI_CANONNAME) ? (strlen(utsname.nodename) + 1): 0))))
568 RETURN_ERROR(-EAI_MEMORY);
569
570 (*pai)->ai_next = NULL;
571 (*pai)->ai_flags = req->ai_flags;
572 (*pai)->ai_family = AF_LOCAL;
573 (*pai)->ai_socktype = req->ai_socktype ? req->ai_socktype : SOCK_STREAM;
574 (*pai)->ai_protocol = req->ai_protocol;
575 (*pai)->ai_addrlen = sizeof(struct sockaddr_un);
576 (*pai)->ai_addr = (void *)(*pai) + sizeof(struct addrinfo);
577#if SALEN
578 ((struct sockaddr_un *)(*pai)->ai_addr)->sun_len = sizeof(struct sockaddr_un);
579#endif /* SALEN */
580 ((struct sockaddr_un *)(*pai)->ai_addr)->sun_family = AF_LOCAL;
581 memset(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path, 0, UNIX_PATH_MAX);
582 if (service) {
583 char *c;
584 if (c = strchr(service->name, '/')) {
585 if (strlen(service->name) >= sizeof(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path))
586 RETURN_ERROR(GAIH_OKIFUNSPEC | -EAI_SERVICE);
587 strcpy(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path, service->name);
588 } else {
589 if (strlen(P_tmpdir "/") + 1 + strlen(service->name) >= sizeof(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path))
590 RETURN_ERROR(GAIH_OKIFUNSPEC | -EAI_SERVICE);
591 strcpy(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path, P_tmpdir "/");
592 strcat(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path, service->name);
593 };
594 } else {
595 char *c;
596 if (!(c = tmpnam(NULL)))
597 RETURN_ERROR(GAIH_OKIFUNSPEC | -EAI_SYSTEM);
598
599 strncpy((((struct sockaddr_un *)(*pai)->ai_addr)->sun_path), c, sizeof(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path) - 1);
600 c[sizeof(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path) - 1] = 0;
601 };
602 if (req->ai_flags & AI_CANONNAME) {
603 strncpy((*pai)->ai_canonname = (char *)(*pai) + sizeof(struct addrinfo) + sizeof(struct sockaddr_un), utsname.nodename, sizeof(utsname.nodename) - 1);
604 (*pai)->ai_canonname[sizeof(utsname.nodename) - 1] = 0;
605 } else
606 (*pai)->ai_canonname = NULL;
607
608 rval = 0;
609
610ret:
611 return rval;
612};
613#endif /* LOCAL */
614
615static struct gaih_typeproto gaih_inet_typeproto[] = {
616 { 0, 0, NULL },
617 { SOCK_STREAM, IPPROTO_TCP, "tcp" },
618 { SOCK_DGRAM, IPPROTO_UDP, "udp" },
619 { 0, 0, NULL }
620};
621
622static int gaih_inet_serv(char *servicename, struct gaih_typeproto *tp, struct gaih_servtuple **st)
623{
624 int rval;
625 struct servent *s;
626#if HAVE_GETSERVBYNAME_R
627 int i;
628 void *buf;
629 int buflen = 1024;
630 struct servent ts;
631
632 do {
633 if (!(buf = malloc(buflen)))
634 RETURN_ERROR(-EAI_MEMORY);
635
636 if (!getservbyname_r(servicename, tp->name, &ts, buf, buflen, &s))
637 break;
638
639 free(buf);
640 buf = NULL;
641
642 if (errno != ERANGE)
643 RETURN_ERROR(GAIH_OKIFUNSPEC | -EAI_SERVICE);
644
645 if (buflen >= 65536)
646 RETURN_ERROR(-EAI_MEMORY);
647
648 buflen = buflen << 1;
649 } while(1);
650#else /* HAVE_GETSERVBYNAME_R */
651 if (!(s = getservbyname(servicename, tp->name)))
652 RETURN_ERROR(GAIH_OKIFUNSPEC | -EAI_SERVICE);
653#endif /* HAVE_GETSERVBYNAME_R */
654
655 if (!(*st = malloc(sizeof(struct gaih_servtuple))))
656 RETURN_ERROR(-EAI_MEMORY);
657
658 (*st)->next = NULL;
659 (*st)->socktype = tp->socktype;
660 (*st)->protocol = tp->protocol;
661 (*st)->port = s->s_port;
662
663 rval = 0;
664
665ret:
666#if HAVE_GETSERVBYNAME_R
667 if (buf)
668 free(buf);
669#endif /* HAVE_GETSERVBYNAME_R */
670 return rval;
671}
672
673static int gaih_inet(const char *name, const struct gaih_service *service,
674 const struct addrinfo *req, struct addrinfo **pai)
675{
676 int rval;
677 struct hostent *h = NULL;
678 struct gaih_typeproto *tp = gaih_inet_typeproto;
679 struct gaih_servtuple *st = &nullserv;
680 struct gaih_addrtuple *at = NULL;
681 int i;
682
683 if (req->ai_protocol || req->ai_socktype) {
684 for (tp++; tp->name &&
685 ((req->ai_socktype != tp->socktype) || !req->ai_socktype) &&
686 ((req->ai_protocol != tp->protocol) || !req->ai_protocol); tp++);
687 if (!tp->name)
688 if (req->ai_socktype)
689 RETURN_ERROR(GAIH_OKIFUNSPEC | -EAI_SOCKTYPE);
690 else
691 RETURN_ERROR(GAIH_OKIFUNSPEC | -EAI_SERVICE);
692 }
693
694 if (service && (service->num < 0)) {
695 if (tp->name) {
696 if (rval = gaih_inet_serv(service->name, tp, &st))
697 goto ret;
698 } else {
699 struct gaih_servtuple **pst = &st;
700 for (tp++; tp->name; tp++) {
701 if (rval = gaih_inet_serv(service->name, tp, pst)) {
702 if (rval & GAIH_OKIFUNSPEC)
703 continue;
704 goto ret;
705 };
706 pst = &((*pst)->next);
707 };
708 if (st == &nullserv)
709 RETURN_ERROR(GAIH_OKIFUNSPEC | -EAI_SERVICE);
710 };
711 } else {
712 if (!(st = malloc(sizeof(struct gaih_servtuple))))
713 RETURN_ERROR(-EAI_MEMORY);
714
715 st->next = NULL;
716 st->socktype = tp->socktype;
717 st->protocol = tp->protocol;
718 if (service)
719 st->port = htons(service->num);
720 else
721 st->port = 0;
722 };
723
724 if (!name) {
725 if (!(at = malloc(sizeof(struct gaih_addrtuple))))
726 RETURN_ERROR(-EAI_MEMORY);
727
728 memset(at, 0, sizeof(struct gaih_addrtuple));
729
730#if INET6
731 if (req->ai_family)
732 at->family = req->ai_family;
733 else {
734 if (!(at->next = malloc(sizeof(struct gaih_addrtuple))))
735 RETURN_ERROR(-EAI_MEMORY);
736
737 at->family = AF_INET6;
738
739 memset(at->next, 0, sizeof(struct gaih_addrtuple));
740 at->next->family = AF_INET;
741 };
742#else /* INET6 */
743 at->family = AF_INET;
744#endif /* INET6 */
745
746 goto build;
747 };
748
749 if (!req->ai_family || (req->ai_family == AF_INET)) {
750 struct in_addr in_addr;
751 if (inet_pton(AF_INET, name, &in_addr) > 0) {
752 if (!(at = malloc(sizeof(struct gaih_addrtuple))))
753 RETURN_ERROR(-EAI_MEMORY);
754
755 memset(at, 0, sizeof(struct gaih_addrtuple));
756
757 at->family = AF_INET;
758 memcpy(at->addr, &in_addr, sizeof(struct in_addr));
759 goto build;
760 };
761 };
762
763#if INET6
764 if (!req->ai_family || (req->ai_family == AF_INET6)) {
765 struct in6_addr in6_addr;
766 if (inet_pton(AF_INET6, name, &in6_addr) > 0) {
767 if (!(at = malloc(sizeof(struct gaih_addrtuple))))
768 RETURN_ERROR(-EAI_MEMORY);
769
770 memset(at, 0, sizeof(struct gaih_addrtuple));
771
772 at->family = AF_INET6;
773 memcpy(at->addr, &in6_addr, sizeof(struct in6_addr));
774 goto build;
775 };
776 };
777#endif /* INET6 */
778
779 if (!(req->ai_flags & AI_NUMERICHOST)) {
780#if NETDB
781#if INET6
782 if (!req->ai_family || (req->ai_family == AF_INET6))
783 if ((rval = netdb_lookup_addr(name, AF_INET6, req, &at)) < 0)
784 goto ret;
785#endif /* INET6 */
786 if (!req->ai_family || (req->ai_family == AF_INET))
787 if ((rval = netdb_lookup_addr(name, AF_INET, req, &at)) < 0)
788 goto ret;
789
790 if (!rval)
791 goto build;
792#else /* NETDB */
793#if HOSTTABLE
794 if ((rval = hosttable_lookup_addr(name, req, &at)) < 0)
795 goto ret;
796
797 if (!rval)
798 goto build;
799#endif /* HOSTTABLE */
800
801#if RESOLVER
802#if INET6
803 {
804 int rval2;
805
806 if (!req->ai_family || (req->ai_family == AF_INET6))
807 if ((rval2 = resolver_lookup_addr(name, T_AAAA, req, &at)) < 0) {
808 rval = rval2;
809 goto ret;
810 };
811#endif /* INET6 */
812
813 if (!req->ai_family || (req->ai_family == AF_INET))
814 if ((rval = resolver_lookup_addr(name, T_A, req, &at)) < 0)
815 goto ret;
816
817#if INET6
818 if (!rval || !rval2)
819 goto build;
820 };
821#else /* INET6 */
822 if (!rval)
823 goto build;
824#endif /* INET6 */
825#endif /* RESOLVER */
826#endif /* NETDB */
827 };
828
829 if (!at)
830 RETURN_ERROR(GAIH_OKIFUNSPEC | -EAI_NONAME);
831
832build:
833 {
834 char *prevcname = NULL;
835 struct gaih_servtuple *st2;
836 struct gaih_addrtuple *at2 = at;
837 int j;
838
839 while(at2) {
840 if (req->ai_flags & AI_CANONNAME) {
841 if (at2->cname)
842 j = strlen(at2->cname) + 1;
843 else
844 if (name)
845 j = strlen(name) + 1;
846 else
847 j = 2;
848 } else
849 j = 0;
850
851#if INET6
852 if (at2->family == AF_INET6)
853 i = sizeof(struct sockaddr_in6);
854 else
855#endif /* INET6 */
856 i = sizeof(struct sockaddr_in);
857
858 st2 = st;
859 while(st2) {
860 if (!(*pai = malloc(sizeof(struct addrinfo) + i + j)))
861 RETURN_ERROR(-EAI_MEMORY);
862
863 memset(*pai, 0, sizeof(struct addrinfo) + i + j);
864
865 (*pai)->ai_flags = req->ai_flags;
866 (*pai)->ai_family = at2->family;
867 (*pai)->ai_socktype = st2->socktype;
868 (*pai)->ai_protocol = st2->protocol;
869 (*pai)->ai_addrlen = i;
870 (*pai)->ai_addr = (void *)(*pai) + sizeof(struct addrinfo);
871#if SALEN
872 ((struct sockaddr_in *)(*pai)->ai_addr)->sin_len = i;
873#endif /* SALEN */
874 ((struct sockaddr_in *)(*pai)->ai_addr)->sin_family = at2->family;
875 ((struct sockaddr_in *)(*pai)->ai_addr)->sin_port = st2->port;
876
877#if INET6
878 if (at2->family == AF_INET6)
879 memcpy(&((struct sockaddr_in6 *)(*pai)->ai_addr)->sin6_addr, at2->addr, sizeof(struct in6_addr));
880 else
881#endif /* INET6 */
882 memcpy(&((struct sockaddr_in *)(*pai)->ai_addr)->sin_addr, at2->addr, sizeof(struct in_addr));
883
884 if (j) {
885 (*pai)->ai_canonname = (void *)(*pai) + sizeof(struct addrinfo) + i;
886 if (at2->cname) {
887 strcpy((*pai)->ai_canonname, at2->cname);
888 if (prevcname != at2->cname) {
889 if (prevcname)
890 free(prevcname);
891 prevcname = at2->cname;
892 };
893 } else
894 strcpy((*pai)->ai_canonname, name ? name : "*");
895 };
896
897 pai = &((*pai)->ai_next);
898
899 st2 = st2->next;
900 };
901 at2 = at2->next;
902 };
903 };
904
905 rval = 0;
906
907ret:
908 if (st != &nullserv) {
909 struct gaih_servtuple *st2 = st;
910 while(st) {
911 st2 = st->next;
912 free(st);
913 st = st2;
914 }
915 }
916 if (at) {
917 struct gaih_addrtuple *at2 = at;
918 while(at) {
919 at2 = at->next;
920 free(at);
921 at = at2;
922 }
923 }
924
925 return rval;
926}
927
928struct gaih {
929 int family;
930 char *name;
931 int (*gaih)(const char *name, const struct gaih_service *service,
932 const struct addrinfo *req, struct addrinfo **pai);
933};
934
935static struct gaih gaih[] = {
936#if INET6
937 { PF_INET6, "inet6", gaih_inet },
938#endif /* INET6 */
939 { PF_INET, "inet", gaih_inet },
940#if LOCAL
941 { PF_LOCAL, "local", gaih_local },
942#endif /* LOCAL */
943 { -1, NULL, NULL }
944};
945
946#if DEBUG
947static void dump_addrinfo(const struct addrinfo *ai, int follownext)
948{
949 char *c;
950
951loop:
952 fprintf(stderr, "addrinfo at ");
953 if (!ai) {
954 fprintf(stderr, "NULL\n");
955 return;
956 };
957 fprintf(stderr, "%08x:\n", (unsigned int)ai);
958 fprintf(stderr, " flags=%x(", ai->ai_flags);
959 c = "";
960 if (ai->ai_flags & AI_PASSIVE) {
961 fprintf(stderr, "passive");
962 c = " ";
963 };
964 if (ai->ai_flags & AI_CANONNAME) {
965 fprintf(stderr, "%scanonname", c);
966 c = " ";
967 };
968 if (ai->ai_flags & AI_NUMERICHOST) {
969 fprintf(stderr, "%snumerichost", c);
970 c = " ";
971 };
972 if (ai->ai_flags & AI_EXT) {
973 fprintf(stderr, "%sext", c);
974 };
975 fprintf(stderr, ")\n");
976 fprintf(stderr, " family=%x(%s)\n", ai->ai_family, nrl_afnumtoname(ai->ai_family));
977 fprintf(stderr, " socktype=%x(%s)\n", ai->ai_socktype, nrl_socktypenumtoname(ai->ai_socktype));
978 fprintf(stderr, " protocol=%x\n", ai->ai_protocol);
979 fprintf(stderr, " addrlen=%x\n", ai->ai_addrlen);
980 fprintf(stderr, " addr=%08x", (unsigned int)ai->ai_addr);
981 if (ai->ai_addr) {
982 fprintf(stderr, ":\n");
983#if SALEN
984 fprintf(stderr, " len=%x\n", ai->ai_addr->sa_len);
985#endif /* SALEN */
986 fprintf(stderr, " family=%x(%s)\n", ai->ai_addr->sa_family, nrl_afnumtoname(ai->ai_addr->sa_family));
987 fprintf(stderr, " data=");
988
989#if SALEN
990 if (ai->ai_addrlen != ai->ai_addr->sa_len) {
991 fprintf(stderr, " (addrlen != len, skipping)");
992 } else
993#endif /* SALEN */
994 {
995 uint8_t *p;
996 int i;
997
998 p = (uint8_t *)ai->ai_addr->sa_data;
999 i = ai->ai_addrlen - ((void *)ai->ai_addr->sa_data - (void *)ai->ai_addr);
1000 while (i-- > 0)
1001 fprintf(stderr, "%02x", *(p++));
1002 };
1003 };
1004 fprintf(stderr, "\n canonname=%08x", (unsigned int)ai->ai_canonname);
1005 if (ai->ai_canonname)
1006 fprintf(stderr, "(%s)", ai->ai_canonname);
1007 fprintf(stderr, "\n next=%08x\n", (unsigned int)ai->ai_next);
1008
1009 if (follownext && ai->ai_next) {
1010 ai = ai->ai_next;
1011 goto loop;
1012 };
1013};
1014#endif /* DEBUG */
1015
1016int getaddrinfo(const char *name, const char *service,
1017 const struct addrinfo *req, struct addrinfo **pai)
1018{
1019 int rval = EAI_SYSTEM; /* XXX */
1020 int i, j = 0;
1021 struct addrinfo *p = NULL, **end;
1022 struct gaih *g = gaih, *pg = NULL;
1023 struct gaih_service gaih_service, *pservice;
1024
1025#if DEBUG
1026 if (DEBUG_MESSAGES) {
1027 fprintf(stderr, "getaddrinfo(name=%s, service=%s, req=%p, pai=%p)\n req: ", name ? name : "NULL", service ? service : "NULL", req, pai);
1028
1029 dump_addrinfo(req, 0);
1030 };
1031#endif /* DEBUG */
1032
1033 if (name && (name[0] == '*') && !name[1])
1034 name = NULL;
1035
1036 if (service && (service[0] == '*') && !service[1])
1037 service = NULL;
1038
1039#if BROKEN_LIKE_POSIX
1040 if (!name && !service && !(req.ai_flags & AI_EXT))
1041 RETURN_ERROR(EAI_NONAME);
1042#endif /* BROKEN_LIKE_POSIX */
1043
1044 if (!req)
1045 req = &nullreq;
1046
1047 if (req->ai_flags & ~(AI_CANONNAME | AI_PASSIVE | AI_NUMERICHOST | AI_EXT))
1048 RETURN_ERROR(EAI_BADFLAGS);
1049
1050#if BROKEN_LIKE_POSIX
1051 if ((req->ai_flags & AI_CANONNAME) && !name && !(req.ai_flags & AI_EXT))
1052 RETURN_ERROR(EAI_BADFLAGS);
1053#endif /* BROKEN_LIKE_POSIX */
1054
1055 if (service && *service) {
1056 char *c;
1057 gaih_service.num = strtoul(gaih_service.name = (void *)service, &c, 10);
1058 if (*c) {
1059 gaih_service.num = -1;
1060 }
1061#if BROKEN_LIKE_POSIX
1062 else
1063 if (!req->ai_socktype && !(req.ai_flags & AI_EXT))
1064 RETURN_ERROR(EAI_SERVICE);
1065#endif /* BROKEN_LIKE_POSIX */
1066
1067 pservice = &gaih_service;
1068 } else
1069 pservice = NULL;
1070
1071 if (pai)
1072 end = &p;
1073 else
1074 end = NULL;
1075
1076 while(g->gaih) {
1077 if ((req->ai_family == g->family) || !req->ai_family) {
1078 j++;
1079 if (!((pg && (pg->gaih == g->gaih)))) {
1080 pg = g;
1081 if (rval = g->gaih(name, pservice, req, end)) {
1082 if (!req->ai_family && (rval & GAIH_OKIFUNSPEC))
1083 continue;
1084
1085 if (p)
1086 freeaddrinfo(p);
1087
1088 rval = -(rval & GAIH_EAI);
1089 goto ret;
1090 }
1091 if (end)
1092 while(*end) end = &((*end)->ai_next);
1093 }
1094 }
1095 g++;
1096 }
1097
1098 if (!j)
1099 RETURN_ERROR(EAI_FAMILY);
1100
1101 if (p) {
1102 *pai = p;
1103#if DEBUG
1104 if (DEBUG_MESSAGES) {
1105 fprintf(stderr, "getaddrinfo: Success. *pai:\n");
1106 dump_addrinfo(p, 1);
1107 };
1108#endif /* DEBUG */
1109 rval = 0;
1110 goto ret;
1111 }
1112
1113 if (!pai && !rval) {
1114 rval = 0;
1115 goto ret;
1116 };
1117
1118 RETURN_ERROR(EAI_NONAME);
1119
1120ret:
1121#if DEBUG
1122 if (DEBUG_MESSAGES)
1123 fprintf(stderr, "getaddrinfo=%d\n", rval);
1124#endif /* DEBUG */
1125 return rval;
1126}
1127
diff --git a/src/lib/libc/net/getnameinfo.c b/src/lib/libc/net/getnameinfo.c
new file mode 100644
index 0000000000..15aa67d464
--- /dev/null
+++ b/src/lib/libc/net/getnameinfo.c
@@ -0,0 +1,562 @@
1/*
2 * %%% copyright-cmetz-96-bsd
3 * Copyright (c) 1996-1999, Craig Metz, All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Craig Metz and
16 * by other contributors.
17 * 4. Neither the name of the author nor the names of contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. All advertising materials mentioning features or use of this software
42 * must display the following acknowledgement:
43 * This product includes software developed by Craig Metz and
44 * by other contributors.
45 * 4. Neither the name of the author nor the names of contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 * 1. Redistributions of source code must retain the above copyright
65 * notice, this list of conditions and the following disclaimer.
66 * 2. Redistributions in binary form must reproduce the above copyright
67 * notice, this list of conditions and the following disclaimer in the
68 * documentation and/or other materials provided with the distribution.
69 * 3. All advertising materials mentioning features or use of this software
70 * must display the following acknowledgement:
71 * This product includes software developed by Craig Metz and
72 * by other contributors.
73 * 4. Neither the name of the author nor the names of contributors
74 * may be used to endorse or promote products derived from this software
75 * without specific prior written permission.
76 *
77 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
78 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
79 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
80 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
81 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
82 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
83 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
84 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
85 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
86 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
87 * SUCH DAMAGE.
88 */
89
90/* getnameinfo() v1.38 */
91
92/* To enable debugging support (REQUIRES NRL support library), define: */
93/* #define DEBUG 1 */
94
95#ifdef __OpenBSD__
96#define HAVE_POSIX1G_TYPES 1
97#define INET6 1
98#define LOCAL 1
99#define NETDB 1
100#define SALEN 1
101#undef RESOLVER
102#undef HOSTTABLE
103#undef DEBUG
104#undef HAVE_GETSERVBYNAME_R
105#undef HAVE_GETHOSTBYNAME2_R
106#endif /* __OpenBSD__ */
107
108#include <sys/types.h>
109#include <sys/socket.h>
110
111#include <netinet/in.h>
112#if LOCAL
113#include <sys/un.h>
114#include <sys/utsname.h>
115#endif /* LOCAL */
116#include <netdb.h>
117#include <errno.h>
118#include <string.h>
119#if RESOLVER
120#include <arpa/nameser.h>
121#include <resolv.h>
122#endif /* RESOLVER */
123
124#include "support.h"
125
126#ifndef AF_LOCAL
127#define AF_LOCAL AF_UNIX
128#endif /* AF_LOCAL */
129
130#ifndef min
131#define min(x,y) (((x) > (y)) ? (y) : (x))
132#endif /* min */
133
134#if DEBUG
135#if RESOLVER
136#define DEBUG_MESSAGES (_res.options & RES_DEBUG)
137#else /* RESOLVER */
138int __getnameinfo_debug = 0;
139#define DEBUG_MESSAGES (__getnameinfo_debug)
140#endif /* RESOLVER */
141#endif /* DEBUG */
142
143#if DEBUG
144#define RETURN_ERROR(x) do { \
145 if (DEBUG_MESSAGES) \
146 fprintf(stderr, "%s:%d: returning %s\n", __FILE__, __LINE__, #x); \
147 rval = (x); \
148 goto ret; \
149 } while(0)
150#else /* DEBUG */
151#define RETURN_ERROR(x) do { \
152 rval = (x); \
153 goto ret; \
154 } while(0)
155#endif /* DEBUG */
156
157#if HOSTTABLE
158static int hosttable_lookup_name(int family, void *addr, char *name, int namelen, int flags)
159{
160 int rval;
161 FILE *f;
162 char buffer[1024];
163 char addrbuf[16];
164 char *c, *c2;
165 int i;
166 char *prevcname = NULL;
167
168 if (!(f = fopen("/etc/hosts", "r")))
169 RETURN_ERROR(EAI_SYSTEM);
170
171 while(fgets(buffer, sizeof(buffer), f)) {
172 if (c = strchr(buffer, '#'))
173 *c = 0;
174
175 c = buffer;
176 while(*c && !isspace(*c)) c++;
177 if (!*c)
178 continue;
179
180 *(c++) = 0;
181
182 if (family == AF_INET)
183 if (inet_pton(AF_INET, buffer, addrbuf) > 0)
184 if (!memcmp(addrbuf, addr, sizeof(struct in_addr)))
185 goto build;
186
187#if INET6
188 if (family == AF_INET6)
189 if (inet_pton(AF_INET6, buffer, addrbuf) > 0)
190 if (!memcmp(addrbuf, addr, sizeof(struct in6_addr)))
191 goto build;
192#endif /* INET6 */
193
194 continue;
195
196build:
197 while(*c && isspace(*c)) c++;
198 if (!*c)
199 continue;
200
201 c2 = c;
202 while(*c2 && !isspace(*c2)) c2++;
203 if (!*c2)
204 continue;
205 *c2 = 0;
206
207 if ((flags & NI_NOFQDN) && (_res.options & RES_INIT) && _res.defdname[0] && (c2 = strstr(c + 1, _res.defdname)) && (*(--c2) == '.')) {
208 *c2 = 0;
209 i = min(c2 - c, namelen) - 1;
210 strncpy(name, c, i);
211 } else
212 strncpy(name, c, namelen - 1);
213
214 rval = 0;
215 goto ret;
216 };
217
218 RETURN_ERROR(1);
219
220ret:
221 fclose(f);
222 return rval;
223};
224#endif /* HOSTTABLE */
225
226#if RESOLVER
227#if INET6
228static char hextab[] = { '0', '1', '2', '3', '4', '5', '6', '7',
229 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
230#endif /* INET6 */
231
232struct rrheader {
233 int16_t type;
234 int16_t class;
235 u_int32_t ttl;
236 int16_t size;
237};
238#define RRHEADER_SZ 10
239
240int resolver_lookup_name(const char *ptrname, char *name, int namelen, int flags)
241{
242 int rval;
243 char answer[PACKETSZ];
244 int answerlen;
245 char dn[MAXDNAME];
246 char *prevcname = NULL;
247 void *p, *ep;
248 int answers, i;
249 uint16_t rtype, rclass;
250
251 if ((answerlen = res_search(ptrname, C_IN, T_PTR, answer, sizeof(answer))) < 0) {
252 switch(h_errno) {
253 case NETDB_INTERNAL:
254 RETURN_ERROR(EAI_SYSTEM);
255 case HOST_NOT_FOUND:
256 RETURN_ERROR(1);
257 case TRY_AGAIN:
258 RETURN_ERROR(EAI_AGAIN);
259 case NO_RECOVERY:
260 RETURN_ERROR(EAI_FAIL);
261 case NO_DATA:
262 RETURN_ERROR(1);
263 default:
264 RETURN_ERROR(EAI_FAIL);
265 };
266 };
267
268 p = answer;
269 ep = answer + answerlen;
270
271 if (answerlen < sizeof(HEADER))
272 RETURN_ERROR(EAI_FAIL);
273
274 {
275 HEADER *h = (HEADER *)p;
276 if (!h->qr || (h->opcode != QUERY) || (h->qdcount != htons(1)) || !h->ancount)
277 RETURN_ERROR(EAI_FAIL);
278
279 answers = ntohs(h->ancount);
280 };
281 p += sizeof(HEADER);
282
283 if ((i = dn_expand(answer, ep, p, dn, sizeof(dn))) < 0)
284 RETURN_ERROR(EAI_FAIL);
285
286 p += i;
287
288 if (p + 2*sizeof(u_int16_t) >= ep)
289 RETURN_ERROR(EAI_FAIL);
290
291 GETSHORT(rtype, p);
292 GETSHORT(rclass, p);
293
294 if ((rtype != T_PTR) || (rclass != C_IN))
295 RETURN_ERROR(EAI_FAIL);
296
297 while(answers--) {
298 if ((i = dn_expand(answer, ep, p, dn, sizeof(dn))) < 0)
299 RETURN_ERROR(EAI_FAIL);
300
301 p += i;
302
303 if (p + RRHEADER_SZ >= ep)
304 RETURN_ERROR(EAI_FAIL);
305
306 GETSHORT(rtype, p);
307 GETSHORT(rclass, p);
308 p += sizeof(uint32_t);
309 if (rclass != C_IN)
310 RETURN_ERROR(EAI_FAIL);
311 GETSHORT(rclass, p);
312 i = rclass;
313
314 if (p + i > ep)
315 RETURN_ERROR(EAI_FAIL);
316
317 if (rtype == T_PTR) {
318 if (dn_expand(answer, ep, p, dn, sizeof(dn)) != i)
319 RETURN_ERROR(EAI_FAIL);
320
321 {
322 char *c2;
323
324 if ((flags & NI_NOFQDN) && (_res.options & RES_INIT) && _res.defdname[0] && (c2 = strstr(dn + 1, _res.defdname)) && (*(--c2) == '.')) {
325 *c2 = 0;
326 strncpy(name, dn, min(c2 - dn, namelen) - 1);
327 } else
328 strncpy(name, dn, namelen - 1);
329 };
330 };
331 p += i;
332 };
333
334 rval = 0;
335
336ret:
337 return rval;
338};
339#endif /* RESOLVER */
340
341#if NETDB
342static int netdb_lookup_name(int family, void *addr, int addrlen, char *name,
343 int namelen)
344{
345 struct hostent *hostent;
346 char *c, *c2;
347 int rval, i;
348
349 if (!(hostent = gethostbyaddr(addr, addrlen, family))) {
350 switch(h_errno) {
351 case NETDB_INTERNAL:
352 RETURN_ERROR(EAI_SYSTEM);
353 case HOST_NOT_FOUND:
354 RETURN_ERROR(1);
355 case TRY_AGAIN:
356 RETURN_ERROR(EAI_AGAIN);
357 case NO_RECOVERY:
358 RETURN_ERROR(EAI_FAIL);
359 case NO_DATA:
360 RETURN_ERROR(1);
361 default:
362 RETURN_ERROR(EAI_FAIL);
363 };
364 };
365
366 endhostent();
367
368 c = hostent->h_name;
369 if ((flags & NI_NOFQDN) && (_res.options & RES_INIT) && _res.defdname[0] &&
370 (c2 = strstr(c + 1, _res.defdname)) && (*(--c2) == '.')) {
371 *c2 = 0;
372 i = min(c2 - c, namelen) - 1;
373 strncpy(name, c, i);
374 } else
375 strncpy(name, c, namelen - 1);
376
377 rval = 0;
378
379ret:
380 return rval;
381}
382#endif /* NETDB */
383
384int getnameinfo(const struct sockaddr *sa, size_t addrlen, char *host, size_t hostlen, char *serv, size_t servlen, int flags)
385{
386 int rval;
387 int serrno = errno;
388
389 if (!sa || (addrlen != SA_LEN(sa)))
390 RETURN_ERROR(EAI_FAIL);
391
392 if (host && (hostlen > 0))
393 switch(sa->sa_family) {
394#if INET6
395 case AF_INET6:
396 if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)sa)->sin6_addr)) {
397 if (flags & NI_NUMERICHOST)
398 goto inet6_noname;
399 else
400 strncpy(host, "*", hostlen - 1);
401 break;
402 };
403
404 if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)sa)->sin6_addr)) {
405 struct sockaddr_in sin;
406 memset(&sin, 0, sizeof(struct sockaddr_in));
407#if SALEN
408 sin.sin_len = sizeof(struct sockaddr_in);
409#endif /* SALEN */
410 sin.sin_family = AF_INET;
411 sin.sin_port = ((struct sockaddr_in6 *)sa)->sin6_port;
412 sin.sin_addr.s_addr = ((u_int32_t *)&((struct sockaddr_in6 *)sa)->sin6_addr)[3];
413 if (!(rval = getnameinfo((struct sockaddr *)&sin, sizeof(struct sockaddr_in), host, hostlen, serv, servlen, flags | NI_NAMEREQD)))
414 goto ret;
415 if (rval != EAI_NONAME)
416 goto ret;
417 goto inet6_noname;
418 };
419
420 if (flags & NI_NUMERICHOST)
421 goto inet6_noname;
422
423#if HOSTTABLE
424 if ((rval = hosttable_lookup_name(AF_INET6, &((struct sockaddr_in6 *)sa)->sin6_addr, host, hostlen, flags)) < 0)
425 goto ret;
426
427 if (!rval)
428 break;
429#endif /* HOSTTABLE */
430#if RESOLVER
431 {
432 char ptrname[sizeof("0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.ip6.int.")];
433 {
434 int i;
435 char *c = ptrname;
436 u_int8_t *p = (u_int8_t *)&((struct sockaddr_in6 *)sa)->sin6_addr + sizeof(struct in6_addr) - 1;
437
438 for (i = sizeof(struct in6_addr) / sizeof(u_int8_t); i > 0; i--, p--) {
439 *(c++) = hextab[*p & 0x0f];
440 *(c++) = '.';
441 *(c++) = hextab[(*p & 0xf0) >> 4];
442 *(c++) = '.';
443 };
444 strcpy(c, "ip6.int.");
445 };
446
447 if ((rval = resolver_lookup_name(ptrname, host, hostlen, flags)) < 0)
448 goto ret;
449
450 if (!rval)
451 break;
452 };
453#endif /* RESOLVER */
454
455inet6_noname:
456 if (flags & NI_NAMEREQD)
457 RETURN_ERROR(EAI_NONAME);
458
459 if (!inet_ntop(AF_INET6, &((struct sockaddr_in6 *)sa)->sin6_addr, host, hostlen))
460 RETURN_ERROR(EAI_NONAME);
461
462 break;
463#endif /* INET6 */
464 case AF_INET:
465 if (flags & NI_NUMERICHOST)
466 goto inet_noname;
467
468 if (!((struct sockaddr_in *)sa)->sin_addr.s_addr) {
469 strncpy(host, "*", hostlen - 1);
470 break;
471 };
472
473#if HOSTTABLE
474 if ((rval = hosttable_lookup_name(AF_INET, &((struct sockaddr_in *)sa)->sin_addr, host, hostlen, flags)) < 0)
475 goto ret;
476
477 if (!rval)
478 break;
479#endif /* HOSTTABLE */
480#if RESOLVER
481 {
482 char ptrname[30];
483 u_int8_t *p = (u_int8_t *)&((struct sockaddr_in *)sa)->sin_addr;
484 sprintf(ptrname, "%d.%d.%d.%d.in-addr.arpa.", p[3], p[2], p[1], p[0]);
485
486 if ((rval = resolver_lookup_name(ptrname, host, hostlen, flags)) < 0)
487 goto ret;
488
489 if (!rval)
490 break;
491 };
492#endif /* RESOLVER */
493
494inet_noname:
495 if (flags & NI_NAMEREQD)
496 RETURN_ERROR(EAI_NONAME);
497
498 if (!inet_ntop(AF_INET, &((struct sockaddr_in *)sa)->sin_addr, host, hostlen))
499 RETURN_ERROR(EAI_NONAME);
500
501 break;
502#if LOCAL
503 case AF_LOCAL:
504 if (!(flags & NI_NUMERICHOST)) {
505 struct utsname utsname;
506
507 if (!uname(&utsname)) {
508 strncpy(host, utsname.nodename, hostlen - 1);
509 break;
510 };
511 };
512
513 if (flags & NI_NAMEREQD)
514 RETURN_ERROR(EAI_NONAME);
515
516 strncpy(host, "localhost", hostlen - 1);
517 break;
518#endif /* LOCAL */
519 default:
520 RETURN_ERROR(EAI_FAMILY);
521 };
522
523 if (serv && (servlen > 0))
524 switch(sa->sa_family) {
525 case AF_INET:
526#if INET6
527 case AF_INET6:
528#endif /* INET6 */
529 if (!(flags & NI_NUMERICSERV)) {
530 struct servent *s;
531 if (s = getservbyport(((struct sockaddr_in *)sa)->sin_port, (flags & NI_DGRAM) ? "udp" : "tcp")) {
532 strncpy(serv, s->s_name, servlen - 1);
533 break;
534 };
535 if (!((struct sockaddr_in *)sa)->sin_port) {
536 strncpy(serv, "*", servlen - 1);
537 break;
538 };
539 };
540 snprintf(serv, servlen - 1, "%d", ntohs(((struct sockaddr_in *)sa)->sin_port));
541 break;
542#if LOCAL
543 case AF_LOCAL:
544 strncpy(serv, ((struct sockaddr_un *)sa)->sun_path, servlen - 1);
545 break;
546#endif /* LOCAL */
547 };
548
549 if (host && (hostlen > 0))
550 host[hostlen-1] = 0;
551 if (serv && (servlen > 0))
552 serv[servlen-1] = 0;
553 rval = 0;
554
555ret:
556 if (rval == 1)
557 rval = EAI_FAIL;
558
559 errno = serrno;
560
561 return rval;
562};
diff --git a/src/lib/libc/net/if_indextoname.c b/src/lib/libc/net/if_indextoname.c
new file mode 100644
index 0000000000..ff7fcada91
--- /dev/null
+++ b/src/lib/libc/net/if_indextoname.c
@@ -0,0 +1,181 @@
1/*
2 * %%% copyright-cmetz-98-bsd
3 * Copyright (c) 1998-1999, Craig Metz, All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Craig Metz and
16 * by other contributors.
17 * 4. Neither the name of the author nor the names of contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. All advertising materials mentioning features or use of this software
42 * must display the following acknowledgement:
43 * This product includes software developed by Craig Metz and
44 * by other contributors.
45 * 4. Neither the name of the author nor the names of contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 * 1. Redistributions of source code must retain the above copyright
65 * notice, this list of conditions and the following disclaimer.
66 * 2. Redistributions in binary form must reproduce the above copyright
67 * notice, this list of conditions and the following disclaimer in the
68 * documentation and/or other materials provided with the distribution.
69 * 3. All advertising materials mentioning features or use of this software
70 * must display the following acknowledgement:
71 * This product includes software developed by Craig Metz and
72 * by other contributors.
73 * 4. Neither the name of the author nor the names of contributors
74 * may be used to endorse or promote products derived from this software
75 * without specific prior written permission.
76 *
77 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
78 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
79 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
80 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
81 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
82 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
83 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
84 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
85 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
86 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
87 * SUCH DAMAGE.
88 */
89
90#include <sys/types.h>
91#include <stdlib.h>
92#include <sys/socket.h>
93#include <sys/ioctl.h>
94#include <net/if.h>
95#ifdef AF_LINK
96#include <net/if_dl.h>
97#endif /* AF_LINK */
98#include <errno.h>
99
100static char __name[IFNAMSIZ + 1];
101
102char *if_indextoname(unsigned int index, char *name)
103{
104 int i, fd;
105#ifdef SIOCGIFNAME
106 struct ifreq ifreq;
107#else /* SIOCGIFNAME */
108 struct ifconf ifconf;
109 void *p;
110 int len;
111 char lastname[IFNAMSIZ + 1];
112 char iname[IFNAMSIZ + 1];
113 char *retname = NULL;
114#endif /* SIOCGIFNAME */
115
116 if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
117 return 0;
118
119 if (!name)
120 name = __name;
121
122#ifdef SIOCGIFNAME
123 ifreq.ifr_ifindex = index;
124 i = ioctl(fd, SIOCGIFNAME, &ifreq);
125 close(fd);
126 if (i)
127 return NULL;
128
129 strcpy(name, ifreq.ifr_name);
130 return name;
131#else /* SIOCGIFNAME */
132 if (__siocgifconf(fd, &ifconf)) {
133 close(fd);
134 return NULL;
135 };
136
137 i = 0;
138 p = ifconf.ifc_buf;
139 len = ifconf.ifc_len;
140 lastname[0] = 0;
141 lastname[IFNAMSIZ] = 0;
142 iname[0] = 0;
143
144 while(len > 0) {
145 if (len < (IFNAMSIZ + sizeof(struct sockaddr)))
146 goto ret;
147 if (strncmp(lastname, p, IFNAMSIZ)) {
148 if (i == index)
149 strcpy(iname, lastname);
150 memcpy(lastname, p, IFNAMSIZ);
151 i++;
152 };
153 len -= IFNAMSIZ;
154 p += IFNAMSIZ;
155
156#ifdef AF_LINK
157 if (((struct sockaddr *)p)->sa_family == AF_LINK)
158 if (((struct sockaddr_dl *)p)->sdl_index == index) {
159 strcpy(retname = name, lastname);
160 goto ret;
161 };
162#endif /* AF_LINK */
163
164 if (len < SA_LEN((struct sockaddr *)p))
165 goto ret;
166 len -= SA_LEN((struct sockaddr *)p);
167 p += SA_LEN((struct sockaddr *)p);
168 };
169
170 if (i == index)
171 strcpy(iname, lastname);
172
173 if (iname[0])
174 strcpy(retname = name, iname);
175
176ret:
177 close(fd);
178 free(ifconf.ifc_buf);
179 return retname;
180#endif /* SIOCGIFNAME */
181};
diff --git a/src/lib/libc/net/if_indextoname.o b/src/lib/libc/net/if_indextoname.o
new file mode 100644
index 0000000000..332c550d58
--- /dev/null
+++ b/src/lib/libc/net/if_indextoname.o
Binary files differ
diff --git a/src/lib/libc/net/if_nameindex.c b/src/lib/libc/net/if_nameindex.c
new file mode 100644
index 0000000000..65bdbde9af
--- /dev/null
+++ b/src/lib/libc/net/if_nameindex.c
@@ -0,0 +1,212 @@
1/*
2 * %%% copyright-cmetz-98-bsd
3 * Copyright (c) 1998-1999, Craig Metz, All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Craig Metz and
16 * by other contributors.
17 * 4. Neither the name of the author nor the names of contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. All advertising materials mentioning features or use of this software
42 * must display the following acknowledgement:
43 * This product includes software developed by Craig Metz and
44 * by other contributors.
45 * 4. Neither the name of the author nor the names of contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 * 1. Redistributions of source code must retain the above copyright
65 * notice, this list of conditions and the following disclaimer.
66 * 2. Redistributions in binary form must reproduce the above copyright
67 * notice, this list of conditions and the following disclaimer in the
68 * documentation and/or other materials provided with the distribution.
69 * 3. All advertising materials mentioning features or use of this software
70 * must display the following acknowledgement:
71 * This product includes software developed by Craig Metz and
72 * by other contributors.
73 * 4. Neither the name of the author nor the names of contributors
74 * may be used to endorse or promote products derived from this software
75 * without specific prior written permission.
76 *
77 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
78 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
79 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
80 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
81 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
82 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
83 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
84 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
85 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
86 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
87 * SUCH DAMAGE.
88 */
89
90#include <stdlib.h>
91#include <sys/types.h>
92#include <sys/socket.h>
93#include <sys/ioctl.h>
94#include <net/if.h>
95#ifdef AF_LINK
96#include <net/if_dl.h>
97#endif /* AF_LINK */
98#include <errno.h>
99
100struct if_nameindex *if_nameindex(void)
101{
102 int i, j, fd;
103 struct if_nameindex *nameindex = NULL;
104 struct ifconf ifconf;
105 void *p;
106 int len;
107 char lastname[IFNAMSIZ + 1];
108
109 if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
110 return NULL;
111
112 if (__siocgifconf(fd, &ifconf)) {
113 close(fd);
114 return NULL;
115 };
116
117 i = sizeof(struct if_nameindex);
118 j = 0;
119 p = ifconf.ifc_buf;
120 len = ifconf.ifc_len;
121 lastname[0] = 0;
122 lastname[IFNAMSIZ] = 0;
123
124 while(len > 0) {
125 if (len < (IFNAMSIZ + sizeof(struct sockaddr)))
126 goto ret;
127 if (strncmp(lastname, p, IFNAMSIZ)) {
128 memcpy(lastname, p, IFNAMSIZ);
129 i += sizeof(struct if_nameindex);
130 j += strlen(lastname) + 1;
131 };
132 len -= IFNAMSIZ;
133 p += IFNAMSIZ;
134
135 if (len < SA_LEN((struct sockaddr *)p))
136 goto ret;
137 len -= SA_LEN((struct sockaddr *)p);
138 p += SA_LEN((struct sockaddr *)p);
139 };
140
141 if (!(nameindex = malloc(i + j))) {
142 errno = ENOMEM;
143 goto ret;
144 };
145 memset(nameindex, 0, i + j);
146
147 {
148#ifdef SIOCGIFINDEX
149 struct ifreq ifreq;
150#endif /* SIOCGIFINDEX */
151 struct if_nameindex *n;
152 char *c;
153
154 n = nameindex;
155 p = ifconf.ifc_buf;
156 c = (void *)nameindex + i;
157 i = 0;
158 len = ifconf.ifc_len;
159 lastname[0] = 0;
160
161 while(len > 0) {
162 if (len < (IFNAMSIZ + sizeof(struct sockaddr)))
163 goto ret;
164 if (strncmp(lastname, p, IFNAMSIZ)) {
165 if (i) {
166 if (!n->if_index) {
167#ifdef SIOCGIFINDEX
168 strcpy(ifreq.ifr_name, lastname);
169 if (ioctl(fd, SIOCGIFINDEX, &ifreq))
170 goto ret;
171 n->if_index = ifreq.ifr_ifindex;
172#else /* SIOCGIFINDEX */
173 n->if_index = i;
174#endif /* SIOCGIFINDEX */
175 };
176 n++;
177 };
178 i++;
179 memcpy(lastname, p, IFNAMSIZ);
180 strcpy(n->if_name = c, lastname);
181 c += strlen(c) + 1;
182 };
183 len -= IFNAMSIZ;
184 p += IFNAMSIZ;
185
186 if (len < SA_LEN((struct sockaddr *)p))
187 goto ret;
188#ifdef AF_LINK
189 if (((struct sockaddr *)p)->sa_family == AF_LINK)
190 n->if_index = ((struct sockaddr_dl *)p)->sdl_index;
191#endif /* AF_LINK */
192 len -= SA_LEN((struct sockaddr *)p);
193 p += SA_LEN((struct sockaddr *)p);
194 };
195
196 if (!n->if_index) {
197#ifdef SIOCGIFINDEX
198 strcpy(ifreq.ifr_name, lastname);
199 if (ioctl(fd, SIOCGIFINDEX, &ifreq))
200 goto ret;
201 n->if_index = ifreq.ifr_ifindex;
202#else /* SIOCGIFINDEX */
203 n->if_index = i;
204#endif /* SIOCGIFINDEX */
205 };
206 };
207
208ret:
209 close(fd);
210 free(ifconf.ifc_buf);
211 return nameindex;
212};
diff --git a/src/lib/libc/net/if_nameindex.o b/src/lib/libc/net/if_nameindex.o
new file mode 100644
index 0000000000..65fba476f2
--- /dev/null
+++ b/src/lib/libc/net/if_nameindex.o
Binary files differ
diff --git a/src/lib/libc/net/if_nametoindex.c b/src/lib/libc/net/if_nametoindex.c
new file mode 100644
index 0000000000..8ec2b233d1
--- /dev/null
+++ b/src/lib/libc/net/if_nametoindex.c
@@ -0,0 +1,173 @@
1/*
2 * %%% copyright-cmetz-98-bsd
3 * Copyright (c) 1998-1999, Craig Metz, All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Craig Metz and
16 * by other contributors.
17 * 4. Neither the name of the author nor the names of contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. All advertising materials mentioning features or use of this software
42 * must display the following acknowledgement:
43 * This product includes software developed by Craig Metz and
44 * by other contributors.
45 * 4. Neither the name of the author nor the names of contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 * 1. Redistributions of source code must retain the above copyright
65 * notice, this list of conditions and the following disclaimer.
66 * 2. Redistributions in binary form must reproduce the above copyright
67 * notice, this list of conditions and the following disclaimer in the
68 * documentation and/or other materials provided with the distribution.
69 * 3. All advertising materials mentioning features or use of this software
70 * must display the following acknowledgement:
71 * This product includes software developed by Craig Metz and
72 * by other contributors.
73 * 4. Neither the name of the author nor the names of contributors
74 * may be used to endorse or promote products derived from this software
75 * without specific prior written permission.
76 *
77 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
78 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
79 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
80 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
81 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
82 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
83 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
84 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
85 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
86 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
87 * SUCH DAMAGE.
88 */
89
90#include <sys/types.h>
91#include <stdlib.h>
92#include <sys/socket.h>
93#include <sys/ioctl.h>
94#include <net/if.h>
95#ifdef AF_LINK
96#include <net/if_dl.h>
97#endif /* AF_LINK */
98#include <errno.h>
99
100unsigned int if_nametoindex(const char *name)
101{
102 int i, fd;
103#ifdef SIOCGIFINDEX
104 struct ifreq ifreq;
105#else /* SIOCGIFINDEX */
106 struct ifconf ifconf;
107 void *p;
108 int len;
109 char lastname[IFNAMSIZ + 1], *thisname;
110 unsigned int index = 0;
111#endif /* SIOCGIFINDEX */
112
113 if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
114 return 0;
115
116#ifdef SIOCGIFINDEX
117 strcpy(ifreq.ifr_name, name);
118 i = ioctl(fd, SIOCGIFINDEX, &ifreq);
119 close(fd);
120 if (i)
121 return 0;
122
123 return ifreq.ifr_ifindex;
124#else /* SIOCGIFINDEX */
125 if (__siocgifconf(fd, &ifconf)) {
126 close(fd);
127 return 0;
128 };
129
130 i = 0;
131 p = ifconf.ifc_buf;
132 len = ifconf.ifc_len;
133 lastname[0] = 0;
134 lastname[IFNAMSIZ] = 0;
135
136 while(len > 0) {
137 if (len < (IFNAMSIZ + sizeof(struct sockaddr)))
138 goto ret;
139
140 if (strncmp(lastname, thisname = p, IFNAMSIZ)) {
141 if (!strcmp(lastname, name)) {
142 index = i;
143 goto ret;
144 };
145 memcpy(lastname, thisname, IFNAMSIZ);
146 i++;
147 };
148
149 len -= IFNAMSIZ;
150 p += IFNAMSIZ;
151
152#ifdef AF_LINK
153 if (!strncmp(thisname, name, IFNAMSIZ) && (((struct sockaddr *)p)->sa_family == AF_LINK)) {
154 index = ((struct sockaddr_dl *)p)->sdl_index;
155 goto ret;
156 };
157#endif /* AF_LINK */
158
159 if (len < SA_LEN((struct sockaddr *)p))
160 goto ret;
161 len -= SA_LEN((struct sockaddr *)p);
162 p += SA_LEN((struct sockaddr *)p);
163 };
164
165 if (!strcmp(lastname, name))
166 index = i;
167
168ret:
169 close(fd);
170 free(ifconf.ifc_buf);
171 return index;
172#endif /* SIOCGIFINDEX */
173};
diff --git a/src/lib/libc/net/if_nametoindex.o b/src/lib/libc/net/if_nametoindex.o
new file mode 100644
index 0000000000..910d2b4861
--- /dev/null
+++ b/src/lib/libc/net/if_nametoindex.o
Binary files differ