Augment the 'ifaddr' structure with a 'struct if_data' to keep

statistics on a per network address basis.

Teach the IPv4 and IPv6 input/output routines to log packets/bytes
against the network address connected to the flow.

Teach netstat to display the per-address stats for IP protocols
when 'netstat -i' is evoked, instead of displaying the per-interface
stats.
This commit is contained in:
Josef Karthauser 2000-10-19 23:15:54 +00:00
parent 7ae6b1ebd2
commit 5da9f8fa97
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=67334
6 changed files with 73 additions and 11 deletions

View File

@ -259,6 +259,7 @@ struct ifaddr {
struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */
#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
struct sockaddr *ifa_netmask; /* used to determine subnet */
struct if_data if_data; /* not all members are meaningful */
struct ifnet *ifa_ifp; /* back-pointer to interface */
TAILQ_ENTRY(ifaddr) ifa_link; /* queue macro glue */
void (*ifa_rtrequest) /* check or clean routes (+ or -)'d */

View File

@ -253,7 +253,7 @@ ip_input(struct mbuf *m)
{
struct ip *ip;
struct ipq *fp;
struct in_ifaddr *ia;
struct in_ifaddr *ia = NULL;
int i, hlen, mff;
u_short sum;
u_int16_t divert_cookie; /* firewall cookie */
@ -585,6 +585,11 @@ ip_input(struct mbuf *m)
return;
ours:
/* Count the packet in the ip address stats */
if (ia != NULL) {
ia->ia_ifa.if_ipackets++;
ia->ia_ifa.if_ibytes += m->m_pkthdr.len;
}
/*
* If offset or IP_MF are set, must reassemble.

View File

@ -801,6 +801,13 @@ ip_output(m0, opt, ro, flags, imo)
ip->ip_sum = in_cksum(m, hlen);
}
}
/* Record statistics for this interface address. */
if (!(flags & IP_FORWARDING)) {
ia->ia_ifa.if_opackets++;
ia->ia_ifa.if_obytes += m->m_pkthdr.len;
}
error = (*ifp->if_output)(ifp, m,
(struct sockaddr *)dst, ro->ro_rt);
goto done;

View File

@ -493,6 +493,11 @@ ip6_input(m)
/* this address is ready */
ours = 1;
deliverifp = ia6->ia_ifp; /* correct? */
/* Count the packet in the ip address stats */
ia6->ia_ifa.if_ipackets++;
ia6->ia_ifa.if_ibytes += m->m_pkthdr.len;
goto hbhcheck;
} else {
/* address is not ready, so discard the packet. */

View File

@ -156,7 +156,7 @@ ip6_output(m0, opt, ro, flags, im6o, ifpp)
struct route_in6 ip6route;
struct sockaddr_in6 *dst;
int error = 0;
struct in6_ifaddr *ia;
struct in6_ifaddr *ia = NULL;
u_long mtu;
u_int32_t optlen = 0, plen = 0, unfragpartlen = 0;
struct ip6_exthdrs exthdrs;
@ -890,6 +890,12 @@ skip_ipsec2:;
#endif
)
{
/* Record statistics for this interface address. */
if (ia && !(flags & IPV6_FORWARDING)) {
ia->ia_ifa.if_opackets++;
ia->ia_ifa.if_obytes += m->m_pkthdr.len;
}
error = nd6_output(ifp, origifp, m, dst, ro->ro_rt);
goto done;
} else if (mtu < IPV6_MMTU) {

View File

@ -152,6 +152,15 @@ intpr(interval, ifnetaddr, pfunc)
u_long ifaddraddr;
u_long ifaddrfound;
u_long ifnetfound;
u_long opackets;
u_long ipackets;
u_long obytes;
u_long ibytes;
u_long oerrors;
u_long ierrors;
u_long collisions;
short timer;
int drops;
struct sockaddr *sa = NULL;
char name[32], tname[16];
@ -217,6 +226,21 @@ intpr(interval, ifnetaddr, pfunc)
}
printf("%-5.5s %-5lu ", name, ifnet.if_mtu);
ifaddrfound = ifaddraddr;
/*
* Get the interface stats. These may get
* overriden below on a per-interface basis.
*/
opackets = ifnet.if_opackets;
ipackets = ifnet.if_ipackets;
obytes = ifnet.if_obytes;
ibytes = ifnet.if_ibytes;
oerrors = ifnet.if_oerrors;
ierrors = ifnet.if_ierrors;
collisions = ifnet.if_collisions;
timer = ifnet.if_timer;
drops = ifnet.if_snd.ifq_drops;
if (ifaddraddr == 0) {
printf("%-13.13s ", "none");
printf("%-15.15s ", "none");
@ -327,21 +351,35 @@ intpr(interval, ifnetaddr, pfunc)
putchar(' ');
break;
}
/*
* Fixup the statistics for interfaces that
* update stats for their network addresses
*/
if (sa->sa_family == AF_INET ||
sa->sa_family == AF_INET6) {
opackets = ifaddr.in.ia_ifa.if_opackets;
ipackets = ifaddr.in.ia_ifa.if_ipackets;
obytes = ifaddr.in.ia_ifa.if_obytes;
ibytes = ifaddr.in.ia_ifa.if_ibytes;
oerrors = ierrors = 0;
collisions = timer = drops = 0;
}
ifaddraddr = (u_long)ifaddr.ifa.ifa_link.tqe_next;
}
printf("%8lu %5lu ",
ifnet.if_ipackets, ifnet.if_ierrors);
printf("%8lu %5lu ", ipackets, ierrors);
if (bflag)
printf("%10lu ", ifnet.if_ibytes);
printf("%8lu %5lu ",
ifnet.if_opackets, ifnet.if_oerrors);
printf("%10lu ", ibytes);
printf("%8lu %5lu ", opackets, oerrors);
if (bflag)
printf("%10lu ", ifnet.if_obytes);
printf("%5lu", ifnet.if_collisions);
printf("%10lu ", obytes);
printf("%5lu", collisions);
if (tflag)
printf(" %3d", ifnet.if_timer);
printf(" %3d", timer);
if (dflag)
printf(" %3d", ifnet.if_snd.ifq_drops);
printf(" %3d", drops);
putchar('\n');
if (aflag && ifaddrfound) {
/*