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

Cache object: 28927d349c4d5cd65b2ac80d5a62cf59


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