From owner-freebsd-net@FreeBSD.ORG Thu Aug 13 16:35:09 2009 Return-Path: Delivered-To: net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6E3E81065676 for ; Thu, 13 Aug 2009 16:35:09 +0000 (UTC) (envelope-from ady@ady.ro) Received: from mail-ew0-f206.google.com (mail-ew0-f206.google.com [209.85.219.206]) by mx1.freebsd.org (Postfix) with ESMTP id 937608FC6C for ; Thu, 13 Aug 2009 16:35:08 +0000 (UTC) Received: by ewy2 with SMTP id 2so237322ewy.43 for ; Thu, 13 Aug 2009 09:35:07 -0700 (PDT) MIME-Version: 1.0 Sender: ady@ady.ro Received: by 10.210.12.13 with SMTP id 13mr4180002ebl.12.1250179413072; Thu, 13 Aug 2009 09:03:33 -0700 (PDT) In-Reply-To: <533A2900-CDAC-4BFB-952B-45FB18E19B7E@neville-neil.com> References: <533A2900-CDAC-4BFB-952B-45FB18E19B7E@neville-neil.com> Date: Thu, 13 Aug 2009 18:03:33 +0200 X-Google-Sender-Auth: c48f32e6af885789 Message-ID: <78cb3d3f0908130903v6b16d819qa27b9f5263676479@mail.gmail.com> From: Adrian Penisoara To: George Neville-Neil Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Cc: net@freebsd.org Subject: Re: RFC: ARP Statistics X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Aug 2009 16:35:09 -0000 Hi, Perhaps it would be useful to add a "ARP flip-flop events" field, counting the "arp: is on but got reply from on " events. PS: minor nit/correction: use "ARP cache entries timed out" instead of "ARP entrys timed out" Regards, Adrian Penisoara EnterpriseBSD On Wed, Aug 12, 2009 at 3:43 PM, George Neville-Neil wrote: > Howdy, > > Here is a small patch that updates the kernel and the netstat(1) program to > print out protocol > statistics for ARP. I'd be interested in any feedback people have on this. > > Sample output: > > netstat -s -p arp > arp: > 469 ARP requests sent > 2117 ARP replies received > 0 total packets dropped due to no ARP entry > 469 ARP entrys timed out > 0 Duplicate IPs seen > > > Best, > George > > > > Index: usr.bin/netstat/inet.c > =================================================================== > --- usr.bin/netstat/inet.c (revision 196095) > +++ usr.bin/netstat/inet.c (working copy) > @@ -49,6 +49,7 @@ > #include > > #include > +#include > #include > #include > #include > @@ -871,6 +872,44 @@ > #undef p1a > } > > +/* > + * Dump ARP statistics structure. > + */ > +void > +arp_stats(u_long off, const char *name, int af1 __unused, int proto > __unused) > +{ > + struct arpstat arpstat, zerostat; > + size_t len = sizeof(arpstat); > + > + if (live) { > + if (zflag) > + memset(&zerostat, 0, len); > + if (sysctlbyname("net.link.ether.arp.stats", &arpstat, > &len, > + zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { > + warn("sysctl: net.link.ether.arp.stats"); > + return; > + } > + } else > + kread(off, &arpstat, len); > + > + printf("%s:\n", name); > + > +#define p(f, m) if (arpstat.f || sflag <= 1) \ > + printf(m, arpstat.f, plural(arpstat.f)) > +#define p1a(f, m) if (arpstat.f || sflag <= 1) \ > + printf(m, arpstat.f) > + > + p(arp_requests, "\t%lu ARP request%s sent\n"); > + p(arp_replies, "\t%lu ARP replie%s received\n"); > + p(arp_dropped, "\t%lu total packet%s dropped due to no ARP > entry\n"); > + p(arp_timeout, "\t%lu ARP entry%s timed out\n"); > + p(arp_dupips, "\t%lu Duplicate IP%s seen\n"); > +#undef p > +#undef p1a > +} > + > + > + > static const char *icmpnames[ICMP_MAXTYPE + 1] = { > "echo reply", /* RFC 792 */ > "#1", > Index: usr.bin/netstat/main.c > =================================================================== > --- usr.bin/netstat/main.c (revision 196095) > +++ usr.bin/netstat/main.c (working copy) > @@ -184,6 +184,8 @@ > { .n_name = "_sctpstat" }, > #define N_MFCTABLESIZE 54 > { .n_name = "_mfctablesize" }, > +#define N_ARPSTAT 55 > + { .n_name = "_arpstat" }, > { .n_name = NULL }, > }; > > @@ -232,6 +234,8 @@ > carp_stats, NULL, "carp", 1, 0 }, > { -1, N_PFSYNCSTAT, 1, NULL, > pfsync_stats, NULL, "pfsync", 1, 0 }, > + { -1, N_ARPSTAT, 1, NULL, > + arp_stats, NULL, "arp", 1, 0 }, > { -1, -1, 0, NULL, > NULL, NULL, NULL, 0, 0 } > }; > Index: usr.bin/netstat/netstat.h > =================================================================== > --- usr.bin/netstat/netstat.h (revision 196095) > +++ usr.bin/netstat/netstat.h (working copy) > @@ -75,6 +75,7 @@ > void sctp_protopr(u_long, const char *, int, int); > void sctp_stats(u_long, const char *, int, int); > #endif > +void arp_stats(u_long, const char *, int, int); > void ip_stats(u_long, const char *, int, int); > void icmp_stats(u_long, const char *, int, int); > void igmp_stats(u_long, const char *, int, int); > Index: sys/netinet/if_ether.c > =================================================================== > --- sys/netinet/if_ether.c (revision 196095) > +++ sys/netinet/if_ether.c (working copy) > @@ -80,6 +80,7 @@ > > SYSCTL_DECL(_net_link_ether); > SYSCTL_NODE(_net_link_ether, PF_INET, inet, CTLFLAG_RW, 0, ""); > +SYSCTL_NODE(_net_link_ether, PF_ARP, arp, CTLFLAG_RW, 0, ""); > > VNET_DEFINE(int, useloopback) = 1; /* use loopback interface for > * local traffic */ > @@ -108,6 +109,11 @@ > &VNET_NAME(arp_proxyall), 0, > "Enable proxy ARP for all suitable requests"); > > +struct arpstat arpstat; /* ARP statistics, see if_arp.h */ > +SYSCTL_STRUCT(_net_link_ether_arp, OID_AUTO, stats, CTLFLAG_RW, > + &arpstat, arpstat, > + "ARP statistics (struct arpstat, net/if_arp.h)"); > + > static void arp_init(void); > void arprequest(struct ifnet *, > struct in_addr *, struct in_addr *, u_char *); > @@ -127,6 +133,7 @@ > #ifdef AF_INET > void arp_ifscrub(struct ifnet *ifp, uint32_t addr); > > + > /* > * called by in_ifscrub to remove entry from the table when > * the interface goes away > @@ -165,12 +172,13 @@ > ifp = lle->lle_tbl->llt_ifp; > IF_AFDATA_LOCK(ifp); > LLE_WLOCK(lle); > - if (((lle->la_flags & LLE_DELETED) > - || (time_second >= lle->la_expire)) > - && (!callout_pending(&lle->la_timer) && > - callout_active(&lle->la_timer))) > + if (((lle->la_flags & LLE_DELETED) || > + (time_second >= lle->la_expire)) && > + (!callout_pending(&lle->la_timer) && > + callout_active(&lle->la_timer))) { > (void) llentry_free(lle); > - else { > + arpstat.arp_timeout++; > + } else { > /* > * Still valid, just drop our reference > */ > @@ -238,6 +246,7 @@ > sa.sa_len = 2; > m->m_flags |= M_BCAST; > (*ifp->if_output)(ifp, m, &sa, NULL); > + arpstat.arp_requests++; > } > > /* > @@ -339,8 +348,10 @@ > * latest one. > */ > if (m != NULL) { > - if (la->la_hold != NULL) > + if (la->la_hold != NULL) { > m_freem(la->la_hold); > + arpstat.arp_dropped++; > + } > la->la_hold = m; > if (renew == 0 && (flags & LLE_EXCLUSIVE)) { > flags &= ~LLE_EXCLUSIVE; > @@ -413,6 +424,7 @@ > ar = mtod(m, struct arphdr *); > } > > + arpstat.arp_replies++; > switch (ntohs(ar->ar_pro)) { > #ifdef INET > case ETHERTYPE_IP: > @@ -603,6 +615,7 @@ > ifp->if_addrlen, (u_char *)ar_sha(ah), ":", > inet_ntoa(isaddr), ifp->if_xname); > itaddr = myaddr; > + arpstat.arp_dupips++; > goto reply; > } > if (ifp->if_flags & IFF_STATICARP) > @@ -821,7 +834,7 @@ > static void > arp_init(void) > { > - > + bzero(&arpstat, sizeof(arpstat)); > netisr_register(&arp_nh); > } > SYSINIT(arp, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, arp_init, 0); > Index: sys/net/if_arp.h > =================================================================== > --- sys/net/if_arp.h (revision 196095) > +++ sys/net/if_arp.h (working copy) > @@ -108,6 +108,16 @@ > #define IFP2AC(ifp) ((struct arpcom *)(ifp->if_l2com)) > #define AC2IFP(ac) ((ac)->ac_ifp) > > -#endif > +#endif /* _KERNEL */ > > +struct arpstat { > + /* Normal things that happen */ > + u_long arp_requests; /* # of ARP requests sent by this host */ > + u_long arp_replies; /* # of ARP replies received by this host */ > + /* Abnormal event and error counting */ > + u_long arp_dropped; /* # of packets dropped while waiting for a > reply */ > + u_long arp_timeout; /* # of times an entry is removed due to > timeout */ > + u_long arp_dupips; /* # of duplicate IPs detected. */ > +}; > + > #endif /* !_NET_IF_ARP_H_ */ > > _______________________________________________ > freebsd-net@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-net > To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org" >