at_control.c (15885) | at_control.c (17254) |
---|---|
1/* 2 * Copyright (c) 1990,1991 Regents of The University of Michigan. 3 * All Rights Reserved. 4 */ 5 6#include <sys/param.h> 7#include <sys/systm.h> | 1/* 2 * Copyright (c) 1990,1991 Regents of The University of Michigan. 3 * All Rights Reserved. 4 */ 5 6#include <sys/param.h> 7#include <sys/systm.h> |
8#ifdef ibm032 9#include <sys/dir.h> 10#endif ibm032 | |
11#include <sys/proc.h> | 8#include <sys/proc.h> |
12#ifndef BSD4_4 13#include <sys/user.h> 14#endif | |
15#include <sys/types.h> 16#include <sys/errno.h> 17#include <sys/ioctl.h> 18#include <sys/mbuf.h> | 9#include <sys/types.h> 10#include <sys/errno.h> 11#include <sys/ioctl.h> 12#include <sys/mbuf.h> |
19#ifndef _IBMR2 | |
20#include <sys/kernel.h> | 13#include <sys/kernel.h> |
21#endif _IBMR2 | |
22#include <sys/socket.h> 23#include <sys/socketvar.h> 24#include <net/if.h> | 14#include <sys/socket.h> 15#include <sys/socketvar.h> 16#include <net/if.h> |
25/* #include <net/af.h> */ | |
26#include <net/route.h> 27#include <netinet/in.h> 28#undef s_net 29#include <netinet/if_ether.h> | 17#include <net/route.h> 18#include <netinet/in.h> 19#undef s_net 20#include <netinet/if_ether.h> |
30#ifdef _IBMR2 31#include <net/spl.h> 32#endif _IBMR2 | |
33 34#include "at.h" 35#include "at_var.h" 36#include "aarp.h" 37#include "phase2.h" 38#include <netatalk/at_extern.h> 39 | 21 22#include "at.h" 23#include "at_var.h" 24#include "aarp.h" 25#include "phase2.h" 26#include <netatalk/at_extern.h> 27 |
28static int aa_addrangeroute(struct ifaddr *ifa, int first, int last); 29static int aa_addsingleroute(struct ifaddr *ifa, 30 struct at_addr *addr, struct at_addr *mask); 31static int aa_delsingleroute(struct ifaddr *ifa, 32 struct at_addr *addr, struct at_addr *mask); 33static int aa_dosingleroute(struct ifaddr *ifa, struct at_addr *addr, 34 struct at_addr *mask, int cmd, int flags); |
|
40static int at_scrub( struct ifnet *ifp, struct at_ifaddr *aa ); 41static int at_ifinit( struct ifnet *ifp, struct at_ifaddr *aa, 42 struct sockaddr_at *sat ); 43 | 35static int at_scrub( struct ifnet *ifp, struct at_ifaddr *aa ); 36static int at_ifinit( struct ifnet *ifp, struct at_ifaddr *aa, 37 struct sockaddr_at *sat ); 38 |
44#ifdef BSD4_4 | |
45# define sateqaddr(a,b) ((a)->sat_len == (b)->sat_len && \ 46 (a)->sat_family == (b)->sat_family && \ 47 (a)->sat_addr.s_net == (b)->sat_addr.s_net && \ 48 (a)->sat_addr.s_node == (b)->sat_addr.s_node ) | 39# define sateqaddr(a,b) ((a)->sat_len == (b)->sat_len && \ 40 (a)->sat_family == (b)->sat_family && \ 41 (a)->sat_addr.s_net == (b)->sat_addr.s_net && \ 42 (a)->sat_addr.s_node == (b)->sat_addr.s_node ) |
49#else BSD4_4 50atalk_hash( sat, hp ) 51 struct sockaddr_at *sat; 52 struct afhash *hp; 53{ 54 hp->afh_nethash = sat->sat_addr.s_net; 55 hp->afh_hosthash = ( sat->sat_addr.s_net << 8 ) + 56 sat->sat_addr.s_node; 57} | |
58 | 43 |
59/* 60 * Note the magic to get ifa_ifwithnet() to work without adding an 61 * ifaddr entry for each net in our local range. 62 */ | |
63int | 44int |
64atalk_netmatch( sat1, sat2 ) 65 struct sockaddr_at *sat1, *sat2; 66{ 67 struct at_ifaddr *aa; 68 69 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { 70 if ( AA_SAT( aa ) == sat1 ) { 71 break; 72 } 73 } 74 if ( aa ) { 75 return( ntohs( aa->aa_firstnet ) <= ntohs( sat2->sat_addr.s_net ) && 76 ntohs( aa->aa_lastnet ) >= ntohs( sat2->sat_addr.s_net )); 77 } 78 return( sat1->sat_addr.s_net == sat2->sat_addr.s_net ); 79} 80#endif BSD4_4 81 82int | |
83at_control( int cmd, caddr_t data, struct ifnet *ifp, struct proc *p ) 84{ 85 struct ifreq *ifr = (struct ifreq *)data; 86 struct sockaddr_at *sat; 87 struct netrange *nr; | 45at_control( int cmd, caddr_t data, struct ifnet *ifp, struct proc *p ) 46{ 47 struct ifreq *ifr = (struct ifreq *)data; 48 struct sockaddr_at *sat; 49 struct netrange *nr; |
88#ifdef BSD4_4 | |
89 struct at_aliasreq *ifra = (struct at_aliasreq *)data; 90 struct at_ifaddr *aa0; | 50 struct at_aliasreq *ifra = (struct at_aliasreq *)data; 51 struct at_ifaddr *aa0; |
91#endif BSD4_4 | |
92 struct at_ifaddr *aa = 0; 93 struct mbuf *m; 94 struct ifaddr *ifa; 95 96 if ( ifp ) { 97 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { 98 if ( aa->aa_ifp == ifp ) break; 99 } 100 } 101 102 switch ( cmd ) { | 52 struct at_ifaddr *aa = 0; 53 struct mbuf *m; 54 struct ifaddr *ifa; 55 56 if ( ifp ) { 57 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { 58 if ( aa->aa_ifp == ifp ) break; 59 } 60 } 61 62 switch ( cmd ) { |
103#ifdef BSD4_4 | |
104 case SIOCAIFADDR: 105 case SIOCDIFADDR: 106 if ( ifra->ifra_addr.sat_family == AF_APPLETALK ) { 107 for ( ; aa; aa = aa->aa_next ) { 108 if ( aa->aa_ifp == ifp && 109 sateqaddr( &aa->aa_addr, &ifra->ifra_addr )) { 110 break; 111 } 112 } 113 } 114 if ( cmd == SIOCDIFADDR && aa == 0 ) { 115 return( EADDRNOTAVAIL ); 116 } 117 /*FALLTHROUGH*/ | 63 case SIOCAIFADDR: 64 case SIOCDIFADDR: 65 if ( ifra->ifra_addr.sat_family == AF_APPLETALK ) { 66 for ( ; aa; aa = aa->aa_next ) { 67 if ( aa->aa_ifp == ifp && 68 sateqaddr( &aa->aa_addr, &ifra->ifra_addr )) { 69 break; 70 } 71 } 72 } 73 if ( cmd == SIOCDIFADDR && aa == 0 ) { 74 return( EADDRNOTAVAIL ); 75 } 76 /*FALLTHROUGH*/ |
118#endif BSD4_4 | |
119 120 case SIOCSIFADDR: | 77 78 case SIOCSIFADDR: |
121#ifdef BSD4_4 122 /* 123 * What a great idea this is: Let's reverse the meaning of 124 * the return... 125 */ 126#if defined( __FreeBSD__ ) | |
127 if ( suser(p->p_ucred, &p->p_acflag) ) { | 79 if ( suser(p->p_ucred, &p->p_acflag) ) { |
128#else 129 if ( suser( u.u_cred, &u.u_acflag )) { 130#endif | |
131 return( EPERM ); 132 } | 80 return( EPERM ); 81 } |
133#else BSD4_4 134 if ( !suser()) { 135 return( EPERM ); 136 } 137#endif BSD4_4 | |
138 139 sat = satosat( &ifr->ifr_addr ); 140 nr = (struct netrange *)sat->sat_zero; 141 if ( nr->nr_phase == 1 ) { 142 for ( ; aa; aa = aa->aa_next ) { 143 if ( aa->aa_ifp == ifp && 144 ( aa->aa_flags & AFA_PHASE2 ) == 0 ) { 145 break; --- 40 unchanged lines hidden (view full) --- 186 if (( ifa = ifp->if_addrlist ) != NULL ) { 187 for ( ; ifa->ifa_next; ifa = ifa->ifa_next ) 188 ; 189 ifa->ifa_next = (struct ifaddr *)aa; 190 } else { 191 ifp->if_addrlist = (struct ifaddr *)aa; 192 } 193 | 82 83 sat = satosat( &ifr->ifr_addr ); 84 nr = (struct netrange *)sat->sat_zero; 85 if ( nr->nr_phase == 1 ) { 86 for ( ; aa; aa = aa->aa_next ) { 87 if ( aa->aa_ifp == ifp && 88 ( aa->aa_flags & AFA_PHASE2 ) == 0 ) { 89 break; --- 40 unchanged lines hidden (view full) --- 130 if (( ifa = ifp->if_addrlist ) != NULL ) { 131 for ( ; ifa->ifa_next; ifa = ifa->ifa_next ) 132 ; 133 ifa->ifa_next = (struct ifaddr *)aa; 134 } else { 135 ifp->if_addrlist = (struct ifaddr *)aa; 136 } 137 |
194#ifdef BSD4_4 | |
195 aa->aa_ifa.ifa_addr = (struct sockaddr *)&aa->aa_addr; 196 aa->aa_ifa.ifa_dstaddr = (struct sockaddr *)&aa->aa_addr; 197 aa->aa_ifa.ifa_netmask = (struct sockaddr *)&aa->aa_netmask; | 138 aa->aa_ifa.ifa_addr = (struct sockaddr *)&aa->aa_addr; 139 aa->aa_ifa.ifa_dstaddr = (struct sockaddr *)&aa->aa_addr; 140 aa->aa_ifa.ifa_netmask = (struct sockaddr *)&aa->aa_netmask; |
198#endif BSD4_4 | |
199 200 /* 201 * Set/clear the phase 2 bit. 202 */ 203 if ( nr->nr_phase == 1 ) { 204 aa->aa_flags &= ~AFA_PHASE2; 205 } else { 206 aa->aa_flags |= AFA_PHASE2; --- 24 unchanged lines hidden (view full) --- 231 232 if ( aa == (struct at_ifaddr *) 0 ) 233 return( EADDRNOTAVAIL ); 234 break; 235 } 236 237 switch ( cmd ) { 238 case SIOCGIFADDR: | 141 142 /* 143 * Set/clear the phase 2 bit. 144 */ 145 if ( nr->nr_phase == 1 ) { 146 aa->aa_flags &= ~AFA_PHASE2; 147 } else { 148 aa->aa_flags |= AFA_PHASE2; --- 24 unchanged lines hidden (view full) --- 173 174 if ( aa == (struct at_ifaddr *) 0 ) 175 return( EADDRNOTAVAIL ); 176 break; 177 } 178 179 switch ( cmd ) { 180 case SIOCGIFADDR: |
239#ifdef BSD4_4 240 *(struct sockaddr_at *)&ifr->ifr_addr = aa->aa_addr; 241#else BSD4_4 242 ifr->ifr_addr = aa->aa_addr; 243#endif BSD4_4 | 181 sat = (struct sockaddr_at *)&ifr->ifr_addr; 182 *sat = aa->aa_addr; 183 ((struct netrange *)&sat->sat_zero)->nr_phase 184 = (aa->aa_flags & AFA_PHASE2) ? 2 : 1; 185 ((struct netrange *)&sat->sat_zero)->nr_firstnet = aa->aa_firstnet; 186 ((struct netrange *)&sat->sat_zero)->nr_lastnet = aa->aa_lastnet; |
244 break; 245 246 case SIOCSIFADDR: 247 return( at_ifinit( ifp, aa, (struct sockaddr_at *)&ifr->ifr_addr )); 248 | 187 break; 188 189 case SIOCSIFADDR: 190 return( at_ifinit( ifp, aa, (struct sockaddr_at *)&ifr->ifr_addr )); 191 |
249#ifdef BSD4_4 | |
250 case SIOCAIFADDR: 251 if ( sateqaddr( &ifra->ifra_addr, &aa->aa_addr )) { 252 return( 0 ); 253 } 254 return( at_ifinit( ifp, aa, (struct sockaddr_at *)&ifr->ifr_addr )); 255 256 case SIOCDIFADDR: 257 at_scrub( ifp, aa ); --- 20 unchanged lines hidden (view full) --- 278 if ( aa->aa_next ) { 279 aa->aa_next = aa0->aa_next; 280 } else { 281 panic( "at_control" ); 282 } 283 } 284 m_free( dtom( aa0 )); 285 break; | 192 case SIOCAIFADDR: 193 if ( sateqaddr( &ifra->ifra_addr, &aa->aa_addr )) { 194 return( 0 ); 195 } 196 return( at_ifinit( ifp, aa, (struct sockaddr_at *)&ifr->ifr_addr )); 197 198 case SIOCDIFADDR: 199 at_scrub( ifp, aa ); --- 20 unchanged lines hidden (view full) --- 220 if ( aa->aa_next ) { 221 aa->aa_next = aa0->aa_next; 222 } else { 223 panic( "at_control" ); 224 } 225 } 226 m_free( dtom( aa0 )); 227 break; |
286#endif BSD4_4 | |
287 288 default: 289 if ( ifp == 0 || ifp->if_ioctl == 0 ) 290 return( EOPNOTSUPP ); 291 return( (*ifp->if_ioctl)( ifp, cmd, data )); 292 } 293 return( 0 ); 294} | 228 229 default: 230 if ( ifp == 0 || ifp->if_ioctl == 0 ) 231 return( EOPNOTSUPP ); 232 return( (*ifp->if_ioctl)( ifp, cmd, data )); 233 } 234 return( 0 ); 235} |
236 |
|
295static int 296at_scrub( ifp, aa ) 297 struct ifnet *ifp; 298 struct at_ifaddr *aa; 299{ | 237static int 238at_scrub( ifp, aa ) 239 struct ifnet *ifp; 240 struct at_ifaddr *aa; 241{ |
300#ifndef BSD4_4 301 struct sockaddr_at netsat; 302 u_short net; 303#endif BSD4_4 | |
304 int error; 305 306 if ( aa->aa_flags & AFA_ROUTE ) { | 242 int error; 243 244 if ( aa->aa_flags & AFA_ROUTE ) { |
307#ifdef BSD4_4 | |
308 if (( error = rtinit( &(aa->aa_ifa), RTM_DELETE, 309 ( ifp->if_flags & IFF_LOOPBACK ) ? RTF_HOST : 0 )) != 0 ) { 310 return( error ); 311 } 312 aa->aa_ifa.ifa_flags &= ~IFA_ROUTE; | 245 if (( error = rtinit( &(aa->aa_ifa), RTM_DELETE, 246 ( ifp->if_flags & IFF_LOOPBACK ) ? RTF_HOST : 0 )) != 0 ) { 247 return( error ); 248 } 249 aa->aa_ifa.ifa_flags &= ~IFA_ROUTE; |
313#else BSD4_4 314 if ( ifp->if_flags & IFF_LOOPBACK ) { 315 rtinit( &aa->aa_addr, &aa->aa_addr, SIOCDELRT, RTF_HOST ); 316 } else { 317 bzero( &netsat, sizeof( struct sockaddr_at )); 318 netsat.sat_family = AF_APPLETALK; 319 netsat.sat_addr.s_node = ATADDR_ANYNODE; 320 321 /* 322 * If the range is the full 0-fffe range, just use 323 * the default route. 324 */ 325 if ( aa->aa_firstnet == htons( 0x0000 ) && 326 aa->aa_lastnet == htons( 0xfffe )) { 327 netsat.sat_addr.s_net = 0; 328 rtinit((struct sockaddr *)&netsat, &aa->aa_addr, 329 (int)SIOCDELRT, 0 ); 330 } else { 331 for ( net = ntohs( aa->aa_firstnet ); 332 net <= ntohs( aa->aa_lastnet ); net++ ) { 333 netsat.sat_addr.s_net = htons( net ); 334 rtinit((struct sockaddr *)&netsat, &aa->aa_addr, 335 (int)SIOCDELRT, 0 ); 336 } 337 } 338 } 339#endif BSD4_4 | |
340 aa->aa_flags &= ~AFA_ROUTE; 341 } 342 return( 0 ); 343} 344 | 250 aa->aa_flags &= ~AFA_ROUTE; 251 } 252 return( 0 ); 253} 254 |
345#if !defined( __FreeBSD__ ) 346extern struct timeval time; 347#endif __FreeBSD__ 348 | |
349static int 350at_ifinit( ifp, aa, sat ) 351 struct ifnet *ifp; 352 struct at_ifaddr *aa; 353 struct sockaddr_at *sat; 354{ 355 struct netrange nr, onr; | 255static int 256at_ifinit( ifp, aa, sat ) 257 struct ifnet *ifp; 258 struct at_ifaddr *aa; 259 struct sockaddr_at *sat; 260{ 261 struct netrange nr, onr; |
356#ifdef BSD4_4 | |
357 struct sockaddr_at oldaddr; | 262 struct sockaddr_at oldaddr; |
358#else BSD4_4 359 struct sockaddr oldaddr; 360#endif BSD4_4 361 struct sockaddr_at netaddr; 362 int s = splimp(), error = 0, i, j, netinc, nodeinc, nnets; | 263 int s = splimp(), error = 0, i, j; 264 int flags = RTF_UP, netinc, nodeinc, nnets; |
363 u_short net; 364 365 oldaddr = aa->aa_addr; 366 bzero( AA_SAT( aa ), sizeof( struct sockaddr_at )); 367 bcopy( sat->sat_zero, &nr, sizeof( struct netrange )); | 265 u_short net; 266 267 oldaddr = aa->aa_addr; 268 bzero( AA_SAT( aa ), sizeof( struct sockaddr_at )); 269 bcopy( sat->sat_zero, &nr, sizeof( struct netrange )); |
270 bcopy( sat->sat_zero, AA_SAT( aa )->sat_zero, sizeof( struct netrange )); |
|
368 nnets = ntohs( nr.nr_lastnet ) - ntohs( nr.nr_firstnet ) + 1; 369 370 onr.nr_firstnet = aa->aa_firstnet; 371 onr.nr_lastnet = aa->aa_lastnet; 372 aa->aa_firstnet = nr.nr_firstnet; 373 aa->aa_lastnet = nr.nr_lastnet; 374 | 271 nnets = ntohs( nr.nr_lastnet ) - ntohs( nr.nr_firstnet ) + 1; 272 273 onr.nr_firstnet = aa->aa_firstnet; 274 onr.nr_lastnet = aa->aa_lastnet; 275 aa->aa_firstnet = nr.nr_firstnet; 276 aa->aa_lastnet = nr.nr_lastnet; 277 |
278/* XXX ALC */ 279 printf("at_ifinit: %s: %u.%u range %u-%u phase %d\n", 280 ifp->if_name, 281 ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node, 282 ntohs(aa->aa_firstnet), ntohs(aa->aa_lastnet), 283 (aa->aa_flags & AFA_PHASE2) ? 2 : 1); 284 |
|
375 /* 376 * We could eliminate the need for a second phase 1 probe (post 377 * autoconf) if we check whether we're resetting the node. Note 378 * that phase 1 probes use only nodes, not net.node pairs. Under 379 * phase 2, both the net and node must be the same. 380 */ 381 if ( ifp->if_flags & IFF_LOOPBACK ) { | 285 /* 286 * We could eliminate the need for a second phase 1 probe (post 287 * autoconf) if we check whether we're resetting the node. Note 288 * that phase 1 probes use only nodes, not net.node pairs. Under 289 * phase 2, both the net and node must be the same. 290 */ 291 if ( ifp->if_flags & IFF_LOOPBACK ) { |
382#ifdef BSD4_4 | |
383 AA_SAT( aa )->sat_len = sat->sat_len; | 292 AA_SAT( aa )->sat_len = sat->sat_len; |
384#endif BSD4_4 | |
385 AA_SAT( aa )->sat_family = AF_APPLETALK; 386 AA_SAT( aa )->sat_addr.s_net = sat->sat_addr.s_net; 387 AA_SAT( aa )->sat_addr.s_node = sat->sat_addr.s_node; | 293 AA_SAT( aa )->sat_family = AF_APPLETALK; 294 AA_SAT( aa )->sat_addr.s_net = sat->sat_addr.s_net; 295 AA_SAT( aa )->sat_addr.s_node = sat->sat_addr.s_node; |
296#if 0 297 } else if ( fp->if_flags & IFF_POINTOPOINT) { 298 /* unimplemented */ 299#endif |
|
388 } else { 389 aa->aa_flags |= AFA_PROBING; | 300 } else { 301 aa->aa_flags |= AFA_PROBING; |
390#ifdef BSD4_4 | |
391 AA_SAT( aa )->sat_len = sizeof(struct sockaddr_at); | 302 AA_SAT( aa )->sat_len = sizeof(struct sockaddr_at); |
392#endif BSD4_4 | |
393 AA_SAT( aa )->sat_family = AF_APPLETALK; 394 if ( aa->aa_flags & AFA_PHASE2 ) { 395 if ( sat->sat_addr.s_net == ATADDR_ANYNET ) { 396 if ( nnets != 1 ) { 397 net = ntohs( nr.nr_firstnet ) + time.tv_sec % ( nnets - 1 ); 398 } else { 399 net = ntohs( nr.nr_firstnet ); 400 } --- 25 unchanged lines hidden (view full) --- 426 j++, AA_SAT( aa )->sat_addr.s_node += nodeinc ) { 427 if ( AA_SAT( aa )->sat_addr.s_node > 253 || 428 AA_SAT( aa )->sat_addr.s_node < 1 ) { 429 continue; 430 } 431 aa->aa_probcnt = 10; 432 timeout( (timeout_func_t)aarpprobe, (caddr_t)ifp, hz / 5 ); 433 splx( s ); | 303 AA_SAT( aa )->sat_family = AF_APPLETALK; 304 if ( aa->aa_flags & AFA_PHASE2 ) { 305 if ( sat->sat_addr.s_net == ATADDR_ANYNET ) { 306 if ( nnets != 1 ) { 307 net = ntohs( nr.nr_firstnet ) + time.tv_sec % ( nnets - 1 ); 308 } else { 309 net = ntohs( nr.nr_firstnet ); 310 } --- 25 unchanged lines hidden (view full) --- 336 j++, AA_SAT( aa )->sat_addr.s_node += nodeinc ) { 337 if ( AA_SAT( aa )->sat_addr.s_node > 253 || 338 AA_SAT( aa )->sat_addr.s_node < 1 ) { 339 continue; 340 } 341 aa->aa_probcnt = 10; 342 timeout( (timeout_func_t)aarpprobe, (caddr_t)ifp, hz / 5 ); 343 splx( s ); |
434 if ( 435#if defined( __FreeBSD__ ) 436 tsleep( aa, PPAUSE|PCATCH, "at_ifinit", 0 ) 437#else 438 sleep( aa, PSLEP|PCATCH ) 439#endif 440 ) { 441 printf( "at_ifinit why did this happen?!\n" ); | 344 if ( tsleep( aa, PPAUSE|PCATCH, "at_ifinit", 0 )) { 345 printf( "at_ifinit: why did this happen?!\n" ); |
442 aa->aa_addr = oldaddr; 443 aa->aa_firstnet = onr.nr_firstnet; 444 aa->aa_lastnet = onr.nr_lastnet; 445 return( EINTR ); 446 } 447 s = splimp(); 448 if (( aa->aa_flags & AFA_PROBING ) == 0 ) { 449 break; --- 12 unchanged lines hidden (view full) --- 462 aa->aa_lastnet = onr.nr_lastnet; 463 splx( s ); 464 return( EADDRINUSE ); 465 } 466 } 467 468 if ( ifp->if_ioctl && 469 ( error = (*ifp->if_ioctl)( ifp, SIOCSIFADDR, (caddr_t)aa ))) { | 346 aa->aa_addr = oldaddr; 347 aa->aa_firstnet = onr.nr_firstnet; 348 aa->aa_lastnet = onr.nr_lastnet; 349 return( EINTR ); 350 } 351 s = splimp(); 352 if (( aa->aa_flags & AFA_PROBING ) == 0 ) { 353 break; --- 12 unchanged lines hidden (view full) --- 366 aa->aa_lastnet = onr.nr_lastnet; 367 splx( s ); 368 return( EADDRINUSE ); 369 } 370 } 371 372 if ( ifp->if_ioctl && 373 ( error = (*ifp->if_ioctl)( ifp, SIOCSIFADDR, (caddr_t)aa ))) { |
470 splx( s ); | |
471 aa->aa_addr = oldaddr; 472 aa->aa_firstnet = onr.nr_firstnet; 473 aa->aa_lastnet = onr.nr_lastnet; | 374 aa->aa_addr = oldaddr; 375 aa->aa_firstnet = onr.nr_firstnet; 376 aa->aa_lastnet = onr.nr_lastnet; |
377 splx( s ); |
|
474 return( error ); 475 } 476 | 378 return( error ); 379 } 380 |
477#ifdef BSD4_4 478 aa->aa_netmask.sat_len = 6/*sizeof(struct sockaddr_at)*/; | 381 /* Initialize interface netmask, which is silly for us */ 382 383 bzero(&aa->aa_netmask, sizeof(aa->aa_netmask)); 384 aa->aa_netmask.sat_len = sizeof(struct sockaddr_at); |
479 aa->aa_netmask.sat_family = AF_APPLETALK; | 385 aa->aa_netmask.sat_family = AF_APPLETALK; |
480 aa->aa_netmask.sat_addr.s_net = 0xffff; 481 aa->aa_netmask.sat_addr.s_node = 0; 482#if defined( __FreeBSD__ ) 483 aa->aa_ifa.ifa_netmask =(struct sockaddr *) &(aa->aa_netmask); /* XXX */ 484#endif __FreeBSD__ 485#endif BSD4_4 | 386 aa->aa_ifa.ifa_netmask = (struct sockaddr *) &aa->aa_netmask; |
486 | 387 |
388 /* "Add a route to the network" */ 389 390 aa->aa_ifa.ifa_metric = ifp->if_metric; 391 if (ifp->if_flags & IFF_BROADCAST) { 392 bzero(&aa->aa_broadaddr, sizeof(aa->aa_broadaddr)); 393 aa->aa_broadaddr.sat_len = sat->sat_len; 394 aa->aa_broadaddr.sat_family = AF_APPLETALK; 395 aa->aa_broadaddr.sat_addr.s_net = htons(0); 396 aa->aa_broadaddr.sat_addr.s_node = 0xff; 397 aa->aa_ifa.ifa_broadaddr = (struct sockaddr *) &aa->aa_broadaddr; 398 aa->aa_netmask.sat_addr.s_net = htons(0xffff); /* XXX */ 399 aa->aa_netmask.sat_addr.s_node = htons(0); /* XXX */ 400 } else if (ifp->if_flags & IFF_LOOPBACK) { 401 aa->aa_ifa.ifa_dstaddr = aa->aa_ifa.ifa_addr; 402 aa->aa_netmask.sat_addr.s_net = htons(0xffff); /* XXX */ 403 aa->aa_netmask.sat_addr.s_node = htons(0xffff); /* XXX */ 404 flags |= RTF_HOST; 405 } else if (ifp->if_flags & IFF_POINTOPOINT) { 406 aa->aa_ifa.ifa_dstaddr = aa->aa_ifa.ifa_addr; 407 aa->aa_netmask.sat_addr.s_net = htons(0xffff); 408 aa->aa_netmask.sat_addr.s_node = htons(0xffff); 409 flags |= RTF_HOST; 410 } 411 error = rtinit(&(aa->aa_ifa), (int)RTM_ADD, flags); 412 413#if 0 |
|
487 if ( ifp->if_flags & IFF_LOOPBACK ) { | 414 if ( ifp->if_flags & IFF_LOOPBACK ) { |
488#ifndef BSD4_4 489 rtinit( &aa->aa_addr, &aa->aa_addr, (int)SIOCADDRT, 490 RTF_HOST|RTF_UP ); 491#else BSD4_4 492 error = rtinit( &(aa->aa_ifa), (int)RTM_ADD, 493#if !defined( __FreeBSD__ ) 494 RTF_HOST | 495#else 496 /* XXX not a host route? */ 497#endif __FreeBSD__ 498 RTF_UP ); 499#endif BSD4_4 | 415 struct at_addr rtaddr, rtmask; 416 417 bzero(&rtaddr, sizeof(rtaddr)); 418 bzero(&rtmask, sizeof(rtmask)); 419 rtaddr.s_net = AA_SAT( aa )->sat_addr.s_net; 420 rtaddr.s_node = AA_SAT( aa )->sat_addr.s_node; 421 rtmask.s_net = 0xffff; 422 rtmask.s_node = 0xff; 423 424 error = aa_addsingleroute(&aa->aa_ifa, &rtaddr, &rtmask); 425 |
500 } else { | 426 } else { |
501#ifndef BSD4_4 502 /* 503 * rtrequest looks for point-to-point links first. The 504 * broadaddr is in the same spot as the destaddr. So, if 505 * ATADDR_ANYNET is 0, and we don't fill in the broadaddr, we 506 * get 0.0 routed out the ether interface. So, initialize the 507 * broadaddr, even tho we don't use it. 508 * 509 * We *could* use the broadaddr field to reduce some of the 510 * sockaddr_at overloading that we've done. E.g. Just send 511 * to INTERFACE-NET.255, and have the kernel reroute that 512 * to broadaddr, which would be 0.255 for phase 2 interfaces, 513 * and IFACE-NET.255 for phase 1 interfaces. 514 */ 515 ((struct sockaddr_at *)&aa->aa_broadaddr)->sat_addr.s_net = 516 sat->sat_addr.s_net; 517 ((struct sockaddr_at *)&aa->aa_broadaddr)->sat_addr.s_node = 518 ATADDR_BCAST; | |
519 | 427 |
520 bzero( &netaddr, sizeof( struct sockaddr_at )); 521 netaddr.sat_family = AF_APPLETALK; 522 netaddr.sat_addr.s_node = ATADDR_ANYNODE; 523 if (( aa->aa_flags & AFA_PHASE2 ) == 0 ) { 524 netaddr.sat_addr.s_net = AA_SAT( aa )->sat_addr.s_net; 525 rtinit((struct sockaddr *)&netaddr, &aa->aa_addr, 526 (int)SIOCADDRT, RTF_UP ); 527 } else { 528 /* 529 * If the range is the full 0-fffe range, just use 530 * the default route. 531 */ 532 if ( aa->aa_firstnet == htons( 0x0000 ) && 533 aa->aa_lastnet == htons( 0xfffe )) { 534 netaddr.sat_addr.s_net = 0; 535 rtinit((struct sockaddr *)&netaddr, &aa->aa_addr, 536 (int)SIOCADDRT, RTF_UP ); 537 } else { 538 for ( net = ntohs( aa->aa_firstnet ); 539 net <= ntohs( aa->aa_lastnet ); net++ ) { 540 netaddr.sat_addr.s_net = htons( net ); 541 rtinit((struct sockaddr *)&netaddr, &aa->aa_addr, 542 (int)SIOCADDRT, RTF_UP ); 543 } 544 } 545 } 546#else BSD4_4 547 error = rtinit( &(aa->aa_ifa), (int)RTM_ADD, RTF_UP ); 548#endif BSD4_4 | 428 /* Install routes for our own network, and then also for 429 all networks above and below it in the network range */ 430 431 error = aa_addrangeroute(&aa->aa_ifa, 432 ntohs(aa->aa_addr.sat_addr.s_net), 433 ntohs(aa->aa_addr.sat_addr.s_net) + 1); 434 if (!error 435 && ntohs(aa->aa_firstnet) < ntohs(aa->aa_addr.sat_addr.s_net)) 436 error = aa_addrangeroute(&aa->aa_ifa, 437 ntohs(aa->aa_firstnet), ntohs(aa->aa_addr.sat_addr.s_net)); 438 if (!error 439 && ntohs(aa->aa_addr.sat_addr.s_net) < ntohs(aa->aa_lastnet)) 440 error = aa_addrangeroute(&aa->aa_ifa, 441 ntohs(aa->aa_addr.sat_addr.s_net) + 1, 442 ntohs(aa->aa_lastnet) + 1); |
549 } | 443 } |
444#endif 445 446 |
|
550 if ( error ) { 551 aa->aa_addr = oldaddr; 552 aa->aa_firstnet = onr.nr_firstnet; 553 aa->aa_lastnet = onr.nr_lastnet; 554 splx( s ); 555 return( error ); 556 } 557 | 447 if ( error ) { 448 aa->aa_addr = oldaddr; 449 aa->aa_firstnet = onr.nr_firstnet; 450 aa->aa_lastnet = onr.nr_lastnet; 451 splx( s ); 452 return( error ); 453 } 454 |
558#ifdef BSD4_4 | |
559 aa->aa_ifa.ifa_flags |= IFA_ROUTE; | 455 aa->aa_ifa.ifa_flags |= IFA_ROUTE; |
560#endif BSD4_4 | |
561 aa->aa_flags |= AFA_ROUTE; 562 splx( s ); 563 return( 0 ); 564} 565 566int 567at_broadcast( sat ) 568 struct sockaddr_at *sat; --- 12 unchanged lines hidden (view full) --- 581 ntohs( sat->sat_addr.s_net ) <= ntohs( aa->aa_lastnet ))) { 582 return( 1 ); 583 } 584 } 585 } 586 return( 0 ); 587} 588 | 456 aa->aa_flags |= AFA_ROUTE; 457 splx( s ); 458 return( 0 ); 459} 460 461int 462at_broadcast( sat ) 463 struct sockaddr_at *sat; --- 12 unchanged lines hidden (view full) --- 476 ntohs( sat->sat_addr.s_net ) <= ntohs( aa->aa_lastnet ))) { 477 return( 1 ); 478 } 479 } 480 } 481 return( 0 ); 482} 483 |
484/* 485 * aa_addrangeroute() 486 * 487 * Add a route for a range of networks from bot to top - 1. 488 * Algorithm: 489 * 490 * Split the range into three subranges such that the middle 491 * subrange is from (base + 2^N) to (base + 2^N + 2^(N-1)) for 492 * some N. Then add a route for the middle range and recurse on 493 * the upper and lower sub-ranges. As a degenerate case, it may 494 * be that the middle subrange is empty. 495 */ 496 497static int 498aa_addrangeroute(struct ifaddr *ifa, int bot, int top) 499{ 500 int base, mask, mbot, mtop; 501 int a, b, abit, bbit, error; 502 struct at_addr rtaddr, rtmask; 503 504/* Special case the whole range */ 505 506 if (bot == 0 && top == 0xffff) 507 { 508 bzero(&rtaddr, sizeof(rtaddr)); 509 bzero(&rtmask, sizeof(rtmask)); 510 return(aa_addsingleroute(ifa, &rtaddr, &rtmask)); 511 } 512 513 if (top <= bot) 514 panic("aa_addrangeroute"); 515 516/* Mask out the high order bits on which both bounds agree */ 517 518 for (mask = 0xffff; (bot & mask) != (top & mask); mask <<= 1); 519 base = bot & mask; 520 a = bot & ~mask; 521 b = top & ~mask; 522 523/* Find suitable powers of two between a and b we can make a route with */ 524 525 for (bbit = 0x8000; bbit > b; bbit >>= 1); 526 if (a == 0) 527 abit = 0; 528 else 529 { 530 for (abit = 0x0001; a > abit; abit <<= 1); 531 if ((abit << 1) > bbit) 532 bbit = abit; 533 else 534 bbit = abit << 1; 535 } 536 537/* Now we have a "square" middle chunk from abit to bbit, possibly empty */ 538 539 mbot = base + abit; 540 mtop = base + bbit; 541 mask = ~(bbit - 1); 542 543/* Route to the middle chunk */ 544 545 if (mbot < mtop) 546 { 547 bzero(&rtaddr, sizeof(rtaddr)); 548 bzero(&rtmask, sizeof(rtmask)); 549 rtaddr.s_net = htons((u_short) mbot); 550 rtmask.s_net = htons((u_short) mask); 551 if ((error = aa_addsingleroute(ifa, &rtaddr, &rtmask))) 552 return(error); 553 } 554 555/* Recurse on the upper and lower chunks we didn't get to */ 556 557 if (bot < mbot) 558 if ((error = aa_addrangeroute(ifa, bot, mbot))) 559 { 560 if (mbot < mtop) 561 aa_delsingleroute(ifa, &rtaddr, &rtmask); 562 return(error); 563 } 564 if (mtop < top) 565 if ((error = aa_addrangeroute(ifa, mtop, top))) 566 { 567 if (mbot < mtop) 568 aa_delsingleroute(ifa, &rtaddr, &rtmask); 569 return(error); 570 } 571 return(0); 572} 573 574static int 575aa_addsingleroute(struct ifaddr *ifa, 576 struct at_addr *addr, struct at_addr *mask) 577{ 578 int error; 579 580 printf("aa_addsingleroute: %x.%x mask %x.%x ...\n", 581 ntohs(addr->s_net), addr->s_node, 582 ntohs(mask->s_net), mask->s_node); 583 584 error = aa_dosingleroute(ifa, addr, mask, RTM_ADD, RTF_UP); 585 if (error) 586 printf("error %d\n", error); 587 return(error); 588} 589 590static int 591aa_delsingleroute(struct ifaddr *ifa, 592 struct at_addr *addr, struct at_addr *mask) 593{ 594 int error; 595 596 error = aa_dosingleroute(ifa, addr, mask, RTM_DELETE, 0); 597 if (error) 598 printf("aa_delsingleroute: error %d\n", error); 599 return(error); 600} 601 602static int 603aa_dosingleroute(struct ifaddr *ifa, 604 struct at_addr *at_addr, struct at_addr *at_mask, int cmd, int flags) 605{ 606 struct sockaddr_at addr, mask; 607 608 bzero(&addr, sizeof(addr)); 609 bzero(&mask, sizeof(mask)); 610 addr.sat_family = AF_APPLETALK; 611 addr.sat_len = sizeof(struct sockaddr_at); 612 addr.sat_addr.s_net = at_addr->s_net; 613 addr.sat_addr.s_node = at_addr->s_node; 614 mask.sat_addr.s_net = at_mask->s_net; 615 mask.sat_addr.s_node = at_mask->s_node; 616 if (at_mask->s_node) 617 flags |= RTF_HOST; 618 return(rtrequest(cmd, (struct sockaddr *) &addr, ifa->ifa_addr, 619 (struct sockaddr *) &mask, flags, NULL)); 620} 621 622#if 0 623 |
|
589static void 590aa_clean(void) 591{ 592 struct at_ifaddr *aa; 593 struct ifaddr *ifa; 594 struct ifnet *ifp; 595 596 while ( aa = at_ifaddr ) { --- 10 unchanged lines hidden (view full) --- 607 if ( ifa->ifa_next ) { 608 ifa->ifa_next = ((struct ifaddr *)aa)->ifa_next; 609 } else { 610 panic( "at_entry" ); 611 } 612 } 613 } 614} | 624static void 625aa_clean(void) 626{ 627 struct at_ifaddr *aa; 628 struct ifaddr *ifa; 629 struct ifnet *ifp; 630 631 while ( aa = at_ifaddr ) { --- 10 unchanged lines hidden (view full) --- 642 if ( ifa->ifa_next ) { 643 ifa->ifa_next = ((struct ifaddr *)aa)->ifa_next; 644 } else { 645 panic( "at_entry" ); 646 } 647 } 648 } 649} |
650 651#endif 652 |
|