This source file includes following definitions.
- at_control
- at_scrub
- at_ifinit
- at_broadcast
- aa_dorangeroute
- aa_addsingleroute
- aa_delsingleroute
- aa_dosingleroute
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/timeout.h>
66
67 #include <net/if.h>
68 #include <net/route.h>
69 #include <netinet/in.h>
70 #undef s_net
71 #include <netinet/if_ether.h>
72 #include <net/if_llc.h>
73
74 #include <netatalk/at.h>
75 #include <netatalk/at_var.h>
76 #include <netatalk/aarp.h>
77 #include <netatalk/phase2.h>
78 #include <netatalk/at_extern.h>
79
80 #include <dev/rndvar.h>
81
82 int at_control( u_long, caddr_t, struct ifnet *, struct proc * );
83 static int at_scrub( struct ifnet *, struct at_ifaddr * );
84 static int at_ifinit( struct ifnet *, struct at_ifaddr *,
85 struct sockaddr_at * );
86 int at_broadcast( struct sockaddr_at * );
87
88 static int aa_dorangeroute(struct ifaddr *, u_int, u_int, int);
89 static int aa_addsingleroute(struct ifaddr *, struct at_addr *,
90 struct at_addr *);
91 static int aa_delsingleroute(struct ifaddr *, struct at_addr *,
92 struct at_addr *);
93 static int aa_dosingleroute(struct ifaddr *, struct at_addr *,
94 struct at_addr *, int, int );
95
96 # define sateqaddr(a,b) ((a)->sat_len == (b)->sat_len && \
97 (a)->sat_family == (b)->sat_family && \
98 (a)->sat_addr.s_net == (b)->sat_addr.s_net && \
99 (a)->sat_addr.s_node == (b)->sat_addr.s_node )
100
101 extern struct timeout aarpprobe_timeout;
102
103 int
104 at_control( cmd, data, ifp, p )
105 u_long cmd;
106 caddr_t data;
107 struct ifnet *ifp;
108 struct proc *p;
109 {
110 struct ifreq *ifr = (struct ifreq *)data;
111 struct sockaddr_at *sat;
112 struct netrange *nr;
113 struct at_aliasreq *ifra = (struct at_aliasreq *)data;
114 struct at_ifaddr *aa0;
115 struct at_ifaddr *aa = 0;
116 struct ifaddr *ifa, *ifa0;
117
118 if ( ifp ) {
119 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
120 if ( aa->aa_ifp == ifp ) break;
121 }
122 }
123
124 switch ( cmd ) {
125 case SIOCAIFADDR:
126 case SIOCDIFADDR:
127 if ( ifra->ifra_addr.sat_family == AF_APPLETALK ) {
128 for ( ; aa; aa = aa->aa_next ) {
129 if ( aa->aa_ifp == ifp &&
130 sateqaddr( &aa->aa_addr, &ifra->ifra_addr )) {
131 break;
132 }
133 }
134 }
135 if ( cmd == SIOCDIFADDR && aa == 0 ) {
136 return( EADDRNOTAVAIL );
137 }
138
139
140 case SIOCSIFADDR:
141
142
143
144
145 if ( suser( p, 0 )) {
146 return( EPERM );
147 }
148
149 sat = satosat( &ifr->ifr_addr );
150 nr = (struct netrange *)sat->sat_zero;
151 if ( nr->nr_phase == 1 ) {
152 for ( ; aa; aa = aa->aa_next ) {
153 if ( aa->aa_ifp == ifp &&
154 ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
155 break;
156 }
157 }
158 } else {
159 for ( ; aa; aa = aa->aa_next ) {
160 if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 )) {
161 break;
162 }
163 }
164 }
165
166 if ( ifp == 0 )
167 panic( "at_control" );
168
169 if ( aa == (struct at_ifaddr *) 0 ) {
170 aa0 = malloc(sizeof(struct at_ifaddr), M_IFADDR, M_WAITOK);
171 bzero(aa0, sizeof(struct at_ifaddr));
172
173 if (( aa = at_ifaddr ) != NULL ) {
174
175
176
177
178
179 if ( at_ifaddr->aa_ifp->if_flags & IFF_LOOPBACK ) {
180 aa = aa0;
181 aa->aa_next = at_ifaddr;
182 at_ifaddr = aa;
183 } else {
184 for ( ; aa->aa_next; aa = aa->aa_next )
185 ;
186 aa->aa_next = aa0;
187 }
188 } else {
189 at_ifaddr = aa0;
190 }
191
192 aa = aa0;
193
194 if (( ifa = ifp->if_addrlist.tqh_first ) != NULL ) {
195 for ( ; ifa->ifa_list.tqe_next; ifa = ifa->ifa_list.tqe_next )
196 ;
197 ifa->ifa_list.tqe_next = (struct ifaddr *)aa;
198 } else {
199 ifp->if_addrlist.tqh_first = (struct ifaddr *)aa;
200 }
201
202
203 aa->aa_ifa.ifa_refcnt++;
204
205 aa->aa_ifa.ifa_addr = (struct sockaddr *)&aa->aa_addr;
206 aa->aa_ifa.ifa_dstaddr = (struct sockaddr *)&aa->aa_addr;
207 aa->aa_ifa.ifa_netmask = (struct sockaddr *)&aa->aa_netmask;
208
209
210
211
212 if ( nr->nr_phase == 1 ) {
213 aa->aa_flags &= ~AFA_PHASE2;
214 } else {
215 aa->aa_flags |= AFA_PHASE2;
216 }
217 aa->aa_ifp = ifp;
218 } else {
219 at_scrub( ifp, aa );
220 }
221 break;
222
223 case SIOCGIFADDR :
224 sat = satosat( &ifr->ifr_addr );
225 nr = (struct netrange *)sat->sat_zero;
226 if ( nr->nr_phase == 1 ) {
227 for ( ; aa; aa = aa->aa_next ) {
228 if ( aa->aa_ifp == ifp &&
229 ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
230 break;
231 }
232 }
233 } else {
234 for ( ; aa; aa = aa->aa_next ) {
235 if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 )) {
236 break;
237 }
238 }
239 }
240
241 if ( aa == (struct at_ifaddr *) 0 )
242 return( EADDRNOTAVAIL );
243 break;
244 }
245
246 switch ( cmd ) {
247 case SIOCGIFADDR:
248 *(struct sockaddr_at *)&ifr->ifr_addr = aa->aa_addr;
249
250
251 ((struct netrange *)&sat->sat_zero)->nr_phase
252 = (aa->aa_flags & AFA_PHASE2) ? 2 : 1;
253 ((struct netrange *)&sat->sat_zero)->nr_firstnet = aa->aa_firstnet;
254 ((struct netrange *)&sat->sat_zero)->nr_lastnet = aa->aa_lastnet;
255 break;
256
257 case SIOCSIFADDR:
258 return( at_ifinit( ifp, aa, (struct sockaddr_at *)&ifr->ifr_addr ));
259
260 case SIOCAIFADDR:
261 if ( sateqaddr( &ifra->ifra_addr, &aa->aa_addr )) {
262 return( 0 );
263 }
264 return( at_ifinit( ifp, aa, (struct sockaddr_at *)&ifr->ifr_addr ));
265
266 case SIOCDIFADDR:
267 at_scrub( ifp, aa );
268 ifa0 = (struct ifaddr *)aa;
269 if (( ifa = ifp->if_addrlist.tqh_first ) == ifa0 ) {
270 ifp->if_addrlist.tqh_first = ifa->ifa_list.tqe_next;
271 } else {
272 while ( ifa->ifa_list.tqe_next &&
273 ( ifa->ifa_list.tqe_next != ifa0 )) {
274 ifa = ifa->ifa_list.tqe_next;
275 }
276 if ( ifa->ifa_list.tqe_next ) {
277 ifa->ifa_list.tqe_next = ifa0->ifa_list.tqe_next;
278 } else {
279 panic( "at_control" );
280 }
281 }
282
283
284 IFAFREE(ifa0);
285
286 aa0 = aa;
287 if ( aa0 == ( aa = at_ifaddr )) {
288 at_ifaddr = aa->aa_next;
289 } else {
290 while ( aa->aa_next && ( aa->aa_next != aa0 )) {
291 aa = aa->aa_next;
292 }
293 if ( aa->aa_next ) {
294 aa->aa_next = aa0->aa_next;
295 } else {
296 panic( "at_control" );
297 }
298 }
299
300
301 IFAFREE(ifa0);
302 break;
303
304 default:
305 if ( ifp == 0 || ifp->if_ioctl == 0 )
306 return( EOPNOTSUPP );
307 return( (*ifp->if_ioctl)( ifp, cmd, data ));
308 }
309 return( 0 );
310 }
311
312
313 static int
314 at_scrub( ifp, aa )
315 struct ifnet *ifp;
316 struct at_ifaddr *aa;
317 {
318 int error;
319
320 if ( aa->aa_flags & AFA_ROUTE ) {
321 if (ifp->if_flags & IFF_LOOPBACK) {
322 if ((error = aa_delsingleroute(&aa->aa_ifa,
323 &aa->aa_addr.sat_addr,
324 &aa->aa_netmask.sat_addr))) {
325 return( error );
326 }
327 } else if (ifp->if_flags & IFF_POINTOPOINT) {
328 if ((error = rtinit( &aa->aa_ifa, RTM_DELETE, RTF_HOST)) != 0)
329 return( error );
330 } else if (ifp->if_flags & IFF_BROADCAST) {
331 error = aa_dorangeroute(&aa->aa_ifa,
332 ntohs(aa->aa_firstnet),
333 ntohs(aa->aa_lastnet),
334 RTM_DELETE );
335 }
336 aa->aa_ifa.ifa_flags &= ~IFA_ROUTE;
337 aa->aa_flags &= ~AFA_ROUTE;
338 }
339 return( 0 );
340 }
341
342 static int
343 at_ifinit( ifp, aa, sat )
344 struct ifnet *ifp;
345 struct at_ifaddr *aa;
346 struct sockaddr_at *sat;
347 {
348 struct netrange nr, onr;
349 struct sockaddr_at oldaddr;
350 int s = splnet(), error = 0, i, j, netinc, nodeinc, nnets;
351 u_int16_t net;
352
353 oldaddr = aa->aa_addr;
354 bzero( AA_SAT( aa ), sizeof( struct sockaddr_at ));
355 bcopy( sat->sat_zero, &nr, sizeof( struct netrange ));
356 bcopy( sat->sat_zero, AA_SAT( aa )->sat_zero, sizeof( struct netrange ));
357 nnets = ntohs( nr.nr_lastnet ) - ntohs( nr.nr_firstnet ) + 1;
358
359 onr.nr_firstnet = aa->aa_firstnet;
360 onr.nr_lastnet = aa->aa_lastnet;
361 aa->aa_firstnet = nr.nr_firstnet;
362 aa->aa_lastnet = nr.nr_lastnet;
363
364
365
366
367
368
369
370 if ( ifp->if_flags & IFF_LOOPBACK ) {
371 AA_SAT( aa )->sat_len = sat->sat_len;
372 AA_SAT( aa )->sat_family = AF_APPLETALK;
373 AA_SAT( aa )->sat_addr.s_net = sat->sat_addr.s_net;
374 AA_SAT( aa )->sat_addr.s_node = sat->sat_addr.s_node;
375 } else {
376 aa->aa_flags |= AFA_PROBING;
377 AA_SAT( aa )->sat_len = sizeof(struct sockaddr_at);
378 AA_SAT( aa )->sat_family = AF_APPLETALK;
379 if ( aa->aa_flags & AFA_PHASE2 ) {
380 if ( sat->sat_addr.s_net == ATADDR_ANYNET ) {
381 if ( nnets != 1 ) {
382 net = ntohs( nr.nr_firstnet ) +
383 arc4random() % ( nnets - 1 );
384 } else {
385 net = ntohs( nr.nr_firstnet );
386 }
387 } else {
388 if ( ntohs( sat->sat_addr.s_net ) < ntohs( nr.nr_firstnet ) ||
389 ntohs( sat->sat_addr.s_net ) > ntohs( nr.nr_lastnet )) {
390 aa->aa_addr = oldaddr;
391 aa->aa_firstnet = onr.nr_firstnet;
392 aa->aa_lastnet = onr.nr_lastnet;
393 splx(s);
394 return( EINVAL );
395 }
396 net = ntohs( sat->sat_addr.s_net );
397 }
398 } else {
399 net = ntohs( sat->sat_addr.s_net );
400 }
401
402 if ( sat->sat_addr.s_node == ATADDR_ANYNODE ) {
403 AA_SAT( aa )->sat_addr.s_node = arc4random();
404 } else {
405 AA_SAT( aa )->sat_addr.s_node = sat->sat_addr.s_node;
406 }
407
408 for ( i = nnets, netinc = 1; i > 0; net = ntohs( nr.nr_firstnet ) +
409 (( net - ntohs( nr.nr_firstnet ) + netinc ) % nnets ), i-- ) {
410 AA_SAT( aa )->sat_addr.s_net = htons( net );
411
412 for ( j = 0, nodeinc = arc4random() | 1; j < 256;
413 j++, AA_SAT( aa )->sat_addr.s_node += nodeinc ) {
414 if ( AA_SAT( aa )->sat_addr.s_node > 253 ||
415 AA_SAT( aa )->sat_addr.s_node < 1 ) {
416 continue;
417 }
418 aa->aa_probcnt = 10;
419 timeout_set(&aarpprobe_timeout, aarpprobe, ifp);
420
421 timeout_add(&aarpprobe_timeout, hz / 5);
422 if ( tsleep( aa, PPAUSE|PCATCH, "at_ifinit", 0 )) {
423 printf( "at_ifinit why did this happen?!\n" );
424 aa->aa_addr = oldaddr;
425 aa->aa_firstnet = onr.nr_firstnet;
426 aa->aa_lastnet = onr.nr_lastnet;
427 splx( s );
428 return( EINTR );
429 }
430 if (( aa->aa_flags & AFA_PROBING ) == 0 ) {
431 break;
432 }
433 }
434 if (( aa->aa_flags & AFA_PROBING ) == 0 ) {
435 break;
436 }
437
438 AA_SAT( aa )->sat_addr.s_node = arc4random();
439 }
440
441 if ( aa->aa_flags & AFA_PROBING ) {
442 aa->aa_addr = oldaddr;
443 aa->aa_firstnet = onr.nr_firstnet;
444 aa->aa_lastnet = onr.nr_lastnet;
445 splx( s );
446 return( EADDRINUSE );
447 }
448 }
449
450 if ( ifp->if_ioctl &&
451 ( error = (*ifp->if_ioctl)( ifp, SIOCSIFADDR, (caddr_t) aa ))) {
452 aa->aa_addr = oldaddr;
453 aa->aa_firstnet = onr.nr_firstnet;
454 aa->aa_lastnet = onr.nr_lastnet;
455 splx( s );
456 return( error );
457 }
458
459 bzero(&aa->aa_netmask, sizeof(aa->aa_netmask));
460 aa->aa_netmask.sat_len = sizeof(struct sockaddr_at);
461 aa->aa_netmask.sat_family = AF_APPLETALK;
462 aa->aa_netmask.sat_addr.s_net = 0xffff;
463 aa->aa_netmask.sat_addr.s_node = 0;
464
465 aa->aa_ifa.ifa_netmask =(struct sockaddr *) &(aa->aa_netmask);
466
467
468
469
470
471 bzero(&aa->aa_broadaddr, sizeof(aa->aa_broadaddr));
472 aa->aa_broadaddr.sat_len = sizeof(struct sockaddr_at);
473 aa->aa_broadaddr.sat_family = AF_APPLETALK;
474
475 aa->aa_ifa.ifa_metric = ifp->if_metric;
476 if (ifp->if_flags & IFF_BROADCAST) {
477 aa->aa_broadaddr.sat_addr.s_net = htons(0);
478 aa->aa_broadaddr.sat_addr.s_node = 0xff;
479 aa->aa_ifa.ifa_broadaddr = (struct sockaddr *) &aa->aa_broadaddr;
480
481 error = aa_dorangeroute(&aa->aa_ifa,
482 ntohs(aa->aa_firstnet), ntohs(aa->aa_lastnet), RTM_ADD );
483 }
484 else if (ifp->if_flags & IFF_POINTOPOINT) {
485 struct at_addr rtaddr, rtmask;
486
487 bzero(&rtaddr, sizeof(rtaddr));
488 bzero(&rtmask, sizeof(rtmask));
489
490 aa->aa_ifa.ifa_dstaddr = (struct sockaddr *) &aa->aa_broadaddr;
491 error = aa_addsingleroute(&aa->aa_ifa, &rtaddr, &rtmask);
492 }
493 else if ( ifp->if_flags & IFF_LOOPBACK ) {
494 struct at_addr rtaddr, rtmask;
495
496 bzero(&rtaddr, sizeof(rtaddr));
497 bzero(&rtmask, sizeof(rtmask));
498 rtaddr.s_net = AA_SAT( aa )->sat_addr.s_net;
499 rtaddr.s_node = AA_SAT( aa )->sat_addr.s_node;
500 rtmask.s_net = 0xffff;
501 rtmask.s_node = 0x0;
502 error = aa_addsingleroute(&aa->aa_ifa, &rtaddr, &rtmask);
503 }
504
505 if ( error ) {
506 at_scrub( ifp, aa );
507 aa->aa_addr = oldaddr;
508 aa->aa_firstnet = onr.nr_firstnet;
509 aa->aa_lastnet = onr.nr_lastnet;
510 splx( s );
511 return( error );
512 }
513
514 aa->aa_ifa.ifa_flags |= IFA_ROUTE;
515 aa->aa_flags |= AFA_ROUTE;
516 splx( s );
517 return( 0 );
518 }
519
520 int
521 at_broadcast( sat )
522 struct sockaddr_at *sat;
523 {
524 struct at_ifaddr *aa;
525
526 if ( sat->sat_addr.s_node != ATADDR_BCAST ) {
527 return( 0 );
528 }
529 if ( sat->sat_addr.s_net == ATADDR_ANYNET ) {
530 return( 1 );
531 } else {
532 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
533 if (( aa->aa_ifp->if_flags & IFF_BROADCAST ) &&
534 ( ntohs( sat->sat_addr.s_net ) >= ntohs( aa->aa_firstnet ) &&
535 ntohs( sat->sat_addr.s_net ) <= ntohs( aa->aa_lastnet ))) {
536 return( 1 );
537 }
538 }
539 }
540 return( 0 );
541 }
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559 static int
560 aa_dorangeroute(struct ifaddr *ifa, u_int bot, u_int top, int cmd)
561 {
562 u_int mask1;
563 struct at_addr addr;
564 struct at_addr mask;
565 int error;
566
567
568
569
570 if (bot > top) return (EINVAL);
571
572 addr.s_node = 0;
573 mask.s_node = 0;
574
575
576
577
578
579 while (bot <= top) {
580 mask1 = 1;
581 while ((( bot & ~mask1) >= bot)
582 && (( bot | mask1) <= top)) {
583 mask1 <<= 1;
584 mask1 |= 1;
585 }
586 mask1 >>= 1;
587 mask.s_net = htons(~mask1);
588 addr.s_net = htons(bot);
589 if(cmd == RTM_ADD) {
590 error = aa_addsingleroute(ifa,&addr,&mask);
591 if (error) {
592
593 return (error);
594 }
595 } else {
596 error = aa_delsingleroute(ifa,&addr,&mask);
597 }
598 bot = (bot | mask1) + 1;
599 }
600 return 0;
601 }
602
603 static int
604 aa_addsingleroute(struct ifaddr *ifa,
605 struct at_addr *addr, struct at_addr *mask)
606 {
607 int error;
608
609 #if 0
610 printf("aa_addsingleroute: %x.%x mask %x.%x ...\n",
611 ntohs(addr->s_net), addr->s_node,
612 ntohs(mask->s_net), mask->s_node);
613 #endif
614
615 error = aa_dosingleroute(ifa, addr, mask, RTM_ADD, RTF_UP);
616 if (error)
617 printf("aa_addsingleroute: error %d\n", error);
618 return(error);
619 }
620
621 static int
622 aa_delsingleroute(struct ifaddr *ifa,
623 struct at_addr *addr, struct at_addr *mask)
624 {
625 int error;
626
627 error = aa_dosingleroute(ifa, addr, mask, RTM_DELETE, 0);
628 if (error)
629 printf("aa_delsingleroute: error %d\n", error);
630 return(error);
631 }
632
633 static int
634 aa_dosingleroute(struct ifaddr *ifa,
635 struct at_addr *at_addr, struct at_addr *at_mask, int cmd, int flags)
636 {
637 struct sockaddr_at addr, mask;
638
639 bzero(&addr, sizeof(addr));
640 bzero(&mask, sizeof(mask));
641 addr.sat_family = AF_APPLETALK;
642 addr.sat_len = sizeof(struct sockaddr_at);
643 addr.sat_addr.s_net = at_addr->s_net;
644 addr.sat_addr.s_node = at_addr->s_node;
645 mask.sat_family = AF_APPLETALK;
646 mask.sat_len = sizeof(struct sockaddr_at);
647 mask.sat_addr.s_net = at_mask->s_net;
648 mask.sat_addr.s_node = at_mask->s_node;
649 if (at_mask->s_node)
650 flags |= RTF_HOST;
651 return(rtrequest(cmd, (struct sockaddr *) &addr,
652 (flags & RTF_HOST)?(ifa->ifa_dstaddr):(ifa->ifa_addr),
653 (struct sockaddr *) &mask, flags, NULL, 0));
654 }