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