1*5669Ssam /* raw_ip.c 4.4 82/02/02 */ 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" 135612Swnj #include "/usr/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 *); 325612Swnj struct sockaddr_in sin; 335612Swnj struct sockproto sp; 345123Swnj 355123Swnj COUNT(RIP_INPUT); 365612Swnj ripproto.sp_protocol = ip->ip_p; 375646Ssam ripdst.sin_addr = ip->ip_dst; 385646Ssam ripsrc.sin_addr = ip->ip_src; 39*5669Ssam raw_input(m, &ripproto, &ripdst, &ripsrc); 405123Swnj } 415123Swnj 425123Swnj /*ARGSUSED*/ 435123Swnj rip_ctlinput(m) 445123Swnj struct mbuf *m; 455123Swnj { 465123Swnj COUNT(RIP_CTLINPUT); 475123Swnj } 485123Swnj 495612Swnj /* 505612Swnj * Generate IP header and pass packet to ip_output. 515612Swnj * Tack on options user may have setup with control call. 525612Swnj */ 535612Swnj rip_output(m0, so) 545612Swnj struct mbuf *m0; 555612Swnj struct socket *so; 565123Swnj { 575612Swnj register struct mbuf *m; 585612Swnj register struct ip *ip; 595612Swnj register int len = 0; 605612Swnj register struct rawcb *rp = sotorawcb(so); 615123Swnj 625123Swnj COUNT(RIP_OUTPUT); 635612Swnj /* 645612Swnj * Calculate data length and get an mbuf 655612Swnj * for IP header. 665612Swnj */ 675612Swnj for (m = m0; m; m = m->m_next) 685612Swnj len += m->m_len; 695612Swnj m = m_get(M_DONTWAIT); 705612Swnj if (m == 0) { 71*5669Ssam m_freem(m); 725612Swnj return; 735612Swnj } 745612Swnj 755612Swnj /* 765612Swnj * Fill in IP header as needed. 775612Swnj */ 785612Swnj m->m_off = MMAXOFF - sizeof(struct ip); 795612Swnj m->m_len = sizeof(struct ip); 805612Swnj m->m_next = m0; 815612Swnj ip = mtod(m, struct ip *); 825612Swnj ip->ip_p = so->so_proto->pr_protocol; 835612Swnj ip->ip_len = sizeof(struct ip) + len; 845612Swnj ip->ip_dst = 855612Swnj ((struct sockaddr_in *)&rp->rcb_addr)->sin_addr; 865612Swnj ip->ip_src = 875612Swnj ((struct sockaddr_in *)&so->so_addr)->sin_addr; 885612Swnj ip->ip_ttl = MAXTTL; 895612Swnj return (ip_output(m, 0)); 905123Swnj } 915123Swnj 925612Swnj /* 935612Swnj * Intercept control operations related to 945612Swnj * handling of IP options. Otherwise, 955612Swnj * just pass things on to the raw_usrreq 965612Swnj * routine for setup and tear down of 975612Swnj * raw control block data structures. 985612Swnj */ 995123Swnj rip_usrreq(so, req, m, addr) 1005123Swnj struct socket *so; 1015123Swnj int req; 1025123Swnj struct mbuf *m; 1035123Swnj caddr_t addr; 1045123Swnj { 1055612Swnj register struct rawcb *rp = sotorawcb(so); 1065123Swnj 1075123Swnj COUNT(RAW_USRREQ); 1085612Swnj if (rp == 0 && req != PRU_ATTACH) 1095612Swnj return (EINVAL); 1105123Swnj 1115612Swnj switch (req) { 1125612Swnj 113*5669Ssam /* 114*5669Ssam * SHOULD HAVE CONTROL TO SET PROTOCOL NUMBER (e.g. GGP) 115*5669Ssam */ 1165612Swnj case PRU_CONTROL: 1175612Swnj return (EOPNOTSUPP); 1185612Swnj } 1195612Swnj return (raw_usrreq(so, req, m, addr)); 1205123Swnj } 121