xref: /csrg-svn/sys/netinet/raw_ip.c (revision 6161)
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