1*6161Ssam /* raw_ip.c 4.7 82/03/13 */ 25123Swnj 35123Swnj #include "../h/param.h" 45123Swnj #include "../h/mbuf.h" 55123Swnj #include "../h/socket.h" 65612Swnj #include "../h/protosw.h" 75123Swnj #include "../h/socketvar.h" 85123Swnj #include "../net/in.h" 95123Swnj #include "../net/in_systm.h" 105612Swnj #include "../net/ip.h" 115612Swnj #include "../net/ip_var.h" 125612Swnj #include "../net/raw_cb.h" 136040Sroot #include "../errno.h" 145123Swnj 155123Swnj /* 165612Swnj * Raw interface to IP protocol. 175123Swnj */ 185612Swnj 195646Ssam static struct sockaddr_in ripdst = { PF_INET }; 205646Ssam static struct sockaddr_in ripsrc = { PF_INET }; 215612Swnj static struct sockproto ripproto = { AF_INET }; 225612Swnj 235612Swnj /* 245612Swnj * Setup generic address and protocol structures 255612Swnj * for raw_input routine, then pass them along with 265612Swnj * mbuf chain. 275612Swnj */ 285123Swnj rip_input(m) 295123Swnj struct mbuf *m; 305123Swnj { 315612Swnj register struct ip *ip = mtod(m, struct ip *); 325123Swnj 335123Swnj COUNT(RIP_INPUT); 345612Swnj ripproto.sp_protocol = ip->ip_p; 355646Ssam ripdst.sin_addr = ip->ip_dst; 365646Ssam ripsrc.sin_addr = ip->ip_src; 37*6161Ssam raw_input(m, &ripproto, (struct sockaddr *)&ripdst, 38*6161Ssam (struct sockaddr *)&ripsrc); 395123Swnj } 405123Swnj 415123Swnj /*ARGSUSED*/ 425123Swnj rip_ctlinput(m) 435123Swnj struct mbuf *m; 445123Swnj { 455123Swnj COUNT(RIP_CTLINPUT); 465123Swnj } 475123Swnj 485612Swnj /* 495612Swnj * Generate IP header and pass packet to ip_output. 505612Swnj * Tack on options user may have setup with control call. 515612Swnj */ 525612Swnj rip_output(m0, so) 535612Swnj struct mbuf *m0; 545612Swnj struct socket *so; 555123Swnj { 565612Swnj register struct mbuf *m; 575612Swnj register struct ip *ip; 585612Swnj register int len = 0; 595612Swnj register struct rawcb *rp = sotorawcb(so); 605123Swnj 615123Swnj COUNT(RIP_OUTPUT); 625612Swnj /* 635612Swnj * Calculate data length and get an mbuf 645612Swnj * for IP header. 655612Swnj */ 665612Swnj for (m = m0; m; m = m->m_next) 675612Swnj len += m->m_len; 685612Swnj m = m_get(M_DONTWAIT); 695612Swnj if (m == 0) { 705669Ssam m_freem(m); 716147Ssam return (0); 725612Swnj } 735612Swnj 745612Swnj /* 755612Swnj * Fill in IP header as needed. 765612Swnj */ 775612Swnj m->m_off = MMAXOFF - sizeof(struct ip); 785612Swnj m->m_len = sizeof(struct ip); 795612Swnj m->m_next = m0; 805612Swnj ip = mtod(m, struct ip *); 815612Swnj ip->ip_p = so->so_proto->pr_protocol; 825612Swnj ip->ip_len = sizeof(struct ip) + len; 835612Swnj ip->ip_dst = 845612Swnj ((struct sockaddr_in *)&rp->rcb_addr)->sin_addr; 855612Swnj ip->ip_src = 865612Swnj ((struct sockaddr_in *)&so->so_addr)->sin_addr; 875612Swnj ip->ip_ttl = MAXTTL; 88*6161Ssam return (ip_output(m, (struct mbuf *)0)); 895123Swnj } 905123Swnj 915612Swnj /* 925612Swnj * Intercept control operations related to 935612Swnj * handling of IP options. Otherwise, 945612Swnj * just pass things on to the raw_usrreq 955612Swnj * routine for setup and tear down of 965612Swnj * raw control block data structures. 975612Swnj */ 985123Swnj rip_usrreq(so, req, m, addr) 995123Swnj struct socket *so; 1005123Swnj int req; 1015123Swnj struct mbuf *m; 1025123Swnj caddr_t addr; 1035123Swnj { 1045612Swnj register struct rawcb *rp = sotorawcb(so); 1055123Swnj 1065123Swnj COUNT(RAW_USRREQ); 1075612Swnj if (rp == 0 && req != PRU_ATTACH) 1085612Swnj return (EINVAL); 1095123Swnj 1105612Swnj switch (req) { 1115612Swnj 1125669Ssam /* 1135669Ssam * SHOULD HAVE CONTROL TO SET PROTOCOL NUMBER (e.g. GGP) 1145669Ssam */ 1155612Swnj case PRU_CONTROL: 1165612Swnj return (EOPNOTSUPP); 1175612Swnj } 1185612Swnj return (raw_usrreq(so, req, m, addr)); 1195123Swnj } 120