socksubr.c revision c6c65e5445ba6bc005f3da488bddd36494d26e65
199767f8919635c4928607450d9e0abb932109ceToomas Soome * CDDL HEADER START
199767f8919635c4928607450d9e0abb932109ceToomas Soome * The contents of this file are subject to the terms of the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Common Development and Distribution License (the "License").
199767f8919635c4928607450d9e0abb932109ceToomas Soome * You may not use this file except in compliance with the License.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
199767f8919635c4928607450d9e0abb932109ceToomas Soome * See the License for the specific language governing permissions
199767f8919635c4928607450d9e0abb932109ceToomas Soome * and limitations under the License.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * When distributing Covered Code, include this CDDL HEADER in each
199767f8919635c4928607450d9e0abb932109ceToomas Soome * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * If applicable, add the following below this CDDL HEADER, with the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * fields enclosed by brackets "[]" replaced with your own identifying
199767f8919635c4928607450d9e0abb932109ceToomas Soome * information: Portions Copyright [yyyy] [name of copyright owner]
199767f8919635c4928607450d9e0abb932109ceToomas Soome * CDDL HEADER END
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Use is subject to license terms.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#pragma ident "%Z%%M% %I% %E% SMI"
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Macros that operate on struct cmsghdr.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * The CMSG_VALID macro does not assume that the last option buffer is padded.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define CMSG_CONTENTLEN(cmsg) ((cmsg)->cmsg_len - sizeof (struct cmsghdr))
199767f8919635c4928607450d9e0abb932109ceToomas Soome ((ssize_t)(cmsg)->cmsg_len >= sizeof (struct cmsghdr)) && \
199767f8919635c4928607450d9e0abb932109ceToomas Soome ((uintptr_t)(cmsg) + (cmsg)->cmsg_len <= (uintptr_t)(end)))
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define SO_LOCK_WAKEUP_TIME 3000 /* Wakeup time in milliseconds */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic struct kmem_cache *socktpi_cache, *socktpi_unix_cache;
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int sockfs_snapshot(kstat_t *, void *, int);
199767f8919635c4928607450d9e0abb932109ceToomas Soomeextern void nl7c_init(void);
199767f8919635c4928607450d9e0abb932109ceToomas Soome * kernel structure for passing the sockinfo data back up to the user.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * the strings array allows us to convert AF_UNIX addresses into strings
199767f8919635c4928607450d9e0abb932109ceToomas Soome * with a common method regardless of which n-bit kernel we're running.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Translate from a device pathname (e.g. "/dev/tcp") to a vnode.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Returns with the vnode held.
199767f8919635c4928607450d9e0abb932109ceToomas Soomesogetvp(char *devpath, vnode_t **vpp, int uioflag)
199767f8919635c4928607450d9e0abb932109ceToomas Soome ASSERT(uioflag == UIO_SYSSPACE || uioflag == UIO_USERSPACE);
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Lookup the underlying filesystem vnode.
199767f8919635c4928607450d9e0abb932109ceToomas Soome error = lookupname(devpath, uioflag, FOLLOW, NULLVPP, &vp);
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Check that it is the correct vnode */
199767f8919635c4928607450d9e0abb932109ceToomas Soome * If devpath went through devfs, the device should already
199767f8919635c4928607450d9e0abb932109ceToomas Soome * be configured. If devpath is a mknod file, however, we
199767f8919635c4928607450d9e0abb932109ceToomas Soome * need to make sure the device is properly configured.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * To do this, we do something similar to spec_open()
199767f8919635c4928607450d9e0abb932109ceToomas Soome * except that we resolve to the minor/leaf level since
199767f8919635c4928607450d9e0abb932109ceToomas Soome * we need to return a vnode.
199767f8919635c4928607450d9e0abb932109ceToomas Soome char *pathname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
199767f8919635c4928607450d9e0abb932109ceToomas Soome error = ddi_dev_pathname(vp->v_rdev, S_IFCHR, pathname);
199767f8919635c4928607450d9e0abb932109ceToomas Soome error = devfs_lookupname(pathname, NULLVPP, &dvp);
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* device is configured at this point */
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Add or delete (latter if devpath is NULL) an enter to the sockparams
199767f8919635c4928607450d9e0abb932109ceToomas Soome * table. If devpathlen is zero the devpath with not be kmem_freed. Otherwise
199767f8919635c4928607450d9e0abb932109ceToomas Soome * this routine assumes that the caller has kmem_alloced devpath/devpathlen
199767f8919635c4928607450d9e0abb932109ceToomas Soome * for this routine to consume.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * The zero devpathlen could be used if the kernel wants to create entries
199767f8919635c4928607450d9e0abb932109ceToomas Soome * itself by calling sockconfig(1,2,3, "/dev/tcp", 0);
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Look for an existing match.
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (spp = &sphead; (sp = *spp) != NULL; spp = &sp->sp_next) {
goto done;
goto done;
if (error) {
goto done;
done:
if (error) {
#ifdef SOCK_DEBUG
return (error);
vnode_t *
int error;
int found = 0;
switch (found) {
return (NULL);
if (error) {
return (NULL);
return (vp);
return (vp);
struct vnode *
#ifdef notyet
return (vp);
while (mp) {
#ifdef DEBUG
* file descriptor will behave like a stream w.r.t. the timestamps.
int retval;
return (retval);
int error;
char *err_str;
if (error != 0) {
return (error);
if (error != 0) {
goto failure;
if (error != 0) {
goto failure;
if (error != 0) {
goto failure;
dev = 0;
nl7c_init();
return (error);
return (EWOULDBLOCK);
return (EWOULDBLOCK);
return (EINTR);
eprintline(0);
return (NULL);
eprintline(0);
return (NULL);
return ((void *)ptr1);
int error;
if (error) {
return (error);
goto done2;
if (checkaccess) {
goto done2;
goto done2;
goto done;
goto done;
done:
return (error);
int family;
switch (family) {
case AF_INET:
return (EAFNOSUPPORT);
return (EINVAL);
case AF_INET6: {
#ifdef DEBUG
return (EAFNOSUPPORT);
return (EINVAL);
#ifdef DEBUG
case AF_UNIX:
return (ENOENT);
return (EAFNOSUPPORT);
return (ENAMETOOLONG);
int error;
void *addr;
if (error) {
return (error);
mblk_t *
return (mp);
int i, fd;
int *rp;
int numfd;
for (i = 0; i < numfd; i++) {
goto cleanup;
if (audit_active)
dprint(0,
return (EMFILE);
int numfd, i;
int *fds;
int fdbufsize;
for (i = 0; i < numfd; i++) {
return (EBADF);
if (audit_active)
int numfd;
static t_uscalar_t
(int)sizeof (struct file *) * (int)sizeof (int));
(void *)mp);
for (i = 0; i < numfd; i++) {
if (startoff < 0)
startoff = 0;
if (startoff < (int)sizeof (int)) {
dprint(0,
startoff -= (int)sizeof (int);
int startoff)
if (oldflg) {
void *fds;
int fdlen;
if (oldflg) {
if (controllen == 0)
fdlen = 0;
return (EINVAL);
if (oldflg)
sizeof (struct T_opthdr));
return (optlen);
if (oldflg) {
int fdbuflen;
if (oldflg) {
if (oldflg)
if (oldflg)
return (cmsglen);
int fdbuflen;
int error;
return (EPROTO);
if (oldflg) {
(int)controllen);
if (error != 0)
return (error);
int fdlen;
sizeof (struct cmsghdr));
if (error != 0)
return (error);
if (oldflg)
sizeof (intptr_t));
sizeof (struct cmsghdr);
sizeof (struct cmsghdr);
if (oldflg)
sizeof (struct cmsghdr));
*srclenp = 0;
mblk_t *
switch (sleepflg) {
case _ALLOC_SLEEP:
case _ALLOC_INTR:
return (NULL);
case _ALLOC_NOSLEEP:
return (NULL);
return (mp);
mblk_t *
if (size == 0)
return (NULL);
if (len != 0) {
return (mp);
if (len != 0) {
mblk_t *
if (size == 0)
if (mp)
return (mp);
mblk_t *
if (size == 0)
return (mp);
#ifdef DEBUG
buf[0] = 0;
return (buf);
return (buf);
switch (family) {
case AF_INET: {
case AF_INET6: {
case AF_UNIX: {
return (buf);
#define EQUIV(a, b) (((a) && (b)) || (!(a) && (!(b))))
case SS_OOBPEND:
case SS_HADOOBDATA:
return (ksp);
return (EACCES);
nactive++;
return (EACCES);
if (sn_len != 0) {
if (sn_len != 0) {
ns++;
pksi++;
int error = 0;
int iovcnt = 0;
short fflag;
rwflag = 0;
error = 0;
out:
if (error != 0) {
*err = 0;
return (cnt);