summaryrefslogtreecommitdiff
path: root/netload/linux-proc.c
blob: 4a0dc34b2bba6962be0353f06d372c9a7d7790bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <glib.h>

#include "linux-proc.h"
#include "netload.h"

#include <config.h>

/* Make sure we have a recent version of LibGTop. */
#if (defined LIBGTOP_VERSION_CODE) && (LIBGTOP_VERSION_CODE >= 26005)
#define NETLOAD_LIBGTOP 1
#else
#ifdef __FreeBSD__
#warning "You need LibGTop >= 0.26.5 to make this work on your system."
#endif
#endif

#ifdef NETLOAD_LIBGTOP

#include <glibtop.h>
#include <glibtop/netload.h>

#define REQUIRED_NETLOAD_FLAGS (1 << GLIBTOP_NETLOAD_BYTES_TOTAL)

#endif /* NETLOAD_LIBGTOP */

static char *skip_token(const char *p)
{
	while (isspace(*p)) p++;
        while (*p && !isspace(*p)) p++;
        	return (char *)p;
}  

/*
 * Return a -1-terminated array structures containing the name & byte counts.
 */

Device_Info *ReadProc()
{
	Device_Info	*retval = NULL;
	int	devs = 0;
	char	buffer[256];
	static FILE	*fp = NULL;

	if (!fp){
		/* Read /proc/net/ip_acct. */
		if (!(fp = fopen("/proc/net/ip_acct", "r"))){
			error_dialog("Failed to open the /proc/net/ip_acct file. Please ensure IP accounting is enabled in this kernel.", 1);
			return NULL;
		}
	}

	fseek(fp, 0, 0);
	retval = (Device_Info *)g_malloc(sizeof(Device_Info));
	/* Skip the header line. */
	fgets(buffer, 255, fp);

	while (fgets(buffer, 255, fp)){
		char	*p;
		retval = (Device_Info *)g_realloc(retval, (sizeof(Device_Info) * (++devs + 1)));

		/* Skip over the network thing. */		
		p = skip_token(buffer) + 1;
		strncpy(retval[devs - 1].name, p, 5);
		retval[devs - 1].name[5] = 0;
		retval[devs - 1].bytes = strtoul(buffer + 64, &p, 10);
#if 0
		printf("%d: %s - %ld\n", devs, retval[devs - 1].name, retval[devs - 1].bytes);
#endif
	}

	retval[devs].name[0] = 0;

	return retval;
}	

/*
 * Return the byte count for a single device. Cache the result from reading the /proc file.
 * refresh = 1 means reload the /proc file.
 */
unsigned long int
GetTraffic(int refresh, char *device)
{
#ifdef NETLOAD_LIBGTOP
	glibtop_netload netload;

	glibtop_get_netload (&netload, device);
	return netload.bytes_total;
#else
	static	Device_Info	*di = NULL;
	Device_Info	*d;
	static	error_printed = 0;

	if (refresh || !di){
		if (di)
			free(di);
		di = ReadProc();
	}

	d = di;
	while (d && d->name[0] != 0){
		if (!strcmp(device, d->name)){
			return d->bytes;
		}
		d++;
	}
	error_printed = 1;
	error_dialog("IP accounting is enabled, but not activated for the specified device. Either activate it (with a command like \nipfwadm -A -i -P all -W <device name>\nwhere device name is something like ppp0 or eth0.\nAlso check that the device properties are set properly.", 0);
	return 0;
#endif
}