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

Cache object: ea8317314135ca81852f8cce2a9d5e69


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