+ register struct mbuf *m;
+ register struct ip *ip;
+ int len = 0, error;
+ struct rawcb *rp = sotorawcb(so);
+ struct sockaddr_in *sin;
+
+ /*
+ * Calculate data length and get an mbuf
+ * for IP header.
+ */
+ for (m = m0; m; m = m->m_next)
+ len += m->m_len;
+ m = m_get(M_DONTWAIT, MT_HEADER);
+ if (m == 0) {
+ error = ENOBUFS;
+ goto bad;
+ }
+
+ /*
+ * Fill in IP header as needed.
+ */
+ m->m_off = MMAXOFF - sizeof(struct ip);
+ m->m_len = sizeof(struct ip);
+ m->m_next = m0;
+ ip = mtod(m, struct ip *);
+ ip->ip_p = so->so_proto->pr_protocol;
+ ip->ip_len = sizeof(struct ip) + len;
+ if (rp->rcb_flags & RAW_LADDR) {
+ sin = (struct sockaddr_in *)&rp->rcb_laddr;
+ if (sin->sin_family != AF_INET) {
+ error = EAFNOSUPPORT;
+ goto bad;
+ }
+ ip->ip_src.s_addr = sin->sin_addr.s_addr;
+ } else
+ ip->ip_src.s_addr = 0;
+ ip->ip_dst = ((struct sockaddr_in *)&rp->rcb_faddr)->sin_addr;
+ ip->ip_ttl = MAXTTL;
+ return (ip_output(m, (struct mbuf *)0, &routetoif, 1));
+bad:
+ m_freem(m);
+ return (error);