📄 statuscalls.c
字号:
/* This file is part of GNUnet. (C) 2001, 2002, 2003, 2005, 2006 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNUnet 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 GNUnet; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*//** * @file util/os/statuscalls.c * @brief calls to determine current network load * @author Tzvetan Horozov * @author Christian Grothoff * @author Igor Wronsky * @author Heikki Lindholm * * Status calls implementation for load management. */#include "platform.h"#include "gnunet_util_os.h"#include "gnunet_util_error.h"#include "gnunet_util_string.h"#include "gnunet_util_threads.h"#if SOLARIS#if HAVE_KSTAT_H#include <kstat.h>#endif#if HAVE_SYS_SYSINFO_H#include <sys/sysinfo.h>#endif#if HAVE_KVM_H#include <kvm.h>#endif#endif#if SOMEBSD#if HAVE_KVM_H#include <kvm.h>#endif#endif#if OSX#include <sys/sysctl.h>#include <net/if.h>#include <net/if_mib.h>#endif#define DEBUG_STATUSCALLS GNUNET_NO/** * where to read network interface information from * under Linux */#define PROC_NET_DEV "/proc/net/dev"typedef struct{ char *name; unsigned long long last_in; unsigned long long last_out;} NetworkStats;typedef struct{ unsigned long long overload; unsigned long long lastSum; GNUNET_CronTime lastCall; int lastValue; /** * Can we compute statistics (because we have a previous * value)? GNUNET_YES or GNUNET_NO. */ int have_last; /** * Maximum bandwidth as per config. */ unsigned long long max;} DirectionInfo;typedef struct GNUNET_LoadMonitor{ /** * Traffic counter for only gnunetd traffic. */ NetworkStats globalTrafficBetweenProc; /** * tracking */ NetworkStats *ifcs; /** * how many interfaces do we have? */ unsigned int ifcsSize; /** * How to measure traffic (GNUNET_YES == only gnunetd, * GNUNET_NO == try to include all apps) */ int useBasicMethod;#ifdef LINUX FILE *proc_net_dev;#endif /** * Lock. */ struct GNUNET_Mutex *statusMutex; struct GNUNET_GE_Context *ectx; struct GNUNET_GC_Configuration *cfg; DirectionInfo upload_info; DirectionInfo download_info; GNUNET_CronTime last_ifc_update;} LoadMonitor;voidGNUNET_network_monitor_notify_transmission (struct GNUNET_LoadMonitor *monitor, GNUNET_NETWORK_DIRECTION dir, unsigned long long delta){ GNUNET_mutex_lock (monitor->statusMutex); if (dir == GNUNET_ND_DOWNLOAD) monitor->globalTrafficBetweenProc.last_in += delta; else monitor->globalTrafficBetweenProc.last_out += delta; GNUNET_mutex_unlock (monitor->statusMutex);}#define MAX_PROC_LINE 5000static voidupdateInterfaceTraffic (struct GNUNET_LoadMonitor *monitor){#ifdef LINUX unsigned long long rxnew; unsigned long long txnew; int i; char line[MAX_PROC_LINE]; NetworkStats *ifc; char *data; if (monitor->proc_net_dev != NULL) { rewind (monitor->proc_net_dev); /* Parse the line matching the interface ('eth0') */ while (!feof (monitor->proc_net_dev)) { if (NULL == fgets (line, MAX_PROC_LINE, monitor->proc_net_dev)) break; for (i = 0; i < monitor->ifcsSize; i++) { ifc = &monitor->ifcs[i]; if (NULL != strstr (line, ifc->name)) { data = strchr (line, ':'); if (data == NULL) continue; data++; if (2 != SSCANF (data, "%llu %*s %*s %*s %*s %*s %*s %*s %llu", &rxnew, &txnew)) { GNUNET_GE_LOG (monitor->ectx, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_BULK, _ ("Failed to parse interface data from `%s'.\n"), PROC_NET_DEV); continue; } ifc->last_in = rxnew; ifc->last_out = txnew; monitor->globalTrafficBetweenProc.last_in = 0; monitor->globalTrafficBetweenProc.last_out = 0; break; } } } }#elif OSX int name[6]; size_t len; int rows; int j; int i; NetworkStats *ifc; name[0] = CTL_NET; name[1] = PF_LINK; name[2] = NETLINK_GENERIC; name[3] = IFMIB_SYSTEM; name[4] = IFMIB_IFCOUNT; len = sizeof (rows); if (sysctl (name, 5, &rows, &len, (void *) 0, 0) == 0) { for (j = 1; j <= rows; j++) { struct ifmibdata ifmd; name[0] = CTL_NET; name[1] = PF_LINK; name[2] = NETLINK_GENERIC; name[3] = IFMIB_IFDATA; name[4] = j; name[5] = IFDATA_GENERAL; len = sizeof (ifmd); if (sysctl (name, 6, &ifmd, &len, (void *) 0, 0) != 0) { if (errno == ENOENT) continue; else { GNUNET_GE_LOG_STRERROR (monitor->ectx, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_BULK, "sysctl"); break; } } for (i = 0; i < monitor->ifcsSize; i++) { ifc = &monitor->ifcs[i]; if (strcmp (ifc->name, ifmd.ifmd_name) == 0) { ifc->last_in = ifmd.ifmd_data.ifi_ibytes; ifc->last_out = ifmd.ifmd_data.ifi_obytes; monitor->globalTrafficBetweenProc.last_in = 0; monitor->globalTrafficBetweenProc.last_out = 0; break; } } } } else { GNUNET_GE_LOG_STRERROR (monitor->ectx, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_BULK, "sysctl"); }#elif MINGW NetworkStats *ifc; PMIB_IFTABLE pTable; DWORD dwIfIdx; unsigned long long l; BYTE bPhysAddr[MAXLEN_PHYSADDR]; int iLine = 0; FILE *command; unsigned long long rxnew; unsigned long long txnew; int i; char line[MAX_PROC_LINE]; /* Win 98 and NT SP 4 */ if (GNGetIfEntry) { EnumNICs (&pTable, NULL); for (i = 0; i < monitor->ifcsSize; i++) { ifc = &monitor->ifcs[i]; for (dwIfIdx = 0; dwIfIdx < pTable->dwNumEntries; dwIfIdx++) { l = _atoi64 (ifc->name); memset (bPhysAddr, 0, MAXLEN_PHYSADDR); memcpy (bPhysAddr, pTable->table[dwIfIdx].bPhysAddr, pTable->table[dwIfIdx].dwPhysAddrLen); if (0 == memcmp (bPhysAddr, &l, sizeof (unsigned long long))) { ifc->last_in = pTable->table[dwIfIdx].dwInOctets; ifc->last_out = pTable->table[dwIfIdx].dwOutOctets; monitor->globalTrafficBetweenProc.last_in = 0; monitor->globalTrafficBetweenProc.last_out = 0; break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -