[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netatalk/aarp.c

Version: -  FREEBSD  -  FREEBSD10  -  FREEBSD9  -  FREEBSD92  -  FREEBSD91  -  FREEBSD90  -  FREEBSD8  -  FREEBSD82  -  FREEBSD81  -  FREEBSD80  -  FREEBSD7  -  FREEBSD74  -  FREEBSD73  -  FREEBSD72  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  cheribsd  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1  -  FREEBSD-LIBC  -  FREEBSD8-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  3  -  10 

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

Cache object: 8b821ec74b41270dc292953ad9702a3b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.