fcba898971e8a84d57445551ffea62ae1d236344
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, 20080202
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 /* ======= All path names are defined hear (for RPM patch) ======= */
40 char *tc
= "/sbin/tc"; /* requires tc with HTB support */
41 char *iptables
= "/sbin/iptables"; /* requires iptables utility */
42 char *iptablessave
= "/sbin/iptables-save"; /* not yet required */
43 char *iptablesrestore
= "/sbin/iptables-restore"; /* requires iptables-restore */
45 char *config
= "/etc/prometheus/prometheus.conf"; /* main configuration file */
46 char *hosts
= "/etc/prometheus/hosts"; /* per-IP bandwidth definition file */
48 char *iptablesfile
= "/var/spool/prometheus.iptables"; /* temporary file for iptables-restore*/
49 char *credit
= "/var/lib/misc/prometheus.credit"; /* credit log file */
50 char *html
= "/var/www/traffic.html"; /* hall of fame filename */
51 char *preview
= "/var/www/preview.html"; /* hall of fame preview */
52 char *cmdlog
= "/var/log/prometheuslog"; /* command log filename */
53 char *log_dir
= "/var/www/logs/"; /* log directory pathname, ended with slash */
54 char *log_url
= "logs/"; /* log directory relative URI prefix (partial URL) */
56 /* ======= Help screen is hopefuly self-documenting part of code :-) ======= */
60 puts("Command line switches:\n\
62 -?, --help this help screen\n\
63 -v, --version show version number of this utility and exit\n\
64 -c filename force alternative /etc/prometheus.conf filename\n\
65 -h filename force alternative /etc/hosts filename (overrides hosts keyword)\n\
66 -f just flush iptables and tc classes and exit (stop shaping)\n\
67 -9 emergency iptables flush (do not read data transfer statistics)\n\
68 -p just generate preview of data transfer statistics and exit\n\
69 -n no delay (overrides qos-free-delay keyword)\n\
70 -d dry run (preview tc and iptables commands on stdout)\n\
74 /* === Configuraration file values defaults - stored in global variables ==== */
76 int filter_type
=1; /*1 mark, 2 classify*/
78 char *mark_iptables
="MARK --set-mark ";
79 int dry_run
=0; /* preview - use puts() instead of system() */
80 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]";
81 FILE *iptables_file
=NULL
;
82 int enable_credit
=1; /* enable credit file */
83 int use_credit
=0; /* use credit file (if enabled)*/
84 char *title
="Hall of Fame - Greatest Suckers"; /* hall of fame title */
85 int hall_of_fame
=1; /* enable hall of fame */
86 char *lan
="eth0"; /* LAN interface */
87 char *lan_medium
="100Mbit"; /* 10Mbit/100Mbit ethernet */
88 char *wan
="eth1"; /* WAN/ISP interface */
89 char *wan_medium
="100Mbit"; /* 10Mbit/100Mbit ethernet */
90 char *qos_leaf
="sfq perturb 5"; /* leaf discipline */
91 char *qos_free_zone
=NULL
; /* QoS free zone */
92 int qos_proxy
=1; /* include proxy port to QoS */
93 int include_upload
=1; /* upload+download=total traffic */
94 char *proxy_ip
="192.168.1.1/32"; /* our IP with proxy port */
95 int proxy_port
=3128; /* proxy port number */
96 long long int line
=1024; /* WAN/ISP download in kbps */
97 long long int up
=1024; /* WAN/ISP upload in kbps */
98 int free_min
=32; /* minimum guaranted bandwidth for all undefined hosts */
99 int free_max
=64; /* maximum allowed bandwidth for all undefined hosts */
100 int qos_free_delay
=0; /* seconds to sleep before applying new QoS rules */
101 int digital_divide
=2; /* controls digital divide weirdness ratio, 1...3 */
102 int max_nesting
=3; /* maximum nesting of HTB clases, built-in maximum seems to be 4 */
104 int burst
=8; /* HTB burst (in kbits) */
107 int magic_priorities
=8; /* number of priority levels (soft shaping) */
108 int magic_treshold
=8; /* reduce ceil by X*magic_treshhold kbps (hard shaping) */
111 /* not yet implemented:
112 int fixed_packets=0; maximum number of pps per IP address (not class!)
113 int packet_limit=5; maximum number of pps to htn CEIL, not rate !!!
117 char *kwd
="via-prometheus"; /* /etc/hosts comment, eg. #qos-64-128 */
119 const int idxtable_treshold1
=24; /* this is no longer configurable */
120 const int idxtable_treshold2
=12; /* this is no longer configurable */
121 const int idxtable_bitmask1
=3; /* this is no longer configurable */
122 const int idxtable_bitmask2
=3; /* this is no longer configurable */
125 /* not yet implemented:
126 -s start shaping! (keep data transfer statistics - but apply shaping)\n\
127 -r just reload configuration (...and keep data transfer statistics)\n\
130 /* ==== This is C<<1 stuff - learn C<<1 first! http://cll1.arachne.cz ==== */
144 unsigned long long direct
;
145 unsigned long long proxy
;
146 unsigned long long upload
;
147 unsigned long long traffic
;
148 unsigned long long credit
;
149 unsigned long pktsup
;
150 unsigned long pktsdown
;
151 struct Keyword
*keyword
;
153 } *ips
=NULL
, *ip
, *sharedip
;
162 } *groups
=NULL
, *group
;
168 struct Index
*parent
;
172 } *idxs
=NULL
, *idx
, *metaindex
;
178 int asymetry_ratio
; /* ratio for ADSL-like upload */
179 int asymetry_fixed
; /* fixed treshold for ADSL-like upload */
180 int data_limit
; /* hard shaping: apply magic_treshold if max*data_limit MB exceeded */
181 int data_prio
; /* soft shaping (qos): reduce HTB prio if max*data_prio MB exceeded */
182 long fixed_limit
; /* fixed data limit for setting lower HTB ceil */
183 long fixed_prio
; /* fixed data lmit for setting lower HTB prio */
184 int reserve_min
; /* bonus for nominal HTB rate bandwidth (in kbps) */
185 int reserve_max
; /* malus for nominal HTB ceil (in kbps) */
186 // int divide_max; /* relative malus: new_ceil=rate+(old_ceil-rate)/divide_max */
187 // int htb_ceil_bonus_divide; /* relative bonus: new_ceil=old_ceil+old_ceil/htb_ceil_bonus_divide */
188 int default_prio
; /* default HTB priority for this keyword */
191 char *leaf_discipline
;
194 } *keyword
,*defaultkeyword
=NULL
,*keywords
=NULL
;
196 /* Damned, this must be object oriented! This looks almost like constructor ;-) */
206 ip
->mark
=ip
->min
=ip
->max
=ip
->desired
=ip
->credit
=0;
207 ip
->upload
=ip
->proxy
=ip
->direct
=ip
->traffic
=0;
208 ip
->pktsup
=ip
->pktsdown
=0;
209 ip
->keyword
=keywords
;
213 /* ====== Iptables indexes are used to reduce complexity to log8(N) ===== */
215 char *very_ugly_ipv4_code(char *inip
,int bitmask
,int format_as_chainname
)
217 /* warning: this function was debugged only for bitmask values 20,24,28 !!!*/
219 char *ip
,*outip
,*outptr
,*fmt
;
222 /* debug printf("(%s,%d) -> ",ip,bitmask); */
224 if(ip
&& *ip
&& bitmask
>=0 && bitmask
<=32)
225 string(outip
,strlen(ip
)+10); /*fuck unicode? assertion: 10>strlen("_%d_%d") */
227 /* should never exit here */
234 if(dot
<(bitmask
/8-1))
236 if(format_as_chainname
)
245 char *cutdot
=strchr(ip
+1,'.'); /*for bitmask<24*/
246 if(cutdot
)*cutdot
='\0';
247 if(format_as_chainname
)
252 n
=atoi(ip
+1)-atoi(ip
+1)%(1<<(8-bitmask
%8));
256 /*debug printf("%d/%d => [_%d_%d]\n",atoi(ip+1),bitmask,n,bitmask); */
257 sprintf(outptr
,fmt
,n
,bitmask
);
258 if(!format_as_chainname
) while(bitmask
<24)
263 /* debug printf("[%s]\n",outip); */
274 /*should never exit here*/
279 char *hash_id(char *ip
,int bitmask
)
280 { return very_ugly_ipv4_code(ip
,bitmask
,1); }
282 char *subnet_id(char *ip
,int bitmask
)
283 { return very_ugly_ipv4_code(ip
,bitmask
,0); }
285 /* ================= Let's parse configuration file here =================== */
287 void reject_config_and_exit(char *filename
)
289 printf("Configuration file %s rejected - abnormal exit.",filename
);
293 void get_config(char *config_filename
)
297 printf("Configured keywords: ");
298 parse(config_filename
)
300 option("keyword",kwd
);
305 create(keyword
,Keyword
);
307 keyword
->asymetry_ratio
=1; /* ratio for ADSL-like upload */
308 keyword
->asymetry_fixed
=0; /* fixed treshold for ADSL-like upload */
309 keyword
->data_limit
=8; /* hard shaping: apply magic_treshold if max*data_limit MB exceeded */
310 keyword
->data_prio
=4; /* soft shaping (qos): reduce HTB prio if max*data_prio MB exceeded */
311 keyword
->fixed_limit
=0; /* fixed data limit for setting lower HTB ceil */
312 keyword
->fixed_prio
=0; /* fixed data limit for setting lower HTB prio */
313 keyword
->reserve_min
=8; /* bonus for nominal HTB rate bandwidth (in kbps) */
314 keyword
->reserve_max
=0; /* malus for nominal HTB ceil (in kbps) */
316 keyword->divide_max=0; relative malus: new_ceil=rate+(old_ceil-rate)/divide_max
317 keyword->htb_ceil_bonus_divide=0; relative bonus: new_ceil=old_ceil+old_ceil/htb_ceil_bonus_divide
319 keyword
->default_prio
=1;
320 keyword
->html_color
="000000";
322 keyword
->leaf_discipline
="";
324 push(keyword
,keywords
);
325 if(!defaultkeyword
) defaultkeyword
=keyword
;
330 else every(keyword
,keywords
)
332 int l
=strlen(keyword
->key
);
335 if(!strncmp(keyword
->key
,_
,l
) && strlen(_
)>l
+2)
337 char *tmptr
=_
; /* <---- l+1 ----> */
338 _
+=l
+1; /* via-prometheus-asymetry-ratio, etc. */
339 ioption("asymetry-ratio",keyword
->asymetry_ratio
);
340 ioption("asymetry-treshold",keyword
->asymetry_fixed
);
341 ioption("magic-relative-limit",keyword
->data_limit
);
342 ioption("magic-relative-prio",keyword
->data_prio
);
343 loption("magic-fixed-limit",keyword
->fixed_limit
);
344 loption("magic-fixed-prio",keyword
->fixed_prio
);
345 ioption("htb-default-prio",keyword
->default_prio
);
346 ioption("htb-rate-bonus",keyword
->reserve_min
);
347 ioption("htb-ceil-malus",keyword
->reserve_max
);
349 ioption("htb-ceil-divide",keyword->divide_max);
350 ioption("htb-ceil-bonus-divide",keyword->htb_ceil_bonus_divide);
352 option("leaf-discipline",keyword
->leaf_discipline
);
353 option("html-color",keyword
->html_color
);
356 if(keyword
->data_limit
|| keyword
->fixed_limit
||
357 keyword
->data_prio
|| keyword
->fixed_prio
)
365 option("iptables",iptables
);
366 option("iptables-save",iptablessave
); /* new */
367 option("iptables-restore",iptablesrestore
); /* new */
368 option("iptables-file",iptablesfile
); /* new */
369 option("hosts",hosts
);
370 option("lan-interface",lan
);
371 option("wan-interface",wan
);
372 option("lan-medium",lan_medium
);
373 option("wan-medium",wan_medium
);
374 lloption("wan-download",line
);
375 lloption("wan-upload",up
);
376 ioption("hall-of-fame-enable",hall_of_fame
);
377 option("hall-of-fame-title",title
);
378 option("hall-of-fame-filename",html
);
379 option("hall-of-fame-preview",preview
);
380 option("log-filename",cmdlog
);
381 option("credit-filename",credit
);
382 ioption("credit-enable",enable_credit
);
383 option("log-traffic-directory",log_dir
);
384 option("log-traffic-url-path",log_url
);
385 option("qos-free-zone",qos_free_zone
);
386 ioption("qos-free-delay",qos_free_delay
);
387 ioption("qos-proxy-enable",qos_proxy
);
388 option("qos-proxy-ip",proxy_ip
);
389 option("htb-leaf-discipline",qos_leaf
);
390 ioption("qos-proxy-port",proxy_port
);
391 ioption("free-rate",free_min
);
392 ioption("free-ceil",free_max
);
393 ioption("htb-burst",burst
);
394 ioption("htb-burst-main",burst_main
);
395 ioption("htb-burst-group",burst_group
);
396 ioption("htb-nesting-limit",max_nesting
);
397 ioption("htb-r2q",htb_r2q
);
398 ioption("magic-include-upload",include_upload
);
399 ioption("magic-priorities",magic_priorities
);
400 ioption("magic-treshold",magic_treshold
);
402 option("filter-type", cnf
);
404 /* not yet implemented:
405 ioption("magic-fixed-packets",fixed_packets);
406 ioption("magic-relative-packets",packet_limit);
411 perror(config_filename
);
412 puts("Warning - using built-in defaults instead ...");
417 /*leaf discipline for keywords*/
418 every(keyword
,keywords
)
420 if (!strcmpi(keyword
->leaf_discipline
, "")){
421 keyword
->leaf_discipline
= qos_leaf
;
425 if (strcmpi(cnf
, "mark")){
428 mark_iptables
= "CLASSIFY --set-class 1:";
432 mark_iptables
= "MARK --set-mark ";
435 /* are supplied values meaningful ?*/
438 puts("Illegal value of wan bandwidth: 0 kbps.");
439 reject_config_and_exit(config_filename
);
443 /* ===================== traffic analyser - uses iptables ================ */
445 void get_traffic_statistics(void)
450 textfile(Pipe
,str
) *line
,*lines
=NULL
;
454 sprintf(cmd
,"%s -L -v -x -n -t mangle",iptables
);
466 int col
, accept
=0,proxyflag
=0,valid
=1,setchainname
=0,commonflag
=0;
467 unsigned long long traffic
=0;
468 unsigned long pkts
=0;
469 char *ipaddr
=NULL
,*ptr
;
471 /* debug puts(line->str); */
472 valid_columns(ptr
,line
->str
,' ',col
)
473 if(valid
) switch(col
)
475 case 1: if(eq(ptr
,"Chain"))
477 else if(eq(ptr
,"pkts"))
480 sscanf(ptr
,"%lu",&pkts
);
482 case 2: if(setchainname
)
484 if(!strncmp(ptr
,"post_",5) || eq(ptr
,"POSTROUTING"))
487 if(!strncmp(ptr
,"forw_",5) || eq(ptr
,"FORWARD"))
490 if(eq(ptr
,"post_common") || eq(ptr
,"forw_common"))
494 sscanf(ptr
,"%Lu",&traffic
); traffic
+=(1<<19); traffic
>>=20;
496 case 3: if((strncmp(ptr
,"post_",5) && strncmp(ptr
,"forw_",5)) || commonflag
)
498 /*if (filter_type==1) accept=eq(ptr,"MARK"); else accept=eq(ptr,"CLASSIFY");*/
500 case 8: if(downloadflag
)
502 if(strstr(proxy_ip
,ptr
))proxyflag
=1;
507 case 9: if(downloadflag
)ipaddr
=ptr
;break;
510 if(accept
&& traffic
>0 && ipaddr
)
512 if(proxyflag
)printf("(proxy) ");
513 else if(!downloadflag
) printf("(upload) ");
514 printf("IP %s: %Lu M (%ld pkts)\n", ipaddr
, traffic
, pkts
);
515 find(ip
,ips
,eq(ip
->addr
,ipaddr
));
520 if(eq(ip
->addr
,"0.0.0.0/0"))
522 ip
->name
="(unregistered)";
524 ip
->max
=ip
->desired
=free_max
;
533 ip
->traffic
+=traffic
;
534 ip
->direct
=ip
->traffic
-ip
->upload
-ip
->proxy
;
542 ip
->traffic
+=traffic
;
544 if(traffic
>ip
->traffic
)
554 /* ========== This function executes, logs OR ALSO prints command ========== */
556 void safe_run(char *cmd
)
558 if(dry_run
) printf("\n=>%s\n",cmd
); else system(cmd
);
559 if(log_file
) fprintf(log_file
,"%s\n",cmd
);
562 void save_line(char *line
)
564 fprintf(iptables_file
,"%s\n",line
);
567 void run_restore(void)
570 string(restor
,STRLEN
);
572 /*-----------------------------------------------------------------*/
573 printf("Running %s <%s ...\n",iptablesrestore
,iptablesfile
);
574 /*-----------------------------------------------------------------*/
577 fclose(iptables_file
);
587 sprintf(restor
,"%s <%s",iptablesrestore
, iptablesfile
);
593 /* == This function strips extra characters after IP address and stores it = */
595 void parse_ip(char *str
)
597 char *ptr
=str
,*ipaddr
=NULL
,*ipname
=NULL
;;
599 while(*ptr
&& *ptr
!=' ' && *ptr
!=9)
605 while(*ptr
&& (*ptr
==' ' || *ptr
==9))
608 while(*ptr
&& *ptr
!=' ' && *ptr
!=9)
612 find(ip
,ips
,eq(ip
->addr
,ipaddr
)); else TheIP();
617 char *parse_datafile_line(char *str
)
619 char *ptr
=strchr(str
,' ');
631 /*-----------------------------------------------------------------*/
632 /* Are you looking for int main (int argc, char **argv) ? :-)) */
633 /*-----------------------------------------------------------------*/
641 int class_count
=0,ip_count
=0;
645 int just_preview
=0; /* preview - generate just stats */
646 char *chain_forward
, *chain_postrouting
;
650 Prometheus QoS - \"fair-per-IP\" Quality of Service setup utility.\n\
651 Version %s - Copyright (C)2005-2008 Michael Polak (xChaos)\n\
652 iptables-restore & burst tunning & classify modification 0.7d by Ludva\n\
653 Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version
);
655 /*----- Boring... we have to check command line options first: ----*/
659 argument("-c") { nextargument(config
); }
660 argument("-h") { nextargument(althosts
);}
661 argument("-d") { dry_run
=1; }
662 argument("-f") { just_flush
=1; }
663 argument("-9") { just_flush
=9; }
664 argument("-p") { just_preview
=1; }
665 argument("-n") { nodelay
=1; }
666 argument("-?") { help(); exit(0); }
667 argument("--help") { help(); exit(0); }
668 argument("-v") { exit(0); }
669 argument("--version") { exit(0); }
673 puts("*** THIS IS JUST DRY RUN ! ***\n");
675 date(d
); /* this is typical cll1.h macro */
677 /*-----------------------------------------------------------------*/
678 printf("Parsing configuration file %s ...\n", config
);
679 /*-----------------------------------------------------------------*/
682 if(althosts
) hosts
=althosts
;
686 /*-----------------------------------------------------------------*/
687 puts("Parsing iptables verbose output ...");
688 /*-----------------------------------------------------------------*/
689 get_traffic_statistics();
692 /*-----------------------------------------------------------------*/
693 printf("Parsing class defintion file %s ...\n", hosts
);
694 /*-----------------------------------------------------------------*/
695 int groupidx
= FIRSTGROUPID
;
700 if(*str
<'0' || *str
>'9')
703 //Does this IP share QoS class with some other ?
704 substring
=strstr(str
,"sharing-");
707 substring
+=8; //"sharing-"
710 ip
->sharing
=substring
;
711 ip
->keyword
=defaultkeyword
; /* settings for default keyword */
712 while(*substring
&& *substring
!='\n')
718 //Do we have to create new QoS class for this IP ?
720 find(keyword
,keywords
,(substring
=strstr(str
,keyword
->key
)))
726 ip
->prio
=keyword
->default_prio
;
727 substring
+=strlen(keyword
->key
)+1;
729 while(*ptr
&& *ptr
!='-')
734 ip
->max
=ip
->desired
=atoi(ptr
+1);
736 ip
->min
=atoi(substring
);
739 puts("Illegal value of minimum bandwidth: 0 kbps.");
740 reject_config_and_exit(hosts
);
745 ip
->max
=ip
->min
+ip
->keyword
->reserve_min
;
749 ip
->max
-=ip
->keyword
->reserve_max
;
752 if(ip->keyword->divide_max>1)
753 ip->max=ip->min+(ip->max-ip->min)/ip->keyword->divide_max;
754 if(ip->keyword->htb_ceil_bonus_divide>0)
755 ip->max+=ip->max/ip->keyword->htb_ceil_bonus_divide;
760 ip
->mark
=FIRSTIPCLASS
+1+class_count
++;
762 find(group
,groups
,group
->min
==ip
->min
)
765 group
->desired
+=ip
->min
;
766 ip
->group
= group
->id
;
772 group
->id
= groupidx
++;
773 ip
->group
= group
->id
;
775 if(group
->min
<8) group
->min
=8;
776 /* Warning - this is maybe because of primitive tc namespace, can be fixed */
777 /* it is because class IDs are derived from min. bandwidth. - xCh */
778 //if(group->min>MAX_GUARANTED_KBPS) group->min=MAX_GUARANTED_KBPS;
781 group
->desired
=ip
->min
;
782 insert(group
,groups
,desc_order_by
,min
);
794 /*-----------------------------------------------------------------*/
795 /* cll1.h - let's allocate brand new character buffer... */
796 /*-----------------------------------------------------------------*/
799 /*-----------------------------------------------------------------*/
800 puts("Resolving shared connections ...");
801 /*-----------------------------------------------------------------*/
802 search(ip
,ips
,ip
->sharing
)
804 search(sharedip
,ips
,eq(sharedip
->name
,ip
->sharing
))
806 sharedip
->traffic
+=ip
->traffic
;
808 ip
->mark
=sharedip
->mark
;
812 printf("Unresolved shared connection: %s %s sharing-%s\n",ip
->addr
,ip
->name
,ip
->sharing
);
815 if(enable_credit
&& just_flush
<9)
817 /*-----------------------------------------------------------------*/
818 printf("Parsing credit file %s ...\n", credit
);
819 /*-----------------------------------------------------------------*/
822 ptr
=parse_datafile_line(_
);
825 find(ip
,ips
,eq(ip
->addr
,_
))
826 sscanf(ptr
,"%Lu",&(ip
->credit
));
834 /*-----------------------------------------------------------------*/
835 puts("Initializing iptables and tc classes ...");
836 /*-----------------------------------------------------------------*/
838 iptables_file
=fopen(iptablesfile
,"w");
839 if (iptables_file
== NULL
) {
840 puts("Cannot open iptablesfile!");
844 log_file
=fopen(cmdlog
,"w");
845 if (log_file
== NULL
) {
846 puts("Cannot open logfile!");
850 save_line(iptablespreamble
);
853 sprintf(str
,"%s qdisc del dev %s root 2>/dev/null",tc
,lan
);
856 sprintf(str
,"%s qdisc del dev %s root 2>/dev/null",tc
,wan
);
859 iptables_file
=fopen(iptablesfile
,"w");
860 save_line(iptablespreamble
);
862 if(qos_free_zone
&& *qos_free_zone
!='0')
866 sprintf(str
,"-A FORWARD -d %s -o %s -j ACCEPT", qos_free_zone
, wan
);
871 save_line(":post_noproxy - [0:0]");
872 sprintf(str
,"-A POSTROUTING -p ! tcp -o %s -j post_noproxy", lan
);
874 sprintf(str
,"-A POSTROUTING -s ! %s -o %s -j post_noproxy", proxy_ip
, lan
);
876 sprintf(str
,"-A POSTROUTING -s %s -p tcp --sport ! %d -o %s -j post_noproxy", proxy_ip
, proxy_port
, lan
);
879 chain
="post_noproxy";
884 sprintf(str
,"-A %s -s %s -o %s -j ACCEPT", chain
, qos_free_zone
, lan
);
888 if(ip_count
>idxtable_treshold1
&& !just_flush
)
890 int idxcount
=0, bitmask
=32-idxtable_bitmask1
; /* default net mask: 255.255.255.240 */
892 /*-----------------------------------------------------------------*/
893 printf("Detected %d addresses - indexing iptables rules to improve performance...\n",ip_count
);
894 /*-----------------------------------------------------------------*/
896 save_line(":post_common - [0:0]");
897 save_line(":forw_common - [0:0]");
899 search(ip
,ips
,ip
->addr
&& *(ip
->addr
) && !eq(ip
->addr
,"0.0.0.0/0"))
901 buf
=hash_id(ip
->addr
,bitmask
);
902 find(idx
,idxs
,eq(idx
->id
,buf
))
909 idx
->bitmask
=bitmask
;
917 /* brutal perfomance optimalization */
918 while(idxcount
>idxtable_treshold2
&& bitmask
>2*idxtable_bitmask2
)
920 bitmask
-=idxtable_bitmask2
;
922 search(idx
,idxs
,idx
->parent
==NULL
)
924 buf
=hash_id(idx
->addr
,bitmask
);
925 find(metaindex
,idxs
,eq(metaindex
->id
,buf
))
926 metaindex
->children
++;
929 create(metaindex
,Index
);
930 metaindex
->addr
=idx
->addr
;
932 metaindex
->bitmask
=bitmask
;
933 metaindex
->parent
=NULL
;
934 metaindex
->children
=0;
936 push(metaindex
,idxs
);
938 idx
->parent
=metaindex
;
942 /* this should slightly optimize throughout ... */
943 sort(idx
,idxs
,desc_order_by
,children
);
944 sort(idx
,idxs
,order_by
,bitmask
);
949 subnet
=subnet_id(idx
->addr
,idx
->bitmask
);
950 printf("%d: %s/%d\n",++i
,subnet
,idx
->bitmask
);
952 sprintf(str
,":post_%s - [0:0]", idx
->id
);
955 sprintf(str
,":forw_%s - [0:0]", idx
->id
);
960 string(buf
,strlen(idx
->parent
->id
)+6);
961 sprintf(buf
,"post_%s",idx
->parent
->id
);
966 sprintf(str
,"-A %s -d %s/%d -o %s -j post_%s", buf
, subnet
, idx
->bitmask
, lan
, idx
->id
);
969 sprintf(str
,"-A %s -d %s/%d -o %s -j post_common", buf
, subnet
, idx
->bitmask
, lan
);
974 string(buf
,strlen(idx
->parent
->id
)+6);
975 sprintf(buf
,"forw_%s",idx
->parent
->id
);
980 sprintf(str
,"-A %s -s %s/%d -o %s -j forw_%s", buf
, subnet
, idx
->bitmask
, wan
, idx
->id
);
983 sprintf(str
,"-A %s -s %s/%d -o %s -j forw_common", buf
, subnet
, idx
->bitmask
, wan
);
986 printf("Total indexed iptables chains created: %d\n", i
);
988 sprintf(str
,"-A FORWARD -o %s -j forw_common", wan
);
991 sprintf(str
,"-A POSTROUTING -o %s -j post_common", lan
);
999 fclose(iptables_file
);
1000 if (log_file
) fclose(log_file
);
1001 puts("Just flushed iptables and tc classes - now exiting ...");
1007 if(!dry_run
&& !nodelay
&& qos_free_delay
)
1009 printf("Flushed iptables and tc classes - now sleeping for %d seconds...\n",qos_free_delay
);
1010 sleep(qos_free_delay
);
1013 sprintf(str
,"%s qdisc add dev %s root handle 1: htb r2q %d default 1",tc
,lan
,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
,lan
,lan_medium
,lan_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
,lan
,line
,line
,burst_main
);
1022 sprintf(str
,"%s qdisc add dev %s root handle 1: htb r2q %d default 1",tc
,wan
,htb_r2q
);
1025 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
);
1028 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
);
1032 /*-----------------------------------------------------------------*/
1033 puts("Locating suckers and generating root classes ...");
1034 /*-----------------------------------------------------------------*/
1035 sort(ip
,ips
,desc_order_by
,traffic
);
1038 /*-----------------------------------------------------------------*/
1039 /* sub-scope - local variables */
1041 long long int rate
=line
;
1042 long long int max
=line
;
1044 FILE *credit_file
=NULL
;
1046 if(!just_preview
&& !dry_run
&& enable_credit
) credit_file
=fopen(credit
,"w");
1054 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",
1055 tc
, lan
, parent
, group
->id
, rate
, max
, burst_group
, group
->desired
);
1059 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",
1060 tc
, wan
, parent
, group
->id
, rate
*up
/line
, max
*up
/line
, burst_group
, group
->desired
);
1064 if(group_count
++<max_nesting
) parent
=group
->id
;
1066 rate
-=digital_divide
*group
->min
;
1067 if(rate
<group
->min
)rate
=group
->min
;
1069 /*shaping of aggresive downloaders, with credit file support */
1072 int group_rate
=group
->min
, priority_sequence
=magic_priorities
+1;
1074 search(ip
, ips
, ip
->min
==group
->min
&& ip
->max
>ip
->min
)
1076 if( ip
->keyword
->data_limit
&& !ip
->fixedprio
&&
1077 ip
->traffic
>ip
->credit
+
1078 (ip
->min
*ip
->keyword
->data_limit
+(ip
->keyword
->fixed_limit
<<20)) )
1080 if(group_rate
<ip
->max
) ip
->max
=group_rate
;
1081 group_rate
+=magic_treshold
;
1082 ip
->prio
=magic_priorities
+2;
1083 if(ip
->prio
<3) ip
->prio
=3;
1087 if( ip
->keyword
->data_prio
&& !ip
->fixedprio
&&
1088 ip
->traffic
>ip
->credit
+
1089 (ip
->min
*ip
->keyword
->data_prio
+(ip
->keyword
->fixed_prio
<<20)) )
1091 ip
->prio
=priority_sequence
--;
1092 if(ip
->prio
<2) ip
->prio
=2;
1097 unsigned long long lcredit
=0;
1099 if((ip
->min
*ip
->keyword
->data_limit
+(ip
->keyword
->fixed_limit
<<20))>ip
->traffic
)
1100 lcredit
=(ip
->min
*ip
->keyword
->data_limit
+(ip
->keyword
->fixed_limit
<<20))-ip
->traffic
;
1101 fprintf(credit_file
,"%s %Lu\n",ip
->addr
,lcredit
);
1108 if(credit_file
)fclose(credit_file
);
1113 f
=fopen(preview
,"w");
1116 else if(!dry_run
&& !just_flush
)
1118 /*-----------------------------------------------------------------*/
1119 printf("Writing data transfer database ...\n");
1120 /*-----------------------------------------------------------------*/
1121 f
=fopen("/var/run/prometheus.previous","w");
1124 search(ip
,ips
,ip
->traffic
|| ip
->direct
|| ip
->proxy
||ip
->upload
)
1125 fprintf(f
,"%s %Lu %Lu %Lu %Lu\n",ip
->addr
,ip
->traffic
,ip
->direct
,ip
->proxy
,ip
->upload
);
1139 /*-----------------------------------------------------------------*/
1140 printf("Sorting data and generating statistics page %s ...\n",ptr
);
1141 /*-----------------------------------------------------------------*/
1143 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
);
1144 fprintf(f
,"<th colspan=\"%d\">data limits</th>\n",keywordcount
);
1149 printf("%d k group: %d bandwidth requested: %d k\n",group
->min
,group
->count
,group
->desired
);
1151 fprintf(f
,"<tr><td align=\"right\">%d</td><td align=\"right\">%d k</td>",count
,group
->min
);
1152 fprintf(f
,"<td align=\"right\">%d</td><td align=\"right\">%d k</td>",group
->count
,group
->desired
);
1154 every(keyword
,keywords
)
1155 fprintf(f
,"<td align=\"right\"><font color=\"#%s\">%d M</font></td>",keyword
->html_color
,group
->min
*keyword
->data_limit
);
1158 total
+=group
->count
;
1162 printf("Total groups: %d Total bandwidth requested: %d k\nAGGREGATION: 1/%d\n",count
,i
,i
/line
);
1164 fprintf(f
,"<tr><th colspan=\"2\" align=\"left\">Line %Ld k</td>",line
);
1165 fprintf(f
,"<th align=\"right\">%d</td><th align=\"right\">%d k</td>",total
,i
);
1167 every(keyword
,keywords
)
1168 fprintf(f
,"<th align=\"right\">%d IPs</th>",keyword
->ip_count
);
1170 fprintf(f
,"</tr><tr><th colspan=\"4\">Aggregation 1/%d</th>\n",(int)(0.5+i
/line
));
1171 fprintf(f
,"<th colspan=\"%d\">%d traffic classes</th></tr>\n",keywordcount
,total
);
1173 fputs("</table>\n",f
);
1175 else if(!dry_run
&& !just_flush
)
1181 unsigned long long total
=0, total_direct
=0, total_proxy
=0, total_upload
=0, tmp_sum
=0;
1182 int active_classes
=0;
1185 struct Sum
{unsigned long long l
; int i
; list(Sum
);} *sum
,*sums
=NULL
;
1192 fprintf(f
,"<p><table border>\n<tr><th colspan=\"%d\">%s",colspan
,title
);
1193 fprintf(f
," (%s)</th></tr>\n", d
);
1194 fputs("<tr><td align=\"right\">#</td><td>hostname</td>\
1195 <td align=\"right\">credit</td>\
1196 <td align=\"right\">limit</td>\
1197 <td align=\"right\">total</td>\
1198 <td align=\"right\">direct</td>\n",f
);
1200 fputs("<td align=\"right\">proxy</td>\n",f
);
1201 fputs("<td align=\"right\">upload</td>\
1202 <td align=\"right\">minimum</td>\
1203 <td align=\"right\">desired</td>\
1204 <td align=\"right\">maximum</td>\
1205 <td>prio</td></tr>\n",f
);
1209 char *f1
="", *f2
="";
1210 if(ip
->max
<ip
->desired
)
1212 f1
="<font color=\"red\">";
1217 f1
="<font color=\"brown\">";
1222 printf("%03d. %-22s %10Lu (%d/%d)\n",i
,ip
->name
, ip
->traffic
, ip
->min
, ip
->max
);
1224 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",
1225 ip
->name
, i
, log_url
, ip
->name
, ip
->name
, ip
->credit
);
1226 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)));
1227 fprintf(f
,"<td align=\"right\">%s%Lu M%s</td><td align=\"right\">%Lu M</td>\n", f1
, ip
->traffic
, f2
, ip
->direct
);
1229 fprintf(f
,"<td align=\"right\">%Lu M</td>\n", ip
->proxy
);
1230 fprintf(f
,"<td align=\"right\">%Lu M</td>\n", ip
->upload
);
1231 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
);
1233 total_direct
+=ip
->direct
;
1234 total_proxy
+=ip
->proxy
;
1235 total_upload
+=ip
->upload
;
1239 tmp_sum
+=ip
->traffic
;
1242 sum
->i
=active_classes
;
1243 insert(sum
,sums
,order_by
,i
);
1250 sprintf(str
,"%s%s.log",log_dir
,ip
->name
);
1251 iplog
=fopen(str
,"a");
1254 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
);
1260 fprintf(f
,"<tr><th colspan=\"4 \"align=\"left\">SUMMARY:</td>");
1261 fprintf(f
,"<th align=\"right\">%Lu M</th>\
1262 <th align=\"right\">%Lu M</th>\n", total
, total_direct
);
1264 fprintf(f
,"<th align=\"right\">%Lu M</th>\n", total_proxy
);
1265 fprintf(f
,"<th align=\"right\">%Lu M</th>", total_upload
);
1266 fputs("<td colspan=\"4\"></td></th>\n</table>\n",f
);
1268 if(active_classes
>10)
1270 fputs("<a name=\"erp\"></a><p><table border><tr><th colspan=\"5\">Enterprise Research and Planning (ERP)</th></tr>\n",f
);
1271 fputs("<tr><td>Analytic category</td>\n",f
);
1272 fputs("<td colspan=\"2\" align=\"center\">Active Classes</td><td colspan=\"2\" align=\"center\">Data transfers</td></tr>\n",f
);
1274 find(sum
,sums
,sum
->l
>=total
/4)
1276 fprintf(f
,"<tr><td>Top 25%% of traffic</td>\n");
1277 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
);
1280 find(sum
,sums
,sum
->i
==10)
1282 fprintf(f
,"<tr><td>Top 10 downloaders</td>\n");
1283 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
);
1286 find(sum
,sums
,sum
->l
>=total
/2)
1288 fprintf(f
,"<tr><td>Top 50%% of traffic</td>\n");
1289 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
);
1292 find(sum
,sums
,sum
->l
>=4*total
/5)
1294 fprintf(f
,"<tr><td>Top 80%% of traffic</td>\n");
1295 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
);
1298 find (sum
,sums
,sum
->i
>=(active_classes
+1)/5)
1300 fprintf(f
,"<tr><td>Top 20%% downloaders</td>\n");
1301 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
);
1304 find(sum
,sums
,sum
->i
>=(active_classes
+1)/4)
1306 fprintf(f
,"<tr><td>Top 25%% downloaders</td>\n");
1307 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
);
1310 find(sum
,sums
,sum
->i
>=(active_classes
+1)/2)
1312 fprintf(f
,"<tr><td>Top 50%% downloaders</td>\n");
1313 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
);
1316 find(sum
,sums
,sum
->i
>=4*(active_classes
+1)/5)
1318 fprintf(f
,"<tr><td>Top 80%% downloaders</td>\n");
1319 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
);
1322 fprintf(f
,"<tr><td>All users, all traffic</td>\n");
1323 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
);
1324 fputs("</table>\n",f
);
1326 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
);
1332 puts("Statistics preview generated (-p switch) - now exiting ...");
1336 /*-----------------------------------------------------------------*/
1337 puts("Generating iptables and tc classes ...");
1338 /*-----------------------------------------------------------------*/
1341 printf("%-22s %-15s mark\n","name","ip");
1342 search(ip
,ips
,ip
->mark
>0)
1348 duplicate(ip
->addr
,buf
);
1349 buf
=hash_id(ip
->addr
,32-idxtable_bitmask1
);
1351 string(chain_forward
,6+strlen(buf
));
1352 strcpy(chain_forward
,"forw_");
1353 strcat(chain_forward
,buf
);
1355 string(chain_postrouting
,6+strlen(buf
));
1356 strcpy(chain_postrouting
,"post_");
1357 strcat(chain_postrouting
,buf
);
1363 chain_forward
="FORWARD";
1364 chain_postrouting
="POSTROUTING";
1367 printf("%-22s %-16s %04d ", ip
->name
, ip
->addr
, ip
->mark
);
1369 /* -------------------------------------------------------- mark download */
1371 sprintf(str
,"-A %s -d %s/32 -o %s -j %s%d",chain_postrouting
,ip
->addr
,lan
,mark_iptables
,ip
->mark
);
1372 /*sprintf(str,"-A %s -d %s/32 -o %s -j MARK --set-mark %d",chain_postrouting,ip->addr,lan,ip->mark);*/
1373 /* -m limit --limit 1/s */
1378 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
);
1379 /*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);*/
1383 sprintf(str
,"-A %s -d %s/32 -o %s -j ACCEPT",chain_postrouting
,ip
->addr
,lan
);
1386 /* -------------------------------------------------------- mark upload */
1387 sprintf(str
,"-A %s -s %s/32 -o %s -j %s%d",chain_forward
,ip
->addr
,wan
,mark_iptables
,ip
->mark
);
1388 /* sprintf(str,"-A %s -s %s/32 -o %s -j MARK --set-mark %d",chain_forward,ip->addr,wan,ip->mark);*/
1391 sprintf(str
,"-A %s -s %s/32 -o %s -j ACCEPT",chain_forward
,ip
->addr
,wan
);
1396 /* -------------------------------------------------------- download class */
1397 printf("(down: %dk-%dk ", ip
->min
, ip
->max
);
1399 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
);
1402 if (strcmpi(ip
->keyword
->leaf_discipline
, "none")){
1403 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*/
1407 if (filter_type
== 1){
1408 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle %d fw flowid 1:%d", tc
, lan
, ip
->mark
, ip
->mark
);
1412 /* -------------------------------------------------------- upload class */
1413 printf("up: %dk-%dk)\n", (int)((ip
->min
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
),
1414 (int)((ip
->max
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
));
1416 sprintf(str
,"%s class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit burst %dk prio %d",
1417 tc
, wan
, ip
->group
, ip
->mark
,
1418 (int)((ip
->min
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
),
1419 (int)((ip
->max
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
), burst
, ip
->prio
);
1422 if (strcmpi(ip
->keyword
->leaf_discipline
, "none")){
1423 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*/
1427 if (filter_type
== 1){
1428 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle %d fw flowid 1:%d",tc
, wan
, ip
->mark
, ip
->mark
);
1433 printf("(sharing %s)\n", ip
->sharing
);
1440 chain_forward
="forw_common";
1441 chain_postrouting
="post_common";
1445 chain_forward
="FORWARD";
1446 chain_postrouting
="POSTROUTING";
1449 /* -------------------------------------------------------- mark download */
1453 sprintf(str
,"-A %s -s %s -p tcp --sport %d -o %s -j MARK --set-mark 3",chain_postrouting
,proxy_ip
,proxy_port
,lan
);
1455 sprintf(str
,"-A %s -s %s -p tcp --sport %d -o %s -j ACCEPT",chain_postrouting
,proxy_ip
,proxy_port
,lan
);
1458 sprintf(str
,"-A %s -o %s -j MARK --set-mark 3",chain_postrouting
,lan
);
1460 sprintf(str
,"-A %s -o %s -j ACCEPT",chain_postrouting
,lan
);
1463 /* -------------------------------------------------------- mark upload */
1464 sprintf(str
,"-A %s -o %s -j MARK --set-mark 3",chain_forward
,wan
);
1466 sprintf(str
,"-A %s -o %s -j ACCEPT",chain_forward
,wan
);
1469 printf("Total IP count: %d\n", i
);
1471 /*-----------------------------------------------------------------*/
1472 puts("Generating free bandwith classes ...");
1473 /*-----------------------------------------------------------------*/
1475 /* ---------------------------------------- tc - free bandwith shared class */
1476 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
);
1479 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
);
1483 if (strcmpi(qos_leaf
, "none")){
1484 sprintf(str
,"%s qdisc add dev %s parent 1:3 handle 3 %s",tc
,lan
,qos_leaf
);
1487 sprintf(str
,"%s qdisc add dev %s parent 1:3 handle 3 %s",tc
,wan
,qos_leaf
);
1491 /* tc handle 1 fw flowid */
1492 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle 3 fw flowid 1:3",tc
,lan
);
1495 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle 3 fw flowid 1:3",tc
,wan
);
1500 if (log_file
) fclose(log_file
);
1503 /* that's all folks, thank you for reading it all the way up to this point ;-) */
1504 /* bad luck C<<1 is not yet finished, I promise no sprintf() next time... */
This page took 1.131829 seconds and 3 git commands to generate.