#include #include #include #include #include #include #include #include #include #include #define TRUE 1 #define FALSE 0 #define MX_IFNAME IFNAMSIZ /* subset from netload applet -> net.h */ typedef struct { int mib_name1[6]; int mib_name2[6]; char* buf1; char* buf2; int alloc1; int alloc2; /* test hack: workalike member */ struct { char if_name[MX_IFNAME]; } ifdata; } netdata; /* from netload applet -> openbsd.c */ 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 OpenBSD.\n" ); #endif } /* from netload applet -> openbsd.c */ /***************************************************************************** * * 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; 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); /* search for the right network interface */ if (sdl->sdl_family != AF_LINK) continue; /* OpenBSD netstat code checks > 0, so do so here */ if (sdl->sdl_nlen > 0) { size_t nlen = sdl->sdl_nlen; if (strncmp(sdl->sdl_data, data->ifdata.if_name, nlen) != 0) continue; if (data->ifdata.if_name[nlen] != '\0') continue; } else continue; validinterface = TRUE; break; /* stop searching */ } } return validinterface; } /* from netload applet -> openbsd.c */ /***************************************************************************** * * get_stat() * * this code is based on gkrellm code (thanks guys!) * ****************************************************************************/ int get_stat_orig(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); /* search for the right network interface */ if (sdl->sdl_family != AF_LINK) continue; if (strcmp(sdl->sdl_data, data->ifdata.if_name) != 0) continue; strncpy(s, sdl->sdl_data, sdl->sdl_nlen); s[sdl->sdl_nlen] = '\0'; /* write stats */ /* original stats collection was here; * now just print that iface is found */ printf("FOUND '%s' -- ORIG STATS OK\n", data->ifdata.if_name); } } return 0; } /* from netload applet -> openbsd.c */ /***************************************************************************** * * get_stat() * * this code is based on gkrellm code (thanks guys!) * ****************************************************************************/ int get_stat_fixed(netdata* data) { char *lim, *next; struct if_msghdr *ifm, *nextifm; struct sockaddr_dl *sdl; 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); /* search for the right network interface */ if (sdl->sdl_family != AF_LINK) continue; /* OpenBSD netstat code checks > 0, so do so here */ if (sdl->sdl_nlen > 0) { size_t nlen = sdl->sdl_nlen; if (strncmp(sdl->sdl_data, data->ifdata.if_name, nlen) != 0) continue; if (data->ifdata.if_name[nlen] != '\0') continue; } else continue; /* write stats */ /* original stats collection was here; * now just print that iface is found */ printf("FOUND '%s' -- FIXED STATS OK\n", data->ifdata.if_name); } } return 0; } int main(int argc, char *argv[]) { int i; netdata data; for (i = 1; i < argc; i++) { memset(&data, 0, sizeof(data)); init_osspecific(&data); strlcpy(data.ifdata.if_name, argv[i], sizeof(data.ifdata.if_name)); if ( checkinterface(&data) ) { printf("Found: '%s' -- doing get_stat_fixed()\n", argv[i]); get_stat_fixed(&data); printf("Found: '%s' -- doing get_stat_orig()\n", argv[i]); get_stat_orig(&data); } else { fprintf(stderr, "Not found: '%s'\n", argv[i]); } } return 0; }