📄 nettest_stat.c
字号:
#ifndef lintstatic char sccsid[] = "@(#)nettest_stat.c 1.1 7/30/92 Copyright Sun Microsystems";#endif/* * Copyright (c) 1987 by Sun Microsystems, Inc. *//****************************************************************************** nettest_stat.c Revison : Anantha N. Srirama anantha@ravi Total rewrite, I ripped the guts out of this program. The present version bears very little resemblence to the previous version, tons of useless stuff has been thrown away with vengence.******************************************************************************/#include <sys/param.h>#include <sys/vmmac.h>#include <sys/socket.h>#include <sys/types.h>#include <net/if.h>#include <netinet/in.h>#include <net/route.h>#include <sys/mbuf.h>#include <fcntl.h>#include <machine/pte.h>#include <netinet/in_var.h>#include <netinet/if_ether.h>#include <kvm.h>#include <ctype.h>#include <errno.h>#include <nlist.h>#include <stdio.h>#include <netdb.h>#include <sunif/if_lereg.h>#include <sunif/if_levar.h>#include <sys/time.h>#include <sunif/if_ievar.h>#include "if_trvar.h"#ifdef FDDI /* defined in FDDI software was installed */#include <sunfw/fddi/fddi_types.h>#include <sunfw/fddi/commands.h>#else#include "fddi_types.h"#include "commands.h"#endif FDDI#include <sys/ioctl.h>#include <sdrtns.h>#include "nettest.h"extern char *routename (), *inet_ntoa ();extern char *netname ();char* index ();kvm_t *kd;struct nlist nl[] = { {""}, {""}};struct nlist nl_driver[] = { {""}, {""}};struct net_stat start_net_stat;#define FMT1 "\n%-5.5s %-12.12s %-12.12s %-7.7s %-5.5s %-7.7s %-5.5s %-13.13s\n%-5.5s %-12.12s %-12.12s %-7d %-5d %-7d %-5d %-6d \n\n"/****************************************************************************** stat_start_up******************************************************************************/void stat_start_up (){ char *vmunix, *getenv(); func_name = "stat_start_up"; TRACE_IN#ifdef sun386 nl[0].n_name = "ifnet";#else nl[0].n_name = "_ifnet";#endif sun386 vmunix = getenv("KERNELNAME"); if ((kd = kvm_open (vmunix, NULL, NULL, O_RDONLY, "nettest_stat"))==NULL) { send_message (-NAMELIST_ERROR, ERROR, "Unable to read kernel VM %s", errmsg (errno)); } else { if (kvm_nlist (kd, nl) < 0) { send_message (-NAMELIST_ERROR, ERROR, "Bad namelist"); } else { /* * Keep file descriptors open to avoid overhead of open/close on * each call to get routines. */ sethostent (1); setnetent (1); } } TRACE_OUT}/****************************************************************************** init_net_stat First time call to initialize the network statistics structure. The status printing routines in this file utilize this structure, therefore, this must be the first call in every program for any network interface device.******************************************************************************/void init_net_stat (devicenm)char* devicenm;{ int stat; func_name = "init_net_stat"; TRACE_IN bzero ((char *) &start_net_stat, sizeof (struct net_stat)); get_dev_netstat (devicenm, &start_net_stat); TRACE_OUT}/****************************************************************************** kread******************************************************************************/int kread (addr, buf, nbytes)u_long addr;char* buf;u_int nbytes;{ int status; char* f_name = "kread"; if ((status = kvm_read (kd, addr, buf, nbytes)) < 0) { send_message (-NAMELIST_ERROR, ERROR, "%s: %s", f_name, errmsg (errno)); } return (status);}/****************************************************************************** netname Return the name of the network whose address is given. The address is assumed to be that of a net or subnet, not a host.******************************************************************************/char* netname (iaddr, mask)u_long iaddr;u_long mask;{ static char line[50]; struct in_addr in; char* cp = 0; func_name = "netname"; TRACE_IN in.s_addr = ntohl (iaddr); if (in.s_addr) { struct netent *np = 0; struct hostent *hp; u_long net; if (mask == 0) { register u_long i = in.s_addr; int subnetshift; if (IN_CLASSA (i)) { mask = IN_CLASSA_NET; subnetshift = 8; } else if (IN_CLASSB(i)) { mask = IN_CLASSB_NET; subnetshift = 8; } else { mask = IN_CLASSC_NET; subnetshift = 4; } /* * If there are more bits than the standard mask would suggest, * subnets must be in use. Guess at the subnet mask, assuming * reasonable width subnet fields. */ while (in.s_addr &~ mask) { mask = (long)mask >> subnetshift; } } net = in.s_addr & mask; /* * Right-justify the network number. * * This is a throw-back to the old conventions used in the kernel. We * now store it left-justified in the kernel, but still right-justified * in the YP maps for backward compatibility. */ while ((mask & 1) == 0) { mask >>= 1, net >>= 1; } np = getnetbyaddr (net, AF_INET); if (np) { cp = np->n_name; } else { /* * gethostbyaddr takes network order; above wanted host order. */ in.s_addr = iaddr; hp = gethostbyaddr (&in,sizeof (struct in_addr),AF_INET); if (hp) cp = hp->h_name; } } if (cp) { strcpy (line, cp); } else { in.s_addr = iaddr; strcpy (line, inet_ntoa (in)); } TRACE_OUT return (line);}/****************************************************************************** routename Returns a pointer to the specified IF routename.******************************************************************************/char* routename (in)struct in_addr in; /* in network order */{ char* cp; static char line[50]; struct hostent* hp; static char domain[MAXHOSTNAMELEN + 1]; static int first = 1; func_name = "routename"; TRACE_IN bzero (line, 50); if (first) { /* * Record domain name for future reference. Check first for the 4.3bsd * convention of keeping it as * part of the hostname. Failing that, * try extracting it using the domainname system call. */ first = 0; if ((gethostname (domain, MAXHOSTNAMELEN) == 0) && (cp = index (domain, '.'))) { (void) strcpy (domain, cp + 1); } else { if (getdomainname (domain, MAXHOSTNAMELEN) < 0) { domain[0] = 0; } } } cp = 0; hp = gethostbyaddr (&in, sizeof (struct in_addr), AF_INET); if (hp) { /* * If the hostname contains a domain part, and it's the same as the * local domain, elide it. */ if ((cp = index (hp->h_name, '.')) && (!strcmp (cp + 1, domain))) { *cp = 0; } cp = hp->h_name; } if (cp) { strcpy (line, cp); } else { strcpy (line, inet_ntoa (in)); } TRACE_OUT return (line);}/****************************************************************************** get_dev_netstat******************************************************************************/int get_dev_netstat (ifname, net_stat_ptr)char* ifname;struct net_stat *net_stat_ptr;{ struct ifnet ifnet; union { struct ifaddr ifa; struct in_ifaddr in; } ifaddr; off_t ifaddraddr; off_t ifnetaddr; /* value of this symbol (or sdb offset) */ char name[16]; func_name = "get_dev_netstat"; TRACE_IN if (kd > 0) { ifnetaddr = nl[0].n_value; kread (ifnetaddr, &ifnetaddr, sizeof ifnetaddr); ifaddraddr = 0; while (ifnetaddr || ifaddraddr) { struct sockaddr_in *sin; register char *cp; char *index (); int n; struct in_addr in, inet_makeaddr (); /* * No address list for the current interface: find the first * address. */ if (kread (ifnetaddr, &ifnet, sizeof ifnet) < 0) { break; } if (kread ((off_t)ifnet.if_name, name, 16) < 0) { break; } name[15] = '\0'; ifnetaddr = (off_t) ifnet.if_next; /* * Extend device name with unit number. */ cp = index (name, '\0'); *cp++ = ifnet.if_unit + '0'; *cp = '\0'; if (ifname) { /* * If a particular interface has been singled out, skip * over all others. */ if (strcmp (ifname, name) != 0) { continue; } } else { if ((ifnet.if_flags&IFF_UP) == 0) { /* * The interface is down: don't report on it unless it's * been singled out or we're reporting everything. */ *cp++ = '*'; *cp = '\0'; } else { if (ifaddr.ifa.ifa_addr.sa_family!= AF_INET) { continue; } } } ifaddraddr = (off_t)ifnet.if_addrlist; /* * save interface name */ strcpy (net_stat_ptr->name, name); kread (ifaddraddr, &ifaddr, sizeof ifaddr); ifaddraddr = (off_t)ifaddr.ifa.ifa_next; switch (ifaddr.ifa.ifa_addr.sa_family) { case AF_UNSPEC: strcpy (net_stat_ptr->dstroutename, "none"); strcpy (net_stat_ptr->src_netaddr, "none"); break; case AF_INET: if (ifnet.if_flags & IFF_POINTOPOINT) { sin = (struct sockaddr_in *) &ifaddr.in.ia_dstaddr; strcpy (net_stat_ptr->dstroutename, routename (sin->sin_addr)); } else { strcpy (net_stat_ptr->dstroutename, netname (htonl (ifaddr.in.ia_subnet), ifaddr.in.ia_subnetmask)); } sin = (struct sockaddr_in *)&ifaddr.in.ia_addr; strcpy (net_stat_ptr->src_netaddr, routename (sin->sin_addr)); break; default: cp = "????"; strcpy (net_stat_ptr->dstroutename, cp); strcpy (net_stat_ptr->src_netaddr, cp); break; } net_stat_ptr->if_ipackets = ifnet.if_ipackets; net_stat_ptr->if_ierrors = ifnet.if_ierrors; net_stat_ptr->if_opackets = ifnet.if_opackets; net_stat_ptr->if_oerrors = ifnet.if_oerrors; net_stat_ptr->if_collisions = ifnet.if_collisions; } } TRACE_OUT return ((int) kd);}/******************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -