summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netatalk/aarp.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/netatalk/aarp.c')
-rw-r--r--freebsd/sys/netatalk/aarp.c726
1 files changed, 0 insertions, 726 deletions
diff --git a/freebsd/sys/netatalk/aarp.c b/freebsd/sys/netatalk/aarp.c
deleted file mode 100644
index 4ce3701a..00000000
--- a/freebsd/sys/netatalk/aarp.c
+++ /dev/null
@@ -1,726 +0,0 @@
-#include <machine/rtems-bsd-kernel-space.h>
-
-/*-
- * Copyright (c) 2004-2009 Robert N. M. Watson
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Copyright (c) 1990,1991,1994 Regents of The University of Michigan.
- * All Rights Reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation, and that the name of The University
- * of Michigan not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. This software is supplied as is without expressed or
- * implied warranties of any kind.
- *
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- *
- * Research Systems Unix Group
- * The University of Michigan
- * c/o Wesley Craig
- * 535 W. William Street
- * Ann Arbor, Michigan
- * +1-313-764-2278
- * netatalk@umich.edu
- *
- * $FreeBSD$
- */
-
-#include <rtems/bsd/local/opt_atalk.h>
-
-#include <rtems/bsd/sys/param.h>
-#include <sys/systm.h>
-#include <sys/mbuf.h>
-#include <sys/kernel.h>
-#include <sys/socket.h>
-#include <sys/syslog.h>
-
-#include <net/if.h>
-#include <net/if_dl.h>
-
-#include <netinet/in.h>
-#undef s_net
-#include <netinet/if_ether.h>
-
-#include <netatalk/at.h>
-#include <netatalk/at_var.h>
-#include <netatalk/aarp.h>
-#include <netatalk/phase2.h>
-#include <netatalk/at_extern.h>
-
-#include <security/mac/mac_framework.h>
-
-static void aarptfree(struct aarptab *aat);
-static void at_aarpinput(struct ifnet *ifp, struct mbuf *m);
-
-#define AARPTAB_BSIZ 9
-#define AARPTAB_NB 19
-#define AARPTAB_SIZE (AARPTAB_BSIZ * AARPTAB_NB)
-static struct aarptab aarptab[AARPTAB_SIZE];
-
-struct mtx aarptab_mtx;
-MTX_SYSINIT(aarptab_mtx, &aarptab_mtx, "aarptab_mtx", MTX_DEF);
-
-#define AARPTAB_HASH(a) ((((a).s_net << 8) + (a).s_node) % AARPTAB_NB)
-
-#define AARPTAB_LOOK(aat, addr) do { \
- int n; \
- \
- AARPTAB_LOCK_ASSERT(); \
- aat = &aarptab[ AARPTAB_HASH(addr) * AARPTAB_BSIZ ]; \
- for (n = 0; n < AARPTAB_BSIZ; n++, aat++) { \
- if (aat->aat_ataddr.s_net == (addr).s_net && \
- aat->aat_ataddr.s_node == (addr).s_node) \
- break; \
- } \
- if (n >= AARPTAB_BSIZ) \
- aat = NULL; \
-} while (0)
-
-#define AARPT_AGE (60 * 1)
-#define AARPT_KILLC 20
-#define AARPT_KILLI 3
-
-static const u_char atmulticastaddr[6] = {
- 0x09, 0x00, 0x07, 0xff, 0xff, 0xff,
-};
-
-u_char at_org_code[3] = {
- 0x08, 0x00, 0x07,
-};
-const u_char aarp_org_code[3] = {
- 0x00, 0x00, 0x00,
-};
-
-static struct callout_handle aarptimer_ch =
- CALLOUT_HANDLE_INITIALIZER(&aarptimer_ch);
-
-static void
-aarptimer(void *ignored)
-{
- struct aarptab *aat;
- int i;
-
- aarptimer_ch = timeout(aarptimer, NULL, AARPT_AGE * hz);
- aat = aarptab;
- AARPTAB_LOCK();
- for (i = 0; i < AARPTAB_SIZE; i++, aat++) {
- if (aat->aat_flags == 0 || (aat->aat_flags & ATF_PERM))
- continue;
- if (++aat->aat_timer < ((aat->aat_flags & ATF_COM) ?
- AARPT_KILLC : AARPT_KILLI))
- continue;
- aarptfree(aat);
- }
- AARPTAB_UNLOCK();
-}
-
-/*
- * Search through the network addresses to find one that includes the given
- * network. Remember to take netranges into consideration.
- *
- * The _locked variant relies on the caller holding the at_ifaddr lock; the
- * unlocked variant returns a reference that the caller must dispose of.
- */
-struct at_ifaddr *
-at_ifawithnet_locked(struct sockaddr_at *sat)
-{
- struct at_ifaddr *aa;
- struct sockaddr_at *sat2;
-
- AT_IFADDR_LOCK_ASSERT();
-
- TAILQ_FOREACH(aa, &at_ifaddrhead, aa_link) {
- sat2 = &(aa->aa_addr);
- if (sat2->sat_addr.s_net == sat->sat_addr.s_net)
- break;
- if ((aa->aa_flags & AFA_PHASE2) &&
- (ntohs(aa->aa_firstnet) <= ntohs(sat->sat_addr.s_net)) &&
- (ntohs(aa->aa_lastnet) >= ntohs(sat->sat_addr.s_net)))
- break;
- }
- return (aa);
-}
-
-struct at_ifaddr *
-at_ifawithnet(struct sockaddr_at *sat)
-{
- struct at_ifaddr *aa;
-
- AT_IFADDR_RLOCK();
- aa = at_ifawithnet_locked(sat);
- if (aa != NULL)
- ifa_ref(&aa->aa_ifa);
- AT_IFADDR_RUNLOCK();
- return (aa);
-}
-
-static void
-aarpwhohas(struct ifnet *ifp, struct sockaddr_at *sat)
-{
- struct mbuf *m;
- struct ether_header *eh;
- struct ether_aarp *ea;
- struct at_ifaddr *aa;
- struct llc *llc;
- struct sockaddr sa;
-
- AARPTAB_UNLOCK_ASSERT();
- m = m_gethdr(M_DONTWAIT, MT_DATA);
- if (m == NULL)
- return;
-#ifdef MAC
- mac_netatalk_aarp_send(ifp, m);
-#endif
- m->m_len = sizeof(*ea);
- m->m_pkthdr.len = sizeof(*ea);
- MH_ALIGN(m, sizeof(*ea));
-
- ea = mtod(m, struct ether_aarp *);
- bzero((caddr_t)ea, sizeof(*ea));
-
- ea->aarp_hrd = htons(AARPHRD_ETHER);
- ea->aarp_pro = htons(ETHERTYPE_AT);
- ea->aarp_hln = sizeof(ea->aarp_sha);
- ea->aarp_pln = sizeof(ea->aarp_spu);
- ea->aarp_op = htons(AARPOP_REQUEST);
- bcopy(IF_LLADDR(ifp), (caddr_t)ea->aarp_sha, sizeof(ea->aarp_sha));
-
- /*
- * We need to check whether the output ethernet type should be phase
- * 1 or 2. We have the interface that we'll be sending the aarp out.
- * We need to find an AppleTalk network on that interface with the
- * same address as we're looking for. If the net is phase 2,
- * generate an 802.2 and SNAP header.
- */
- aa = at_ifawithnet(sat);
- if (aa == NULL) {
- m_freem(m);
- return;
- }
-
- eh = (struct ether_header *)sa.sa_data;
-
- if (aa->aa_flags & AFA_PHASE2) {
- bcopy(atmulticastaddr, eh->ether_dhost,
- sizeof(eh->ether_dhost));
- eh->ether_type = htons(sizeof(struct llc) +
- sizeof(struct ether_aarp));
- M_PREPEND(m, sizeof(struct llc), M_DONTWAIT);
- if (m == NULL) {
- ifa_free(&aa->aa_ifa);
- return;
- }
- llc = mtod(m, struct llc *);
- llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
- llc->llc_control = LLC_UI;
- bcopy(aarp_org_code, llc->llc_org_code,
- sizeof(aarp_org_code));
- llc->llc_ether_type = htons(ETHERTYPE_AARP);
- bcopy(&AA_SAT(aa)->sat_addr.s_net, ea->aarp_spnet,
- sizeof(ea->aarp_spnet));
- bcopy(&sat->sat_addr.s_net, ea->aarp_tpnet,
- sizeof(ea->aarp_tpnet));
- ea->aarp_spnode = AA_SAT(aa)->sat_addr.s_node;
- ea->aarp_tpnode = sat->sat_addr.s_node;
- } else {
- bcopy(ifp->if_broadcastaddr, (caddr_t)eh->ether_dhost,
- sizeof(eh->ether_dhost));
- eh->ether_type = htons(ETHERTYPE_AARP);
- ea->aarp_spa = AA_SAT(aa)->sat_addr.s_node;
- ea->aarp_tpa = sat->sat_addr.s_node;
- }
-
-#ifdef NETATALKDEBUG
- printf("aarp: sending request for %u.%u\n",
- ntohs(AA_SAT(aa)->sat_addr.s_net), AA_SAT(aa)->sat_addr.s_node);
-#endif /* NETATALKDEBUG */
- ifa_free(&aa->aa_ifa);
-
- sa.sa_len = sizeof(struct sockaddr);
- sa.sa_family = AF_UNSPEC;
- ifp->if_output(ifp, m, &sa, NULL);
-}
-
-int
-aarpresolve(struct ifnet *ifp, struct mbuf *m, struct sockaddr_at *destsat,
- u_char *desten)
-{
- struct at_ifaddr *aa;
- struct aarptab *aat;
-
- AT_IFADDR_RLOCK();
- if (at_broadcast(destsat)) {
- m->m_flags |= M_BCAST;
- if ((aa = at_ifawithnet_locked(destsat)) == NULL) {
- AT_IFADDR_RUNLOCK();
- m_freem(m);
- return (0);
- }
- if (aa->aa_flags & AFA_PHASE2)
- bcopy(atmulticastaddr, (caddr_t)desten,
- sizeof(atmulticastaddr));
- else
- bcopy(ifp->if_broadcastaddr, (caddr_t)desten,
- sizeof(ifp->if_addrlen));
- AT_IFADDR_RUNLOCK();
- return (1);
- }
- AT_IFADDR_RUNLOCK();
-
- AARPTAB_LOCK();
- AARPTAB_LOOK(aat, destsat->sat_addr);
- if (aat == NULL) {
- /* No entry. */
- aat = aarptnew(&destsat->sat_addr);
-
- /* We should fail more gracefully. */
- if (aat == NULL)
- panic("aarpresolve: no free entry");
- goto done;
- }
-
- /* Found an entry. */
- aat->aat_timer = 0;
- if (aat->aat_flags & ATF_COM) {
- /* Entry is COMplete. */
- bcopy((caddr_t)aat->aat_enaddr, (caddr_t)desten,
- sizeof(aat->aat_enaddr));
- AARPTAB_UNLOCK();
- return (1);
- }
-
- /* Entry has not completed. */
- if (aat->aat_hold)
- m_freem(aat->aat_hold);
-done:
- aat->aat_hold = m;
- AARPTAB_UNLOCK();
- aarpwhohas(ifp, destsat);
- return (0);
-}
-
-void
-aarpintr(struct mbuf *m)
-{
- struct arphdr *ar;
- struct ifnet *ifp;
-
- ifp = m->m_pkthdr.rcvif;
- if (ifp->if_flags & IFF_NOARP)
- goto out;
-
- if (m->m_len < sizeof(struct arphdr))
- goto out;
-
- ar = mtod(m, struct arphdr *);
- if (ntohs(ar->ar_hrd) != AARPHRD_ETHER)
- goto out;
-
- if (m->m_len < sizeof(struct arphdr) + 2 * ar->ar_hln +
- 2 * ar->ar_pln)
- goto out;
-
- switch(ntohs(ar->ar_pro)) {
- case ETHERTYPE_AT:
- at_aarpinput(ifp, m);
- return;
- default:
- break;
- }
-
-out:
- m_freem(m);
-}
-
-static void
-at_aarpinput(struct ifnet *ifp, struct mbuf *m)
-{
- struct ether_aarp *ea;
- struct at_ifaddr *aa;
- struct aarptab *aat;
- struct ether_header *eh;
- struct llc *llc;
- struct sockaddr_at sat;
- struct sockaddr sa;
- struct at_addr spa, tpa, ma;
- int op;
- u_short net;
-
- ea = mtod(m, struct ether_aarp *);
-
- /* Check to see if from my hardware address. */
- if (!bcmp((caddr_t)ea->aarp_sha, IF_LLADDR(ifp), ETHER_ADDR_LEN)) {
- m_freem(m);
- return;
- }
-
- /* Don't accept requests from broadcast address. */
- if (!bcmp(ea->aarp_sha, ifp->if_broadcastaddr, ifp->if_addrlen)) {
- log(LOG_ERR, "aarp: source link address is broadcast\n");
- m_freem(m);
- return;
- }
-
- op = ntohs(ea->aarp_op);
- bcopy(ea->aarp_tpnet, &net, sizeof(net));
-
- if (net != 0) {
- /* Should be ATADDR_ANYNET? */
- sat.sat_len = sizeof(struct sockaddr_at);
- sat.sat_family = AF_APPLETALK;
- sat.sat_addr.s_net = net;
- aa = at_ifawithnet(&sat);
- if (aa == NULL) {
- m_freem(m);
- return;
- }
- bcopy(ea->aarp_spnet, &spa.s_net, sizeof(spa.s_net));
- bcopy(ea->aarp_tpnet, &tpa.s_net, sizeof(tpa.s_net));
- } else {
- /*
- * Since we don't know the net, we just look for the first
- * phase 1 address on the interface.
- */
- IF_ADDR_RLOCK(ifp);
- for (aa = (struct at_ifaddr *)TAILQ_FIRST(&ifp->if_addrhead);
- aa;
- aa = (struct at_ifaddr *)aa->aa_ifa.ifa_link.tqe_next) {
- if (AA_SAT(aa)->sat_family == AF_APPLETALK &&
- (aa->aa_flags & AFA_PHASE2) == 0) {
- break;
- }
- }
- if (aa == NULL) {
- IF_ADDR_RUNLOCK(ifp);
- m_freem(m);
- return;
- }
- ifa_ref(&aa->aa_ifa);
- IF_ADDR_RUNLOCK(ifp);
- tpa.s_net = spa.s_net = AA_SAT(aa)->sat_addr.s_net;
- }
-
- spa.s_node = ea->aarp_spnode;
- tpa.s_node = ea->aarp_tpnode;
- ma.s_net = AA_SAT(aa)->sat_addr.s_net;
- ma.s_node = AA_SAT(aa)->sat_addr.s_node;
-
- /*
- * This looks like it's from us.
- */
- if (spa.s_net == ma.s_net && spa.s_node == ma.s_node) {
- if (aa->aa_flags & AFA_PROBING) {
- /*
- * We're probing, someone either responded to our
- * probe, or probed for the same address we'd like to
- * use. Change the address we're probing for.
- */
- callout_stop(&aa->aa_callout);
- wakeup(aa);
- ifa_free(&aa->aa_ifa);
- m_freem(m);
- return;
- } else if (op != AARPOP_PROBE) {
- /*
- * This is not a probe, and we're not probing. This
- * means that someone's saying they have the same
- * source address as the one we're using. Get upset.
- */
- ifa_free(&aa->aa_ifa);
- log(LOG_ERR,
- "aarp: duplicate AT address!! %x:%x:%x:%x:%x:%x\n",
- ea->aarp_sha[0], ea->aarp_sha[1],
- ea->aarp_sha[2], ea->aarp_sha[3],
- ea->aarp_sha[4], ea->aarp_sha[5]);
- m_freem(m);
- return;
- }
- }
-
- AARPTAB_LOCK();
- AARPTAB_LOOK(aat, spa);
- if (aat != NULL) {
- if (op == AARPOP_PROBE) {
- /*
- * Someone's probing for spa, dealocate the one we've
- * got, so that if the prober keeps the address,
- * we'll be able to arp for him.
- */
- aarptfree(aat);
- AARPTAB_UNLOCK();
- ifa_free(&aa->aa_ifa);
- m_freem(m);
- return;
- }
-
- bcopy((caddr_t)ea->aarp_sha, (caddr_t)aat->aat_enaddr,
- sizeof(ea->aarp_sha));
- aat->aat_flags |= ATF_COM;
- if (aat->aat_hold) {
- struct mbuf *mhold = aat->aat_hold;
- aat->aat_hold = NULL;
- AARPTAB_UNLOCK();
- sat.sat_len = sizeof(struct sockaddr_at);
- sat.sat_family = AF_APPLETALK;
- sat.sat_addr = spa;
- (*ifp->if_output)(ifp, mhold,
- (struct sockaddr *)&sat, NULL); /* XXX */
- } else
- AARPTAB_UNLOCK();
- } else if ((tpa.s_net == ma.s_net) && (tpa.s_node == ma.s_node)
- && (op != AARPOP_PROBE) && ((aat = aarptnew(&spa)) != NULL)) {
- bcopy((caddr_t)ea->aarp_sha, (caddr_t)aat->aat_enaddr,
- sizeof(ea->aarp_sha));
- aat->aat_flags |= ATF_COM;
- AARPTAB_UNLOCK();
- } else
- AARPTAB_UNLOCK();
-
- /*
- * Don't respond to responses, and never respond if we're still
- * probing.
- */
- if (tpa.s_net != ma.s_net || tpa.s_node != ma.s_node ||
- op == AARPOP_RESPONSE || (aa->aa_flags & AFA_PROBING)) {
- ifa_free(&aa->aa_ifa);
- m_freem(m);
- return;
- }
-
- bcopy((caddr_t)ea->aarp_sha, (caddr_t)ea->aarp_tha,
- sizeof(ea->aarp_sha));
- bcopy(IF_LLADDR(ifp), (caddr_t)ea->aarp_sha, sizeof(ea->aarp_sha));
-
- /* XXX */
- eh = (struct ether_header *)sa.sa_data;
- bcopy((caddr_t)ea->aarp_tha, (caddr_t)eh->ether_dhost,
- sizeof(eh->ether_dhost));
-
- if (aa->aa_flags & AFA_PHASE2) {
- eh->ether_type = htons(sizeof(struct llc) +
- sizeof(struct ether_aarp));
- M_PREPEND(m, sizeof(struct llc), M_DONTWAIT);
- if (m == NULL) {
- ifa_free(&aa->aa_ifa);
- return;
- }
- llc = mtod(m, struct llc *);
- llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
- llc->llc_control = LLC_UI;
- bcopy(aarp_org_code, llc->llc_org_code,
- sizeof(aarp_org_code));
- llc->llc_ether_type = htons(ETHERTYPE_AARP);
-
- bcopy(ea->aarp_spnet, ea->aarp_tpnet,
- sizeof(ea->aarp_tpnet));
- bcopy(&ma.s_net, ea->aarp_spnet, sizeof(ea->aarp_spnet));
- } else
- eh->ether_type = htons(ETHERTYPE_AARP);
- ifa_free(&aa->aa_ifa);
-
- ea->aarp_tpnode = ea->aarp_spnode;
- ea->aarp_spnode = ma.s_node;
- ea->aarp_op = htons(AARPOP_RESPONSE);
-
- sa.sa_len = sizeof(struct sockaddr);
- sa.sa_family = AF_UNSPEC;
- (*ifp->if_output)(ifp, m, &sa, NULL); /* XXX */
- return;
-}
-
-static void
-aarptfree(struct aarptab *aat)
-{
-
- AARPTAB_LOCK_ASSERT();
- if (aat->aat_hold)
- m_freem(aat->aat_hold);
- aat->aat_hold = NULL;
- aat->aat_timer = aat->aat_flags = 0;
- aat->aat_ataddr.s_net = 0;
- aat->aat_ataddr.s_node = 0;
-}
-
-struct aarptab *
-aarptnew(struct at_addr *addr)
-{
- int n;
- int oldest = -1;
- struct aarptab *aat, *aato = NULL;
- static int first = 1;
-
- AARPTAB_LOCK_ASSERT();
- if (first) {
- first = 0;
- aarptimer_ch = timeout(aarptimer, (caddr_t)0, hz);
- }
- aat = &aarptab[AARPTAB_HASH(*addr) * AARPTAB_BSIZ];
- for (n = 0; n < AARPTAB_BSIZ; n++, aat++) {
- if (aat->aat_flags == 0)
- goto out;
- if (aat->aat_flags & ATF_PERM)
- continue;
- if ((int) aat->aat_timer > oldest) {
- oldest = aat->aat_timer;
- aato = aat;
- }
- }
- if (aato == NULL)
- return (NULL);
- aat = aato;
- aarptfree(aat);
-out:
- aat->aat_ataddr = *addr;
- aat->aat_flags = ATF_INUSE;
- return (aat);
-}
-
-
-void
-aarpprobe(void *arg)
-{
- struct ifnet *ifp = arg;
- struct mbuf *m;
- struct ether_header *eh;
- struct ether_aarp *ea;
- struct at_ifaddr *aa;
- struct llc *llc;
- struct sockaddr sa;
-
- /*
- * We need to check whether the output ethernet type should be phase
- * 1 or 2. We have the interface that we'll be sending the aarp out.
- * We need to find an AppleTalk network on that interface with the
- * same address as we're looking for. If the net is phase 2,
- * generate an 802.2 and SNAP header.
- */
- AARPTAB_LOCK();
- for (aa = (struct at_ifaddr *)TAILQ_FIRST(&ifp->if_addrhead); aa;
- aa = (struct at_ifaddr *)aa->aa_ifa.ifa_link.tqe_next) {
- if (AA_SAT(aa)->sat_family == AF_APPLETALK &&
- (aa->aa_flags & AFA_PROBING))
- break;
- }
- if (aa == NULL) {
- /* Serious error XXX. */
- AARPTAB_UNLOCK();
- printf("aarpprobe why did this happen?!\n");
- return;
- }
-
- if (aa->aa_probcnt <= 0) {
- aa->aa_flags &= ~AFA_PROBING;
- wakeup(aa);
- AARPTAB_UNLOCK();
- return;
- } else
- callout_reset(&aa->aa_callout, hz / 5, aarpprobe, ifp);
- ifa_ref(&aa->aa_ifa);
- AARPTAB_UNLOCK();
-
- m = m_gethdr(M_DONTWAIT, MT_DATA);
- if (m == NULL) {
- ifa_free(&aa->aa_ifa);
- return;
- }
-#ifdef MAC
- mac_netatalk_aarp_send(ifp, m);
-#endif
- m->m_len = sizeof(*ea);
- m->m_pkthdr.len = sizeof(*ea);
- MH_ALIGN(m, sizeof(*ea));
-
- ea = mtod(m, struct ether_aarp *);
- bzero((caddr_t)ea, sizeof(*ea));
-
- ea->aarp_hrd = htons(AARPHRD_ETHER);
- ea->aarp_pro = htons(ETHERTYPE_AT);
- ea->aarp_hln = sizeof(ea->aarp_sha);
- ea->aarp_pln = sizeof(ea->aarp_spu);
- ea->aarp_op = htons(AARPOP_PROBE);
- bcopy(IF_LLADDR(ifp), (caddr_t)ea->aarp_sha,
- sizeof(ea->aarp_sha));
-
- eh = (struct ether_header *)sa.sa_data;
-
- if (aa->aa_flags & AFA_PHASE2) {
- bcopy(atmulticastaddr, eh->ether_dhost,
- sizeof(eh->ether_dhost));
- eh->ether_type = htons(sizeof(struct llc) +
- sizeof(struct ether_aarp));
- M_PREPEND(m, sizeof(struct llc), M_WAIT);
- llc = mtod(m, struct llc *);
- llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
- llc->llc_control = LLC_UI;
- bcopy(aarp_org_code, llc->llc_org_code,
- sizeof(aarp_org_code));
- llc->llc_ether_type = htons(ETHERTYPE_AARP);
-
- bcopy(&AA_SAT(aa)->sat_addr.s_net, ea->aarp_spnet,
- sizeof(ea->aarp_spnet));
- bcopy(&AA_SAT(aa)->sat_addr.s_net, ea->aarp_tpnet,
- sizeof(ea->aarp_tpnet));
- ea->aarp_spnode = ea->aarp_tpnode =
- AA_SAT(aa)->sat_addr.s_node;
- } else {
- bcopy(ifp->if_broadcastaddr, (caddr_t)eh->ether_dhost,
- sizeof(eh->ether_dhost));
- eh->ether_type = htons(ETHERTYPE_AARP);
- ea->aarp_spa = ea->aarp_tpa = AA_SAT(aa)->sat_addr.s_node;
- }
-
-#ifdef NETATALKDEBUG
- printf("aarp: sending probe for %u.%u\n",
- ntohs(AA_SAT(aa)->sat_addr.s_net), AA_SAT(aa)->sat_addr.s_node);
-#endif /* NETATALKDEBUG */
- ifa_free(&aa->aa_ifa);
-
- sa.sa_len = sizeof(struct sockaddr);
- sa.sa_family = AF_UNSPEC;
- (*ifp->if_output)(ifp, m, &sa, NULL); /* XXX */
- aa->aa_probcnt--;
-}
-
-void
-aarp_clean(void)
-{
- struct aarptab *aat;
- int i;
-
- untimeout(aarptimer, 0, aarptimer_ch);
- AARPTAB_LOCK();
- for (i = 0, aat = aarptab; i < AARPTAB_SIZE; i++, aat++) {
- if (aat->aat_hold) {
- m_freem(aat->aat_hold);
- aat->aat_hold = NULL;
- }
- }
- AARPTAB_UNLOCK();
-}