ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/network_stats.c
Revision: 1.6
Committed: Fri Mar 7 11:56:44 2003 UTC (21 years, 2 months ago) by pajs
Content type: text/plain
Branch: MAIN
CVS Tags: LIBSTATGRAB_0_3
Changes since 1.5: +62 -6 lines
Log Message:
Made network stats work with linux.

File Contents

# Content
1 /*
2 * i-scream central monitoring system
3 * http://www.i-scream.org.uk
4 * Copyright (C) 2000-2002 i-scream
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include "statgrab.h"
28 #include "time.h"
29 #ifdef SOLARIS
30 #include <kstat.h>
31 #include <sys/sysinfo.h>
32 #endif
33 #ifdef LINUX
34 #include <stdio.h>
35 #include <sys/types.h>
36 #include <regex.h>
37 #include "tools.h"
38 #endif
39
40 static network_stat_t *network_stats=NULL;
41 static int interfaces=0;
42
43 void network_stat_init(int start, int end, network_stat_t *net_stats){
44
45 for(net_stats+=start; start<end; start++){
46 net_stats->interface_name=NULL;
47 net_stats->tx=0;
48 net_stats->rx=0;
49 net_stats++;
50 }
51 }
52
53 network_stat_t *network_stat_malloc(int needed_entries, int *cur_entries, network_stat_t *net_stats){
54
55 if(net_stats==NULL){
56
57 if((net_stats=malloc(needed_entries * sizeof(network_stat_t)))==NULL){
58 return NULL;
59 }
60 network_stat_init(0, needed_entries, net_stats);
61 *cur_entries=needed_entries;
62
63 return net_stats;
64 }
65
66
67 if(*cur_entries<needed_entries){
68 net_stats=realloc(net_stats, (sizeof(network_stat_t)*needed_entries));
69 if(net_stats==NULL){
70 return NULL;
71 }
72 network_stat_init(*cur_entries, needed_entries, net_stats);
73 *cur_entries=needed_entries;
74 }
75
76 return net_stats;
77 }
78
79
80 network_stat_t *get_network_stats(int *entries){
81
82 static int sizeof_network_stats=0;
83 network_stat_t *network_stat_ptr;
84
85 #ifdef SOLARIS
86 kstat_ctl_t *kc;
87 kstat_t *ksp;
88 kstat_named_t *knp;
89 #endif
90
91 #ifdef LINUX
92 FILE *f;
93 /* Horrible big enough, but it should be quite easily */
94 char line[8096];
95 regex_t regex;
96 regmatch_t line_match[4];
97 #endif
98
99 #ifdef SOLARIS
100 if ((kc = kstat_open()) == NULL) {
101 return NULL;
102 }
103
104 interfaces=0;
105
106 for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
107 if (!strcmp(ksp->ks_class, "net")) {
108 kstat_read(kc, ksp, NULL);
109
110 if((knp=kstat_data_lookup(ksp, "rbytes64"))==NULL){
111 /* Not a network interface, so skip to the next entry */
112 continue;
113 }
114
115 network_stats=network_stat_malloc((interfaces+1), &sizeof_network_stats, network_stats);
116 if(network_stats==NULL){
117 return NULL;
118 }
119 network_stat_ptr=network_stats+interfaces;
120 network_stat_ptr->rx=knp->value.ui64;
121
122 if((knp=kstat_data_lookup(ksp, "obytes64"))==NULL){
123 /* Not a network interface, so skip to the next entry */
124 continue;
125 }
126 network_stat_ptr->tx=knp->value.ui64;
127 if(network_stat_ptr->interface_name!=NULL){
128 free(network_stat_ptr->interface_name);
129 }
130 network_stat_ptr->interface_name=strdup(ksp->ks_name);
131
132 network_stat_ptr->systime=time(NULL);
133 interfaces++;
134 }
135 }
136
137 kstat_close(kc);
138 #endif
139 #ifdef LINUX
140 f=fopen("/proc/net/dev", "r");
141 if(f==NULL){
142 return NULL;
143 }
144 /* read the 2 lines.. Its the title, so we dont care :) */
145 fgets(line, sizeof(line), f);
146 fgets(line, sizeof(line), f);
147
148
149 if((regcomp(&regex, "^[[:space:]]*([^:]+):[[:space:]]*([[:digit:]]+)[[:space:]]+[[:digit:]]+[[:space:]]+[[:digit:]]+[[:space:]]+[[:digit:]]+[[:space:]]+[[:digit:]]+[[:space:]]+[[:digit:]]+[[:space:]]+[[:digit:]]+[[:space:]]+[[:digit:]]+[[:space:]]+([[:digit:]]+)", REG_EXTENDED))!=0){
150 return NULL;
151 }
152
153 interfaces=0;
154
155 while((fgets(line, sizeof(line), f)) != NULL){
156 if((regexec(&regex, line, 4, line_match, 0))!=0){
157 continue;
158 }
159 network_stats=network_stat_malloc((interfaces+1), &sizeof_network_stats, network_stats);
160 if(network_stats==NULL){
161 return NULL;
162 }
163 network_stat_ptr=network_stats+interfaces;
164
165 if(network_stat_ptr->interface_name!=NULL){
166 free(network_stat_ptr->interface_name);
167 }
168
169 network_stat_ptr->interface_name=get_string_match(line, &line_match[1]);
170 network_stat_ptr->rx=get_ll_match(line, &line_match[2]);
171 network_stat_ptr->tx=get_ll_match(line, &line_match[3]);
172 network_stat_ptr->systime=time(NULL);
173
174 interfaces++;
175 }
176
177 #endif
178 *entries=interfaces;
179
180 return network_stats;
181 }
182
183 network_stat_t *get_network_stats_diff(int *entries){
184 static network_stat_t *network_stats_diff=NULL;
185 static int sizeof_net_stats_diff=0;
186 network_stat_t *network_stats_ptr, *network_stats_diff_ptr;
187 int ifaces, x, y;
188
189 if(network_stats==NULL){
190 network_stats_ptr=get_network_stats(&ifaces);
191 *entries=ifaces;
192 return network_stats_ptr;
193 }
194
195 network_stats_diff=network_stat_malloc(interfaces, &sizeof_net_stats_diff, network_stats_diff);
196 if(network_stats_diff==NULL){
197 return NULL;
198 }
199
200 network_stats_ptr=network_stats;
201 network_stats_diff_ptr=network_stats_diff;
202
203 for(ifaces=0;ifaces<interfaces;ifaces++){
204 if(network_stats_diff_ptr->interface_name!=NULL){
205 free(network_stats_diff_ptr->interface_name);
206 }
207 network_stats_diff_ptr->interface_name=strdup(network_stats_ptr->interface_name);
208 network_stats_diff_ptr->tx=network_stats_ptr->tx;
209 network_stats_diff_ptr->rx=network_stats_ptr->rx;
210 network_stats_diff_ptr->systime=network_stats->systime;
211
212 network_stats_ptr++;
213 network_stats_diff_ptr++;
214 }
215 network_stats_ptr=get_network_stats(&ifaces);
216 network_stats_diff_ptr=network_stats_diff;
217
218 for(x=0;x<sizeof_net_stats_diff;x++){
219
220 if((strcmp(network_stats_diff_ptr->interface_name, network_stats_ptr->interface_name))==0){
221 network_stats_diff_ptr->tx = network_stats_ptr->tx - network_stats_diff_ptr->tx;
222 network_stats_diff_ptr->rx = network_stats_ptr->rx - network_stats_diff_ptr->rx;
223 network_stats_diff_ptr->systime = network_stats_ptr->systime - network_stats_diff_ptr->systime;
224 }else{
225
226 network_stats_ptr=network_stats;
227 for(y=0;y<ifaces;y++){
228 if((strcmp(network_stats_diff_ptr->interface_name, network_stats_ptr->interface_name))==0){
229 network_stats_diff_ptr->tx = network_stats_ptr->tx - network_stats_diff_ptr->tx;
230 network_stats_diff_ptr->rx = network_stats_ptr->rx - network_stats_diff_ptr->rx;
231 network_stats_diff_ptr->systime = network_stats_ptr->systime - network_stats_diff_ptr->systime;
232 break;
233 }
234
235 network_stats_ptr++;
236 }
237 }
238
239 network_stats_ptr++;
240 network_stats_diff_ptr++;
241 }
242
243 *entries=sizeof_net_stats_diff;
244 return network_stats_diff;
245 }
246