+ rh = mtod(m, struct raw_header *);
+ last = 0;
+ 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)
+ continue;
+ if (lproto->pr_protocol &&
+ lproto->pr_protocol != rh->raw_proto.sp_protocol)
+ continue;
+ /*
+ * We assume the lower level routines have
+ * placed the address in a canonical format
+ * suitable for a structure comparison.
+ */
+#define equal(a1, a2) \
+ (bcmp((caddr_t)&(a1), (caddr_t)&(a2), sizeof (struct sockaddr)) == 0)
+ if ((rp->rcb_flags & RAW_LADDR) &&
+ !equal(rp->rcb_laddr, rh->raw_dst))
+ continue;
+ if ((rp->rcb_flags & RAW_FADDR) &&
+ !equal(rp->rcb_faddr, rh->raw_src))
+ continue;
+ if (last) {
+ struct mbuf *n;
+ if ((n = m_copy(m->m_next, 0, (int)M_COPYALL)) == 0)
+ goto nospace;
+ if (sbappendaddr(&last->so_rcv, &rh->raw_src, n)==0) {
+ /* should notify about lost packet */
+ m_freem(n);
+ goto nospace;
+ }
+ sorwakeup(last);
+ }
+nospace:
+ last = rp->rcb_socket;
+ }
+ if (last) {
+ m = m_free(m); /* header */
+ if (sbappendaddr(&last->so_rcv, &rh->raw_src, m) == 0)
+ goto drop;
+ sorwakeup(last);
+ goto next;
+ }