sys_socket.c revision 110908
1214501Srpaulo/* 2214501Srpaulo * Copyright (c) 1982, 1986, 1990, 1993 3214501Srpaulo * The Regents of the University of California. All rights reserved. 4214501Srpaulo * 5214501Srpaulo * Redistribution and use in source and binary forms, with or without 6214501Srpaulo * modification, are permitted provided that the following conditions 7214501Srpaulo * are met: 8214501Srpaulo * 1. Redistributions of source code must retain the above copyright 9214501Srpaulo * notice, this list of conditions and the following disclaimer. 10214501Srpaulo * 2. Redistributions in binary form must reproduce the above copyright 11214501Srpaulo * notice, this list of conditions and the following disclaimer in the 12214501Srpaulo * documentation and/or other materials provided with the distribution. 13214501Srpaulo * 3. All advertising materials mentioning features or use of this software 14214501Srpaulo * must display the following acknowledgement: 15214501Srpaulo * This product includes software developed by the University of 16214501Srpaulo * California, Berkeley and its contributors. 17214501Srpaulo * 4. Neither the name of the University nor the names of its contributors 18214501Srpaulo * may be used to endorse or promote products derived from this software 19214501Srpaulo * without specific prior written permission. 20214501Srpaulo * 21214501Srpaulo * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22214501Srpaulo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23214501Srpaulo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24214501Srpaulo * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25214501Srpaulo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26214501Srpaulo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27214501Srpaulo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28214501Srpaulo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29214501Srpaulo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30214501Srpaulo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31214501Srpaulo * SUCH DAMAGE. 32214501Srpaulo * 33214501Srpaulo * @(#)sys_socket.c 8.1 (Berkeley) 6/10/93 34214501Srpaulo * $FreeBSD: head/sys/kern/sys_socket.c 110908 2003-02-15 06:04:55Z alfred $ 35214501Srpaulo */ 36214501Srpaulo 37214501Srpaulo#include "opt_mac.h" 38214501Srpaulo 39214501Srpaulo#include <sys/param.h> 40214501Srpaulo#include <sys/systm.h> 41214501Srpaulo#include <sys/file.h> 42214501Srpaulo#include <sys/filedesc.h> 43214501Srpaulo#include <sys/mac.h> 44214501Srpaulo#include <sys/protosw.h> 45214501Srpaulo#include <sys/sigio.h> 46214501Srpaulo#include <sys/socket.h> 47214501Srpaulo#include <sys/socketvar.h> 48214501Srpaulo#include <sys/filio.h> /* XXX */ 49214501Srpaulo#include <sys/sockio.h> 50214501Srpaulo#include <sys/stat.h> 51214501Srpaulo#include <sys/uio.h> 52214501Srpaulo#include <sys/filedesc.h> 53214501Srpaulo#include <sys/ucred.h> 54214501Srpaulo 55214501Srpaulo#include <net/if.h> 56214501Srpaulo#include <net/route.h> 57214501Srpaulo 58214501Srpaulostruct fileops socketops = { 59214501Srpaulo soo_read, soo_write, soo_ioctl, soo_poll, soo_kqfilter, 60214501Srpaulo soo_stat, soo_close, DFLAG_PASSABLE 61214501Srpaulo}; 62214501Srpaulo 63214501Srpaulo/* ARGSUSED */ 64214501Srpauloint 65214501Srpaulosoo_read(fp, uio, active_cred, flags, td) 66214501Srpaulo struct file *fp; 67214501Srpaulo struct uio *uio; 68214501Srpaulo struct ucred *active_cred; 69214501Srpaulo struct thread *td; 70214501Srpaulo int flags; 71214501Srpaulo{ 72214501Srpaulo struct socket *so = fp->f_data; 73214501Srpaulo int error; 74214501Srpaulo 75214501Srpaulo mtx_lock(&Giant); 76214501Srpaulo#ifdef MAC 77214501Srpaulo error = mac_check_socket_receive(active_cred, so); 78214501Srpaulo if (error) { 79214501Srpaulo mtx_unlock(&Giant); 80214501Srpaulo return (error); 81214501Srpaulo } 82214501Srpaulo#endif 83214501Srpaulo error = so->so_proto->pr_usrreqs->pru_soreceive(so, 0, uio, 0, 0, 0); 84214501Srpaulo mtx_unlock(&Giant); 85214501Srpaulo return (error); 86214501Srpaulo} 87214501Srpaulo 88214501Srpaulo/* ARGSUSED */ 89214501Srpauloint 90214501Srpaulosoo_write(fp, uio, active_cred, flags, td) 91214501Srpaulo struct file *fp; 92214501Srpaulo struct uio *uio; 93214501Srpaulo struct ucred *active_cred; 94214501Srpaulo struct thread *td; 95214501Srpaulo int flags; 96214501Srpaulo{ 97214501Srpaulo struct socket *so = fp->f_data; 98214501Srpaulo int error; 99214501Srpaulo 100214501Srpaulo mtx_lock(&Giant); 101214501Srpaulo#ifdef MAC 102214501Srpaulo error = mac_check_socket_send(active_cred, so); 103214501Srpaulo if (error) { 104214501Srpaulo mtx_unlock(&Giant); 105214501Srpaulo return (error); 106214501Srpaulo } 107214501Srpaulo#endif 108214501Srpaulo error = so->so_proto->pr_usrreqs->pru_sosend(so, 0, uio, 0, 0, 0, 109214501Srpaulo uio->uio_td); 110214501Srpaulo mtx_unlock(&Giant); 111214501Srpaulo return (error); 112214501Srpaulo} 113214501Srpaulo 114214501Srpauloint 115214501Srpaulosoo_ioctl(fp, cmd, data, active_cred, td) 116214501Srpaulo struct file *fp; 117214501Srpaulo u_long cmd; 118214501Srpaulo void *data; 119214501Srpaulo struct ucred *active_cred; 120214501Srpaulo struct thread *td; 121214501Srpaulo{ 122214501Srpaulo register struct socket *so = fp->f_data; 123214501Srpaulo 124214501Srpaulo switch (cmd) { 125214501Srpaulo 126214501Srpaulo case FIONBIO: 127214501Srpaulo if (*(int *)data) 128214501Srpaulo so->so_state |= SS_NBIO; 129214501Srpaulo else 130214501Srpaulo so->so_state &= ~SS_NBIO; 131214501Srpaulo return (0); 132214501Srpaulo 133214501Srpaulo case FIOASYNC: 134214501Srpaulo if (*(int *)data) { 135214501Srpaulo so->so_state |= SS_ASYNC; 136214501Srpaulo so->so_rcv.sb_flags |= SB_ASYNC; 137214501Srpaulo so->so_snd.sb_flags |= SB_ASYNC; 138214501Srpaulo } else { 139214501Srpaulo so->so_state &= ~SS_ASYNC; 140214501Srpaulo so->so_rcv.sb_flags &= ~SB_ASYNC; 141214501Srpaulo so->so_snd.sb_flags &= ~SB_ASYNC; 142214501Srpaulo } 143214501Srpaulo return (0); 144214501Srpaulo 145214501Srpaulo case FIONREAD: 146214501Srpaulo *(int *)data = so->so_rcv.sb_cc; 147214501Srpaulo return (0); 148214501Srpaulo 149214501Srpaulo case FIOSETOWN: 150214501Srpaulo return (fsetown(*(int *)data, &so->so_sigio)); 151214501Srpaulo 152214501Srpaulo case FIOGETOWN: 153214501Srpaulo *(int *)data = fgetown(&so->so_sigio); 154214501Srpaulo return (0); 155214501Srpaulo 156214501Srpaulo case SIOCSPGRP: 157214501Srpaulo return (fsetown(-(*(int *)data), &so->so_sigio)); 158214501Srpaulo 159214501Srpaulo case SIOCGPGRP: 160214501Srpaulo *(int *)data = -fgetown(&so->so_sigio); 161214501Srpaulo return (0); 162214501Srpaulo 163214501Srpaulo case SIOCATMARK: 164214501Srpaulo *(int *)data = (so->so_state&SS_RCVATMARK) != 0; 165214501Srpaulo return (0); 166214501Srpaulo } 167214501Srpaulo /* 168214501Srpaulo * Interface/routing/protocol specific ioctls: 169214501Srpaulo * interface and routing ioctls should have a 170214501Srpaulo * different entry since a socket's unnecessary 171214501Srpaulo */ 172214501Srpaulo if (IOCGROUP(cmd) == 'i') 173214501Srpaulo return (ifioctl(so, cmd, data, td)); 174214501Srpaulo if (IOCGROUP(cmd) == 'r') 175214501Srpaulo return (rtioctl(cmd, data)); 176214501Srpaulo return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, 0, td)); 177214501Srpaulo} 178214501Srpaulo 179214501Srpauloint 180214501Srpaulosoo_poll(fp, events, active_cred, td) 181214501Srpaulo struct file *fp; 182214501Srpaulo int events; 183214501Srpaulo struct ucred *active_cred; 184214501Srpaulo struct thread *td; 185214501Srpaulo{ 186214501Srpaulo struct socket *so = fp->f_data; 187214501Srpaulo return so->so_proto->pr_usrreqs->pru_sopoll(so, events, 188214501Srpaulo fp->f_cred, td); 189214501Srpaulo} 190214501Srpaulo 191214501Srpauloint 192214501Srpaulosoo_stat(fp, ub, active_cred, td) 193214501Srpaulo struct file *fp; 194214501Srpaulo struct stat *ub; 195214501Srpaulo struct ucred *active_cred; 196214501Srpaulo struct thread *td; 197214501Srpaulo{ 198214501Srpaulo struct socket *so = fp->f_data; 199214501Srpaulo 200214501Srpaulo bzero((caddr_t)ub, sizeof (*ub)); 201214501Srpaulo ub->st_mode = S_IFSOCK; 202214501Srpaulo /* 203214501Srpaulo * If SS_CANTRCVMORE is set, but there's still data left in the 204214501Srpaulo * receive buffer, the socket is still readable. 205214501Srpaulo */ 206214501Srpaulo if ((so->so_state & SS_CANTRCVMORE) == 0 || 207214501Srpaulo so->so_rcv.sb_cc != 0) 208214501Srpaulo ub->st_mode |= S_IRUSR | S_IRGRP | S_IROTH; 209214501Srpaulo if ((so->so_state & SS_CANTSENDMORE) == 0) 210214501Srpaulo ub->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; 211214501Srpaulo ub->st_size = so->so_rcv.sb_cc - so->so_rcv.sb_ctl; 212214501Srpaulo ub->st_uid = so->so_cred->cr_uid; 213214501Srpaulo ub->st_gid = so->so_cred->cr_gid; 214214501Srpaulo return ((*so->so_proto->pr_usrreqs->pru_sense)(so, ub)); 215214501Srpaulo} 216214501Srpaulo 217214501Srpaulo/* 218214501Srpaulo * API socket close on file pointer. We call soclose() to close the 219214501Srpaulo * socket (including initiating closing protocols). soclose() will 220214501Srpaulo * sorele() the file reference but the actual socket will not go away 221214501Srpaulo * until the socket's ref count hits 0. 222214501Srpaulo */ 223214501Srpaulo/* ARGSUSED */ 224214501Srpauloint 225214501Srpaulosoo_close(fp, td) 226214501Srpaulo struct file *fp; 227214501Srpaulo struct thread *td; 228214501Srpaulo{ 229214501Srpaulo int error = 0; 230214501Srpaulo struct socket *so; 231214501Srpaulo 232214501Srpaulo so = fp->f_data; 233214501Srpaulo fp->f_ops = &badfileops; 234214501Srpaulo fp->f_data = NULL; 235 236 if (so) 237 error = soclose(so); 238 return (error); 239} 240