1139804Simp/*- 21541Srgrimes * Copyright (c) 1982, 1986, 1990, 1993 31541Srgrimes * The Regents of the University of California. All rights reserved. 41541Srgrimes * 51541Srgrimes * Redistribution and use in source and binary forms, with or without 61541Srgrimes * modification, are permitted provided that the following conditions 71541Srgrimes * are met: 81541Srgrimes * 1. Redistributions of source code must retain the above copyright 91541Srgrimes * notice, this list of conditions and the following disclaimer. 101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111541Srgrimes * notice, this list of conditions and the following disclaimer in the 121541Srgrimes * documentation and/or other materials provided with the distribution. 131541Srgrimes * 4. Neither the name of the University nor the names of its contributors 141541Srgrimes * may be used to endorse or promote products derived from this software 151541Srgrimes * without specific prior written permission. 161541Srgrimes * 171541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271541Srgrimes * SUCH DAMAGE. 281541Srgrimes * 291541Srgrimes * @(#)sys_socket.c 8.1 (Berkeley) 6/10/93 301541Srgrimes */ 311541Srgrimes 32116182Sobrien#include <sys/cdefs.h> 33116182Sobrien__FBSDID("$FreeBSD$"); 34116182Sobrien 351541Srgrimes#include <sys/param.h> 361541Srgrimes#include <sys/systm.h> 371541Srgrimes#include <sys/file.h> 38108524Salfred#include <sys/filedesc.h> 39143417Srwatson#include <sys/proc.h> 401541Srgrimes#include <sys/protosw.h> 41108524Salfred#include <sys/sigio.h> 42143417Srwatson#include <sys/signal.h> 43143417Srwatson#include <sys/signalvar.h> 441541Srgrimes#include <sys/socket.h> 451541Srgrimes#include <sys/socketvar.h> 4624206Sbde#include <sys/filio.h> /* XXX */ 4724206Sbde#include <sys/sockio.h> 481541Srgrimes#include <sys/stat.h> 4934924Sbde#include <sys/uio.h> 5060405Schris#include <sys/ucred.h> 511541Srgrimes 521541Srgrimes#include <net/if.h> 531541Srgrimes#include <net/route.h> 54196019Srwatson#include <net/vnet.h> 551541Srgrimes 56163606Srwatson#include <security/mac/mac_framework.h> 57163606Srwatson 58167206Srwatsonstruct fileops socketops = { 59116546Sphk .fo_read = soo_read, 60116546Sphk .fo_write = soo_write, 61175140Sjhb .fo_truncate = soo_truncate, 62116546Sphk .fo_ioctl = soo_ioctl, 63116546Sphk .fo_poll = soo_poll, 64116546Sphk .fo_kqfilter = soo_kqfilter, 65116546Sphk .fo_stat = soo_stat, 66116546Sphk .fo_close = soo_close, 67224914Skib .fo_chmod = invfo_chmod, 68224914Skib .fo_chown = invfo_chown, 69254356Sglebius .fo_sendfile = invfo_sendfile, 70116546Sphk .fo_flags = DFLAG_PASSABLE 7172521Sjlemon}; 721541Srgrimes 731541Srgrimes/* ARGSUSED */ 7443408Snewtonint 75167206Srwatsonsoo_read(struct file *fp, struct uio *uio, struct ucred *active_cred, 76167206Srwatson int flags, struct thread *td) 771541Srgrimes{ 78109153Sdillon struct socket *so = fp->f_data; 7992310Salfred int error; 8092310Salfred 81191816Szec#ifdef MAC 82172930Srwatson error = mac_socket_check_receive(active_cred, so); 83171744Srwatson if (error) 84104571Srwatson return (error); 85104571Srwatson#endif 86191816Szec error = soreceive(so, 0, uio, 0, 0, 0); 87191816Szec return (error); 881541Srgrimes} 891541Srgrimes 901541Srgrimes/* ARGSUSED */ 9143408Snewtonint 92167206Srwatsonsoo_write(struct file *fp, struct uio *uio, struct ucred *active_cred, 93167206Srwatson int flags, struct thread *td) 941541Srgrimes{ 95109153Sdillon struct socket *so = fp->f_data; 9692310Salfred int error; 9792310Salfred 98104571Srwatson#ifdef MAC 99172930Srwatson error = mac_socket_check_send(active_cred, so); 100171744Srwatson if (error) 101104571Srwatson return (error); 102104571Srwatson#endif 103160619Srwatson error = sosend(so, 0, uio, 0, 0, 0, uio->uio_td); 104143417Srwatson if (error == EPIPE && (so->so_options & SO_NOSIGPIPE) == 0) { 105143417Srwatson PROC_LOCK(uio->uio_td->td_proc); 106209595Sjhb tdsignal(uio->uio_td, SIGPIPE); 107143417Srwatson PROC_UNLOCK(uio->uio_td->td_proc); 108143417Srwatson } 10992310Salfred return (error); 1101541Srgrimes} 1111541Srgrimes 1121549Srgrimesint 113175140Sjhbsoo_truncate(struct file *fp, off_t length, struct ucred *active_cred, 114175140Sjhb struct thread *td) 115175140Sjhb{ 116175140Sjhb 117175140Sjhb return (EINVAL); 118175140Sjhb} 119175140Sjhb 120175140Sjhbint 121167206Srwatsonsoo_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *active_cred, 122167206Srwatson struct thread *td) 1231541Srgrimes{ 124137671Sphk struct socket *so = fp->f_data; 125137671Sphk int error = 0; 1261541Srgrimes 1271541Srgrimes switch (cmd) { 1281541Srgrimes case FIONBIO: 129130653Srwatson SOCK_LOCK(so); 1301541Srgrimes if (*(int *)data) 1311541Srgrimes so->so_state |= SS_NBIO; 1321541Srgrimes else 1331541Srgrimes so->so_state &= ~SS_NBIO; 134130653Srwatson SOCK_UNLOCK(so); 135137671Sphk break; 1361541Srgrimes 1371541Srgrimes case FIOASYNC: 138130653Srwatson /* 139167206Srwatson * XXXRW: This code separately acquires SOCK_LOCK(so) and 140167206Srwatson * SOCKBUF_LOCK(&so->so_rcv) even though they are the same 141167206Srwatson * mutex to avoid introducing the assumption that they are 142167206Srwatson * the same. 143130653Srwatson */ 1441541Srgrimes if (*(int *)data) { 145130653Srwatson SOCK_LOCK(so); 1461541Srgrimes so->so_state |= SS_ASYNC; 147130653Srwatson SOCK_UNLOCK(so); 148130653Srwatson SOCKBUF_LOCK(&so->so_rcv); 1491541Srgrimes so->so_rcv.sb_flags |= SB_ASYNC; 150130653Srwatson SOCKBUF_UNLOCK(&so->so_rcv); 151130653Srwatson SOCKBUF_LOCK(&so->so_snd); 1521541Srgrimes so->so_snd.sb_flags |= SB_ASYNC; 153130653Srwatson SOCKBUF_UNLOCK(&so->so_snd); 1541541Srgrimes } else { 155130653Srwatson SOCK_LOCK(so); 1561541Srgrimes so->so_state &= ~SS_ASYNC; 157130653Srwatson SOCK_UNLOCK(so); 158130653Srwatson SOCKBUF_LOCK(&so->so_rcv); 1591541Srgrimes so->so_rcv.sb_flags &= ~SB_ASYNC; 160130653Srwatson SOCKBUF_UNLOCK(&so->so_rcv); 161130653Srwatson SOCKBUF_LOCK(&so->so_snd); 1621541Srgrimes so->so_snd.sb_flags &= ~SB_ASYNC; 163130653Srwatson SOCKBUF_UNLOCK(&so->so_snd); 1641541Srgrimes } 165137671Sphk break; 1661541Srgrimes 1671541Srgrimes case FIONREAD: 168130796Srwatson /* Unlocked read. */ 1691541Srgrimes *(int *)data = so->so_rcv.sb_cc; 170137671Sphk break; 1711541Srgrimes 172195134Sphk case FIONWRITE: 173195134Sphk /* Unlocked read. */ 174195134Sphk *(int *)data = so->so_snd.sb_cc; 175195134Sphk break; 176195134Sphk 177195191Semaste case FIONSPACE: 178195191Semaste if ((so->so_snd.sb_hiwat < so->so_snd.sb_cc) || 179195191Semaste (so->so_snd.sb_mbmax < so->so_snd.sb_mbcnt)) 180195191Semaste *(int *)data = 0; 181195191Semaste else 182195191Semaste *(int *)data = sbspace(&so->so_snd); 183195191Semaste break; 184195191Semaste 18541086Struckman case FIOSETOWN: 186137671Sphk error = fsetown(*(int *)data, &so->so_sigio); 187137671Sphk break; 18841086Struckman 18941086Struckman case FIOGETOWN: 190104393Struckman *(int *)data = fgetown(&so->so_sigio); 191137671Sphk break; 1921541Srgrimes 19341086Struckman case SIOCSPGRP: 194137671Sphk error = fsetown(-(*(int *)data), &so->so_sigio); 195137671Sphk break; 19641086Struckman 1971541Srgrimes case SIOCGPGRP: 198104393Struckman *(int *)data = -fgetown(&so->so_sigio); 199137671Sphk break; 2001541Srgrimes 2011541Srgrimes case SIOCATMARK: 202130796Srwatson /* Unlocked read. */ 203130480Srwatson *(int *)data = (so->so_rcv.sb_state & SBS_RCVATMARK) != 0; 204137671Sphk break; 205137671Sphk default: 206137671Sphk /* 207167206Srwatson * Interface/routing/protocol specific ioctls: interface and 208167206Srwatson * routing ioctls should have a different entry since a 209167206Srwatson * socket is unnecessary. 210137671Sphk */ 211137671Sphk if (IOCGROUP(cmd) == 'i') 212137671Sphk error = ifioctl(so, cmd, data, td); 213218757Sbz else if (IOCGROUP(cmd) == 'r') { 214218757Sbz CURVNET_SET(so->so_vnet); 215178888Sjulian error = rtioctl_fib(cmd, data, so->so_fibnum); 216218757Sbz CURVNET_RESTORE(); 217218757Sbz } else { 218218757Sbz CURVNET_SET(so->so_vnet); 219137671Sphk error = ((*so->so_proto->pr_usrreqs->pru_control) 220137671Sphk (so, cmd, data, 0, td)); 221218757Sbz CURVNET_RESTORE(); 222218757Sbz } 223137671Sphk break; 2241541Srgrimes } 225171744Srwatson return (error); 2261541Srgrimes} 2271541Srgrimes 2281549Srgrimesint 229167206Srwatsonsoo_poll(struct file *fp, int events, struct ucred *active_cred, 230167206Srwatson struct thread *td) 2311541Srgrimes{ 232109153Sdillon struct socket *so = fp->f_data; 233171744Srwatson#ifdef MAC 234137671Sphk int error; 235137671Sphk 236172930Srwatson error = mac_socket_check_poll(active_cred, so); 237171744Srwatson if (error) 238145167Srwatson return (error); 239145167Srwatson#endif 240171744Srwatson return (sopoll(so, events, fp->f_cred, td)); 2411541Srgrimes} 2421541Srgrimes 2431549Srgrimesint 244167206Srwatsonsoo_stat(struct file *fp, struct stat *ub, struct ucred *active_cred, 245167206Srwatson struct thread *td) 2461541Srgrimes{ 247109153Sdillon struct socket *so = fp->f_data; 248171744Srwatson#ifdef MAC 249132554Srwatson int error; 250171744Srwatson#endif 2511541Srgrimes 2521541Srgrimes bzero((caddr_t)ub, sizeof (*ub)); 25362425Schris ub->st_mode = S_IFSOCK; 254145167Srwatson#ifdef MAC 255172930Srwatson error = mac_socket_check_stat(active_cred, so); 256171744Srwatson if (error) 257145167Srwatson return (error); 258145167Srwatson#endif 25962425Schris /* 260130480Srwatson * If SBS_CANTRCVMORE is set, but there's still data left in the 26162425Schris * receive buffer, the socket is still readable. 26262425Schris */ 263183661Srwatson SOCKBUF_LOCK(&so->so_rcv); 264130480Srwatson if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) == 0 || 26562425Schris so->so_rcv.sb_cc != 0) 26662425Schris ub->st_mode |= S_IRUSR | S_IRGRP | S_IROTH; 267183661Srwatson ub->st_size = so->so_rcv.sb_cc - so->so_rcv.sb_ctl; 268183661Srwatson SOCKBUF_UNLOCK(&so->so_rcv); 269183661Srwatson /* Unlocked read. */ 270130480Srwatson if ((so->so_snd.sb_state & SBS_CANTSENDMORE) == 0) 27162425Schris ub->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; 27260405Schris ub->st_uid = so->so_cred->cr_uid; 27360405Schris ub->st_gid = so->so_cred->cr_gid; 274171744Srwatson return (*so->so_proto->pr_usrreqs->pru_sense)(so, ub); 2751541Srgrimes} 2761541Srgrimes 27786487Sdillon/* 278167206Srwatson * API socket close on file pointer. We call soclose() to close the socket 279167206Srwatson * (including initiating closing protocols). soclose() will sorele() the 280167206Srwatson * file reference but the actual socket will not go away until the socket's 281167206Srwatson * ref count hits 0. 28286487Sdillon */ 2831541Srgrimes/* ARGSUSED */ 28443408Snewtonint 285167206Srwatsonsoo_close(struct file *fp, struct thread *td) 2861541Srgrimes{ 2871541Srgrimes int error = 0; 28886487Sdillon struct socket *so; 2891541Srgrimes 290109153Sdillon so = fp->f_data; 29149413Sgreen fp->f_ops = &badfileops; 292109153Sdillon fp->f_data = NULL; 29389306Salfred 29489306Salfred if (so) 29586487Sdillon error = soclose(so); 2961541Srgrimes return (error); 2971541Srgrimes} 298