ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/network_stats.c
(Generate patch)

Comparing projects/libstatgrab/src/libstatgrab/network_stats.c (file contents):
Revision 1.2 by pajs, Tue Feb 18 23:23:36 2003 UTC vs.
Revision 1.14 by pajs, Sun Apr 6 00:27:19 2003 UTC

# Line 22 | Line 22
22   #include "config.h"
23   #endif
24  
25 #include <stdio.h>
26 #include "statgrab.h"
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>
31 #include <string.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 + #ifdef FREEBSD
40 + #include <sys/types.h>
41 + #include <sys/socket.h>
42 + #include <ifaddrs.h>
43 + #include <net/if.h>
44 + #endif
45  
46 < #define START_VAL 1
46 > static network_stat_t *network_stats=NULL;
47 > static int interfaces=0;
48  
49 < network_stat_t *network_stat_init(int num_iface, int *wmark, network_stat_t *net_stats){
37 <        int x;
38 <        network_stat_t *net_stats_ptr;
49 > void network_stat_init(int start, int end, network_stat_t *net_stats){
50  
51 <        if(*wmark==-1){
52 <                printf("new malloc\n");
53 <                if((net_stats=malloc(START_VAL * sizeof(network_stat_t)))==NULL){
51 >        for(net_stats+=start; start<end; start++){
52 >                net_stats->interface_name=NULL;
53 >                net_stats->tx=0;
54 >                net_stats->rx=0;
55 >                net_stats++;
56 >        }
57 > }
58 >
59 > network_stat_t *network_stat_malloc(int needed_entries, int *cur_entries, network_stat_t *net_stats){
60 >
61 >        if(net_stats==NULL){
62 >
63 >                if((net_stats=malloc(needed_entries * sizeof(network_stat_t)))==NULL){
64                          return NULL;
65                  }
66 <                *wmark=START_VAL;
67 <                net_stats_ptr=net_stats;
68 <                for(x=0;x<(*wmark);x++){
48 <                        net_stats_ptr->interface_name=NULL;
49 <                        net_stats_ptr++;
50 <                }
66 >                network_stat_init(0, needed_entries, net_stats);
67 >                *cur_entries=needed_entries;
68 >
69                  return net_stats;
70          }
71 <        if(num_iface>(*wmark-1)){
72 <                if((net_stats=realloc(net_stats, (*wmark)*2 * sizeof(network_stat_t)))==NULL){
71 >
72 >
73 >        if(*cur_entries<needed_entries){
74 >                net_stats=realloc(net_stats, (sizeof(network_stat_t)*needed_entries));
75 >                if(net_stats==NULL){
76                          return NULL;
77                  }
78 <
79 <                *wmark=(*wmark)*2;
59 <                net_stats_ptr=net_stats+num_iface;
60 <                for(x=num_iface;x<(*wmark);x++){
61 <                        net_stats_ptr->interface_name=NULL;
62 <                        net_stats_ptr++;
63 <                }
64 <                return net_stats;
78 >                network_stat_init(*cur_entries, needed_entries, net_stats);
79 >                *cur_entries=needed_entries;
80          }
81  
82          return net_stats;
83   }
84  
85 +
86   network_stat_t *get_network_stats(int *entries){
87 +
88 +        static int sizeof_network_stats=0;      
89 +        network_stat_t *network_stat_ptr;
90 +
91 + #ifdef SOLARIS
92          kstat_ctl_t *kc;
93          kstat_t *ksp;
94          kstat_named_t *knp;
95 + #endif
96 +
97 + #ifdef LINUX
98 +        FILE *f;
99 +        /* Horrible big enough, but it should be easily big enough */
100 +        char line[8096];
101 +        regex_t regex;
102 +        regmatch_t line_match[4];
103 + #endif
104 + #ifdef FREEBSD
105 +        struct ifaddrs *net, *net_ptr;
106 +        struct if_data *net_data;
107 + #endif
108 +
109 + #ifdef FREEBSD
110 +        if(getifaddrs(&net) != 0){
111 +                return NULL;
112 +        }
113 +
114 +        interfaces=0;
115          
116 <        int interfaces=0;      
117 <        network_stat_t *network_stat_ptr;
118 <        static network_stat_t *network_stats=NULL;
119 <        static int watermark=-1;
116 >        for(net_ptr=net;net_ptr!=NULL;net_ptr=net_ptr->ifa_next){
117 >                if(net_ptr->ifa_addr->sa_family != AF_LINK) continue;
118 >                network_stats=network_stat_malloc((interfaces+1), &sizeof_network_stats, network_stats);
119 >                if(network_stats==NULL){
120 >                        return NULL;
121 >                }
122 >                network_stat_ptr=network_stats+interfaces;
123 >                
124 >                if(network_stat_ptr->interface_name!=NULL) free(network_stat_ptr->interface_name);
125 >                network_stat_ptr->interface_name=strdup(net_ptr->ifa_name);
126 >                if(network_stat_ptr->interface_name==NULL) return NULL;
127 >                net_data=(struct if_data *)net_ptr->ifa_data;
128 >                network_stat_ptr->rx=net_data->ifi_ibytes;
129 >                network_stat_ptr->tx=net_data->ifi_obytes;                      
130 >                network_stat_ptr->systime=time(NULL);
131 >                interfaces++;
132 >        }
133 >        freeifaddrs(net);      
134 > #endif
135  
136 + #ifdef SOLARIS
137          if ((kc = kstat_open()) == NULL) {
138                  return NULL;
139          }
140  
141 +        interfaces=0;
142 +
143          for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
144                  if (!strcmp(ksp->ks_class, "net")) {
145                          kstat_read(kc, ksp, NULL);
146  
147 <                        if((knp=kstat_data_lookup(ksp, "rbytes64"))==NULL){
147 > #ifdef SOL7
148 > #define RLOOKUP "rbytes"
149 > #define WLOOKUP "obytes"
150 > #define VALTYPE value.ui32
151 > #else
152 > #define RLOOKUP "rbytes64"
153 > #define WLOOKUP "obytes64"
154 > #define VALTYPE value.ui64
155 > #endif
156 >
157 >                        if((knp=kstat_data_lookup(ksp, RLOOKUP))==NULL){
158                                  /* Not a network interface, so skip to the next entry */
159                                  continue;
160                          }
161 <                        network_stats=network_stat_init(interfaces, &watermark, network_stats);
161 >
162 >                        network_stats=network_stat_malloc((interfaces+1), &sizeof_network_stats, network_stats);
163                          if(network_stats==NULL){
164                                  return NULL;
165                          }
166                          network_stat_ptr=network_stats+interfaces;
167 <                        network_stat_ptr->rx=knp->value.ui64;
167 >                        network_stat_ptr->rx=knp->VALTYPE;
168  
169 <                        if((knp=kstat_data_lookup(ksp, "obytes64"))==NULL){
169 >                        if((knp=kstat_data_lookup(ksp, WLOOKUP))==NULL){
170                                  /* Not a network interface, so skip to the next entry */
171                                  continue;
172                          }
173 <                        network_stat_ptr->tx=knp->value.ui64;
173 >                        network_stat_ptr->tx=knp->VALTYPE;
174                          if(network_stat_ptr->interface_name!=NULL){
175                                  free(network_stat_ptr->interface_name);
176                          }
177                          network_stat_ptr->interface_name=strdup(ksp->ks_name);
178 +
179 +                        network_stat_ptr->systime=time(NULL);
180                          interfaces++;
181                  }
182          }
183                  
184          kstat_close(kc);        
185 + #endif
186 + #ifdef LINUX
187 +        f=fopen("/proc/net/dev", "r");
188 +        if(f==NULL){
189 +                return NULL;
190 +        }
191 +        /* read the 2 lines.. Its the title, so we dont care :) */
192 +        fgets(line, sizeof(line), f);
193 +        fgets(line, sizeof(line), f);
194  
195 +
196 +        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){
197 +                return NULL;
198 +        }
199 +
200 +        interfaces=0;
201 +
202 +        while((fgets(line, sizeof(line), f)) != NULL){
203 +                if((regexec(&regex, line, 4, line_match, 0))!=0){
204 +                        continue;
205 +                }
206 +                network_stats=network_stat_malloc((interfaces+1), &sizeof_network_stats, network_stats);
207 +                if(network_stats==NULL){
208 +                        return NULL;
209 +                }
210 +                network_stat_ptr=network_stats+interfaces;
211 +
212 +                if(network_stat_ptr->interface_name!=NULL){
213 +                        free(network_stat_ptr->interface_name);
214 +                }
215 +
216 +                network_stat_ptr->interface_name=get_string_match(line, &line_match[1]);
217 +                network_stat_ptr->rx=get_ll_match(line, &line_match[2]);
218 +                network_stat_ptr->tx=get_ll_match(line, &line_match[3]);
219 +                network_stat_ptr->systime=time(NULL);
220 +
221 +                interfaces++;
222 +        }
223 +        fclose(f);
224 +        regfree(&regex);
225 +
226 + #endif
227          *entries=interfaces;
228  
229          return network_stats;  
230 + }
231  
232 + long long transfer_diff(long long new, long long old){
233 + #ifdef SOL7
234 + #define MAXVAL 4294967296
235 + #else
236 + #define MAXVAL 18446744073709551616
237 + #endif
238 +        long long result;
239 +        if(new>=old){
240 +                result = (new-old);
241 +        }else{
242 +                result = (MAXVAL+(new-old));
243 +        }
244 +
245 +        return result;
246 +
247   }
248 +
249 + network_stat_t *get_network_stats_diff(int *entries){
250 +        static network_stat_t *network_stats_diff=NULL;
251 +        static int sizeof_net_stats_diff=0;
252 +        network_stat_t *network_stats_ptr, *network_stats_diff_ptr;
253 +        int ifaces, x, y;
254 +
255 +        if(network_stats==NULL){
256 +                network_stats_ptr=get_network_stats(&ifaces);
257 +                *entries=ifaces;
258 +                return network_stats_ptr;
259 +        }
260 +
261 +        network_stats_diff=network_stat_malloc(interfaces, &sizeof_net_stats_diff, network_stats_diff);
262 +        if(network_stats_diff==NULL){
263 +                return NULL;
264 +        }
265 +
266 +        network_stats_ptr=network_stats;
267 +        network_stats_diff_ptr=network_stats_diff;
268 +
269 +        for(ifaces=0;ifaces<interfaces;ifaces++){
270 +                if(network_stats_diff_ptr->interface_name!=NULL){
271 +                        free(network_stats_diff_ptr->interface_name);
272 +                }
273 +                network_stats_diff_ptr->interface_name=strdup(network_stats_ptr->interface_name);
274 +                network_stats_diff_ptr->tx=network_stats_ptr->tx;
275 +                network_stats_diff_ptr->rx=network_stats_ptr->rx;
276 +                network_stats_diff_ptr->systime=network_stats->systime;
277 +
278 +                network_stats_ptr++;
279 +                network_stats_diff_ptr++;
280 +        }
281 +        network_stats_ptr=get_network_stats(&ifaces);          
282 +        network_stats_diff_ptr=network_stats_diff;
283 +
284 +        for(x=0;x<sizeof_net_stats_diff;x++){
285 +
286 +                if((strcmp(network_stats_diff_ptr->interface_name, network_stats_ptr->interface_name))==0){
287 +                        network_stats_diff_ptr->tx = transfer_diff(network_stats_ptr->tx, network_stats_diff_ptr->tx);
288 +                        network_stats_diff_ptr->rx = transfer_diff(network_stats_ptr->rx, network_stats_diff_ptr->rx);
289 +                        network_stats_diff_ptr->systime = network_stats_ptr->systime - network_stats_diff_ptr->systime;
290 +                }else{
291 +                        
292 +                        network_stats_ptr=network_stats;
293 +                        for(y=0;y<ifaces;y++){
294 +                                if((strcmp(network_stats_diff_ptr->interface_name, network_stats_ptr->interface_name))==0){
295 +                                        network_stats_diff_ptr->tx = transfer_diff(network_stats_ptr->tx, network_stats_diff_ptr->tx);
296 +                                        network_stats_diff_ptr->rx = transfer_diff(network_stats_ptr->rx, network_stats_diff_ptr->rx);  
297 +                                        network_stats_diff_ptr->systime = network_stats_ptr->systime - network_stats_diff_ptr->systime;
298 +                                        break;
299 +                                }
300 +
301 +                                network_stats_ptr++;
302 +                        }      
303 +                }
304 +
305 +                network_stats_ptr++;
306 +                network_stats_diff_ptr++;
307 +        }
308 +
309 +        *entries=sizeof_net_stats_diff;
310 +        return network_stats_diff;
311 + }      
312  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines