xref: /onnv-gate/usr/src/lib/libsocket/socket/socket.c (revision 13055:5b1463e9bb94)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*13055SAnders.Persson@Sun.COM  * Common Development and Distribution License (the "License").
6*13055SAnders.Persson@Sun.COM  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*13055SAnders.Persson@Sun.COM  * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate  */
240Sstevel@tonic-gate 
250Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
260Sstevel@tonic-gate /*	  All Rights Reserved   */
270Sstevel@tonic-gate 
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
300Sstevel@tonic-gate  * The Regents of the University of California
310Sstevel@tonic-gate  * All Rights Reserved
320Sstevel@tonic-gate  *
330Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
340Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
350Sstevel@tonic-gate  * contributors.
360Sstevel@tonic-gate  */
370Sstevel@tonic-gate 
380Sstevel@tonic-gate #include <sys/types.h>
390Sstevel@tonic-gate #include <sys/socket.h>
400Sstevel@tonic-gate #include <sys/stropts.h>
410Sstevel@tonic-gate #include <sys/stream.h>
420Sstevel@tonic-gate #include <sys/socketvar.h>
430Sstevel@tonic-gate #include <errno.h>
440Sstevel@tonic-gate #include <unistd.h>
450Sstevel@tonic-gate #include <stdlib.h>
460Sstevel@tonic-gate 
470Sstevel@tonic-gate extern int _so_socket();
480Sstevel@tonic-gate extern int _s_netconfig_path();
490Sstevel@tonic-gate extern int _setsockopt();
500Sstevel@tonic-gate 
510Sstevel@tonic-gate int _socket_create(int, int, int, int);
520Sstevel@tonic-gate 
530Sstevel@tonic-gate #pragma weak socket = _socket
540Sstevel@tonic-gate 
550Sstevel@tonic-gate int
_socket(int family,int type,int protocol)560Sstevel@tonic-gate _socket(int family, int type, int protocol)
570Sstevel@tonic-gate {
580Sstevel@tonic-gate 	return (_socket_create(family, type, protocol, SOV_DEFAULT));
590Sstevel@tonic-gate }
600Sstevel@tonic-gate 
610Sstevel@tonic-gate /*
620Sstevel@tonic-gate  * Used by the BCP library.
630Sstevel@tonic-gate  */
640Sstevel@tonic-gate int
_socket_bsd(int family,int type,int protocol)650Sstevel@tonic-gate _socket_bsd(int family, int type, int protocol)
660Sstevel@tonic-gate {
670Sstevel@tonic-gate 	return (_socket_create(family, type, protocol, SOV_SOCKBSD));
680Sstevel@tonic-gate }
690Sstevel@tonic-gate 
700Sstevel@tonic-gate int
_socket_svr4(int family,int type,int protocol)710Sstevel@tonic-gate _socket_svr4(int family, int type, int protocol)
720Sstevel@tonic-gate {
730Sstevel@tonic-gate 	return (_socket_create(family, type, protocol, SOV_SOCKSTREAM));
740Sstevel@tonic-gate }
750Sstevel@tonic-gate 
760Sstevel@tonic-gate int
__xnet_socket(int family,int type,int protocol)770Sstevel@tonic-gate __xnet_socket(int family, int type, int protocol)
780Sstevel@tonic-gate {
790Sstevel@tonic-gate 	return (_socket_create(family, type, protocol, SOV_XPG4_2));
800Sstevel@tonic-gate }
810Sstevel@tonic-gate 
820Sstevel@tonic-gate /*
830Sstevel@tonic-gate  * Create a socket endpoint for socket() and socketpair().
840Sstevel@tonic-gate  * In SunOS 4.X and in SunOS 5.X prior to XPG 4.2 the only error
850Sstevel@tonic-gate  * that could be returned due to invalid <family, type, protocol>
860Sstevel@tonic-gate  * was EPROTONOSUPPORT. (While the SunOS 4.X source contains EPROTOTYPE
870Sstevel@tonic-gate  * error as well that error can only be generated if the kernel is
880Sstevel@tonic-gate  * incorrectly configured.)
890Sstevel@tonic-gate  * For backwards compatibility only applications that request XPG 4.2
900Sstevel@tonic-gate  * (through c89 or XOPEN_SOURCE) will get EPROTOTYPE or EAFNOSUPPORT errors.
910Sstevel@tonic-gate  */
920Sstevel@tonic-gate int
_socket_create(int family,int type,int protocol,int version)930Sstevel@tonic-gate _socket_create(int family, int type, int protocol, int version)
940Sstevel@tonic-gate {
950Sstevel@tonic-gate 	int fd;
960Sstevel@tonic-gate 
970Sstevel@tonic-gate 	/*
980Sstevel@tonic-gate 	 * Try creating without knowing the device assuming that
99*13055SAnders.Persson@Sun.COM 	 * the transport provider is registered in /etc/sock2path.d.
1000Sstevel@tonic-gate 	 * If none found fall back to using /etc/netconfig to look
1010Sstevel@tonic-gate 	 * up the name of the transport device name. This provides
1020Sstevel@tonic-gate 	 * backwards compatibility for transport providers that have not
103*13055SAnders.Persson@Sun.COM 	 * yet been converted to using /etc/sock2path.d.
104*13055SAnders.Persson@Sun.COM 	 * XXX When all transport providers use /etc/sock2path.d. this
1050Sstevel@tonic-gate 	 * part of the code can be removed.
1060Sstevel@tonic-gate 	 */
1070Sstevel@tonic-gate 	fd = _so_socket(family, type, protocol, NULL, version);
1080Sstevel@tonic-gate 	if (fd == -1) {
1090Sstevel@tonic-gate 		char *devpath;
1100Sstevel@tonic-gate 		int saved_errno = errno;
1110Sstevel@tonic-gate 		int prototype = 0;
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate 		switch (saved_errno) {
1140Sstevel@tonic-gate 		case EAFNOSUPPORT:
1150Sstevel@tonic-gate 		case EPROTOTYPE:
1160Sstevel@tonic-gate 			if (version != SOV_XPG4_2)
1170Sstevel@tonic-gate 				saved_errno = EPROTONOSUPPORT;
1180Sstevel@tonic-gate 			break;
1190Sstevel@tonic-gate 		case EPROTONOSUPPORT:
1200Sstevel@tonic-gate 			break;
1210Sstevel@tonic-gate 
1220Sstevel@tonic-gate 		default:
1230Sstevel@tonic-gate 			errno = saved_errno;
1240Sstevel@tonic-gate 			return (-1);
1250Sstevel@tonic-gate 		}
1260Sstevel@tonic-gate 		if (_s_netconfig_path(family, type, protocol,
127*13055SAnders.Persson@Sun.COM 		    &devpath, &prototype) == -1) {
1280Sstevel@tonic-gate 			errno = saved_errno;
1290Sstevel@tonic-gate 			return (-1);
1300Sstevel@tonic-gate 		}
1310Sstevel@tonic-gate 		fd = _so_socket(family, type, protocol, devpath, version);
1320Sstevel@tonic-gate 		free(devpath);
1330Sstevel@tonic-gate 		if (fd == -1) {
1340Sstevel@tonic-gate 			errno = saved_errno;
1350Sstevel@tonic-gate 			return (-1);
1360Sstevel@tonic-gate 		}
1370Sstevel@tonic-gate 		if (prototype != 0) {
1380Sstevel@tonic-gate 			if (_setsockopt(fd, SOL_SOCKET, SO_PROTOTYPE,
1390Sstevel@tonic-gate 			    (caddr_t)&prototype, (int)sizeof (prototype)) < 0) {
1400Sstevel@tonic-gate 				(void) close(fd);
1410Sstevel@tonic-gate 				/*
1420Sstevel@tonic-gate 				 * setsockopt often fails with ENOPROTOOPT
1430Sstevel@tonic-gate 				 * but socket() should fail with
1440Sstevel@tonic-gate 				 * EPROTONOSUPPORT.
1450Sstevel@tonic-gate 				 */
1460Sstevel@tonic-gate 				errno = EPROTONOSUPPORT;
1470Sstevel@tonic-gate 				return (-1);
1480Sstevel@tonic-gate 			}
1490Sstevel@tonic-gate 		}
1500Sstevel@tonic-gate 	}
1510Sstevel@tonic-gate 	return (fd);
1520Sstevel@tonic-gate }
153