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:
parent
7ae6b1ebd2
commit
5da9f8fa97
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=67334
@ -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 */
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user