ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/network_stats.c
Revision: 1.8
Committed: Tue Mar 11 16:16:20 2003 UTC (21 years, 2 months ago) by pajs
Content type: text/plain
Branch: MAIN
CVS Tags: LIBSTATGRAB_0_3_1
Changes since 1.7: +17 -0 lines
Log Message:
Ok, wrap around fixed for 32bit machines, not 64. I really ought to change
all the long long's to ulong long's. I'll ponder if i can be bothered :)

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 #ifdef SOL7
111 #define RLOOKUP "rbytes"
112 #define WLOOKUP "obytes"
113 #define VALTYPE value.ui32
114 #else
115 #define RLOOKUP "rbytes64"
116 #define WLOOKUP "obytes64"
117 #define VALTYPE value.ui64
118 #endif
119
120 if((knp=kstat_data_lookup(ksp, RLOOKUP))==NULL){
121 /* Not a network interface, so skip to the next entry */
122 continue;
123 }
124
125 network_stats=network_stat_malloc((interfaces+1), &sizeof_network_stats, network_stats);
126 if(network_stats==NULL){
127 return NULL;
128 }
129 network_stat_ptr=network_stats+interfaces;
130 network_stat_ptr->rx=knp->VALTYPE;
131
132 if((knp=kstat_data_lookup(ksp, WLOOKUP))==NULL){
133 /* Not a network interface, so skip to the next entry */
134 continue;
135 }
136 network_stat_ptr->tx=knp->VALTYPE;
137 if(network_stat_ptr->interface_name!=NULL){
138 free(network_stat_ptr->interface_name);
139 }
140 network_stat_ptr->interface_name=strdup(ksp->ks_name);
141
142 network_stat_ptr->systime=time(NULL);
143 interfaces++;
144 }
145 }
146
147 kstat_close(kc);
148 #endif
149 #ifdef LINUX
150 f=fopen("/proc/net/dev", "r");
151 if(f==NULL){
152 return NULL;
153 }
154 /* read the 2 lines.. Its the title, so we dont care :) */
155 fgets(line, sizeof(line), f);
156 fgets(line, sizeof(line), f);
157
158
159 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){
160 return NULL;
161 }
162
163 interfaces=0;
164
165 while((fgets(line, sizeof(line), f)) != NULL){
166 if((regexec(&regex, line, 4, line_match, 0))!=0){
167 continue;
168 }
169 network_stats=network_stat_malloc((interfaces+1), &sizeof_network_stats, network_stats);
170 if(network_stats==NULL){
171 return NULL;
172 }
173 network_stat_ptr=network_stats+interfaces;
174
175 if(network_stat_ptr->interface_name!=NULL){
176 free(network_stat_ptr->interface_name);
177 }
178
179 network_stat_ptr->interface_name=get_string_match(line, &line_match[1]);
180 network_stat_ptr->rx=get_ll_match(line, &line_match[2]);
181 network_stat_ptr->tx=get_ll_match(line, &line_match[3]);
182 network_stat_ptr->systime=time(NULL);
183
184 interfaces++;
185 }
186
187 #endif
188 *entries=interfaces;
189
190 return network_stats;
191 }
192
193 long long transfer_diff(long long new, long long old){
194 #ifdef SOL7
195 #define MAXVAL 4294967296
196 #else
197 #define MAXVAL 18446744073709551616
198 #endif
199 long long result;
200 if(new>old){
201 result = (new-old);
202 }else{
203 result = (MAXVAL+(new-old));
204 }
205
206 return result;
207
208 }
209
210 network_stat_t *get_network_stats_diff(int *entries){
211 static network_stat_t *network_stats_diff=NULL;
212 static int sizeof_net_stats_diff=0;
213 network_stat_t *network_stats_ptr, *network_stats_diff_ptr;
214 int ifaces, x, y;
215
216 if(network_stats==NULL){
217 network_stats_ptr=get_network_stats(&ifaces);
218 *entries=ifaces;
219 return network_stats_ptr;
220 }
221
222 network_stats_diff=network_stat_malloc(interfaces, &sizeof_net_stats_diff, network_stats_diff);
223 if(network_stats_diff==NULL){
224 return NULL;
225 }
226
227 network_stats_ptr=network_stats;
228 network_stats_diff_ptr=network_stats_diff;
229
230 for(ifaces=0;ifaces<interfaces;ifaces++){
231 if(network_stats_diff_ptr->interface_name!=NULL){
232 free(network_stats_diff_ptr->interface_name);
233 }
234 network_stats_diff_ptr->interface_name=strdup(network_stats_ptr->interface_name);
235 network_stats_diff_ptr->tx=network_stats_ptr->tx;
236 network_stats_diff_ptr->rx=network_stats_ptr->rx;
237 network_stats_diff_ptr->systime=network_stats->systime;
238
239 network_stats_ptr++;
240 network_stats_diff_ptr++;
241 }
242 network_stats_ptr=get_network_stats(&ifaces);
243 network_stats_diff_ptr=network_stats_diff;
244
245 for(x=0;x<sizeof_net_stats_diff;x++){
246
247 if((strcmp(network_stats_diff_ptr->interface_name, network_stats_ptr->interface_name))==0){
248 network_stats_diff_ptr->tx = network_stats_ptr->tx - network_stats_diff_ptr->tx;
249 network_stats_diff_ptr->rx = network_stats_ptr->rx - network_stats_diff_ptr->rx;
250 network_stats_diff_ptr->systime = network_stats_ptr->systime - network_stats_diff_ptr->systime;
251 }else{
252
253 network_stats_ptr=network_stats;
254 for(y=0;y<ifaces;y++){
255 if((strcmp(network_stats_diff_ptr->interface_name, network_stats_ptr->interface_name))==0){
256 network_stats_diff_ptr->tx = network_stats_ptr->tx - network_stats_diff_ptr->tx;
257 network_stats_diff_ptr->rx = network_stats_ptr->rx - network_stats_diff_ptr->rx;
258 network_stats_diff_ptr->systime = network_stats_ptr->systime - network_stats_diff_ptr->systime;
259 break;
260 }
261
262 network_stats_ptr++;
263 }
264 }
265
266 network_stats_ptr++;
267 network_stats_diff_ptr++;
268 }
269
270 *entries=sizeof_net_stats_diff;
271 return network_stats_diff;
272 }
273