4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
30 * Portions of this source code were derived from Berkeley 4.3 BSD
31 * under license from the Regents of the University of California.
34 #include <sys/netconfig.h>
35 #include <sys/types.h>
36 #include <sys/socket.h>
38 #include <netinet/in.h>
45 * XXX The functions in this file are only needed to support transport
46 * providers that have not yet been converted to use /etc/sock2path.d.
47 * Once all transport providers have been converted this file can be
51 static struct netconfig
*_s_match_netconf(int family
, int type
, int proto
,
55 * The following two string arrays map a number as specified
56 * by a user of sockets, to the string as would be returned
57 * by a call to getnetconfig().
59 * They are used by _s_match_netconf();
61 * proto_sw contains protocol entries for which there is a corresponding
62 * /dev device. All others would presumably use raw IP and download the
65 static char *proto_sw
[] = {
67 "icmp", /* 1 = ICMP */
86 static char *family_sw
[] = {
87 "-", /* 0 = AF_UNSPEC */
88 "loopback", /* 1 = AF_UNIX */
89 "inet", /* 2 = AF_INET */
90 "implink", /* 3 = AF_IMPLINK */
91 "pup", /* 4 = AF_PUP */
92 "chaos", /* 5 = AF_CHAOS */
94 "nbs", /* 7 = AF_NBS */
95 "ecma", /* 8 = AF_ECMA */
96 "datakit", /* 9 = AF_DATAKIT */
97 "ccitt", /* 10 = AF_CCITT */
98 "sna", /* 11 = AF_SNA */
99 "decnet", /* 12 = AF_DECnet */
100 "dli", /* 13 = AF_DLI */
101 "lat", /* 14 = AF_LAT */
102 "hylink", /* 15 = AF_HYLINK */
103 "appletalk", /* 16 = AF_APPLETALK */
104 "nit", /* 17 = AF_NIT */
105 "ieee802", /* 18 = AF_802 */
106 "osi", /* 19 = AF_OSI */
107 "x25", /* 20 = AF_X25 */
108 "osinet", /* 21 = AF_OSINET */
109 "gosip", /* 22 = AF_GOSIP */
110 "ipx", /* 23 = AF_IPX */
111 "route", /* 24 = AF_ROUTE */
112 "link", /* 25 = AF_LINK */
113 "inet6", /* 26 = AF_INET6 */
114 "key", /* 27 = AF_KEY */
118 * Lookup family/type/protocol in /etc/netconfig.
119 * Returns the pathname and a prototype value (to be passed into SO_PROTOTYPE)
120 * The path is malloc'ed and has to be freed by the caller.
123 _s_netconfig_path(int family
, int type
, int protocol
,
124 char **pathp
, int *prototype
)
126 struct netconfig
*net
;
130 net
= _s_match_netconf(family
, type
, protocol
, &nethandle
);
134 if (strcmp(net
->nc_proto
, NC_NOPROTO
) != 0)
137 *prototype
= protocol
;
140 if (stat(net
->nc_device
, &stats
) < 0) {
150 errno
= EPFNOSUPPORT
;
153 endnetconfig(nethandle
); /* finished with netconfig struct */
156 if (!S_ISCHR(stats
.st_mode
)) {
157 errno
= EPFNOSUPPORT
;
158 endnetconfig(nethandle
); /* finished with netconfig struct */
161 *pathp
= malloc(strlen(net
->nc_device
) + 1);
162 if (*pathp
== NULL
) {
163 endnetconfig(nethandle
);
167 (void) strcpy(*pathp
, net
->nc_device
);
168 endnetconfig(nethandle
); /* finished with netconfig struct */
173 * Match config entry for protocol
176 static struct netconfig
*
177 _s_match_netconf(int family
, int type
, int proto
, void **nethandle
)
179 struct netconfig
*net
;
180 struct netconfig
*maybe
;
184 family
>= (int)sizeof (family_sw
) / (int)sizeof (char *) ||
185 proto
< 0 || proto
>= IPPROTO_MAX
) {
186 errno
= EPROTONOSUPPORT
;
190 if (proto
>= (int)sizeof (proto_sw
) / (int)sizeof (char *))
193 oproto
= proto_sw
[proto
];
197 * Loop through each entry in netconfig
198 * until one matches or we reach the end.
200 if ((*nethandle
= setnetconfig()) == NULL
) {
205 while ((net
= getnetconfig(*nethandle
)) != NULL
) {
207 * We make a copy of net->nc_semantics rather than modifying
208 * it in place because the network selection code shares the
209 * structures returned by getnetconfig() among all its callers.
210 * See bug #1160886 for more details.
212 unsigned int semantics
= net
->nc_semantics
;
214 if (semantics
== NC_TPI_COTS_ORD
)
215 semantics
= NC_TPI_COTS
;
217 if (strcmp(net
->nc_protofmly
, family_sw
[family
]) == 0 &&
219 strcmp(net
->nc_proto
, oproto
) == 0)
222 if (strcmp(net
->nc_protofmly
, family_sw
[family
]) == 0 &&
224 semantics
== SOCK_RAW
&&
225 strcmp(net
->nc_proto
, NC_NOPROTO
) == 0 &&
227 maybe
= net
; /* in case no exact match */
231 if (strcmp(net
->nc_protofmly
, family_sw
[family
]) == 0 &&
237 if (net
== NULL
&& maybe
)
241 endnetconfig(*nethandle
);
242 errno
= EPROTONOSUPPORT
;