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