/*
* Copyright (c) 2001 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* nifmon - network interface handling
* -----------------------------------
*
* last edit-date: [Sat Sep 8 15:28:18 2001]
*
*---------------------------------------------------------------------------*/
#include "nifmon.h"
static int ifcount = 0;
static int sockfd = -1;
static int mrow;
static struct ifconf ifc;
static char buf[2048];
static int len;
static char *ptr;
static struct ifreq *ifr, *ifr1;
static struct sockaddr_in *sin;
static char *addr, *dstaddr;
static char lastaddr[] = "";
static size_t slen;
static int row;
static struct ifmibdata ifmd;
static int name[6];
static struct hostent he;
static struct hostent *hep;
static time_t lastchange;
static time_t prevchange;
static time_t lastdiff;
static time_t prevdiff;
static u_long ibs;
static u_long obs;
static u_long ips;
static u_long ops;
static time_t m_t;
static u_long ibm;
static u_long obm;
static u_long ipm;
static u_long opm;
static time_t h_t;
static u_long ibh;
static u_long obh;
static u_long iph;
static u_long oph;
static struct timeval tvlast;
/*---------------------------------------------------------------------------*
* initialize interface data
*---------------------------------------------------------------------------*/
void
init_interface(char *interface)
{
slen = sizeof(int);
if (sysctlbyname("net.link.generic.system.ifcount", &ifcount, &slen, 0, 0) < 0)
{
perror("sysctl-ifcount");
do_exit(1);
}
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
ifc.ifc_len = sizeof(buf);
ifc.ifc_req = (struct ifreq *) buf;
ioctl(sockfd, SIOCGIFCONF, &ifc);
for (ptr = buf; ptr < buf + ifc.ifc_len;)
{
ifr = (struct ifreq *) ptr;
len = sizeof(struct sockaddr);
if (ifr->ifr_addr.sa_len > len)
len = ifr->ifr_addr.sa_len;
ptr += sizeof(ifr->ifr_name) + len;
if (strcmp(ifr->ifr_name, interface))
continue;
if (ifr->ifr_addr.sa_family == AF_INET)
{
ifr1 = ifr;
if (ioctl(sockfd, SIOCGIFFLAGS, ifr1) < 0)
{
perror("FLAGS");
do_exit(1);
}
if_flags = ifr1->ifr_flags;
for (row = 1; row <= ifcount; row++)
{
slen = sizeof(ifmd);
name[0] = CTL_NET;
name[1] = PF_LINK;
name[2] = NETLINK_GENERIC;
name[3] = IFMIB_IFDATA;
name[4] = row;
name[5] = IFDATA_GENERAL;
sysctl(name, 6, &ifmd, &slen, (void *) 0, 0);
if (!strcmp(ifmd.ifmd_name, ifr->ifr_name))
{
mrow = row;
prevchange =
ifmd.ifmd_data.ifi_lastchange.
tv_sec;
lastchange = prevchange =
ifmd.ifmd_data.ifi_lastchange.
tv_sec;
gettimeofday(&tvlast, NULL);
m_t = h_t = tvlast.tv_sec;
ibs = ibm = ibh =
ifmd.ifmd_data.ifi_ibytes;
obs = obm = obh =
ifmd.ifmd_data.ifi_obytes;
ips = ipm = iph =
ifmd.ifmd_data.ifi_ipackets;
ops = opm = oph =
ifmd.ifmd_data.ifi_opackets;
break;
}
}
break;
}
}
}
/*---------------------------------------------------------------------------*
* update interface data
*---------------------------------------------------------------------------*/
void
update_interface(char *interface)
{
struct timeval tv;
gettimeofday(&tv, NULL);
if (tv.tv_sec == tvlast.tv_sec)
return;
if (tv.tv_sec == (tvlast.tv_sec + 1))
{
if (tv.tv_usec < tvlast.tv_usec)
return;
}
tvlast = tv;
ifc.ifc_len = sizeof(buf);
ifc.ifc_req = (struct ifreq *) buf;
ioctl(sockfd, SIOCGIFCONF, &ifc);
for (ptr = buf; ptr < buf + ifc.ifc_len;)
{
ifr = (struct ifreq *) ptr;
len = sizeof(struct sockaddr);
if (ifr->ifr_addr.sa_len > len)
len = ifr->ifr_addr.sa_len;
ptr += sizeof(ifr->ifr_name) + len;
if (strcmp(ifr->ifr_name, interface))
continue;
if (ifr->ifr_addr.sa_family == AF_INET)
{
ifr1 = ifr;
if (ioctl(sockfd, SIOCGIFFLAGS, ifr1) < 0)
{
perror("FLAGS");
do_exit(1);
}
sin = (struct sockaddr_in *) &ifr1->ifr_addr;
addr = inet_ntoa(sin->sin_addr);
if(strcmp(addr, lastaddr))
{
strcpy(lastaddr, addr);
hep = &he;
hep = gethostbyaddr((char *) &sin->sin_addr,
sizeof(sin->sin_addr), AF_INET);
if (hep)
hostname = hep->h_name;
else
hostname = "unknown hostname";
}
mvwprintw(upper_w, V_IP, H_LOCIP, "%-15s", addr);
mvwprintw(upper_w, V_IP, H_LOCHN, "%-36s", hostname);
if (ifr1->ifr_flags & IFF_LOOPBACK)
{
}
else if (ifr1->ifr_flags & IFF_POINTOPOINT)
{
if (ioctl(sockfd, SIOCGIFDSTADDR, ifr1) < 0)
{
perror("DST");
do_exit(1);
}
sin =
(struct sockaddr_in *) &ifr1->
ifr_dstaddr;
dstaddr = inet_ntoa(sin->sin_addr);
mvwprintw(upper_w, V_IP, H_REMIP, "%-15s",
dstaddr);
}
else
{
if (ioctl(sockfd, SIOCGIFBRDADDR, ifr1) < 0)
{
perror("BRD");
do_exit(1);
}
sin = (struct sockaddr_in *) &ifr1->ifr_broadaddr;
dstaddr = inet_ntoa(sin->sin_addr);
mvwprintw(upper_w, V_IP, H_REMIP, "%-15s",
dstaddr);
}
slen = sizeof(ifmd);
name[0] = CTL_NET;
name[1] = PF_LINK;
name[2] = NETLINK_GENERIC;
name[3] = IFMIB_IFDATA;
name[4] = mrow;
name[5] = IFDATA_GENERAL;
sysctl(name, 6, &ifmd, &slen, (void *) 0, 0);
if (ifmd.ifmd_data.ifi_ibytes > 1024000000)
sprintf(buf, "%lu (%dG)",
ifmd.ifmd_data.ifi_ibytes,
(int)ifmd.ifmd_data.ifi_ibytes / 1024000000);
else if (ifmd.ifmd_data.ifi_ibytes > 1024000)
sprintf(buf, "%lu (%dM)",
ifmd.ifmd_data.ifi_ibytes,
(int)ifmd.ifmd_data.ifi_ibytes / 1024000);
else if (ifmd.ifmd_data.ifi_ibytes > 1024)
sprintf(buf, "%lu (%dk)",
ifmd.ifmd_data.ifi_ibytes,
(int)ifmd.ifmd_data.ifi_ibytes / 1024);
else
sprintf(buf, "%lu",
ifmd.ifmd_data.ifi_ibytes);
mvwprintw(upper_w, V_BIO, H_BIN, "%-24s", buf);
if (ifmd.ifmd_data.ifi_obytes > 1024000000)
sprintf(buf, "%lu (%dG)",
ifmd.ifmd_data.ifi_obytes,
(int)ifmd.ifmd_data.ifi_obytes / 1024000000);
else if (ifmd.ifmd_data.ifi_obytes > 1024000)
sprintf(buf, "%lu (%dM)",
ifmd.ifmd_data.ifi_obytes,
(int)ifmd.ifmd_data.ifi_obytes / 1024000);
else if (ifmd.ifmd_data.ifi_obytes > 1024)
sprintf(buf, "%lu (%dk)",
ifmd.ifmd_data.ifi_obytes,
(int)ifmd.ifmd_data.ifi_obytes / 1024);
else
sprintf(buf, "%lu",
ifmd.ifmd_data.ifi_obytes);
mvwprintw(upper_w, V_BIO, H_BOUT, "%-24s", buf);
mvwprintw(upper_w, V_PIO, H_PIN, "%lu",
ifmd.ifmd_data.ifi_ipackets);
mvwprintw(upper_w, V_PIO, H_POUT, "%lu",
ifmd.ifmd_data.ifi_opackets);
if (ifmd.ifmd_data.ifi_lastchange.tv_sec)
{
time_t diff;
time_t d, h, m, r;
diff = (time_t) difftime(tv.tv_sec,
ifmd.ifmd_data.
ifi_lastchange.
tv_sec);
d = diff / (24 * 60 * 60);
r = diff % (24 * 60 * 60);
h = r / (60 * 60);
r = r % (60 * 60);
m = r / 60;
sprintf(buf, "%24.24s (%d:%d:%d)",
ctime(&ifmd.ifmd_data. ifi_lastchange.tv_sec),
(int)d, (int)h, (int)m);
mvwprintw(upper_w, V_LADCD, H_LADMCHG, "%-35s", buf);
if (ifmd.ifmd_data.ifi_lastchange.tv_sec !=
lastchange)
{
prevdiff = lastdiff;
prevchange = lastchange;
lastchange =
ifmd.ifmd_data.ifi_lastchange.
tv_sec;
d = prevdiff / (24 * 60 * 60);
r = prevdiff % (24 * 60 * 60);
h = r / (60 * 60);
r = r % (60 * 60);
m = r / 60;
sprintf(buf, "%24.24s (%d:%d:%d)",
ctime(&prevchange),
(int)d, (int)h, (int)m);
mvwprintw(upper_w, V_LADCD, H_PADMCHG, "%-35s", buf);
}
lastdiff = diff;
}
else
{
mvwprintw(upper_w, V_LADCD, H_LADMCHG,
"last administrative change time unsupported by driver");
}
mvwprintw(upper_w, V_IBYTE, H_SEC, "%-9lu",
ifmd.ifmd_data.ifi_ibytes - ibs);
ibs = ifmd.ifmd_data.ifi_ibytes;
mvwprintw(upper_w, V_OBYTE, H_SEC, "%-9lu",
ifmd.ifmd_data.ifi_obytes - obs);
obs = ifmd.ifmd_data.ifi_obytes;
mvwprintw(upper_w, V_IPACK, H_SEC, "%-9lu",
ifmd.ifmd_data.ifi_ipackets - ips);
ips = ifmd.ifmd_data.ifi_ipackets;
mvwprintw(upper_w, V_OPACK, H_SEC, "%-9lu",
ifmd.ifmd_data.ifi_opackets - ops);
ops = ifmd.ifmd_data.ifi_opackets;
if (tv.tv_sec > (m_t + 60))
{
m_t = tv.tv_sec;
mvwprintw(upper_w, V_IBYTE, H_MIN, "%-16lu",
ifmd.ifmd_data.ifi_ibytes - ibm);
ibm = ifmd.ifmd_data.ifi_ibytes;
mvwprintw(upper_w, V_OBYTE, H_MIN, "%-16lu",
ifmd.ifmd_data.ifi_obytes - obm);
obm = ifmd.ifmd_data.ifi_obytes;
mvwprintw(upper_w, V_IPACK, H_MIN, "%-16lu",
ifmd.ifmd_data.ifi_ipackets - ipm);
ipm = ifmd.ifmd_data.ifi_ipackets;
mvwprintw(upper_w, V_OPACK, H_MIN, "%-16lu",
ifmd.ifmd_data.ifi_opackets - opm);
opm = ifmd.ifmd_data.ifi_opackets;
}
if (tv.tv_sec > (h_t + (60 * 60)))
{
h_t = tv.tv_sec;
mvwprintw(upper_w, V_IBYTE, H_HR, "%-16lu",
ifmd.ifmd_data.ifi_ibytes - ibh);
ibh = ifmd.ifmd_data.ifi_ibytes;
mvwprintw(upper_w, V_OBYTE, H_HR, "%-16lu",
ifmd.ifmd_data.ifi_obytes - obh);
obh = ifmd.ifmd_data.ifi_obytes;
mvwprintw(upper_w, V_IPACK, H_HR, "%-16lu",
ifmd.ifmd_data.ifi_ipackets - iph);
iph = ifmd.ifmd_data.ifi_ipackets;
mvwprintw(upper_w, V_OPACK, H_HR, "%-16lu",
ifmd.ifmd_data.ifi_opackets - oph);
oph = ifmd.ifmd_data.ifi_opackets;
}
wrefresh(upper_w);
break;
}
}
}
/* EOF */
syntax highlighted by Code2HTML, v. 0.9.1