* Copyright (c) 1980, 1986 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* @(#)raw_usrreq.c 7.7 (Berkeley) %G%
#include "machine/mtpr.h"
* Initialize raw connection block q.
rawcb
.rcb_next
= rawcb
.rcb_prev
= &rawcb
;
rawintrq
.ifq_maxlen
= IFQ_MAXLEN
;
* Raw protocol input routine. Find the socket
* associated with the packet(s) and move them over. If
* nothing exists for this packet, drop it.
* Raw protocol interface.
raw_input(m0
, proto
, src
, dst
)
register struct sockproto
*proto
;
struct sockaddr
*src
, *dst
;
register struct rawcb
*rp
;
register struct mbuf
*m
= m0
;
register int sockets
= 0;
for (rp
= rawcb
.rcb_next
; rp
!= &rawcb
; rp
= rp
->rcb_next
) {
if (rp
->rcb_proto
.sp_family
!= proto
->sp_family
)
if (rp
->rcb_proto
.sp_protocol
&&
rp
->rcb_proto
.sp_protocol
!= proto
->sp_protocol
)
* We assume the lower level routines have
* placed the address in a canonical format
* suitable for a structure comparison.
* Note that if the lengths are not the same
* the comparison will fail at the first byte.
(bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0)
if (rp
->rcb_laddr
&& !equal(rp
->rcb_laddr
, dst
))
if (rp
->rcb_faddr
&& !equal(rp
->rcb_faddr
, src
))
if (n
= m_copy(m
, 0, (int)M_COPYALL
)) {
if (sbappendaddr(&last
->so_rcv
, src
,
n
, (struct mbuf
*)0) == 0)
/* should notify about lost packet */
if (sbappendaddr(&last
->so_rcv
, src
,
m
, (struct mbuf
*)0) == 0)
if (cmd
< 0 || cmd
> PRC_NCMDS
)
raw_usrreq(so
, req
, m
, nam
, rights
, control
)
struct mbuf
*m
, *nam
, *rights
, *control
;
register struct rawcb
*rp
= sotorawcb(so
);
if (rights
&& rights
->m_len
) {
* Allocate a raw control block and fill in the
* necessary info to allow packets to be routed to
* the appropriate raw interface routine.
if ((so
->so_state
& SS_PRIV
) == 0) {
error
= raw_attach(so
, (int)nam
);
* Destroy state just before socket deallocation.
* Flush data or not depending on the options.
* If a socket isn't bound to a single address,
* the raw input routine will hand it anything
* within that protocol family (assuming there's
* nothing else around it should go to).
nam
= m_copym(nam
, 0, M_COPYALL
, M_WAIT
);
rp
->rcb_faddr
= mtod(nam
, struct sockaddr
*);
error
= EINVAL
; /* XXX */
error
= raw_bind(so
, nam
);
if (rp
->rcb_faddr
== 0) {
* Mark the connection as being incapable of further input.
* Ship a packet out. The appropriate raw output
* routine handles any massaging necessary.
rp
->rcb_faddr
= mtod(nam
, struct sockaddr
*);
} else if (rp
->rcb_faddr
== 0) {
error
= (*so
->so_proto
->pr_output
)(m
, so
);
* stat: don't bother with a blocksize.
if (rp
->rcb_laddr
== 0) {
len
= rp
->rcb_laddr
->sa_len
;
bcopy((caddr_t
)rp
->rcb_laddr
, mtod(nam
, caddr_t
), (unsigned)len
);
if (rp
->rcb_faddr
== 0) {
len
= rp
->rcb_faddr
->sa_len
;
bcopy((caddr_t
)rp
->rcb_faddr
, mtod(nam
, caddr_t
), (unsigned)len
);
rawintr() {} /* XXX - referenced by locore. will soon go away */