Make ARP stats per-cpu.
This commit is contained in:
parent
b849cd90e5
commit
881a947288
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_arp.h,v 1.28 2008/02/20 17:05:52 matt Exp $ */
|
||||
/* $NetBSD: if_arp.h,v 1.29 2008/04/15 15:17:54 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1986, 1993
|
||||
|
@ -101,33 +101,30 @@ struct arpreq {
|
|||
/*
|
||||
* Kernel statistics about arp
|
||||
*/
|
||||
struct arpstat {
|
||||
u_quad_t as_sndtotal; /* total packets sent */
|
||||
u_quad_t as_sndreply; /* replies sent */
|
||||
u_quad_t as_sndrequest; /* requests sent */
|
||||
#define ARP_STAT_SNDTOTAL 0 /* total packets sent */
|
||||
#define ARP_STAT_SNDREPLY 1 /* replies sent */
|
||||
#define ARP_STAT_SENDREQUEST 2 /* requests sent */
|
||||
#define ARP_STAT_RCVTOTAL 3 /* total packets received */
|
||||
#define ARP_STAT_RCVREQUEST 4 /* valid requests received */
|
||||
#define ARP_STAT_RCVREPLY 5 /* replies received */
|
||||
#define ARP_STAT_RCVMCAST 6 /* multicast/broadcast received */
|
||||
#define ARP_STAT_RCVBADPROTO 7 /* unknown protocol type received */
|
||||
#define ARP_STAT_RCVBADLEN 8 /* bad (short) length received */
|
||||
#define ARP_STAT_RCVZEROTPA 9 /* received w/ null target ip */
|
||||
#define ARP_STAT_RCVZEROSPA 10 /* received w/ null source ip */
|
||||
#define ARP_STAT_RCVNOINT 11 /* couldn't map to interface */
|
||||
#define ARP_STAT_RCVLOCALSHA 12 /* received from local hw address */
|
||||
#define ARP_STAT_RCVBCASTSHA 13 /* received w/ broadcast src */
|
||||
#define ARP_STAT_RCVLOCALSPA 14 /* received for a local ip [dup!] */
|
||||
#define ARP_STAT_RCVOVERPERM 15 /* attempts to overwrite static info */
|
||||
#define ARP_STAT_RCVOVERINT 16 /* attempts to overwrite wrong if */
|
||||
#define ARP_STAT_RCVOVER 17 /* entries overwritten! */
|
||||
#define ARP_STAT_RCVLENCHG 18 /* changes in hw address len */
|
||||
#define ARP_STAT_DFRTOTAL 19 /* deferred pending ARP resolution */
|
||||
#define ARP_STAT_DFRSENT 20 /* deferred, then sent */
|
||||
#define ARP_STAT_DFRDROPPED 21 /* deferred, then dropped */
|
||||
#define ARP_STAT_ALLOCFAIL 22 /* failures to allocate llinfo */
|
||||
|
||||
u_quad_t as_rcvtotal; /* total packets received */
|
||||
u_quad_t as_rcvrequest; /* valid requests received */
|
||||
u_quad_t as_rcvreply; /* replies received */
|
||||
u_quad_t as_rcvmcast; /* multicast/broadcast received */
|
||||
u_quad_t as_rcvbadproto; /* unknown protocol type received */
|
||||
u_quad_t as_rcvbadlen; /* bad (short) length received */
|
||||
u_quad_t as_rcvzerotpa; /* received w/ null target ip */
|
||||
u_quad_t as_rcvzerospa; /* received w/ null src ip */
|
||||
u_quad_t as_rcvnoint; /* couldn't map to interface */
|
||||
u_quad_t as_rcvlocalsha; /* received from local hw address */
|
||||
u_quad_t as_rcvbcastsha; /* received w/ broadcast src */
|
||||
u_quad_t as_rcvlocalspa; /* received for a local ip [dup!] */
|
||||
u_quad_t as_rcvoverperm; /* attempts to overwrite static info */
|
||||
u_quad_t as_rcvoverint; /* attempts to overwrite wrong if */
|
||||
u_quad_t as_rcvover; /* entries overwritten! */
|
||||
u_quad_t as_rcvlenchg; /* changes in hw add len */
|
||||
|
||||
u_quad_t as_dfrtotal; /* deferred pending ARP resolution. */
|
||||
u_quad_t as_dfrsent; /* deferred, then sent */
|
||||
u_quad_t as_dfrdropped; /* deferred, then dropped */
|
||||
|
||||
u_quad_t as_allocfail; /* Failures to allocate llinfo */
|
||||
};
|
||||
#define ARP_NSTATS 23
|
||||
|
||||
#endif /* !_NET_IF_ARP_H_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_arp.c,v 1.131 2008/01/20 18:09:12 joerg Exp $ */
|
||||
/* $NetBSD: if_arp.c,v 1.132 2008/04/15 15:17:54 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
|
||||
|
@ -75,7 +75,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.131 2008/01/20 18:09:12 joerg Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.132 2008/04/15 15:17:54 thorpej Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_inet.h"
|
||||
|
@ -100,6 +100,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.131 2008/01/20 18:09:12 joerg Exp $");
|
|||
#include <sys/protosw.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/percpu.h>
|
||||
|
||||
#include <net/ethertypes.h>
|
||||
#include <net/if.h>
|
||||
|
@ -169,7 +170,25 @@ int arp_maxtries = 5;
|
|||
int useloopback = 1; /* use loopback interface for local traffic */
|
||||
int arpinit_done = 0;
|
||||
|
||||
struct arpstat arpstat;
|
||||
static percpu_t *arpstat_percpu;
|
||||
|
||||
#define ARP_STAT_GETREF() percpu_getref(arpstat_percpu)
|
||||
#define ARP_STAT_PUTREF() percpu_putref(arpstat_percpu)
|
||||
|
||||
#define ARP_STATINC(x) \
|
||||
do { \
|
||||
uint64_t *_arps_ = ARP_STAT_GETREF(); \
|
||||
_arps_[x]++; \
|
||||
ARP_STAT_PUTREF(); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define ARP_STATADD(x, v) \
|
||||
do { \
|
||||
uint64_t *_arps_ = ARP_STAT_GETREF(); \
|
||||
_arps_[x] += (v); \
|
||||
ARP_STAT_PUTREF(); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
struct callout arptimer_ch;
|
||||
|
||||
/* revarp state */
|
||||
|
@ -231,7 +250,7 @@ const struct protosw arpsw[] = {
|
|||
.pr_ctlinput = 0,
|
||||
.pr_ctloutput = 0,
|
||||
.pr_usrreq = 0,
|
||||
.pr_init = 0,
|
||||
.pr_init = arp_init,
|
||||
.pr_fasttimo = 0,
|
||||
.pr_slowtimo = 0,
|
||||
.pr_drain = arp_drain,
|
||||
|
@ -315,11 +334,17 @@ do { \
|
|||
|
||||
#define ARP_UNLOCK() arp_unlock()
|
||||
|
||||
void
|
||||
arp_init(void)
|
||||
{
|
||||
|
||||
arpstat_percpu = percpu_alloc(sizeof(uint64_t) * ARP_NSTATS);
|
||||
}
|
||||
|
||||
/*
|
||||
* ARP protocol drain routine. Called when memory is in short supply.
|
||||
* Called at splvm();
|
||||
*/
|
||||
|
||||
void
|
||||
arp_drain(void)
|
||||
{
|
||||
|
@ -344,7 +369,7 @@ arp_drain(void)
|
|||
}
|
||||
}
|
||||
ARP_UNLOCK();
|
||||
arpstat.as_dfrdropped += count;
|
||||
ARP_STATADD(ARP_STAT_DFRDROPPED, count);
|
||||
}
|
||||
|
||||
|
||||
|
@ -658,6 +683,7 @@ arprequest(struct ifnet *ifp,
|
|||
struct mbuf *m;
|
||||
struct arphdr *ah;
|
||||
struct sockaddr sa;
|
||||
uint64_t *arps;
|
||||
|
||||
if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
|
||||
return;
|
||||
|
@ -695,8 +721,10 @@ arprequest(struct ifnet *ifp,
|
|||
sa.sa_family = AF_ARP;
|
||||
sa.sa_len = 2;
|
||||
m->m_flags |= M_BCAST;
|
||||
arpstat.as_sndtotal++;
|
||||
arpstat.as_sndrequest++;
|
||||
arps = ARP_STAT_GETREF();
|
||||
arps[ARP_STAT_SNDTOTAL]++;
|
||||
arps[ARP_STAT_SENDREQUEST]++;
|
||||
ARP_STAT_PUTREF();
|
||||
(*ifp->if_output)(ifp, m, &sa, NULL);
|
||||
}
|
||||
|
||||
|
@ -723,7 +751,7 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt, struct mbuf *m,
|
|||
rt = la->la_rt;
|
||||
|
||||
if (la == 0 || rt == 0) {
|
||||
arpstat.as_allocfail++;
|
||||
ARP_STATINC(ARP_STAT_ALLOCFAIL);
|
||||
log(LOG_DEBUG,
|
||||
"arpresolve: can't allocate llinfo on %s for %s\n",
|
||||
ifp->if_xname, in_fmtaddr(satocsin(dst)->sin_addr));
|
||||
|
@ -748,14 +776,14 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt, struct mbuf *m,
|
|||
* latest one.
|
||||
*/
|
||||
|
||||
arpstat.as_dfrtotal++;
|
||||
ARP_STATINC(ARP_STAT_DFRTOTAL);
|
||||
s = splnet();
|
||||
mold = la->la_hold;
|
||||
la->la_hold = m;
|
||||
splx(s);
|
||||
|
||||
if (mold) {
|
||||
arpstat.as_dfrdropped++;
|
||||
ARP_STATINC(ARP_STAT_DFRDROPPED);
|
||||
m_freem(mold);
|
||||
}
|
||||
|
||||
|
@ -813,7 +841,7 @@ arpintr(void)
|
|||
panic("arpintr");
|
||||
|
||||
MCLAIM(m, &arpdomain.dom_mowner);
|
||||
arpstat.as_rcvtotal++;
|
||||
ARP_STATINC(ARP_STAT_RCVTOTAL);
|
||||
|
||||
/*
|
||||
* First, make sure we have at least struct arphdr.
|
||||
|
@ -841,11 +869,11 @@ arpintr(void)
|
|||
in_arpinput(m);
|
||||
continue;
|
||||
default:
|
||||
arpstat.as_rcvbadproto++;
|
||||
ARP_STATINC(ARP_STAT_RCVBADPROTO);
|
||||
}
|
||||
else {
|
||||
badlen:
|
||||
arpstat.as_rcvbadlen++;
|
||||
ARP_STATINC(ARP_STAT_RCVBADLEN);
|
||||
}
|
||||
m_freem(m);
|
||||
}
|
||||
|
@ -886,6 +914,7 @@ in_arpinput(struct mbuf *m)
|
|||
struct mbuf *mold;
|
||||
void *tha;
|
||||
int s;
|
||||
uint64_t *arps;
|
||||
|
||||
if (__predict_false(m_makewritable(&m, 0, m->m_pkthdr.len, M_DONTWAIT)))
|
||||
goto out;
|
||||
|
@ -915,7 +944,7 @@ in_arpinput(struct mbuf *m)
|
|||
memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr));
|
||||
|
||||
if (m->m_flags & (M_BCAST|M_MCAST))
|
||||
arpstat.as_rcvmcast++;
|
||||
ARP_STATINC(ARP_STAT_RCVMCAST);
|
||||
|
||||
/*
|
||||
* If the target IP address is zero, ignore the packet.
|
||||
|
@ -923,7 +952,7 @@ in_arpinput(struct mbuf *m)
|
|||
* when we are using IP address zero (booting).
|
||||
*/
|
||||
if (in_nullhost(itaddr)) {
|
||||
arpstat.as_rcvzerotpa++;
|
||||
ARP_STATINC(ARP_STAT_RCVZEROTPA);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -933,7 +962,7 @@ in_arpinput(struct mbuf *m)
|
|||
* XXX: Should we bother trying to reply to these?
|
||||
*/
|
||||
if (in_nullhost(isaddr)) {
|
||||
arpstat.as_rcvzerospa++;
|
||||
ARP_STATINC(ARP_STAT_RCVZEROSPA);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -990,7 +1019,7 @@ in_arpinput(struct mbuf *m)
|
|||
if (ia == NULL) {
|
||||
IFP_TO_IA(ifp, ia);
|
||||
if (ia == NULL) {
|
||||
arpstat.as_rcvnoint++;
|
||||
ARP_STATINC(ARP_STAT_RCVNOINT);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
@ -1000,13 +1029,13 @@ in_arpinput(struct mbuf *m)
|
|||
|
||||
/* XXX checks for bridge case? */
|
||||
if (!memcmp(ar_sha(ah), CLLADDR(ifp->if_sadl), ifp->if_addrlen)) {
|
||||
arpstat.as_rcvlocalsha++;
|
||||
ARP_STATINC(ARP_STAT_RCVLOCALSHA);
|
||||
goto out; /* it's from me, ignore it. */
|
||||
}
|
||||
|
||||
/* XXX checks for bridge case? */
|
||||
if (!memcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen)) {
|
||||
arpstat.as_rcvbcastsha++;
|
||||
ARP_STATINC(ARP_STAT_RCVBCASTSHA);
|
||||
log(LOG_ERR,
|
||||
"%s: arp: link address is broadcast for IP address %s!\n",
|
||||
ifp->if_xname, in_fmtaddr(isaddr));
|
||||
|
@ -1014,7 +1043,7 @@ in_arpinput(struct mbuf *m)
|
|||
}
|
||||
|
||||
if (in_hosteq(isaddr, myaddr)) {
|
||||
arpstat.as_rcvlocalspa++;
|
||||
ARP_STATINC(ARP_STAT_RCVLOCALSPA);
|
||||
log(LOG_ERR,
|
||||
"duplicate IP address %s sent from link address %s\n",
|
||||
in_fmtaddr(isaddr), lla_snprintf(ar_sha(ah), ah->ar_hln));
|
||||
|
@ -1026,7 +1055,7 @@ in_arpinput(struct mbuf *m)
|
|||
if (sdl->sdl_alen &&
|
||||
memcmp(ar_sha(ah), CLLADDR(sdl), sdl->sdl_alen)) {
|
||||
if (rt->rt_flags & RTF_STATIC) {
|
||||
arpstat.as_rcvoverperm++;
|
||||
ARP_STATINC(ARP_STAT_RCVOVERPERM);
|
||||
log(LOG_INFO,
|
||||
"%s tried to overwrite permanent arp info"
|
||||
" for %s\n",
|
||||
|
@ -1034,7 +1063,7 @@ in_arpinput(struct mbuf *m)
|
|||
in_fmtaddr(isaddr));
|
||||
goto out;
|
||||
} else if (rt->rt_ifp != ifp) {
|
||||
arpstat.as_rcvoverint++;
|
||||
ARP_STATINC(ARP_STAT_RCVOVERINT);
|
||||
log(LOG_INFO,
|
||||
"%s on %s tried to overwrite "
|
||||
"arp info for %s on %s\n",
|
||||
|
@ -1043,7 +1072,7 @@ in_arpinput(struct mbuf *m)
|
|||
rt->rt_ifp->if_xname);
|
||||
goto out;
|
||||
} else {
|
||||
arpstat.as_rcvover++;
|
||||
ARP_STATINC(ARP_STAT_RCVOVER);
|
||||
log(LOG_INFO,
|
||||
"arp info overwritten for %s by %s\n",
|
||||
in_fmtaddr(isaddr),
|
||||
|
@ -1057,13 +1086,13 @@ in_arpinput(struct mbuf *m)
|
|||
*/
|
||||
if (sdl->sdl_alen &&
|
||||
sdl->sdl_alen != ah->ar_hln) {
|
||||
arpstat.as_rcvlenchg++;
|
||||
ARP_STATINC(ARP_STAT_RCVLENCHG);
|
||||
log(LOG_WARNING,
|
||||
"arp from %s: new addr len %d, was %d",
|
||||
in_fmtaddr(isaddr), ah->ar_hln, sdl->sdl_alen);
|
||||
}
|
||||
if (ifp->if_addrlen != ah->ar_hln) {
|
||||
arpstat.as_rcvbadlen++;
|
||||
ARP_STATINC(ARP_STAT_RCVBADLEN);
|
||||
log(LOG_WARNING,
|
||||
"arp from %s: addr len: new %d, i/f %d (ignored)",
|
||||
in_fmtaddr(isaddr), ah->ar_hln,
|
||||
|
@ -1110,19 +1139,19 @@ in_arpinput(struct mbuf *m)
|
|||
splx(s);
|
||||
|
||||
if (mold) {
|
||||
arpstat.as_dfrsent++;
|
||||
ARP_STATINC(ARP_STAT_DFRSENT);
|
||||
(*ifp->if_output)(ifp, mold, rt_getkey(rt), rt);
|
||||
}
|
||||
}
|
||||
reply:
|
||||
if (op != ARPOP_REQUEST) {
|
||||
if (op == ARPOP_REPLY)
|
||||
arpstat.as_rcvreply++;
|
||||
ARP_STATINC(ARP_STAT_RCVREPLY);
|
||||
out:
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
arpstat.as_rcvrequest++;
|
||||
ARP_STATINC(ARP_STAT_RCVREQUEST);
|
||||
if (in_hosteq(itaddr, myaddr)) {
|
||||
/* I am the target */
|
||||
tha = ar_tha(ah);
|
||||
|
@ -1166,8 +1195,10 @@ reply:
|
|||
m->m_pkthdr.len = m->m_len;
|
||||
sa.sa_family = AF_ARP;
|
||||
sa.sa_len = 2;
|
||||
arpstat.as_sndtotal++;
|
||||
arpstat.as_sndreply++;
|
||||
arps = ARP_STAT_GETREF();
|
||||
arps[ARP_STAT_SNDTOTAL]++;
|
||||
arps[ARP_STAT_SNDREPLY]++;
|
||||
ARP_STAT_PUTREF();
|
||||
(*ifp->if_output)(ifp, m, &sa, (struct rtentry *)0);
|
||||
return;
|
||||
}
|
||||
|
@ -1238,7 +1269,7 @@ arplookup1(struct mbuf *m, const struct in_addr *addr, int create, int proxy,
|
|||
if (rt->rt_flags & RTF_GATEWAY)
|
||||
why = "host is not on local network";
|
||||
else if ((rt->rt_flags & RTF_LLINFO) == 0) {
|
||||
arpstat.as_allocfail++;
|
||||
ARP_STATINC(ARP_STAT_ALLOCFAIL);
|
||||
why = "could not allocate llinfo";
|
||||
} else
|
||||
why = "gateway route is not ours";
|
||||
|
@ -1546,6 +1577,38 @@ db_show_arptab(db_expr_t addr, bool have_addr,
|
|||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
arpstat_convert_to_user_cb(void *v1, void *v2, struct cpu_info *ci)
|
||||
{
|
||||
uint64_t *arpsc = v1;
|
||||
uint64_t *arps = v2;
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < ARP_NSTATS; i++)
|
||||
arps[i] += arpsc[i];
|
||||
}
|
||||
|
||||
static void
|
||||
arpstat_convert_to_user(uint64_t *arps)
|
||||
{
|
||||
|
||||
memset(arps, 0, sizeof(uint64_t) * ARP_NSTATS);
|
||||
percpu_foreach(arpstat_percpu, arpstat_convert_to_user_cb, arps);
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_net_inet_arp_stats(SYSCTLFN_ARGS)
|
||||
{
|
||||
struct sysctlnode node;
|
||||
uint64_t arps[ARP_NSTATS];
|
||||
|
||||
arpstat_convert_to_user(arps);
|
||||
node = *rnode;
|
||||
node.sysctl_data = arps;
|
||||
node.sysctl_size = sizeof(arps);
|
||||
return (sysctl_lookup(SYSCTLFN_CALL(&node)));
|
||||
}
|
||||
|
||||
SYSCTL_SETUP(sysctl_net_inet_arp_setup, "sysctl net.inet.arp subtree setup")
|
||||
{
|
||||
const struct sysctlnode *node;
|
||||
|
@ -1594,6 +1657,13 @@ SYSCTL_SETUP(sysctl_net_inet_arp_setup, "sysctl net.inet.arp subtree setup")
|
|||
SYSCTL_DESCR("ARP entry refresh interval"),
|
||||
NULL, 0, &arpt_refresh, 0,
|
||||
CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL);
|
||||
|
||||
sysctl_createv(clog, 0, NULL, NULL,
|
||||
CTLFLAG_PERMANENT,
|
||||
CTLTYPE_STRUCT, "stats",
|
||||
SYSCTL_DESCR("ARP statistics"),
|
||||
sysctl_net_inet_arp_stats, 0, NULL, 0,
|
||||
CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL);
|
||||
}
|
||||
|
||||
#endif /* INET */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_inarp.h,v 1.39 2007/03/04 06:03:20 christos Exp $ */
|
||||
/* $NetBSD: if_inarp.h,v 1.40 2008/04/15 15:17:54 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
|
@ -68,6 +68,7 @@ int arpresolve(struct ifnet *, struct rtentry *, struct mbuf *,
|
|||
void arpintr(void);
|
||||
void arprequest(struct ifnet *, const struct in_addr *, const struct in_addr *,
|
||||
const u_int8_t *);
|
||||
void arp_init(void);
|
||||
void arp_drain(void);
|
||||
int arpioctl(u_long, void *);
|
||||
void arpwhohas(struct ifnet *, struct in_addr *);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: inet.c,v 1.85 2008/04/15 06:03:28 thorpej Exp $ */
|
||||
/* $NetBSD: inet.c,v 1.86 2008/04/15 15:17:54 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1988, 1993
|
||||
|
@ -34,7 +34,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "from: @(#)inet.c 8.4 (Berkeley) 4/20/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: inet.c,v 1.85 2008/04/15 06:03:28 thorpej Exp $");
|
||||
__RCSID("$NetBSD: inet.c,v 1.86 2008/04/15 15:17:54 thorpej Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -720,46 +720,56 @@ pim_stats(u_long off, char *name)
|
|||
void
|
||||
arp_stats(u_long off, char *name)
|
||||
{
|
||||
struct arpstat arpstat;
|
||||
uint64_t arpstat[ARP_NSTATS];
|
||||
|
||||
if (use_sysctl) {
|
||||
size_t size = sizeof(arpstat);
|
||||
|
||||
if (sysctlbyname("net.inet.arp.stats", arpstat, &size,
|
||||
NULL, 0) == -1) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (off == 0)
|
||||
return;
|
||||
kread(off, (char *)arpstat, sizeof(arpstat));
|
||||
}
|
||||
|
||||
if (off == 0)
|
||||
return;
|
||||
kread(off, (char *)&arpstat, sizeof (arpstat));
|
||||
printf("%s:\n", name);
|
||||
|
||||
#define ps(f, m) if (arpstat.f || sflag <= 1) \
|
||||
printf(m, (unsigned long long)arpstat.f)
|
||||
#define p(f, m) if (arpstat.f || sflag <= 1) \
|
||||
printf(m, (unsigned long long)arpstat.f, plural(arpstat.f))
|
||||
#define ps(f, m) if (arpstat[f] || sflag <= 1) \
|
||||
printf(m, (unsigned long long)arpstat[f])
|
||||
#define p(f, m) if (arpstat[f] || sflag <= 1) \
|
||||
printf(m, (unsigned long long)arpstat[f], plural(arpstat[f]))
|
||||
|
||||
p(as_sndtotal, "\t%llu packet%s sent\n");
|
||||
p(as_sndreply, "\t\t%llu reply packet%s\n");
|
||||
p(as_sndrequest, "\t\t%llu request packet%s\n");
|
||||
p(ARP_STAT_SNDTOTAL, "\t%llu packet%s sent\n");
|
||||
p(ARP_STAT_SNDREPLY, "\t\t%llu reply packet%s\n");
|
||||
p(ARP_STAT_SENDREQUEST, "\t\t%llu request packet%s\n");
|
||||
|
||||
p(as_rcvtotal, "\t%llu packet%s received\n");
|
||||
p(as_rcvreply, "\t\t%llu reply packet%s\n");
|
||||
p(as_rcvrequest, "\t\t%llu valid request packet%s\n");
|
||||
p(as_rcvmcast, "\t\t%llu broadcast/multicast packet%s\n");
|
||||
p(as_rcvbadproto, "\t\t%llu packet%s with unknown protocol type\n");
|
||||
p(as_rcvbadlen, "\t\t%llu packet%s with bad (short) length\n");
|
||||
p(as_rcvzerotpa, "\t\t%llu packet%s with null target IP address\n");
|
||||
p(as_rcvzerospa, "\t\t%llu packet%s with null source IP address\n");
|
||||
ps(as_rcvnoint, "\t\t%llu could not be mapped to an interface\n");
|
||||
p(as_rcvlocalsha, "\t\t%llu packet%s sourced from a local hardware "
|
||||
p(ARP_STAT_RCVTOTAL, "\t%llu packet%s received\n");
|
||||
p(ARP_STAT_RCVREPLY, "\t\t%llu reply packet%s\n");
|
||||
p(ARP_STAT_RCVREQUEST, "\t\t%llu valid request packet%s\n");
|
||||
p(ARP_STAT_RCVMCAST, "\t\t%llu broadcast/multicast packet%s\n");
|
||||
p(ARP_STAT_RCVBADPROTO, "\t\t%llu packet%s with unknown protocol type\n");
|
||||
p(ARP_STAT_RCVBADLEN, "\t\t%llu packet%s with bad (short) length\n");
|
||||
p(ARP_STAT_RCVZEROTPA, "\t\t%llu packet%s with null target IP address\n");
|
||||
p(ARP_STAT_RCVZEROSPA, "\t\t%llu packet%s with null source IP address\n");
|
||||
ps(ARP_STAT_RCVNOINT, "\t\t%llu could not be mapped to an interface\n");
|
||||
p(ARP_STAT_RCVLOCALSHA, "\t\t%llu packet%s sourced from a local hardware "
|
||||
"address\n");
|
||||
p(as_rcvbcastsha, "\t\t%llu packet%s with a broadcast "
|
||||
p(ARP_STAT_RCVBCASTSHA, "\t\t%llu packet%s with a broadcast "
|
||||
"source hardware address\n");
|
||||
p(as_rcvlocalspa, "\t\t%llu duplicate%s for a local IP address\n");
|
||||
p(as_rcvoverperm, "\t\t%llu attempt%s to overwrite a static entry\n");
|
||||
p(as_rcvoverint, "\t\t%llu packet%s received on wrong interface\n");
|
||||
p(as_rcvover, "\t\t%llu entry%s overwritten\n");
|
||||
p(as_rcvlenchg, "\t\t%llu change%s in hardware address length\n");
|
||||
p(ARP_STAT_RCVLOCALSPA, "\t\t%llu duplicate%s for a local IP address\n");
|
||||
p(ARP_STAT_RCVOVERPERM, "\t\t%llu attempt%s to overwrite a static entry\n");
|
||||
p(ARP_STAT_RCVOVERINT, "\t\t%llu packet%s received on wrong interface\n");
|
||||
p(ARP_STAT_RCVOVER, "\t\t%llu entry%s overwritten\n");
|
||||
p(ARP_STAT_RCVLENCHG, "\t\t%llu change%s in hardware address length\n");
|
||||
|
||||
p(as_dfrtotal, "\t%llu packet%s deferred pending ARP resolution\n");
|
||||
ps(as_dfrsent, "\t\t%llu sent\n");
|
||||
ps(as_dfrdropped, "\t\t%llu dropped\n");
|
||||
p(ARP_STAT_DFRTOTAL, "\t%llu packet%s deferred pending ARP resolution\n");
|
||||
ps(ARP_STAT_DFRSENT, "\t\t%llu sent\n");
|
||||
ps(ARP_STAT_DFRDROPPED, "\t\t%llu dropped\n");
|
||||
|
||||
p(as_allocfail, "\t%llu failure%s to allocate llinfo\n");
|
||||
p(ARP_STAT_ALLOCFAIL, "\t%llu failure%s to allocate llinfo\n");
|
||||
|
||||
#undef ps
|
||||
#undef p
|
||||
|
|
Loading…
Reference in New Issue