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

Cache object: 734f401a674ed47ab65de2f7e09019bf


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