#include "netstatus.h" #if defined(__FreeBSD__) || defined(__DragonFly__) # include # include # include # include #endif #if defined(__OpenBSD__) # include # include # include # include # include # include # include # include #endif #if defined(__FreeBSD__) || defined(__DragonFly__) static int get_ifmib_general(int row, struct ifmibdata *data) { int mib[6]; size_t len; mib[0] = CTL_NET; mib[1] = PF_LINK; mib[2] = NETLINK_GENERIC; mib[3] = IFMIB_IFDATA; mib[4] = row; mib[5] = IFDATA_GENERAL; len = sizeof(*data); return sysctl(mib, 6, data, &len, NULL, 0); } static void _freebsd_generic_network_status(unsigned long int *in, unsigned long int *out) { struct ifmibdata *ifmd; size_t len; int i, count; len = sizeof(count); if (sysctlbyname("net.link.generic.system.ifcount", &count, &len, NULL, 0) < 0) return; ifmd = malloc(sizeof(struct ifmibdata)); if (!ifmd) return; for (i = 1; i <= count; i++) { get_ifmib_general(i, ifmd); *in += ifmd->ifmd_data.ifi_ibytes; *out += ifmd->ifmd_data.ifi_obytes; } free(ifmd); } #endif #if defined(__OpenBSD__) static void _openbsd_generic_network_status(unsigned long int *in, unsigned long int *out) { struct ifaddrs *interfaces, *ifa; if (getifaddrs(&interfaces) < 0) return; int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) return; for (ifa = interfaces; ifa; ifa = ifa->ifa_next) { struct ifreq ifreq; struct if_data if_data; ifreq.ifr_data = (void *)&if_data; strncpy(ifreq.ifr_name, ifa->ifa_name, IFNAMSIZ - 1); if (ioctl(sock, SIOCGIFDATA, &ifreq) < 0) return; struct if_data *const ifi = &if_data; if (ifi->ifi_type == IFT_ETHER || ifi->ifi_type == IFT_IEEE80211) { if (ifi->ifi_ibytes) *in += ifi->ifi_ibytes; else *in += 0; if (ifi->ifi_obytes) *out += ifi->ifi_obytes; else *out += 0; } } close(sock); } #endif void _netstatus_sysctl_getstatus(Eina_Bool automax, time_t *last_checked, unsigned long *prev_in, unsigned long *prev_incurrent, unsigned long *prev_inmax, int *prev_inpercent, unsigned long *prev_out, unsigned long *prev_outcurrent, unsigned long *prev_outmax, int *prev_outpercent) { unsigned long tot_out = 0, tot_in = 0, diffin, diffout; int percent = 0; unsigned long int incoming = 0, outgoing = 0; time_t current = time(NULL); time_t diff = 0; #if defined(__OpenBSD__) _openbsd_generic_network_status(&incoming, &outgoing); #elif defined(__FreeBSD__) || defined(__DragonFly__) _freebsd_generic_network_status(&incoming, &outgoing); #endif if (!*last_checked) *last_checked = current; if ((current - *last_checked) < 1) return; else diff = current - *last_checked; tot_in = incoming; tot_out = outgoing; diffin = tot_in - *prev_in; if (diff > 1) diffin /= diff; if (!*prev_in) *prev_in = tot_in; else { *prev_in = tot_in; if (automax) { if (diffin > *prev_inmax) *prev_inmax = diffin; } *prev_incurrent = diffin; if (*prev_inmax > 0) percent = 100 * ((float)*prev_incurrent / (float)*prev_inmax); if (percent > 100) percent = 100; else if (percent < 0) percent = 0; *prev_inpercent = percent; } percent = 0; diffout = tot_out - *prev_out; if (diff > 1) diffout /= diff; if (!*prev_out) *prev_out = tot_out; else { *prev_out = tot_out; if (automax) { if (diffout > *prev_outmax) *prev_outmax = diffout; } *prev_outcurrent = diffout; if (*prev_outcurrent > 0) percent = 100 * ((float)*prev_outcurrent / (float)*prev_outmax); if (percent > 100) percent = 100; else if (percent < 0) percent = 0; *prev_outpercent = percent; } *last_checked = current; }