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