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/types.h>
35 #include <sys/socket.h>
37 #include <netinet/in.h>
44 * XXX The functions in this file are only needed to support transport
45 * providers that have not yet been converted to use /etc/sock2path.d.
46 * Once all transport providers have been converted this file can be
50 static struct netconfig
*_s_match_netconf(int family
, int type
, int proto
,
54 * The following two string arrays map a number as specified
55 * by a user of sockets, to the string as would be returned
56 * by a call to getnetconfig().
58 * They are used by _s_match_netconf();
60 * proto_sw contains protocol entries for which there is a corresponding
61 * /dev device. All others would presumably use raw IP and download the
64 static char *proto_sw
[] = {
66 "icmp", /* 1 = ICMP */
85 static char *family_sw
[] = {
86 "-", /* 0 = AF_UNSPEC */
87 "loopback", /* 1 = AF_UNIX */
88 "inet", /* 2 = AF_INET */
89 "implink", /* 3 = AF_IMPLINK */
90 "pup", /* 4 = AF_PUP */
91 "chaos", /* 5 = AF_CHAOS */
93 "nbs", /* 7 = AF_NBS */
94 "ecma", /* 8 = AF_ECMA */
95 "datakit", /* 9 = AF_DATAKIT */
96 "ccitt", /* 10 = AF_CCITT */
97 "sna", /* 11 = AF_SNA */
98 "decnet", /* 12 = AF_DECnet */
99 "dli", /* 13 = AF_DLI */
100 "lat", /* 14 = AF_LAT */
101 "hylink", /* 15 = AF_HYLINK */
102 "appletalk", /* 16 = AF_APPLETALK */
103 "nit", /* 17 = AF_NIT */
104 "ieee802", /* 18 = AF_802 */
105 "osi", /* 19 = AF_OSI */
106 "x25", /* 20 = AF_X25 */
107 "osinet", /* 21 = AF_OSINET */
108 "gosip", /* 22 = AF_GOSIP */
109 "ipx", /* 23 = AF_IPX */
110 "route", /* 24 = AF_ROUTE */
111 "link", /* 25 = AF_LINK */
112 "inet6", /* 26 = AF_INET6 */
113 "key", /* 27 = AF_KEY */
117 * Lookup family/type/protocol in /etc/netconfig.
118 * Returns the pathname and a prototype value (to be passed into SO_PROTOTYPE)
119 * The path is malloc'ed and has to be freed by the caller.
122 _s_netconfig_path(int family
, int type
, int protocol
,
123 char **pathp
, int *prototype
)
125 struct netconfig
*net
;
129 net
= _s_match_netconf(family
, type
, protocol
, &nethandle
);
133 if (strcmp(net
->nc_proto
, NC_NOPROTO
) != 0)
136 *prototype
= protocol
;
139 if (stat(net
->nc_device
, &stats
) < 0) {
149 errno
= EPFNOSUPPORT
;
152 endnetconfig(nethandle
); /* finished with netconfig struct */
155 if (!S_ISCHR(stats
.st_mode
)) {
156 errno
= EPFNOSUPPORT
;
157 endnetconfig(nethandle
); /* finished with netconfig struct */
160 *pathp
= malloc(strlen(net
->nc_device
) + 1);
161 if (*pathp
== NULL
) {
162 endnetconfig(nethandle
);
166 (void) strcpy(*pathp
, net
->nc_device
);
167 endnetconfig(nethandle
); /* finished with netconfig struct */
172 * Match config entry for protocol
175 static struct netconfig
*
176 _s_match_netconf(int family
, int type
, int proto
, void **nethandle
)
178 struct netconfig
*net
;
179 struct netconfig
*maybe
;
183 family
>= (int)sizeof (family_sw
) / (int)sizeof (char *) ||
184 proto
< 0 || proto
>= IPPROTO_MAX
) {
185 errno
= EPROTONOSUPPORT
;
189 if (proto
>= (int)sizeof (proto_sw
) / (int)sizeof (char *))
192 oproto
= proto_sw
[proto
];
196 * Loop through each entry in netconfig
197 * until one matches or we reach the end.
199 if ((*nethandle
= setnetconfig()) == NULL
) {
204 while ((net
= getnetconfig(*nethandle
)) != NULL
) {
206 * We make a copy of net->nc_semantics rather than modifying
207 * it in place because the network selection code shares the
208 * structures returned by getnetconfig() among all its callers.
209 * See bug #1160886 for more details.
211 unsigned int semantics
= net
->nc_semantics
;
213 if (semantics
== NC_TPI_COTS_ORD
)
214 semantics
= NC_TPI_COTS
;
216 if (strcmp(net
->nc_protofmly
, family_sw
[family
]) == 0 &&
218 strcmp(net
->nc_proto
, oproto
) == 0)
221 if (strcmp(net
->nc_protofmly
, family_sw
[family
]) == 0 &&
223 semantics
== SOCK_RAW
&&
224 strcmp(net
->nc_proto
, NC_NOPROTO
) == 0 &&
226 maybe
= net
; /* in case no exact match */
230 if (strcmp(net
->nc_protofmly
, family_sw
[family
]) == 0 &&
236 if (net
== NULL
&& maybe
)
240 endnetconfig(*nethandle
);
241 errno
= EPROTONOSUPPORT
;