1*25202Skarels #ifdef	RCSIDENT
2*25202Skarels static char rcsident[] = "$Header: raw_input.c,v 1.17 85/07/31 09:33:16 walsh Exp $";
3*25202Skarels #endif
4*25202Skarels 
5*25202Skarels #include "../h/param.h"
6*25202Skarels #include "../h/dir.h"
7*25202Skarels #include "../h/user.h"
8*25202Skarels #include "../machine/mtpr.h"
9*25202Skarels #include "../h/mbuf.h"
10*25202Skarels #include "../h/socket.h"
11*25202Skarels #include "../h/socketvar.h"
12*25202Skarels 
13*25202Skarels #include "../net/if.h"
14*25202Skarels #include "../net/netisr.h"
15*25202Skarels #include "../net/route.h"
16*25202Skarels #include "../net/raw_cb.h"
17*25202Skarels 
18*25202Skarels #include "../bbnnet/in.h"
19*25202Skarels #include "../bbnnet/net.h"
20*25202Skarels #include "../bbnnet/in_pcb.h"
21*25202Skarels #include "../bbnnet/in_var.h"
22*25202Skarels #include "../bbnnet/ip.h"
23*25202Skarels #include "../bbnnet/fsm.h"
24*25202Skarels #include "../bbnnet/tcp.h"
25*25202Skarels #include "../bbnnet/icmp.h"
26*25202Skarels #include "../bbnnet/udp.h"
27*25202Skarels #ifdef HMP
28*25202Skarels #include "../bbnnet/hmp.h"
29*25202Skarels #endif HMP
30*25202Skarels #include "../bbnnet/nopcb.h"
31*25202Skarels 
32*25202Skarels /*
33*25202Skarels  * Sort INET packets for user(s).  To get a packet, socket must match:
34*25202Skarels  *
35*25202Skarels  *    raw_ip_proto
36*25202Skarels  *		domain   (INET)
37*25202Skarels  *		protocol (TCP/UDP/ICMP)
38*25202Skarels  *    raw_ip_dst
39*25202Skarels  *		domain   (INET)
40*25202Skarels  *		address, but not port, if connected(2)
41*25202Skarels  *    raw_ip_src
42*25202Skarels  *		domain   (INET)
43*25202Skarels  *		address, but not port, if bound(2)
44*25202Skarels  *
45*25202Skarels  * Called from ip_input() for packets that were well-formed enough to get
46*25202Skarels  * passed up to TCP/UDP/ICMP.
47*25202Skarels  */
48*25202Skarels struct	sockaddr_in raw_ip_dst =
49*25202Skarels {
50*25202Skarels     AF_INET
51*25202Skarels } ;
52*25202Skarels struct	sockaddr_in raw_ip_src =
53*25202Skarels {
54*25202Skarels     AF_INET
55*25202Skarels } ;
56*25202Skarels struct	sockproto raw_ip_proto =
57*25202Skarels {
58*25202Skarels     PF_INET
59*25202Skarels } ;
60*25202Skarels 
61*25202Skarels raw_ip_input(m)
62*25202Skarels struct mbuf *m;
63*25202Skarels {
64*25202Skarels     register struct ip *ip = mtod(m, struct ip *);
65*25202Skarels 
66*25202Skarels     raw_ip_proto.sp_protocol = ip->ip_p;
67*25202Skarels     raw_ip_dst.sin_addr.s_addr = ip->ip_dst.s_addr;
68*25202Skarels     raw_ip_src.sin_addr.s_addr = ip->ip_src.s_addr;
69*25202Skarels 
70*25202Skarels     raw_input (m, &raw_ip_proto, (struct sockaddr *)&raw_ip_src,
71*25202Skarels 	(struct sockaddr *)&raw_ip_dst);
72*25202Skarels }
73*25202Skarels 
74*25202Skarels /*
75*25202Skarels  * Bad ip packets, which are taken care of via calls to ip_log() and netlog().
76*25202Skarels  */
77*25202Skarels struct	sockaddr_in netlog_dst =
78*25202Skarels {
79*25202Skarels     AF_INET
80*25202Skarels } ;
81*25202Skarels struct	sockaddr_in netlog_src =
82*25202Skarels {
83*25202Skarels     AF_INET
84*25202Skarels } ;
85*25202Skarels struct	sockproto netlog_proto =
86*25202Skarels {
87*25202Skarels     PF_INET, NETLOG_PROTO
88*25202Skarels } ;
89*25202Skarels 
90*25202Skarels netlog(m)
91*25202Skarels struct mbuf *m;
92*25202Skarels {
93*25202Skarels     raw_input (m, &netlog_proto, (struct sockaddr *)&netlog_src,
94*25202Skarels 	(struct sockaddr *)&netlog_dst);
95*25202Skarels }
96*25202Skarels 
97*25202Skarels #ifdef AF_TCPDEBUG
98*25202Skarels 	/*
99*25202Skarels 	 * TCP debugging log
100*25202Skarels 	 *
101*25202Skarels 	 * Though the mbuf contains a copy of the tcpcb, and thus a pointer to the
102*25202Skarels 	 * inpcb, kernel can't do address sorting since this may point within a freed
103*25202Skarels 	 * (and perhaps now recycled) mbuf.  Remember that this logging is done after
104*25202Skarels 	 * state changes (closing).
105*25202Skarels 	 */
106*25202Skarels 	struct	sockaddr_in tcpdebug_dst =
107*25202Skarels 	{
108*25202Skarels 	    AF_TCPDEBUG
109*25202Skarels 	} ;
110*25202Skarels 	struct	sockaddr_in tcpdebug_src =
111*25202Skarels 	{
112*25202Skarels 	    AF_TCPDEBUG
113*25202Skarels 	} ;
114*25202Skarels 	struct	sockproto tcpdebug_proto =
115*25202Skarels 	{
116*25202Skarels 	    PF_TCPDEBUG, 0
117*25202Skarels 	} ;
118*25202Skarels 
119*25202Skarels 	tcpdebuglog(m)
120*25202Skarels 	struct mbuf *m;
121*25202Skarels 	{
122*25202Skarels 	    raw_input (m, &tcpdebug_proto, (struct sockaddr *)&tcpdebug_src,
123*25202Skarels 		(struct sockaddr *)&tcpdebug_dst);
124*25202Skarels 	}
125*25202Skarels #else
126*25202Skarels 	tcpdebuglog(m)
127*25202Skarels 	struct mbuf *m;
128*25202Skarels 	{
129*25202Skarels 	    m_freem(m);
130*25202Skarels 	}
131*25202Skarels #endif
132*25202Skarels 
133*25202Skarels #ifdef AF_RDPDEBUG
134*25202Skarels 	struct sockaddr_in rdpdebug_dst =
135*25202Skarels 	{
136*25202Skarels 	    AF_RDPDEBUG
137*25202Skarels 	} ;
138*25202Skarels 	struct sockaddr_in rdpdebug_src =
139*25202Skarels 	{
140*25202Skarels 	    AF_RDPDEBUG
141*25202Skarels 	} ;
142*25202Skarels 	struct sockproto rdpdebug_proto =
143*25202Skarels 	{
144*25202Skarels 	    PF_RDPDEBUG, 0
145*25202Skarels 	} ;
146*25202Skarels 
147*25202Skarels 	rdpdebuglog(m)
148*25202Skarels 	struct mbuf *m;
149*25202Skarels 	{
150*25202Skarels 	    raw_input (m, &rdpdebug_proto, (struct sockaddr *)&rdpdebug_src,
151*25202Skarels 		(struct sockaddr *)&rdpdebug_dst);
152*25202Skarels 	}
153*25202Skarels #else
154*25202Skarels 	rdpdebuglog(m)
155*25202Skarels 	struct mbuf *m;
156*25202Skarels 	{
157*25202Skarels 	    m_freem(m);
158*25202Skarels 	}
159*25202Skarels #endif
160*25202Skarels 
161*25202Skarels 
m_bpullup(m0,len)162*25202Skarels struct mbuf *m_bpullup(m0, len)
163*25202Skarels struct mbuf *m0;
164*25202Skarels int len;
165*25202Skarels {
166*25202Skarels     register struct mbuf *m, *n;
167*25202Skarels     unsigned count;
168*25202Skarels 
169*25202Skarels     n = m0;
170*25202Skarels     if (len > MLEN)
171*25202Skarels     {
172*25202Skarels 	m_freem(n);
173*25202Skarels 	return ((struct mbuf *) NULL);
174*25202Skarels     }
175*25202Skarels #ifdef MBUF_DEBUG
176*25202Skarels     m = m_get(M_DONTWAIT, n->m_type);
177*25202Skarels #else
178*25202Skarels     MGET(m, M_DONTWAIT, n->m_type);
179*25202Skarels #endif
180*25202Skarels     if (m == 0)
181*25202Skarels     {
182*25202Skarels 	m_freem(n);
183*25202Skarels 	return ((struct mbuf *) NULL);
184*25202Skarels     }
185*25202Skarels     m->m_len = 0;
186*25202Skarels     m->m_off = MMAXOFF - len;	/* -- difference from m_pullup -- */
187*25202Skarels     do
188*25202Skarels     {
189*25202Skarels 	count = MIN(len, n->m_len);
190*25202Skarels 	bcopy(mtod(n, caddr_t), mtod(m, caddr_t)+m->m_len, count);
191*25202Skarels 	len -= count;
192*25202Skarels 	m->m_len += count;
193*25202Skarels 	n->m_off += count;
194*25202Skarels 	n->m_len -= count;
195*25202Skarels 	if (n->m_len)
196*25202Skarels 	    break;
197*25202Skarels 	n = m_free(n);
198*25202Skarels     }
199*25202Skarels     while (n);
200*25202Skarels 
201*25202Skarels     if (len)
202*25202Skarels     {
203*25202Skarels 	(void) m_free(m);
204*25202Skarels 	m_freem(n);
205*25202Skarels 	return ((struct mbuf *) NULL);
206*25202Skarels     }
207*25202Skarels     m->m_next = n;
208*25202Skarels     return (m);
209*25202Skarels }
210*25202Skarels 
211*25202Skarels /*
212*25202Skarels  * output function called from net/raw_usrreq
213*25202Skarels  */
214*25202Skarels 
215*25202Skarels /* ARGSUSED */
216*25202Skarels raw_ip_output (m0, so)
217*25202Skarels struct mbuf *m0;
218*25202Skarels struct socket *so;
219*25202Skarels {
220*25202Skarels     register struct mbuf	*m;
221*25202Skarels     register struct ip 	*ip;
222*25202Skarels     register int		 len;
223*25202Skarels     int retval;
224*25202Skarels 
225*25202Skarels     /*
226*25202Skarels      * verify length of datagram, get IP header at end of mbuf so can
227*25202Skarels      * prepend local net header.
228*25202Skarels      */
229*25202Skarels     len = 0;
230*25202Skarels     for (m = m0 ; m ; m = m->m_next)
231*25202Skarels 	len += m->m_len;
232*25202Skarels     if (len < sizeof(struct ip))
233*25202Skarels     {
234*25202Skarels 	m_freem(m0);
235*25202Skarels 	return(EMSGSIZE);	/* ### */
236*25202Skarels     }
237*25202Skarels     if ((m = m_bpullup(m0, sizeof(struct ip))) == NULL)
238*25202Skarels 	return (ENOBUFS);
239*25202Skarels     ip = mtod(m, struct ip *);
240*25202Skarels     if ((ntohs((u_short)ip->ip_len) != len) ||
241*25202Skarels 	((ip->ip_hl << IP_HLSHIFT) > len))
242*25202Skarels     {
243*25202Skarels 	m_freem(m);
244*25202Skarels 	return(EMSGSIZE);	/* ### */
245*25202Skarels     }
246*25202Skarels 
247*25202Skarels #ifdef notdef
248*25202Skarels     /* have to be super-user anyway to do this.
249*25202Skarels      * Cronus wants to be able to forward broadcast UDP packets.
250*25202Skarels      */
251*25202Skarels 
252*25202Skarels     /*
253*25202Skarels      * verify that addresses are valid
254*25202Skarels      */
255*25202Skarels     if (in_broadcast(ip->ip_src) || (in_iawithaddr(ip->ip_src, TRUE) == 0))
256*25202Skarels #else
257*25202Skarels     if (in_broadcast(ip->ip_src))
258*25202Skarels #endif
259*25202Skarels     {
260*25202Skarels 	m_freem(m);
261*25202Skarels 	return (EADDRNOTAVAIL);
262*25202Skarels     }
263*25202Skarels 
264*25202Skarels     NOPCB_IPSEND (m, len, TRUE, retval);
265*25202Skarels     return (retval);
266*25202Skarels }
267*25202Skarels 
268*25202Skarels 
269*25202Skarels 
270*25202Skarels /*
271*25202Skarels  * Send out an icmp packet.  Use the user's ICMP header, and our own IP
272*25202Skarels  * header.
273*25202Skarels  */
274*25202Skarels /* ARGSUSED */
275*25202Skarels raw_icmp_output (m0, so)
276*25202Skarels struct mbuf	*m0;
277*25202Skarels struct socket	*so;
278*25202Skarels {
279*25202Skarels     register struct mbuf  *m;
280*25202Skarels     register struct icmp  *p;
281*25202Skarels     register struct ip    *ip;
282*25202Skarels     register struct rawcb *rcb;
283*25202Skarels     int len;
284*25202Skarels     int retval;
285*25202Skarels 
286*25202Skarels     rcb = sotorawcb(so);
287*25202Skarels     if (!(rcb->rcb_flags & RAW_FADDR))
288*25202Skarels     {
289*25202Skarels 	m_freem(m0);
290*25202Skarels 	return(EDESTADDRREQ);
291*25202Skarels     }
292*25202Skarels 
293*25202Skarels     /*
294*25202Skarels      * find length of datagram
295*25202Skarels      */
296*25202Skarels     len = 0;
297*25202Skarels     for (m = m0 ; m ; m = m->m_next)
298*25202Skarels 	len += m->m_len;
299*25202Skarels     if (len < ICMPSIZE)
300*25202Skarels     {
301*25202Skarels 	m_freem(m0);
302*25202Skarels 	return (EMSGSIZE);	/* ### */
303*25202Skarels     }
304*25202Skarels 
305*25202Skarels     /*
306*25202Skarels      * Pull up user's ICMP header so we can prepend IP header later.
307*25202Skarels      */
308*25202Skarels     if ((m = m_bpullup(m0, ICMPSIZE)) == NULL)
309*25202Skarels 	return (ENOBUFS);
310*25202Skarels 
311*25202Skarels     /*
312*25202Skarels      * "Verify" ICMP header.  Accept user's type and code.
313*25202Skarels      */
314*25202Skarels     p = mtod(m, struct icmp *);
315*25202Skarels 
316*25202Skarels     /*
317*25202Skarels      * Use our own checksum, though.  It'll be at least as fast as the
318*25202Skarels      * user's and we'll have to use those CPU cycles sometime.
319*25202Skarels      */
320*25202Skarels     p->ic_sum = 0;
321*25202Skarels     p->ic_sum = in_cksum(m, len);
322*25202Skarels 
323*25202Skarels     /*
324*25202Skarels      * Fill in IP header and send it
325*25202Skarels      */
326*25202Skarels     m->m_off -= sizeof(struct ip);
327*25202Skarels     m->m_len += sizeof(struct ip);
328*25202Skarels     ip = mtod(m, struct ip *);
329*25202Skarels     ip->ip_p	= IPPROTO_ICMP;
330*25202Skarels     ip->ip_tos	= 0;
331*25202Skarels     ip->ip_dst.s_addr =
332*25202Skarels 	((struct sockaddr_in *) &rcb->rcb_faddr)->sin_addr.s_addr;
333*25202Skarels 
334*25202Skarels     if (rcb->rcb_flags & RAW_LADDR)
335*25202Skarels     {
336*25202Skarels 	ip->ip_src.s_addr =
337*25202Skarels 	    ((struct sockaddr_in *) &rcb->rcb_laddr)->sin_addr.s_addr;
338*25202Skarels     }
339*25202Skarels     else
340*25202Skarels     {
341*25202Skarels 	/*
342*25202Skarels 	 * We may examine the routing tables twice.
343*25202Skarels 	 * perhaps if this gets used a lot, it can be changed.
344*25202Skarels 	 */
345*25202Skarels 	struct route r;
346*25202Skarels 	struct rtentry *rt;
347*25202Skarels 
348*25202Skarels 	bzero ((caddr_t) &r, sizeof(r));
349*25202Skarels 	((struct sockaddr_in *) (&r.ro_dst)) ->sin_family = AF_INET;
350*25202Skarels 	((struct sockaddr_in *) (&r.ro_dst)) ->sin_addr.s_addr =
351*25202Skarels 	    ip->ip_dst.s_addr;
352*25202Skarels 	rtalloc(&r);
353*25202Skarels 	if (rt = r.ro_rt)
354*25202Skarels 	{
355*25202Skarels 	    ip->ip_src = IA_INADDR(in_iafromif(rt->rt_ifp));
356*25202Skarels 	    rtfree (rt);
357*25202Skarels 	}
358*25202Skarels 	else
359*25202Skarels 	{
360*25202Skarels 	    m_freem(m);
361*25202Skarels 	    return (ENETUNREACH);
362*25202Skarels 	}
363*25202Skarels     }
364*25202Skarels 
365*25202Skarels     NOPCB_IPSEND (m, len, FALSE, retval);
366*25202Skarels     return (retval);
367*25202Skarels }
368*25202Skarels 
369*25202Skarels #ifdef NSIP
370*25202Skarels /*
371*25202Skarels  * Generate IP header and pass packet to ip_output.
372*25202Skarels  * Tack on options user may have setup with control call.
373*25202Skarels  */
374*25202Skarels rip_output(m0, so)
375*25202Skarels struct mbuf *m0;
376*25202Skarels struct socket *so;
377*25202Skarels {
378*25202Skarels     register struct mbuf *m;
379*25202Skarels 
380*25202Skarels     /*
381*25202Skarels      * get an mbuf for IP header.
382*25202Skarels      */
383*25202Skarels     m = m_get(M_DONTWAIT, MT_HEADER);
384*25202Skarels     if (m == NULL)
385*25202Skarels     {
386*25202Skarels 	m_freem(m0);
387*25202Skarels 	return (ENOBUFS);
388*25202Skarels     }
389*25202Skarels 
390*25202Skarels     /*
391*25202Skarels      * Fill in IP header as needed.
392*25202Skarels      */
393*25202Skarels     m->m_off = MMAXOFF - sizeof(struct ip);
394*25202Skarels     m->m_len = sizeof(struct ip);
395*25202Skarels     m->m_next = m0;
396*25202Skarels     {
397*25202Skarels     register struct ip *ip;
398*25202Skarels     register struct rawcb *rcb = sotorawcb(so);
399*25202Skarels 
400*25202Skarels     ip = mtod(m, struct ip *);
401*25202Skarels     ip->ip_p	= rcb->rcb_proto.sp_protocol;
402*25202Skarels     ip->ip_tos	= 0;
403*25202Skarels     ip->ip_dst.s_addr =
404*25202Skarels 	((struct sockaddr_in *) &rcb->rcb_faddr)->sin_addr.s_addr;
405*25202Skarels     if (rcb->rcb_flags & RAW_LADDR)
406*25202Skarels 	ip->ip_src.s_addr =
407*25202Skarels 	    ((struct sockaddr_in *) &rcb->rcb_laddr)->sin_addr.s_addr;
408*25202Skarels     else
409*25202Skarels 	ip->ip_src.s_addr = 0;
410*25202Skarels     }
411*25202Skarels 
412*25202Skarels     {
413*25202Skarels     register int retval;
414*25202Skarels     register int len;
415*25202Skarels 
416*25202Skarels     /*
417*25202Skarels      * Calculate data length
418*25202Skarels      */
419*25202Skarels     len = 0;
420*25202Skarels     while (m0)
421*25202Skarels     {
422*25202Skarels 	len += m0->m_len;
423*25202Skarels 	m0 = m0->m_next;
424*25202Skarels     }
425*25202Skarels 
426*25202Skarels 
427*25202Skarels     NOPCB_IPSEND (m, len, FALSE, retval);
428*25202Skarels     return (retval);
429*25202Skarels     }
430*25202Skarels }
431*25202Skarels #endif
432*25202Skarels 
433*25202Skarels /*
434*25202Skarels  * The UDP header is so small and simple, the user should either:
435*25202Skarels  *	1.  go all the way and use a raw IP socket
436*25202Skarels  * or	2.  use send(2) type system calls.
437*25202Skarels  */
438*25202Skarels /* ARGSUSED */
439*25202Skarels raw_udp_output (m0, so)
440*25202Skarels struct mbuf *m0;
441*25202Skarels struct socket *so;
442*25202Skarels {
443*25202Skarels     m_freem(m0);
444*25202Skarels     return (EOPNOTSUPP);
445*25202Skarels }
446*25202Skarels 
447*25202Skarels /*
448*25202Skarels  * TCP requires a lot of state information.  Sure we could try to verify the
449*25202Skarels  * user's header and pass it on to ip, but unless debugging a new version
450*25202Skarels  * in user code with a different protocol number, probably shouldn't ship
451*25202Skarels  * out tcp packets, since we'll get packets in reply that might screw us up.
452*25202Skarels  *
453*25202Skarels  * And how does the sending of a single tcp packet make sense?
454*25202Skarels  */
455*25202Skarels /* ARGSUSED */
456*25202Skarels raw_tcp_output (m0, so)
457*25202Skarels struct mbuf *m0;
458*25202Skarels struct socket *so;
459*25202Skarels {
460*25202Skarels     m_freem(m0);
461*25202Skarels     return (EOPNOTSUPP);
462*25202Skarels }
463*25202Skarels 
464*25202Skarels #ifdef RDP
465*25202Skarels /*
466*25202Skarels  * ditto TCP for RDP
467*25202Skarels  */
468*25202Skarels /* ARGSUSED */
469*25202Skarels raw_rdp_output (m0, so)
470*25202Skarels struct mbuf *m0;
471*25202Skarels struct socket *so;
472*25202Skarels {
473*25202Skarels     m_freem(m0);
474*25202Skarels     return(EOPNOTSUPP);
475*25202Skarels }
476*25202Skarels #endif
477*25202Skarels 
478*25202Skarels /*
479*25202Skarels  * use the user level stuff to send -- much simpler
480*25202Skarels  */
481*25202Skarels 
482*25202Skarels #ifdef HMP
483*25202Skarels /* ARGSUSED */
484*25202Skarels raw_hmp_output (m0, so)
485*25202Skarels struct mbuf *m0;
486*25202Skarels struct socket *so;
487*25202Skarels {
488*25202Skarels     m_freem(m0);
489*25202Skarels     return(EOPNOTSUPP);
490*25202Skarels }
491*25202Skarels #endif
492