|
|
|
/*
|
|
|
|
KSysGuard, the KDE System Guard
|
|
|
|
|
|
|
|
Copyright (c) 1999, 2000 Chris Schlaeger <cs@kde.org>
|
|
|
|
|
|
|
|
Solaris support by Torsten Kasch <tk@Genetik.Uni-Bielefeld.DE>
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of version 2 of the GNU General Public
|
|
|
|
License as published by the Free Software Foundation.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <stropts.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <net/if.h>
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#ifdef HAVE_KSTAT
|
|
|
|
#include <kstat.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "ksysguardd.h"
|
|
|
|
#include "Command.h"
|
|
|
|
#include "NetDev.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* available network interface statistics through kstat(3):
|
|
|
|
*
|
|
|
|
* kstat name value
|
|
|
|
* ----------------------------------------------------------------------
|
|
|
|
* for the loopback interface(s) we can get
|
|
|
|
* ipackets # packets received
|
|
|
|
* opackets # packets sent
|
|
|
|
* in addition to those, for "real" interfaces:
|
|
|
|
* oerrors # xmit errors
|
|
|
|
* ierrors # recv errors
|
|
|
|
* macxmt_errors # xmit errors reported by hardware?
|
|
|
|
* macrcv_errors # recv errors reported by hardware?
|
|
|
|
* opackets64 same as opackets (64bit)
|
|
|
|
* ipackets64 same as ipackets (64bit)
|
|
|
|
* obytes # bytes sent
|
|
|
|
* rbytes # bytes received
|
|
|
|
* obytes64 same as obytes (64bit)
|
|
|
|
* rbytes64 same as ibytes (64bit)
|
|
|
|
* collisions # collisions
|
|
|
|
* multixmt # multicasts sent?
|
|
|
|
* multircv # multicasts received?
|
|
|
|
* brdcstxmt # broadcasts transmitted
|
|
|
|
* brdcstrcv # broadcasts received
|
|
|
|
* unknowns
|
|
|
|
* blocked
|
|
|
|
* ex_collisions
|
|
|
|
* defer_xmts
|
|
|
|
* align_errors
|
|
|
|
* fcs_errors
|
|
|
|
* oflo # overflow errors
|
|
|
|
* uflo # underflow errors
|
|
|
|
* runt_errors
|
|
|
|
* missed
|
|
|
|
* tx_late_collisions
|
|
|
|
* carrier_errors
|
|
|
|
* noxmtbuf
|
|
|
|
* norcvbuf
|
|
|
|
* xmt_badinterp
|
|
|
|
* rcv_badinterp
|
|
|
|
* intr # interrupts?
|
|
|
|
* xmtretry # xmit retries?
|
|
|
|
* ifspeed interface speed: 10000000 for 10BaseT
|
|
|
|
* duplex "half" or "full"
|
|
|
|
* media e.g. "PHY/MII"
|
|
|
|
* promisc promiscuous mode (e.g. "off")
|
|
|
|
* first_collisions
|
|
|
|
* multi_collisions
|
|
|
|
* sqe_errors
|
|
|
|
* toolong_errors
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
char *Name;
|
|
|
|
short flags;
|
|
|
|
unsigned long ipackets;
|
|
|
|
unsigned long OLDipackets;
|
|
|
|
unsigned long opackets;
|
|
|
|
unsigned long OLDopackets;
|
|
|
|
unsigned long ierrors;
|
|
|
|
unsigned long OLDierrors;
|
|
|
|
unsigned long oerrors;
|
|
|
|
unsigned long OLDoerrors;
|
|
|
|
unsigned long collisions;
|
|
|
|
unsigned long OLDcollisions;
|
|
|
|
unsigned long multixmt;
|
|
|
|
unsigned long OLDmultixmt;
|
|
|
|
unsigned long multircv;
|
|
|
|
unsigned long OLDmultircv;
|
|
|
|
unsigned long brdcstxmt;
|
|
|
|
unsigned long OLDbrdcstxmt;
|
|
|
|
unsigned long brdcstrcv;
|
|
|
|
unsigned long OLDbrdcstrcv;
|
|
|
|
} NetDevInfo;
|
|
|
|
|
|
|
|
|
|
|
|
#define NBUFFERS 64
|
|
|
|
#define MAXNETDEVS 64
|
|
|
|
static NetDevInfo IfInfo[MAXNETDEVS];
|
|
|
|
|
|
|
|
static int NetDevCount;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* insertnetdev() -- insert device name & flags into our list
|
|
|
|
*/
|
|
|
|
int insertnetdev( const char *name, const short flags ) {
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* interface "aliases" don't seem to have
|
|
|
|
* separate kstat statistics, so we skip them
|
|
|
|
*/
|
|
|
|
if( strchr( name, (int) ':' ) != NULL )
|
|
|
|
return( 0 );
|
|
|
|
|
|
|
|
while( (i < NetDevCount) && (strcmp( IfInfo[i].Name, name ) != 0) ) {
|
|
|
|
if( strcmp( IfInfo[i].Name, name ) == 0 )
|
|
|
|
return( 0 );
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* init new slot
|
|
|
|
*/
|
|
|
|
IfInfo[i].Name = strdup( name );
|
|
|
|
IfInfo[i].flags = flags;
|
|
|
|
IfInfo[i].ipackets = 0L;
|
|
|
|
IfInfo[i].OLDipackets = 0L;
|
|
|
|
IfInfo[i].opackets = 0L;
|
|
|
|
IfInfo[i].OLDopackets = 0L;
|
|
|
|
IfInfo[i].ierrors = 0L;
|
|
|
|
IfInfo[i].OLDierrors = 0L;
|
|
|
|
IfInfo[i].oerrors = 0L;
|
|
|
|
IfInfo[i].OLDoerrors = 0L;
|
|
|
|
IfInfo[i].collisions = 0L;
|
|
|
|
IfInfo[i].OLDcollisions = 0L;
|
|
|
|
IfInfo[i].multixmt = 0L;
|
|
|
|
IfInfo[i].OLDmultixmt = 0L;
|
|
|
|
IfInfo[i].multircv = 0L;
|
|
|
|
IfInfo[i].OLDmultircv = 0L;
|
|
|
|
IfInfo[i].brdcstxmt = 0L;
|
|
|
|
IfInfo[i].OLDbrdcstxmt = 0L;
|
|
|
|
IfInfo[i].brdcstrcv = 0L;
|
|
|
|
IfInfo[i].OLDbrdcstrcv = 0L;
|
|
|
|
NetDevCount = ++i;
|
|
|
|
|
|
|
|
/* XXX: need sanity checks! */
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* getnetdevlist() -- get a list of all "up" interfaces
|
|
|
|
*/
|
|
|
|
int getnetdevlist( void ) {
|
|
|
|
|
|
|
|
int fd;
|
|
|
|
int buffsize;
|
|
|
|
int prevsize;
|
|
|
|
int prevCount;
|
|
|
|
struct ifconf ifc;
|
|
|
|
struct ifreq *ifr;
|
|
|
|
|
|
|
|
if( (fd = socket( PF_INET, SOCK_DGRAM, 0 )) < 0 ) {
|
|
|
|
return( -1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* get the interface list via iotl( SIOCGIFCONF )
|
|
|
|
* the following algorithm based on ideas from W.R. Stevens'
|
|
|
|
* "UNIX Network Programming", Vol. 1:
|
|
|
|
* Since the ioctl may return 0, indicating success, even if the
|
|
|
|
* ifreq buffer was too small, we have to make sure, it didn't
|
|
|
|
* get truncated by comparing our initial size guess with the
|
|
|
|
* actual returned size.
|
|
|
|
*/
|
|
|
|
prevsize = 0;
|
|
|
|
buffsize = NBUFFERS * sizeof( struct ifreq );
|
|
|
|
while( 1 ) {
|
|
|
|
if( (ifc.ifc_buf = malloc( buffsize )) == NULL )
|
|
|
|
return( -1 );
|
|
|
|
|
|
|
|
ifc.ifc_len = buffsize;
|
|
|
|
if( ioctl( fd, SIOCGIFCONF, &ifc ) < 0 ) {
|
|
|
|
if( errno != EINVAL || prevsize != 0 ) {
|
|
|
|
free( ifc.ifc_buf );
|
|
|
|
return( -1 );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if( ifc.ifc_len == prevsize )
|
|
|
|
/* success */
|
|
|
|
break;
|
|
|
|
prevsize = ifc.ifc_len;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* initial buffer guessed too small, allocate a bigger one
|
|
|
|
*/
|
|
|
|
free( ifc.ifc_buf );
|
|
|
|
buffsize = (NBUFFERS + 10) * sizeof( struct ifreq );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* get the names for all interfaces which are configured "up"
|
|
|
|
* we're not interested in the ifc data (address), so we reuse the
|
|
|
|
* same structure (with ifc.len set) for the next ioctl()
|
|
|
|
*/
|
|
|
|
prevCount = NetDevCount;
|
|
|
|
for( ifr = (struct ifreq *) ifc.ifc_buf;
|
|
|
|
ifr < (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
|
|
|
|
ifr++ ) {
|
|
|
|
if( ioctl( fd, SIOCGIFFLAGS, ifr ) < 0 ) {
|
|
|
|
free( ifc.ifc_buf );
|
|
|
|
return( -1 );
|
|
|
|
}
|
|
|
|
if( ifr->ifr_flags & IFF_UP )
|
|
|
|
insertnetdev( ifr->ifr_name, ifr->ifr_flags );
|
|
|
|
}
|
|
|
|
free( ifc.ifc_buf );
|
|
|
|
close( fd );
|
|
|
|
|
|
|
|
if( (prevCount > 0) && (prevCount != NetDevCount) ) {
|
|
|
|
print_error( "RECONFIGURE\n" );
|
|
|
|
prevCount = NetDevCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
return( NetDevCount );
|
|
|
|
}
|
|
|
|
|
|
|
|
void initNetDev( struct SensorModul* sm ) {
|
|
|
|
#ifdef HAVE_KSTAT
|
|
|
|
char mon[128];
|
|
|
|
int i;
|
|
|
|
|
|
|
|
getnetdevlist();
|
|
|
|
for( i = 0; i < NetDevCount; i++ ) {
|
|
|
|
sprintf( mon, "network/%s/ipackets", IfInfo[i].Name );
|
|
|
|
registerMonitor( mon, "integer",
|
|
|
|
printIPackets, printIPacketsInfo, sm );
|
|
|
|
sprintf( mon, "network/%s/opackets", IfInfo[i].Name );
|
|
|
|
registerMonitor( mon, "integer",
|
|
|
|
printOPackets, printOPacketsInfo, sm );
|
|
|
|
/*
|
|
|
|
* if this isn't a loopback interface,
|
|
|
|
* register additional monitors
|
|
|
|
*/
|
|
|
|
if( ! (IfInfo[i].flags & IFF_LOOPBACK) ) {
|
|
|
|
/*
|
|
|
|
* recv errors
|
|
|
|
*/
|
|
|
|
sprintf( mon, "network/%s/ierrors",
|
|
|
|
IfInfo[i].Name );
|
|
|
|
registerMonitor( mon, "integer",
|
|
|
|
printIErrors, printIErrorsInfo, sm );
|
|
|
|
/*
|
|
|
|
* xmit errors
|
|
|
|
*/
|
|
|
|
sprintf( mon, "network/%s/oerrors",
|
|
|
|
IfInfo[i].Name );
|
|
|
|
registerMonitor( mon, "integer",
|
|
|
|
printOErrors, printOErrorsInfo, sm );
|
|
|
|
/*
|
|
|
|
* collisions
|
|
|
|
*/
|
|
|
|
sprintf( mon, "network/%s/collisions",
|
|
|
|
IfInfo[i].Name );
|
|
|
|
registerMonitor( mon, "integer",
|
|
|
|
printCollisions, printCollisionsInfo, sm );
|
|
|
|
/*
|
|
|
|
* multicast xmits
|
|
|
|
*/
|
|
|
|
sprintf( mon, "network/%s/multixmt",
|
|
|
|
IfInfo[i].Name );
|
|
|
|
registerMonitor( mon, "integer",
|
|
|
|
printMultiXmits, printMultiXmitsInfo, sm );
|
|
|
|
/*
|
|
|
|
* multicast recvs
|
|
|
|
*/
|
|
|
|
sprintf( mon, "network/%s/multircv",
|
|
|
|
IfInfo[i].Name );
|
|
|
|
registerMonitor( mon, "integer",
|
|
|
|
printMultiRecvs, printMultiRecvsInfo, sm );
|
|
|
|
/*
|
|
|
|
* broadcast xmits
|
|
|
|
*/
|
|
|
|
sprintf( mon, "network/%s/brdcstxmt",
|
|
|
|
IfInfo[i].Name );
|
|
|
|
registerMonitor( mon, "integer",
|
|
|
|
printBcastXmits, printBcastXmitsInfo, sm );
|
|
|
|
/*
|
|
|
|
* broadcast recvs
|
|
|
|
*/
|
|
|
|
sprintf( mon, "network/%s/brdcstrcv",
|
|
|
|
IfInfo[i].Name );
|
|
|
|
registerMonitor( mon, "integer",
|
|
|
|
printBcastRecvs, printBcastRecvsInfo, sm );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void exitNetDev( void ) {
|
|
|
|
}
|
|
|
|
|
|
|
|
int updateNetDev( void ) {
|
|
|
|
|
|
|
|
#ifdef HAVE_KSTAT
|
|
|
|
kstat_ctl_t *kctl;
|
|
|
|
kstat_t *ksp;
|
|
|
|
kstat_named_t *kdata;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* get a kstat handle and update the user's kstat chain
|
|
|
|
*/
|
|
|
|
if( (kctl = kstat_open()) == NULL )
|
|
|
|
return( 0 );
|
|
|
|
while( kstat_chain_update( kctl ) != 0 )
|
|
|
|
;
|
|
|
|
|
|
|
|
for( i = 0; i < NetDevCount; i++ ) {
|
|
|
|
char *name;
|
|
|
|
char *ptr;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* chop off the trailing interface no
|
|
|
|
*/
|
|
|
|
name = strdup( IfInfo[i].Name );
|
|
|
|
ptr = name + strlen( name ) - 1;
|
|
|
|
while( (ptr > name) && isdigit( (int) *ptr ) ) {
|
|
|
|
*ptr = '\0';
|
|
|
|
ptr--;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* traverse the kstat chain
|
|
|
|
* to find the appropriate statistics
|
|
|
|
*/
|
|
|
|
if( (ksp = kstat_lookup( kctl,
|
|
|
|
name, 0, IfInfo[i].Name )) == NULL ) {
|
|
|
|
free( name );
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
if( kstat_read( kctl, ksp, NULL ) == -1 ) {
|
|
|
|
free( name );
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
free( name );
|
|
|
|
|
|
|
|
/*
|
|
|
|
* lookup & store the data
|
|
|
|
*/
|
|
|
|
kdata = (kstat_named_t *) kstat_data_lookup( ksp, "ipackets" );
|
|
|
|
if( kdata != NULL ) {
|
|
|
|
IfInfo[i].OLDipackets = IfInfo[i].ipackets;
|
|
|
|
IfInfo[i].ipackets = kdata->value.ul;
|
|
|
|
}
|
|
|
|
kdata = (kstat_named_t *) kstat_data_lookup( ksp, "opackets" );
|
|
|
|
if( kdata != NULL ) {
|
|
|
|
IfInfo[i].OLDopackets = IfInfo[i].opackets;
|
|
|
|
IfInfo[i].opackets = kdata->value.ul;
|
|
|
|
}
|
|
|
|
kdata = (kstat_named_t *) kstat_data_lookup( ksp, "ierrors" );
|
|
|
|
if( kdata != NULL ) {
|
|
|
|
IfInfo[i].OLDierrors = IfInfo[i].ierrors;
|
|
|
|
IfInfo[i].ierrors = kdata->value.ul;
|
|
|
|
}
|
|
|
|
kdata = (kstat_named_t *) kstat_data_lookup( ksp, "oerrors" );
|
|
|
|
if( kdata != NULL ) {
|
|
|
|
IfInfo[i].OLDoerrors = IfInfo[i].oerrors;
|
|
|
|
IfInfo[i].oerrors = kdata->value.ul;
|
|
|
|
}
|
|
|
|
kdata = (kstat_named_t *) kstat_data_lookup( ksp, "collisions" );
|
|
|
|
if( kdata != NULL ) {
|
|
|
|
IfInfo[i].OLDcollisions = IfInfo[i].collisions;
|
|
|
|
IfInfo[i].collisions = kdata->value.ul;
|
|
|
|
}
|
|
|
|
kdata = (kstat_named_t *) kstat_data_lookup( ksp, "multixmt" );
|
|
|
|
if( kdata != NULL ) {
|
|
|
|
IfInfo[i].OLDmultixmt = IfInfo[i].multixmt;
|
|
|
|
IfInfo[i].multixmt = kdata->value.ul;
|
|
|
|
}
|
|
|
|
kdata = (kstat_named_t *) kstat_data_lookup( ksp, "multircv" );
|
|
|
|
if( kdata != NULL ) {
|
|
|
|
IfInfo[i].OLDmultircv = IfInfo[i].multircv;
|
|
|
|
IfInfo[i].multircv = kdata->value.ul;
|
|
|
|
}
|
|
|
|
kdata = (kstat_named_t *) kstat_data_lookup( ksp, "brdcstxmt" );
|
|
|
|
if( kdata != NULL ) {
|
|
|
|
IfInfo[i].OLDbrdcstxmt = IfInfo[i].brdcstxmt;
|
|
|
|
IfInfo[i].brdcstxmt = kdata->value.ul;
|
|
|
|
}
|
|
|
|
kdata = (kstat_named_t *) kstat_data_lookup( ksp, "brdcstrcv" );
|
|
|
|
if( kdata != NULL ) {
|
|
|
|
IfInfo[i].OLDbrdcstrcv = IfInfo[i].brdcstrcv;
|
|
|
|
IfInfo[i].brdcstrcv = kdata->value.ul;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
kstat_close( kctl );
|
|
|
|
#endif /* ! HAVE_KSTAT */
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
void printIPacketsInfo( const char *cmd ) {
|
|
|
|
fprintf(CurrentClient, "Received Packets\t0\t0\tPackets\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void printIPackets( const char *cmd ) {
|
|
|
|
|
|
|
|
char *cmdcopy = strdup( cmd );
|
|
|
|
char *name, *ptr;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
ptr = strchr( cmdcopy, (int) '/' );
|
|
|
|
name = ++ptr;
|
|
|
|
ptr = strchr( name, (int) '/' );
|
|
|
|
*ptr = '\0';
|
|
|
|
|
|
|
|
for( i = 0; i < NetDevCount; i++ ) {
|
|
|
|
if( (IfInfo[i].OLDipackets > 0)
|
|
|
|
&& (strcmp( IfInfo[i].Name, name ) == 0) ) {
|
|
|
|
fprintf(CurrentClient, "%ld\n",
|
|
|
|
IfInfo[i].ipackets - IfInfo[i].OLDipackets);
|
|
|
|
free( cmdcopy );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free( cmdcopy );
|
|
|
|
fprintf(CurrentClient, "0\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void printOPacketsInfo( const char *cmd ) {
|
|
|
|
fprintf(CurrentClient, "Transmitted Packets\t0\t0\tPackets\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void printOPackets( const char *cmd ) {
|
|
|
|
|
|
|
|
char *cmdcopy = strdup( cmd );
|
|
|
|
char *name, *ptr;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
ptr = strchr( cmdcopy, (int) '/' );
|
|
|
|
name = ++ptr;
|
|
|
|
ptr = strchr( name, (int) '/' );
|
|
|
|
*ptr = '\0';
|
|
|
|
|
|
|
|
for( i = 0; i < NetDevCount; i++ ) {
|
|
|
|
if( (IfInfo[i].OLDopackets > 0)
|
|
|
|
&& (strcmp( IfInfo[i].Name, name ) == 0) ) {
|
|
|
|
fprintf(CurrentClient, "%ld\n",
|
|
|
|
IfInfo[i].opackets - IfInfo[i].OLDopackets );
|
|
|
|
free( cmdcopy );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free( cmdcopy );
|
|
|
|
fprintf(CurrentClient, "0\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void printIErrorsInfo( const char *cmd ) {
|
|
|
|
fprintf(CurrentClient, "Input Errors\t0\t0\tPackets\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void printIErrors( const char *cmd ) {
|
|
|
|
|
|
|
|
char *cmdcopy = strdup( cmd );
|
|
|
|
char *name, *ptr;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
ptr = strchr( cmdcopy, (int) '/' );
|
|
|
|
name = ++ptr;
|
|
|
|
ptr = strchr( name, (int) '/' );
|
|
|
|
*ptr = '\0';
|
|
|
|
|
|
|
|
for( i = 0; i < NetDevCount; i++ ) {
|
|
|
|
if( (IfInfo[i].OLDierrors > 0)
|
|
|
|
&& (strcmp( IfInfo[i].Name, name ) == 0) ) {
|
|
|
|
fprintf(CurrentClient, "%ld\n",
|
|
|
|
IfInfo[i].ierrors - IfInfo[i].OLDierrors );
|
|
|
|
free( cmdcopy );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free( cmdcopy );
|
|
|
|
fprintf(CurrentClient, "0\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void printOErrorsInfo( const char *cmd ) {
|
|
|
|
fprintf(CurrentClient, "Output Errors\t0\t0\tPackets\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void printOErrors( const char *cmd ) {
|
|
|
|
|
|
|
|
char *cmdcopy = strdup( cmd );
|
|
|
|
char *name, *ptr;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
ptr = strchr( cmdcopy, (int) '/' );
|
|
|
|
name = ++ptr;
|
|
|
|
ptr = strchr( name, (int) '/' );
|
|
|
|
*ptr = '\0';
|
|
|
|
|
|
|
|
for( i = 0; i < NetDevCount; i++ ) {
|
|
|
|
if( (IfInfo[i].OLDoerrors > 0)
|
|
|
|
&& (strcmp( IfInfo[i].Name, name ) == 0) ) {
|
|
|
|
fprintf(CurrentClient, "%ld\n",
|
|
|
|
IfInfo[i].oerrors - IfInfo[i].OLDoerrors );
|
|
|
|
free( cmdcopy );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free( cmdcopy );
|
|
|
|
fprintf(CurrentClient, "0\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void printCollisionsInfo( const char *cmd ) {
|
|
|
|
fprintf(CurrentClient, "Collisions\t0\t0\tPackets\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void printCollisions( const char *cmd ) {
|
|
|
|
|
|
|
|
char *cmdcopy = strdup( cmd );
|
|
|
|
char *name, *ptr;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
ptr = strchr( cmdcopy, (int) '/' );
|
|
|
|
name = ++ptr;
|
|
|
|
ptr = strchr( name, (int) '/' );
|
|
|
|
*ptr = '\0';
|
|
|
|
|
|
|
|
for( i = 0; i < NetDevCount; i++ ) {
|
|
|
|
if( (IfInfo[i].OLDcollisions > 0)
|
|
|
|
&& (strcmp( IfInfo[i].Name, name ) == 0) ) {
|
|
|
|
fprintf(CurrentClient, "%ld\n",
|
|
|
|
IfInfo[i].collisions - IfInfo[i].OLDcollisions );
|
|
|
|
free( cmdcopy );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free( cmdcopy );
|
|
|
|
fprintf(CurrentClient, "0\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void printMultiXmitsInfo( const char *cmd ) {
|
|
|
|
fprintf(CurrentClient, "Multicasts Sent\t0\t0\tPackets\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void printMultiXmits( const char *cmd ) {
|
|
|
|
|
|
|
|
char *cmdcopy = strdup( cmd );
|
|
|
|
char *name, *ptr;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
ptr = strchr( cmdcopy, (int) '/' );
|
|
|
|
name = ++ptr;
|
|
|
|
ptr = strchr( name, (int) '/' );
|
|
|
|
*ptr = '\0';
|
|
|
|
|
|
|
|
for( i = 0; i < NetDevCount; i++ ) {
|
|
|
|
if( (IfInfo[i].OLDmultixmt > 0)
|
|
|
|
&& (strcmp( IfInfo[i].Name, name ) == 0) ) {
|
|
|
|
fprintf(CurrentClient, "%ld\n",
|
|
|
|
IfInfo[i].multixmt - IfInfo[i].OLDmultixmt );
|
|
|
|
free( cmdcopy );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free( cmdcopy );
|
|
|
|
fprintf(CurrentClient, "0\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void printMultiRecvsInfo( const char *cmd ) {
|
|
|
|
fprintf(CurrentClient, "Multicasts Received\t0\t0\tPackets\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void printMultiRecvs( const char *cmd ) {
|
|
|
|
|
|
|
|
char *cmdcopy = strdup( cmd );
|
|
|
|
char *name, *ptr;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
ptr = strchr( cmdcopy, (int) '/' );
|
|
|
|
name = ++ptr;
|
|
|
|
ptr = strchr( name, (int) '/' );
|
|
|
|
*ptr = '\0';
|
|
|
|
|
|
|
|
for( i = 0; i < NetDevCount; i++ ) {
|
|
|
|
if( (IfInfo[i].OLDmultircv > 0)
|
|
|
|
&& (strcmp( IfInfo[i].Name, name ) == 0) ) {
|
|
|
|
fprintf(CurrentClient, "%ld\n",
|
|
|
|
IfInfo[i].multircv - IfInfo[i].OLDmultircv );
|
|
|
|
free( cmdcopy );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free( cmdcopy );
|
|
|
|
fprintf(CurrentClient, "0\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void printBcastXmitsInfo( const char *cmd ) {
|
|
|
|
fprintf(CurrentClient, "Broadcasts Sent\t0\t0\tPackets\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void printBcastXmits( const char *cmd ) {
|
|
|
|
|
|
|
|
char *cmdcopy = strdup( cmd );
|
|
|
|
char *name, *ptr;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
ptr = strchr( cmdcopy, (int) '/' );
|
|
|
|
name = ++ptr;
|
|
|
|
ptr = strchr( name, (int) '/' );
|
|
|
|
*ptr = '\0';
|
|
|
|
|
|
|
|
for( i = 0; i < NetDevCount; i++ ) {
|
|
|
|
if( (IfInfo[i].OLDbrdcstxmt > 0)
|
|
|
|
&& (strcmp( IfInfo[i].Name, name ) == 0) ) {
|
|
|
|
fprintf(CurrentClient, "%ld\n",
|
|
|
|
IfInfo[i].brdcstxmt - IfInfo[i].OLDbrdcstxmt );
|
|
|
|
free( cmdcopy );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free( cmdcopy );
|
|
|
|
fprintf(CurrentClient, "0\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void printBcastRecvsInfo( const char *cmd ) {
|
|
|
|
fprintf(CurrentClient, "Broadcasts Received\t0\t0\tPackets\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void printBcastRecvs( const char *cmd ) {
|
|
|
|
|
|
|
|
char *cmdcopy = strdup( cmd );
|
|
|
|
char *name, *ptr;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
ptr = strchr( cmdcopy, (int) '/' );
|
|
|
|
name = ++ptr;
|
|
|
|
ptr = strchr( name, (int) '/' );
|
|
|
|
*ptr = '\0';
|
|
|
|
|
|
|
|
for( i = 0; i < NetDevCount; i++ ) {
|
|
|
|
if( (IfInfo[i].OLDbrdcstrcv > 0)
|
|
|
|
&& (strcmp( IfInfo[i].Name, name ) == 0) ) {
|
|
|
|
fprintf(CurrentClient, "%ld\n",
|
|
|
|
IfInfo[i].brdcstrcv - IfInfo[i].OLDbrdcstrcv );
|
|
|
|
free( cmdcopy );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free( cmdcopy );
|
|
|
|
fprintf(CurrentClient, "0\n" );
|
|
|
|
}
|