raw_usrreq.c revision 183550
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: head/sys/net/raw_usrreq.c 183550 2008-10-02 15:37:58Z zec $ 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> 47181803Sbz#include <sys/vimage.h> 481541Srgrimes 49183550Szec#include <net/if.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{ 60183550Szec INIT_VNET_NET(curvnet); 61130514Srwatson 62181803Sbz LIST_INIT(&V_rawcb_list); 631541Srgrimes} 641541Srgrimes 651541Srgrimes/* 66180305Srwatson * Raw protocol input routine. Find the socket associated with the packet(s) 67180305Srwatson * and move them over. If nothing exists for this packet, drop it. 681541Srgrimes */ 691541Srgrimes/* 701541Srgrimes * Raw protocol interface. 711541Srgrimes */ 721541Srgrimesvoid 73180385Srwatsonraw_input(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src) 741541Srgrimes{ 75183550Szec INIT_VNET_NET(curvnet); 76180305Srwatson struct rawcb *rp; 77180305Srwatson struct mbuf *m = m0; 781541Srgrimes struct socket *last; 791541Srgrimes 80107113Sluigi last = 0; 81130514Srwatson mtx_lock(&rawcb_mtx); 82181803Sbz LIST_FOREACH(rp, &V_rawcb_list, list) { 831541Srgrimes if (rp->rcb_proto.sp_family != proto->sp_family) 841541Srgrimes continue; 851541Srgrimes if (rp->rcb_proto.sp_protocol && 861541Srgrimes rp->rcb_proto.sp_protocol != proto->sp_protocol) 871541Srgrimes continue; 881541Srgrimes if (last) { 89107113Sluigi struct mbuf *n; 90107113Sluigi n = m_copy(m, 0, (int)M_COPYALL); 913443Sphk if (n) { 921541Srgrimes if (sbappendaddr(&last->so_rcv, src, 93107113Sluigi n, (struct mbuf *)0) == 0) 941541Srgrimes /* should notify about lost packet */ 951541Srgrimes m_freem(n); 96180305Srwatson else 971541Srgrimes sorwakeup(last); 981541Srgrimes } 991541Srgrimes } 1001541Srgrimes last = rp->rcb_socket; 1011541Srgrimes } 1021541Srgrimes if (last) { 103107113Sluigi if (sbappendaddr(&last->so_rcv, src, 104107113Sluigi m, (struct mbuf *)0) == 0) 1051541Srgrimes m_freem(m); 106180305Srwatson else 1071541Srgrimes sorwakeup(last); 1081541Srgrimes } else 1091541Srgrimes m_freem(m); 110130514Srwatson mtx_unlock(&rawcb_mtx); 1111541Srgrimes} 1121541Srgrimes 1131541Srgrimes/*ARGSUSED*/ 1141541Srgrimesvoid 115180305Srwatsonraw_ctlinput(int cmd, struct sockaddr *arg, void *dummy) 1161541Srgrimes{ 1171541Srgrimes 118119995Sru if (cmd < 0 || cmd >= PRC_NCMDS) 1191541Srgrimes return; 1201541Srgrimes /* INCOMPLETE */ 1211541Srgrimes} 1221541Srgrimes 123157366Srwatsonstatic void 12425201Swollmanraw_uabort(struct socket *so) 1251541Srgrimes{ 1261541Srgrimes 127180385Srwatson KASSERT(sotorawcb(so) != NULL, ("raw_uabort: rp == NULL")); 128180385Srwatson 129130387Srwatson soisdisconnected(so); 13025201Swollman} 1311541Srgrimes 132160549Srwatsonstatic void 133160549Srwatsonraw_uclose(struct socket *so) 134160549Srwatson{ 135160549Srwatson 136180385Srwatson KASSERT(sotorawcb(so) != NULL, ("raw_uabort: rp == NULL")); 137180385Srwatson 138160549Srwatson soisdisconnected(so); 139160549Srwatson} 140160549Srwatson 14125201Swollman/* pru_accept is EOPNOTSUPP */ 1421541Srgrimes 14325201Swollmanstatic int 14483366Sjulianraw_uattach(struct socket *so, int proto, struct thread *td) 14525201Swollman{ 14625201Swollman int error; 1471541Srgrimes 148157604Srwatson /* 149157604Srwatson * Implementors of raw sockets will already have allocated the PCB, 150180385Srwatson * so it must be non-NULL here. 151157604Srwatson */ 152157604Srwatson KASSERT(sotorawcb(so) != NULL, ("raw_uattach: so_pcb == NULL")); 153157604Srwatson 154164033Srwatson if (td != NULL) { 155164033Srwatson error = priv_check(td, PRIV_NET_RAW); 156164033Srwatson if (error) 157180385Srwatson return (error); 158164033Srwatson } 159180385Srwatson return (raw_attach(so, proto)); 16025201Swollman} 1611541Srgrimes 16225201Swollmanstatic int 16383366Sjulianraw_ubind(struct socket *so, struct sockaddr *nam, struct thread *td) 16425201Swollman{ 165180305Srwatson 166180305Srwatson return (EINVAL); 16725201Swollman} 1681541Srgrimes 16925201Swollmanstatic int 17083366Sjulianraw_uconnect(struct socket *so, struct sockaddr *nam, struct thread *td) 17125201Swollman{ 172180305Srwatson 173180305Srwatson return (EINVAL); 17425201Swollman} 1751541Srgrimes 17625201Swollman/* pru_connect2 is EOPNOTSUPP */ 17725201Swollman/* pru_control is EOPNOTSUPP */ 1781541Srgrimes 179157370Srwatsonstatic void 18025201Swollmanraw_udetach(struct socket *so) 18125201Swollman{ 18225201Swollman struct rawcb *rp = sotorawcb(so); 1831541Srgrimes 184157372Srwatson KASSERT(rp != NULL, ("raw_udetach: rp == NULL")); 185180385Srwatson 18625201Swollman raw_detach(rp); 18725201Swollman} 1881541Srgrimes 18925201Swollmanstatic int 19025201Swollmanraw_udisconnect(struct socket *so) 19125201Swollman{ 1921541Srgrimes 193180385Srwatson KASSERT(sotorawcb(so) != NULL, ("raw_udisconnect: rp == NULL")); 194180385Srwatson 195180385Srwatson return (ENOTCONN); 19625201Swollman} 1971541Srgrimes 19825201Swollman/* pru_listen is EOPNOTSUPP */ 1991541Srgrimes 20025201Swollmanstatic int 20128270Swollmanraw_upeeraddr(struct socket *so, struct sockaddr **nam) 20225201Swollman{ 2031541Srgrimes 204180385Srwatson KASSERT(sotorawcb(so) != NULL, ("raw_upeeraddr: rp == NULL")); 205180385Srwatson 206180385Srwatson return (ENOTCONN); 20725201Swollman} 2081541Srgrimes 20925201Swollman/* pru_rcvd is EOPNOTSUPP */ 21025201Swollman/* pru_rcvoob is EOPNOTSUPP */ 21125201Swollman 21225201Swollmanstatic int 213180305Srwatsonraw_usend(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, 214180305Srwatson struct mbuf *control, struct thread *td) 21525201Swollman{ 21625201Swollman 217180385Srwatson KASSERT(sotorawcb(so) != NULL, ("raw_usend: rp == NULL")); 21825201Swollman 219180385Srwatson if ((flags & PRUS_OOB) || (control && control->m_len)) { 220180385Srwatson /* XXXRW: Should control also be freed here? */ 221180385Srwatson if (m != NULL) 222180385Srwatson m_freem(m); 223180385Srwatson return (EOPNOTSUPP); 22425201Swollman } 22525201Swollman 226180385Srwatson /* 227180385Srwatson * For historical (bad?) reasons, we effectively ignore the address 228180385Srwatson * argument to sendto(2). Perhaps we should return an error instead? 229180385Srwatson */ 230180385Srwatson return ((*so->so_proto->pr_output)(m, so)); 2311541Srgrimes} 23225201Swollman 23325201Swollman/* pru_sense is null */ 23425201Swollman 23525201Swollmanstatic int 23625201Swollmanraw_ushutdown(struct socket *so) 23725201Swollman{ 23825201Swollman 239157372Srwatson KASSERT(sotorawcb(so) != NULL, ("raw_ushutdown: rp == NULL")); 240180385Srwatson 24125201Swollman socantsendmore(so); 242180305Srwatson return (0); 24325201Swollman} 24425201Swollman 24525201Swollmanstatic int 24628270Swollmanraw_usockaddr(struct socket *so, struct sockaddr **nam) 24725201Swollman{ 24825201Swollman 249180385Srwatson KASSERT(sotorawcb(so) != NULL, ("raw_usockaddr: rp == NULL")); 250180385Srwatson 251180385Srwatson return (EINVAL); 25225201Swollman} 25325201Swollman 25425201Swollmanstruct pr_usrreqs raw_usrreqs = { 255137386Sphk .pru_abort = raw_uabort, 256137386Sphk .pru_attach = raw_uattach, 257137386Sphk .pru_bind = raw_ubind, 258137386Sphk .pru_connect = raw_uconnect, 259137386Sphk .pru_detach = raw_udetach, 260137386Sphk .pru_disconnect = raw_udisconnect, 261137386Sphk .pru_peeraddr = raw_upeeraddr, 262137386Sphk .pru_send = raw_usend, 263137386Sphk .pru_shutdown = raw_ushutdown, 264137386Sphk .pru_sockaddr = raw_usockaddr, 265160549Srwatson .pru_close = raw_uclose, 26625201Swollman}; 267