1/* A sample version of rip_output() from /sys/netinet/raw_ip.c */ 2 3rip_output(m, so) 4 register struct mbuf *m; 5 struct socket *so; 6{ 7 register struct ip *ip; 8 int error; 9 struct rawcb *rp = sotorawcb(so); 10 struct sockaddr_in *sin; 11#if BSD>=43 12 short proto = rp->rcb_proto.sp_protocol; 13#else 14 short proto = so->so_proto->pr_protocol; 15#endif 16 /* 17 * if the protocol is IPPROTO_RAW, the user handed us a 18 * complete IP packet. Otherwise, allocate an mbuf for a 19 * header and fill it in as needed. 20 */ 21 if (proto != IPPROTO_RAW) { 22 /* 23 * Calculate data length and get an mbuf 24 * for IP header. 25 */ 26 int len = 0; 27 struct mbuf *m0; 28 29 for (m0 = m; m; m = m->m_next) 30 len += m->m_len; 31 32 m = m_get(M_DONTWAIT, MT_HEADER); 33 if (m == 0) { 34 m = m0; 35 error = ENOBUFS; 36 goto bad; 37 } 38 m->m_off = MMAXOFF - sizeof(struct ip); 39 m->m_len = sizeof(struct ip); 40 m->m_next = m0; 41 42 ip = mtod(m, struct ip *); 43 ip->ip_tos = 0; 44 ip->ip_off = 0; 45 ip->ip_p = proto; 46 ip->ip_len = sizeof(struct ip) + len; 47 ip->ip_ttl = MAXTTL; 48 } else 49 ip = mtod(m, struct ip *); 50 51 if (rp->rcb_flags & RAW_LADDR) { 52 sin = (struct sockaddr_in *)&rp->rcb_laddr; 53 if (sin->sin_family != AF_INET) { 54 error = EAFNOSUPPORT; 55 goto bad; 56 } 57 ip->ip_src.s_addr = sin->sin_addr.s_addr; 58 } else 59 ip->ip_src.s_addr = 0; 60 61 ip->ip_dst = ((struct sockaddr_in *)&rp->rcb_faddr)->sin_addr; 62 63#if BSD>=43 64 return (ip_output(m, rp->rcb_options, &rp->rcb_route, 65 (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST)); 66#else 67 return (ip_output(m, (struct mbuf *)0, &rp->rcb_route, 68 (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST)); 69#endif 70bad: 71 m_freem(m); 72 return (error); 73} 74