The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ 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  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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


[ 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.