172 lines
4.8 KiB
C
172 lines
4.8 KiB
C
|
/*****************************************************************************
|
||
|
*
|
||
|
* init_osspecific()
|
||
|
*
|
||
|
* Init function
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
void init_osspecific(netdata* data)
|
||
|
{
|
||
|
data->mib_name1[0] = CTL_NET;
|
||
|
data->mib_name1[1] = PF_ROUTE;
|
||
|
data->mib_name1[2] = 0;
|
||
|
data->mib_name1[3] = 0;
|
||
|
data->mib_name1[4] = NET_RT_IFLIST;
|
||
|
data->mib_name1[5] = 0;
|
||
|
|
||
|
data->mib_name2[0] = CTL_NET;
|
||
|
data->mib_name2[1] = PF_ROUTE;
|
||
|
data->mib_name2[2] = 0;
|
||
|
data->mib_name2[3] = 0;
|
||
|
data->mib_name2[4] = NET_RT_IFLIST;
|
||
|
data->mib_name2[5] = 0;
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
fprintf( stderr, "The netload plugin was initialized for NetBSD.\n" );
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* checkinterface()
|
||
|
*
|
||
|
* check if a given interface exists, return TRUE if it does and FALSE if not
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
int checkinterface(netdata* data)
|
||
|
{
|
||
|
int validinterface = FALSE;
|
||
|
char *lim, *next;
|
||
|
struct if_msghdr *ifm, *nextifm;
|
||
|
struct sockaddr_dl *sdl;
|
||
|
size_t needed;
|
||
|
char s[32];
|
||
|
|
||
|
if (sysctl(data->mib_name1, 6, NULL, &needed, NULL, 0) < 0)
|
||
|
return FALSE;
|
||
|
if (data->alloc1 < (signed long) needed)
|
||
|
{
|
||
|
if (data->buf1 != NULL)
|
||
|
free (data->buf1);
|
||
|
data->buf1 = malloc(needed);
|
||
|
if (data->buf1 == NULL)
|
||
|
return FALSE;
|
||
|
data->alloc1 = needed;
|
||
|
}
|
||
|
|
||
|
if (sysctl(data->mib_name1, 6, data->buf1, &needed, NULL, 0) < 0)
|
||
|
return FALSE;
|
||
|
lim = data->buf1 + needed;
|
||
|
next = data->buf1;
|
||
|
while ((next < lim) && (validinterface == 0))
|
||
|
{
|
||
|
ifm = (struct if_msghdr *)next;
|
||
|
if (ifm->ifm_type != RTM_IFINFO)
|
||
|
return FALSE;
|
||
|
next += ifm->ifm_msglen;
|
||
|
|
||
|
while (next < lim)
|
||
|
{
|
||
|
nextifm = (struct if_msghdr *)next;
|
||
|
if (nextifm->ifm_type != RTM_NEWADDR)
|
||
|
break;
|
||
|
next += nextifm->ifm_msglen;
|
||
|
}
|
||
|
|
||
|
if (ifm->ifm_flags & IFF_UP)
|
||
|
{
|
||
|
sdl = (struct sockaddr_dl *)(ifm + 1);
|
||
|
strncpy(s, sdl->sdl_data, sdl->sdl_nlen);
|
||
|
s[sdl->sdl_nlen] = '\0';
|
||
|
/* search for the right network interface */
|
||
|
if (sdl->sdl_family != AF_LINK)
|
||
|
continue;
|
||
|
if (strcmp(s, data->ifdata.if_name) != 0)
|
||
|
continue;
|
||
|
else
|
||
|
{
|
||
|
validinterface = TRUE;
|
||
|
break; /* stop searching */
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return validinterface;
|
||
|
}
|
||
|
/******************************************************************************
|
||
|
*
|
||
|
* get_stat()
|
||
|
*
|
||
|
* this code is based on gkrellm code (thanks guys!)
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
int get_stat(netdata* data)
|
||
|
{
|
||
|
char *lim, *next;
|
||
|
struct if_msghdr *ifm, *nextifm;
|
||
|
struct sockaddr_dl *sdl;
|
||
|
char s[32];
|
||
|
size_t needed;
|
||
|
unsigned long rx_o, tx_o;
|
||
|
|
||
|
if (sysctl(data->mib_name2, 6, NULL, &needed, NULL, 0) < 0)
|
||
|
return 1;
|
||
|
if (data->alloc2 < (signed long) needed)
|
||
|
{
|
||
|
if (data->buf2 != NULL)
|
||
|
free (data->buf2);
|
||
|
data->buf2 = malloc(needed);
|
||
|
if (data->buf2 == NULL)
|
||
|
return 1;
|
||
|
data->alloc2 = needed;
|
||
|
}
|
||
|
|
||
|
if (sysctl(data->mib_name2, 6, data->buf2, &needed, NULL, 0) < 0)
|
||
|
return 1;
|
||
|
lim = data->buf2 + needed;
|
||
|
next = data->buf2;
|
||
|
while (next < lim)
|
||
|
{
|
||
|
ifm = (struct if_msghdr *)next;
|
||
|
if (ifm->ifm_type != RTM_IFINFO)
|
||
|
return 1;
|
||
|
next += ifm->ifm_msglen;
|
||
|
|
||
|
while (next < lim)
|
||
|
{
|
||
|
nextifm = (struct if_msghdr *)next;
|
||
|
if (nextifm->ifm_type != RTM_NEWADDR)
|
||
|
break;
|
||
|
next += nextifm->ifm_msglen;
|
||
|
}
|
||
|
|
||
|
if (ifm->ifm_flags & IFF_UP)
|
||
|
{
|
||
|
sdl = (struct sockaddr_dl *)(ifm + 1);
|
||
|
strncpy(s, sdl->sdl_data, sdl->sdl_nlen);
|
||
|
s[sdl->sdl_nlen] = '\0';
|
||
|
|
||
|
/* search for the right network interface */
|
||
|
if (strcmp(s, data->ifdata.if_name) != 0)
|
||
|
continue;
|
||
|
|
||
|
rx_o = data->stats.rx_bytes; tx_o = data->stats.tx_bytes;
|
||
|
/* write stats */
|
||
|
data->stats.tx_packets = ifm->ifm_data.ifi_opackets;
|
||
|
data->stats.rx_packets = ifm->ifm_data.ifi_ipackets;
|
||
|
data->stats.rx_bytes = ifm->ifm_data.ifi_ibytes;
|
||
|
data->stats.tx_bytes = ifm->ifm_data.ifi_obytes;
|
||
|
data->stats.rx_errors = ifm->ifm_data.ifi_ierrors;
|
||
|
data->stats.tx_errors = ifm->ifm_data.ifi_oerrors;
|
||
|
|
||
|
if (rx_o > data->stats.rx_bytes)
|
||
|
data->stats.rx_over++;
|
||
|
if (tx_o > data->stats.tx_bytes)
|
||
|
data->stats.tx_over++;
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|