2 * $Id: at_control.c,v 1.2 2001-06-29 14:14:47 rufustfirefly Exp $
4 * Copyright (c) 1990,1991 Regents of The University of Michigan.
10 #endif /* HAVE_CONFIG_H */
12 #include <sys/param.h>
13 #include <sys/systm.h>
18 #include <sys/types.h>
19 #include <sys/errno.h>
20 #include <sys/ioctl.h>
23 #include <sys/kernel.h>
25 #include <sys/socket.h>
26 #include <sys/socketvar.h>
29 #include <net/route.h>
30 #include <netinet/in.h>
32 #include <netinet/if_ether.h>
43 # define sateqaddr(a,b) ((a)->sat_len == (b)->sat_len && \
44 (a)->sat_family == (b)->sat_family && \
45 (a)->sat_addr.s_net == (b)->sat_addr.s_net && \
46 (a)->sat_addr.s_node == (b)->sat_addr.s_node )
49 struct sockaddr_at *sat;
52 hp->afh_nethash = sat->sat_addr.s_net;
53 hp->afh_hosthash = ( sat->sat_addr.s_net << 8 ) +
58 * Note the magic to get ifa_ifwithnet() to work without adding an
59 * ifaddr entry for each net in our local range.
61 atalk_netmatch( sat1, sat2 )
62 struct sockaddr_at *sat1, *sat2;
66 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
67 if ( AA_SAT( aa ) == sat1 ) {
72 return( ntohs( aa->aa_firstnet ) <= ntohs( sat2->sat_addr.s_net ) &&
73 ntohs( aa->aa_lastnet ) >= ntohs( sat2->sat_addr.s_net ));
75 return( sat1->sat_addr.s_net == sat2->sat_addr.s_net );
79 at_control( cmd, data, ifp )
84 struct ifreq *ifr = (struct ifreq *)data;
85 struct sockaddr_at *sat;
88 struct at_aliasreq *ifra = (struct at_aliasreq *)data;
89 struct at_ifaddr *aa0;
91 struct at_ifaddr *aa = 0;
96 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
97 if ( aa->aa_ifp == ifp ) break;
105 if ( ifra->ifra_addr.sat_family == AF_APPLETALK ) {
106 for ( ; aa; aa = aa->aa_next ) {
107 if ( aa->aa_ifp == ifp &&
108 sateqaddr( &aa->aa_addr, &ifra->ifra_addr )) {
113 if ( cmd == SIOCDIFADDR && aa == 0 ) {
114 return( EADDRNOTAVAIL );
122 * What a great idea this is: Let's reverse the meaning of
125 if ( suser( u.u_cred, &u.u_acflag )) {
134 sat = satosat( &ifr->ifr_addr );
135 nr = (struct netrange *)sat->sat_zero;
136 if ( nr->nr_phase == 1 ) {
137 for ( ; aa; aa = aa->aa_next ) {
138 if ( aa->aa_ifp == ifp &&
139 ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
143 } else { /* default to phase 2 */
144 for ( ; aa; aa = aa->aa_next ) {
145 if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 )) {
152 panic( "at_control" );
154 if ( aa == (struct at_ifaddr *) 0 ) {
155 m = m_getclr( M_WAIT, MT_IFADDR );
156 if ( m == (struct mbuf *)NULL ) {
160 if (( aa = at_ifaddr ) != NULL ) {
162 * Don't let the loopback be first, since the first
163 * address is the machine's default address for
166 if ( at_ifaddr->aa_ifp->if_flags & IFF_LOOPBACK ) {
167 aa = mtod( m, struct at_ifaddr *);
168 aa->aa_next = at_ifaddr;
171 for ( ; aa->aa_next; aa = aa->aa_next )
173 aa->aa_next = mtod( m, struct at_ifaddr *);
176 at_ifaddr = mtod( m, struct at_ifaddr *);
179 aa = mtod( m, struct at_ifaddr *);
181 if (( ifa = ifp->if_addrlist ) != NULL ) {
182 for ( ; ifa->ifa_next; ifa = ifa->ifa_next )
184 ifa->ifa_next = (struct ifaddr *)aa;
186 ifp->if_addrlist = (struct ifaddr *)aa;
190 aa->aa_ifa.ifa_addr = (struct sockaddr *)&aa->aa_addr;
191 aa->aa_ifa.ifa_dstaddr = (struct sockaddr *)&aa->aa_addr;
192 aa->aa_ifa.ifa_netmask = (struct sockaddr *)&aa->aa_netmask;
196 * Set/clear the phase 2 bit.
198 if ( nr->nr_phase == 1 ) {
199 aa->aa_flags &= ~AFA_PHASE2;
201 aa->aa_flags |= AFA_PHASE2;
210 sat = satosat( &ifr->ifr_addr );
211 nr = (struct netrange *)sat->sat_zero;
212 if ( nr->nr_phase == 1 ) {
213 for ( ; aa; aa = aa->aa_next ) {
214 if ( aa->aa_ifp == ifp &&
215 ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
219 } else { /* default to phase 2 */
220 for ( ; aa; aa = aa->aa_next ) {
221 if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 )) {
227 if ( aa == (struct at_ifaddr *) 0 )
228 return( EADDRNOTAVAIL );
235 *(struct sockaddr_at *)&ifr->ifr_addr = aa->aa_addr;
237 ifr->ifr_addr = aa->aa_addr;
242 return( at_ifinit( ifp, aa, (struct sockaddr_at *)&ifr->ifr_addr ));
246 if ( sateqaddr( &ifra->ifra_addr, &aa->aa_addr )) {
249 return( at_ifinit( ifp, aa, (struct sockaddr_at *)&ifr->ifr_addr ));
253 if (( ifa = ifp->if_addrlist ) == (struct ifaddr *)aa ) {
254 ifp->if_addrlist = ifa->ifa_next;
256 while ( ifa->ifa_next && ( ifa->ifa_next != (struct ifaddr *)aa )) {
259 if ( ifa->ifa_next ) {
260 ifa->ifa_next = ((struct ifaddr *)aa)->ifa_next;
262 panic( "at_control" );
267 if ( aa0 == ( aa = at_ifaddr )) {
268 at_ifaddr = aa->aa_next;
270 while ( aa->aa_next && ( aa->aa_next != aa0 )) {
274 aa->aa_next = aa0->aa_next;
276 panic( "at_control" );
279 m_free( dtom( aa0 ));
284 if ( ifp == 0 || ifp->if_ioctl == 0 )
285 return( EOPNOTSUPP );
286 return( (*ifp->if_ioctl)( ifp, cmd, data ));
293 struct at_ifaddr *aa;
296 struct sockaddr_at netsat;
299 #endif /* ! BSD4_4 */
301 if ( aa->aa_flags & AFA_ROUTE ) {
303 if (( error = rtinit( &(aa->aa_ifa), RTM_DELETE,
304 ( ifp->if_flags & IFF_LOOPBACK ) ? RTF_HOST : 0 )) != 0 ) {
307 aa->aa_ifa.ifa_flags &= ~IFA_ROUTE;
309 if ( ifp->if_flags & IFF_LOOPBACK ) {
310 rtinit( &aa->aa_addr, &aa->aa_addr, SIOCDELRT, RTF_HOST );
312 bzero( &netsat, sizeof( struct sockaddr_at ));
313 netsat.sat_family = AF_APPLETALK;
314 netsat.sat_addr.s_node = ATADDR_ANYNODE;
317 * If the range is the full 0-fffe range, just use
320 if ( aa->aa_firstnet == htons( 0x0000 ) &&
321 aa->aa_lastnet == htons( 0xfffe )) {
322 netsat.sat_addr.s_net = 0;
323 rtinit((struct sockaddr *)&netsat, &aa->aa_addr,
326 for ( net = ntohs( aa->aa_firstnet );
327 net <= ntohs( aa->aa_lastnet ); net++ ) {
328 netsat.sat_addr.s_net = htons( net );
329 rtinit((struct sockaddr *)&netsat, &aa->aa_addr,
335 aa->aa_flags &= ~AFA_ROUTE;
340 extern struct timeval time;
342 at_ifinit( ifp, aa, sat )
344 struct at_ifaddr *aa;
345 struct sockaddr_at *sat;
347 struct netrange nr, onr;
349 struct sockaddr_at oldaddr;
351 struct sockaddr oldaddr;
353 struct sockaddr_at netaddr;
354 int s = splimp(), error = 0, i, j, netinc, nodeinc, nnets;
357 oldaddr = aa->aa_addr;
358 bzero( AA_SAT( aa ), sizeof( struct sockaddr_at ));
359 bcopy( sat->sat_zero, &nr, sizeof( struct netrange ));
360 nnets = ntohs( nr.nr_lastnet ) - ntohs( nr.nr_firstnet ) + 1;
362 onr.nr_firstnet = aa->aa_firstnet;
363 onr.nr_lastnet = aa->aa_lastnet;
364 aa->aa_firstnet = nr.nr_firstnet;
365 aa->aa_lastnet = nr.nr_lastnet;
368 * We could eliminate the need for a second phase 1 probe (post
369 * autoconf) if we check whether we're resetting the node. Note
370 * that phase 1 probes use only nodes, not net.node pairs. Under
371 * phase 2, both the net and node must be the same.
373 if ( ifp->if_flags & IFF_LOOPBACK ) {
375 AA_SAT( aa )->sat_len = sat->sat_len;
377 AA_SAT( aa )->sat_family = AF_APPLETALK;
378 AA_SAT( aa )->sat_addr.s_net = sat->sat_addr.s_net;
379 AA_SAT( aa )->sat_addr.s_node = sat->sat_addr.s_node;
381 aa->aa_flags |= AFA_PROBING;
382 AA_SAT( aa )->sat_family = AF_APPLETALK;
383 if ( aa->aa_flags & AFA_PHASE2 ) {
384 if ( sat->sat_addr.s_net == ATADDR_ANYNET ) {
386 net = ntohs( nr.nr_firstnet ) + time.tv_sec % ( nnets - 1 );
388 net = ntohs( nr.nr_firstnet );
391 if ( ntohs( sat->sat_addr.s_net ) < ntohs( nr.nr_firstnet ) ||
392 ntohs( sat->sat_addr.s_net ) > ntohs( nr.nr_lastnet )) {
393 aa->aa_addr = oldaddr;
394 aa->aa_firstnet = onr.nr_firstnet;
395 aa->aa_lastnet = onr.nr_lastnet;
398 net = ntohs( sat->sat_addr.s_net );
401 net = ntohs( sat->sat_addr.s_net );
404 if ( sat->sat_addr.s_node == ATADDR_ANYNODE ) {
405 AA_SAT( aa )->sat_addr.s_node = time.tv_sec;
407 AA_SAT( aa )->sat_addr.s_node = sat->sat_addr.s_node;
410 for ( i = nnets, netinc = 1; i > 0; net = ntohs( nr.nr_firstnet ) +
411 (( net - ntohs( nr.nr_firstnet ) + netinc ) % nnets ), i-- ) {
412 AA_SAT( aa )->sat_addr.s_net = htons( net );
414 for ( j = 0, nodeinc = time.tv_sec | 1; j < 256;
415 j++, AA_SAT( aa )->sat_addr.s_node += nodeinc ) {
416 if ( AA_SAT( aa )->sat_addr.s_node > 253 ||
417 AA_SAT( aa )->sat_addr.s_node < 1 ) {
421 timeout( aarpprobe, (caddr_t)ifp, hz / 5 );
423 if ( sleep( aa, PSLEP|PCATCH )) {
424 printf( "at_ifinit why did this happen?!\n" );
425 aa->aa_addr = oldaddr;
426 aa->aa_firstnet = onr.nr_firstnet;
427 aa->aa_lastnet = onr.nr_lastnet;
431 if (( aa->aa_flags & AFA_PROBING ) == 0 ) {
435 if (( aa->aa_flags & AFA_PROBING ) == 0 ) {
438 /* reset node for next network */
439 AA_SAT( aa )->sat_addr.s_node = time.tv_sec;
442 if ( aa->aa_flags & AFA_PROBING ) {
443 aa->aa_addr = oldaddr;
444 aa->aa_firstnet = onr.nr_firstnet;
445 aa->aa_lastnet = onr.nr_lastnet;
447 return( EADDRINUSE );
451 if ( ifp->if_ioctl &&
452 ( error = (*ifp->if_ioctl)( ifp, SIOCSIFADDR, aa ))) {
454 aa->aa_addr = oldaddr;
455 aa->aa_firstnet = onr.nr_firstnet;
456 aa->aa_lastnet = onr.nr_lastnet;
461 aa->aa_netmask.sat_len = 6;
462 aa->aa_netmask.sat_family = AF_APPLETALK;
463 aa->aa_netmask.sat_addr.s_net = 0xffff;
464 aa->aa_netmask.sat_addr.s_node = 0;
467 if ( ifp->if_flags & IFF_LOOPBACK ) {
469 rtinit( &aa->aa_addr, &aa->aa_addr, (int)SIOCADDRT,
472 error = rtinit( &(aa->aa_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP );
473 #endif /* ! BSD4_4 */
477 * rtrequest looks for point-to-point links first. The
478 * broadaddr is in the same spot as the destaddr. So, if
479 * ATADDR_ANYNET is 0, and we don't fill in the broadaddr, we
480 * get 0.0 routed out the ether interface. So, initialize the
481 * broadaddr, even tho we don't use it.
483 * We *could* use the broadaddr field to reduce some of the
484 * sockaddr_at overloading that we've done. E.g. Just send
485 * to INTERFACE-NET.255, and have the kernel reroute that
486 * to broadaddr, which would be 0.255 for phase 2 interfaces,
487 * and IFACE-NET.255 for phase 1 interfaces.
489 ((struct sockaddr_at *)&aa->aa_broadaddr)->sat_addr.s_net =
491 ((struct sockaddr_at *)&aa->aa_broadaddr)->sat_addr.s_node =
494 bzero( &netaddr, sizeof( struct sockaddr_at ));
495 netaddr.sat_family = AF_APPLETALK;
496 netaddr.sat_addr.s_node = ATADDR_ANYNODE;
497 if (( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
498 netaddr.sat_addr.s_net = AA_SAT( aa )->sat_addr.s_net;
499 rtinit((struct sockaddr *)&netaddr, &aa->aa_addr,
500 (int)SIOCADDRT, RTF_UP );
503 * If the range is the full 0-fffe range, just use
506 if ( aa->aa_firstnet == htons( 0x0000 ) &&
507 aa->aa_lastnet == htons( 0xfffe )) {
508 netaddr.sat_addr.s_net = 0;
509 rtinit((struct sockaddr *)&netaddr, &aa->aa_addr,
510 (int)SIOCADDRT, RTF_UP );
512 for ( net = ntohs( aa->aa_firstnet );
513 net <= ntohs( aa->aa_lastnet ); net++ ) {
514 netaddr.sat_addr.s_net = htons( net );
515 rtinit((struct sockaddr *)&netaddr, &aa->aa_addr,
516 (int)SIOCADDRT, RTF_UP );
521 error = rtinit( &(aa->aa_ifa), (int)RTM_ADD, RTF_UP );
522 #endif /* ! BSD4_4 */
525 aa->aa_addr = oldaddr;
526 aa->aa_firstnet = onr.nr_firstnet;
527 aa->aa_lastnet = onr.nr_lastnet;
533 aa->aa_ifa.ifa_flags |= IFA_ROUTE;
535 aa->aa_flags |= AFA_ROUTE;
541 struct sockaddr_at *sat;
543 struct at_ifaddr *aa;
545 if ( sat->sat_addr.s_node != ATADDR_BCAST ) {
548 if ( sat->sat_addr.s_net == 0 ) {
551 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
552 if (( aa->aa_ifp->if_flags & IFF_BROADCAST ) &&
553 ( ntohs( sat->sat_addr.s_net ) >= ntohs( aa->aa_firstnet ) &&
554 ntohs( sat->sat_addr.s_net ) <= ntohs( aa->aa_lastnet ))) {
564 struct at_ifaddr *aa;
568 while ( aa = at_ifaddr ) {
571 at_ifaddr = aa->aa_next;
572 if (( ifa = ifp->if_addrlist ) == (struct ifaddr *)aa ) {
573 ifp->if_addrlist = ifa->ifa_next;
575 while ( ifa->ifa_next &&
576 ( ifa->ifa_next != (struct ifaddr *)aa )) {
579 if ( ifa->ifa_next ) {
580 ifa->ifa_next = ((struct ifaddr *)aa)->ifa_next;