1 /* =============================================================== */
2 /* == Prometheus QoS - you can "steal fire" from your ISP == */
3 /* == "fair-per-IP" quality of service (QoS) utility == */
4 /* == requires Linux 2.4.x or 2.6.x with HTB support == */
5 /* == Copyright(C) 2005-2008 Michael Polak (xChaos) == */
6 /* == iptables-restore support Copyright(C) 2007-2008 ludva == */
7 /* == Credit: CZFree.Net,Martin Devera,Netdave,Aquarius,Gandalf == */
8 /* =============================================================== */
10 /* Modified: xChaos, 20080201
13 Prometheus QoS is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2.1 of
16 the License, or (at your option) any later version.
18 Prometheus QoS is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with Prometheus Qos; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 GNU General Public License is located in file COPYING */
30 #define FIRSTGROUPID 1024
31 #define FIRSTIPCLASS 2048
36 const char *version
="0.7.8"; /*0.7.9 will be last development, 0.8.0 first stable */
38 /* ======= Help screen is hopefuly self-documenting part of code :-) ======= */
42 puts("Command line switches:\n\
44 -?, --help this help screen\n\
45 -v, --version show version number of this utility and exit\n\
46 -c filename force alternative /etc/prometheus.conf filename\n\
47 -h filename force alternative /etc/hosts filename (overrides hosts keyword)\n\
48 -f just flush iptables and tc classes and exit (stop shaping)\n\
49 -9 emergency iptables flush (do not read data transfer statistics)\n\
50 -p just generate preview of data transfer statistics and exit\n\
51 -n no delay (overrides qos-free-delay keyword)\n\
52 -d dry run (preview tc and iptables commands on stdout)\n\
56 /* === Configuraration file values defaults - stored in global variables ==== */
58 int filter_type
=1; /*1 mark, 2 classify*/
60 char *mark_iptables
="MARK --set-mark ";
61 int dry_run
=0; /* preview - use puts() instead of system() */
62 char *config
="/etc/prometheus/prometheus.conf"; /* main configuration file */
63 char *hosts
="/etc/prometheus/hosts"; /* line bandwidth definition file */
64 char *tc
="/sbin/tc"; /* requires tc with HTB support */
65 char *iptables
="/sbin/iptables"; /* requires iptables utility */
66 char *iptablessave
="/sbin/iptables-save"; /* new */
67 char *iptablesrestore
="/sbin/iptables-restore"; /* new */
68 char *iptablesfile
="/var/spool/prometheus.iptables"; /* new; file for iptables-restore*/
69 char *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]";
70 FILE *iptables_file
=NULL
;
71 char *html
="/var/www/traffic.html"; /* hall of fame filename */
72 char *preview
="/var/www/preview.html"; /* hall of fame preview */
73 char *cmdlog
="/var/log/prometheus"; /* command log filename */
74 char *credit
="/var/run/prometheus.credit"; /* credit log file */
75 int enable_credit
=1; /* enable credit file */
76 int use_credit
=0; /* use credit file (if enabled)*/
77 char *log_dir
="/var/www/logs/"; /* log directory pathname */
78 char *log_url
="logs/"; /* log directory URL prefix */
79 char *title
="Hall of Fame - Greatest Suckers"; /* hall of fame title */
80 int hall_of_fame
=1; /* enable hall of fame */
81 char *lan
="eth0"; /* LAN interface */
82 char *lan_medium
="100Mbit"; /* 10Mbit/100Mbit ethernet */
83 char *wan
="eth1"; /* WAN/ISP interface */
84 char *wan_medium
="100Mbit"; /* 10Mbit/100Mbit ethernet */
85 char *qos_leaf
="sfq perturb 5"; /* leaf discipline */
86 char *qos_free_zone
=NULL
; /* QoS free zone */
87 int qos_proxy
=1; /* include proxy port to QoS */
88 int include_upload
=1; /* upload+download=total traffic */
89 char *proxy_ip
="192.168.1.1/32"; /* our IP with proxy port */
90 int proxy_port
=3128; /* proxy port number */
91 long long int line
=1024; /* WAN/ISP download in kbps */
92 long long int up
=1024; /* WAN/ISP upload in kbps */
93 int free_min
=32; /* minimum guaranted bandwidth for all undefined hosts */
94 int free_max
=64; /* maximum allowed bandwidth for all undefined hosts */
95 int qos_free_delay
=0; /* seconds to sleep before applying new QoS rules */
96 int digital_divide
=2; /* controls digital divide weirdness ratio, 1...3 */
97 int max_nesting
=3; /* maximum nesting of HTB clases, built-in maximum seems to be 4 */
99 int burst
=8; /* HTB burst (in kbits) */
102 int magic_priorities
=8; /* number of priority levels (soft shaping) */
103 int magic_treshold
=8; /* reduce ceil by X*magic_treshhold kbps (hard shaping) */
106 /* not yet implemented:
107 int fixed_packets=0; maximum number of pps per IP address (not class!)
108 int packet_limit=5; maximum number of pps to htn CEIL, not rate !!!
112 char *kwd
="via-prometheus"; /* /etc/hosts comment, eg. #qos-64-128 */
114 const int idxtable_treshold1
=24; /* this is no longer configurable */
115 const int idxtable_treshold2
=12; /* this is no longer configurable */
116 const int idxtable_bitmask1
=3; /* this is no longer configurable */
117 const int idxtable_bitmask2
=3; /* this is no longer configurable */
120 /* not yet implemented:
121 -s start shaping! (keep data transfer statistics - but apply shaping)\n\
122 -r just reload configuration (...and keep data transfer statistics)\n\
125 /* ==== This is C<<1 stuff - learn C<<1 first! http://cll1.arachne.cz ==== */
139 unsigned long long direct
;
140 unsigned long long proxy
;
141 unsigned long long upload
;
142 unsigned long long traffic
;
143 unsigned long long credit
;
144 unsigned long pktsup
;
145 unsigned long pktsdown
;
146 struct Keyword
*keyword
;
148 } *ips
=NULL
, *ip
, *sharedip
;
157 } *groups
=NULL
, *group
;
163 struct Index
*parent
;
167 } *idxs
=NULL
, *idx
, *metaindex
;
173 int asymetry_ratio
; /* ratio for ADSL-like upload */
174 int asymetry_fixed
; /* fixed treshold for ADSL-like upload */
175 int data_limit
; /* hard shaping: apply magic_treshold if max*data_limit MB exceeded */
176 int data_prio
; /* soft shaping (qos): reduce HTB prio if max*data_prio MB exceeded */
177 long fixed_limit
; /* fixed data limit for setting lower HTB ceil */
178 long fixed_prio
; /* fixed data lmit for setting lower HTB prio */
179 int reserve_min
; /* bonus for nominal HTB rate bandwidth (in kbps) */
180 int reserve_max
; /* malus for nominal HTB ceil (in kbps) */
181 // int divide_max; /* relative malus: new_ceil=rate+(old_ceil-rate)/divide_max */
182 // int htb_ceil_bonus_divide; /* relative bonus: new_ceil=old_ceil+old_ceil/htb_ceil_bonus_divide */
183 int default_prio
; /* default HTB priority for this keyword */
186 char *leaf_discipline
;
189 } *keyword
,*defaultkeyword
=NULL
,*keywords
=NULL
;
191 /* Damned, this must be object oriented! This looks almost like constructor ;-) */
201 ip
->mark
=ip
->min
=ip
->max
=ip
->desired
=ip
->credit
=0;
202 ip
->upload
=ip
->proxy
=ip
->direct
=ip
->traffic
=0;
203 ip
->pktsup
=ip
->pktsdown
=0;
204 ip
->keyword
=keywords
;
208 /* ====== Iptables indexes are used to reduce complexity to log8(N) ===== */
210 char *very_ugly_ipv4_code(char *inip
,int bitmask
,int format_as_chainname
)
212 /* warning: this function was debugged only for bitmask values 20,24,28 !!!*/
214 char *ip
,*outip
,*outptr
,*fmt
;
217 /* debug printf("(%s,%d) -> ",ip,bitmask); */
219 if(ip
&& *ip
&& bitmask
>=0 && bitmask
<=32)
220 string(outip
,strlen(ip
)+10); /*fuck unicode? assertion: 10>strlen("_%d_%d") */
222 /* should never exit here */
229 if(dot
<(bitmask
/8-1))
231 if(format_as_chainname
)
240 char *cutdot
=strchr(ip
+1,'.'); /*for bitmask<24*/
241 if(cutdot
)*cutdot
='\0';
242 if(format_as_chainname
)
247 n
=atoi(ip
+1)-atoi(ip
+1)%(1<<(8-bitmask
%8));
251 /*debug printf("%d/%d => [_%d_%d]\n",atoi(ip+1),bitmask,n,bitmask); */
252 sprintf(outptr
,fmt
,n
,bitmask
);
253 if(!format_as_chainname
) while(bitmask
<24)
258 /* debug printf("[%s]\n",outip); */
269 /*should never exit here*/
274 char *hash_id(char *ip
,int bitmask
)
275 { return very_ugly_ipv4_code(ip
,bitmask
,1); }
277 char *subnet_id(char *ip
,int bitmask
)
278 { return very_ugly_ipv4_code(ip
,bitmask
,0); }
280 /* ================= Let's parse configuration file here =================== */
282 void reject_config_and_exit(char *filename
)
284 printf("Configuration file %s rejected - abnormal exit.",filename
);
288 void get_config(char *config_filename
)
292 printf("Configured keywords: ");
293 parse(config_filename
)
295 option("keyword",kwd
);
300 create(keyword
,Keyword
);
302 keyword
->asymetry_ratio
=1; /* ratio for ADSL-like upload */
303 keyword
->asymetry_fixed
=0; /* fixed treshold for ADSL-like upload */
304 keyword
->data_limit
=8; /* hard shaping: apply magic_treshold if max*data_limit MB exceeded */
305 keyword
->data_prio
=4; /* soft shaping (qos): reduce HTB prio if max*data_prio MB exceeded */
306 keyword
->fixed_limit
=0; /* fixed data limit for setting lower HTB ceil */
307 keyword
->fixed_prio
=0; /* fixed data limit for setting lower HTB prio */
308 keyword
->reserve_min
=8; /* bonus for nominal HTB rate bandwidth (in kbps) */
309 keyword
->reserve_max
=0; /* malus for nominal HTB ceil (in kbps) */
311 keyword->divide_max=0; relative malus: new_ceil=rate+(old_ceil-rate)/divide_max
312 keyword->htb_ceil_bonus_divide=0; relative bonus: new_ceil=old_ceil+old_ceil/htb_ceil_bonus_divide
314 keyword
->default_prio
=1;
315 keyword
->html_color
="000000";
317 keyword
->leaf_discipline
="";
319 push(keyword
,keywords
);
320 if(!defaultkeyword
) defaultkeyword
=keyword
;
325 else every(keyword
,keywords
)
327 int l
=strlen(keyword
->key
);
330 if(!strncmp(keyword
->key
,_
,l
) && strlen(_
)>l
+2)
332 char *tmptr
=_
; /* <---- l+1 ----> */
333 _
+=l
+1; /* via-prometheus-asymetry-ratio, etc. */
334 ioption("asymetry-ratio",keyword
->asymetry_ratio
);
335 ioption("asymetry-treshold",keyword
->asymetry_fixed
);
336 ioption("magic-relative-limit",keyword
->data_limit
);
337 ioption("magic-relative-prio",keyword
->data_prio
);
338 loption("magic-fixed-limit",keyword
->fixed_limit
);
339 loption("magic-fixed-prio",keyword
->fixed_prio
);
340 ioption("htb-default-prio",keyword
->default_prio
);
341 ioption("htb-rate-bonus",keyword
->reserve_min
);
342 ioption("htb-ceil-malus",keyword
->reserve_max
);
344 ioption("htb-ceil-divide",keyword->divide_max);
345 ioption("htb-ceil-bonus-divide",keyword->htb_ceil_bonus_divide);
347 option("leaf-discipline",keyword
->leaf_discipline
);
348 option("html-color",keyword
->html_color
);
351 if(keyword
->data_limit
|| keyword
->fixed_limit
||
352 keyword
->data_prio
|| keyword
->fixed_prio
)
360 option("iptables",iptables
);
361 option("iptables-save",iptablessave
); /* new */
362 option("iptables-restore",iptablesrestore
); /* new */
363 option("iptables-file",iptablesfile
); /* new */
364 option("hosts",hosts
);
365 option("lan-interface",lan
);
366 option("wan-interface",wan
);
367 option("lan-medium",lan_medium
);
368 option("wan-medium",wan_medium
);
369 lloption("wan-download",line
);
370 lloption("wan-upload",up
);
371 ioption("hall-of-fame-enable",hall_of_fame
);
372 option("hall-of-fame-title",title
);
373 option("hall-of-fame-filename",html
);
374 option("hall-of-fame-preview",preview
);
375 option("log-filename",cmdlog
);
376 option("credit-filename",credit
);
377 ioption("credit-enable",enable_credit
);
378 option("log-traffic-directory",log_dir
);
379 option("log-traffic-url-path",log_url
);
380 option("qos-free-zone",qos_free_zone
);
381 ioption("qos-free-delay",qos_free_delay
);
382 ioption("qos-proxy-enable",qos_proxy
);
383 option("qos-proxy-ip",proxy_ip
);
384 option("htb-leaf-discipline",qos_leaf
);
385 ioption("qos-proxy-port",proxy_port
);
386 ioption("free-rate",free_min
);
387 ioption("free-ceil",free_max
);
388 ioption("htb-burst",burst
);
389 ioption("htb-burst-main",burst_main
);
390 ioption("htb-burst-group",burst_group
);
391 ioption("htb-nesting-limit",max_nesting
);
392 ioption("htb-r2q",htb_r2q
);
393 ioption("magic-include-upload",include_upload
);
394 ioption("magic-priorities",magic_priorities
);
395 ioption("magic-treshold",magic_treshold
);
397 option("filter-type", cnf
);
399 /* not yet implemented:
400 ioption("magic-fixed-packets",fixed_packets);
401 ioption("magic-relative-packets",packet_limit);
406 perror(config_filename
);
407 puts("Warning - using built-in defaults instead ...");
412 /*leaf discipline for keywords*/
413 every(keyword
,keywords
)
415 if (!strcmpi(keyword
->leaf_discipline
, "")){
416 keyword
->leaf_discipline
= qos_leaf
;
420 if (strcmpi(cnf
, "mark")){
423 mark_iptables
= "CLASSIFY --set-class 1:";
427 mark_iptables
= "MARK --set-mark ";
430 /* are supplied values meaningful ?*/
433 puts("Illegal value of wan bandwidth: 0 kbps.");
434 reject_config_and_exit(config_filename
);
438 /* ===================== traffic analyser - uses iptables ================ */
440 void get_traffic_statistics(void)
445 textfile(Pipe
,str
) *line
,*lines
=NULL
;
449 sprintf(cmd
,"%s -L -v -x -n -t mangle",iptables
);
461 int col
, accept
=0,proxyflag
=0,valid
=1,setchainname
=0,commonflag
=0;
462 unsigned long long traffic
=0;
463 unsigned long pkts
=0;
464 char *ipaddr
=NULL
,*ptr
;
466 /* debug puts(line->str); */
467 valid_columns(ptr
,line
->str
,' ',col
)
468 if(valid
) switch(col
)
470 case 1: if(eq(ptr
,"Chain"))
472 else if(eq(ptr
,"pkts"))
475 sscanf(ptr
,"%lu",&pkts
);
477 case 2: if(setchainname
)
479 if(!strncmp(ptr
,"post_",5) || eq(ptr
,"POSTROUTING"))
482 if(!strncmp(ptr
,"forw_",5) || eq(ptr
,"FORWARD"))
485 if(eq(ptr
,"post_common") || eq(ptr
,"forw_common"))
489 sscanf(ptr
,"%Lu",&traffic
); traffic
+=(1<<19); traffic
>>=20;
491 case 3: if((strncmp(ptr
,"post_",5) && strncmp(ptr
,"forw_",5)) || commonflag
)
493 /*if (filter_type==1) accept=eq(ptr,"MARK"); else accept=eq(ptr,"CLASSIFY");*/
495 case 8: if(downloadflag
)
497 if(strstr(proxy_ip
,ptr
))proxyflag
=1;
502 case 9: if(downloadflag
)ipaddr
=ptr
;break;
505 if(accept
&& traffic
>0 && ipaddr
)
507 if(proxyflag
)printf("(proxy) ");
508 else if(!downloadflag
) printf("(upload) ");
509 printf("IP %s: %Lu M (%ld pkts)\n", ipaddr
, traffic
, pkts
);
510 find(ip
,ips
,eq(ip
->addr
,ipaddr
));
515 if(eq(ip
->addr
,"0.0.0.0/0"))
517 ip
->name
="(unregistered)";
519 ip
->max
=ip
->desired
=free_max
;
528 ip
->traffic
+=traffic
;
529 ip
->direct
=ip
->traffic
-ip
->upload
-ip
->proxy
;
537 ip
->traffic
+=traffic
;
539 if(traffic
>ip
->traffic
)
549 /* ========== This function executes, logs OR ALSO prints command ========== */
551 void safe_run(char *cmd
)
553 if(dry_run
) printf("\n=>%s\n",cmd
); else system(cmd
);
554 if(log_file
) fprintf(log_file
,"%s\n",cmd
);
557 void save_line(char *line
)
559 fprintf(iptables_file
,"%s\n",line
);
562 void run_restore(void)
565 string(restor
,STRLEN
);
568 fclose(iptables_file
);
576 //sprintf(restor,"cat %s",iptablesfile); else
577 sprintf(restor
,"%s <%s",iptablesrestore
, iptablesfile
);
584 /* == This function strips extra characters after IP address and stores it = */
586 void parse_ip(char *str
)
588 char *ptr
=str
,*ipaddr
=NULL
,*ipname
=NULL
;;
590 while(*ptr
&& *ptr
!=' ' && *ptr
!=9)
596 while(*ptr
&& (*ptr
==' ' || *ptr
==9))
599 while(*ptr
&& *ptr
!=' ' && *ptr
!=9)
603 find(ip
,ips
,eq(ip
->addr
,ipaddr
)); else TheIP();
608 char *parse_datafile_line(char *str
)
610 char *ptr
=strchr(str
,' ');
622 /*-----------------------------------------------------------------*/
623 /* Are you looking for int main (int argc, char **argv) ? :-)) */
624 /*-----------------------------------------------------------------*/
632 int class_count
=0,ip_count
=0;
636 int just_preview
=0; /* preview - generate just stats */
637 char *chain_forward
, *chain_postrouting
;
641 Prometheus QoS - \"fair-per-IP\" Quality of Service setup utility.\n\
642 Version %s - Copyright (C)2005-2008 Michael Polak (xChaos)\n\
643 iptables-restore & burst tunning & classify modification 0.7d by Ludva\n\
644 Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version
);
646 /*----- Boring... we have to check command line options first: ----*/
650 argument("-c") { nextargument(config
); }
651 argument("-h") { nextargument(althosts
);}
652 argument("-d") { dry_run
=1; }
653 argument("-f") { just_flush
=1; }
654 argument("-9") { just_flush
=9; }
655 argument("-p") { just_preview
=1; }
656 argument("-n") { nodelay
=1; }
657 argument("-?") { help(); exit(0); }
658 argument("--help") { help(); exit(0); }
659 argument("-v") { exit(0); }
660 argument("--version") { exit(0); }
664 puts("*** THIS IS JUST DRY RUN ! ***\n");
666 date(d
); /* this is typical cll1.h macro */
668 /*-----------------------------------------------------------------*/
669 printf("Parsing configuration file %s ...\n", config
);
670 /*-----------------------------------------------------------------*/
673 if(althosts
) hosts
=althosts
;
677 /*-----------------------------------------------------------------*/
678 puts("Parsing iptables verbose output ...");
679 /*-----------------------------------------------------------------*/
680 get_traffic_statistics();
683 /*-----------------------------------------------------------------*/
684 printf("Parsing class defintion file %s ...\n", hosts
);
685 /*-----------------------------------------------------------------*/
686 int groupidx
= FIRSTGROUPID
;
691 if(*str
<'0' || *str
>'9')
694 //Does this IP share QoS class with some other ?
695 substring
=strstr(str
,"sharing-");
698 substring
+=8; //"sharing-"
701 ip
->sharing
=substring
;
702 ip
->keyword
=defaultkeyword
; /* settings for default keyword */
703 while(*substring
&& *substring
!='\n')
709 //Do we have to create new QoS class for this IP ?
711 find(keyword
,keywords
,(substring
=strstr(str
,keyword
->key
)))
717 ip
->prio
=keyword
->default_prio
;
718 substring
+=strlen(keyword
->key
)+1;
720 while(*ptr
&& *ptr
!='-')
725 ip
->max
=ip
->desired
=atoi(ptr
+1);
727 ip
->min
=atoi(substring
);
730 puts("Illegal value of minimum bandwidth: 0 kbps.");
731 reject_config_and_exit(hosts
);
736 ip
->max
=ip
->min
+ip
->keyword
->reserve_min
;
740 ip
->max
-=ip
->keyword
->reserve_max
;
743 if(ip->keyword->divide_max>1)
744 ip->max=ip->min+(ip->max-ip->min)/ip->keyword->divide_max;
745 if(ip->keyword->htb_ceil_bonus_divide>0)
746 ip->max+=ip->max/ip->keyword->htb_ceil_bonus_divide;
751 ip
->mark
=FIRSTIPCLASS
+1+class_count
++;
753 find(group
,groups
,group
->min
==ip
->min
)
756 group
->desired
+=ip
->min
;
757 ip
->group
= group
->id
;
763 group
->id
= groupidx
++;
764 ip
->group
= group
->id
;
766 if(group
->min
<8) group
->min
=8;
767 /* Warning - this is maybe because of primitive tc namespace, can be fixed */
768 /* it is because class IDs are derived from min. bandwidth. - xCh */
769 //if(group->min>MAX_GUARANTED_KBPS) group->min=MAX_GUARANTED_KBPS;
772 group
->desired
=ip
->min
;
773 insert(group
,groups
,desc_order_by
,min
);
785 /*-----------------------------------------------------------------*/
786 /* cll1.h - let's allocate brand new character buffer... */
787 /*-----------------------------------------------------------------*/
790 /*-----------------------------------------------------------------*/
791 puts("Resolving shared connections ...");
792 /*-----------------------------------------------------------------*/
793 search(ip
,ips
,ip
->sharing
)
795 search(sharedip
,ips
,eq(sharedip
->name
,ip
->sharing
))
797 sharedip
->traffic
+=ip
->traffic
;
799 ip
->mark
=sharedip
->mark
;
803 printf("Unresolved shared connection: %s %s sharing-%s\n",ip
->addr
,ip
->name
,ip
->sharing
);
806 if(enable_credit
&& just_flush
<9)
808 /*-----------------------------------------------------------------*/
809 printf("Parsing credit file %s ...\n", credit
);
810 /*-----------------------------------------------------------------*/
813 ptr
=parse_datafile_line(_
);
816 find(ip
,ips
,eq(ip
->addr
,_
))
817 sscanf(ptr
,"%Lu",&(ip
->credit
));
825 /*-----------------------------------------------------------------*/
826 puts("Initializing iptables and tc classes ...");
827 /*-----------------------------------------------------------------*/
829 iptables_file
=fopen(iptablesfile
,"w");
830 if (iptables_file
== NULL
) {
831 puts("Cannot open iptablesfile!");
835 log_file
=fopen(cmdlog
,"w");
836 if (log_file
== NULL
) {
837 puts("Cannot open logfile!");
841 save_line(iptablespreamble
);
844 sprintf(str
,"%s qdisc del dev %s root 2>/dev/null",tc
,lan
);
847 sprintf(str
,"%s qdisc del dev %s root 2>/dev/null",tc
,wan
);
850 iptables_file
=fopen(iptablesfile
,"w");
851 save_line(iptablespreamble
);
853 if(qos_free_zone
&& *qos_free_zone
!='0')
857 sprintf(str
,"-A FORWARD -d %s -o %s -j ACCEPT", qos_free_zone
, wan
);
862 save_line(":post_noproxy - [0:0]");
863 sprintf(str
,"-A POSTROUTING -p ! tcp -o %s -j post_noproxy", lan
);
865 sprintf(str
,"-A POSTROUTING -s ! %s -o %s -j post_noproxy", proxy_ip
, lan
);
867 sprintf(str
,"-A POSTROUTING -s %s -p tcp --sport ! %d -o %s -j post_noproxy", proxy_ip
, proxy_port
, lan
);
870 chain
="post_noproxy";
875 sprintf(str
,"-A %s -s %s -o %s -j ACCEPT", chain
, qos_free_zone
, lan
);
879 if(ip_count
>idxtable_treshold1
&& !just_flush
)
881 int idxcount
=0, bitmask
=32-idxtable_bitmask1
; /* default net mask: 255.255.255.240 */
883 /*-----------------------------------------------------------------*/
884 printf("Detected %d addresses - indexing iptables rules to improve performance...\n",ip_count
);
885 /*-----------------------------------------------------------------*/
887 save_line(":post_common - [0:0]");
888 save_line(":forw_common - [0:0]");
890 search(ip
,ips
,ip
->addr
&& *(ip
->addr
) && !eq(ip
->addr
,"0.0.0.0/0"))
892 buf
=hash_id(ip
->addr
,bitmask
);
893 find(idx
,idxs
,eq(idx
->id
,buf
))
900 idx
->bitmask
=bitmask
;
908 /* brutal perfomance optimalization */
909 while(idxcount
>idxtable_treshold2
&& bitmask
>2*idxtable_bitmask2
)
911 bitmask
-=idxtable_bitmask2
;
913 search(idx
,idxs
,idx
->parent
==NULL
)
915 buf
=hash_id(idx
->addr
,bitmask
);
916 find(metaindex
,idxs
,eq(metaindex
->id
,buf
))
917 metaindex
->children
++;
920 create(metaindex
,Index
);
921 metaindex
->addr
=idx
->addr
;
923 metaindex
->bitmask
=bitmask
;
924 metaindex
->parent
=NULL
;
925 metaindex
->children
=0;
927 push(metaindex
,idxs
);
929 idx
->parent
=metaindex
;
933 /* this should slightly optimize throughout ... */
934 sort(idx
,idxs
,desc_order_by
,children
);
935 sort(idx
,idxs
,order_by
,bitmask
);
940 subnet
=subnet_id(idx
->addr
,idx
->bitmask
);
941 printf("%d: %s/%d\n",++i
,subnet
,idx
->bitmask
);
943 sprintf(str
,":post_%s - [0:0]", idx
->id
);
946 sprintf(str
,":forw_%s - [0:0]", idx
->id
);
951 string(buf
,strlen(idx
->parent
->id
)+6);
952 sprintf(buf
,"post_%s",idx
->parent
->id
);
957 sprintf(str
,"-A %s -d %s/%d -o %s -j post_%s", buf
, subnet
, idx
->bitmask
, lan
, idx
->id
);
960 sprintf(str
,"-A %s -d %s/%d -o %s -j post_common", buf
, subnet
, idx
->bitmask
, lan
);
965 string(buf
,strlen(idx
->parent
->id
)+6);
966 sprintf(buf
,"forw_%s",idx
->parent
->id
);
971 sprintf(str
,"-A %s -s %s/%d -o %s -j forw_%s", buf
, subnet
, idx
->bitmask
, wan
, idx
->id
);
974 sprintf(str
,"-A %s -s %s/%d -o %s -j forw_common", buf
, subnet
, idx
->bitmask
, wan
);
977 printf("Total indexed iptables chains created: %d\n", i
);
979 sprintf(str
,"-A FORWARD -o %s -j forw_common", wan
);
982 sprintf(str
,"-A POSTROUTING -o %s -j post_common", lan
);
990 fclose(iptables_file
);
991 if (log_file
) fclose(log_file
);
992 puts("Just flushed iptables and tc classes - now exiting ...");
998 if(!dry_run
&& !nodelay
&& qos_free_delay
)
1000 printf("Flushed iptables and tc classes - now sleeping for %d seconds...\n",qos_free_delay
);
1001 sleep(qos_free_delay
);
1004 sprintf(str
,"%s qdisc add dev %s root handle 1: htb r2q %d default 1",tc
,lan
,htb_r2q
);
1007 sprintf(str
,"%s class add dev %s parent 1: classid 1:2 htb rate %s ceil %s burst %dk prio 0",tc
,lan
,lan_medium
,lan_medium
,burst_main
);
1010 sprintf(str
,"%s class add dev %s parent 1:2 classid 1:1 htb rate %Ldkbit ceil %Ldkbit burst %dk prio 0",tc
,lan
,line
,line
,burst_main
);
1013 sprintf(str
,"%s qdisc add dev %s root handle 1: htb r2q %d default 1",tc
,wan
,htb_r2q
);
1016 sprintf(str
,"%s class add dev %s parent 1: classid 1:2 htb rate %s ceil %s burst %dk prio 0",tc
,wan
,wan_medium
,wan_medium
,burst_main
);
1019 sprintf(str
,"%s class add dev %s parent 1:2 classid 1:1 htb rate %Ldkbit ceil %Ldkbit burst %dk prio 0",tc
,wan
,up
,up
,burst_main
);
1023 /*-----------------------------------------------------------------*/
1024 puts("Locating suckers and generating root classes ...");
1025 /*-----------------------------------------------------------------*/
1026 sort(ip
,ips
,desc_order_by
,traffic
);
1029 /*-----------------------------------------------------------------*/
1030 /* sub-scope - local variables */
1032 long long int rate
=line
;
1033 long long int max
=line
;
1035 FILE *credit_file
=NULL
;
1037 if(!just_preview
&& !dry_run
&& enable_credit
) credit_file
=fopen(credit
,"w");
1045 sprintf(str
,"%s class add dev %s parent 1:%d classid 1:%d htb rate %Ldkbit ceil %Ldkbit burst %dk prio 1 #down desired %d",
1046 tc
, lan
, parent
, group
->id
, rate
, max
, burst_group
, group
->desired
);
1050 sprintf(str
,"%s class add dev %s parent 1:%d classid 1:%d htb rate %Ldkbit ceil %Ldkbit burst %dk prio 1 #up desired %d",
1051 tc
, wan
, parent
, group
->id
, rate
*up
/line
, max
*up
/line
, burst_group
, group
->desired
);
1055 if(group_count
++<max_nesting
) parent
=group
->id
;
1057 rate
-=digital_divide
*group
->min
;
1058 if(rate
<group
->min
)rate
=group
->min
;
1060 /*shaping of aggresive downloaders, with credit file support */
1063 int group_rate
=group
->min
, priority_sequence
=magic_priorities
+1;
1065 search(ip
, ips
, ip
->min
==group
->min
&& ip
->max
>ip
->min
)
1067 if( ip
->keyword
->data_limit
&& !ip
->fixedprio
&&
1068 ip
->traffic
>ip
->credit
+
1069 (ip
->min
*ip
->keyword
->data_limit
+(ip
->keyword
->fixed_limit
<<20)) )
1071 if(group_rate
<ip
->max
) ip
->max
=group_rate
;
1072 group_rate
+=magic_treshold
;
1073 ip
->prio
=magic_priorities
+2;
1074 if(ip
->prio
<3) ip
->prio
=3;
1078 if( keyword
->data_prio
&& !ip
->fixedprio
&&
1079 ip
->traffic
>ip
->credit
+
1080 (ip
->min
*ip
->keyword
->data_prio
+(ip
->keyword
->fixed_prio
<<20)) )
1082 ip
->prio
=priority_sequence
--;
1083 if(ip
->prio
<2) ip
->prio
=2;
1088 unsigned long long lcredit
=0;
1090 if((ip
->min
*ip
->keyword
->data_limit
+(ip
->keyword
->fixed_limit
<<20))>ip
->traffic
)
1091 lcredit
=(ip
->min
*ip
->keyword
->data_limit
+(ip
->keyword
->fixed_limit
<<20))-ip
->traffic
;
1092 fprintf(credit_file
,"%s %Lu\n",ip
->addr
,lcredit
);
1099 if(credit_file
)fclose(credit_file
);
1104 f
=fopen(preview
,"w");
1107 else if(!dry_run
&& !just_flush
)
1109 /*-----------------------------------------------------------------*/
1110 printf("Writing data transfer database ...\n");
1111 /*-----------------------------------------------------------------*/
1112 f
=fopen("/var/run/prometheus.previous","w");
1115 search(ip
,ips
,ip
->traffic
|| ip
->direct
|| ip
->proxy
||ip
->upload
)
1116 fprintf(f
,"%s %Lu %Lu %Lu %Lu\n",ip
->addr
,ip
->traffic
,ip
->direct
,ip
->proxy
,ip
->upload
);
1130 /*-----------------------------------------------------------------*/
1131 printf("Sorting data and generating statistics page %s ...\n",ptr
);
1132 /*-----------------------------------------------------------------*/
1134 fputs("<table border>\n<tr><th align=\"right\">#</th><th align=\"right\">group</th><th align=\"right\">IPs</th><th align=\"right\">requested</th>\n",f
);
1135 fprintf(f
,"<th colspan=\"%d\">data limits</th>\n",keywordcount
);
1140 printf("%d k group: %d bandwidth requested: %d k\n",group
->min
,group
->count
,group
->desired
);
1142 fprintf(f
,"<tr><td align=\"right\">%d</td><td align=\"right\">%d k</td>",count
,group
->min
);
1143 fprintf(f
,"<td align=\"right\">%d</td><td align=\"right\">%d k</td>",group
->count
,group
->desired
);
1145 every(keyword
,keywords
)
1146 fprintf(f
,"<td align=\"right\"><font color=\"#%s\">%d M</font></td>",keyword
->html_color
,group
->min
*keyword
->data_limit
);
1149 total
+=group
->count
;
1153 printf("Total groups: %d Total bandwidth requested: %d k\nAGGREGATION: 1/%d\n",count
,i
,i
/line
);
1155 fprintf(f
,"<tr><th colspan=\"2\" align=\"left\">Line %Ld k</td>",line
);
1156 fprintf(f
,"<th align=\"right\">%d</td><th align=\"right\">%d k</td>",total
,i
);
1158 every(keyword
,keywords
)
1159 fprintf(f
,"<th align=\"right\">%d IPs</th>",keyword
->ip_count
);
1161 fprintf(f
,"</tr><tr><th colspan=\"4\">Aggregation 1/%d</th>\n",(int)(0.5+i
/line
));
1162 fprintf(f
,"<th colspan=\"%d\">%d traffic classes</th></tr>\n",keywordcount
,total
);
1164 fputs("</table>\n",f
);
1166 else if(!dry_run
&& !just_flush
)
1172 unsigned long long total
=0, total_direct
=0, total_proxy
=0, total_upload
=0, tmp_sum
=0;
1173 int active_classes
=0;
1176 struct Sum
{unsigned long long l
; int i
; list(Sum
);} *sum
,*sums
=NULL
;
1183 fprintf(f
,"<p><table border>\n<tr><th colspan=\"%d\">%s",colspan
,title
);
1184 fprintf(f
," (%s)</th></tr>\n", d
);
1185 fputs("<tr><td align=\"right\">#</td><td>hostname</td>\
1186 <td align=\"right\">credit</td>\
1187 <td align=\"right\">limit</td>\
1188 <td align=\"right\">total</td>\
1189 <td align=\"right\">direct</td>\n",f
);
1191 fputs("<td align=\"right\">proxy</td>\n",f
);
1192 fputs("<td align=\"right\">upload</td>\
1193 <td align=\"right\">minimum</td>\
1194 <td align=\"right\">desired</td>\
1195 <td align=\"right\">maximum</td>\
1196 <td>prio</td></tr>\n",f
);
1200 char *f1
="", *f2
="";
1201 if(ip
->max
<ip
->desired
)
1203 f1
="<font color=\"red\">";
1208 f1
="<font color=\"brown\">";
1213 printf("%03d. %-22s %10Lu (%d/%d)\n",i
,ip
->name
, ip
->traffic
, ip
->min
, ip
->max
);
1215 fprintf(f
,"<tr><td align=\"right\"><a name=\"%s\"></a>%d</td><td><a href=\"%s%s.log\">%s</a></td><td align=\"right\">%Lu M</td>\n",
1216 ip
->name
, i
, log_url
, ip
->name
, ip
->name
, ip
->credit
);
1217 fprintf(f
,"<td align=\"right\"><font color=\"#%s\">%Lu M</font></td>",ip
->keyword
->html_color
,ip
->credit
+(ip
->min
*ip
->keyword
->data_limit
+(ip
->keyword
->fixed_limit
<<20)));
1218 fprintf(f
,"<td align=\"right\">%s%Lu M%s</td><td align=\"right\">%Lu M</td>\n", f1
, ip
->traffic
, f2
, ip
->direct
);
1220 fprintf(f
,"<td align=\"right\">%Lu M</td>\n", ip
->proxy
);
1221 fprintf(f
,"<td align=\"right\">%Lu M</td>\n", ip
->upload
);
1222 fprintf(f
,"<td align=\"right\">%d k</td><td align=\"right\">%d k</td><td align=\"right\">%s%d k%s</td><td>%s%d%s</td></tr>\n",ip
->min
,ip
->desired
,f1
,ip
->max
,f2
,f1
,ip
->prio
,f2
);
1224 total_direct
+=ip
->direct
;
1225 total_proxy
+=ip
->proxy
;
1226 total_upload
+=ip
->upload
;
1230 tmp_sum
+=ip
->traffic
;
1233 sum
->i
=active_classes
;
1234 insert(sum
,sums
,order_by
,i
);
1241 sprintf(str
,"%s%s.log",log_dir
,ip
->name
);
1242 iplog
=fopen(str
,"a");
1245 fprintf(iplog
,"%ld\t%s\t%Lu\t%Lu\t%Lu\t%Lu\t%s",time(NULL
),ip
->name
,ip
->traffic
, ip
->direct
, ip
->proxy
, ip
->upload
,d
);
1251 fprintf(f
,"<tr><th colspan=\"4 \"align=\"left\">SUMMARY:</td>");
1252 fprintf(f
,"<th align=\"right\">%Lu M</th>\
1253 <th align=\"right\">%Lu M</th>\n", total
, total_direct
);
1255 fprintf(f
,"<th align=\"right\">%Lu M</th>\n", total_proxy
);
1256 fprintf(f
,"<th align=\"right\">%Lu M</th>", total_upload
);
1257 fputs("<td colspan=\"4\"></td></th>\n</table>\n",f
);
1259 if(active_classes
>10)
1261 fputs("<a name=\"erp\"></a><p><table border><tr><th colspan=\"5\">Enterprise Research and Planning (ERP)</th></tr>\n",f
);
1262 fputs("<tr><td>Analytic category</td>\n",f
);
1263 fputs("<td colspan=\"2\" align=\"center\">Active Classes</td><td colspan=\"2\" align=\"center\">Data transfers</td></tr>\n",f
);
1265 find(sum
,sums
,sum
->l
>=total
/4)
1267 fprintf(f
,"<tr><td>Top 25%% of traffic</td>\n");
1268 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
);
1271 find(sum
,sums
,sum
->i
==10)
1273 fprintf(f
,"<tr><td>Top 10 downloaders</td>\n");
1274 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
);
1277 find(sum
,sums
,sum
->l
>=total
/2)
1279 fprintf(f
,"<tr><td>Top 50%% of traffic</td>\n");
1280 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
);
1283 find(sum
,sums
,sum
->l
>=4*total
/5)
1285 fprintf(f
,"<tr><td>Top 80%% of traffic</td>\n");
1286 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
);
1289 find (sum
,sums
,sum
->i
>=(active_classes
+1)/5)
1291 fprintf(f
,"<tr><td>Top 20%% downloaders</td>\n");
1292 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
);
1295 find(sum
,sums
,sum
->i
>=(active_classes
+1)/4)
1297 fprintf(f
,"<tr><td>Top 25%% downloaders</td>\n");
1298 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
);
1301 find(sum
,sums
,sum
->i
>=(active_classes
+1)/2)
1303 fprintf(f
,"<tr><td>Top 50%% downloaders</td>\n");
1304 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
);
1307 find(sum
,sums
,sum
->i
>=4*(active_classes
+1)/5)
1309 fprintf(f
,"<tr><td>Top 80%% downloaders</td>\n");
1310 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
);
1313 fprintf(f
,"<tr><td>All users, all traffic</td>\n");
1314 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
);
1315 fputs("</table>\n",f
);
1317 fprintf(f
,"<small>Statistics generated by Prometheus QoS version %s<br>GPL+Copyright(C)2005-2008 Michael Polak, <a href=\"http://www.arachne.cz/\">Arachne Labs</a></small>\n",version
);
1323 puts("Statistics preview generated (-p switch) - now exiting ...");
1327 /*-----------------------------------------------------------------*/
1328 puts("Generating iptables and tc classes ...");
1329 /*-----------------------------------------------------------------*/
1332 printf("%-22s %-15s mark\n","name","ip");
1333 search(ip
,ips
,ip
->mark
>0)
1339 duplicate(ip
->addr
,buf
);
1340 buf
=hash_id(ip
->addr
,32-idxtable_bitmask1
);
1342 string(chain_forward
,6+strlen(buf
));
1343 strcpy(chain_forward
,"forw_");
1344 strcat(chain_forward
,buf
);
1346 string(chain_postrouting
,6+strlen(buf
));
1347 strcpy(chain_postrouting
,"post_");
1348 strcat(chain_postrouting
,buf
);
1354 chain_forward
="FORWARD";
1355 chain_postrouting
="POSTROUTING";
1358 printf("%-22s %-16s %04d ", ip
->name
, ip
->addr
, ip
->mark
);
1360 /* -------------------------------------------------------- mark download */
1362 sprintf(str
,"-A %s -d %s/32 -o %s -j %s%d",chain_postrouting
,ip
->addr
,lan
,mark_iptables
,ip
->mark
);
1363 /*sprintf(str,"-A %s -d %s/32 -o %s -j MARK --set-mark %d",chain_postrouting,ip->addr,lan,ip->mark);*/
1364 /* -m limit --limit 1/s */
1369 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
);
1370 /*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);*/
1374 sprintf(str
,"-A %s -d %s/32 -o %s -j ACCEPT",chain_postrouting
,ip
->addr
,lan
);
1377 /* -------------------------------------------------------- mark upload */
1378 sprintf(str
,"-A %s -s %s/32 -o %s -j %s%d",chain_forward
,ip
->addr
,wan
,mark_iptables
,ip
->mark
);
1379 /* sprintf(str,"-A %s -s %s/32 -o %s -j MARK --set-mark %d",chain_forward,ip->addr,wan,ip->mark);*/
1382 sprintf(str
,"-A %s -s %s/32 -o %s -j ACCEPT",chain_forward
,ip
->addr
,wan
);
1387 /* -------------------------------------------------------- download class */
1388 printf("(down: %dk-%dk ", ip
->min
, ip
->max
);
1390 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
);
1393 if (strcmpi(ip
->keyword
->leaf_discipline
, "none")){
1394 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*/
1398 if (filter_type
== 1){
1399 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle %d fw flowid 1:%d", tc
, lan
, ip
->mark
, ip
->mark
);
1403 /* -------------------------------------------------------- upload class */
1404 printf("up: %dk-%dk)\n", (int)((ip
->min
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
),
1405 (int)((ip
->max
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
));
1407 sprintf(str
,"%s class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit burst %dk prio %d",
1408 tc
, wan
, ip
->group
, ip
->mark
,
1409 (int)((ip
->min
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
),
1410 (int)((ip
->max
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
), burst
, ip
->prio
);
1413 if (strcmpi(ip
->keyword
->leaf_discipline
, "none")){
1414 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*/
1418 if (filter_type
== 1){
1419 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle %d fw flowid 1:%d",tc
, wan
, ip
->mark
, ip
->mark
);
1424 printf("(sharing %s)\n", ip
->sharing
);
1431 chain_forward
="forw_common";
1432 chain_postrouting
="post_common";
1436 chain_forward
="FORWARD";
1437 chain_postrouting
="POSTROUTING";
1440 /* -------------------------------------------------------- mark download */
1444 sprintf(str
,"-A %s -s %s -p tcp --sport %d -o %s -j MARK --set-mark 3",chain_postrouting
,proxy_ip
,proxy_port
,lan
);
1446 sprintf(str
,"-A %s -s %s -p tcp --sport %d -o %s -j ACCEPT",chain_postrouting
,proxy_ip
,proxy_port
,lan
);
1449 sprintf(str
,"-A %s -o %s -j MARK --set-mark 3",chain_postrouting
,lan
);
1451 sprintf(str
,"-A %s -o %s -j ACCEPT",chain_postrouting
,lan
);
1454 /* -------------------------------------------------------- mark upload */
1455 sprintf(str
,"-A %s -o %s -j MARK --set-mark 3",chain_forward
,wan
);
1457 sprintf(str
,"-A %s -o %s -j ACCEPT",chain_forward
,wan
);
1460 printf("Total IP count: %d\n", i
);
1462 /* ---------------------------------------- tc - free bandwith shared class */
1463 sprintf(str
,"%s class add dev %s parent 1:%d classid 1:3 htb rate %dkbit ceil %dkbit burst %dk prio 2",tc
,lan
,parent
,free_min
,free_max
,burst
);
1466 sprintf(str
,"%s class add dev %s parent 1:%d classid 1:3 htb rate %dkbit ceil %dkbit burst %dk prio 2",tc
,wan
,parent
,free_min
,free_max
,burst
);
1470 if (strcmpi(qos_leaf
, "none")){
1471 sprintf(str
,"%s qdisc add dev %s parent 1:3 handle 3 %s",tc
,lan
,qos_leaf
);
1474 sprintf(str
,"%s qdisc add dev %s parent 1:3 handle 3 %s",tc
,wan
,qos_leaf
);
1478 /* tc handle 1 fw flowid */
1479 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle 3 fw flowid 1:3",tc
,lan
);
1482 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle 3 fw flowid 1:3",tc
,wan
);
1487 if (log_file
) fclose(log_file
);
1490 /* that's all folks, thank you for reading it all the way up to this point ;-) */
1491 /* bad luck C<<1 is not yet finished, I promise no sprintf() next time... */
This page took 1.291892 seconds and 4 git commands to generate.