File: linux.c

package info (click to toggle)
xfce4-netload-plugin 1.4.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,656 kB
  • sloc: sh: 4,348; ansic: 2,598; makefile: 111
file content (138 lines) | stat: -rw-r--r-- 3,864 bytes parent folder | download | duplicates (7)
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "linux.h"

/*****************************************************************************
 *
 * init_osspecific()
 *
 * Init function
 *
 ****************************************************************************/

void init_osspecific(netdata* data)
{
#ifdef DEBUG
    fprintf( stderr, "The netload plugin was initialized for Linux.\n" );
#endif
}


/*****************************************************************************
 *
 * checkinterface()
 *
 * check if a given interface exists and is up.
 * return TRUE if found, FALSE if not
 *
 ****************************************************************************/

int checkinterface(netdata* data)
{
	int interfacefound = FALSE;
	unsigned int i;
	struct if_nameindex *ifs;

#ifdef DEBUG
    fprintf( stderr, "Checking the interface '%s' now ...\n", data->ifdata.if_name );
#endif

    
	if ((ifs = if_nameindex()) == NULL)
		return FALSE;

	for (i = 0; ifs[i].if_index; i++)
	{
		if (strcmp(ifs[i].if_name, data->ifdata.if_name) == 0)
		{
			interfacefound = TRUE;
			break;
		}
	}
    
    /* free the nameindex structure */
    if_freenameindex(ifs);
    
    /* check if the /proc/net/dev exists */
    if (access(PATH_NET_DEV, R_OK) != 0)
    {
        data->errorcode = PROC_DEVICE_NOT_FOUND;
        return FALSE;
    }

	return interfacefound;
}

/******************************************************************************
 *
 * get_stat()
 *
 * read the network statistics from /proc/net/dev (PATH_NET_DEV)
 * if the file is not open open it. fseek() to the beginning and parse
 * each line until we've found the right interface
 *
 * returns 0 if successful, 1 in case of error
 *
 *****************************************************************************/

int get_stat(netdata* data)
{
    /* bwalle: Instead of the original code we open the file each time new. The
     * performance difference is _very_ minimal. But I don't think that it's a good
     * idea to keep the file open for a very long time for _each_ plugin instance.
     */
    char buffer[BUFSIZE];
    char *ptr;
    char *devname;
    int dump;
    int interfacefound;
    FILE* proc_net_dev;
    unsigned long rx_o, tx_o;

    if ((proc_net_dev = fopen(PATH_NET_DEV, "r")) == NULL)
    {
        fprintf(stderr, "cannot open %s!\nnot running Linux?\n",
            PATH_NET_DEV);
        return 1;
    }

    /* backup old rx/tx values */
    rx_o = data->stats.rx_bytes; tx_o = data->stats.tx_bytes;

    /* do not parse the first two lines as they only contain static garbage */
    fseek(proc_net_dev, 0, SEEK_SET);
    fgets(buffer, BUFSIZE-1, proc_net_dev);
    fgets(buffer, BUFSIZE-1, proc_net_dev);

    interfacefound = 0;
    while (fgets(buffer, BUFSIZE-1, proc_net_dev) != NULL)
    {
        /* find the device name and substitute ':' with '\0' */
        ptr = buffer;
        while (*ptr == ' ')
            ptr++;
        devname = ptr;
        while (*ptr != ':')
            ptr++;
        *ptr = '\0';
        ptr++;
        if (!strcmp(devname, (char *) data->ifdata.if_name))
        {
            /* read stats and fill struct */
            sscanf(ptr, "%lg %lu %lu %d %d %d %d %d %lg %lu %lu %d %d %d %d %d",
                &(data->stats.rx_bytes), &(data->stats.rx_packets), &(data->stats.rx_errors),
                &dump, &dump, &dump, &dump, &dump,
                &(data->stats.tx_bytes), &(data->stats.tx_packets), &(data->stats.tx_errors),
                &dump, &dump, &dump, &dump, &dump);
            interfacefound = 1;
            continue; /* break, as we won't get any new information */
        }
    }
    fclose( proc_net_dev );
    if (interfacefound)
    {
        if (rx_o > data->stats.rx_bytes)
            data->stats.rx_over++;
        if (tx_o > data->stats.tx_bytes)
            data->stats.tx_over++;
    }
    return (interfacefound == 1)? 0 : 1;
}