This source file includes following definitions.
- atintr
- ddp_input
- m_printm
- bprint
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 #include <sys/param.h>
55 #include <sys/systm.h>
56 #include <sys/kernel.h>
57 #include <sys/malloc.h>
58 #include <sys/mbuf.h>
59 #include <sys/protosw.h>
60 #include <sys/socket.h>
61 #include <sys/ioctl.h>
62 #include <sys/errno.h>
63 #include <sys/syslog.h>
64 #include <sys/proc.h>
65 #include <sys/socketvar.h>
66
67 #include <net/if.h>
68 #include <net/route.h>
69
70 #include <machine/endian.h>
71
72 #include <netatalk/at.h>
73 #include <netatalk/at_var.h>
74 #include <netatalk/ddp.h>
75 #include <netatalk/ddp_var.h>
76 #include <netatalk/at_extern.h>
77
78 void atintr(void);
79 void ddp_input(struct mbuf *, struct ifnet *,
80 struct elaphdr *, int);
81 #if 0
82 static void m_printm(struct mbuf *);
83 static void bprint( char *, int );
84 #endif
85
86 int ddp_forward = 1;
87 int ddp_firewall = 0;
88 extern int ddp_cksum;
89
90
91
92
93 void
94 atintr()
95 {
96 struct elaphdr *elhp, elh;
97 struct ifnet *ifp;
98 struct mbuf *m;
99 struct at_ifaddr *aa;
100 int s;
101
102 for (;;) {
103 s = splnet();
104
105 IF_DEQUEUE( &atintrq2, m );
106
107 splx( s );
108
109 if ( m == 0 ) {
110 break;
111 }
112
113 ifp = m->m_pkthdr.rcvif;
114 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
115 if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 )) {
116 break;
117 }
118 }
119 if ( aa == NULL ) {
120 m_freem( m );
121 continue;
122 }
123
124 ddp_input( m, ifp, (struct elaphdr *)NULL, 2 );
125 }
126
127 for (;;) {
128 s = splnet();
129
130 IF_DEQUEUE( &atintrq1, m );
131
132 splx( s );
133
134 if ( m == 0 ) {
135 break;
136 }
137
138 ifp = m->m_pkthdr.rcvif;
139 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
140 if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
141 break;
142 }
143 }
144 if ( aa == NULL ) {
145 m_freem( m );
146 continue;
147 }
148
149 if ( m->m_len < SZ_ELAPHDR &&
150 (( m = m_pullup( m, SZ_ELAPHDR )) == 0 )) {
151 ddpstat.ddps_tooshort++;
152 continue;
153 }
154
155 elhp = mtod( m, struct elaphdr *);
156 m_adj( m, SZ_ELAPHDR );
157
158 if ( elhp->el_type == ELAP_DDPEXTEND ) {
159 ddp_input( m, ifp, (struct elaphdr *)NULL, 1 );
160 } else {
161 bcopy((caddr_t)elhp, (caddr_t)&elh, SZ_ELAPHDR );
162 ddp_input( m, ifp, &elh, 1 );
163 }
164 }
165 return;
166 }
167
168 struct route forwro;
169
170 void
171 ddp_input( m, ifp, elh, phase )
172 struct mbuf *m;
173 struct ifnet *ifp;
174 struct elaphdr *elh;
175 int phase;
176 {
177 struct sockaddr_at from, to;
178 struct ddpshdr *dsh, ddps;
179 struct at_ifaddr *aa;
180 struct ddpehdr *deh, ddpe;
181 struct ddpcb *ddp;
182 int dlen, mlen;
183 u_int16_t cksum;
184
185 bzero( (caddr_t)&from, sizeof( struct sockaddr_at ));
186 if ( elh ) {
187 ddpstat.ddps_short++;
188
189 if ( m->m_len < sizeof( struct ddpshdr ) &&
190 (( m = m_pullup( m, sizeof( struct ddpshdr ))) == 0 )) {
191 ddpstat.ddps_tooshort++;
192 return;
193 }
194
195 dsh = mtod( m, struct ddpshdr *);
196 bcopy( (caddr_t)dsh, (caddr_t)&ddps, sizeof( struct ddpshdr ));
197 ddps.dsh_bytes = ntohl( ddps.dsh_bytes );
198 dlen = ddps.dsh_len;
199
200 to.sat_addr.s_net = 0;
201 to.sat_addr.s_node = elh->el_dnode;
202 to.sat_port = ddps.dsh_dport;
203 from.sat_addr.s_net = 0;
204 from.sat_addr.s_node = elh->el_snode;
205 from.sat_port = ddps.dsh_sport;
206
207 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
208 if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 ) == 0 &&
209 ( AA_SAT( aa )->sat_addr.s_node == to.sat_addr.s_node ||
210 to.sat_addr.s_node == ATADDR_BCAST )) {
211 break;
212 }
213 }
214 if ( aa == NULL ) {
215 m_freem( m );
216 return;
217 }
218 } else {
219 ddpstat.ddps_long++;
220
221 if ( m->m_len < sizeof( struct ddpehdr ) &&
222 (( m = m_pullup( m, sizeof( struct ddpehdr ))) == 0 )) {
223 ddpstat.ddps_tooshort++;
224 return;
225 }
226
227 deh = mtod( m, struct ddpehdr *);
228 bcopy( (caddr_t)deh, (caddr_t)&ddpe, sizeof( struct ddpehdr ));
229 ddpe.deh_bytes = ntohl( ddpe.deh_bytes );
230 dlen = ddpe.deh_len;
231
232 if (( cksum = ddpe.deh_sum ) == 0 ) {
233 ddpstat.ddps_nosum++;
234 }
235
236 from.sat_addr.s_net = ddpe.deh_snet;
237 from.sat_addr.s_node = ddpe.deh_snode;
238 from.sat_port = ddpe.deh_sport;
239 to.sat_addr.s_net = ddpe.deh_dnet;
240 to.sat_addr.s_node = ddpe.deh_dnode;
241 to.sat_port = ddpe.deh_dport;
242
243 if ( to.sat_addr.s_net == 0 ) {
244 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
245 if ( phase == 1 && ( aa->aa_flags & AFA_PHASE2 )) {
246 continue;
247 }
248 if ( phase == 2 && ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
249 continue;
250 }
251 if ( aa->aa_ifp == ifp &&
252 ( AA_SAT( aa )->sat_addr.s_node == to.sat_addr.s_node ||
253 to.sat_addr.s_node == ATADDR_BCAST ||
254 ( ifp->if_flags & IFF_LOOPBACK ))) {
255 break;
256 }
257 }
258 } else {
259 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
260 if ( to.sat_addr.s_net == aa->aa_firstnet &&
261 to.sat_addr.s_node == 0 ) {
262 break;
263 }
264 if (( ntohs( to.sat_addr.s_net ) < ntohs( aa->aa_firstnet ) ||
265 ntohs( to.sat_addr.s_net ) > ntohs( aa->aa_lastnet )) &&
266 ( ntohs( to.sat_addr.s_net ) < 0xff00 ||
267 ntohs( to.sat_addr.s_net ) > 0xfffe)) {
268 continue;
269 }
270 if ( to.sat_addr.s_node != AA_SAT( aa )->sat_addr.s_node &&
271 to.sat_addr.s_node != ATADDR_BCAST ) {
272 continue;
273 }
274 break;
275 }
276 }
277 }
278
279
280
281
282
283
284 mlen = m->m_pkthdr.len;
285 if ( mlen < dlen ) {
286 ddpstat.ddps_toosmall++;
287 m_freem( m );
288 return;
289 }
290 if ( mlen > dlen ) {
291 m_adj( m, dlen - mlen );
292 }
293
294
295
296
297
298 if ( aa == NULL || ( to.sat_addr.s_node == ATADDR_BCAST &&
299 aa->aa_ifp != ifp && ( ifp->if_flags & IFF_LOOPBACK ) == 0 )) {
300 if ( ddp_forward == 0 ) {
301 m_freem( m );
302 return;
303 }
304 if ( forwro.ro_rt && ( satosat( &forwro.ro_dst )->sat_addr.s_net !=
305 to.sat_addr.s_net ||
306 satosat( &forwro.ro_dst )->sat_addr.s_node !=
307 to.sat_addr.s_node )) {
308 RTFREE( forwro.ro_rt );
309 forwro.ro_rt = (struct rtentry *)0;
310 }
311 if ( forwro.ro_rt == (struct rtentry *)0 ||
312 forwro.ro_rt->rt_ifp == (struct ifnet *)0 ) {
313 forwro.ro_dst.sa_len = sizeof( struct sockaddr_at );
314 forwro.ro_dst.sa_family = AF_APPLETALK;
315 satosat( &forwro.ro_dst )->sat_addr.s_net = to.sat_addr.s_net;
316 satosat( &forwro.ro_dst )->sat_addr.s_node = to.sat_addr.s_node;
317 rtalloc( &forwro );
318 }
319
320 if ( to.sat_addr.s_net != satosat( &forwro.ro_dst )->sat_addr.s_net &&
321 ddpe.deh_hops == DDP_MAXHOPS ) {
322 m_freem( m );
323 return;
324 }
325
326
327 if ( ddp_firewall &&
328 ( forwro.ro_rt == NULL || ( forwro.ro_rt->rt_ifp != ifp &&
329 forwro.ro_rt->rt_ifp != at_ifaddr->aa_ifp ))) {
330 m_freem( m );
331 return;
332 }
333
334 ddpe.deh_hops++;
335 ddpe.deh_bytes = htonl( ddpe.deh_bytes );
336 bcopy( (caddr_t)&ddpe, (caddr_t)deh, sizeof( u_int16_t ));
337 if ( ddp_route( m, &forwro )) {
338 ddpstat.ddps_cantforward++;
339 } else {
340 ddpstat.ddps_forward++;
341 }
342 return;
343 }
344
345 from.sat_len = sizeof( struct sockaddr_at );
346 from.sat_family = AF_APPLETALK;
347
348 if ( elh ) {
349 m_adj( m, sizeof( struct ddpshdr ));
350 } else {
351
352
353
354
355
356
357
358 if ( ddp_cksum && cksum && cksum != at_cksum( m, sizeof( int ))) {
359 ddpstat.ddps_badsum++;
360 m_freem( m );
361 return;
362 }
363 m_adj( m, sizeof( struct ddpehdr ));
364 }
365
366 if (( ddp = ddp_search( &from, &to, aa )) == NULL ) {
367 m_freem( m );
368 return;
369 }
370
371 if ( sbappendaddr( &ddp->ddp_socket->so_rcv, (struct sockaddr *)&from,
372 m, (struct mbuf *)0 ) == 0 ) {
373 ddpstat.ddps_nosockspace++;
374 m_freem( m );
375 return;
376 }
377 sorwakeup( ddp->ddp_socket );
378 }
379
380 #if 0
381 static void
382 m_printm( m )
383 struct mbuf *m;
384 {
385 for (; m; m = m->m_next ) {
386 bprint( mtod( m, char * ), m->m_len );
387 }
388 }
389
390 #define BPXLEN 48
391 #define BPALEN 16
392 char hexdig[] = "0123456789ABCDEF";
393
394 static void
395 bprint( data, len )
396 char *data;
397 int len;
398 {
399 char xout[ BPXLEN ], aout[ BPALEN ];
400 int i = 0;
401
402 bzero( xout, BPXLEN );
403 bzero( aout, BPALEN );
404
405 for ( ;; ) {
406 if ( len < 1 ) {
407 if ( i != 0 ) {
408 printf( "%s\t%s\n", xout, aout );
409 }
410 printf( "%s\n", "(end)" );
411 break;
412 }
413
414 xout[ (i*3) ] = hexdig[ ( *data & 0xf0 ) >> 4 ];
415 xout[ (i*3) + 1 ] = hexdig[ *data & 0x0f ];
416
417 if ( (u_char)*data < 0x7f && (u_char)*data > 0x20 ) {
418 aout[ i ] = *data;
419 } else {
420 aout[ i ] = '.';
421 }
422
423 xout[ (i*3) + 2 ] = ' ';
424
425 i++;
426 len--;
427 data++;
428
429 if ( i > BPALEN - 2 ) {
430 printf( "%s\t%s\n", xout, aout );
431 bzero( xout, BPXLEN );
432 bzero( aout, BPALEN );
433 i = 0;
434 continue;
435 }
436 }
437 }
438 #endif