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