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  -  FREEBSD11  -  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  -  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 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1990,1991 Regents of The University of Michigan.
    3  * All Rights Reserved.
    4  *
    5  * $FreeBSD: src/sys/netatalk/aarp.c,v 1.21 2003/03/21 17:53:16 mdodd Exp $
    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 
   31 static void aarptfree( struct aarptab *aat);
   32 static 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)
   37 static 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__ )
   58 extern u_char                   etherbroadcastaddr[6];
   59 # endif /* __FreeBSD__ */
   60 
   61 static 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 struct callout_handle aarptimer_ch =
   73     CALLOUT_HANDLE_INITIALIZER(&aarptimer_ch);
   74 
   75 static void
   76 aarptimer(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  */
  100 struct at_ifaddr *
  101 at_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 
  120 static void
  121 aarpwhohas( 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)ac->ac_if.if_broadcastaddr, (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 
  203 int
  204 aarpresolve( 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)ac->ac_if.if_broadcastaddr, (caddr_t)desten,
  225                     sizeof( ac->ac_if.if_addrlen ));
  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 
  260 void
  261 aarpintr( m )
  262     struct mbuf         *m;
  263 {
  264     struct arphdr       *ar;
  265     struct arpcom       *ac;
  266 
  267     ac = (struct arpcom *)m->m_pkthdr.rcvif;
  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 
  294 out:
  295     m_freem( m );
  296 }
  297 
  298 static void
  299 at_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 
  470 static void
  471 aarptfree( 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 *
  483 aarptnew( 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 );
  510 out:
  511     aat->aat_ataddr = *addr;
  512     aat->aat_flags = ATF_INUSE;
  513     return( aat );
  514 }
  515 
  516 
  517 void
  518 aarpprobe( 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)ac->ac_if.if_broadcastaddr, (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 
  614 void
  615 aarp_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 }

Cache object: e2b7d89a94fba27d79b15c2cd85a89a3


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