1 /* raw_ip.c 6.2 83/12/15 */ 2 3 #include "../h/param.h" 4 #include "../h/mbuf.h" 5 #include "../h/socket.h" 6 #include "../h/protosw.h" 7 #include "../h/socketvar.h" 8 #include "../h/errno.h" 9 10 #include "../net/if.h" 11 #include "../net/route.h" 12 #include "../net/raw_cb.h" 13 14 #include "../netinet/in.h" 15 #include "../netinet/in_systm.h" 16 #include "../netinet/ip.h" 17 #include "../netinet/ip_var.h" 18 19 /* 20 * Raw interface to IP protocol. 21 */ 22 23 struct sockaddr_in ripdst = { AF_INET }; 24 struct sockaddr_in ripsrc = { AF_INET }; 25 struct sockproto ripproto = { PF_INET }; 26 /* 27 * Setup generic address and protocol structures 28 * for raw_input routine, then pass them along with 29 * mbuf chain. 30 */ 31 rip_input(m) 32 struct mbuf *m; 33 { 34 register struct ip *ip = mtod(m, struct ip *); 35 36 ripproto.sp_protocol = ip->ip_p; 37 ripdst.sin_addr = ip->ip_dst; 38 ripsrc.sin_addr = ip->ip_src; 39 raw_input(m, &ripproto, (struct sockaddr *)&ripsrc, 40 (struct sockaddr *)&ripdst); 41 } 42 43 /* 44 * Generate IP header and pass packet to ip_output. 45 * Tack on options user may have setup with control call. 46 */ 47 rip_output(m0, so) 48 struct mbuf *m0; 49 struct socket *so; 50 { 51 register struct mbuf *m; 52 register struct ip *ip; 53 int len = 0, error; 54 struct rawcb *rp = sotorawcb(so); 55 struct sockaddr_in *sin; 56 57 /* 58 * Calculate data length and get an mbuf 59 * for IP header. 60 */ 61 for (m = m0; m; m = m->m_next) 62 len += m->m_len; 63 m = m_get(M_DONTWAIT, MT_HEADER); 64 if (m == 0) { 65 error = ENOBUFS; 66 goto bad; 67 } 68 69 /* 70 * Fill in IP header as needed. 71 */ 72 m->m_off = MMAXOFF - sizeof(struct ip); 73 m->m_len = sizeof(struct ip); 74 m->m_next = m0; 75 ip = mtod(m, struct ip *); 76 ip->ip_off = 0; 77 ip->ip_p = so->so_proto->pr_protocol; 78 ip->ip_len = sizeof(struct ip) + len; 79 if (rp->rcb_flags & RAW_LADDR) { 80 sin = (struct sockaddr_in *)&rp->rcb_laddr; 81 if (sin->sin_family != AF_INET) { 82 error = EAFNOSUPPORT; 83 goto bad; 84 } 85 ip->ip_src.s_addr = sin->sin_addr.s_addr; 86 } else 87 ip->ip_src.s_addr = 0; 88 ip->ip_dst = ((struct sockaddr_in *)&rp->rcb_faddr)->sin_addr; 89 ip->ip_ttl = MAXTTL; 90 return (ip_output(m, (struct mbuf *)0, &rp->rcb_route, 91 IP_ROUTETOIF|IP_ALLOWBROADCAST)); 92 bad: 93 m_freem(m); 94 return (error); 95 } 96