vnstat  2.9
About: vnStat is a console-based network traffic monitor (using the /proc filesystem).
  Fossies Dox: vnstat-2.9.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

ibw.c
Go to the documentation of this file.
1#include "common.h"
2#include "cfg.h"
3#include "ifinfo.h"
4#include "ibw.h"
5
6int ibwloadcfg(const char *cfgfile)
7{
8 FILE *fd;
9 int ret;
10
11 ifacebw = NULL;
12
13 ret = opencfgfile(cfgfile, &fd);
14 if (ret != 2)
15 return ret;
16
17 rewind(fd);
18 ibwcfgread(fd);
19 fclose(fd);
20
21 if (debug)
22 ibwlist();
23
24 return 1;
25}
26
27int ibwadd(const char *iface, const uint32_t limit)
28{
29 ibwnode *n, *p = ifacebw;
30
31 /* add new node if list is empty */
32 if (p == NULL) {
33
34 n = (ibwnode *)malloc(sizeof(ibwnode));
35
36 if (n == NULL) {
37 return 0;
38 }
39
40 n->next = ifacebw;
41 ifacebw = n;
42 strncpy_nt(n->interface, iface, 32);
43 n->limit = limit;
44 n->fallback = limit;
45 n->retries = 0;
46 n->detected = 0;
47
48 } else {
49
50 /* update previous value if already in list */
51 while (p != NULL) {
52 if (strcmp(p->interface, iface) == 0) {
53 p->limit = limit;
54 return 1;
55 }
56 p = p->next;
57 }
58
59 /* add new node if not found */
60 n = (ibwnode *)malloc(sizeof(ibwnode));
61
62 if (n == NULL) {
63 return 0;
64 }
65
66 n->next = ifacebw;
67 ifacebw = n;
68 strncpy_nt(n->interface, iface, 32);
69 n->limit = limit;
70 n->fallback = limit;
71 n->retries = 0;
72 n->detected = 0;
73 }
74
75 return 1;
76}
77
78void ibwlist(void)
79{
80 int i = 1;
81 ibwnode *p = ifacebw;
82
83 if (p == NULL) {
84 printf("ibw list is empty.\n");
85 return;
86 }
87
88 printf("ibw: ");
89 while (p != NULL) {
90 printf("%2d: i\"%s\" l%u f%u r%d d%u ", i, p->interface, p->limit, p->fallback, p->retries, (unsigned int)p->detected);
91 p = p->next;
92 i++;
93 }
94 printf("\n");
95}
96
97int ibwget(const char *iface, uint32_t *limit)
98{
99 ibwnode *p = ifacebw;
100 time_t current;
101 uint32_t speed;
102
103 *limit = 0;
104 current = time(NULL);
105
106 /* search for interface specific limit */
107 while (p != NULL) {
108 if (strcasecmp(p->interface, iface) == 0) {
109
110 /* never override manually configured limits */
111 if (p->detected == 0 && p->limit > 0) {
112 *limit = p->limit;
113 return 1;
114 }
115
116 if (!istun(iface) && cfg.bwdetection && p->retries < 5) {
117 if (cfg.bwdetectioninterval > 0 && (current - p->detected) > (cfg.bwdetectioninterval * 60)) {
118 speed = getifspeed(iface);
119 if (speed > 0) {
120 if (p->detected > 0 && speed != p->limit) {
121 snprintf(errorstring, 1024, "Detected bandwidth limit for \"%s\" changed from %" PRIu32 " Mbit to %" PRIu32 " Mbit.", iface, p->limit, speed);
123 }
124 p->limit = speed;
125 p->retries = 0;
126 p->detected = current;
127 *limit = speed;
128 return 1;
129 }
130 p->retries++;
131 }
132 }
133
134 if (p->limit > 0) {
135 *limit = p->limit;
136 return 1;
137 } else {
138 return 0;
139 }
140 }
141 p = p->next;
142 }
143
144 if (!istun(iface) && cfg.bwdetection) {
145 if (ibwadd(iface, (uint32_t)cfg.maxbw)) {
146 p = ibwgetnode(iface);
147 if (p != NULL) {
148 speed = getifspeed(iface);
149 if (speed > 0) {
150 p->limit = speed;
151 p->retries = 0;
152 p->detected = current;
153 *limit = speed;
154 return 1;
155 }
156 p->retries++;
157 }
158 }
159 }
160
161 /* return default limit if specified */
162 if (cfg.maxbw > 0) {
163 *limit = (uint32_t)cfg.maxbw;
164 return 1;
165 }
166 return 0;
167}
168
169ibwnode *ibwgetnode(const char *iface)
170{
171 ibwnode *p = ifacebw;
172
173 while (p != NULL) {
174 if (strcasecmp(p->interface, iface) == 0) {
175 return p;
176 }
177 p = p->next;
178 }
179 return NULL;
180}
181
182void ibwflush(void)
183{
184 ibwnode *f, *p = ifacebw;
185
186 while (p != NULL) {
187 f = p;
188 p = p->next;
189 free(f);
190 }
191
192 ifacebw = NULL;
193}
194
195int ibwcfgread(FILE *fd)
196{
197 char cfgline[512], name[512], value[512];
198 int i, j, linelen, count = 0;
199 long ivalue;
200
201 /* start from value search from first line */
202 rewind(fd);
203
204 /* cycle all lines */
205 while (!feof(fd)) {
206
207 cfgline[0] = '\0';
208
209 /* get current line */
210 if (fgets(cfgline, 512, fd) == NULL) {
211 break;
212 }
213
214 linelen = (int)strlen(cfgline);
215
216 if (linelen <= 8 || cfgline[0] == '#') {
217 continue;
218 }
219
220 if (strncasecmp(cfgline, "MaxBW", 5) != 0) {
221 continue;
222 }
223
224 /* clear name and value buffers */
225 for (j = 0; j < 512; j++) {
226 name[j] = value[j] = '\0';
227 }
228
229 /* get interface name */
230 j = 0;
231 for (i = 5; i < linelen; i++) {
232 if (cfgline[i] == ' ' || cfgline[i] == '=' || cfgline[i] == '\t' || cfgline[i] == '\n' || cfgline[i] == '\r') {
233 break;
234 } else {
235 name[j] = cfgline[i];
236 j++;
237 }
238 }
239
240 /* get new line if no usable name was found */
241 if (strlen(name) == 0) {
242 continue;
243 }
244
245 /* search value */
246 j = 0;
247 for (i++; i < linelen; i++) {
248 if (cfgline[i] == '\n' || cfgline[i] == '\r') {
249 break;
250 } else if (cfgline[i] == '\"') {
251 if (j == 0) {
252 continue;
253 } else {
254 break;
255 }
256 } else {
257 if (j == 0 && (cfgline[i] == ' ' || cfgline[i] == '=' || cfgline[i] == '\t')) {
258 continue;
259 } else {
260 value[j] = cfgline[i];
261 j++;
262 }
263 }
264 }
265
266 /* get new line if no usable value was found */
267 if ((strlen(value) == 0) || (!isdigit(value[0]))) {
268 continue;
269 }
270
271 /* add interface and limit to list if value is within limits */
272 ivalue = strtol(value, (char **)NULL, 0);
273 if (ivalue < 0 || ivalue > BWMAX) {
274 snprintf(errorstring, 1024, "Invalid value \"%ld\" for MaxBW%s, ignoring parameter.", ivalue, name);
276 } else {
277 ibwadd(name, (uint32_t)ivalue);
278 }
279 }
280
281 return count;
282}
int opencfgfile(const char *cfgfile, FILE **fd)
Definition: cfg.c:443
ibwnode * ifacebw
Definition: common.c:7
char errorstring[1024]
Definition: common.c:6
int printe(const PrintType type)
Definition: common.c:14
int debug
Definition: common.c:8
CFG cfg
Definition: common.c:4
char * strncpy_nt(char *dest, const char *src, size_t n)
Definition: common.c:253
@ PT_Info
Definition: common.h:350
@ PT_Config
Definition: common.h:354
#define BWMAX
Definition: common.h:147
int ibwcfgread(FILE *fd)
Definition: ibw.c:195
int ibwadd(const char *iface, const uint32_t limit)
Definition: ibw.c:27
void ibwflush(void)
Definition: ibw.c:182
int ibwloadcfg(const char *cfgfile)
Definition: ibw.c:6
ibwnode * ibwgetnode(const char *iface)
Definition: ibw.c:169
void ibwlist(void)
Definition: ibw.c:78
int ibwget(const char *iface, uint32_t *limit)
Definition: ibw.c:97
int istun(const char *iface)
Definition: ifinfo.c:490
uint32_t getifspeed(const char *iface)
Definition: ifinfo.c:411
int32_t bwdetectioninterval
Definition: common.h:322
int32_t bwdetection
Definition: common.h:322
int32_t maxbw
Definition: common.h:315
short retries
Definition: common.h:344
struct ibwnode * next
Definition: common.h:346
time_t detected
Definition: common.h:345
char interface[32]
Definition: common.h:341
uint32_t limit
Definition: common.h:342
uint32_t fallback
Definition: common.h:343