1139823Simp/*- 21541Srgrimes * Copyright (c) 1980, 1986, 1993 3180305Srwatson * The Regents of the University of California. 4180305Srwatson * All rights reserved. 51541Srgrimes * 61541Srgrimes * Redistribution and use in source and binary forms, with or without 71541Srgrimes * modification, are permitted provided that the following conditions 81541Srgrimes * are met: 91541Srgrimes * 1. Redistributions of source code must retain the above copyright 101541Srgrimes * notice, this list of conditions and the following disclaimer. 111541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 121541Srgrimes * notice, this list of conditions and the following disclaimer in the 131541Srgrimes * documentation and/or other materials provided with the distribution. 141541Srgrimes * 4. Neither the name of the University nor the names of its contributors 151541Srgrimes * may be used to endorse or promote products derived from this software 161541Srgrimes * without specific prior written permission. 171541Srgrimes * 181541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 191541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 201541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 211541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 221541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 231541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 241541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 251541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 261541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 271541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 281541Srgrimes * SUCH DAMAGE. 291541Srgrimes * 301541Srgrimes * @(#)raw_usrreq.c 8.1 (Berkeley) 6/10/93 3150477Speter * $FreeBSD: releng/11.0/sys/net/raw_usrreq.c 298075 2016-04-15 17:30:33Z pfg $ 321541Srgrimes */ 331541Srgrimes 341541Srgrimes#include <sys/param.h> 35130514Srwatson#include <sys/kernel.h> 3695759Stanimura#include <sys/lock.h> 37126425Srwatson#include <sys/malloc.h> 381541Srgrimes#include <sys/mbuf.h> 39130387Srwatson#include <sys/mutex.h> 40164033Srwatson#include <sys/priv.h> 411541Srgrimes#include <sys/protosw.h> 4295759Stanimura#include <sys/signalvar.h> 431541Srgrimes#include <sys/socket.h> 441541Srgrimes#include <sys/socketvar.h> 4595759Stanimura#include <sys/sx.h> 4695759Stanimura#include <sys/systm.h> 471541Srgrimes 48183550Szec#include <net/if.h> 49257135Sglebius#include <net/vnet.h> 501541Srgrimes#include <net/raw_cb.h> 511541Srgrimes 52130514SrwatsonMTX_SYSINIT(rawcb_mtx, &rawcb_mtx, "rawcb", MTX_DEF); 53130514Srwatson 541541Srgrimes/* 551541Srgrimes * Initialize raw connection block q. 561541Srgrimes */ 571541Srgrimesvoid 58180305Srwatsonraw_init(void) 591541Srgrimes{ 60130514Srwatson 61181803Sbz LIST_INIT(&V_rawcb_list); 621541Srgrimes} 631541Srgrimes 641541Srgrimes/* 65180305Srwatson * Raw protocol input routine. Find the socket associated with the packet(s) 66180305Srwatson * and move them over. If nothing exists for this packet, drop it. 671541Srgrimes */ 681541Srgrimes/* 691541Srgrimes * Raw protocol interface. 701541Srgrimes */ 711541Srgrimesvoid 72180385Srwatsonraw_input(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src) 731541Srgrimes{ 74225837Sbz 75225837Sbz return (raw_input_ext(m0, proto, src, NULL)); 76225837Sbz} 77225837Sbz 78225837Sbzvoid 79225837Sbzraw_input_ext(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src, 80225837Sbz raw_input_cb_fn cb) 81225837Sbz{ 82180305Srwatson struct rawcb *rp; 83180305Srwatson struct mbuf *m = m0; 841541Srgrimes struct socket *last; 851541Srgrimes 86298075Spfg last = NULL; 87130514Srwatson mtx_lock(&rawcb_mtx); 88181803Sbz LIST_FOREACH(rp, &V_rawcb_list, list) { 891541Srgrimes if (rp->rcb_proto.sp_family != proto->sp_family) 901541Srgrimes continue; 911541Srgrimes if (rp->rcb_proto.sp_protocol && 921541Srgrimes rp->rcb_proto.sp_protocol != proto->sp_protocol) 931541Srgrimes continue; 94225837Sbz if (cb != NULL && (*cb)(m, proto, src, rp) != 0) 95225837Sbz continue; 961541Srgrimes if (last) { 97107113Sluigi struct mbuf *n; 98107113Sluigi n = m_copy(m, 0, (int)M_COPYALL); 993443Sphk if (n) { 1001541Srgrimes if (sbappendaddr(&last->so_rcv, src, 101107113Sluigi n, (struct mbuf *)0) == 0) 1021541Srgrimes /* should notify about lost packet */ 1031541Srgrimes m_freem(n); 104180305Srwatson else 1051541Srgrimes sorwakeup(last); 1061541Srgrimes } 1071541Srgrimes } 1081541Srgrimes last = rp->rcb_socket; 1091541Srgrimes } 1101541Srgrimes if (last) { 111107113Sluigi if (sbappendaddr(&last->so_rcv, src, 112107113Sluigi m, (struct mbuf *)0) == 0) 1131541Srgrimes m_freem(m); 114180305Srwatson else 1151541Srgrimes sorwakeup(last); 1161541Srgrimes } else 1171541Srgrimes m_freem(m); 118130514Srwatson mtx_unlock(&rawcb_mtx); 1191541Srgrimes} 1201541Srgrimes 1211541Srgrimes/*ARGSUSED*/ 1221541Srgrimesvoid 123180305Srwatsonraw_ctlinput(int cmd, struct sockaddr *arg, void *dummy) 1241541Srgrimes{ 1251541Srgrimes 126119995Sru if (cmd < 0 || cmd >= PRC_NCMDS) 1271541Srgrimes return; 1281541Srgrimes /* INCOMPLETE */ 1291541Srgrimes} 1301541Srgrimes 131157366Srwatsonstatic void 13225201Swollmanraw_uabort(struct socket *so) 1331541Srgrimes{ 1341541Srgrimes 135180385Srwatson KASSERT(sotorawcb(so) != NULL, ("raw_uabort: rp == NULL")); 136180385Srwatson 137130387Srwatson soisdisconnected(so); 13825201Swollman} 1391541Srgrimes 140160549Srwatsonstatic void 141160549Srwatsonraw_uclose(struct socket *so) 142160549Srwatson{ 143160549Srwatson 144180385Srwatson KASSERT(sotorawcb(so) != NULL, ("raw_uabort: rp == NULL")); 145180385Srwatson 146160549Srwatson soisdisconnected(so); 147160549Srwatson} 148160549Srwatson 14925201Swollman/* pru_accept is EOPNOTSUPP */ 1501541Srgrimes 15125201Swollmanstatic int 15283366Sjulianraw_uattach(struct socket *so, int proto, struct thread *td) 15325201Swollman{ 15425201Swollman int error; 1551541Srgrimes 156157604Srwatson /* 157157604Srwatson * Implementors of raw sockets will already have allocated the PCB, 158180385Srwatson * so it must be non-NULL here. 159157604Srwatson */ 160157604Srwatson KASSERT(sotorawcb(so) != NULL, ("raw_uattach: so_pcb == NULL")); 161157604Srwatson 162164033Srwatson if (td != NULL) { 163164033Srwatson error = priv_check(td, PRIV_NET_RAW); 164164033Srwatson if (error) 165180385Srwatson return (error); 166164033Srwatson } 167180385Srwatson return (raw_attach(so, proto)); 16825201Swollman} 1691541Srgrimes 17025201Swollmanstatic int 17183366Sjulianraw_ubind(struct socket *so, struct sockaddr *nam, struct thread *td) 17225201Swollman{ 173180305Srwatson 174180305Srwatson return (EINVAL); 17525201Swollman} 1761541Srgrimes 17725201Swollmanstatic int 17883366Sjulianraw_uconnect(struct socket *so, struct sockaddr *nam, struct thread *td) 17925201Swollman{ 180180305Srwatson 181180305Srwatson return (EINVAL); 18225201Swollman} 1831541Srgrimes 18425201Swollman/* pru_connect2 is EOPNOTSUPP */ 18525201Swollman/* pru_control is EOPNOTSUPP */ 1861541Srgrimes 187157370Srwatsonstatic void 18825201Swollmanraw_udetach(struct socket *so) 18925201Swollman{ 19025201Swollman struct rawcb *rp = sotorawcb(so); 1911541Srgrimes 192157372Srwatson KASSERT(rp != NULL, ("raw_udetach: rp == NULL")); 193180385Srwatson 19425201Swollman raw_detach(rp); 19525201Swollman} 1961541Srgrimes 19725201Swollmanstatic int 19825201Swollmanraw_udisconnect(struct socket *so) 19925201Swollman{ 2001541Srgrimes 201180385Srwatson KASSERT(sotorawcb(so) != NULL, ("raw_udisconnect: rp == NULL")); 202180385Srwatson 203180385Srwatson return (ENOTCONN); 20425201Swollman} 2051541Srgrimes 20625201Swollman/* pru_listen is EOPNOTSUPP */ 2071541Srgrimes 20825201Swollmanstatic int 20928270Swollmanraw_upeeraddr(struct socket *so, struct sockaddr **nam) 21025201Swollman{ 2111541Srgrimes 212180385Srwatson KASSERT(sotorawcb(so) != NULL, ("raw_upeeraddr: rp == NULL")); 213180385Srwatson 214180385Srwatson return (ENOTCONN); 21525201Swollman} 2161541Srgrimes 21725201Swollman/* pru_rcvd is EOPNOTSUPP */ 21825201Swollman/* pru_rcvoob is EOPNOTSUPP */ 21925201Swollman 22025201Swollmanstatic int 221180305Srwatsonraw_usend(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, 222180305Srwatson struct mbuf *control, struct thread *td) 22325201Swollman{ 22425201Swollman 225180385Srwatson KASSERT(sotorawcb(so) != NULL, ("raw_usend: rp == NULL")); 22625201Swollman 227180385Srwatson if ((flags & PRUS_OOB) || (control && control->m_len)) { 228180385Srwatson /* XXXRW: Should control also be freed here? */ 229180385Srwatson if (m != NULL) 230180385Srwatson m_freem(m); 231180385Srwatson return (EOPNOTSUPP); 23225201Swollman } 23325201Swollman 234180385Srwatson /* 235180385Srwatson * For historical (bad?) reasons, we effectively ignore the address 236180385Srwatson * argument to sendto(2). Perhaps we should return an error instead? 237180385Srwatson */ 238180385Srwatson return ((*so->so_proto->pr_output)(m, so)); 2391541Srgrimes} 24025201Swollman 24125201Swollman/* pru_sense is null */ 24225201Swollman 24325201Swollmanstatic int 24425201Swollmanraw_ushutdown(struct socket *so) 24525201Swollman{ 24625201Swollman 247157372Srwatson KASSERT(sotorawcb(so) != NULL, ("raw_ushutdown: rp == NULL")); 248180385Srwatson 24925201Swollman socantsendmore(so); 250180305Srwatson return (0); 25125201Swollman} 25225201Swollman 25325201Swollmanstatic int 25428270Swollmanraw_usockaddr(struct socket *so, struct sockaddr **nam) 25525201Swollman{ 25625201Swollman 257180385Srwatson KASSERT(sotorawcb(so) != NULL, ("raw_usockaddr: rp == NULL")); 258180385Srwatson 259180385Srwatson return (EINVAL); 26025201Swollman} 26125201Swollman 26225201Swollmanstruct pr_usrreqs raw_usrreqs = { 263137386Sphk .pru_abort = raw_uabort, 264137386Sphk .pru_attach = raw_uattach, 265137386Sphk .pru_bind = raw_ubind, 266137386Sphk .pru_connect = raw_uconnect, 267137386Sphk .pru_detach = raw_udetach, 268137386Sphk .pru_disconnect = raw_udisconnect, 269137386Sphk .pru_peeraddr = raw_upeeraddr, 270137386Sphk .pru_send = raw_usend, 271137386Sphk .pru_shutdown = raw_ushutdown, 272137386Sphk .pru_sockaddr = raw_usockaddr, 273160549Srwatson .pru_close = raw_uclose, 27425201Swollman}; 275