/* raw_usrreq.c 4.18 82/07/24 */
#include "../h/protosw.h"
#include "../h/socketvar.h"
#include "../net/in_systm.h"
#include "../net/raw_cb.h"
int rawqmaxlen
= IFQ_MAXLEN
;
* Initialize raw connection block q.
rawcb
.rcb_next
= rawcb
.rcb_prev
= &rawcb
;
rawintrq
.ifq_maxlen
= IFQ_MAXLEN
;
* Raw protocol interface.
raw_input(m0
, proto
, src
, dst
)
struct sockaddr
*src
, *dst
;
* Rip off an mbuf for a generic header.
m
->m_len
= sizeof(struct raw_header
);
rh
= mtod(m
, struct raw_header
*);
* Header now contains enough info to decide
* which socket to place packet in (if any).
* Queue it up for the raw protocol process
* running at software interrupt level.
IF_ENQUEUE(&rawintrq
, m
);
* Raw protocol input routine. Process packets entered
* into the queue at interrupt time. Find the socket
* associated with the packet(s) and move them over. If
* nothing exists for this packet, drop it.
register struct rawcb
*rp
;
register struct protosw
*lproto
;
register struct raw_header
*rh
;
IF_DEQUEUE(&rawintrq
, m
);
rh
= mtod(m
, struct raw_header
*);
for (rp
= rawcb
.rcb_next
; rp
!= &rawcb
; rp
= rp
->rcb_next
) {
lproto
= rp
->rcb_socket
->so_proto
;
if (lproto
->pr_family
!= rh
->raw_proto
.sp_family
)
if (lproto
->pr_protocol
&&
lproto
->pr_protocol
!= rh
->raw_proto
.sp_protocol
)
* We assume the lower level routines have
* placed the address in a canonical format
* suitable for a structure comparison.
(bcmp((caddr_t)&(a1), (caddr_t)&(a2), sizeof (struct sockaddr)) == 0)
if ((rp
->rcb_flags
& RAW_LADDR
) &&
!equal(rp
->rcb_laddr
, rh
->raw_dst
))
if ((rp
->rcb_flags
& RAW_FADDR
) &&
!equal(rp
->rcb_faddr
, rh
->raw_src
))
if ((n
= m_copy(m
->m_next
, 0, (int)M_COPYALL
)) == 0)
if (sbappendaddr(&last
->so_rcv
, &rh
->raw_src
, n
)==0) {
/* should notify about lost packet */
m
= m_free(m
); /* header */
if (sbappendaddr(&last
->so_rcv
, &rh
->raw_src
, m
) == 0)
if (cmd
< 0 || cmd
> PRC_NCMDS
)
raw_usrreq(so
, req
, m
, addr
)
register struct rawcb
*rp
= sotorawcb(so
);
if (rp
== 0 && req
!= PRU_ATTACH
)
* 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
, (struct sockaddr
*)addr
);
* 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).
if (rp
->rcb_flags
& RAW_FADDR
)
raw_connaddr(rp
, (struct sockaddr
*)addr
);
if ((rp
->rcb_flags
& RAW_FADDR
) == 0)
* Mark the connection as being incapable of further input.
* Ship a packet out. The appropriate raw output
* routine handles any massaging necessary.
if (rp
->rcb_flags
& RAW_FADDR
)
raw_connaddr(rp
, (struct sockaddr
*)addr
);
} else if ((rp
->rcb_flags
& RAW_FADDR
) == 0)
error
= (*so
->so_proto
->pr_output
)(m
, so
);
rp
->rcb_flags
&= ~RAW_FADDR
;
bcopy(addr
, (caddr_t
)&rp
->rcb_laddr
, sizeof (struct sockaddr
));