118579Sfenner/* A sample version of rip_output() from /sys/netinet/raw_ip.c */
218579Sfenner
318579Sfennerrip_output(m, so)
418579Sfenner	register struct mbuf *m;
518579Sfenner	struct socket *so;
618579Sfenner{
718579Sfenner	register struct ip *ip;
818579Sfenner	int error;
918579Sfenner	struct rawcb *rp = sotorawcb(so);
1018579Sfenner	struct sockaddr_in *sin;
1118579Sfenner#if BSD>=43
1218579Sfenner	short proto = rp->rcb_proto.sp_protocol;
1318579Sfenner#else
1418579Sfenner	short proto = so->so_proto->pr_protocol;
1518579Sfenner#endif
1618579Sfenner	/*
1718579Sfenner	 * if the protocol is IPPROTO_RAW, the user handed us a
1818579Sfenner	 * complete IP packet.  Otherwise, allocate an mbuf for a
1918579Sfenner	 * header and fill it in as needed.
2018579Sfenner	 */
2118579Sfenner	if (proto != IPPROTO_RAW) {
2218579Sfenner		/*
2318579Sfenner		 * Calculate data length and get an mbuf
2418579Sfenner		 * for IP header.
2518579Sfenner		 */
2618579Sfenner		int len = 0;
2718579Sfenner		struct mbuf *m0;
2818579Sfenner
2918579Sfenner		for (m0 = m; m; m = m->m_next)
3018579Sfenner			len += m->m_len;
3118579Sfenner
3218579Sfenner		m = m_get(M_DONTWAIT, MT_HEADER);
3318579Sfenner		if (m == 0) {
3418579Sfenner			m = m0;
3518579Sfenner			error = ENOBUFS;
3618579Sfenner			goto bad;
3718579Sfenner		}
3818579Sfenner		m->m_off = MMAXOFF - sizeof(struct ip);
3918579Sfenner		m->m_len = sizeof(struct ip);
4018579Sfenner		m->m_next = m0;
4118579Sfenner
4218579Sfenner		ip = mtod(m, struct ip *);
4318579Sfenner		ip->ip_tos = 0;
4418579Sfenner		ip->ip_off = 0;
4518579Sfenner		ip->ip_p = proto;
4618579Sfenner		ip->ip_len = sizeof(struct ip) + len;
4718579Sfenner		ip->ip_ttl = MAXTTL;
4818579Sfenner	} else
4918579Sfenner		ip = mtod(m, struct ip *);
5018579Sfenner
5118579Sfenner	if (rp->rcb_flags & RAW_LADDR) {
5218579Sfenner		sin = (struct sockaddr_in *)&rp->rcb_laddr;
5318579Sfenner		if (sin->sin_family != AF_INET) {
5418579Sfenner			error = EAFNOSUPPORT;
5518579Sfenner			goto bad;
5618579Sfenner		}
5718579Sfenner		ip->ip_src.s_addr = sin->sin_addr.s_addr;
5818579Sfenner	} else
5918579Sfenner		ip->ip_src.s_addr = 0;
6018579Sfenner
6118579Sfenner	ip->ip_dst = ((struct sockaddr_in *)&rp->rcb_faddr)->sin_addr;
6218579Sfenner
6318579Sfenner#if BSD>=43
6418579Sfenner	return (ip_output(m, rp->rcb_options, &rp->rcb_route,
6518579Sfenner	   (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST));
6618579Sfenner#else
6718579Sfenner	return (ip_output(m, (struct mbuf *)0, &rp->rcb_route,
6818579Sfenner	   (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST));
6918579Sfenner#endif
7018579Sfennerbad:
7118579Sfenner	m_freem(m);
7218579Sfenner	return (error);
7318579Sfenner}
74