1/* 2 * $Id: at_control.c,v 1.2 2001-06-29 14:14:47 rufustfirefly Exp $ 3 * 4 * Copyright (c) 1990,1991 Regents of The University of Michigan. 5 * All Rights Reserved. 6 */ 7 8#ifdef HAVE_CONFIG_H 9#include "config.h" 10#endif /* HAVE_CONFIG_H */ 11 12#include <sys/param.h> 13#include <sys/systm.h> 14#ifdef ibm032 15#include <sys/dir.h> 16#endif /* ibm032 */ 17#include <sys/user.h> 18#include <sys/types.h> 19#include <sys/errno.h> 20#include <sys/ioctl.h> 21#include <sys/mbuf.h> 22#ifndef _IBMR2 23#include <sys/kernel.h> 24#endif /* ! _IBMR2 */ 25#include <sys/socket.h> 26#include <sys/socketvar.h> 27#include <net/if.h> 28#include <net/af.h> 29#include <net/route.h> 30#include <netinet/in.h> 31#undef s_net 32#include <netinet/if_ether.h> 33#ifdef _IBMR2 34#include <net/spl.h> 35#endif /* _IBMR2 */ 36 37#include "at.h" 38#include "at_var.h" 39#include "aarp.h" 40#include "phase2.h" 41 42#ifdef BSD4_4 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 ) 47#else /* BSD4_4 */ 48atalk_hash( sat, hp ) 49 struct sockaddr_at *sat; 50 struct afhash *hp; 51{ 52 hp->afh_nethash = sat->sat_addr.s_net; 53 hp->afh_hosthash = ( sat->sat_addr.s_net << 8 ) + 54 sat->sat_addr.s_node; 55} 56 57/* 58 * Note the magic to get ifa_ifwithnet() to work without adding an 59 * ifaddr entry for each net in our local range. 60 */ 61atalk_netmatch( sat1, sat2 ) 62 struct sockaddr_at *sat1, *sat2; 63{ 64 struct at_ifaddr *aa; 65 66 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { 67 if ( AA_SAT( aa ) == sat1 ) { 68 break; 69 } 70 } 71 if ( aa ) { 72 return( ntohs( aa->aa_firstnet ) <= ntohs( sat2->sat_addr.s_net ) && 73 ntohs( aa->aa_lastnet ) >= ntohs( sat2->sat_addr.s_net )); 74 } 75 return( sat1->sat_addr.s_net == sat2->sat_addr.s_net ); 76} 77#endif /* BSD4_4 */ 78 79at_control( cmd, data, ifp ) 80 int cmd; 81 caddr_t data; 82 struct ifnet *ifp; 83{ 84 struct ifreq *ifr = (struct ifreq *)data; 85 struct sockaddr_at *sat; 86 struct netrange *nr; 87#ifdef BSD4_4 88 struct at_aliasreq *ifra = (struct at_aliasreq *)data; 89 struct at_ifaddr *aa0; 90#endif /* BSD4_4 */ 91 struct at_ifaddr *aa = 0; 92 struct mbuf *m; 93 struct ifaddr *ifa; 94 95 if ( ifp ) { 96 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { 97 if ( aa->aa_ifp == ifp ) break; 98 } 99 } 100 101 switch ( cmd ) { 102#ifdef BSD4_4 103 case SIOCAIFADDR: 104 case SIOCDIFADDR: 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 )) { 109 break; 110 } 111 } 112 } 113 if ( cmd == SIOCDIFADDR && aa == 0 ) { 114 return( EADDRNOTAVAIL ); 115 } 116 /*FALLTHROUGH*/ 117#endif /* BSD4_4 */ 118 119 case SIOCSIFADDR: 120#ifdef BSD4_4 121 /* 122 * What a great idea this is: Let's reverse the meaning of 123 * the return... 124 */ 125 if ( suser( u.u_cred, &u.u_acflag )) { 126 return( EPERM ); 127 } 128#else /* BSD4_4 */ 129 if ( !suser()) { 130 return( EPERM ); 131 } 132#endif /* BSD4_4 */ 133 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 ) { 140 break; 141 } 142 } 143 } else { /* default to phase 2 */ 144 for ( ; aa; aa = aa->aa_next ) { 145 if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 )) { 146 break; 147 } 148 } 149 } 150 151 if ( ifp == 0 ) 152 panic( "at_control" ); 153 154 if ( aa == (struct at_ifaddr *) 0 ) { 155 m = m_getclr( M_WAIT, MT_IFADDR ); 156 if ( m == (struct mbuf *)NULL ) { 157 return( ENOBUFS ); 158 } 159 160 if (( aa = at_ifaddr ) != NULL ) { 161 /* 162 * Don't let the loopback be first, since the first 163 * address is the machine's default address for 164 * binding. 165 */ 166 if ( at_ifaddr->aa_ifp->if_flags & IFF_LOOPBACK ) { 167 aa = mtod( m, struct at_ifaddr *); 168 aa->aa_next = at_ifaddr; 169 at_ifaddr = aa; 170 } else { 171 for ( ; aa->aa_next; aa = aa->aa_next ) 172 ; 173 aa->aa_next = mtod( m, struct at_ifaddr *); 174 } 175 } else { 176 at_ifaddr = mtod( m, struct at_ifaddr *); 177 } 178 179 aa = mtod( m, struct at_ifaddr *); 180 181 if (( ifa = ifp->if_addrlist ) != NULL ) { 182 for ( ; ifa->ifa_next; ifa = ifa->ifa_next ) 183 ; 184 ifa->ifa_next = (struct ifaddr *)aa; 185 } else { 186 ifp->if_addrlist = (struct ifaddr *)aa; 187 } 188 189#ifdef BSD4_4 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; 193#endif /* BSD4_4 */ 194 195 /* 196 * Set/clear the phase 2 bit. 197 */ 198 if ( nr->nr_phase == 1 ) { 199 aa->aa_flags &= ~AFA_PHASE2; 200 } else { 201 aa->aa_flags |= AFA_PHASE2; 202 } 203 aa->aa_ifp = ifp; 204 } else { 205 at_scrub( ifp, aa ); 206 } 207 break; 208 209 case SIOCGIFADDR : 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 ) { 216 break; 217 } 218 } 219 } else { /* default to phase 2 */ 220 for ( ; aa; aa = aa->aa_next ) { 221 if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 )) { 222 break; 223 } 224 } 225 } 226 227 if ( aa == (struct at_ifaddr *) 0 ) 228 return( EADDRNOTAVAIL ); 229 break; 230 } 231 232 switch ( cmd ) { 233 case SIOCGIFADDR: 234#ifdef BSD4_4 235 *(struct sockaddr_at *)&ifr->ifr_addr = aa->aa_addr; 236#else /* BSD4_4 */ 237 ifr->ifr_addr = aa->aa_addr; 238#endif /* BSD4_4 */ 239 break; 240 241 case SIOCSIFADDR: 242 return( at_ifinit( ifp, aa, (struct sockaddr_at *)&ifr->ifr_addr )); 243 244#ifdef BSD4_4 245 case SIOCAIFADDR: 246 if ( sateqaddr( &ifra->ifra_addr, &aa->aa_addr )) { 247 return( 0 ); 248 } 249 return( at_ifinit( ifp, aa, (struct sockaddr_at *)&ifr->ifr_addr )); 250 251 case SIOCDIFADDR: 252 at_scrub( ifp, aa ); 253 if (( ifa = ifp->if_addrlist ) == (struct ifaddr *)aa ) { 254 ifp->if_addrlist = ifa->ifa_next; 255 } else { 256 while ( ifa->ifa_next && ( ifa->ifa_next != (struct ifaddr *)aa )) { 257 ifa = ifa->ifa_next; 258 } 259 if ( ifa->ifa_next ) { 260 ifa->ifa_next = ((struct ifaddr *)aa)->ifa_next; 261 } else { 262 panic( "at_control" ); 263 } 264 } 265 266 aa0 = aa; 267 if ( aa0 == ( aa = at_ifaddr )) { 268 at_ifaddr = aa->aa_next; 269 } else { 270 while ( aa->aa_next && ( aa->aa_next != aa0 )) { 271 aa = aa->aa_next; 272 } 273 if ( aa->aa_next ) { 274 aa->aa_next = aa0->aa_next; 275 } else { 276 panic( "at_control" ); 277 } 278 } 279 m_free( dtom( aa0 )); 280 break; 281#endif /* BSD4_4 */ 282 283 default: 284 if ( ifp == 0 || ifp->if_ioctl == 0 ) 285 return( EOPNOTSUPP ); 286 return( (*ifp->if_ioctl)( ifp, cmd, data )); 287 } 288 return( 0 ); 289} 290 291at_scrub( ifp, aa ) 292 struct ifnet *ifp; 293 struct at_ifaddr *aa; 294{ 295#ifndef BSD4_4 296 struct sockaddr_at netsat; 297 int error; 298 u_short net; 299#endif /* ! BSD4_4 */ 300 301 if ( aa->aa_flags & AFA_ROUTE ) { 302#ifdef BSD4_4 303 if (( error = rtinit( &(aa->aa_ifa), RTM_DELETE, 304 ( ifp->if_flags & IFF_LOOPBACK ) ? RTF_HOST : 0 )) != 0 ) { 305 return( error ); 306 } 307 aa->aa_ifa.ifa_flags &= ~IFA_ROUTE; 308#else /* BSD4_4 */ 309 if ( ifp->if_flags & IFF_LOOPBACK ) { 310 rtinit( &aa->aa_addr, &aa->aa_addr, SIOCDELRT, RTF_HOST ); 311 } else { 312 bzero( &netsat, sizeof( struct sockaddr_at )); 313 netsat.sat_family = AF_APPLETALK; 314 netsat.sat_addr.s_node = ATADDR_ANYNODE; 315 316 /* 317 * If the range is the full 0-fffe range, just use 318 * the default route. 319 */ 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, 324 (int)SIOCDELRT, 0 ); 325 } else { 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, 330 (int)SIOCDELRT, 0 ); 331 } 332 } 333 } 334#endif /* BSD4_4 */ 335 aa->aa_flags &= ~AFA_ROUTE; 336 } 337 return( 0 ); 338} 339 340extern struct timeval time; 341 342at_ifinit( ifp, aa, sat ) 343 struct ifnet *ifp; 344 struct at_ifaddr *aa; 345 struct sockaddr_at *sat; 346{ 347 struct netrange nr, onr; 348#ifdef BSD4_4 349 struct sockaddr_at oldaddr; 350#else /* BSD4_4 */ 351 struct sockaddr oldaddr; 352#endif /* BSD4_4 */ 353 struct sockaddr_at netaddr; 354 int s = splimp(), error = 0, i, j, netinc, nodeinc, nnets; 355 u_short net; 356 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; 361 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; 366 367 /* 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. 372 */ 373 if ( ifp->if_flags & IFF_LOOPBACK ) { 374#ifdef BSD4_4 375 AA_SAT( aa )->sat_len = sat->sat_len; 376#endif /* BSD4_4 */ 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; 380 } else { 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 ) { 385 if ( nnets != 1 ) { 386 net = ntohs( nr.nr_firstnet ) + time.tv_sec % ( nnets - 1 ); 387 } else { 388 net = ntohs( nr.nr_firstnet ); 389 } 390 } else { 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; 396 return( EINVAL ); 397 } 398 net = ntohs( sat->sat_addr.s_net ); 399 } 400 } else { 401 net = ntohs( sat->sat_addr.s_net ); 402 } 403 404 if ( sat->sat_addr.s_node == ATADDR_ANYNODE ) { 405 AA_SAT( aa )->sat_addr.s_node = time.tv_sec; 406 } else { 407 AA_SAT( aa )->sat_addr.s_node = sat->sat_addr.s_node; 408 } 409 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 ); 413 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 ) { 418 continue; 419 } 420 aa->aa_probcnt = 10; 421 timeout( aarpprobe, (caddr_t)ifp, hz / 5 ); 422 splx( s ); 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; 428 return( EINTR ); 429 } 430 s = splimp(); 431 if (( aa->aa_flags & AFA_PROBING ) == 0 ) { 432 break; 433 } 434 } 435 if (( aa->aa_flags & AFA_PROBING ) == 0 ) { 436 break; 437 } 438 /* reset node for next network */ 439 AA_SAT( aa )->sat_addr.s_node = time.tv_sec; 440 } 441 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; 446 splx( s ); 447 return( EADDRINUSE ); 448 } 449 } 450 451 if ( ifp->if_ioctl && 452 ( error = (*ifp->if_ioctl)( ifp, SIOCSIFADDR, aa ))) { 453 splx( s ); 454 aa->aa_addr = oldaddr; 455 aa->aa_firstnet = onr.nr_firstnet; 456 aa->aa_lastnet = onr.nr_lastnet; 457 return( error ); 458 } 459 460#ifdef BSD4_4 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; 465#endif /* BSD4_4 */ 466 467 if ( ifp->if_flags & IFF_LOOPBACK ) { 468#ifndef BSD4_4 469 rtinit( &aa->aa_addr, &aa->aa_addr, (int)SIOCADDRT, 470 RTF_HOST|RTF_UP ); 471#else /* ! BSD4_4 */ 472 error = rtinit( &(aa->aa_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP ); 473#endif /* ! BSD4_4 */ 474 } else { 475#ifndef BSD4_4 476 /* 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. 482 * 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. 488 */ 489 ((struct sockaddr_at *)&aa->aa_broadaddr)->sat_addr.s_net = 490 sat->sat_addr.s_net; 491 ((struct sockaddr_at *)&aa->aa_broadaddr)->sat_addr.s_node = 492 ATADDR_BCAST; 493 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 ); 501 } else { 502 /* 503 * If the range is the full 0-fffe range, just use 504 * the default route. 505 */ 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 ); 511 } else { 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 ); 517 } 518 } 519 } 520#else /* ! BSD4_4 */ 521 error = rtinit( &(aa->aa_ifa), (int)RTM_ADD, RTF_UP ); 522#endif /* ! BSD4_4 */ 523 } 524 if ( error ) { 525 aa->aa_addr = oldaddr; 526 aa->aa_firstnet = onr.nr_firstnet; 527 aa->aa_lastnet = onr.nr_lastnet; 528 splx( s ); 529 return( error ); 530 } 531 532#ifdef BSD4_4 533 aa->aa_ifa.ifa_flags |= IFA_ROUTE; 534#endif /* BSD4_4 */ 535 aa->aa_flags |= AFA_ROUTE; 536 splx( s ); 537 return( 0 ); 538} 539 540at_broadcast( sat ) 541 struct sockaddr_at *sat; 542{ 543 struct at_ifaddr *aa; 544 545 if ( sat->sat_addr.s_node != ATADDR_BCAST ) { 546 return( 0 ); 547 } 548 if ( sat->sat_addr.s_net == 0 ) { 549 return( 1 ); 550 } else { 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 ))) { 555 return( 1 ); 556 } 557 } 558 } 559 return( 0 ); 560} 561 562aa_clean() 563{ 564 struct at_ifaddr *aa; 565 struct ifaddr *ifa; 566 struct ifnet *ifp; 567 568 while ( aa = at_ifaddr ) { 569 ifp = aa->aa_ifp; 570 at_scrub( ifp, aa ); 571 at_ifaddr = aa->aa_next; 572 if (( ifa = ifp->if_addrlist ) == (struct ifaddr *)aa ) { 573 ifp->if_addrlist = ifa->ifa_next; 574 } else { 575 while ( ifa->ifa_next && 576 ( ifa->ifa_next != (struct ifaddr *)aa )) { 577 ifa = ifa->ifa_next; 578 } 579 if ( ifa->ifa_next ) { 580 ifa->ifa_next = ((struct ifaddr *)aa)->ifa_next; 581 } else { 582 panic( "at_entry" ); 583 } 584 } 585 } 586} 587