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, 69116546Sphk .fo_flags = DFLAG_PASSABLE 7072521Sjlemon}; 711541Srgrimes 721541Srgrimes/* ARGSUSED */ 7343408Snewtonint 74167206Srwatsonsoo_read(struct file *fp, struct uio *uio, struct ucred *active_cred, 75167206Srwatson int flags, struct thread *td) 761541Srgrimes{ 77109153Sdillon struct socket *so = fp->f_data; 7892310Salfred int error; 7992310Salfred 80191816Szec#ifdef MAC 81172930Srwatson error = mac_socket_check_receive(active_cred, so); 82171744Srwatson if (error) 83104571Srwatson return (error); 84104571Srwatson#endif 85191816Szec error = soreceive(so, 0, uio, 0, 0, 0); 86191816Szec return (error); 871541Srgrimes} 881541Srgrimes 891541Srgrimes/* ARGSUSED */ 9043408Snewtonint 91167206Srwatsonsoo_write(struct file *fp, struct uio *uio, struct ucred *active_cred, 92167206Srwatson int flags, struct thread *td) 931541Srgrimes{ 94109153Sdillon struct socket *so = fp->f_data; 9592310Salfred int error; 9692310Salfred 97104571Srwatson#ifdef MAC 98172930Srwatson error = mac_socket_check_send(active_cred, so); 99171744Srwatson if (error) 100104571Srwatson return (error); 101104571Srwatson#endif 102160619Srwatson error = sosend(so, 0, uio, 0, 0, 0, uio->uio_td); 103143417Srwatson if (error == EPIPE && (so->so_options & SO_NOSIGPIPE) == 0) { 104143417Srwatson PROC_LOCK(uio->uio_td->td_proc); 105209595Sjhb tdsignal(uio->uio_td, SIGPIPE); 106143417Srwatson PROC_UNLOCK(uio->uio_td->td_proc); 107143417Srwatson } 10892310Salfred return (error); 1091541Srgrimes} 1101541Srgrimes 1111549Srgrimesint 112175140Sjhbsoo_truncate(struct file *fp, off_t length, struct ucred *active_cred, 113175140Sjhb struct thread *td) 114175140Sjhb{ 115175140Sjhb 116175140Sjhb return (EINVAL); 117175140Sjhb} 118175140Sjhb 119175140Sjhbint 120167206Srwatsonsoo_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *active_cred, 121167206Srwatson struct thread *td) 1221541Srgrimes{ 123137671Sphk struct socket *so = fp->f_data; 124137671Sphk int error = 0; 1251541Srgrimes 1261541Srgrimes switch (cmd) { 1271541Srgrimes case FIONBIO: 128130653Srwatson SOCK_LOCK(so); 1291541Srgrimes if (*(int *)data) 1301541Srgrimes so->so_state |= SS_NBIO; 1311541Srgrimes else 1321541Srgrimes so->so_state &= ~SS_NBIO; 133130653Srwatson SOCK_UNLOCK(so); 134137671Sphk break; 1351541Srgrimes 1361541Srgrimes case FIOASYNC: 137130653Srwatson /* 138167206Srwatson * XXXRW: This code separately acquires SOCK_LOCK(so) and 139167206Srwatson * SOCKBUF_LOCK(&so->so_rcv) even though they are the same 140167206Srwatson * mutex to avoid introducing the assumption that they are 141167206Srwatson * the same. 142130653Srwatson */ 1431541Srgrimes if (*(int *)data) { 144130653Srwatson SOCK_LOCK(so); 1451541Srgrimes so->so_state |= SS_ASYNC; 146130653Srwatson SOCK_UNLOCK(so); 147130653Srwatson SOCKBUF_LOCK(&so->so_rcv); 1481541Srgrimes so->so_rcv.sb_flags |= SB_ASYNC; 149130653Srwatson SOCKBUF_UNLOCK(&so->so_rcv); 150130653Srwatson SOCKBUF_LOCK(&so->so_snd); 1511541Srgrimes so->so_snd.sb_flags |= SB_ASYNC; 152130653Srwatson SOCKBUF_UNLOCK(&so->so_snd); 1531541Srgrimes } else { 154130653Srwatson SOCK_LOCK(so); 1551541Srgrimes so->so_state &= ~SS_ASYNC; 156130653Srwatson SOCK_UNLOCK(so); 157130653Srwatson SOCKBUF_LOCK(&so->so_rcv); 1581541Srgrimes so->so_rcv.sb_flags &= ~SB_ASYNC; 159130653Srwatson SOCKBUF_UNLOCK(&so->so_rcv); 160130653Srwatson SOCKBUF_LOCK(&so->so_snd); 1611541Srgrimes so->so_snd.sb_flags &= ~SB_ASYNC; 162130653Srwatson SOCKBUF_UNLOCK(&so->so_snd); 1631541Srgrimes } 164137671Sphk break; 1651541Srgrimes 1661541Srgrimes case FIONREAD: 167130796Srwatson /* Unlocked read. */ 1681541Srgrimes *(int *)data = so->so_rcv.sb_cc; 169137671Sphk break; 1701541Srgrimes 171195134Sphk case FIONWRITE: 172195134Sphk /* Unlocked read. */ 173195134Sphk *(int *)data = so->so_snd.sb_cc; 174195134Sphk break; 175195134Sphk 176195191Semaste case FIONSPACE: 177195191Semaste if ((so->so_snd.sb_hiwat < so->so_snd.sb_cc) || 178195191Semaste (so->so_snd.sb_mbmax < so->so_snd.sb_mbcnt)) 179195191Semaste *(int *)data = 0; 180195191Semaste else 181195191Semaste *(int *)data = sbspace(&so->so_snd); 182195191Semaste break; 183195191Semaste 18441086Struckman case FIOSETOWN: 185137671Sphk error = fsetown(*(int *)data, &so->so_sigio); 186137671Sphk break; 18741086Struckman 18841086Struckman case FIOGETOWN: 189104393Struckman *(int *)data = fgetown(&so->so_sigio); 190137671Sphk break; 1911541Srgrimes 19241086Struckman case SIOCSPGRP: 193137671Sphk error = fsetown(-(*(int *)data), &so->so_sigio); 194137671Sphk break; 19541086Struckman 1961541Srgrimes case SIOCGPGRP: 197104393Struckman *(int *)data = -fgetown(&so->so_sigio); 198137671Sphk break; 1991541Srgrimes 2001541Srgrimes case SIOCATMARK: 201130796Srwatson /* Unlocked read. */ 202130480Srwatson *(int *)data = (so->so_rcv.sb_state & SBS_RCVATMARK) != 0; 203137671Sphk break; 204137671Sphk default: 205137671Sphk /* 206167206Srwatson * Interface/routing/protocol specific ioctls: interface and 207167206Srwatson * routing ioctls should have a different entry since a 208167206Srwatson * socket is unnecessary. 209137671Sphk */ 210137671Sphk if (IOCGROUP(cmd) == 'i') 211137671Sphk error = ifioctl(so, cmd, data, td); 212218757Sbz else if (IOCGROUP(cmd) == 'r') { 213218757Sbz CURVNET_SET(so->so_vnet); 214178888Sjulian error = rtioctl_fib(cmd, data, so->so_fibnum); 215218757Sbz CURVNET_RESTORE(); 216218757Sbz } else { 217218757Sbz CURVNET_SET(so->so_vnet); 218137671Sphk error = ((*so->so_proto->pr_usrreqs->pru_control) 219137671Sphk (so, cmd, data, 0, td)); 220218757Sbz CURVNET_RESTORE(); 221218757Sbz } 222137671Sphk break; 2231541Srgrimes } 224171744Srwatson return (error); 2251541Srgrimes} 2261541Srgrimes 2271549Srgrimesint 228167206Srwatsonsoo_poll(struct file *fp, int events, struct ucred *active_cred, 229167206Srwatson struct thread *td) 2301541Srgrimes{ 231109153Sdillon struct socket *so = fp->f_data; 232171744Srwatson#ifdef MAC 233137671Sphk int error; 234137671Sphk 235172930Srwatson error = mac_socket_check_poll(active_cred, so); 236171744Srwatson if (error) 237145167Srwatson return (error); 238145167Srwatson#endif 239171744Srwatson return (sopoll(so, events, fp->f_cred, td)); 2401541Srgrimes} 2411541Srgrimes 2421549Srgrimesint 243167206Srwatsonsoo_stat(struct file *fp, struct stat *ub, struct ucred *active_cred, 244167206Srwatson struct thread *td) 2451541Srgrimes{ 246109153Sdillon struct socket *so = fp->f_data; 247171744Srwatson#ifdef MAC 248132554Srwatson int error; 249171744Srwatson#endif 2501541Srgrimes 2511541Srgrimes bzero((caddr_t)ub, sizeof (*ub)); 25262425Schris ub->st_mode = S_IFSOCK; 253145167Srwatson#ifdef MAC 254172930Srwatson error = mac_socket_check_stat(active_cred, so); 255171744Srwatson if (error) 256145167Srwatson return (error); 257145167Srwatson#endif 25862425Schris /* 259130480Srwatson * If SBS_CANTRCVMORE is set, but there's still data left in the 26062425Schris * receive buffer, the socket is still readable. 26162425Schris */ 262183661Srwatson SOCKBUF_LOCK(&so->so_rcv); 263130480Srwatson if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) == 0 || 26462425Schris so->so_rcv.sb_cc != 0) 26562425Schris ub->st_mode |= S_IRUSR | S_IRGRP | S_IROTH; 266183661Srwatson ub->st_size = so->so_rcv.sb_cc - so->so_rcv.sb_ctl; 267183661Srwatson SOCKBUF_UNLOCK(&so->so_rcv); 268183661Srwatson /* Unlocked read. */ 269130480Srwatson if ((so->so_snd.sb_state & SBS_CANTSENDMORE) == 0) 27062425Schris ub->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; 27160405Schris ub->st_uid = so->so_cred->cr_uid; 27260405Schris ub->st_gid = so->so_cred->cr_gid; 273171744Srwatson return (*so->so_proto->pr_usrreqs->pru_sense)(so, ub); 2741541Srgrimes} 2751541Srgrimes 27686487Sdillon/* 277167206Srwatson * API socket close on file pointer. We call soclose() to close the socket 278167206Srwatson * (including initiating closing protocols). soclose() will sorele() the 279167206Srwatson * file reference but the actual socket will not go away until the socket's 280167206Srwatson * ref count hits 0. 28186487Sdillon */ 2821541Srgrimes/* ARGSUSED */ 28343408Snewtonint 284167206Srwatsonsoo_close(struct file *fp, struct thread *td) 2851541Srgrimes{ 2861541Srgrimes int error = 0; 28786487Sdillon struct socket *so; 2881541Srgrimes 289109153Sdillon so = fp->f_data; 29049413Sgreen fp->f_ops = &badfileops; 291109153Sdillon fp->f_data = NULL; 29289306Salfred 29389306Salfred if (so) 29486487Sdillon error = soclose(so); 2951541Srgrimes return (error); 2961541Srgrimes} 297