getting ready for IP6tables support
[svn/Prometheus-QoS/.git] / prometheus.c
CommitLineData
068f0e75 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-2013 Michael Polak, Arachne Aerospace */\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
10/* Modified by: xChaos, 20130114\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
208112af 29#include "cll1-0.6.2.h"\r
1c9cae56 30#include "ipstruct.h"\r
007c44c5 31\r
1c9cae56 32const char *version = "0.8.3-g";\r
007c44c5 33\r
068f0e75 34/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
35/* Versions: 0.8.3 is development release, 0.8.4 will be "stable" */\r
36/* Official Trac URL: https://dev.arachne.cz/svn/prometheus */\r
37/* Official SVN URL: https://dev.arachne.cz/repos/prometheus */\r
38/* BTC donations account: 19rriLx8vR19wGefPaMhakqnCYNYwjLvxq */\r
39/* CZK donations account: 2900242944/2010 (transparent account) */\r
40/* Warning: unofficial Github mirror is not supported by author! */\r
41/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
77e71d6b 42\r
3bf40f9b 43const char *stats_html_signature = "<span class=\"small\">Statistics generated by Prometheus QoS version %s<br />GPL+Copyright(C)2005-2013 Michael Polak, <a target=\"_blank\" href=\"http://www.arachne.cz/\">Arachne Labs</a></span>\n";\r
2d114137 44\r
068f0e75 45#define STRLEN 512\r
46#undef DEBUG\r
47\r
82c702a1 48/* ======= All path names are defined here (for RPM patch) ======= */\r
ae776b10 49\r
f19d3cd0 50const char *tc = "/sbin/tc"; /* requires tc with HTB support */\r
51const char *iptables = "/sbin/iptables"; /* requires iptables utility */\r
52const char *ip6tables = "/sbin/ip6tables"; /* requires iptables utility */\r
53const char *iptablessave = "/sbin/iptables-save"; /* not yet required */\r
54const char *iptablesrestore = "/sbin/iptables-restore"; /* requires iptables-restore */\r
55const char *ip6tablessave = "/sbin/ip6tables-save"; /* not yet required */\r
56const char *ip6tablesrestore = "/sbin/ip6tables-restore"; /* requires iptables-restore */\r
57const char *ls = "/bin/ls"; /* this is not user configurable :-) */\r
ae776b10 58\r
2d114137 59char *config = "/etc/prometheus/prometheus.conf"; /* main configuration file */\r
60char *hosts = "/etc/prometheus/hosts"; /* per-IP bandwidth definition file */\r
2d114137 61char *iptablesfile = "/var/spool/prometheus.iptables"; /* temporary file for iptables-restore*/\r
62char *credit = "/var/lib/misc/prometheus.credit"; /* credit log file */\r
be96b71b 63char *classmap = "/var/lib/misc/prometheus.classes"; /* credit log file */\r
64char *html = "/var/www/traffic.html"; /* hall of fame - html version */\r
6fb3c58a 65char *preview = "/var/www/preview.html"; /* hall of fame preview - html version */\r
1ab008b9 66char *json_traffic = "/var/www/logs/traffic.json"; /* hall of fame - json version */\r
6fb3c58a 67char *json_preview = "/var/www/logs/preview.json"; /* hall of fame preview - json version */\r
2d114137 68char *cmdlog = "/var/log/prometheuslog"; /* command log filename */\r
69char *log_dir = "/var/www/logs/"; /* log directory pathname, ended with slash */\r
8bcc3268 70char *log_url = "/logs/"; /* log directory relative URI prefix (partial URL) */\r
2d114137 71char *html_log_dir = "/var/www/logs/html/";\r
ae776b10 72\r
6cc38f96 73char *jquery_url = "http://code.jquery.com/jquery-latest.js";\r
74char *lms_url = "/lms/?m=customerinfo&amp;id=";\r
9a56ab25 75int use_jquery_popups = TRUE;\r
9aa195f6 76int row_odd_even = 0; /*<tr class="odd/even"> */\r
b6fb849a 77 \r
007c44c5 78/* === Configuraration file values defaults - stored in global variables ==== */\r
79\r
43cde5c3 80int filter_type = 1; /*1 mark, 2 classify*/\r
81char *mark = "MARK";\r
82char *mark_iptables = "MARK --set-mark ";\r
9a56ab25 83int dry_run = FALSE; /* preview - use puts() instead of system() */\r
43cde5c3 84char *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
85FILE *iptables_file = NULL;\r
9a56ab25 86int enable_credit = TRUE; /* enable credit file */\r
87int use_credit = FALSE; /* use credit file (if enabled)*/\r
43cde5c3 88char *title = "Hall of Fame - Greatest Suckers"; /* hall of fame title */\r
9a56ab25 89int hall_of_fame = TRUE; /* enable hall of fame */\r
43cde5c3 90char *lan = "eth0"; /* LAN interface */\r
91char *lan_medium = "100Mbit"; /* 10Mbit/100Mbit ethernet */\r
92char *wan = "eth1"; /* WAN/ISP interface */\r
93char *wan_medium = "100Mbit"; /* 10Mbit/100Mbit ethernet */\r
94char *qos_leaf = "sfq perturb 5"; /* leaf discipline */\r
95char *qos_free_zone = NULL; /* QoS free zone */\r
9a56ab25 96int qos_proxy = TRUE; /* include proxy port to QoS */\r
97int found_lmsid = FALSE; /* show links to users in LMS information system */\r
98int include_upload = TRUE; /* upload+download=total traffic */\r
43cde5c3 99char *proxy_ip = "192.168.1.1/32"; /* our IP with proxy port */\r
100int proxy_port = 3128; /* proxy port number */\r
101long long int line = 1024; /* WAN/ISP download in kbps */\r
102long long int up = 1024; /* WAN/ISP upload in kbps */\r
103int free_min = 32; /* minimum guaranted bandwidth for all undefined hosts */\r
104int free_max = 64; /* maximum allowed bandwidth for all undefined hosts */\r
105int qos_free_delay = 0; /* seconds to sleep before applying new QoS rules */\r
106int digital_divide = 2; /* controls digital divide weirdness ratio, 1...3 */ \r
107int max_nesting = 3; /* maximum nesting of HTB clases, built-in maximum seems to be 4 */\r
208112af 108int htb_r2q = 256; /* should work for leaf values 512 kbps to 8 Mbps */\r
43cde5c3 109int burst = 8; /* HTB burst (in kbits) */\r
110int burst_main = 64;\r
111int burst_group = 32;\r
43cde5c3 112int magic_treshold = 8; /* reduce ceil by X*magic_treshhold kbps (hard shaping) */\r
113int keywordcount = 0;\r
9a56ab25 114int class_count = 0;\r
115int ip_count = 0;\r
007c44c5 116/* not yet implemented:\r
43cde5c3 117int fixed_packets = 0; maximum number of pps per IP address (not class!) \r
118int packet_limit = 5; maximum number of pps to htn CEIL, not rate !!! \r
007c44c5 119*/\r
43cde5c3 120FILE *log_file = NULL;\r
121char *kwd = "via-prometheus"; /* /etc/hosts comment, eg. #qos-64-128 */\r
007c44c5 122\r
208112af 123const int highest_priority = 0; /* highest HTB priority (HTB built-in value is 0) */\r
124const int lowest_priority = 7; /* lowest HTB priority (HTB built-in value is 7) */\r
125const int idxtable_treshold1 = 24; /* this is no longer configurable */\r
126const int idxtable_treshold2 = 12; /* this is no longer configurable */\r
127const int idxtable_bitmask1 = 3; /* this is no longer configurable */\r
128const int idxtable_bitmask2 = 3; /* this is no longer configurable */\r
007c44c5 129\r
1c9cae56 130struct IP *ips = NULL, *ip, *sharedip;\r
131struct Group *groups = NULL, *group;\r
132struct Keyword *keyword, *defaultkeyword=NULL, *keywords=NULL;\r
007c44c5 133\r
068f0e75 134void help(void);\r
135/* implemented in help.c */
136\r
f19d3cd0 137void get_traffic_statistics(const char *whichiptables);\r
138/* implemented in parseiptables.c */\r
139\r
b6fb849a 140void parse_ip_log(int argc, char **argv);\r
1ab008b9 141/* implemented in parselog.c */\r
b6fb849a 142\r
143void parse_hosts(char *hosts);\r
1ab008b9 144/* implemented in parsehosts.c */\r
145\r
146void write_json_traffic(char *json);\r
147/* implemented in json.c */\r
b6fb849a 148\r
9a56ab25 149void write_htmlandlogs(char *html, char *d, int total, int just_preview);\r
150/* implemented in htmlandlogs.c */\r
151\r
b6fb849a 152const char *tr_odd_even(void)\r
153{\r
154 row_odd_even = 1 - row_odd_even;\r
155 if(row_odd_even)\r
156 {\r
157 return "<tr class=\"even\">\n";\r
158 }\r
159 else\r
160 {\r
161 return "<tr class=\"odd\">\n";\r
162 }\r
163}\r
164\r
1c9cae56 165/* ==== This is C<<1 stuff - learn C<<1 first! https://dev.arachne.cz/svn/cll1h ==== */\r
068f0e75 166/* (except that this code uses obsolete, archaic version of this header file...) */\r
007c44c5 167\r
168struct Index\r
169{\r
170 char *addr;\r
171 char *id;\r
172 struct Index *parent;\r
173 int bitmask;\r
174 int children;\r
175 list(Index);\r
176} *idxs=NULL, *idx, *metaindex;\r
177\r
007c44c5 178\r
5b902402 179/* ====== iptables indexes are used to reduce complexity to log8(N) ===== */\r
007c44c5 180\r
59c3032e 181char *index_id(char *ip, int bitmask);\r
182/* function implemented in ipv4subnets.c */\r
007c44c5 183\r
59c3032e 184char *subnet_id(char *ip, int bitmask);\r
185/* function implemented in ipv4subnets.c */\r
007c44c5 186\r
59c3032e 187/* ================= Let's parse configuration file here ================ */\r
007c44c5 188\r
189void reject_config_and_exit(char *filename)\r
190{\r
191 printf("Configuration file %s rejected - abnormal exit.",filename);\r
192 exit(-1);\r
193}\r
194\r
195void get_config(char *config_filename)\r
196{\r
197 char *cnf="mark";\r
198 \r
199 printf("Configured keywords: ");\r
200 parse(config_filename)\r
201 {\r
202 option("keyword",kwd);\r
203 if(kwd)\r
204 {\r
205 printf("%s ",kwd);\r
206\r
207 create(keyword,Keyword);\r
208 keyword->key=kwd;\r
209 keyword->asymetry_ratio=1; /* ratio for ADSL-like upload */\r
210 keyword->asymetry_fixed=0; /* fixed treshold for ADSL-like upload */\r
211 keyword->data_limit=8; /* hard shaping: apply magic_treshold if max*data_limit MB exceeded */\r
208112af 212 keyword->data_prio=4; /* soft shaping (qos): reduce HTB prio if max*data_prio MB exceeded */\r
007c44c5 213 keyword->fixed_limit=0; /* fixed data limit for setting lower HTB ceil */\r
214 keyword->fixed_prio=0; /* fixed data limit for setting lower HTB prio */\r
215 keyword->reserve_min=8; /* bonus for nominal HTB rate bandwidth (in kbps) */\r
216 keyword->reserve_max=0; /* malus for nominal HTB ceil (in kbps) */\r
208112af 217 keyword->default_prio=highest_priority+1;\r
007c44c5 218 keyword->html_color="000000";\r
219 keyword->ip_count=0;\r
220 keyword->leaf_discipline="";\r
221\r
222 push(keyword,keywords);\r
4d41c1e4 223 if(!defaultkeyword)\r
224 {\r
225 defaultkeyword=keyword;\r
226 }\r
007c44c5 227 keywordcount++;\r
228 \r
229 kwd=NULL;\r
230 }\r
208112af 231 else\r
007c44c5 232 {\r
208112af 233 for_each(keyword,keywords)\r
234 {\r
235 int l=strlen(keyword->key);\r
007c44c5 236\r
208112af 237 if(!strncmp(keyword->key,_,l) && strlen(_)>l+2)\r
238 {\r
239 char *tmptr=_; /* <---- l+1 ----> */\r
240 _+=l+1; /* via-prometheus-asymetry-ratio, etc. */\r
241 ioption("asymetry-ratio",keyword->asymetry_ratio);\r
242 ioption("asymetry-treshold",keyword->asymetry_fixed);\r
243 ioption("magic-relative-limit",keyword->data_limit);\r
244 ioption("magic-relative-prio",keyword->data_prio);\r
245 loption("magic-fixed-limit",keyword->fixed_limit);\r
246 loption("magic-fixed-prio",keyword->fixed_prio);\r
247 ioption("htb-default-prio",keyword->default_prio);\r
248 ioption("htb-rate-bonus",keyword->reserve_min);\r
249 ioption("htb-ceil-malus",keyword->reserve_max);\r
208112af 250 option("leaf-discipline",keyword->leaf_discipline);\r
251 option("html-color",keyword->html_color);\r
252 _=tmptr;\r
253 \r
254 if(keyword->data_limit || keyword->fixed_limit || \r
255 keyword->data_prio || keyword->fixed_prio)\r
bb9e11ee 256 {\r
257 use_credit=1; \r
258 }\r
208112af 259 }\r
260 }\r
007c44c5 261 }\r
262\r
263 option("tc",tc);\r
264 option("iptables",iptables);\r
265 option("iptables-save",iptablessave); /* new */\r
266 option("iptables-restore",iptablesrestore); /* new */\r
f19d3cd0 267 option("ip6tables",ip6tables);\r
268 option("ip6tables-save",ip6tablessave); /* new */\r
269 option("ip6tables-restore",ip6tablesrestore); /* new */\r
be96b71b 270 option("iptables-in-filename",iptablesfile); /* new */\r
007c44c5 271 option("hosts",hosts);\r
272 option("lan-interface",lan);\r
273 option("wan-interface",wan);\r
274 option("lan-medium",lan_medium);\r
275 option("wan-medium",wan_medium);\r
276 lloption("wan-download",line);\r
277 lloption("wan-upload",up);\r
278 ioption("hall-of-fame-enable",hall_of_fame);\r
279 option("hall-of-fame-title",title);\r
280 option("hall-of-fame-filename",html);\r
1ab008b9 281 option("json-filename",json_traffic);\r
007c44c5 282 option("hall-of-fame-preview",preview);\r
6fb3c58a 283 option("json-preview",json_preview);\r
007c44c5 284 option("log-filename",cmdlog);\r
285 option("credit-filename",credit);\r
be96b71b 286 option("classmap-filename",classmap);\r
007c44c5 287 ioption("credit-enable",enable_credit);\r
288 option("log-traffic-directory",log_dir);\r
5b902402 289 option("log-traffic-html-directory",html_log_dir);\r
007c44c5 290 option("log-traffic-url-path",log_url);\r
6cc38f96 291 option("jquery-url",jquery_url);\r
292 option("lms-url",lms_url);\r
293 ioption("use-jquery-popups",use_jquery_popups);\r
007c44c5 294 option("qos-free-zone",qos_free_zone);\r
295 ioption("qos-free-delay",qos_free_delay);\r
296 ioption("qos-proxy-enable",qos_proxy);\r
297 option("qos-proxy-ip",proxy_ip);\r
298 option("htb-leaf-discipline",qos_leaf);\r
299 ioption("qos-proxy-port",proxy_port);\r
300 ioption("free-rate",free_min);\r
301 ioption("free-ceil",free_max);\r
302 ioption("htb-burst",burst);\r
303 ioption("htb-burst-main",burst_main);\r
304 ioption("htb-burst-group",burst_group);\r
305 ioption("htb-nesting-limit",max_nesting);\r
306 ioption("htb-r2q",htb_r2q);\r
307 ioption("magic-include-upload",include_upload);\r
5b902402 308 ioption("magic-treshold",magic_treshold); \r
260c2719 309 option("filter-type", cnf); \r
007c44c5 310/* not yet implemented:\r
311 ioption("magic-fixed-packets",fixed_packets);\r
312 ioption("magic-relative-packets",packet_limit);\r
313*/\r
314 }\r
315 fail\r
316 { \r
317 perror(config_filename);\r
318 puts("Warning - using built-in defaults instead ...");\r
319 }\r
8e29188a 320 done; /* ugly macro end */\r
007c44c5 321 printf("\n");\r
322 \r
be96b71b 323 /* leaf discipline for keywords */\r
208112af 324 for_each(keyword,keywords)\r
007c44c5 325 {\r
260c2719 326 if(!strcmpi(keyword->leaf_discipline, ""))\r
208112af 327 {\r
007c44c5 328 keyword->leaf_discipline = qos_leaf;\r
329 }\r
330 }\r
331\r
260c2719 332 if(strcmpi(cnf, "mark"))\r
bb9e11ee 333 {\r
334 filter_type = 2;\r
335 mark = "CLASSIFY";\r
336 mark_iptables = "CLASSIFY --set-class 1:";\r
337 }\r
338 else\r
339 {\r
340 filter_type = 1;\r
341 mark = "MARK";\r
342 mark_iptables = "MARK --set-mark ";\r
007c44c5 343 }\r
344\r
345 /* are supplied values meaningful ?*/\r
346 if(line<=0 || up<=0)\r
347 {\r
b1b59b3a 348 puts("Illegal value of LAN or WAN bandwidth: 0 kbps.");\r
007c44c5 349 reject_config_and_exit(config_filename);\r
350 }\r
351}\r
352\r
007c44c5 353 \r
354/* ========== This function executes, logs OR ALSO prints command ========== */\r
355\r
356void safe_run(char *cmd)\r
357{\r
a1d21464 358 if(dry_run)\r
359 {\r
360 printf("\n=>%s\n",cmd);\r
361 }\r
362 else\r
363 {\r
364 system(cmd);\r
365 }\r
366 if(log_file)\r
367 {\r
368 fprintf(log_file,"%s\n",cmd);\r
369 }\r
007c44c5 370}\r
371\r
372void save_line(char *line)\r
373{\r
374 fprintf(iptables_file,"%s\n",line);\r
375}\r
376\r
377void run_restore(void)\r
378{\r
5da44508 379 char *restor;\r
007c44c5 380 string(restor,STRLEN);\r
abe9b855 381\r
382 /*-----------------------------------------------------------------*/\r
1c004f15 383 printf("Running %s <%s ...\n", iptablesrestore, iptablesfile);\r
abe9b855 384 /*-----------------------------------------------------------------*/\r
007c44c5 385 \r
386 save_line("COMMIT");\r
387 fclose(iptables_file);\r
ae776b10 388 if(dry_run) \r
389 {\r
a1d21464 390 parse(iptablesfile)\r
391 {\r
392 printf("%s\n",_);\r
393 }\r
8e29188a 394 done; /* ugly macro end */\r
ae776b10 395 }\r
396\r
397 sprintf(restor,"%s <%s",iptablesrestore, iptablesfile);\r
398 safe_run(restor);\r
007c44c5 399 \r
400 free(restor);\r
401}\r
402\r
007c44c5 403char *parse_datafile_line(char *str)\r
404{\r
405 char *ptr=strchr(str,' ');\r
406\r
407 if(ptr)\r
408 {\r
409 *ptr=0;\r
410 ptr++;\r
411 return ptr;\r
412 } \r
413 else \r
4358455e 414 {\r
007c44c5 415 return NULL;\r
4358455e 416 }\r
007c44c5 417}\r
418\r
5b902402 419\r
007c44c5 420/*-----------------------------------------------------------------*/\r
493e1ccd 421/* Are you looking for int main(int argc, char **argv) ? :-)) */\r
007c44c5 422/*-----------------------------------------------------------------*/\r
423\r
424program\r
425{\r
8e29188a 426 int i=0; /* just plain old Fortran style integer :-) */\r
427 FILE *f=NULL; /* everything is just stream of bytes... */\r
428 char *str, *ptr, *d; /* LET A$=B$ :-) */\r
007c44c5 429 char *substring;\r
1c9cae56 430\r
9a56ab25 431 int parent = 1;\r
432 int just_flush = FALSE; /* deactivates all previous actions */\r
433 int nodelay = FALSE;\r
434 int just_preview = FALSE; /* preview - generate just stats */\r
435 int start_shaping = FALSE; /* apply FUP - requires classmap file */\r
436 int just_logs = FALSE; /* just parse logs */\r
437 int run = FALSE;\r
438 int total = 0;\r
33ec95ab 439 \r
007c44c5 440 char *chain_forward, *chain_postrouting;\r
441 char *althosts=NULL;\r
442 \r
443 printf("\n\\r
444Prometheus QoS - \"fair-per-IP\" Quality of Service setup utility.\n\\r
8e29188a 445Version %s - Copyright (C)2005-2012 Michael Polak, Arachne Labs\n\\r
43cde5c3 446iptables-restore & burst tunning & classify modification by Ludva\n\\r
0d5026c6 447Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);\r
007c44c5 448\r
8e29188a 449 /*----- Boring... we have to check command line options first: ----*/ \r
007c44c5 450 arguments\r
451 {\r
452 argument("-c") { nextargument(config); }\r
453 argument("-h") { nextargument(althosts);}\r
208112af 454 argument("-d") { run=TRUE; dry_run=TRUE; }\r
455 argument("-f") { run=TRUE; just_flush=TRUE; }\r
456 argument("-9") { run=TRUE; just_flush=9; }\r
457 argument("-p") { run=TRUE; just_preview=TRUE; }\r
8e29188a 458 argument("-s") { run=TRUE; just_preview=TRUE; start_shaping=TRUE; }\r
208112af 459 argument("-r") { run=TRUE; }\r
460 argument("-n") { run=TRUE; nodelay=TRUE; }\r
461 argument("-l") { just_logs=TRUE; }\r
462 argument("-m") { just_logs=TRUE; }\r
463 argument("-y") { just_logs=TRUE; }\r
007c44c5 464 argument("-?") { help(); exit(0); }\r
465 argument("--help") { help(); exit(0); }\r
466 argument("-v") { exit(0); } \r
467 argument("--version") { exit(0); } \r
468 }\r
208112af 469 \r
007c44c5 470 if(dry_run)\r
208112af 471 {\r
007c44c5 472 puts("*** THIS IS JUST DRY RUN ! ***\n");\r
208112af 473 }\r
007c44c5 474\r
208112af 475 date(d); /* this is typical cll1.h macro - prints current date */\r
007c44c5 476\r
477 /*-----------------------------------------------------------------*/\r
478 printf("Parsing configuration file %s ...\n", config);\r
479 /*-----------------------------------------------------------------*/\r
480 get_config(config);\r
c9012978 481 \r
33ec95ab 482 if(just_logs)\r
c9012978 483 {\r
208112af 484 parse_ip_log(argc,argv);\r
485 exit(0);\r
486 }\r
487 else if(not run)\r
488 {\r
489 help();\r
490 exit(0);\r
c9012978 491 }\r
007c44c5 492\r
208112af 493 if(althosts)\r
494 {\r
495 hosts=althosts;\r
496 }\r
007c44c5 497\r
498 if(just_flush<9)\r
499 {\r
500 /*-----------------------------------------------------------------*/\r
501 puts("Parsing iptables verbose output ...");\r
502 /*-----------------------------------------------------------------*/\r
f19d3cd0 503 get_traffic_statistics(iptables);\r
007c44c5 504 }\r
505\r
506 /*-----------------------------------------------------------------*/\r
507 printf("Parsing class defintion file %s ...\n", hosts);\r
508 /*-----------------------------------------------------------------*/\r
1c9cae56 509 parse_hosts(hosts);\r
007c44c5 510\r
511 /*-----------------------------------------------------------------*/\r
512 /* cll1.h - let's allocate brand new character buffer... */\r
513 /*-----------------------------------------------------------------*/\r
514 string(str,STRLEN); \r
515\r
516 /*-----------------------------------------------------------------*/\r
517 puts("Resolving shared connections ...");\r
518 /*-----------------------------------------------------------------*/\r
6cc38f96 519 for_each(ip,ips) if(ip->sharing)\r
007c44c5 520 {\r
6cc38f96 521 for_each(sharedip,ips) if(eq(sharedip->name,ip->sharing))\r
007c44c5 522 {\r
523 sharedip->traffic+=ip->traffic;\r
524 ip->traffic=0;\r
525 ip->mark=sharedip->mark; \r
b3175d62 526 ip->lmsid=sharedip->lmsid;\r
007c44c5 527 break;\r
528 }\r
1c9cae56 529 if(not sharedip)\r
bb9e11ee 530 {\r
260c2719 531 printf("Unresolved shared connection: %s %s sharing-%s\n",\r
532 ip->addr, ip->name, ip->sharing);\r
bb9e11ee 533 }\r
007c44c5 534 }\r
535\r
536 if(enable_credit && just_flush<9)\r
537 {\r
538 /*-----------------------------------------------------------------*/\r
539 printf("Parsing credit file %s ...\n", credit);\r
540 /*-----------------------------------------------------------------*/\r
541 parse(credit)\r
542 {\r
543 ptr=parse_datafile_line(_);\r
544 if(ptr)\r
545 {\r
208112af 546 if_exists(ip,ips,eq(ip->addr,_))\r
547 {\r
007c44c5 548 sscanf(ptr,"%Lu",&(ip->credit));\r
208112af 549 }\r
007c44c5 550 }\r
551 }\r
8e29188a 552 done; /* ugly macro end */\r
007c44c5 553 }\r
554\r
555 if(!just_preview)\r
556 {\r
557 /*-----------------------------------------------------------------*/\r
558 puts("Initializing iptables and tc classes ...");\r
559 /*-----------------------------------------------------------------*/\r
560 \r
561 iptables_file=fopen(iptablesfile,"w");\r
260c2719 562 if(iptables_file == NULL)\r
bb9e11ee 563 {\r
007c44c5 564 puts("Cannot open iptablesfile!");\r
565 exit(-1);\r
566 }\r
567 \r
568 log_file=fopen(cmdlog,"w");\r
260c2719 569 if(log_file == NULL) \r
bb9e11ee 570 {\r
007c44c5 571 puts("Cannot open logfile!");\r
572 exit(-1);\r
573 }\r
574 \r
575 save_line(iptablespreamble);\r
576 run_restore();\r
577 \r
578 sprintf(str,"%s qdisc del dev %s root 2>/dev/null",tc,lan);\r
579 safe_run(str);\r
580\r
581 sprintf(str,"%s qdisc del dev %s root 2>/dev/null",tc,wan);\r
582 safe_run(str);\r
583 \r
584 iptables_file=fopen(iptablesfile,"w");\r
585 save_line(iptablespreamble);\r
586\r
587 if(qos_free_zone && *qos_free_zone!='0')\r
588 {\r
589 char *chain;\r
590 \r
591 sprintf(str,"-A FORWARD -d %s -o %s -j ACCEPT", qos_free_zone, wan);\r
592 save_line(str);\r
593 \r
594 if(qos_proxy)\r
595 {\r
596 save_line(":post_noproxy - [0:0]");\r
6b39193d 597 sprintf(str,"-A POSTROUTING ! -p tcp -o %s -j post_noproxy", lan);\r
007c44c5 598 save_line(str); \r
6b39193d 599 sprintf(str,"-A POSTROUTING ! -s %s -o %s -j post_noproxy", proxy_ip, lan);\r
007c44c5 600 save_line(str); \r
6b39193d 601 sprintf(str,"-A POSTROUTING -s %s -p tcp ! --sport %d -o %s -j post_noproxy", proxy_ip, proxy_port, lan);\r
007c44c5 602 save_line(str); \r
603\r
604 chain="post_noproxy"; \r
605 }\r
606 else\r
bb9e11ee 607 {\r
007c44c5 608 chain="POSTROUTING";\r
bb9e11ee 609 }\r
007c44c5 610 \r
611 sprintf(str,"-A %s -s %s -o %s -j ACCEPT", chain, qos_free_zone, lan);\r
612 save_line(str);\r
613 }\r
614 \r
615 if(ip_count>idxtable_treshold1 && !just_flush)\r
616 {\r
617 int idxcount=0, bitmask=32-idxtable_bitmask1; /* default net mask: 255.255.255.240 */\r
e0161edb 618 char *subnet, *buf;\r
007c44c5 619 /*-----------------------------------------------------------------*/\r
620 printf("Detected %d addresses - indexing iptables rules to improve performance...\n",ip_count);\r
621 /*-----------------------------------------------------------------*/\r
622\r
623 save_line(":post_common - [0:0]");\r
624 save_line(":forw_common - [0:0]");\r
625\r
260c2719 626 for_each(ip,ips) if(ip->addr && *(ip->addr) && !eq(ip->addr,"0.0.0.0/0"))\r
007c44c5 627 {\r
b6fb849a 628 buf=index_id(ip->addr,bitmask);\r
208112af 629 if_exists(idx,idxs,eq(idx->id,buf))\r
630 {\r
007c44c5 631 idx->children++;\r
208112af 632 }\r
007c44c5 633 else\r
634 {\r
635 create(idx,Index);\r
636 idx->addr=ip->addr;\r
637 idx->id=buf;\r
638 idx->bitmask=bitmask;\r
639 idx->parent=NULL;\r
640 idx->children=0;\r
641 idxcount++;\r
642 push(idx,idxs);\r
643 }\r
644 }\r
645\r
646 /* brutal perfomance optimalization */\r
647 while(idxcount>idxtable_treshold2 && bitmask>2*idxtable_bitmask2)\r
648 {\r
649 bitmask-=idxtable_bitmask2;\r
650 idxcount=0;\r
208112af 651\r
6cc38f96 652 for_each(idx,idxs) if(idx->parent == NULL)\r
007c44c5 653 {\r
b6fb849a 654 buf=index_id(idx->addr,bitmask);\r
208112af 655 if_exists(metaindex,idxs,eq(metaindex->id,buf))\r
656 {\r
657 metaindex->children++;\r
658 }\r
007c44c5 659 else\r
660 {\r
661 create(metaindex,Index);\r
662 metaindex->addr=idx->addr;\r
663 metaindex->id=buf;\r
664 metaindex->bitmask=bitmask;\r
665 metaindex->parent=NULL;\r
666 metaindex->children=0;\r
667 idxcount++;\r
668 push(metaindex,idxs);\r
669 }\r
670 idx->parent=metaindex;\r
671 }\r
672 }\r
673\r
674 /* this should slightly optimize throughout ... */\r
675 sort(idx,idxs,desc_order_by,children);\r
676 sort(idx,idxs,order_by,bitmask);\r
677\r
678 i=0;\r
208112af 679 for_each(idx,idxs)\r
007c44c5 680 {\r
681 subnet=subnet_id(idx->addr,idx->bitmask);\r
260c2719 682 printf("%d: %s/%d\n",\r
683 ++i, subnet, idx->bitmask);\r
007c44c5 684 \r
685 sprintf(str,":post_%s - [0:0]", idx->id);\r
686 save_line(str);\r
687\r
688 sprintf(str,":forw_%s - [0:0]", idx->id);\r
689 save_line(str);\r
690\r
691 if(idx->parent)\r
692 {\r
693 string(buf,strlen(idx->parent->id)+6);\r
694 sprintf(buf,"post_%s",idx->parent->id);\r
695 }\r
696 else\r
bb9e11ee 697 {\r
007c44c5 698 buf="POSTROUTING";\r
bb9e11ee 699 }\r
007c44c5 700\r
701 sprintf(str,"-A %s -d %s/%d -o %s -j post_%s", buf, subnet, idx->bitmask, lan, idx->id);\r
702 save_line(str);\r
703\r
704 sprintf(str,"-A %s -d %s/%d -o %s -j post_common", buf, subnet, idx->bitmask, lan);\r
705 save_line(str);\r
706\r
707 if(idx->parent)\r
708 {\r
709 string(buf,strlen(idx->parent->id)+6);\r
710 sprintf(buf,"forw_%s",idx->parent->id);\r
711 }\r
712 else\r
bb9e11ee 713 {\r
007c44c5 714 buf="FORWARD";\r
bb9e11ee 715 }\r
007c44c5 716\r
717 sprintf(str,"-A %s -s %s/%d -o %s -j forw_%s", buf, subnet, idx->bitmask, wan, idx->id);\r
718 save_line(str);\r
719\r
720 sprintf(str,"-A %s -s %s/%d -o %s -j forw_common", buf, subnet, idx->bitmask, wan);\r
721 save_line(str);\r
722 }\r
723 printf("Total indexed iptables chains created: %d\n", i);\r
724\r
725 sprintf(str,"-A FORWARD -o %s -j forw_common", wan);\r
726 save_line(str);\r
727 \r
728 sprintf(str,"-A POSTROUTING -o %s -j post_common", lan);\r
729 save_line(str);\r
730 }\r
731 \r
732 }\r
733\r
734 if(just_flush)\r
735 {\r
736 fclose(iptables_file);\r
add90548 737 if(log_file)\r
738 { \r
739 fclose(log_file);\r
740 }\r
007c44c5 741 puts("Just flushed iptables and tc classes - now exiting ...");\r
742 exit(0);\r
743 }\r
744\r
745 if(!just_preview)\r
746 {\r
747 if(!dry_run && !nodelay && qos_free_delay)\r
748 {\r
749 printf("Flushed iptables and tc classes - now sleeping for %d seconds...\n",qos_free_delay);\r
750 sleep(qos_free_delay);\r
751 }\r
752\r
6cc38f96 753 sprintf(str,"%s qdisc add dev %s root handle 1: htb r2q %d default 1",\r
754 tc,lan,htb_r2q);\r
007c44c5 755 safe_run(str);\r
756\r
208112af 757 sprintf(str, "%s class add dev %s parent 1: classid 1:2 htb rate %s ceil %s burst %dk prio %d",\r
758 tc,lan,lan_medium,lan_medium,burst_main,highest_priority);\r
007c44c5 759 safe_run(str);\r
760\r
208112af 761 sprintf(str, "%s class add dev %s parent 1:2 classid 1:1 htb rate %Ldkbit ceil %Ldkbit burst %dk prio %d",\r
762 tc,lan,line,line,burst_main,highest_priority);\r
007c44c5 763 safe_run(str);\r
764\r
765 sprintf(str,"%s qdisc add dev %s root handle 1: htb r2q %d default 1",tc,wan,htb_r2q);\r
766 safe_run(str);\r
767\r
208112af 768 sprintf(str, "%s class add dev %s parent 1: classid 1:2 htb rate %s ceil %s burst %dk prio %d",\r
769 tc,wan,wan_medium,wan_medium,burst_main,highest_priority);\r
007c44c5 770 safe_run(str);\r
771\r
208112af 772 sprintf(str, "%s class add dev %s parent 1:2 classid 1:1 htb rate %Ldkbit ceil %Ldkbit burst %dk prio %d",\r
773 tc,wan,up,up,burst_main,highest_priority);\r
007c44c5 774 safe_run(str);\r
775 }\r
776\r
777 /*-----------------------------------------------------------------*/\r
208112af 778 puts("Locating heavy downloaders and generating root classes ...");\r
007c44c5 779 /*-----------------------------------------------------------------*/\r
bb9e11ee 780 sort(ip,ips,desc_order_by,traffic); \r
007c44c5 781\r
782 /*-----------------------------------------------------------------*/\r
783 /* sub-scope - local variables */ \r
784 {\r
6cc38f96 785 long long int rate = line;\r
786 long long int max = line;\r
787 int group_count = 0;\r
788 FILE *credit_file = NULL;\r
007c44c5 789 \r
4358455e 790 if(!just_preview && !dry_run && enable_credit)\r
791 {\r
6cc38f96 792 credit_file = fopen(credit,"w");\r
4358455e 793 }\r
007c44c5 794 \r
208112af 795 for_each(group,groups)\r
007c44c5 796 {\r
797 if(!just_preview)\r
798 {\r
007c44c5 799 //download\r
208112af 800 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
801 tc, lan, parent, group->id, rate, max, burst_group, highest_priority+1, group->desired);\r
007c44c5 802 safe_run(str);\r
803 \r
804 //upload\r
208112af 805 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
806 tc, wan, parent, group->id, rate*up/line, max*up/line, burst_group, highest_priority+1, group->desired);\r
007c44c5 807 safe_run(str);\r
808 }\r
809 \r
6cc38f96 810 if(group_count++ < max_nesting)\r
bb9e11ee 811 {\r
6cc38f96 812 parent = group->id;\r
bb9e11ee 813 }\r
007c44c5 814 \r
6cc38f96 815 rate -= digital_divide*group->min;\r
816 if(rate < group->min)\r
4358455e 817 {\r
6cc38f96 818 rate = group->min;\r
4358455e 819 }\r
007c44c5 820 \r
821 /*shaping of aggresive downloaders, with credit file support */\r
822 if(use_credit)\r
823 {\r
6cc38f96 824 int group_rate = group->min, priority_sequence = lowest_priority;\r
007c44c5 825 \r
6cc38f96 826 for_each(ip, ips) if(ip->min == group->min && ip->max > ip->min)\r
007c44c5 827 {\r
e48d46c9 828 ip->realquota=ip->credit+(ip->min*ip->keyword->data_limit+(ip->keyword->fixed_limit<<20));\r
829 if( ip->keyword->data_limit \r
830 and not ip->fixedprio \r
831 and ip->traffic > ip->realquota )\r
007c44c5 832 {\r
e48d46c9 833 if(group_rate < ip->max)\r
4358455e 834 {\r
e48d46c9 835 ip->max = group_rate;\r
4358455e 836 }\r
007c44c5 837 group_rate+=magic_treshold;\r
208112af 838 ip->prio=lowest_priority;\r
4358455e 839 if(ip->prio<highest_priority+2)\r
840 {\r
841 ip->prio=highest_priority+2;\r
842 }\r
007c44c5 843 }\r
844 else\r
845 {\r
6cc38f96 846 if( ip->keyword->data_prio \r
847 && !ip->fixedprio \r
848 && ( ip->traffic>ip->credit\r
849 + (ip->min*ip->keyword->data_prio+(ip->keyword->fixed_prio<<20))) )\r
007c44c5 850 {\r
851 ip->prio=priority_sequence--;\r
4358455e 852 if(ip->prio<highest_priority+1)\r
853 {\r
854 ip->prio=highest_priority+1;\r
855 }\r
007c44c5 856 }\r
857 \r
858 if(credit_file)\r
859 {\r
860 unsigned long long lcredit=0;\r
99127c70 861 \r
4358455e 862 if((ip->min*ip->keyword->data_limit+(ip->keyword->fixed_limit<<20))>ip->traffic)\r
863 {\r
007c44c5 864 lcredit=(ip->min*ip->keyword->data_limit+(ip->keyword->fixed_limit<<20))-ip->traffic;\r
4358455e 865 }\r
007c44c5 866 fprintf(credit_file,"%s %Lu\n",ip->addr,lcredit);\r
867 }\r
868 }\r
6cc38f96 869 } \r
007c44c5 870 }\r
871 }\r
4358455e 872 if(credit_file)\r
873 {\r
874 fclose(credit_file);\r
875 }\r
007c44c5 876 }\r
877\r
878 if(just_preview)\r
879 {\r
8e29188a 880 if(start_shaping)\r
881 {\r
882 printf("Reading %s and applying Fair Use Policy rules ... \n", classmap);\r
883 parse(classmap)\r
884 {\r
885 ptr=strchr(_,' ');\r
886 if(ptr)\r
887 {\r
888 *ptr=0;\r
889 ptr++;\r
890 if_exists(ip,ips,eq(ip->addr,_))\r
891 {\r
892 ip->mark=atoi(ptr);\r
893 if(ip->max < ip->desired) /* apply FUP limit immediately.... */\r
894 {\r
895 printf("Applying limit for %-22s %-16s %04d ", ip->name, ip->addr, ip->mark); \r
896 printf("(down: %dk-%dk ", ip->min, ip->max); \r
897 sprintf(str, "%s class change dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit burst %dk prio %d", \r
898 tc, lan, ip->group, ip->mark,ip->min,ip->max, burst, ip->prio);\r
899 safe_run(str);\r
900 printf("up: %dk-%dk)\n", (int)((ip->min/ip->keyword->asymetry_ratio)-ip->keyword->asymetry_fixed), \r
901 (int)((ip->max/ip->keyword->asymetry_ratio)-ip->keyword->asymetry_fixed));\r
902 sprintf(str,"%s class change dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit burst %dk prio %d",\r
903 tc, wan, ip->group, ip->mark,\r
904 (int)((ip->min/ip->keyword->asymetry_ratio)-ip->keyword->asymetry_fixed),\r
905 (int)((ip->max/ip->keyword->asymetry_ratio)-ip->keyword->asymetry_fixed), burst, ip->prio);\r
906 safe_run(str);\r
907 }\r
908 }\r
909 }\r
910 }\r
911 fail\r
912 { \r
913 perror(classmap);\r
914 puts("Warning - classmap file not fund, just generating preview ...");\r
915 start_shaping=FALSE;\r
916 }\r
917 done; /* ugly macro end */\r
918 }\r
6fb3c58a 919 html=preview;\r
1ab008b9 920 json_traffic=json_preview;\r
007c44c5 921 }\r
6fb3c58a 922\r
923 if(!dry_run && !just_flush)\r
007c44c5 924 {\r
925 /*-----------------------------------------------------------------*/\r
1ab008b9 926 printf("Writing json traffic overview %s ... ", json_traffic);\r
007c44c5 927 /*-----------------------------------------------------------------*/\r
1ab008b9 928 write_json_traffic(json_traffic);\r
007c44c5 929 }\r
930\r
9a56ab25 931 /*-----------------------------------------------------------------*/\r
932 printf("Writing statistics into HTML page %s ...\n", html);\r
933 /*-----------------------------------------------------------------*/\r
0db8e993 934 write_htmlandlogs(html, d,total, just_preview);\r
007c44c5 935\r
936 if(just_preview)\r
937 {\r
8e29188a 938 char swchar='p';\r
939 if(start_shaping)\r
940 {\r
941 swchar='s';\r
942 }\r
943 printf("Statistics preview generated (-%c switch) - now exiting ...\n", swchar);\r
007c44c5 944 exit(0);\r
be96b71b 945 } \r
007c44c5 946\r
947 i=0;\r
260c2719 948#ifdef DEBUG\r
007c44c5 949 printf("%-22s %-15s mark\n","name","ip");\r
260c2719 950#endif\r
208112af 951\r
be96b71b 952 printf("Writing %s ... ", classmap); \r
953 f = fopen(classmap, "w"); \r
954 if(f < 0)\r
955 {\r
956 perror(classmap);\r
957 }\r
958\r
959 /*-----------------------------------------------------------------*/\r
960 puts("Generating iptables and tc classes ... ");\r
961 /*-----------------------------------------------------------------*/\r
962\r
963 for_each(ip, ips) if(ip->mark > 0)\r
964 {\r
007c44c5 965 if(idxs)\r
966 {\r
967 char *buf;\r
968 duplicate(ip->addr,buf);\r
b6fb849a 969 buf=index_id(ip->addr,32-idxtable_bitmask1); \r
007c44c5 970 \r
971 string(chain_forward,6+strlen(buf));\r
972 strcpy(chain_forward,"forw_");\r
973 strcat(chain_forward,buf);\r
974\r
975 string(chain_postrouting,6+strlen(buf));\r
976 strcpy(chain_postrouting,"post_");\r
977 strcat(chain_postrouting,buf);\r
978 \r
979 free(buf);\r
980 }\r
981 else\r
982 {\r
983 chain_forward="FORWARD";\r
984 chain_postrouting="POSTROUTING";\r
985 }\r
986\r
260c2719 987#ifdef DEBUG\r
007c44c5 988 printf("%-22s %-16s %04d ", ip->name, ip->addr, ip->mark); \r
260c2719 989#endif\r
007c44c5 990\r
991 /* -------------------------------------------------------- mark download */\r
992 \r
be96b71b 993 sprintf(str, "-A %s -d %s/32 -o %s -j %s%d",\r
994 chain_postrouting, ip->addr, lan, mark_iptables, ip->mark);\r
007c44c5 995 /*sprintf(str,"-A %s -d %s/32 -o %s -j MARK --set-mark %d",chain_postrouting,ip->addr,lan,ip->mark);*/\r
996 /* -m limit --limit 1/s */ \r
997 save_line(str);\r
998\r
999 if(qos_proxy)\r
1000 {\r
be96b71b 1001 sprintf(str, "-A %s -s %s -p tcp --sport %d -d %s/32 -o %s -j %s%d",\r
1002 chain_postrouting, proxy_ip, proxy_port, ip->addr, lan, mark_iptables, ip->mark);\r
007c44c5 1003 /*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
1004 save_line(str);\r
1005 }\r
1006\r
be96b71b 1007 sprintf(str, "-A %s -d %s/32 -o %s -j ACCEPT",\r
1008 chain_postrouting, ip->addr, lan);\r
007c44c5 1009 save_line(str);\r
1010\r
1011 /* -------------------------------------------------------- mark upload */\r
be96b71b 1012 sprintf(str, "-A %s -s %s/32 -o %s -j %s%d", \r
1013 chain_forward, ip->addr, wan, mark_iptables, ip->mark);\r
007c44c5 1014 /* sprintf(str,"-A %s -s %s/32 -o %s -j MARK --set-mark %d",chain_forward,ip->addr,wan,ip->mark);*/\r
1015 save_line(str);\r
1016\r
be96b71b 1017 sprintf(str, "-A %s -s %s/32 -o %s -j ACCEPT",\r
1018 chain_forward, ip->addr, wan);\r
007c44c5 1019 save_line(str);\r
1020\r
1021 if(ip->min)\r
1022 {\r
1023 /* -------------------------------------------------------- download class */\r
260c2719 1024#ifdef DEBUG\r
007c44c5 1025 printf("(down: %dk-%dk ", ip->min, ip->max); \r
260c2719 1026#endif\r
007c44c5 1027\r
be96b71b 1028 sprintf(str, "%s class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit burst %dk prio %d", \r
1029 tc, lan, ip->group, ip->mark,ip->min,ip->max, burst, ip->prio);\r
007c44c5 1030 safe_run(str);\r
1031\r
260c2719 1032 if(strcmpi(ip->keyword->leaf_discipline, "none"))\r
dee5592e 1033 {\r
be96b71b 1034 sprintf(str, "%s qdisc add dev %s parent 1:%d handle %d %s", \r
1035 tc, lan, ip->mark, ip->mark, ip->keyword->leaf_discipline); /*qos_leaf*/\r
dee5592e 1036 safe_run(str);\r
be96b71b 1037 }\r
1038\r
260c2719 1039 if(filter_type == 1)\r
dee5592e 1040 {\r
be96b71b 1041 sprintf(str, "%s filter add dev %s parent 1:0 protocol ip handle %d fw flowid 1:%d",\r
1042 tc, lan, ip->mark, ip->mark);\r
dee5592e 1043 safe_run(str);\r
007c44c5 1044 }\r
1045\r
1046 /* -------------------------------------------------------- upload class */\r
260c2719 1047#ifdef DEBUG\r
007c44c5 1048 printf("up: %dk-%dk)\n", (int)((ip->min/ip->keyword->asymetry_ratio)-ip->keyword->asymetry_fixed), \r
1049 (int)((ip->max/ip->keyword->asymetry_ratio)-ip->keyword->asymetry_fixed));\r
260c2719 1050#endif\r
007c44c5 1051\r
1052 sprintf(str,"%s class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit burst %dk prio %d",\r
1053 tc, wan, ip->group, ip->mark,\r
1054 (int)((ip->min/ip->keyword->asymetry_ratio)-ip->keyword->asymetry_fixed),\r
1055 (int)((ip->max/ip->keyword->asymetry_ratio)-ip->keyword->asymetry_fixed), burst, ip->prio);\r
1056 safe_run(str);\r
1057 \r
260c2719 1058 if(strcmpi(ip->keyword->leaf_discipline, "none"))\r
dee5592e 1059 {\r
be96b71b 1060 sprintf(str, "%s qdisc add dev %s parent 1:%d handle %d %s",\r
1061 tc, wan, ip->mark, ip->mark, ip->keyword->leaf_discipline); /*qos_leaf*/\r
dee5592e 1062 safe_run(str);\r
1063 } \r
be96b71b 1064\r
260c2719 1065 if(filter_type == 1)\r
dee5592e 1066 {\r
be96b71b 1067 sprintf(str, "%s filter add dev %s parent 1:0 protocol ip handle %d fw flowid 1:%d",\r
1068 tc, wan, ip->mark, ip->mark);\r
dee5592e 1069 safe_run(str);\r
007c44c5 1070 }\r
be96b71b 1071 \r
6fb3c58a 1072 if(f > 0)\r
be96b71b 1073 {\r
457d52f2 1074 fprintf(f, "%s %d\n", ip->addr, ip->mark);\r
be96b71b 1075 }\r
007c44c5 1076 }\r
1077 else\r
260c2719 1078 {\r
1079#ifdef DEBUG\r
007c44c5 1080 printf("(sharing %s)\n", ip->sharing);\r
260c2719 1081#endif\r
1082 }\r
007c44c5 1083 i++;\r
1084 }\r
6fb3c58a 1085 if(f > 0)\r
be96b71b 1086 {\r
1087 puts("done.");\r
1088 fclose(f);\r
1089 }\r
1090 \r
007c44c5 1091 if(idxs)\r
1092 {\r
dee5592e 1093 chain_forward = "forw_common";\r
1094 chain_postrouting = "post_common";\r
007c44c5 1095 }\r
1096 else\r
1097 {\r
dee5592e 1098 chain_forward = "FORWARD";\r
1099 chain_postrouting = "POSTROUTING";\r
007c44c5 1100 }\r
dee5592e 1101 /* -------------------------------- classify or reject free download */\r
007c44c5 1102 {\r
b6a8d473 1103 char *final_chain = "DROP"; /* REJECT would be better, but it is impossible in mangle */\r
be96b71b 1104 if(free_min)\r
1105 {\r
1106 final_chain = "ACCEPT";\r
1107 }\r
dee5592e 1108 if(qos_proxy)\r
1109 {\r
1110 if(free_min)\r
1111 {\r
be96b71b 1112 sprintf(str,"-A %s -s %s -p tcp --sport %d -o %s -j %s%d",\r
1113 chain_postrouting,proxy_ip,proxy_port,lan,mark_iptables,3);\r
dee5592e 1114 save_line(str);\r
1115 }\r
be96b71b 1116 sprintf(str,"-A %s -s %s -p tcp --sport %d -o %s -j %s",\r
1117 chain_postrouting,proxy_ip,proxy_port,lan,final_chain);\r
dee5592e 1118 save_line(str);\r
1119 }\r
1120 if(free_min)\r
1121 {\r
be96b71b 1122 sprintf(str,"-A %s -o %s -j %s%d", chain_postrouting, lan, mark_iptables, 3);\r
dee5592e 1123 save_line(str);\r
1124 }\r
be96b71b 1125 sprintf(str,"-A %s -o %s -j %s", chain_postrouting, lan, final_chain);\r
dee5592e 1126 save_line(str);\r
1127 /* ------------------------------- classify or reject free upload */\r
1128 if(free_min)\r
1129 {\r
be96b71b 1130 sprintf(str,"-A %s -o %s -j %s%d", chain_forward, wan, mark_iptables, 3);\r
dee5592e 1131 save_line(str);\r
1132 }\r
be96b71b 1133 sprintf(str,"-A %s -o %s -j %s", chain_forward, wan, final_chain);\r
dee5592e 1134 save_line(str);\r
007c44c5 1135 }\r
abe9b855 1136\r
dee5592e 1137 if(free_min) /* allocate free bandwith if it is not zero... */ \r
1138 {\r
1139 /*-----------------------------------------------------------------*/\r
1140 puts("Generating free bandwith classes ...");\r
1141 /*-----------------------------------------------------------------*/\r
208112af 1142 sprintf(str, "%s class add dev %s parent 1:%d classid 1:3 htb rate %dkbit ceil %dkbit burst %dk prio %d",\r
be96b71b 1143 tc, lan, parent, free_min, free_max,burst, lowest_priority);\r
dee5592e 1144 safe_run(str);\r
208112af 1145 sprintf(str, "%s class add dev %s parent 1:%d classid 1:3 htb rate %dkbit ceil %dkbit burst %dk prio %d",\r
be96b71b 1146 tc, wan, parent, free_min, free_max, burst, lowest_priority);\r
dee5592e 1147 safe_run(str);\r
1148 /* tc SFQ */\r
260c2719 1149 if(strcmpi(qos_leaf, "none"))\r
dee5592e 1150 {\r
be96b71b 1151 sprintf(str,"%s qdisc add dev %s parent 1:3 handle 3 %s", tc, lan, qos_leaf);\r
dee5592e 1152 safe_run(str);\r
1153 \r
be96b71b 1154 sprintf(str,"%s qdisc add dev %s parent 1:3 handle 3 %s", tc, wan, qos_leaf);\r
dee5592e 1155 safe_run(str);\r
1156 } \r
1157 /* tc handle 1 fw flowid */\r
be96b71b 1158 sprintf(str,"%s filter add dev %s parent 1:0 protocol ip handle 3 fw flowid 1:3", tc, lan);\r
dee5592e 1159 safe_run(str);\r
007c44c5 1160\r
be96b71b 1161 sprintf(str,"%s filter add dev %s parent 1:0 protocol ip handle 3 fw flowid 1:3", tc, wan);\r
dee5592e 1162 safe_run(str);\r
007c44c5 1163 }\r
dee5592e 1164 printf("Total IP count: %d\n", i);\r
1165 run_restore(); \r
260c2719 1166 if(log_file)\r
1167 {\r
1168 fclose(log_file);\r
1169 }\r
007c44c5 1170 return 0;\r
007c44c5 1171 /* that's all folks, thank you for reading it all the way up to this point ;-) */\r
1172 /* bad luck C<<1 is not yet finished, I promise no sprintf() next time... */\r
1173}\r
This page took 1.341914 seconds and 4 git commands to generate.