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