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