ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/network_stats.c
Revision: 1.7
Committed: Tue Mar 11 14:30:39 2003 UTC (21 years, 2 months ago) by pajs
Content type: text/plain
Branch: MAIN
Changes since 1.6: +14 -4 lines
Log Message:
Make network stats work on pre sol8.
BUGS: On pre sol8 systems, it doesn't cope with a wrap around once the
32bit uint becomes too big. So when this happens it will report one set
of dodgy data, then continue. This bug technically is there in the 64bit
version too, but it will need to of sent 9223372036854775808 bytes first.
(8388608 terrabytes, so basically a *big enough* number that will come around
and byte me in 20 years time or something ;) )

File Contents

# User Rev Content
1 pajs 1.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 tdb 1.4 #include <stdlib.h>
26 pajs 1.6 #include <string.h>
27 pajs 1.1 #include "statgrab.h"
28 pajs 1.6 #include "time.h"
29 pajs 1.1 #ifdef SOLARIS
30     #include <kstat.h>
31     #include <sys/sysinfo.h>
32 pajs 1.6 #endif
33     #ifdef LINUX
34     #include <stdio.h>
35     #include <sys/types.h>
36     #include <regex.h>
37     #include "tools.h"
38 pajs 1.1 #endif
39    
40 pajs 1.3 static network_stat_t *network_stats=NULL;
41     static int interfaces=0;
42 pajs 1.1
43 pajs 1.3 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 pajs 1.1 return NULL;
59     }
60 pajs 1.3 network_stat_init(0, needed_entries, net_stats);
61     *cur_entries=needed_entries;
62    
63 pajs 1.1 return net_stats;
64     }
65 pajs 1.3
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 pajs 1.1 return NULL;
71     }
72 pajs 1.3 network_stat_init(*cur_entries, needed_entries, net_stats);
73     *cur_entries=needed_entries;
74 pajs 1.1 }
75    
76     return net_stats;
77     }
78    
79 pajs 1.3
80 pajs 1.1 network_stat_t *get_network_stats(int *entries){
81 pajs 1.6
82     static int sizeof_network_stats=0;
83     network_stat_t *network_stat_ptr;
84    
85     #ifdef SOLARIS
86 pajs 1.1 kstat_ctl_t *kc;
87     kstat_t *ksp;
88     kstat_named_t *knp;
89 pajs 1.6 #endif
90 pajs 1.3
91 pajs 1.6 #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 pajs 1.1
99 pajs 1.6 #ifdef SOLARIS
100 pajs 1.1 if ((kc = kstat_open()) == NULL) {
101     return NULL;
102     }
103    
104 pajs 1.6 interfaces=0;
105 pajs 1.3
106 pajs 1.1 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 pajs 1.7 #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 pajs 1.1 /* Not a network interface, so skip to the next entry */
122     continue;
123     }
124 pajs 1.3
125     network_stats=network_stat_malloc((interfaces+1), &sizeof_network_stats, network_stats);
126 pajs 1.1 if(network_stats==NULL){
127     return NULL;
128     }
129     network_stat_ptr=network_stats+interfaces;
130 pajs 1.7 network_stat_ptr->rx=knp->VALTYPE;
131 pajs 1.1
132 pajs 1.7 if((knp=kstat_data_lookup(ksp, WLOOKUP))==NULL){
133 pajs 1.1 /* Not a network interface, so skip to the next entry */
134     continue;
135     }
136 pajs 1.7 network_stat_ptr->tx=knp->VALTYPE;
137 pajs 1.1 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 pajs 1.3
142     network_stat_ptr->systime=time(NULL);
143 pajs 1.1 interfaces++;
144     }
145     }
146 pajs 1.2
147     kstat_close(kc);
148 pajs 1.6 #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 pajs 1.1
165 pajs 1.6 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 pajs 1.1 *entries=interfaces;
189    
190     return network_stats;
191 pajs 1.3 }
192    
193     network_stat_t *get_network_stats_diff(int *entries){
194     static network_stat_t *network_stats_diff=NULL;
195     static int sizeof_net_stats_diff=0;
196     network_stat_t *network_stats_ptr, *network_stats_diff_ptr;
197     int ifaces, x, y;
198    
199     if(network_stats==NULL){
200     network_stats_ptr=get_network_stats(&ifaces);
201     *entries=ifaces;
202     return network_stats_ptr;
203     }
204    
205     network_stats_diff=network_stat_malloc(interfaces, &sizeof_net_stats_diff, network_stats_diff);
206     if(network_stats_diff==NULL){
207     return NULL;
208     }
209    
210     network_stats_ptr=network_stats;
211     network_stats_diff_ptr=network_stats_diff;
212    
213     for(ifaces=0;ifaces<interfaces;ifaces++){
214     if(network_stats_diff_ptr->interface_name!=NULL){
215     free(network_stats_diff_ptr->interface_name);
216     }
217     network_stats_diff_ptr->interface_name=strdup(network_stats_ptr->interface_name);
218     network_stats_diff_ptr->tx=network_stats_ptr->tx;
219     network_stats_diff_ptr->rx=network_stats_ptr->rx;
220     network_stats_diff_ptr->systime=network_stats->systime;
221    
222     network_stats_ptr++;
223     network_stats_diff_ptr++;
224     }
225     network_stats_ptr=get_network_stats(&ifaces);
226     network_stats_diff_ptr=network_stats_diff;
227    
228     for(x=0;x<sizeof_net_stats_diff;x++){
229    
230     if((strcmp(network_stats_diff_ptr->interface_name, network_stats_ptr->interface_name))==0){
231     network_stats_diff_ptr->tx = network_stats_ptr->tx - network_stats_diff_ptr->tx;
232     network_stats_diff_ptr->rx = network_stats_ptr->rx - network_stats_diff_ptr->rx;
233     network_stats_diff_ptr->systime = network_stats_ptr->systime - network_stats_diff_ptr->systime;
234     }else{
235    
236     network_stats_ptr=network_stats;
237     for(y=0;y<ifaces;y++){
238     if((strcmp(network_stats_diff_ptr->interface_name, network_stats_ptr->interface_name))==0){
239     network_stats_diff_ptr->tx = network_stats_ptr->tx - network_stats_diff_ptr->tx;
240     network_stats_diff_ptr->rx = network_stats_ptr->rx - network_stats_diff_ptr->rx;
241     network_stats_diff_ptr->systime = network_stats_ptr->systime - network_stats_diff_ptr->systime;
242     break;
243     }
244    
245     network_stats_ptr++;
246     }
247     }
248    
249     network_stats_ptr++;
250     network_stats_diff_ptr++;
251     }
252    
253 pajs 1.5 *entries=sizeof_net_stats_diff;
254 pajs 1.3 return network_stats_diff;
255     }
256 pajs 1.1