css formatovani tabulek
[svn/Prometheus-QoS/.git] / prometheus.c
CommitLineData
312ac2c1 1 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
2 /* Prometheus QoS - you can "steal fire" from your ISP */\r
3/* "fair-per-IP" quality of service (QoS) utility */\r
4/* requires Linux 2.4.x or 2.6.x with HTB support */\r
5/* Copyright(C) 2005-2008 Michael Polak (xChaos) */\r
6/* iptables-restore support Copyright(C) 2007-2008 ludva */\r
7/* Credit: CZFree.Net,Martin Devera,Netdave,Aquarius,Gandalf */\r
8/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
9\r
4a1b62ea 10/* Modified by: xChaos, 20111130\r
a031788f 11 ludva, 20080415\r
208112af 12 \r
007c44c5 13 Prometheus QoS is free software; you can redistribute it and/or\r
14 modify it under the terms of the GNU General Public License as \r
15 published by the Free Software Foundation; either version 2.1 of \r
16 the License, or (at your option) any later version.\r
17\r
18 Prometheus QoS is distributed in the hope that it will be useful,\r
19 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
21 General Public License for more details.\r
22\r
c9012978 23 You should have received a copy of the GNU General Public License\r
24 along with Prometheus Qos; if not, write to the Free Software\r
d1ae4fa7 25 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA \r
26 \r
c9012978 27 GNU General Public License is located in file COPYING */\r
007c44c5 28\r
29#define STRLEN 256\r
30#define FIRSTGROUPID 1024\r
43e07280 31#define FIRSTIPCLASS 2048\r
007c44c5 32#undef DEBUG\r
33\r
208112af 34#include "cll1-0.6.2.h"\r
007c44c5 35\r
4a1b62ea 36const char *version = "0.8.3-b";\r
007c44c5 37\r
208112af 38/* Version numbers: 0.8.3 is development releases ("beta"), 0.8.4 will be "stable" */\r
b1b59b3a 39/* Debian(RPM) package versions/patchlevels: 0.7.9-2, 0.8.0-1, 0.8.0-2, etc. */\r
40/* C source code development versions ("beta"): 0.7.9-a, 0.8.1-b, etc. */\r
41/* C source code release versions: 0.8.0, 0.8.2, 0.8.4, etc. */\r
77e71d6b 42\r
7cf6da16 43const char *stats_html_signature = "<small>Statistics generated by Prometheus QoS version %s<br>GPL+Copyright(C)2005-2011 Michael Polak, <a href=\"http://www.arachne.cz/\">Arachne Labs</a></small>\n";\r
2d114137 44\r
82c702a1 45/* ======= All path names are defined here (for RPM patch) ======= */\r
ae776b10 46\r
2d114137 47char *tc = "/sbin/tc"; /* requires tc with HTB support */\r
48char *iptables = "/sbin/iptables"; /* requires iptables utility */\r
49char *iptablessave = "/sbin/iptables-save"; /* not yet required */\r
ae776b10 50char *iptablesrestore = "/sbin/iptables-restore"; /* requires iptables-restore */\r
208112af 51const char *ls = "/bin/ls"; /* this is not user configurable :-) */\r
ae776b10 52\r
2d114137 53char *config = "/etc/prometheus/prometheus.conf"; /* main configuration file */\r
54char *hosts = "/etc/prometheus/hosts"; /* per-IP bandwidth definition file */\r
ae776b10 55\r
2d114137 56char *iptablesfile = "/var/spool/prometheus.iptables"; /* temporary file for iptables-restore*/\r
57char *credit = "/var/lib/misc/prometheus.credit"; /* credit log file */\r
58char *html = "/var/www/traffic.html"; /* hall of fame filename */\r
59char *preview = "/var/www/preview.html"; /* hall of fame preview */\r
60char *cmdlog = "/var/log/prometheuslog"; /* command log filename */\r
61char *log_dir = "/var/www/logs/"; /* log directory pathname, ended with slash */\r
8bcc3268 62char *log_url = "/logs/"; /* log directory relative URI prefix (partial URL) */\r
2d114137 63char *html_log_dir = "/var/www/logs/html/";\r
ae776b10 64\r
6cc38f96 65char *jquery_url = "http://code.jquery.com/jquery-latest.js";\r
66char *lms_url = "/lms/?m=customerinfo&amp;id=";\r
67int use_jquery_popups = 1;\r
9aa195f6 68int row_odd_even = 0; /*<tr class="odd/even"> */\r
69\r
70const char *tr_odd_even(void)\r
71{\r
72 row_odd_even = 1 - row_odd_even;\r
73 if(row_odd_even)\r
74 {\r
75 return "<tr class=\"even\">\n";\r
76 }\r
77 else\r
78 {\r
79 return "<tr class=\"odd\">\n";\r
80 }\r
81}\r
6cc38f96 82\r
007c44c5 83/* ======= Help screen is hopefuly self-documenting part of code :-) ======= */\r
84\r
85void help(void)\r
86{\r
87 puts("Command line switches:\n\\r
88\n\\r
89-?, --help this help screen\n\\r
208112af 90-v, --version show Version number of this utility and exit\n\\r
91-c filename force alternative /etc/prometheus.Conf filename\n\\r
92-h filename force alternative /etc/Hosts filename (overrides hosts keyword)\n\\r
93-f just Flush iptables and tc classes and exit (stop shaping)\n\\r
007c44c5 94-9 emergency iptables flush (do not read data transfer statistics)\n\\r
208112af 95-p just generate Preview of data transfer statistics and exit\n\\r
96-d Dry run (preview tc and iptables commands on stdout)\n\\r
97-r Run (reset all statistics and start shaping)\n\\r
98-n run Now (start shaping without delay - overrides qos-free-delay keyword)\n\\r
99-l Mmm YYYY generate HTML summary of traffic Logs (Mmm=Jan-Dec or Year, YYYY=year)\n\\r
100-m generate HTML summary of traffic logs for yesterday's Month\n\\r
101-y generate HTML summary of traffic logs for yesterday's Year\n");\r
5b902402 102/* not yet implemented:\r
103-s start shaping! (keep data transfer statistics - but apply shaping)\n\\r
5b902402 104*/\r
007c44c5 105}\r
a1d21464 106\r
007c44c5 107/* === Configuraration file values defaults - stored in global variables ==== */\r
108\r
43cde5c3 109int filter_type = 1; /*1 mark, 2 classify*/\r
110char *mark = "MARK";\r
111char *mark_iptables = "MARK --set-mark ";\r
112int dry_run = 0; /* preview - use puts() instead of system() */\r
113char *iptablespreamble = "*mangle\n:PREROUTING ACCEPT [0:0]\n:POSTROUTING ACCEPT [0:0]\n:INPUT ACCEPT [0:0]\n:OUTPUT ACCEPT [0:0]\n:FORWARD ACCEPT [0:0]";\r
114FILE *iptables_file = NULL;\r
115int enable_credit = 1; /* enable credit file */\r
116int use_credit = 0; /* use credit file (if enabled)*/\r
117char *title = "Hall of Fame - Greatest Suckers"; /* hall of fame title */\r
118int hall_of_fame = 1; /* enable hall of fame */\r
119char *lan = "eth0"; /* LAN interface */\r
120char *lan_medium = "100Mbit"; /* 10Mbit/100Mbit ethernet */\r
121char *wan = "eth1"; /* WAN/ISP interface */\r
122char *wan_medium = "100Mbit"; /* 10Mbit/100Mbit ethernet */\r
123char *qos_leaf = "sfq perturb 5"; /* leaf discipline */\r
124char *qos_free_zone = NULL; /* QoS free zone */\r
125int qos_proxy = 1; /* include proxy port to QoS */\r
4358455e 126int found_lmsid = 0; /* show links to users in LMS information system */\r
43cde5c3 127int include_upload = 1; /* upload+download=total traffic */\r
128char *proxy_ip = "192.168.1.1/32"; /* our IP with proxy port */\r
129int proxy_port = 3128; /* proxy port number */\r
130long long int line = 1024; /* WAN/ISP download in kbps */\r
131long long int up = 1024; /* WAN/ISP upload in kbps */\r
132int free_min = 32; /* minimum guaranted bandwidth for all undefined hosts */\r
133int free_max = 64; /* maximum allowed bandwidth for all undefined hosts */\r
134int qos_free_delay = 0; /* seconds to sleep before applying new QoS rules */\r
135int digital_divide = 2; /* controls digital divide weirdness ratio, 1...3 */ \r
136int max_nesting = 3; /* maximum nesting of HTB clases, built-in maximum seems to be 4 */\r
208112af 137int htb_r2q = 256; /* should work for leaf values 512 kbps to 8 Mbps */\r
43cde5c3 138int burst = 8; /* HTB burst (in kbits) */\r
139int burst_main = 64;\r
140int burst_group = 32;\r
43cde5c3 141int magic_treshold = 8; /* reduce ceil by X*magic_treshhold kbps (hard shaping) */\r
142int keywordcount = 0;\r
007c44c5 143/* not yet implemented:\r
43cde5c3 144int fixed_packets = 0; maximum number of pps per IP address (not class!) \r
145int packet_limit = 5; maximum number of pps to htn CEIL, not rate !!! \r
007c44c5 146*/\r
43cde5c3 147FILE *log_file = NULL;\r
148char *kwd = "via-prometheus"; /* /etc/hosts comment, eg. #qos-64-128 */\r
007c44c5 149\r
208112af 150const int highest_priority = 0; /* highest HTB priority (HTB built-in value is 0) */\r
151const int lowest_priority = 7; /* lowest HTB priority (HTB built-in value is 7) */\r
152const int idxtable_treshold1 = 24; /* this is no longer configurable */\r
153const int idxtable_treshold2 = 12; /* this is no longer configurable */\r
154const int idxtable_bitmask1 = 3; /* this is no longer configurable */\r
155const int idxtable_bitmask2 = 3; /* this is no longer configurable */\r
007c44c5 156\r
a1d21464 157/* ==== This is C<<1 stuff - learn C<<1 first! https://dev.arachne.cz/svn/cll1h ==== */\r
007c44c5 158\r
159struct IP\r
160{\r
161 char *addr;\r
162 char *name;\r
163 char *sharing;\r
164 int min;\r
165 int desired;\r
166 int max;\r
167 int mark;\r
168 int prio;\r
169 int fixedprio;\r
170 int group;\r
bb9e11ee 171 int lmsid;\r
007c44c5 172 unsigned long long direct;\r
173 unsigned long long proxy;\r
174 unsigned long long upload;\r
175 unsigned long long traffic;\r
176 unsigned long long credit;\r
177 unsigned long pktsup;\r
178 unsigned long pktsdown;\r
179 struct Keyword *keyword;\r
180 list(IP);\r
181} *ips=NULL, *ip, *sharedip;\r
182\r
183struct Group\r
184{\r
185 int min;\r
186 int count;\r
187 int desired;\r
188 int id;\r
189 list(Group);\r
190} *groups=NULL, *group;\r
191\r
192struct Index\r
193{\r
194 char *addr;\r
195 char *id;\r
196 struct Index *parent;\r
197 int bitmask;\r
198 int children;\r
199 list(Index);\r
200} *idxs=NULL, *idx, *metaindex;\r
201\r
202struct Keyword\r
203{\r
204 char *key;\r
205 \r
206 int asymetry_ratio; /* ratio for ADSL-like upload */\r
207 int asymetry_fixed; /* fixed treshold for ADSL-like upload */\r
208 int data_limit; /* hard shaping: apply magic_treshold if max*data_limit MB exceeded */\r
19a47f60 209 int data_prio; /* soft shaping (qos): reduce HTB prio if max*data_prio MB exceeded */\r
007c44c5 210 long fixed_limit; /* fixed data limit for setting lower HTB ceil */\r
211 long fixed_prio; /* fixed data lmit for setting lower HTB prio */\r
212 int reserve_min; /* bonus for nominal HTB rate bandwidth (in kbps) */\r
213 int reserve_max; /* malus for nominal HTB ceil (in kbps) */\r
214// int divide_max; /* relative malus: new_ceil=rate+(old_ceil-rate)/divide_max */\r
215// int htb_ceil_bonus_divide; /* relative bonus: new_ceil=old_ceil+old_ceil/htb_ceil_bonus_divide */\r
216 int default_prio; /* default HTB priority for this keyword */\r
217 char *html_color;\r
218 int ip_count;\r
219 char *leaf_discipline;\r
220 \r
221 list(Keyword);\r
222} *keyword,*defaultkeyword=NULL,*keywords=NULL;\r
223\r
224/* Damned, this must be object oriented! This looks almost like constructor ;-) */\r
225\r
226void TheIP(void)\r
227{\r
228 create(ip,IP);\r
19a47f60 229 ip->name = "";\r
230 ip->addr = "";\r
231 ip->sharing = NULL;\r
232 ip->prio = highest_priority+1;\r
a1d21464 233 ip->lmsid = -1;\r
bb9e11ee 234 ip->fixedprio = \\r
19a47f60 235 ip->mark = \\r
236 ip->min = \\r
237 ip->max = \\r
238 ip->desired = \\r
239 ip->credit = \\r
240 ip->upload = \\r
241 ip->proxy = \\r
242 ip->direct = \\r
243 ip->traffic = \\r
244 ip->pktsup = \\r
245 ip->pktsdown = 0;\r
246 ip->keyword = keywords;\r
007c44c5 247 push(ip,ips);\r
248}\r
249\r
5b902402 250/* ====== iptables indexes are used to reduce complexity to log8(N) ===== */\r
007c44c5 251\r
252char *very_ugly_ipv4_code(char *inip,int bitmask,int format_as_chainname)\r
253{\r
254 /* warning: this function was debugged only for bitmask values 20,24,28 !!!*/\r
255 int dot=0,n;\r
256 char *ip,*outip,*outptr,*fmt;\r
257\r
258 duplicate(inip,ip);\r
259 /* debug printf("(%s,%d) -> ",ip,bitmask); */\r
260\r
261 if(ip && *ip && bitmask>=0 && bitmask<=32)\r
bb9e11ee 262 {\r
007c44c5 263 string(outip,strlen(ip)+10); /*fuck unicode? assertion: 10>strlen("_%d_%d") */\r
bb9e11ee 264 }\r
007c44c5 265 else \r
bb9e11ee 266 {\r
007c44c5 267 /* should never exit here */\r
268 return "undefined";\r
bb9e11ee 269 }\r
007c44c5 270 outptr=outip;\r
271 while(ip && *ip)\r
272 {\r
273 if(*ip=='.')\r
274 {\r
275 if(dot<(bitmask/8-1)) \r
276 {\r
277 if(format_as_chainname)\r
bb9e11ee 278 {\r
007c44c5 279 *outptr='_';\r
bb9e11ee 280 }\r
007c44c5 281 else\r
bb9e11ee 282 {\r
007c44c5 283 *outptr='.';\r
bb9e11ee 284 }\r
007c44c5 285 outptr++;\r
286 dot++;\r
287 }\r
288 else\r
289 {\r
290 char *cutdot=strchr(ip+1,'.'); /*for bitmask<24*/\r
291 if(cutdot)*cutdot='\0';\r
292 if(format_as_chainname)\r
293 fmt="_%d_%d";\r
294 else\r
295 fmt=".%d";\r
296 if(bitmask%8)\r
297 n=atoi(ip+1)-atoi(ip+1)%(1<<(8-bitmask%8));\r
298 else\r
299 n=0;\r
300\r
301 /*debug printf("%d/%d => [_%d_%d]\n",atoi(ip+1),bitmask,n,bitmask); */\r
302 sprintf(outptr,fmt,n,bitmask);\r
303 if(!format_as_chainname) while(bitmask<24)\r
304 {\r
305 strcat(outip,".0");\r
306 bitmask+=8;\r
307 }\r
308 /* debug printf("[%s]\n",outip); */\r
309 return outip;\r
310 }\r
311 }\r
312 else \r
313 {\r
314 *outptr=*ip;\r
315 outptr++;\r
316 }\r
317 ip++;\r
318 }\r
319 /*should never exit here*/\r
320 *outptr='\0';\r
321 return outip;\r
322}\r
323\r
324char *hash_id(char *ip,int bitmask)\r
a1d21464 325{ \r
326 return very_ugly_ipv4_code(ip,bitmask,1);\r
327}\r
007c44c5 328\r
329char *subnet_id(char *ip,int bitmask)\r
a1d21464 330{\r
331 return very_ugly_ipv4_code(ip,bitmask,0);\r
332}\r
007c44c5 333\r
334/* ================= Let's parse configuration file here =================== */\r
335\r
336void reject_config_and_exit(char *filename)\r
337{\r
338 printf("Configuration file %s rejected - abnormal exit.",filename);\r
339 exit(-1);\r
340}\r
341\r
342void get_config(char *config_filename)\r
343{\r
344 char *cnf="mark";\r
345 \r
346 printf("Configured keywords: ");\r
347 parse(config_filename)\r
348 {\r
349 option("keyword",kwd);\r
350 if(kwd)\r
351 {\r
352 printf("%s ",kwd);\r
353\r
354 create(keyword,Keyword);\r
355 keyword->key=kwd;\r
356 keyword->asymetry_ratio=1; /* ratio for ADSL-like upload */\r
357 keyword->asymetry_fixed=0; /* fixed treshold for ADSL-like upload */\r
358 keyword->data_limit=8; /* hard shaping: apply magic_treshold if max*data_limit MB exceeded */\r
208112af 359 keyword->data_prio=4; /* soft shaping (qos): reduce HTB prio if max*data_prio MB exceeded */\r
007c44c5 360 keyword->fixed_limit=0; /* fixed data limit for setting lower HTB ceil */\r
361 keyword->fixed_prio=0; /* fixed data limit for setting lower HTB prio */\r
362 keyword->reserve_min=8; /* bonus for nominal HTB rate bandwidth (in kbps) */\r
363 keyword->reserve_max=0; /* malus for nominal HTB ceil (in kbps) */\r
208112af 364 keyword->default_prio=highest_priority+1;\r
007c44c5 365 keyword->html_color="000000";\r
366 keyword->ip_count=0;\r
367 keyword->leaf_discipline="";\r
368\r
369 push(keyword,keywords);\r
370 if(!defaultkeyword) defaultkeyword=keyword;\r
371 keywordcount++;\r
372 \r
373 kwd=NULL;\r
374 }\r
208112af 375 else\r
007c44c5 376 {\r
208112af 377 for_each(keyword,keywords)\r
378 {\r
379 int l=strlen(keyword->key);\r
007c44c5 380\r
208112af 381 if(!strncmp(keyword->key,_,l) && strlen(_)>l+2)\r
382 {\r
383 char *tmptr=_; /* <---- l+1 ----> */\r
384 _+=l+1; /* via-prometheus-asymetry-ratio, etc. */\r
385 ioption("asymetry-ratio",keyword->asymetry_ratio);\r
386 ioption("asymetry-treshold",keyword->asymetry_fixed);\r
387 ioption("magic-relative-limit",keyword->data_limit);\r
388 ioption("magic-relative-prio",keyword->data_prio);\r
389 loption("magic-fixed-limit",keyword->fixed_limit);\r
390 loption("magic-fixed-prio",keyword->fixed_prio);\r
391 ioption("htb-default-prio",keyword->default_prio);\r
392 ioption("htb-rate-bonus",keyword->reserve_min);\r
393 ioption("htb-ceil-malus",keyword->reserve_max);\r
208112af 394 option("leaf-discipline",keyword->leaf_discipline);\r
395 option("html-color",keyword->html_color);\r
396 _=tmptr;\r
397 \r
398 if(keyword->data_limit || keyword->fixed_limit || \r
399 keyword->data_prio || keyword->fixed_prio)\r
bb9e11ee 400 {\r
401 use_credit=1; \r
402 }\r
208112af 403 }\r
404 }\r
007c44c5 405 }\r
406\r
407 option("tc",tc);\r
408 option("iptables",iptables);\r
409 option("iptables-save",iptablessave); /* new */\r
410 option("iptables-restore",iptablesrestore); /* new */\r
411 option("iptables-file",iptablesfile); /* new */\r
412 option("hosts",hosts);\r
413 option("lan-interface",lan);\r
414 option("wan-interface",wan);\r
415 option("lan-medium",lan_medium);\r
416 option("wan-medium",wan_medium);\r
417 lloption("wan-download",line);\r
418 lloption("wan-upload",up);\r
419 ioption("hall-of-fame-enable",hall_of_fame);\r
420 option("hall-of-fame-title",title);\r
421 option("hall-of-fame-filename",html);\r
422 option("hall-of-fame-preview",preview);\r
423 option("log-filename",cmdlog);\r
424 option("credit-filename",credit);\r
425 ioption("credit-enable",enable_credit);\r
426 option("log-traffic-directory",log_dir);\r
5b902402 427 option("log-traffic-html-directory",html_log_dir);\r
007c44c5 428 option("log-traffic-url-path",log_url);\r
6cc38f96 429 option("jquery-url",jquery_url);\r
430 option("lms-url",lms_url);\r
431 ioption("use-jquery-popups",use_jquery_popups);\r
007c44c5 432 option("qos-free-zone",qos_free_zone);\r
433 ioption("qos-free-delay",qos_free_delay);\r
434 ioption("qos-proxy-enable",qos_proxy);\r
435 option("qos-proxy-ip",proxy_ip);\r
436 option("htb-leaf-discipline",qos_leaf);\r
437 ioption("qos-proxy-port",proxy_port);\r
438 ioption("free-rate",free_min);\r
439 ioption("free-ceil",free_max);\r
440 ioption("htb-burst",burst);\r
441 ioption("htb-burst-main",burst_main);\r
442 ioption("htb-burst-group",burst_group);\r
443 ioption("htb-nesting-limit",max_nesting);\r
444 ioption("htb-r2q",htb_r2q);\r
445 ioption("magic-include-upload",include_upload);\r
5b902402 446 ioption("magic-treshold",magic_treshold); \r
007c44c5 447 option("filter-type", cnf);\r
448 \r
449/* not yet implemented:\r
450 ioption("magic-fixed-packets",fixed_packets);\r
451 ioption("magic-relative-packets",packet_limit);\r
452*/\r
453 }\r
454 fail\r
455 { \r
456 perror(config_filename);\r
457 puts("Warning - using built-in defaults instead ...");\r
458 }\r
459 done;\r
460 printf("\n");\r
461 \r
462 /*leaf discipline for keywords*/\r
208112af 463 for_each(keyword,keywords)\r
007c44c5 464 {\r
208112af 465 if (!strcmpi(keyword->leaf_discipline, ""))\r
466 {\r
007c44c5 467 keyword->leaf_discipline = qos_leaf;\r
468 }\r
469 }\r
470\r
bb9e11ee 471 if (strcmpi(cnf, "mark"))\r
472 {\r
473 filter_type = 2;\r
474 mark = "CLASSIFY";\r
475 mark_iptables = "CLASSIFY --set-class 1:";\r
476 }\r
477 else\r
478 {\r
479 filter_type = 1;\r
480 mark = "MARK";\r
481 mark_iptables = "MARK --set-mark ";\r
007c44c5 482 }\r
483\r
484 /* are supplied values meaningful ?*/\r
485 if(line<=0 || up<=0)\r
486 {\r
b1b59b3a 487 puts("Illegal value of LAN or WAN bandwidth: 0 kbps.");\r
007c44c5 488 reject_config_and_exit(config_filename);\r
489 }\r
490}\r
491\r
492/* ===================== traffic analyser - uses iptables ================ */ \r
493\r
494void get_traffic_statistics(void)\r
495{\r
496 char *str,*cmd;\r
497 int downloadflag=0;\r
498\r
499 textfile(Pipe,str) *line,*lines=NULL;\r
500 string(str,STRLEN);\r
501 string(cmd,STRLEN);\r
502\r
503 sprintf(cmd,"%s -L -v -x -n -t mangle",iptables);\r
504 shell(cmd);\r
505 input(str,STRLEN)\r
506 {\r
507 create(line,Pipe);\r
508 line->str=str;\r
509 string(str,STRLEN);\r
510 append(line,lines);\r
511 }\r
512\r
208112af 513 for_each(line,lines)\r
007c44c5 514 {\r
515 int col, accept=0,proxyflag=0,valid=1,setchainname=0,commonflag=0; \r
516 unsigned long long traffic=0;\r
517 unsigned long pkts=0;\r
518 char *ipaddr=NULL,*ptr;\r
519 \r
520 /* debug puts(line->str); */\r
521 valid_columns(ptr,line->str,' ',col) \r
522 if(valid) switch(col)\r
523 { \r
524 case 1: if(eq(ptr,"Chain"))\r
525 setchainname=1;\r
526 else if(eq(ptr,"pkts")) \r
527 valid=0;\r
528 else\r
529 sscanf(ptr,"%lu",&pkts); \r
530 break;\r
531 case 2: if(setchainname)\r
532 {\r
533 if(!strncmp(ptr,"post_",5) || eq(ptr,"POSTROUTING"))\r
534 downloadflag=1; \r
535 else \r
536 if(!strncmp(ptr,"forw_",5) || eq(ptr,"FORWARD"))\r
537 downloadflag=0;\r
538 \r
539 if(eq(ptr,"post_common") || eq(ptr,"forw_common"))\r
540 commonflag=1;\r
541 }\r
542 else\r
543 sscanf(ptr,"%Lu",&traffic); traffic+=(1<<19); traffic>>=20;\r
544 break;\r
0045483c 545 case 3: if((strncmp(ptr,"post_",5) && strncmp(ptr,"forw_",5)) || commonflag)\r
007c44c5 546 accept=eq(ptr,mark);\r
547 /*if (filter_type==1) accept=eq(ptr,"MARK"); else accept=eq(ptr,"CLASSIFY");*/\r
548 break;\r
549 case 8: if(downloadflag)\r
550 { \r
551 if(strstr(proxy_ip,ptr))proxyflag=1; \r
552 }\r
553 else\r
554 ipaddr=ptr; \r
555 break;\r
556 case 9: if(downloadflag)ipaddr=ptr;break;\r
557 }\r
558 \r
559 if(accept && traffic>0 && ipaddr)\r
560 {\r
a1d21464 561 if(proxyflag)\r
562 {\r
563 printf("(proxy) ");\r
564 }\r
565 else if(!downloadflag)\r
566 {\r
567 printf("(upload) ");\r
568 }\r
007c44c5 569 printf("IP %s: %Lu M (%ld pkts)\n", ipaddr, traffic, pkts);\r
208112af 570\r
571 if_exists(ip,ips,eq(ip->addr,ipaddr)); \r
007c44c5 572 else \r
573 {\r
574 TheIP();\r
575 ip->addr=ipaddr;\r
576 if(eq(ip->addr,"0.0.0.0/0"))\r
577 {\r
578 ip->name="(unregistered)";\r
579 ip->min=free_min;\r
580 ip->max=ip->desired=free_max;\r
581 }\r
582 }\r
583 \r
584 if(downloadflag)\r
585 {\r
586 if(proxyflag)\r
a1d21464 587 {\r
007c44c5 588 ip->proxy=traffic;\r
a1d21464 589 }\r
007c44c5 590 else\r
a1d21464 591 {\r
007c44c5 592 ip->traffic+=traffic;\r
a1d21464 593 }\r
007c44c5 594 ip->direct=ip->traffic-ip->upload-ip->proxy;\r
595 ip->pktsdown=pkts;\r
596 }\r
597 else\r
598 {\r
599 ip->upload=traffic;\r
600 ip->pktsup=pkts;\r
601 if(include_upload)\r
bb9e11ee 602 {\r
007c44c5 603 ip->traffic+=traffic;\r
bb9e11ee 604 }\r
007c44c5 605 else \r
bb9e11ee 606 {\r
007c44c5 607 if(traffic>ip->traffic)\r
bb9e11ee 608 {\r
007c44c5 609 ip->traffic=traffic; \r
bb9e11ee 610 }\r
611 }\r
007c44c5 612 }\r
613 } \r
614 }\r
615\r
007c44c5 616 free(cmd);\r
617}\r
618 \r
619/* ========== This function executes, logs OR ALSO prints command ========== */\r
620\r
621void safe_run(char *cmd)\r
622{\r
a1d21464 623 if(dry_run)\r
624 {\r
625 printf("\n=>%s\n",cmd);\r
626 }\r
627 else\r
628 {\r
629 system(cmd);\r
630 }\r
631 if(log_file)\r
632 {\r
633 fprintf(log_file,"%s\n",cmd);\r
634 }\r
007c44c5 635}\r
636\r
637void save_line(char *line)\r
638{\r
639 fprintf(iptables_file,"%s\n",line);\r
640}\r
641\r
642void run_restore(void)\r
643{\r
5da44508 644 char *restor;\r
007c44c5 645 string(restor,STRLEN);\r
abe9b855 646\r
647 /*-----------------------------------------------------------------*/\r
648 printf("Running %s <%s ...\n",iptablesrestore,iptablesfile);\r
649 /*-----------------------------------------------------------------*/\r
007c44c5 650 \r
651 save_line("COMMIT");\r
652 fclose(iptables_file);\r
ae776b10 653 if(dry_run) \r
654 {\r
a1d21464 655 parse(iptablesfile)\r
656 {\r
657 printf("%s\n",_);\r
658 }\r
659 done;\r
ae776b10 660 }\r
661\r
662 sprintf(restor,"%s <%s",iptablesrestore, iptablesfile);\r
663 safe_run(restor);\r
007c44c5 664 \r
665 free(restor);\r
666}\r
667\r
668/* == This function strips extra characters after IP address and stores it = */\r
669\r
0eb8bc04 670void parse_ip(char *str)\r
007c44c5 671{\r
4358455e 672 char *ptr,*ipaddr=NULL,*ipname=NULL,*lmsid=NULL;\r
673\r
674 ptr=strchr(str,'{');\r
675 if(ptr)\r
676 {\r
677 lmsid=++ptr;\r
678 while(*ptr && *ptr!='}')\r
a1d21464 679 {\r
4358455e 680 ptr++;\r
a1d21464 681 }\r
4358455e 682 *ptr=0;\r
683 }\r
007c44c5 684 \r
4358455e 685 ptr=str;\r
007c44c5 686 while(*ptr && *ptr!=' ' && *ptr!=9)\r
a1d21464 687 {\r
007c44c5 688 ptr++;\r
a1d21464 689 }\r
007c44c5 690 \r
691 *ptr=0;\r
692 ipaddr=str;\r
693 ptr++;\r
694 while(*ptr && (*ptr==' ' || *ptr==9))\r
a1d21464 695 {\r
007c44c5 696 ptr++;\r
a1d21464 697 }\r
007c44c5 698 ipname=ptr; \r
699 while(*ptr && *ptr!=' ' && *ptr!=9)\r
a1d21464 700 {\r
007c44c5 701 ptr++;\r
a1d21464 702 }\r
007c44c5 703 *ptr=0;\r
704\r
208112af 705 if_exists(ip,ips,eq(ip->addr,ipaddr));\r
706 else\r
707 {\r
708 TheIP();\r
709 }\r
007c44c5 710 ip->addr=ipaddr;\r
711 ip->name=ipname;\r
4358455e 712 if(lmsid)\r
713 {\r
714 ip->lmsid=atoi(lmsid);\r
715 found_lmsid=1;\r
716 }\r
007c44c5 717}\r
718\r
719char *parse_datafile_line(char *str)\r
720{\r
721 char *ptr=strchr(str,' ');\r
722\r
723 if(ptr)\r
724 {\r
725 *ptr=0;\r
726 ptr++;\r
727 return ptr;\r
728 } \r
729 else \r
4358455e 730 {\r
007c44c5 731 return NULL;\r
4358455e 732 }\r
007c44c5 733}\r
734\r
c9012978 735struct IpLog\r
736{\r
737 char *name;\r
738 long traffic;\r
5a8f2e77 739 long guaranted;\r
208112af 740 int i;\r
a1d21464 741 int lmsid;\r
208112af 742 long l;\r
c9012978 743 list(IpLog);\r
744} *iplog,*iplogs;\r
745\r
746void parse_ip_log(int argc, char **argv) \r
747{\r
208112af 748 char *month, *year, *str, *name="(undefined)", *ptr, *ptr2, *filename;\r
749 long traffic=0l, traffic_month, total=0, guaranted;\r
4358455e 750 int col, col2, y_ok, m_ok, accept_month, i=1, any_month=0, lmsid;\r
5a8f2e77 751 char mstr[4], ystr[5];\r
752 FILE *f; \r
c9012978 753 string(str,STRLEN);\r
9da6a279 754 string(filename,STRLEN);\r
c9012978 755\r
5b902402 756 if(argv[1][1]=='l') /* -l */\r
757 {\r
208112af 758 if(argc<4)\r
759 {\r
760 puts("Missing parameter(s)!\nUsage: prometheus -l Mmm YYYY (Mmm=Jan-Dec or Year, YYYY=year)");\r
761 exit(-1);\r
762 }\r
763 else\r
764 {\r
765 month=argv[2];\r
766 if(eq(month,"Year")) any_month=1;\r
767 year=argv[3];\r
768 }\r
5b902402 769 }\r
770 else\r
771 { \r
208112af 772 time_t t = time(NULL) - 3600*24 ; /* yesterday's timestamp*/\r
773 struct tm *timep = localtime(&t); \r
774\r
775 if(argv[1][1]=='m') /* -m yestarday - month */\r
776 {\r
777 strftime(mstr, 4, "%b", timep);\r
778 month=mstr;\r
779 strftime(ystr, 5, "%Y", timep);\r
780 year=ystr; \r
781 }\r
782 else /* -y yesterday - year */\r
783 {\r
784 month="Year";\r
785 any_month=1;\r
786 strftime(ystr, 5, "%Y", timep);\r
787 year=ystr;\r
788 }\r
5b902402 789 }\r
790 printf("Analysing traffic for %s %s ...\n",month,year);\r
c9012978 791\r
493e1ccd 792 /* sorry... next release of C<<1 header file will include for_path_files(name,path) { } macro */\r
793 sprintf(str,"%s %s/",ls,log_dir);\r
c9012978 794 shell(str);\r
493e1ccd 795 input(str,STRLEN) \r
c9012978 796 {\r
493e1ccd 797 if(strstr(str,".log"))\r
9da6a279 798 {\r
493e1ccd 799 ptr=strrchr(str,'\n');\r
800 if(ptr) *ptr='\0';\r
9da6a279 801 sprintf(filename,"%s/%s",log_dir,str);\r
802 printf("Parsing %s ...",filename);\r
493e1ccd 803 accept_month=0;\r
804 traffic_month=0;\r
4358455e 805 guaranted=0;\r
a1d21464 806 lmsid=-1;\r
9da6a279 807 parse(filename)\r
493e1ccd 808 {\r
809 y_ok=m_ok=0; \r
810 valid_columns(ptr,_,'\t',col) switch(col)\r
811 {\r
812 case 2: name = ptr;break;\r
813 case 3: traffic = atol(ptr);break;\r
4358455e 814 /* column number - was 7, now 11...*/\r
493e1ccd 815 case 7:\r
816 case 8:\r
817 case 9:\r
4358455e 818 case 10:\r
819 case 11: if (isalpha(*ptr)) /* character, not numeric string = date, just one*/\r
5a8f2e77 820 {\r
208112af 821 valid_columns(ptr2,ptr,' ',col2) switch(col2)\r
822 {\r
823 case 2: if(any_month || eq(ptr2,month)) m_ok = 1; break;\r
824 case 5: if(eq(ptr2,year)) y_ok = 1; break;\r
825 }\r
5a8f2e77 826 }\r
493e1ccd 827 else\r
828 {\r
829 if(col == 7) guaranted = atol(ptr);\r
4358455e 830 if(col == 10) lmsid = atoi(ptr);\r
493e1ccd 831 }\r
832 }\r
833 \r
834 if(y_ok && m_ok) \r
835 {\r
836 traffic_month += traffic;\r
837 accept_month = 1;\r
838 }\r
839 }\r
840 done;\r
b1b59b3a 841\r
493e1ccd 842 if(accept_month)\r
843 {\r
844 create(iplog,IpLog);\r
845 iplog->name = name;\r
846 iplog->guaranted = guaranted;\r
847 iplog->traffic = traffic_month;\r
a1d21464 848 iplog->lmsid = lmsid;\r
493e1ccd 849 insert(iplog,iplogs,desc_order_by,traffic);\r
850 printf(" %ld MB\n",iplog->traffic);\r
851 }\r
852 else\r
208112af 853 {\r
493e1ccd 854 puts(" no records.");\r
208112af 855 }\r
9da6a279 856 }\r
c9012978 857 }\r
858 sprintf(str,"%s/%s-%s.html",html_log_dir,year,month);\r
859 printf("Writing %s ...",str);\r
860 f=fopen(str,"w");\r
861 if(f)\r
862 {\r
9aa195f6 863 fprintf(f, "<table border=\"1\"><thead><tr class=\"bgGrey\"><th colspan=\"2\">%s %s</th><th align=\"right\">lms</th><th colspan=\"2\">Data transfers</th><th align=\"right\">Min.speed</th></tr></thead><tbody>\n ",\r
6cc38f96 864 month, year);\r
208112af 865\r
9aa195f6 866 row_odd_even = 0;\r
6cc38f96 867 for_each(iplog, iplogs)\r
208112af 868 {\r
c9012978 869 if(iplog->traffic)\r
870 {\r
9aa195f6 871 fprintf(f, "%s<td align=\"right\">%d</td><td align=\"left\"><a href=\"%s%s.log\">%s</td></td><td align=\"right\">", \r
872 tr_odd_even(), i++, log_url, iplog->name, iplog->name); \r
ad4cb129 873 if(iplog->lmsid > 0)\r
874 {\r
875 /*base URL will be configurable soon ... */\r
6cc38f96 876 fprintf(f, "<a href=\"%s%d\">%04d</a>\n", lms_url, iplog->lmsid, iplog->lmsid);\r
ad4cb129 877 }\r
878 else if(iplog->lmsid == 0)\r
879 {\r
880 fputs("-------",f);\r
881 } \r
3365c6a2 882 fprintf(f, "<td align=\"right\">%ld&nbsp;M</td><th align=\"right\">%ld G</th><td align=\"right\">%ld kbps</th></tr>\n",\r
6cc38f96 883 iplog->traffic, iplog->traffic>>10, iplog->guaranted);\r
c9012978 884 total+=iplog->traffic>>10;\r
208112af 885 iplog->i=i;\r
886 iplog->l=total;\r
c9012978 887 }\r
208112af 888 }\r
9aa195f6 889 fprintf(f,"<tr class=\"bgGrey\"><th colspan=\"4\" align=\"left\">Total:</th><th align=\"right\">%ld GB</th><th align=\"right\">%Ld kbps</th></tr>\n", total, line);\r
890 fputs("</tbody></table>\n", f);\r
208112af 891\r
9aa195f6 892 row_odd_even = 0;\r
208112af 893 if(i>10)\r
894 {\r
9aa195f6 895 fputs("<a name=\"erp\"></a><p><table border=\"0\"><thead><caption>Enterprise Resource Planning (ERP)</caption></tr>\n",f);\r
896 fputs("<tr class=\"bgGrey\"><td>Analytic category</td>\n",f);\r
897 fputs("<td colspan=\"2\" align=\"center\">Active Classes</td><td colspan=\"2\" align=\"center\">Data transfers</td></tr>\n</thead><tbody>\n",f);\r
208112af 898\r
899 if_exists(iplog,iplogs,iplog->l>=total/4)\r
900 {\r
9aa195f6 901 fprintf(f,"%s<td>Top 25%% of traffic</td>\n", tr_odd_even());\r
208112af 902 fprintf(f,"<td align=\"right\">%d</td><td align=\"right\">%d %%</td><td align=\"right\">%ld G</td><td align=\"right\">%d %%</td></tr>\n",iplog->i,(100*iplog->i+50)/i,iplog->l,(int)((100*iplog->l+50)/total));\r
903 }\r
904 \r
905 if_exists(iplog,iplogs,iplog->i==10)\r
906 {\r
9aa195f6 907 fprintf(f,"%s<td>Top 10 downloaders</td>\n", tr_odd_even());\r
208112af 908 fprintf(f,"<th align=\"right\">10</th><td align=\"right\">%d %%</td><td align=\"right\">%ld G</td><td align=\"right\">%d %%</td></tr>\n",(100*iplog->i+50)/i,iplog->l,(int)((100*iplog->l+50)/total));\r
909 }\r
910\r
911 if_exists(iplog,iplogs,iplog->l>=total/2)\r
912 {\r
9aa195f6 913 fprintf(f,"%s<td>Top 50%% of traffic</td>\n", tr_odd_even());\r
208112af 914 fprintf(f,"<td align=\"right\">%d</td><td align=\"right\">%d %%</td><td align=\"right\">%ld G</td><th align=\"right\">%d %%</th></tr>\n",iplog->i,(100*iplog->i+50)/i,iplog->l,(int)((100*iplog->l+50)/total));\r
915 }\r
916\r
917 if_exists(iplog,iplogs,iplog->l>=4*total/5)\r
918 {\r
9aa195f6 919 fprintf(f,"%s<td>Top 80%% of traffic</td>\n",tr_odd_even());\r
208112af 920 fprintf(f,"<td align=\"right\">%d</td><td align=\"right\">%d %%</td><td align=\"right\">%ld G</td><th align=\"right\">%d %%</th></tr>\n",iplog->i,(100*iplog->i+50)/i,iplog->l,(int)((100*iplog->l+50)/total));\r
921 }\r
922\r
923 if_exists (iplog,iplogs,iplog->i>=i/5)\r
924 {\r
9aa195f6 925 fprintf(f,"%s<td>Top 20%% downloaders</td>\n",tr_odd_even());\r
208112af 926 fprintf(f,"<td align=\"right\">%d</td><th align=\"right\">%d %%</th><td align=\"right\">%ld G</td><td align=\"right\">%d %%</td></tr>\n",iplog->i,(100*iplog->i+50)/i,iplog->l,(int)((100*iplog->l+50)/total));\r
927 }\r
928\r
929 if_exists(iplog,iplogs,iplog->i>=i/4)\r
930 {\r
9aa195f6 931 fprintf(f,"%s<td>Top 25%% downloaders</td>\n", tr_odd_even());\r
208112af 932 fprintf(f,"<td align=\"right\">%d</td><td align=\"right\">%d %%</td><td align=\"right\">%ld G</td><td align=\"right\">%d %%</td></tr>\n",iplog->i,(100*iplog->i+50)/i,iplog->l,(int)((100*iplog->l+50)/total));\r
933 }\r
934\r
935 if_exists(iplog,iplogs,iplog->i>=i/2)\r
936 {\r
9aa195f6 937 fprintf(f,"%s<td>Top 50%% downloaders</td>\n",tr_odd_even());\r
208112af 938 fprintf(f,"<td align=\"right\">%d</td><th align=\"right\">%d %%</th><td align=\"right\">%ld G</td><td align=\"right\">%d %%</td></tr>\n",iplog->i,(100*iplog->i+50)/i,iplog->l,(int)((100*iplog->l+50)/total));\r
939 }\r
940\r
941 if_exists(iplog,iplogs,iplog->i>=4*i/5)\r
942 {\r
9aa195f6 943 fprintf(f,"%s<td>Top 80%% downloaders</td>\n",tr_odd_even());\r
208112af 944 fprintf(f,"<td align=\"right\">%d</td><td align=\"right\">%d %%</td><td align=\"right\">%ld G</td><td align=\"right\">%d %%</td></tr>\n",iplog->i,(100*iplog->i+50)/i,iplog->l,(int)((100*iplog->l+50)/total));\r
945 }\r
946\r
9aa195f6 947 fprintf(f,"<tr class=\"bgGrey\"><td>All users, all traffic</td>\n");\r
208112af 948 fprintf(f,"<th align=\"right\">%d</th><th align=\"right\">100 %%</th><th align=\"right\">%ld G</th><th align=\"right\">100 %%</th></tr>\n",i-1,total);\r
9aa195f6 949 fputs("</tbody></table>\n", f);\r
208112af 950 }\r
951\r
2d114137 952 fprintf(f, stats_html_signature, version);\r
c9012978 953 fclose(f);\r
954 puts(" done.");\r
955 }\r
956}\r
5b902402 957\r
007c44c5 958/*-----------------------------------------------------------------*/\r
493e1ccd 959/* Are you looking for int main(int argc, char **argv) ? :-)) */\r
007c44c5 960/*-----------------------------------------------------------------*/\r
961\r
962program\r
963{\r
964 int i=0;\r
965 FILE *f=NULL;\r
966 char *str, *ptr, *d;\r
967 char *substring;\r
968 int class_count=0,ip_count=0;\r
969 int parent=1;\r
208112af 970 int just_flush=FALSE;\r
971 int nodelay=FALSE;\r
972 int just_preview=FALSE; /* preview - generate just stats */\r
973 int just_logs=FALSE; /* just parse logs */\r
974 int run=FALSE;\r
b014f181 975 int total=0;\r
33ec95ab 976 \r
007c44c5 977 char *chain_forward, *chain_postrouting;\r
978 char *althosts=NULL;\r
979 \r
980 printf("\n\\r
981Prometheus QoS - \"fair-per-IP\" Quality of Service setup utility.\n\\r
a1d21464 982Version %s - Copyright (C)2005-2011 Michael Polak (xChaos)\n\\r
43cde5c3 983iptables-restore & burst tunning & classify modification by Ludva\n\\r
0d5026c6 984Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);\r
007c44c5 985\r
986 /*----- Boring... we have to check command line options first: ----*/\r
987 \r
988 arguments\r
989 {\r
990 argument("-c") { nextargument(config); }\r
991 argument("-h") { nextargument(althosts);}\r
208112af 992 argument("-d") { run=TRUE; dry_run=TRUE; }\r
993 argument("-f") { run=TRUE; just_flush=TRUE; }\r
994 argument("-9") { run=TRUE; just_flush=9; }\r
995 argument("-p") { run=TRUE; just_preview=TRUE; }\r
996 argument("-r") { run=TRUE; }\r
997 argument("-n") { run=TRUE; nodelay=TRUE; }\r
998 argument("-l") { just_logs=TRUE; }\r
999 argument("-m") { just_logs=TRUE; }\r
1000 argument("-y") { just_logs=TRUE; }\r
007c44c5 1001 argument("-?") { help(); exit(0); }\r
1002 argument("--help") { help(); exit(0); }\r
1003 argument("-v") { exit(0); } \r
1004 argument("--version") { exit(0); } \r
1005 }\r
208112af 1006 \r
007c44c5 1007 if(dry_run)\r
208112af 1008 {\r
007c44c5 1009 puts("*** THIS IS JUST DRY RUN ! ***\n");\r
208112af 1010 }\r
007c44c5 1011\r
208112af 1012 date(d); /* this is typical cll1.h macro - prints current date */\r
007c44c5 1013\r
1014 /*-----------------------------------------------------------------*/\r
1015 printf("Parsing configuration file %s ...\n", config);\r
1016 /*-----------------------------------------------------------------*/\r
1017 get_config(config);\r
c9012978 1018 \r
33ec95ab 1019 if(just_logs)\r
c9012978 1020 {\r
208112af 1021 parse_ip_log(argc,argv);\r
1022 exit(0);\r
1023 }\r
1024 else if(not run)\r
1025 {\r
1026 help();\r
1027 exit(0);\r
c9012978 1028 }\r
007c44c5 1029\r
208112af 1030 if(althosts)\r
1031 {\r
1032 hosts=althosts;\r
1033 }\r
007c44c5 1034\r
1035 if(just_flush<9)\r
1036 {\r
1037 /*-----------------------------------------------------------------*/\r
1038 puts("Parsing iptables verbose output ...");\r
1039 /*-----------------------------------------------------------------*/\r
1040 get_traffic_statistics();\r
1041 }\r
1042\r
1043 /*-----------------------------------------------------------------*/\r
1044 printf("Parsing class defintion file %s ...\n", hosts);\r
1045 /*-----------------------------------------------------------------*/\r
1046 int groupidx = FIRSTGROUPID;\r
1047 parse(hosts)\r
1048 {\r
1049 str=_;\r
1050\r
1051 if(*str<'0' || *str>'9')\r
4358455e 1052 {\r
1053 /* any line starting with non-number is comment ...*/\r
007c44c5 1054 continue;\r
4358455e 1055 }\r
007c44c5 1056 \r
1057 //Does this IP share QoS class with some other ?\r
1058 substring=strstr(str,"sharing-");\r
1059 if(substring)\r
1060 { \r
1061 substring+=8; //"sharing-"\r
0eb8bc04 1062 parse_ip(str);\r
007c44c5 1063 ip_count++;\r
1064 ip->sharing=substring;\r
1065 ip->keyword=defaultkeyword; /* settings for default keyword */\r
1066 while(*substring && *substring!='\n')\r
4358455e 1067 {\r
007c44c5 1068 substring++;\r
4358455e 1069 }\r
007c44c5 1070 *substring=0; \r
1071 }\r
1072 else\r
1073 {\r
1074 //Do we have to create new QoS class for this IP ?\r
1075\r
208112af 1076 if_exists(keyword,keywords,(substring=strstr(str,keyword->key)))\r
007c44c5 1077 {\r
0eb8bc04 1078 parse_ip(str);\r
007c44c5 1079 ip_count++;\r
1080 ip->keyword=keyword;\r
1081 keyword->ip_count++;\r
1082 ip->prio=keyword->default_prio;\r
1083 substring+=strlen(keyword->key)+1;\r
1084 ptr=substring;\r
1085 while(*ptr && *ptr!='-')\r
bb9e11ee 1086 {\r
007c44c5 1087 ptr++;\r
bb9e11ee 1088 }\r
007c44c5 1089 if(*ptr=='-')\r
1090 {\r
1091 *ptr=0;\r
1092 ip->max=ip->desired=atoi(ptr+1);\r
1093 }\r
1094 ip->min=atoi(substring);\r
1095 if(ip->min<=0)\r
1096 {\r
312ac2c1 1097 printf(" %s: Illegal value of minimum bandwidth 0 kbps, using %d kbps\n",str,free_min);\r
c312f6a9 1098 ip->min=free_min;\r
007c44c5 1099 }\r
1100 if(ip->max<=ip->min)\r
1101 {\r
1102 ip->fixedprio=1;\r
1103 ip->max=ip->min+ip->keyword->reserve_min;\r
1104 }\r
1105 else \r
1106 {\r
1107 ip->max-=ip->keyword->reserve_max;\r
007c44c5 1108 if(ip->max<ip->min)\r
bb9e11ee 1109 {\r
007c44c5 1110 ip->max=ip->min;\r
bb9e11ee 1111 }\r
007c44c5 1112 }\r
43e07280 1113 ip->mark=FIRSTIPCLASS+1+class_count++;\r
007c44c5 1114\r
208112af 1115 if_exists(group,groups,group->min==ip->min) \r
007c44c5 1116 { \r
1117 group->count++; \r
1118 group->desired+=ip->min;\r
1119 ip->group = group->id; \r
1120 }\r
1121 else\r
1122 {\r
1123 create(group,Group);\r
1124 group->min=ip->min;\r
1125 group->id = groupidx++;\r
1126 ip->group = group->id;\r
1127\r
1128 if(group->min<8) group->min=8;\r
1129 /* Warning - this is maybe because of primitive tc namespace, can be fixed */\r
1130 /* it is because class IDs are derived from min. bandwidth. - xCh */\r
1131 //if(group->min>MAX_GUARANTED_KBPS) group->min=MAX_GUARANTED_KBPS;\r
1132 \r
1133 group->count=1;\r
1134 group->desired=ip->min; \r
1135 insert(group,groups,desc_order_by,min);\r
1136 }\r
1137 }//endif keyword-\r
1138 }//endif sharing-\r
1139 }\r
1140 fail\r
1141 {\r
1142 perror(hosts);\r
1143 exit(-1);\r
1144 }\r
1145 done;\r
1146\r
1147 /*-----------------------------------------------------------------*/\r
1148 /* cll1.h - let's allocate brand new character buffer... */\r
1149 /*-----------------------------------------------------------------*/\r
1150 string(str,STRLEN); \r
1151\r
1152 /*-----------------------------------------------------------------*/\r
1153 puts("Resolving shared connections ...");\r
1154 /*-----------------------------------------------------------------*/\r
6cc38f96 1155 for_each(ip,ips) if(ip->sharing)\r
007c44c5 1156 {\r
6cc38f96 1157 for_each(sharedip,ips) if(eq(sharedip->name,ip->sharing))\r
007c44c5 1158 {\r
1159 sharedip->traffic+=ip->traffic;\r
1160 ip->traffic=0;\r
1161 ip->mark=sharedip->mark; \r
b3175d62 1162 ip->lmsid=sharedip->lmsid;\r
007c44c5 1163 break;\r
1164 }\r
1165 if(!sharedip)\r
bb9e11ee 1166 {\r
007c44c5 1167 printf("Unresolved shared connection: %s %s sharing-%s\n",ip->addr,ip->name,ip->sharing);\r
bb9e11ee 1168 }\r
007c44c5 1169 }\r
1170\r
1171 if(enable_credit && just_flush<9)\r
1172 {\r
1173 /*-----------------------------------------------------------------*/\r
1174 printf("Parsing credit file %s ...\n", credit);\r
1175 /*-----------------------------------------------------------------*/\r
1176 parse(credit)\r
1177 {\r
1178 ptr=parse_datafile_line(_);\r
1179 if(ptr)\r
1180 {\r
208112af 1181 if_exists(ip,ips,eq(ip->addr,_))\r
1182 {\r
007c44c5 1183 sscanf(ptr,"%Lu",&(ip->credit));\r
208112af 1184 }\r
007c44c5 1185 }\r
1186 }\r
1187 done;\r
1188 }\r
1189\r
1190 if(!just_preview)\r
1191 {\r
1192 /*-----------------------------------------------------------------*/\r
1193 puts("Initializing iptables and tc classes ...");\r
1194 /*-----------------------------------------------------------------*/\r
1195 \r
1196 iptables_file=fopen(iptablesfile,"w");\r
bb9e11ee 1197 if (iptables_file == NULL)\r
1198 {\r
007c44c5 1199 puts("Cannot open iptablesfile!");\r
1200 exit(-1);\r
1201 }\r
1202 \r
1203 log_file=fopen(cmdlog,"w");\r
bb9e11ee 1204 if (log_file == NULL) \r
1205 {\r
007c44c5 1206 puts("Cannot open logfile!");\r
1207 exit(-1);\r
1208 }\r
1209 \r
1210 save_line(iptablespreamble);\r
1211 run_restore();\r
1212 \r
1213 sprintf(str,"%s qdisc del dev %s root 2>/dev/null",tc,lan);\r
1214 safe_run(str);\r
1215\r
1216 sprintf(str,"%s qdisc del dev %s root 2>/dev/null",tc,wan);\r
1217 safe_run(str);\r
1218 \r
1219 iptables_file=fopen(iptablesfile,"w");\r
1220 save_line(iptablespreamble);\r
1221\r
1222 if(qos_free_zone && *qos_free_zone!='0')\r
1223 {\r
1224 char *chain;\r
1225 \r
1226 sprintf(str,"-A FORWARD -d %s -o %s -j ACCEPT", qos_free_zone, wan);\r
1227 save_line(str);\r
1228 \r
1229 if(qos_proxy)\r
1230 {\r
1231 save_line(":post_noproxy - [0:0]");\r
1232 sprintf(str,"-A POSTROUTING -p ! tcp -o %s -j post_noproxy", lan);\r
1233 save_line(str); \r
1234 sprintf(str,"-A POSTROUTING -s ! %s -o %s -j post_noproxy", proxy_ip, lan);\r
1235 save_line(str); \r
1236 sprintf(str,"-A POSTROUTING -s %s -p tcp --sport ! %d -o %s -j post_noproxy", proxy_ip, proxy_port, lan);\r
1237 save_line(str); \r
1238\r
1239 chain="post_noproxy"; \r
1240 }\r
1241 else\r
bb9e11ee 1242 {\r
007c44c5 1243 chain="POSTROUTING";\r
bb9e11ee 1244 }\r
007c44c5 1245 \r
1246 sprintf(str,"-A %s -s %s -o %s -j ACCEPT", chain, qos_free_zone, lan);\r
1247 save_line(str);\r
1248 }\r
1249 \r
1250 if(ip_count>idxtable_treshold1 && !just_flush)\r
1251 {\r
1252 int idxcount=0, bitmask=32-idxtable_bitmask1; /* default net mask: 255.255.255.240 */\r
e0161edb 1253 char *subnet, *buf;\r
007c44c5 1254 /*-----------------------------------------------------------------*/\r
1255 printf("Detected %d addresses - indexing iptables rules to improve performance...\n",ip_count);\r
1256 /*-----------------------------------------------------------------*/\r
1257\r
1258 save_line(":post_common - [0:0]");\r
1259 save_line(":forw_common - [0:0]");\r
1260\r
6cc38f96 1261 for_each(ip,ips) if (ip->addr && *(ip->addr) && !eq(ip->addr,"0.0.0.0/0"))\r
007c44c5 1262 {\r
1263 buf=hash_id(ip->addr,bitmask);\r
208112af 1264 if_exists(idx,idxs,eq(idx->id,buf))\r
1265 {\r
007c44c5 1266 idx->children++;\r
208112af 1267 }\r
007c44c5 1268 else\r
1269 {\r
1270 create(idx,Index);\r
1271 idx->addr=ip->addr;\r
1272 idx->id=buf;\r
1273 idx->bitmask=bitmask;\r
1274 idx->parent=NULL;\r
1275 idx->children=0;\r
1276 idxcount++;\r
1277 push(idx,idxs);\r
1278 }\r
1279 }\r
1280\r
1281 /* brutal perfomance optimalization */\r
1282 while(idxcount>idxtable_treshold2 && bitmask>2*idxtable_bitmask2)\r
1283 {\r
1284 bitmask-=idxtable_bitmask2;\r
1285 idxcount=0;\r
208112af 1286\r
6cc38f96 1287 for_each(idx,idxs) if(idx->parent == NULL)\r
007c44c5 1288 {\r
1289 buf=hash_id(idx->addr,bitmask);\r
208112af 1290 if_exists(metaindex,idxs,eq(metaindex->id,buf))\r
1291 {\r
1292 metaindex->children++;\r
1293 }\r
007c44c5 1294 else\r
1295 {\r
1296 create(metaindex,Index);\r
1297 metaindex->addr=idx->addr;\r
1298 metaindex->id=buf;\r
1299 metaindex->bitmask=bitmask;\r
1300 metaindex->parent=NULL;\r
1301 metaindex->children=0;\r
1302 idxcount++;\r
1303 push(metaindex,idxs);\r
1304 }\r
1305 idx->parent=metaindex;\r
1306 }\r
1307 }\r
1308\r
1309 /* this should slightly optimize throughout ... */\r
1310 sort(idx,idxs,desc_order_by,children);\r
1311 sort(idx,idxs,order_by,bitmask);\r
1312\r
1313 i=0;\r
208112af 1314 for_each(idx,idxs)\r
007c44c5 1315 {\r
1316 subnet=subnet_id(idx->addr,idx->bitmask);\r
1317 printf("%d: %s/%d\n",++i,subnet,idx->bitmask);\r
1318 \r
1319 sprintf(str,":post_%s - [0:0]", idx->id);\r
1320 save_line(str);\r
1321\r
1322 sprintf(str,":forw_%s - [0:0]", idx->id);\r
1323 save_line(str);\r
1324\r
1325 if(idx->parent)\r
1326 {\r
1327 string(buf,strlen(idx->parent->id)+6);\r
1328 sprintf(buf,"post_%s",idx->parent->id);\r
1329 }\r
1330 else\r
bb9e11ee 1331 {\r
007c44c5 1332 buf="POSTROUTING";\r
bb9e11ee 1333 }\r
007c44c5 1334\r
1335 sprintf(str,"-A %s -d %s/%d -o %s -j post_%s", buf, subnet, idx->bitmask, lan, idx->id);\r
1336 save_line(str);\r
1337\r
1338 sprintf(str,"-A %s -d %s/%d -o %s -j post_common", buf, subnet, idx->bitmask, lan);\r
1339 save_line(str);\r
1340\r
1341 if(idx->parent)\r
1342 {\r
1343 string(buf,strlen(idx->parent->id)+6);\r
1344 sprintf(buf,"forw_%s",idx->parent->id);\r
1345 }\r
1346 else\r
bb9e11ee 1347 {\r
007c44c5 1348 buf="FORWARD";\r
bb9e11ee 1349 }\r
007c44c5 1350\r
1351 sprintf(str,"-A %s -s %s/%d -o %s -j forw_%s", buf, subnet, idx->bitmask, wan, idx->id);\r
1352 save_line(str);\r
1353\r
1354 sprintf(str,"-A %s -s %s/%d -o %s -j forw_common", buf, subnet, idx->bitmask, wan);\r
1355 save_line(str);\r
1356 }\r
1357 printf("Total indexed iptables chains created: %d\n", i);\r
1358\r
1359 sprintf(str,"-A FORWARD -o %s -j forw_common", wan);\r
1360 save_line(str);\r
1361 \r
1362 sprintf(str,"-A POSTROUTING -o %s -j post_common", lan);\r
1363 save_line(str);\r
1364 }\r
1365 \r
1366 }\r
1367\r
1368 if(just_flush)\r
1369 {\r
1370 fclose(iptables_file);\r
1371 if (log_file) fclose(log_file);\r
1372 puts("Just flushed iptables and tc classes - now exiting ...");\r
1373 exit(0);\r
1374 }\r
1375\r
1376 if(!just_preview)\r
1377 {\r
1378 if(!dry_run && !nodelay && qos_free_delay)\r
1379 {\r
1380 printf("Flushed iptables and tc classes - now sleeping for %d seconds...\n",qos_free_delay);\r
1381 sleep(qos_free_delay);\r
1382 }\r
1383\r
6cc38f96 1384 sprintf(str,"%s qdisc add dev %s root handle 1: htb r2q %d default 1",\r
1385 tc,lan,htb_r2q);\r
007c44c5 1386 safe_run(str);\r
1387\r
208112af 1388 sprintf(str, "%s class add dev %s parent 1: classid 1:2 htb rate %s ceil %s burst %dk prio %d",\r
1389 tc,lan,lan_medium,lan_medium,burst_main,highest_priority);\r
007c44c5 1390 safe_run(str);\r
1391\r
208112af 1392 sprintf(str, "%s class add dev %s parent 1:2 classid 1:1 htb rate %Ldkbit ceil %Ldkbit burst %dk prio %d",\r
1393 tc,lan,line,line,burst_main,highest_priority);\r
007c44c5 1394 safe_run(str);\r
1395\r
1396 sprintf(str,"%s qdisc add dev %s root handle 1: htb r2q %d default 1",tc,wan,htb_r2q);\r
1397 safe_run(str);\r
1398\r
208112af 1399 sprintf(str, "%s class add dev %s parent 1: classid 1:2 htb rate %s ceil %s burst %dk prio %d",\r
1400 tc,wan,wan_medium,wan_medium,burst_main,highest_priority);\r
007c44c5 1401 safe_run(str);\r
1402\r
208112af 1403 sprintf(str, "%s class add dev %s parent 1:2 classid 1:1 htb rate %Ldkbit ceil %Ldkbit burst %dk prio %d",\r
1404 tc,wan,up,up,burst_main,highest_priority);\r
007c44c5 1405 safe_run(str);\r
1406 }\r
1407\r
1408 /*-----------------------------------------------------------------*/\r
208112af 1409 puts("Locating heavy downloaders and generating root classes ...");\r
007c44c5 1410 /*-----------------------------------------------------------------*/\r
bb9e11ee 1411 sort(ip,ips,desc_order_by,traffic); \r
007c44c5 1412\r
1413 /*-----------------------------------------------------------------*/\r
1414 /* sub-scope - local variables */ \r
1415 {\r
6cc38f96 1416 long long int rate = line;\r
1417 long long int max = line;\r
1418 int group_count = 0;\r
1419 FILE *credit_file = NULL;\r
007c44c5 1420 \r
4358455e 1421 if(!just_preview && !dry_run && enable_credit)\r
1422 {\r
6cc38f96 1423 credit_file = fopen(credit,"w");\r
4358455e 1424 }\r
007c44c5 1425 \r
208112af 1426 for_each(group,groups)\r
007c44c5 1427 {\r
1428 if(!just_preview)\r
1429 {\r
007c44c5 1430 //download\r
208112af 1431 sprintf(str,"%s class add dev %s parent 1:%d classid 1:%d htb rate %Ldkbit ceil %Ldkbit burst %dk prio %d #down desired %d", \r
1432 tc, lan, parent, group->id, rate, max, burst_group, highest_priority+1, group->desired);\r
007c44c5 1433 safe_run(str);\r
1434 \r
1435 //upload\r
208112af 1436 sprintf(str,"%s class add dev %s parent 1:%d classid 1:%d htb rate %Ldkbit ceil %Ldkbit burst %dk prio %d #up desired %d", \r
1437 tc, wan, parent, group->id, rate*up/line, max*up/line, burst_group, highest_priority+1, group->desired);\r
007c44c5 1438 safe_run(str);\r
1439 }\r
1440 \r
6cc38f96 1441 if(group_count++ < max_nesting)\r
bb9e11ee 1442 {\r
6cc38f96 1443 parent = group->id;\r
bb9e11ee 1444 }\r
007c44c5 1445 \r
6cc38f96 1446 rate -= digital_divide*group->min;\r
1447 if(rate < group->min)\r
4358455e 1448 {\r
6cc38f96 1449 rate = group->min;\r
4358455e 1450 }\r
007c44c5 1451 \r
1452 /*shaping of aggresive downloaders, with credit file support */\r
1453 if(use_credit)\r
1454 {\r
6cc38f96 1455 int group_rate = group->min, priority_sequence = lowest_priority;\r
007c44c5 1456 \r
6cc38f96 1457 for_each(ip, ips) if(ip->min == group->min && ip->max > ip->min)\r
007c44c5 1458 {\r
6cc38f96 1459 if( ip->keyword->data_limit && !ip->fixedprio \r
1460 && ( ip->traffic>ip->credit\r
1461 + (ip->min*ip->keyword->data_limit+(ip->keyword->fixed_limit<<20))) )\r
007c44c5 1462 {\r
4358455e 1463 if(group_rate<ip->max)\r
1464 {\r
1465 ip->max=group_rate;\r
1466 }\r
007c44c5 1467 group_rate+=magic_treshold;\r
208112af 1468 ip->prio=lowest_priority;\r
4358455e 1469 if(ip->prio<highest_priority+2)\r
1470 {\r
1471 ip->prio=highest_priority+2;\r
1472 }\r
007c44c5 1473 }\r
1474 else\r
1475 {\r
6cc38f96 1476 if( ip->keyword->data_prio \r
1477 && !ip->fixedprio \r
1478 && ( ip->traffic>ip->credit\r
1479 + (ip->min*ip->keyword->data_prio+(ip->keyword->fixed_prio<<20))) )\r
007c44c5 1480 {\r
1481 ip->prio=priority_sequence--;\r
4358455e 1482 if(ip->prio<highest_priority+1)\r
1483 {\r
1484 ip->prio=highest_priority+1;\r
1485 }\r
007c44c5 1486 }\r
1487 \r
1488 if(credit_file)\r
1489 {\r
1490 unsigned long long lcredit=0;\r
99127c70 1491 \r
4358455e 1492 if((ip->min*ip->keyword->data_limit+(ip->keyword->fixed_limit<<20))>ip->traffic)\r
1493 {\r
007c44c5 1494 lcredit=(ip->min*ip->keyword->data_limit+(ip->keyword->fixed_limit<<20))-ip->traffic;\r
4358455e 1495 }\r
007c44c5 1496 fprintf(credit_file,"%s %Lu\n",ip->addr,lcredit);\r
1497 }\r
1498 }\r
6cc38f96 1499 } \r
007c44c5 1500 }\r
1501 }\r
4358455e 1502 if(credit_file)\r
1503 {\r
1504 fclose(credit_file);\r
1505 }\r
007c44c5 1506 }\r
1507\r
1508 if(just_preview)\r
1509 {\r
1510 f=fopen(preview,"w");\r
1511 ptr=preview; \r
1512 }\r
1513 else if(!dry_run && !just_flush)\r
1514 {\r
1515 /*-----------------------------------------------------------------*/\r
1516 printf("Writing data transfer database ...\n");\r
1517 /*-----------------------------------------------------------------*/\r
1518 f=fopen("/var/run/prometheus.previous","w");\r
1519 if(f)\r
1520 {\r
6cc38f96 1521 for_each(ip,ips) if(ip->traffic || ip->direct || ip->proxy || ip->upload)\r
1522 {\r
1523 fprintf(f,"%s %Lu %Lu %Lu %Lu\n",\r
1524 ip->addr, ip->traffic, ip->direct, ip->proxy, ip->upload);\r
1525 }\r
007c44c5 1526 fclose(f);\r
1527 }\r
1528\r
1529 f=fopen(html,"w");\r
1530 ptr=html;\r
1531 }\r
1532\r
1533 if(f)\r
1534 {\r
007c44c5 1535 int count=1;\r
1536 i=0;\r
1537\r
1538 /*-----------------------------------------------------------------*/\r
6cc38f96 1539 printf("Sorting data and generating statistics page %s ...\n", ptr);\r
007c44c5 1540 /*-----------------------------------------------------------------*/\r
1541\r
6cc38f96 1542 if(use_jquery_popups)\r
1543 {\r
1544 fprintf(f,"<script type=\"text/javascript\" src=\"%s\"></script>\n", jquery_url);\r
1545 }\r
9aa195f6 1546 fputs("<table border=\"0\">\n<thead><tr class=\"bgGrey\"><th align=\"right\">#</th><th align=\"right\">group</th><th align=\"right\">IPs</th><th align=\"right\">requested</th>\n",f);\r
6cc38f96 1547 fprintf(f,"<th colspan=\"%d\">data limits</th>\n", keywordcount);\r
9aa195f6 1548 fputs("</tr></thead><tbody>\n",f);\r
208112af 1549\r
9aa195f6 1550 row_odd_even = 0;\r
6cc38f96 1551 for_each(group, groups) \r
007c44c5 1552 { \r
1553#ifdef DEBUG\r
1554 printf("%d k group: %d bandwidth requested: %d k\n",group->min,group->count,group->desired);\r
1555#endif\r
9aa195f6 1556 fprintf(f, "%s<td align=\"right\">%d</td><td align=\"right\">%d&nbsp;k</td>",\r
1557 tr_odd_even(), count, group->min);\r
1558 fprintf(f, "<td align=\"right\">%d</td><td align=\"right\">%d&nbsp;k</td>",\r
1559 group->count, group->desired);\r
007c44c5 1560\r
6cc38f96 1561 for_each(keyword, keywords)\r
208112af 1562 {\r
3365c6a2 1563 fprintf(f,"<td align=\"right\"><span style=\"color:#%s\">%d&nbsp;M</span></td>",\r
6cc38f96 1564 keyword->html_color, group->min*keyword->data_limit);\r
208112af 1565 } \r
6cc38f96 1566 i += group->desired; \r
1567 total += group->count;\r
007c44c5 1568 count++; \r
1569 }\r
1570#ifdef DEBUG\r
6cc38f96 1571 printf("Total groups: %d Total bandwidth requested: %d k\nAGGREGATION: 1/%d\n",\r
1572 count, i, i/line);\r
007c44c5 1573#endif\r
9aa195f6 1574 fprintf(f,"<tr class=\"bgGrey\"><th colspan=\"2\" align=\"left\">Line %Ld k</td>",line);\r
007c44c5 1575 fprintf(f,"<th align=\"right\">%d</td><th align=\"right\">%d k</td>",total,i);\r
1576\r
6cc38f96 1577 for_each(keyword, keywords)\r
208112af 1578 {\r
1579 fprintf(f,"<th align=\"right\">%d IPs</th>",keyword->ip_count);\r
1580 }\r
6cc38f96 1581 fprintf(f,"</tr><tr><th colspan=\"4\">Aggregation 1/%d</th>\n", (int)(0.5+i/line));\r
1582 fprintf(f,"<th colspan=\"%d\">%d traffic classes</th></tr>\n", keywordcount, total);\r
007c44c5 1583\r
9aa195f6 1584 fputs("</tbody></table>\n",f);\r
007c44c5 1585 }\r
6cc38f96 1586 else if(!dry_run && !just_flush)\r
1587 {\r
007c44c5 1588 perror(html);\r
6cc38f96 1589 }\r
007c44c5 1590\r
6cc38f96 1591 i=0;\r
007c44c5 1592 if(f)\r
1593 {\r
b014f181 1594 unsigned long long total_traffic=0, total_direct=0, total_proxy=0, total_upload=0, tmp_sum=0;\r
007c44c5 1595 int active_classes=0;\r
4a1b62ea 1596 int colspan=11;\r
007c44c5 1597 FILE *iplog;\r
1598 struct Sum {unsigned long long l; int i; list(Sum);} *sum,*sums=NULL;\r
78884bad 1599 int limit_count=0, prio_count=0;\r
4a1b62ea 1600 int popup_button=0;\r
007c44c5 1601\r
1602 if(qos_proxy)\r
4358455e 1603 {\r
1604 colspan++;\r
1605 }\r
1606 if(found_lmsid)\r
1607 {\r
1608 colspan++;\r
1609 }\r
007c44c5 1610 \r
9aa195f6 1611 fprintf(f,"<p><table border>\n<thead><caption>%s",title);\r
1612 fprintf(f," (%s)</caption>\n", d);\r
1613 fputs("<tr class=\"bgGrey\"><td align=\"right\">#</td><td>hostname</td>",f);\r
4358455e 1614 if(found_lmsid)\r
1615 {\r
1616 fputs("<td align=\"right\">lms</td>\n",f);\r
1617 }\r
1618 fputs("<td align=\"right\">credit</td>\\r
1619<td align=\"right\">limit</td>\\r
1620<td align=\"right\">total</td>\\r
1621<td align=\"right\">direct</td>\n",f);\r
007c44c5 1622 if(qos_proxy)\r
4358455e 1623 {\r
007c44c5 1624 fputs("<td align=\"right\">proxy</td>\n",f);\r
4358455e 1625 }\r
007c44c5 1626 fputs("<td align=\"right\">upload</td>\\r
4358455e 1627<td align=\"right\">minimum</td>\\r
1628<td align=\"right\">desired</td>\\r
1629<td align=\"right\">maximum</td>\\r
9aa195f6 1630<td>prio</td></tr>\n\\r
1631</thead><tbody>\n",f); \r
007c44c5 1632\r
9aa195f6 1633 row_odd_even = 0;\r
6cc38f96 1634 for_each(ip,ips) if(!use_jquery_popups || !ip->sharing)\r
007c44c5 1635 {\r
1636 char *f1="", *f2="";\r
6cc38f96 1637 i++;\r
1638 \r
1639 if(ip->max < ip->desired)\r
007c44c5 1640 {\r
78884bad 1641 f1="<span style=\"color:red\">";\r
1642 f2="</span>";\r
1643 limit_count++;\r
007c44c5 1644 }\r
6cc38f96 1645 else if(ip->prio > highest_priority+1)\r
007c44c5 1646 {\r
78884bad 1647 f1="<span style=\"color:brown\">";\r
1648 f2="</span>";\r
1649 prio_count++;\r
007c44c5 1650 }\r
1651\r
1652#ifdef DEBUG\r
1653 printf("%03d. %-22s %10Lu (%d/%d)\n",i ,ip->name, ip->traffic, ip->min, ip->max); \r
1654#endif\r
4a1b62ea 1655 /* hostnames -------------------------------------- */\r
9aa195f6 1656 fprintf(f,"%s<td align=\"right\"><a name=\"%s\"></a>%d</td><td><a href=\"%s%s.log\">%s</a>\n", \r
1657 tr_odd_even(), ip->name, i, log_url, ip->name, ip->name);\r
6cc38f96 1658 if(use_jquery_popups)\r
4a1b62ea 1659 {\r
6cc38f96 1660 fprintf(f,"<span id=\"sharing_%d\" style=\"display:none\">",i);\r
1661 popup_button=0;\r
1662 for_each(sharedip, ips) if(eq(ip->name, sharedip->sharing))\r
1663 {\r
1664 fprintf(f,"<br /><a href=\"%s%s.log\">%s</a>\n", log_url, sharedip->name, sharedip->name);\r
1665 popup_button++;\r
1666 }\r
1667 fputs("</span>\n",f);\r
1668 if(popup_button)\r
1669 {\r
1670 fprintf(f,"<span>[<a href=\"#\" onClick=\"$(this).parent().hide();$(\'#sharing_%d\').show();$(\'#download_%d\').show();$(\'#upload_%d\').show();return(false);\" style=\"cursor: pointer;\">+%d</a>]</span>",\r
1671 i, i, i, popup_button);\r
1672 }\r
4a1b62ea 1673 }\r
1674 fputs("</td>\n",f);\r
1675 /* ----------------------------------------------- */\r
1676\r
4358455e 1677 if(found_lmsid)\r
1678 {\r
1679 fputs("<td align=\"right\">",f);\r
a1d21464 1680 if(ip->lmsid > 0)\r
4358455e 1681 {\r
1682 /*base URL will be configurable soon ... */\r
6cc38f96 1683 fprintf(f,"<a href=\"%s%d\">%04d</a>\n", lms_url, ip->lmsid, ip->lmsid);\r
4358455e 1684 }\r
a1d21464 1685 else if(ip->lmsid == 0)\r
1686 {\r
ad4cb129 1687 fputs("-------",f);\r
a1d21464 1688 }\r
4a1b62ea 1689 fputs("</td>\n",f);\r
4358455e 1690 }\r
3365c6a2 1691 fprintf(f,"<td align=\"right\">%Lu&nbsp;M</td>\n", ip->credit);\r
1692 fprintf(f,"<td align=\"right\"><span style=\"color:#%s\">%Lu&nbsp;M</span></td>",\r
4a1b62ea 1693 ip->keyword->html_color,\r
1694 ip->credit+(ip->min*ip->keyword->data_limit+(ip->keyword->fixed_limit<<20)));\r
3365c6a2 1695 fprintf(f,"<td align=\"right\">%s%Lu&nbsp;M%s", f1, ip->traffic, f2);\r
4a1b62ea 1696\r
1697 /* download --------------------------------------- */\r
3365c6a2 1698 fprintf(f,"</td><td align=\"right\">%Lu&nbsp;M", ip->direct);\r
6cc38f96 1699 if(use_jquery_popups)\r
4a1b62ea 1700 {\r
6cc38f96 1701 fprintf(f,"<span id=\"download_%d\" style=\"display:none\">",i);\r
1702 for_each(sharedip, ips) if(eq(ip->name, sharedip->sharing))\r
1703 {\r
3365c6a2 1704 fprintf(f,"<br />%Lu&nbsp;M", sharedip->direct);\r
6cc38f96 1705 }\r
1706 fputs("</span>\n",f);\r
4a1b62ea 1707 }\r
6cc38f96 1708 fputs("</td>\n",f);\r
4a1b62ea 1709 /* ----------------------------------------------- */\r
1710\r
007c44c5 1711 if(qos_proxy)\r
4358455e 1712 {\r
3365c6a2 1713 fprintf(f,"<td align=\"right\">%Lu&nbsp;M</td>\n", ip->proxy);\r
4358455e 1714 }\r
4a1b62ea 1715 /* upload ---------------------------------------- */\r
3365c6a2 1716 fprintf(f,"<td align=\"right\">%Lu&nbsp;M", ip->upload);\r
6cc38f96 1717 if(use_jquery_popups)\r
4a1b62ea 1718 {\r
6cc38f96 1719 fprintf(f,"<span id=\"upload_%d\" style=\"display:none\">",i);\r
1720 for_each(sharedip,ips) if(eq(ip->name, sharedip->sharing))\r
1721 {\r
3365c6a2 1722 fprintf(f,"<br />%Lu&nbsp;M", sharedip->upload);\r
6cc38f96 1723 }\r
1724 fputs("</span>\n",f);\r
4a1b62ea 1725 }\r
6cc38f96 1726 fputs("</td>\n",f);\r
4a1b62ea 1727 /* ----------------------------------------------- */\r
1728\r
3365c6a2 1729 fprintf(f,"<td align=\"right\">%d&nbsp;k</td><td align=\"right\">%d&nbsp;k</td><td align=\"right\">%s%d&nbsp;k%s</td><td>%s%d%s</td></tr>\n",\r
4358455e 1730 ip->min,ip->desired,f1,ip->max,f2,f1,ip->prio,f2);\r
6cc38f96 1731\r
b014f181 1732 total_traffic+=ip->traffic;\r
007c44c5 1733 total_direct+=ip->direct;\r
1734 total_proxy+=ip->proxy;\r
1735 total_upload+=ip->upload;\r
1736 if(ip->traffic>0)\r
1737 {\r
1738 active_classes++;\r
1739 tmp_sum+=ip->traffic;\r
1740 create(sum,Sum);\r
1741 sum->l=tmp_sum;\r
1742 sum->i=active_classes;\r
1743 insert(sum,sums,order_by,i);\r
1744 }\r
6cc38f96 1745\r
007c44c5 1746 if(!just_preview)\r
1747 {\r
5b902402 1748 sprintf(str,"%s/%s.log",log_dir,ip->name);\r
007c44c5 1749 iplog=fopen(str,"a");\r
1750 if(iplog)\r
1751 {\r
4358455e 1752 fprintf(iplog,"%ld\t%s\t%Lu\t%Lu\t%Lu\t%Lu\t%d\t%d\t%d\t%d\t%s",\r
6cc38f96 1753 time(NULL), ip->name, ip->traffic, ip->direct, ip->proxy,\r
1754 ip->upload, ip->min, ip->max, ip->desired, ip->lmsid, d); /* d = date*/\r
007c44c5 1755 fclose(iplog);\r
1756 }\r
1757 }\r
007c44c5 1758 }\r
9aa195f6 1759 fprintf(f,"<tr class=\"bgGrey\"><th colspan=\"%d\" align=\"left\">%d CLASSES</th>", colspan-7, i);\r
3365c6a2 1760 fprintf(f,"<th align=\"right\">%Lu&nbsp;M</th><th align=\"right\">%Lu&nbsp;M</th>\n", total_traffic, total_direct);\r
007c44c5 1761 if(qos_proxy)\r
4358455e 1762 {\r
3365c6a2 1763 fprintf(f,"<th align=\"right\">%Lu&nbsp;M</th>\n", total_proxy);\r
4358455e 1764 }\r
3365c6a2 1765 fprintf(f,"<th align=\"right\">%Lu&nbsp;M</th>", total_upload);\r
9aa195f6 1766 fprintf(f,"<th colspan=\"4\"><span style=\"color:red\">FUP-LIMIT %dx</span> <span style=\"color:brown\">LOW-PRIO %dx</span></th></tr>\n</tbody></table>\n",limit_count,prio_count);\r
007c44c5 1767\r
9aa195f6 1768 row_odd_even = 0;\r
007c44c5 1769 if(active_classes>10)\r
c9012978 1770 {\r
60a8251d 1771 int top20_count=0,top20_perc1=0;\r
1772 long long top20_perc2=0;\r
1773 unsigned long long top20_sum=0l;\r
1774 \r
9aa195f6 1775 fputs("<a name=\"erp\"></a><p><table border><thead><caption>Enterprise Resource Planning (ERP)</caption>\n",f);\r
1776 fputs("<tr class=\"bgGrey\"><td>Analytic category</td>\n",f);\r
1777 fputs("<td colspan=\"2\" align=\"center\">Active Classes</td><td colspan=\"2\" align=\"center\">Data transfers</td></tr></thead><tbody>\n",f);\r
c9012978 1778\r
b014f181 1779 if_exists(sum,sums,sum->l>=total_traffic/4)\r
c9012978 1780 {\r
9aa195f6 1781 fprintf(f,"%s<td>Top 25%% of traffic</td>\n", tr_odd_even());\r
b014f181 1782 fprintf(f,"<td align=\"right\">%d</td><td align=\"right\">%d %%</td><td align=\"right\">%Lu M</td><td align=\"right\">%Ld %%</td></tr>\n",sum->i,(100*sum->i+50)/active_classes,sum->l,(100*sum->l+50)/total_traffic);\r
c9012978 1783 }\r
1784 \r
208112af 1785 if_exists(sum,sums,sum->i==10)\r
c9012978 1786 {\r
9aa195f6 1787 fprintf(f,"%s<td>Top 10 downloaders</td>\n", tr_odd_even());\r
b014f181 1788 fprintf(f,"<th align=\"right\">10</th><td align=\"right\">%d %%</td><td align=\"right\">%Lu M</td><td align=\"right\">%Ld %%</td></tr>\n",(100*sum->i+50)/active_classes,sum->l,(100*sum->l+50)/total_traffic);\r
c9012978 1789 }\r
1790\r
b014f181 1791 if_exists(sum,sums,sum->l>=total_traffic/2)\r
c9012978 1792 {\r
9aa195f6 1793 fprintf(f,"%s<td>Top 50%% of traffic</td>\n", tr_odd_even());\r
b014f181 1794 fprintf(f,"<td align=\"right\">%d</td><td align=\"right\">%d %%</td><td align=\"right\">%Lu M</td><th align=\"right\">%Ld %%</th></tr>\n",sum->i,(100*sum->i+50)/active_classes,sum->l,(100*sum->l+50)/total_traffic);\r
c9012978 1795 }\r
1796\r
b014f181 1797 if_exists(sum,sums,sum->l>=4*total_traffic/5)\r
c9012978 1798 {\r
9aa195f6 1799 fprintf(f,"%s<td>Top 80%% of traffic</td>\n", tr_odd_even());\r
b014f181 1800 fprintf(f,"<td align=\"right\">%d</td><td align=\"right\">%d %%</td><td align=\"right\">%Lu M</td><th align=\"right\">%Ld %%</th></tr>\n",sum->i,(100*sum->i+50)/active_classes,sum->l,(100*sum->l+50)/total_traffic);\r
c9012978 1801 }\r
1802\r
60a8251d 1803 if_exists(sum,sums,sum->i>=(active_classes+1)/5)\r
c9012978 1804 {\r
9aa195f6 1805 fprintf(f,"%s<td>Top 20%% downloaders</td>\n", tr_odd_even());\r
60a8251d 1806 top20_count=sum->i;\r
1807 top20_perc1=(100*sum->i+50)/active_classes;\r
1808 top20_sum=sum->l;\r
b014f181 1809 top20_perc2=(100*sum->l+50)/total_traffic;\r
60a8251d 1810 fprintf(f,"<td align=\"right\">%d</td><th align=\"right\">%d %%</th><td align=\"right\">%Lu M</td><td align=\"right\">%Ld %%</td></tr>\n",top20_count,top20_perc1,top20_sum,top20_perc2);\r
c9012978 1811 }\r
1812\r
208112af 1813 if_exists(sum,sums,sum->i>=(active_classes+1)/4)\r
c9012978 1814 {\r
9aa195f6 1815 fprintf(f,"%s<td>Top 25%% downloaders</td>\n", tr_odd_even());\r
b014f181 1816 fprintf(f,"<td align=\"right\">%d</td><td align=\"right\">%d %%</td><td align=\"right\">%Lu M</td><td align=\"right\">%Ld %%</td></tr>\n",sum->i,(100*sum->i+50)/active_classes,sum->l,(100*sum->l+50)/total_traffic);\r
c9012978 1817 }\r
1818\r
208112af 1819 if_exists(sum,sums,sum->i>=(active_classes+1)/2)\r
c9012978 1820 {\r
9aa195f6 1821 fprintf(f,"%s<td>Top 50%% downloaders</td>\n", tr_odd_even());\r
b014f181 1822 fprintf(f,"<td align=\"right\">%d</td><th align=\"right\">%d %%</th><td align=\"right\">%Lu M</td><td align=\"right\">%Ld %%</td></tr>\n",sum->i,(100*sum->i+50)/active_classes,sum->l,(100*sum->l+50)/total_traffic);\r
c9012978 1823 }\r
1824\r
208112af 1825 if_exists(sum,sums,sum->i>=4*(active_classes+1)/5)\r
c9012978 1826 {\r
9aa195f6 1827 fprintf(f,"%s<td>Top 80%% downloaders</td>\n", tr_odd_even());\r
b014f181 1828 fprintf(f,"<td align=\"right\">%d</td><td align=\"right\">%d %%</td><td align=\"right\">%Lu M</td><td align=\"right\">%Ld %%</td></tr>\n",sum->i,(100*sum->i+50)/active_classes,sum->l,(100*sum->l+50)/total_traffic);\r
c9012978 1829 }\r
1830\r
9aa195f6 1831 fprintf(f,"<tr class=\"bgGrey\"><td><a href=\"%sERP.log\">All users, all traffic</a></td>\n", log_url);\r
b014f181 1832 fprintf(f,"<th align=\"right\">%d</th><th align=\"right\">100 %%</th><th align=\"right\">%Lu M</th><th align=\"right\">100 %%</th></tr>\n",active_classes,total_traffic);\r
9aa195f6 1833 fputs("</tbody></table>\n", f);\r
60a8251d 1834\r
5da44508 1835 /* write basic ERP data to log directory */\r
60a8251d 1836 if(!just_preview)\r
1837 {\r
1838 sprintf(str,"%s/ERP.log",log_dir);\r
1839 iplog=fopen(str,"a");\r
1840 if(iplog)\r
1841 {\r
78884bad 1842 fprintf(iplog,"%ld\t%d\t%d %%\t%Lu M\t%Ld %%\tACTIVE %d\tTRAFFIC %Lu M\tCLASSES %d\tFUP-LIMIT %d\tLOW-PRIO %d\t%s",\r
4a1b62ea 1843 time(NULL), top20_count, top20_perc1, top20_sum, top20_perc2, \r
6cc38f96 1844 active_classes, total_traffic, i, limit_count, prio_count, d); /* d = date*/\r
60a8251d 1845 fclose(iplog);\r
1846 }\r
1847 }\r
c9012978 1848 }\r
60a8251d 1849\r
2d114137 1850 fprintf(f, stats_html_signature, version);\r
007c44c5 1851 fclose(f);\r
1852 }\r
1853\r
1854 if(just_preview)\r
1855 {\r
1856 puts("Statistics preview generated (-p switch) - now exiting ...");\r
1857 exit(0);\r
1858 }\r
1859 \r
1860 /*-----------------------------------------------------------------*/\r
1861 puts("Generating iptables and tc classes ...");\r
1862 /*-----------------------------------------------------------------*/\r
1863\r
1864 i=0;\r
1865 printf("%-22s %-15s mark\n","name","ip");\r
208112af 1866\r
6cc38f96 1867 for_each(ip,ips) if(ip->mark>0)\r
007c44c5 1868 { \r
007c44c5 1869 if(idxs)\r
1870 {\r
1871 char *buf;\r
1872 duplicate(ip->addr,buf);\r
1873 buf=hash_id(ip->addr,32-idxtable_bitmask1); \r
1874 \r
1875 string(chain_forward,6+strlen(buf));\r
1876 strcpy(chain_forward,"forw_");\r
1877 strcat(chain_forward,buf);\r
1878\r
1879 string(chain_postrouting,6+strlen(buf));\r
1880 strcpy(chain_postrouting,"post_");\r
1881 strcat(chain_postrouting,buf);\r
1882 \r
1883 free(buf);\r
1884 }\r
1885 else\r
1886 {\r
1887 chain_forward="FORWARD";\r
1888 chain_postrouting="POSTROUTING";\r
1889 }\r
1890\r
1891 printf("%-22s %-16s %04d ", ip->name, ip->addr, ip->mark); \r
1892\r
1893 /* -------------------------------------------------------- mark download */\r
1894 \r
1895 sprintf(str,"-A %s -d %s/32 -o %s -j %s%d",chain_postrouting,ip->addr,lan,mark_iptables,ip->mark);\r
1896 /*sprintf(str,"-A %s -d %s/32 -o %s -j MARK --set-mark %d",chain_postrouting,ip->addr,lan,ip->mark);*/\r
1897 /* -m limit --limit 1/s */ \r
1898 save_line(str);\r
1899\r
1900 if(qos_proxy)\r
1901 {\r
1902 sprintf(str,"-A %s -s %s -p tcp --sport %d -d %s/32 -o %s -j %s%d",chain_postrouting,proxy_ip,proxy_port,ip->addr,lan,mark_iptables,ip->mark);\r
1903 /*sprintf(str,"-A %s -s %s -p tcp --sport %d -d %s/32 -o %s -j MARK --set-mark %d",chain_postrouting,proxy_ip,proxy_port,ip->addr,lan,ip->mark);*/\r
1904 save_line(str);\r
1905 }\r
1906\r
1907 sprintf(str,"-A %s -d %s/32 -o %s -j ACCEPT",chain_postrouting,ip->addr,lan);\r
1908 save_line(str);\r
1909\r
1910 /* -------------------------------------------------------- mark upload */\r
1911 sprintf(str,"-A %s -s %s/32 -o %s -j %s%d",chain_forward,ip->addr,wan,mark_iptables,ip->mark);\r
1912 /* sprintf(str,"-A %s -s %s/32 -o %s -j MARK --set-mark %d",chain_forward,ip->addr,wan,ip->mark);*/\r
1913 save_line(str);\r
1914\r
1915 sprintf(str,"-A %s -s %s/32 -o %s -j ACCEPT",chain_forward,ip->addr,wan);\r
1916 save_line(str);\r
1917\r
1918 if(ip->min)\r
1919 {\r
1920 /* -------------------------------------------------------- download class */\r
1921 printf("(down: %dk-%dk ", ip->min, ip->max); \r
1922\r
1923 sprintf(str,"%s class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit burst %dk prio %d", tc, lan, ip->group, ip->mark,ip->min,ip->max, burst, ip->prio);\r
1924 safe_run(str);\r
1925\r
dee5592e 1926 if (strcmpi(ip->keyword->leaf_discipline, "none"))\r
1927 {\r
1928 sprintf(str,"%s qdisc add dev %s parent 1:%d handle %d %s", tc, lan, ip->mark, ip->mark, ip->keyword->leaf_discipline); /*qos_leaf*/\r
1929 safe_run(str);\r
1930 } \r
1931 if (filter_type == 1)\r
1932 {\r
1933 sprintf(str,"%s filter add dev %s parent 1:0 protocol ip handle %d fw flowid 1:%d", tc, lan, ip->mark, ip->mark);\r
1934 safe_run(str);\r
007c44c5 1935 }\r
1936\r
1937 /* -------------------------------------------------------- upload class */\r
1938 printf("up: %dk-%dk)\n", (int)((ip->min/ip->keyword->asymetry_ratio)-ip->keyword->asymetry_fixed), \r
1939 (int)((ip->max/ip->keyword->asymetry_ratio)-ip->keyword->asymetry_fixed));\r
1940\r
1941 sprintf(str,"%s class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit burst %dk prio %d",\r
1942 tc, wan, ip->group, ip->mark,\r
1943 (int)((ip->min/ip->keyword->asymetry_ratio)-ip->keyword->asymetry_fixed),\r
1944 (int)((ip->max/ip->keyword->asymetry_ratio)-ip->keyword->asymetry_fixed), burst, ip->prio);\r
1945 safe_run(str);\r
1946 \r
dee5592e 1947 if (strcmpi(ip->keyword->leaf_discipline, "none"))\r
1948 {\r
1949 sprintf(str,"%s qdisc add dev %s parent 1:%d handle %d %s",tc, wan, ip->mark, ip->mark, ip->keyword->leaf_discipline); /*qos_leaf*/\r
1950 safe_run(str);\r
1951 } \r
1952 if (filter_type == 1)\r
1953 {\r
1954 sprintf(str,"%s filter add dev %s parent 1:0 protocol ip handle %d fw flowid 1:%d",tc, wan, ip->mark, ip->mark);\r
1955 safe_run(str);\r
007c44c5 1956 }\r
1957 }\r
1958 else\r
1959 printf("(sharing %s)\n", ip->sharing);\r
1960 i++;\r
1961 }\r
1962\r
007c44c5 1963 if(idxs)\r
1964 {\r
dee5592e 1965 chain_forward = "forw_common";\r
1966 chain_postrouting = "post_common";\r
007c44c5 1967 }\r
1968 else\r
1969 {\r
dee5592e 1970 chain_forward = "FORWARD";\r
1971 chain_postrouting = "POSTROUTING";\r
007c44c5 1972 }\r
dee5592e 1973 /* -------------------------------- classify or reject free download */\r
007c44c5 1974 {\r
b6a8d473 1975 char *final_chain = "DROP"; /* REJECT would be better, but it is impossible in mangle */\r
dee5592e 1976 if(free_min) final_chain = "ACCEPT";\r
1977 if(qos_proxy)\r
1978 {\r
1979 if(free_min)\r
1980 {\r
1981 sprintf(str,"-A %s -s %s -p tcp --sport %d -o %s -j %s%d",chain_postrouting,proxy_ip,proxy_port,lan,mark_iptables,3);\r
1982 save_line(str);\r
1983 }\r
1984 sprintf(str,"-A %s -s %s -p tcp --sport %d -o %s -j %s",chain_postrouting,proxy_ip,proxy_port,lan,final_chain);\r
1985 save_line(str);\r
1986 }\r
1987 if(free_min)\r
1988 {\r
1989 sprintf(str,"-A %s -o %s -j %s%d",chain_postrouting,lan,mark_iptables,3);\r
1990 save_line(str);\r
1991 }\r
1992 sprintf(str,"-A %s -o %s -j %s",chain_postrouting,lan,final_chain);\r
1993 save_line(str);\r
1994 /* ------------------------------- classify or reject free upload */\r
1995 if(free_min)\r
1996 {\r
1997 sprintf(str,"-A %s -o %s -j %s%d",chain_forward,wan,mark_iptables,3);\r
1998 save_line(str);\r
1999 }\r
2000 sprintf(str,"-A %s -o %s -j %s",chain_forward,wan,final_chain);\r
2001 save_line(str);\r
007c44c5 2002 }\r
abe9b855 2003\r
dee5592e 2004 if(free_min) /* allocate free bandwith if it is not zero... */ \r
2005 {\r
2006 /*-----------------------------------------------------------------*/\r
2007 puts("Generating free bandwith classes ...");\r
2008 /*-----------------------------------------------------------------*/\r
208112af 2009 sprintf(str, "%s class add dev %s parent 1:%d classid 1:3 htb rate %dkbit ceil %dkbit burst %dk prio %d",\r
2010 tc,lan,parent,free_min,free_max,burst,lowest_priority);\r
dee5592e 2011 safe_run(str);\r
208112af 2012 sprintf(str, "%s class add dev %s parent 1:%d classid 1:3 htb rate %dkbit ceil %dkbit burst %dk prio %d",\r
2013 tc,wan,parent,free_min,free_max,burst,lowest_priority);\r
dee5592e 2014 safe_run(str);\r
2015 /* tc SFQ */\r
2016 if (strcmpi(qos_leaf, "none"))\r
2017 {\r
2018 sprintf(str,"%s qdisc add dev %s parent 1:3 handle 3 %s",tc,lan,qos_leaf);\r
2019 safe_run(str);\r
2020 \r
2021 sprintf(str,"%s qdisc add dev %s parent 1:3 handle 3 %s",tc,wan,qos_leaf);\r
2022 safe_run(str);\r
2023 } \r
2024 /* tc handle 1 fw flowid */\r
2025 sprintf(str,"%s filter add dev %s parent 1:0 protocol ip handle 3 fw flowid 1:3",tc,lan);\r
2026 safe_run(str);\r
007c44c5 2027\r
dee5592e 2028 sprintf(str,"%s filter add dev %s parent 1:0 protocol ip handle 3 fw flowid 1:3",tc,wan);\r
2029 safe_run(str);\r
007c44c5 2030 }\r
dee5592e 2031 printf("Total IP count: %d\n", i);\r
2032 run_restore(); \r
007c44c5 2033 if (log_file) fclose(log_file);\r
2034 return 0;\r
007c44c5 2035 /* that's all folks, thank you for reading it all the way up to this point ;-) */\r
2036 /* bad luck C<<1 is not yet finished, I promise no sprintf() next time... */\r
2037}\r
This page took 1.869658 seconds and 4 git commands to generate.