1*5612Swnj /* raw_ip.c 4.2 82/01/24 */ 25123Swnj 35123Swnj #include "../h/param.h" 45123Swnj #include "../h/mbuf.h" 55123Swnj #include "../h/socket.h" 6*5612Swnj #include "../h/protosw.h" 75123Swnj #include "../h/socketvar.h" 85123Swnj #include "../net/in.h" 95123Swnj #include "../net/in_systm.h" 10*5612Swnj #include "../net/ip.h" 11*5612Swnj #include "../net/ip_var.h" 12*5612Swnj #include "../net/raw_cb.h" 13*5612Swnj #include "/usr/include/errno.h" 145123Swnj 155123Swnj /* 16*5612Swnj * Raw interface to IP protocol. 175123Swnj */ 18*5612Swnj 19*5612Swnj static struct sockaddr_in ripaddr = { PF_INET }; 20*5612Swnj static struct sockproto ripproto = { AF_INET }; 21*5612Swnj 22*5612Swnj /* 23*5612Swnj * Setup generic address and protocol structures 24*5612Swnj * for raw_input routine, then pass them along with 25*5612Swnj * mbuf chain. 26*5612Swnj */ 275123Swnj rip_input(m) 285123Swnj struct mbuf *m; 295123Swnj { 30*5612Swnj register struct ip *ip = mtod(m, struct ip *); 31*5612Swnj struct sockaddr_in sin; 32*5612Swnj struct sockproto sp; 335123Swnj 345123Swnj COUNT(RIP_INPUT); 35*5612Swnj ripproto.sp_protocol = ip->ip_p; 36*5612Swnj ripaddr.sin_addr = ip->ip_dst; 37*5612Swnj raw_input(m, ripproto, ripaddr); 385123Swnj } 395123Swnj 405123Swnj /*ARGSUSED*/ 415123Swnj rip_ctlinput(m) 425123Swnj struct mbuf *m; 435123Swnj { 445123Swnj COUNT(RIP_CTLINPUT); 455123Swnj } 465123Swnj 47*5612Swnj /* 48*5612Swnj * Generate IP header and pass packet to ip_output. 49*5612Swnj * Tack on options user may have setup with control call. 50*5612Swnj */ 51*5612Swnj rip_output(m0, so) 52*5612Swnj struct mbuf *m0; 53*5612Swnj struct socket *so; 545123Swnj { 55*5612Swnj register struct mbuf *m; 56*5612Swnj register struct ip *ip; 57*5612Swnj register int len = 0; 58*5612Swnj register struct rawcb *rp = sotorawcb(so); 595123Swnj 605123Swnj COUNT(RIP_OUTPUT); 61*5612Swnj if (so->so_options & SO_DEBUG) 62*5612Swnj printf("rip_output\n"); 63*5612Swnj /* 64*5612Swnj * Calculate data length and get an mbuf 65*5612Swnj * for IP header. 66*5612Swnj */ 67*5612Swnj for (m = m0; m; m = m->m_next) 68*5612Swnj len += m->m_len; 69*5612Swnj m = m_get(M_DONTWAIT); 70*5612Swnj if (m == 0) { 71*5612Swnj (void) m_freem(m); 72*5612Swnj return; 73*5612Swnj } 74*5612Swnj 75*5612Swnj /* 76*5612Swnj * Fill in IP header as needed. 77*5612Swnj */ 78*5612Swnj m->m_off = MMAXOFF - sizeof(struct ip); 79*5612Swnj m->m_len = sizeof(struct ip); 80*5612Swnj m->m_next = m0; 81*5612Swnj ip = mtod(m, struct ip *); 82*5612Swnj ip->ip_p = so->so_proto->pr_protocol; 83*5612Swnj ip->ip_len = sizeof(struct ip) + len; 84*5612Swnj ip->ip_dst = 85*5612Swnj ((struct sockaddr_in *)&rp->rcb_addr)->sin_addr; 86*5612Swnj ip->ip_src = 87*5612Swnj ((struct sockaddr_in *)&so->so_addr)->sin_addr; 88*5612Swnj ip->ip_ttl = MAXTTL; 89*5612Swnj printf("ip=<p=%d,len=%d,dst=%x,src=%x>\n",ip->ip_p,ip->ip_len,ip->ip_dst,ip->ip_src); 90*5612Swnj return (ip_output(m, 0)); 915123Swnj } 925123Swnj 93*5612Swnj /* 94*5612Swnj * Intercept control operations related to 95*5612Swnj * handling of IP options. Otherwise, 96*5612Swnj * just pass things on to the raw_usrreq 97*5612Swnj * routine for setup and tear down of 98*5612Swnj * raw control block data structures. 99*5612Swnj */ 1005123Swnj rip_usrreq(so, req, m, addr) 1015123Swnj struct socket *so; 1025123Swnj int req; 1035123Swnj struct mbuf *m; 1045123Swnj caddr_t addr; 1055123Swnj { 106*5612Swnj register struct rawcb *rp = sotorawcb(so); 1075123Swnj 1085123Swnj COUNT(RAW_USRREQ); 109*5612Swnj if (rp == 0 && req != PRU_ATTACH) 110*5612Swnj return (EINVAL); 1115123Swnj 112*5612Swnj switch (req) { 113*5612Swnj 114*5612Swnj case PRU_CONTROL: 115*5612Swnj return (EOPNOTSUPP); 116*5612Swnj } 117*5612Swnj return (raw_usrreq(so, req, m, addr)); 1185123Swnj } 119