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