6 */ 7 8#include "opt_atalk.h" 9#include "opt_mac.h" 10 11#include <sys/param.h> 12#include <sys/systm.h> 13#include <sys/mac.h> 14#include <sys/mbuf.h> 15#include <sys/kernel.h> 16#include <sys/socket.h> 17#include <sys/syslog.h> 18 19#include <net/if.h> 20 21#include <netinet/in.h> 22#undef s_net 23#include <netinet/if_ether.h> 24 25#include <netatalk/at.h> 26#include <netatalk/at_var.h> 27#include <netatalk/aarp.h> 28#include <netatalk/phase2.h> 29#include <netatalk/at_extern.h> 30 31static void aarptfree( struct aarptab *aat); 32static void at_aarpinput( struct arpcom *ac, struct mbuf *m); 33 34#define AARPTAB_BSIZ 9 35#define AARPTAB_NB 19 36#define AARPTAB_SIZE (AARPTAB_BSIZ * AARPTAB_NB) 37static struct aarptab aarptab[AARPTAB_SIZE]; 38 39#define AARPTAB_HASH(a) \ 40 ((((a).s_net << 8 ) + (a).s_node ) % AARPTAB_NB ) 41 42#define AARPTAB_LOOK(aat,addr) { \ 43 int n; \ 44 aat = &aarptab[ AARPTAB_HASH(addr) * AARPTAB_BSIZ ]; \ 45 for ( n = 0; n < AARPTAB_BSIZ; n++, aat++ ) \ 46 if ( aat->aat_ataddr.s_net == (addr).s_net && \ 47 aat->aat_ataddr.s_node == (addr).s_node ) \ 48 break; \ 49 if ( n >= AARPTAB_BSIZ ) \ 50 aat = 0; \ 51} 52 53#define AARPT_AGE (60 * 1) 54#define AARPT_KILLC 20 55#define AARPT_KILLI 3 56 57# if !defined( __FreeBSD__ ) 58extern u_char etherbroadcastaddr[6]; 59# endif /* __FreeBSD__ */ 60 61static u_char atmulticastaddr[ 6 ] = { 62 0x09, 0x00, 0x07, 0xff, 0xff, 0xff, 63}; 64 65u_char at_org_code[ 3 ] = { 66 0x08, 0x00, 0x07, 67}; 68u_char aarp_org_code[ 3 ] = { 69 0x00, 0x00, 0x00, 70}; 71 72static struct callout_handle aarptimer_ch = 73 CALLOUT_HANDLE_INITIALIZER(&aarptimer_ch); 74 75static void 76aarptimer(void *ignored) 77{ 78 struct aarptab *aat; 79 int i, s; 80 81 aarptimer_ch = timeout( aarptimer, (caddr_t)0, AARPT_AGE * hz ); 82 aat = aarptab; 83 for ( i = 0; i < AARPTAB_SIZE; i++, aat++ ) { 84 if ( aat->aat_flags == 0 || ( aat->aat_flags & ATF_PERM )) 85 continue; 86 if ( ++aat->aat_timer < (( aat->aat_flags & ATF_COM ) ? 87 AARPT_KILLC : AARPT_KILLI )) 88 continue; 89 s = splimp(); 90 aarptfree( aat ); 91 splx( s ); 92 } 93} 94 95/* 96 * search through the network addresses to find one that includes 97 * the given network.. remember to take netranges into 98 * consideration. 99 */ 100struct at_ifaddr * 101at_ifawithnet(struct sockaddr_at *sat ) 102{ 103 struct at_ifaddr *aa; 104 struct sockaddr_at *sat2; 105 106 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { 107 sat2 = &(aa->aa_addr); 108 if ( sat2->sat_addr.s_net == sat->sat_addr.s_net ) { 109 break; 110 } 111 if( (aa->aa_flags & AFA_PHASE2 ) 112 && (ntohs(aa->aa_firstnet) <= ntohs(sat->sat_addr.s_net)) 113 && (ntohs(aa->aa_lastnet) >= ntohs(sat->sat_addr.s_net))) { 114 break; 115 } 116 } 117 return( aa ); 118} 119 120static void 121aarpwhohas( struct arpcom *ac, struct sockaddr_at *sat ) 122{ 123 struct mbuf *m; 124 struct ether_header *eh; 125 struct ether_aarp *ea; 126 struct at_ifaddr *aa; 127 struct llc *llc; 128 struct sockaddr sa; 129 130 if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) { 131 return; 132 } 133#ifdef MAC 134 mac_create_mbuf_linklayer(&ac->ac_if, m); 135#endif 136 m->m_len = sizeof( *ea ); 137 m->m_pkthdr.len = sizeof( *ea ); 138 MH_ALIGN( m, sizeof( *ea )); 139 140 ea = mtod( m, struct ether_aarp *); 141 bzero((caddr_t)ea, sizeof( *ea )); 142 143 ea->aarp_hrd = htons( AARPHRD_ETHER ); 144 ea->aarp_pro = htons( ETHERTYPE_AT ); 145 ea->aarp_hln = sizeof( ea->aarp_sha ); 146 ea->aarp_pln = sizeof( ea->aarp_spu ); 147 ea->aarp_op = htons( AARPOP_REQUEST ); 148 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha, 149 sizeof( ea->aarp_sha )); 150 151 /* 152 * We need to check whether the output ethernet type should 153 * be phase 1 or 2. We have the interface that we'll be sending 154 * the aarp out. We need to find an AppleTalk network on that 155 * interface with the same address as we're looking for. If the 156 * net is phase 2, generate an 802.2 and SNAP header. 157 */ 158 if ((aa = at_ifawithnet( sat )) == NULL) { 159 m_freem( m ); 160 return; 161 } 162 163 eh = (struct ether_header *)sa.sa_data; 164 165 if ( aa->aa_flags & AFA_PHASE2 ) { 166 bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost, 167 sizeof( eh->ether_dhost )); 168 eh->ether_type = htons(sizeof(struct llc) + sizeof(struct ether_aarp)); 169 M_PREPEND( m, sizeof( struct llc ), M_TRYWAIT ); 170 llc = mtod( m, struct llc *); 171 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 172 llc->llc_control = LLC_UI; 173 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code )); 174 llc->llc_ether_type = htons( ETHERTYPE_AARP ); 175 176 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_spnet, 177 sizeof( ea->aarp_spnet )); 178 bcopy( &sat->sat_addr.s_net, ea->aarp_tpnet, 179 sizeof( ea->aarp_tpnet )); 180 ea->aarp_spnode = AA_SAT( aa )->sat_addr.s_node; 181 ea->aarp_tpnode = sat->sat_addr.s_node; 182 } else { 183 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 184 sizeof( eh->ether_dhost )); 185 eh->ether_type = htons( ETHERTYPE_AARP ); 186 187 ea->aarp_spa = AA_SAT( aa )->sat_addr.s_node; 188 ea->aarp_tpa = sat->sat_addr.s_node; 189 } 190 191#ifdef NETATALKDEBUG 192 printf("aarp: sending request for %u.%u\n", 193 ntohs(AA_SAT( aa )->sat_addr.s_net), 194 AA_SAT( aa )->sat_addr.s_node); 195#endif /* NETATALKDEBUG */ 196 197 sa.sa_len = sizeof( struct sockaddr ); 198 sa.sa_family = AF_UNSPEC; 199 (*ac->ac_if.if_output)(&ac->ac_if, 200 m, &sa, NULL); /* XXX NULL should be routing information */ 201} 202 203int 204aarpresolve( ac, m, destsat, desten ) 205 struct arpcom *ac; 206 struct mbuf *m; 207 struct sockaddr_at *destsat; 208 u_char *desten; 209{ 210 struct at_ifaddr *aa; 211 struct aarptab *aat; 212 int s; 213 214 if ( at_broadcast( destsat )) { 215 m->m_flags |= M_BCAST; 216 if ((aa = at_ifawithnet( destsat )) == NULL) { 217 m_freem( m ); 218 return( 0 ); 219 } 220 if ( aa->aa_flags & AFA_PHASE2 ) { 221 bcopy( (caddr_t)atmulticastaddr, (caddr_t)desten, 222 sizeof( atmulticastaddr )); 223 } else { 224 bcopy( (caddr_t)etherbroadcastaddr, (caddr_t)desten, 225 sizeof( etherbroadcastaddr )); 226 } 227 return( 1 ); 228 } 229 230 s = splimp(); 231 AARPTAB_LOOK( aat, destsat->sat_addr ); 232 if ( aat == 0 ) { /* No entry */ 233 aat = aarptnew( &destsat->sat_addr ); 234 if ( aat == 0 ) { 235 panic( "aarpresolve: no free entry" ); 236 } 237 aat->aat_hold = m; 238 aarpwhohas( ac, destsat ); 239 splx( s ); 240 return( 0 ); 241 } 242 /* found an entry */ 243 aat->aat_timer = 0; 244 if ( aat->aat_flags & ATF_COM ) { /* entry is COMplete */ 245 bcopy( (caddr_t)aat->aat_enaddr, (caddr_t)desten, 246 sizeof( aat->aat_enaddr )); 247 splx( s ); 248 return( 1 ); 249 } 250 /* entry has not completed */ 251 if ( aat->aat_hold ) { 252 m_freem( aat->aat_hold ); 253 } 254 aat->aat_hold = m; 255 aarpwhohas( ac, destsat ); 256 splx( s ); 257 return( 0 ); 258} 259 260void
| 6 */ 7 8#include "opt_atalk.h" 9#include "opt_mac.h" 10 11#include <sys/param.h> 12#include <sys/systm.h> 13#include <sys/mac.h> 14#include <sys/mbuf.h> 15#include <sys/kernel.h> 16#include <sys/socket.h> 17#include <sys/syslog.h> 18 19#include <net/if.h> 20 21#include <netinet/in.h> 22#undef s_net 23#include <netinet/if_ether.h> 24 25#include <netatalk/at.h> 26#include <netatalk/at_var.h> 27#include <netatalk/aarp.h> 28#include <netatalk/phase2.h> 29#include <netatalk/at_extern.h> 30 31static void aarptfree( struct aarptab *aat); 32static void at_aarpinput( struct arpcom *ac, struct mbuf *m); 33 34#define AARPTAB_BSIZ 9 35#define AARPTAB_NB 19 36#define AARPTAB_SIZE (AARPTAB_BSIZ * AARPTAB_NB) 37static struct aarptab aarptab[AARPTAB_SIZE]; 38 39#define AARPTAB_HASH(a) \ 40 ((((a).s_net << 8 ) + (a).s_node ) % AARPTAB_NB ) 41 42#define AARPTAB_LOOK(aat,addr) { \ 43 int n; \ 44 aat = &aarptab[ AARPTAB_HASH(addr) * AARPTAB_BSIZ ]; \ 45 for ( n = 0; n < AARPTAB_BSIZ; n++, aat++ ) \ 46 if ( aat->aat_ataddr.s_net == (addr).s_net && \ 47 aat->aat_ataddr.s_node == (addr).s_node ) \ 48 break; \ 49 if ( n >= AARPTAB_BSIZ ) \ 50 aat = 0; \ 51} 52 53#define AARPT_AGE (60 * 1) 54#define AARPT_KILLC 20 55#define AARPT_KILLI 3 56 57# if !defined( __FreeBSD__ ) 58extern u_char etherbroadcastaddr[6]; 59# endif /* __FreeBSD__ */ 60 61static u_char atmulticastaddr[ 6 ] = { 62 0x09, 0x00, 0x07, 0xff, 0xff, 0xff, 63}; 64 65u_char at_org_code[ 3 ] = { 66 0x08, 0x00, 0x07, 67}; 68u_char aarp_org_code[ 3 ] = { 69 0x00, 0x00, 0x00, 70}; 71 72static struct callout_handle aarptimer_ch = 73 CALLOUT_HANDLE_INITIALIZER(&aarptimer_ch); 74 75static void 76aarptimer(void *ignored) 77{ 78 struct aarptab *aat; 79 int i, s; 80 81 aarptimer_ch = timeout( aarptimer, (caddr_t)0, AARPT_AGE * hz ); 82 aat = aarptab; 83 for ( i = 0; i < AARPTAB_SIZE; i++, aat++ ) { 84 if ( aat->aat_flags == 0 || ( aat->aat_flags & ATF_PERM )) 85 continue; 86 if ( ++aat->aat_timer < (( aat->aat_flags & ATF_COM ) ? 87 AARPT_KILLC : AARPT_KILLI )) 88 continue; 89 s = splimp(); 90 aarptfree( aat ); 91 splx( s ); 92 } 93} 94 95/* 96 * search through the network addresses to find one that includes 97 * the given network.. remember to take netranges into 98 * consideration. 99 */ 100struct at_ifaddr * 101at_ifawithnet(struct sockaddr_at *sat ) 102{ 103 struct at_ifaddr *aa; 104 struct sockaddr_at *sat2; 105 106 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { 107 sat2 = &(aa->aa_addr); 108 if ( sat2->sat_addr.s_net == sat->sat_addr.s_net ) { 109 break; 110 } 111 if( (aa->aa_flags & AFA_PHASE2 ) 112 && (ntohs(aa->aa_firstnet) <= ntohs(sat->sat_addr.s_net)) 113 && (ntohs(aa->aa_lastnet) >= ntohs(sat->sat_addr.s_net))) { 114 break; 115 } 116 } 117 return( aa ); 118} 119 120static void 121aarpwhohas( struct arpcom *ac, struct sockaddr_at *sat ) 122{ 123 struct mbuf *m; 124 struct ether_header *eh; 125 struct ether_aarp *ea; 126 struct at_ifaddr *aa; 127 struct llc *llc; 128 struct sockaddr sa; 129 130 if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) { 131 return; 132 } 133#ifdef MAC 134 mac_create_mbuf_linklayer(&ac->ac_if, m); 135#endif 136 m->m_len = sizeof( *ea ); 137 m->m_pkthdr.len = sizeof( *ea ); 138 MH_ALIGN( m, sizeof( *ea )); 139 140 ea = mtod( m, struct ether_aarp *); 141 bzero((caddr_t)ea, sizeof( *ea )); 142 143 ea->aarp_hrd = htons( AARPHRD_ETHER ); 144 ea->aarp_pro = htons( ETHERTYPE_AT ); 145 ea->aarp_hln = sizeof( ea->aarp_sha ); 146 ea->aarp_pln = sizeof( ea->aarp_spu ); 147 ea->aarp_op = htons( AARPOP_REQUEST ); 148 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha, 149 sizeof( ea->aarp_sha )); 150 151 /* 152 * We need to check whether the output ethernet type should 153 * be phase 1 or 2. We have the interface that we'll be sending 154 * the aarp out. We need to find an AppleTalk network on that 155 * interface with the same address as we're looking for. If the 156 * net is phase 2, generate an 802.2 and SNAP header. 157 */ 158 if ((aa = at_ifawithnet( sat )) == NULL) { 159 m_freem( m ); 160 return; 161 } 162 163 eh = (struct ether_header *)sa.sa_data; 164 165 if ( aa->aa_flags & AFA_PHASE2 ) { 166 bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost, 167 sizeof( eh->ether_dhost )); 168 eh->ether_type = htons(sizeof(struct llc) + sizeof(struct ether_aarp)); 169 M_PREPEND( m, sizeof( struct llc ), M_TRYWAIT ); 170 llc = mtod( m, struct llc *); 171 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 172 llc->llc_control = LLC_UI; 173 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code )); 174 llc->llc_ether_type = htons( ETHERTYPE_AARP ); 175 176 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_spnet, 177 sizeof( ea->aarp_spnet )); 178 bcopy( &sat->sat_addr.s_net, ea->aarp_tpnet, 179 sizeof( ea->aarp_tpnet )); 180 ea->aarp_spnode = AA_SAT( aa )->sat_addr.s_node; 181 ea->aarp_tpnode = sat->sat_addr.s_node; 182 } else { 183 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 184 sizeof( eh->ether_dhost )); 185 eh->ether_type = htons( ETHERTYPE_AARP ); 186 187 ea->aarp_spa = AA_SAT( aa )->sat_addr.s_node; 188 ea->aarp_tpa = sat->sat_addr.s_node; 189 } 190 191#ifdef NETATALKDEBUG 192 printf("aarp: sending request for %u.%u\n", 193 ntohs(AA_SAT( aa )->sat_addr.s_net), 194 AA_SAT( aa )->sat_addr.s_node); 195#endif /* NETATALKDEBUG */ 196 197 sa.sa_len = sizeof( struct sockaddr ); 198 sa.sa_family = AF_UNSPEC; 199 (*ac->ac_if.if_output)(&ac->ac_if, 200 m, &sa, NULL); /* XXX NULL should be routing information */ 201} 202 203int 204aarpresolve( ac, m, destsat, desten ) 205 struct arpcom *ac; 206 struct mbuf *m; 207 struct sockaddr_at *destsat; 208 u_char *desten; 209{ 210 struct at_ifaddr *aa; 211 struct aarptab *aat; 212 int s; 213 214 if ( at_broadcast( destsat )) { 215 m->m_flags |= M_BCAST; 216 if ((aa = at_ifawithnet( destsat )) == NULL) { 217 m_freem( m ); 218 return( 0 ); 219 } 220 if ( aa->aa_flags & AFA_PHASE2 ) { 221 bcopy( (caddr_t)atmulticastaddr, (caddr_t)desten, 222 sizeof( atmulticastaddr )); 223 } else { 224 bcopy( (caddr_t)etherbroadcastaddr, (caddr_t)desten, 225 sizeof( etherbroadcastaddr )); 226 } 227 return( 1 ); 228 } 229 230 s = splimp(); 231 AARPTAB_LOOK( aat, destsat->sat_addr ); 232 if ( aat == 0 ) { /* No entry */ 233 aat = aarptnew( &destsat->sat_addr ); 234 if ( aat == 0 ) { 235 panic( "aarpresolve: no free entry" ); 236 } 237 aat->aat_hold = m; 238 aarpwhohas( ac, destsat ); 239 splx( s ); 240 return( 0 ); 241 } 242 /* found an entry */ 243 aat->aat_timer = 0; 244 if ( aat->aat_flags & ATF_COM ) { /* entry is COMplete */ 245 bcopy( (caddr_t)aat->aat_enaddr, (caddr_t)desten, 246 sizeof( aat->aat_enaddr )); 247 splx( s ); 248 return( 1 ); 249 } 250 /* entry has not completed */ 251 if ( aat->aat_hold ) { 252 m_freem( aat->aat_hold ); 253 } 254 aat->aat_hold = m; 255 aarpwhohas( ac, destsat ); 256 splx( s ); 257 return( 0 ); 258} 259 260void
|
267 if ( ac->ac_if.if_flags & IFF_NOARP ) 268 goto out; 269 270 if ( m->m_len < sizeof( struct arphdr )) { 271 goto out; 272 } 273 274 ar = mtod( m, struct arphdr *); 275 if ( ntohs( ar->ar_hrd ) != AARPHRD_ETHER ) { 276 goto out; 277 } 278 279 if ( m->m_len < sizeof( struct arphdr ) + 2 * ar->ar_hln + 280 2 * ar->ar_pln ) { 281 goto out; 282 } 283 284 switch( ntohs( ar->ar_pro )) { 285 case ETHERTYPE_AT : 286 at_aarpinput( ac, m ); 287 return; 288 289 default: 290 break; 291 } 292 293out: 294 m_freem( m ); 295} 296 297static void 298at_aarpinput( struct arpcom *ac, struct mbuf *m) 299{ 300 struct ether_aarp *ea; 301 struct at_ifaddr *aa; 302 struct aarptab *aat; 303 struct ether_header *eh; 304 struct llc *llc; 305 struct sockaddr_at sat; 306 struct sockaddr sa; 307 struct at_addr spa, tpa, ma; 308 int op; 309 u_short net; 310 311 ea = mtod( m, struct ether_aarp *); 312 313 /* Check to see if from my hardware address */ 314 if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )ac->ac_enaddr, 315 sizeof( ac->ac_enaddr ))) { 316 m_freem( m ); 317 return; 318 } 319 320 op = ntohs( ea->aarp_op ); 321 bcopy( ea->aarp_tpnet, &net, sizeof( net )); 322 323 if ( net != 0 ) { /* should be ATADDR_ANYNET? */ 324 sat.sat_len = sizeof(struct sockaddr_at); 325 sat.sat_family = AF_APPLETALK; 326 sat.sat_addr.s_net = net; 327 if ((aa = at_ifawithnet( &sat )) == NULL) { 328 m_freem( m ); 329 return; 330 } 331 bcopy( ea->aarp_spnet, &spa.s_net, sizeof( spa.s_net )); 332 bcopy( ea->aarp_tpnet, &tpa.s_net, sizeof( tpa.s_net )); 333 } else { 334 /* 335 * Since we don't know the net, we just look for the first 336 * phase 1 address on the interface. 337 */ 338 for (aa = (struct at_ifaddr *)TAILQ_FIRST(&ac->ac_if.if_addrhead); aa; 339 aa = (struct at_ifaddr *)aa->aa_ifa.ifa_link.tqe_next) { 340 if ( AA_SAT( aa )->sat_family == AF_APPLETALK && 341 ( aa->aa_flags & AFA_PHASE2 ) == 0 ) { 342 break; 343 } 344 } 345 if ( aa == NULL ) { 346 m_freem( m ); 347 return; 348 } 349 tpa.s_net = spa.s_net = AA_SAT( aa )->sat_addr.s_net; 350 } 351 352 spa.s_node = ea->aarp_spnode; 353 tpa.s_node = ea->aarp_tpnode; 354 ma.s_net = AA_SAT( aa )->sat_addr.s_net; 355 ma.s_node = AA_SAT( aa )->sat_addr.s_node; 356 357 /* 358 * This looks like it's from us. 359 */ 360 if ( spa.s_net == ma.s_net && spa.s_node == ma.s_node ) { 361 if ( aa->aa_flags & AFA_PROBING ) { 362 /* 363 * We're probing, someone either responded to our probe, or 364 * probed for the same address we'd like to use. Change the 365 * address we're probing for. 366 */ 367 untimeout( aarpprobe, ac, aa->aa_ch ); 368 wakeup( aa ); 369 m_freem( m ); 370 return; 371 } else if ( op != AARPOP_PROBE ) { 372 /* 373 * This is not a probe, and we're not probing. This means 374 * that someone's saying they have the same source address 375 * as the one we're using. Get upset... 376 */ 377 log( LOG_ERR, 378 "aarp: duplicate AT address!! %x:%x:%x:%x:%x:%x\n", 379 ea->aarp_sha[ 0 ], ea->aarp_sha[ 1 ], ea->aarp_sha[ 2 ], 380 ea->aarp_sha[ 3 ], ea->aarp_sha[ 4 ], ea->aarp_sha[ 5 ]); 381 m_freem( m ); 382 return; 383 } 384 } 385 386 AARPTAB_LOOK( aat, spa ); 387 if ( aat ) { 388 if ( op == AARPOP_PROBE ) { 389 /* 390 * Someone's probing for spa, dealocate the one we've got, 391 * so that if the prober keeps the address, we'll be able 392 * to arp for him. 393 */ 394 aarptfree( aat ); 395 m_freem( m ); 396 return; 397 } 398 399 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )aat->aat_enaddr, 400 sizeof( ea->aarp_sha )); 401 aat->aat_flags |= ATF_COM; 402 if ( aat->aat_hold ) { 403 struct mbuf *mhold = aat->aat_hold; 404 aat->aat_hold = NULL; 405 sat.sat_len = sizeof(struct sockaddr_at); 406 sat.sat_family = AF_APPLETALK; 407 sat.sat_addr = spa; 408 (*ac->ac_if.if_output)( &ac->ac_if, mhold, 409 (struct sockaddr *)&sat, NULL); /* XXX */ 410 } 411 } else if ((tpa.s_net == ma.s_net) 412 && (tpa.s_node == ma.s_node) 413 && (op != AARPOP_PROBE) 414 && ((aat = aarptnew( &spa )) != NULL)) { 415 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )aat->aat_enaddr, 416 sizeof( ea->aarp_sha )); 417 aat->aat_flags |= ATF_COM; 418 } 419 420 /* 421 * Don't respond to responses, and never respond if we're 422 * still probing. 423 */ 424 if ( tpa.s_net != ma.s_net || tpa.s_node != ma.s_node || 425 op == AARPOP_RESPONSE || ( aa->aa_flags & AFA_PROBING )) { 426 m_freem( m ); 427 return; 428 } 429 430 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )ea->aarp_tha, 431 sizeof( ea->aarp_sha )); 432 bcopy(( caddr_t )ac->ac_enaddr, ( caddr_t )ea->aarp_sha, 433 sizeof( ea->aarp_sha )); 434 435 /* XXX */ 436 eh = (struct ether_header *)sa.sa_data; 437 bcopy(( caddr_t )ea->aarp_tha, ( caddr_t )eh->ether_dhost, 438 sizeof( eh->ether_dhost )); 439 440 if ( aa->aa_flags & AFA_PHASE2 ) { 441 eh->ether_type = htons( sizeof( struct llc ) + 442 sizeof( struct ether_aarp )); 443 M_PREPEND( m, sizeof( struct llc ), M_DONTWAIT ); 444 if ( m == NULL ) { 445 return; 446 } 447 llc = mtod( m, struct llc *); 448 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 449 llc->llc_control = LLC_UI; 450 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code )); 451 llc->llc_ether_type = htons( ETHERTYPE_AARP ); 452 453 bcopy( ea->aarp_spnet, ea->aarp_tpnet, sizeof( ea->aarp_tpnet )); 454 bcopy( &ma.s_net, ea->aarp_spnet, sizeof( ea->aarp_spnet )); 455 } else { 456 eh->ether_type = htons( ETHERTYPE_AARP ); 457 } 458 459 ea->aarp_tpnode = ea->aarp_spnode; 460 ea->aarp_spnode = ma.s_node; 461 ea->aarp_op = htons( AARPOP_RESPONSE ); 462 463 sa.sa_len = sizeof( struct sockaddr ); 464 sa.sa_family = AF_UNSPEC; 465 (*ac->ac_if.if_output)( &ac->ac_if, m, &sa, NULL); /* XXX */ 466 return; 467} 468 469static void 470aarptfree( struct aarptab *aat) 471{ 472 473 if ( aat->aat_hold ) 474 m_freem( aat->aat_hold ); 475 aat->aat_hold = NULL; 476 aat->aat_timer = aat->aat_flags = 0; 477 aat->aat_ataddr.s_net = 0; 478 aat->aat_ataddr.s_node = 0; 479} 480 481 struct aarptab * 482aarptnew( addr ) 483 struct at_addr *addr; 484{ 485 int n; 486 int oldest = -1; 487 struct aarptab *aat, *aato = NULL; 488 static int first = 1; 489 490 if ( first ) { 491 first = 0; 492 aarptimer_ch = timeout( aarptimer, (caddr_t)0, hz ); 493 } 494 aat = &aarptab[ AARPTAB_HASH( *addr ) * AARPTAB_BSIZ ]; 495 for ( n = 0; n < AARPTAB_BSIZ; n++, aat++ ) { 496 if ( aat->aat_flags == 0 ) 497 goto out; 498 if ( aat->aat_flags & ATF_PERM ) 499 continue; 500 if ((int) aat->aat_timer > oldest ) { 501 oldest = aat->aat_timer; 502 aato = aat; 503 } 504 } 505 if ( aato == NULL ) 506 return( NULL ); 507 aat = aato; 508 aarptfree( aat ); 509out: 510 aat->aat_ataddr = *addr; 511 aat->aat_flags = ATF_INUSE; 512 return( aat ); 513} 514 515 516void 517aarpprobe( void *arg ) 518{ 519 struct arpcom *ac = arg; 520 struct mbuf *m; 521 struct ether_header *eh; 522 struct ether_aarp *ea; 523 struct at_ifaddr *aa; 524 struct llc *llc; 525 struct sockaddr sa; 526 527 /* 528 * We need to check whether the output ethernet type should 529 * be phase 1 or 2. We have the interface that we'll be sending 530 * the aarp out. We need to find an AppleTalk network on that 531 * interface with the same address as we're looking for. If the 532 * net is phase 2, generate an 802.2 and SNAP header. 533 */ 534 for (aa = (struct at_ifaddr *)TAILQ_FIRST(&ac->ac_if.if_addrhead); aa; 535 aa = (struct at_ifaddr *)aa->aa_ifa.ifa_link.tqe_next) { 536 if ( AA_SAT( aa )->sat_family == AF_APPLETALK && 537 ( aa->aa_flags & AFA_PROBING )) { 538 break; 539 } 540 } 541 if ( aa == NULL ) { /* serious error XXX */ 542 printf( "aarpprobe why did this happen?!\n" ); 543 return; 544 } 545 546 if ( aa->aa_probcnt <= 0 ) { 547 aa->aa_flags &= ~AFA_PROBING; 548 wakeup( aa ); 549 return; 550 } else { 551 aa->aa_ch = timeout( aarpprobe, (caddr_t)ac, hz / 5 ); 552 } 553 554 if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) { 555 return; 556 } 557#ifdef MAC 558 mac_create_mbuf_linklayer(&ac->ac_if, m); 559#endif 560 m->m_len = sizeof( *ea ); 561 m->m_pkthdr.len = sizeof( *ea ); 562 MH_ALIGN( m, sizeof( *ea )); 563 564 ea = mtod( m, struct ether_aarp *); 565 bzero((caddr_t)ea, sizeof( *ea )); 566 567 ea->aarp_hrd = htons( AARPHRD_ETHER ); 568 ea->aarp_pro = htons( ETHERTYPE_AT ); 569 ea->aarp_hln = sizeof( ea->aarp_sha ); 570 ea->aarp_pln = sizeof( ea->aarp_spu ); 571 ea->aarp_op = htons( AARPOP_PROBE ); 572 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha, 573 sizeof( ea->aarp_sha )); 574 575 eh = (struct ether_header *)sa.sa_data; 576 577 if ( aa->aa_flags & AFA_PHASE2 ) { 578 bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost, 579 sizeof( eh->ether_dhost )); 580 eh->ether_type = htons( sizeof( struct llc ) + 581 sizeof( struct ether_aarp )); 582 M_PREPEND( m, sizeof( struct llc ), M_TRYWAIT ); 583 llc = mtod( m, struct llc *); 584 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 585 llc->llc_control = LLC_UI; 586 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code )); 587 llc->llc_ether_type = htons( ETHERTYPE_AARP ); 588 589 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_spnet, 590 sizeof( ea->aarp_spnet )); 591 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_tpnet, 592 sizeof( ea->aarp_tpnet )); 593 ea->aarp_spnode = ea->aarp_tpnode = AA_SAT( aa )->sat_addr.s_node; 594 } else { 595 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 596 sizeof( eh->ether_dhost )); 597 eh->ether_type = htons( ETHERTYPE_AARP ); 598 ea->aarp_spa = ea->aarp_tpa = AA_SAT( aa )->sat_addr.s_node; 599 } 600 601#ifdef NETATALKDEBUG 602 printf("aarp: sending probe for %u.%u\n", 603 ntohs(AA_SAT( aa )->sat_addr.s_net), 604 AA_SAT( aa )->sat_addr.s_node); 605#endif /* NETATALKDEBUG */ 606 607 sa.sa_len = sizeof( struct sockaddr ); 608 sa.sa_family = AF_UNSPEC; 609 (*ac->ac_if.if_output)(&ac->ac_if, m, &sa, NULL); /* XXX */ 610 aa->aa_probcnt--; 611} 612 613void 614aarp_clean(void) 615{ 616 struct aarptab *aat; 617 int i; 618 619 untimeout( aarptimer, 0, aarptimer_ch ); 620 for ( i = 0, aat = aarptab; i < AARPTAB_SIZE; i++, aat++ ) { 621 if ( aat->aat_hold ) { 622 m_freem( aat->aat_hold ); 623 aat->aat_hold = NULL; 624 } 625 } 626}
| 268 if ( ac->ac_if.if_flags & IFF_NOARP ) 269 goto out; 270 271 if ( m->m_len < sizeof( struct arphdr )) { 272 goto out; 273 } 274 275 ar = mtod( m, struct arphdr *); 276 if ( ntohs( ar->ar_hrd ) != AARPHRD_ETHER ) { 277 goto out; 278 } 279 280 if ( m->m_len < sizeof( struct arphdr ) + 2 * ar->ar_hln + 281 2 * ar->ar_pln ) { 282 goto out; 283 } 284 285 switch( ntohs( ar->ar_pro )) { 286 case ETHERTYPE_AT : 287 at_aarpinput( ac, m ); 288 return; 289 290 default: 291 break; 292 } 293 294out: 295 m_freem( m ); 296} 297 298static void 299at_aarpinput( struct arpcom *ac, struct mbuf *m) 300{ 301 struct ether_aarp *ea; 302 struct at_ifaddr *aa; 303 struct aarptab *aat; 304 struct ether_header *eh; 305 struct llc *llc; 306 struct sockaddr_at sat; 307 struct sockaddr sa; 308 struct at_addr spa, tpa, ma; 309 int op; 310 u_short net; 311 312 ea = mtod( m, struct ether_aarp *); 313 314 /* Check to see if from my hardware address */ 315 if ( !bcmp(( caddr_t )ea->aarp_sha, ( caddr_t )ac->ac_enaddr, 316 sizeof( ac->ac_enaddr ))) { 317 m_freem( m ); 318 return; 319 } 320 321 op = ntohs( ea->aarp_op ); 322 bcopy( ea->aarp_tpnet, &net, sizeof( net )); 323 324 if ( net != 0 ) { /* should be ATADDR_ANYNET? */ 325 sat.sat_len = sizeof(struct sockaddr_at); 326 sat.sat_family = AF_APPLETALK; 327 sat.sat_addr.s_net = net; 328 if ((aa = at_ifawithnet( &sat )) == NULL) { 329 m_freem( m ); 330 return; 331 } 332 bcopy( ea->aarp_spnet, &spa.s_net, sizeof( spa.s_net )); 333 bcopy( ea->aarp_tpnet, &tpa.s_net, sizeof( tpa.s_net )); 334 } else { 335 /* 336 * Since we don't know the net, we just look for the first 337 * phase 1 address on the interface. 338 */ 339 for (aa = (struct at_ifaddr *)TAILQ_FIRST(&ac->ac_if.if_addrhead); aa; 340 aa = (struct at_ifaddr *)aa->aa_ifa.ifa_link.tqe_next) { 341 if ( AA_SAT( aa )->sat_family == AF_APPLETALK && 342 ( aa->aa_flags & AFA_PHASE2 ) == 0 ) { 343 break; 344 } 345 } 346 if ( aa == NULL ) { 347 m_freem( m ); 348 return; 349 } 350 tpa.s_net = spa.s_net = AA_SAT( aa )->sat_addr.s_net; 351 } 352 353 spa.s_node = ea->aarp_spnode; 354 tpa.s_node = ea->aarp_tpnode; 355 ma.s_net = AA_SAT( aa )->sat_addr.s_net; 356 ma.s_node = AA_SAT( aa )->sat_addr.s_node; 357 358 /* 359 * This looks like it's from us. 360 */ 361 if ( spa.s_net == ma.s_net && spa.s_node == ma.s_node ) { 362 if ( aa->aa_flags & AFA_PROBING ) { 363 /* 364 * We're probing, someone either responded to our probe, or 365 * probed for the same address we'd like to use. Change the 366 * address we're probing for. 367 */ 368 untimeout( aarpprobe, ac, aa->aa_ch ); 369 wakeup( aa ); 370 m_freem( m ); 371 return; 372 } else if ( op != AARPOP_PROBE ) { 373 /* 374 * This is not a probe, and we're not probing. This means 375 * that someone's saying they have the same source address 376 * as the one we're using. Get upset... 377 */ 378 log( LOG_ERR, 379 "aarp: duplicate AT address!! %x:%x:%x:%x:%x:%x\n", 380 ea->aarp_sha[ 0 ], ea->aarp_sha[ 1 ], ea->aarp_sha[ 2 ], 381 ea->aarp_sha[ 3 ], ea->aarp_sha[ 4 ], ea->aarp_sha[ 5 ]); 382 m_freem( m ); 383 return; 384 } 385 } 386 387 AARPTAB_LOOK( aat, spa ); 388 if ( aat ) { 389 if ( op == AARPOP_PROBE ) { 390 /* 391 * Someone's probing for spa, dealocate the one we've got, 392 * so that if the prober keeps the address, we'll be able 393 * to arp for him. 394 */ 395 aarptfree( aat ); 396 m_freem( m ); 397 return; 398 } 399 400 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )aat->aat_enaddr, 401 sizeof( ea->aarp_sha )); 402 aat->aat_flags |= ATF_COM; 403 if ( aat->aat_hold ) { 404 struct mbuf *mhold = aat->aat_hold; 405 aat->aat_hold = NULL; 406 sat.sat_len = sizeof(struct sockaddr_at); 407 sat.sat_family = AF_APPLETALK; 408 sat.sat_addr = spa; 409 (*ac->ac_if.if_output)( &ac->ac_if, mhold, 410 (struct sockaddr *)&sat, NULL); /* XXX */ 411 } 412 } else if ((tpa.s_net == ma.s_net) 413 && (tpa.s_node == ma.s_node) 414 && (op != AARPOP_PROBE) 415 && ((aat = aarptnew( &spa )) != NULL)) { 416 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )aat->aat_enaddr, 417 sizeof( ea->aarp_sha )); 418 aat->aat_flags |= ATF_COM; 419 } 420 421 /* 422 * Don't respond to responses, and never respond if we're 423 * still probing. 424 */ 425 if ( tpa.s_net != ma.s_net || tpa.s_node != ma.s_node || 426 op == AARPOP_RESPONSE || ( aa->aa_flags & AFA_PROBING )) { 427 m_freem( m ); 428 return; 429 } 430 431 bcopy(( caddr_t )ea->aarp_sha, ( caddr_t )ea->aarp_tha, 432 sizeof( ea->aarp_sha )); 433 bcopy(( caddr_t )ac->ac_enaddr, ( caddr_t )ea->aarp_sha, 434 sizeof( ea->aarp_sha )); 435 436 /* XXX */ 437 eh = (struct ether_header *)sa.sa_data; 438 bcopy(( caddr_t )ea->aarp_tha, ( caddr_t )eh->ether_dhost, 439 sizeof( eh->ether_dhost )); 440 441 if ( aa->aa_flags & AFA_PHASE2 ) { 442 eh->ether_type = htons( sizeof( struct llc ) + 443 sizeof( struct ether_aarp )); 444 M_PREPEND( m, sizeof( struct llc ), M_DONTWAIT ); 445 if ( m == NULL ) { 446 return; 447 } 448 llc = mtod( m, struct llc *); 449 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 450 llc->llc_control = LLC_UI; 451 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code )); 452 llc->llc_ether_type = htons( ETHERTYPE_AARP ); 453 454 bcopy( ea->aarp_spnet, ea->aarp_tpnet, sizeof( ea->aarp_tpnet )); 455 bcopy( &ma.s_net, ea->aarp_spnet, sizeof( ea->aarp_spnet )); 456 } else { 457 eh->ether_type = htons( ETHERTYPE_AARP ); 458 } 459 460 ea->aarp_tpnode = ea->aarp_spnode; 461 ea->aarp_spnode = ma.s_node; 462 ea->aarp_op = htons( AARPOP_RESPONSE ); 463 464 sa.sa_len = sizeof( struct sockaddr ); 465 sa.sa_family = AF_UNSPEC; 466 (*ac->ac_if.if_output)( &ac->ac_if, m, &sa, NULL); /* XXX */ 467 return; 468} 469 470static void 471aarptfree( struct aarptab *aat) 472{ 473 474 if ( aat->aat_hold ) 475 m_freem( aat->aat_hold ); 476 aat->aat_hold = NULL; 477 aat->aat_timer = aat->aat_flags = 0; 478 aat->aat_ataddr.s_net = 0; 479 aat->aat_ataddr.s_node = 0; 480} 481 482 struct aarptab * 483aarptnew( addr ) 484 struct at_addr *addr; 485{ 486 int n; 487 int oldest = -1; 488 struct aarptab *aat, *aato = NULL; 489 static int first = 1; 490 491 if ( first ) { 492 first = 0; 493 aarptimer_ch = timeout( aarptimer, (caddr_t)0, hz ); 494 } 495 aat = &aarptab[ AARPTAB_HASH( *addr ) * AARPTAB_BSIZ ]; 496 for ( n = 0; n < AARPTAB_BSIZ; n++, aat++ ) { 497 if ( aat->aat_flags == 0 ) 498 goto out; 499 if ( aat->aat_flags & ATF_PERM ) 500 continue; 501 if ((int) aat->aat_timer > oldest ) { 502 oldest = aat->aat_timer; 503 aato = aat; 504 } 505 } 506 if ( aato == NULL ) 507 return( NULL ); 508 aat = aato; 509 aarptfree( aat ); 510out: 511 aat->aat_ataddr = *addr; 512 aat->aat_flags = ATF_INUSE; 513 return( aat ); 514} 515 516 517void 518aarpprobe( void *arg ) 519{ 520 struct arpcom *ac = arg; 521 struct mbuf *m; 522 struct ether_header *eh; 523 struct ether_aarp *ea; 524 struct at_ifaddr *aa; 525 struct llc *llc; 526 struct sockaddr sa; 527 528 /* 529 * We need to check whether the output ethernet type should 530 * be phase 1 or 2. We have the interface that we'll be sending 531 * the aarp out. We need to find an AppleTalk network on that 532 * interface with the same address as we're looking for. If the 533 * net is phase 2, generate an 802.2 and SNAP header. 534 */ 535 for (aa = (struct at_ifaddr *)TAILQ_FIRST(&ac->ac_if.if_addrhead); aa; 536 aa = (struct at_ifaddr *)aa->aa_ifa.ifa_link.tqe_next) { 537 if ( AA_SAT( aa )->sat_family == AF_APPLETALK && 538 ( aa->aa_flags & AFA_PROBING )) { 539 break; 540 } 541 } 542 if ( aa == NULL ) { /* serious error XXX */ 543 printf( "aarpprobe why did this happen?!\n" ); 544 return; 545 } 546 547 if ( aa->aa_probcnt <= 0 ) { 548 aa->aa_flags &= ~AFA_PROBING; 549 wakeup( aa ); 550 return; 551 } else { 552 aa->aa_ch = timeout( aarpprobe, (caddr_t)ac, hz / 5 ); 553 } 554 555 if (( m = m_gethdr( M_DONTWAIT, MT_DATA )) == NULL ) { 556 return; 557 } 558#ifdef MAC 559 mac_create_mbuf_linklayer(&ac->ac_if, m); 560#endif 561 m->m_len = sizeof( *ea ); 562 m->m_pkthdr.len = sizeof( *ea ); 563 MH_ALIGN( m, sizeof( *ea )); 564 565 ea = mtod( m, struct ether_aarp *); 566 bzero((caddr_t)ea, sizeof( *ea )); 567 568 ea->aarp_hrd = htons( AARPHRD_ETHER ); 569 ea->aarp_pro = htons( ETHERTYPE_AT ); 570 ea->aarp_hln = sizeof( ea->aarp_sha ); 571 ea->aarp_pln = sizeof( ea->aarp_spu ); 572 ea->aarp_op = htons( AARPOP_PROBE ); 573 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->aarp_sha, 574 sizeof( ea->aarp_sha )); 575 576 eh = (struct ether_header *)sa.sa_data; 577 578 if ( aa->aa_flags & AFA_PHASE2 ) { 579 bcopy((caddr_t)atmulticastaddr, (caddr_t)eh->ether_dhost, 580 sizeof( eh->ether_dhost )); 581 eh->ether_type = htons( sizeof( struct llc ) + 582 sizeof( struct ether_aarp )); 583 M_PREPEND( m, sizeof( struct llc ), M_TRYWAIT ); 584 llc = mtod( m, struct llc *); 585 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 586 llc->llc_control = LLC_UI; 587 bcopy( aarp_org_code, llc->llc_org_code, sizeof( aarp_org_code )); 588 llc->llc_ether_type = htons( ETHERTYPE_AARP ); 589 590 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_spnet, 591 sizeof( ea->aarp_spnet )); 592 bcopy( &AA_SAT( aa )->sat_addr.s_net, ea->aarp_tpnet, 593 sizeof( ea->aarp_tpnet )); 594 ea->aarp_spnode = ea->aarp_tpnode = AA_SAT( aa )->sat_addr.s_node; 595 } else { 596 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 597 sizeof( eh->ether_dhost )); 598 eh->ether_type = htons( ETHERTYPE_AARP ); 599 ea->aarp_spa = ea->aarp_tpa = AA_SAT( aa )->sat_addr.s_node; 600 } 601 602#ifdef NETATALKDEBUG 603 printf("aarp: sending probe for %u.%u\n", 604 ntohs(AA_SAT( aa )->sat_addr.s_net), 605 AA_SAT( aa )->sat_addr.s_node); 606#endif /* NETATALKDEBUG */ 607 608 sa.sa_len = sizeof( struct sockaddr ); 609 sa.sa_family = AF_UNSPEC; 610 (*ac->ac_if.if_output)(&ac->ac_if, m, &sa, NULL); /* XXX */ 611 aa->aa_probcnt--; 612} 613 614void 615aarp_clean(void) 616{ 617 struct aarptab *aat; 618 int i; 619 620 untimeout( aarptimer, 0, aarptimer_ch ); 621 for ( i = 0, aat = aarptab; i < AARPTAB_SIZE; i++, aat++ ) { 622 if ( aat->aat_hold ) { 623 m_freem( aat->aat_hold ); 624 aat->aat_hold = NULL; 625 } 626 } 627}
|