4461346cd47e73e0c60f3669091d1ab3f3e8964a
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, 20080205
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.1"; /*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 */
44 char *ls
= "/bin/ls"; /* this is not user configurable :-) */
46 char *config
= "/etc/prometheus/prometheus.conf"; /* main configuration file */
47 char *hosts
= "/etc/prometheus/hosts"; /* per-IP bandwidth definition file */
49 char *iptablesfile
= "/var/spool/prometheus.iptables"; /* temporary file for iptables-restore*/
50 char *credit
= "/var/lib/misc/prometheus.credit"; /* credit log file */
51 char *html
= "/var/www/traffic.html"; /* hall of fame filename */
52 char *preview
= "/var/www/preview.html"; /* hall of fame preview */
53 char *cmdlog
= "/var/log/prometheuslog"; /* command log filename */
54 char *log_dir
= "/var/www/logs/"; /* log directory pathname, ended with slash */
55 char *log_url
= "logs/"; /* log directory relative URI prefix (partial URL) */
56 char *html_log_dir
= "/var/www/logs/html/";
58 /* ======= Help screen is hopefuly self-documenting part of code :-) ======= */
62 puts("Command line switches:\n\
64 -?, --help this help screen\n\
65 -v, --version show version number of this utility and exit\n\
66 -c filename force alternative /etc/prometheus.conf filename\n\
67 -h filename force alternative /etc/hosts filename (overrides hosts keyword)\n\
68 -f just flush iptables and tc classes and exit (stop shaping)\n\
69 -9 emergency iptables flush (do not read data transfer statistics)\n\
70 -p just generate preview of data transfer statistics and exit\n\
71 -n no delay (overrides qos-free-delay keyword)\n\
72 -d dry run (preview tc and iptables commands on stdout)\n\
73 -l Mmm YYYY generate HTML summary of traffic logs (Mmm=Jan-Dec or Year, YYYY=year)\n\
74 -m generate HTML summary of traffic logs for yesterday's month\n\
75 -y generate HTML summary of traffic logs for yesterday's year\n");
76 /* not yet implemented:
77 -s start shaping! (keep data transfer statistics - but apply shaping)\n\
78 -r just reload configuration (...and keep data transfer statistics)\n\
82 /* === Configuraration file values defaults - stored in global variables ==== */
84 int filter_type
=1; /*1 mark, 2 classify*/
86 char *mark_iptables
="MARK --set-mark ";
87 int dry_run
=0; /* preview - use puts() instead of system() */
88 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]";
89 FILE *iptables_file
=NULL
;
90 int enable_credit
=1; /* enable credit file */
91 int use_credit
=0; /* use credit file (if enabled)*/
92 char *title
="Hall of Fame - Greatest Suckers"; /* hall of fame title */
93 int hall_of_fame
=1; /* enable hall of fame */
94 char *lan
="eth0"; /* LAN interface */
95 char *lan_medium
="100Mbit"; /* 10Mbit/100Mbit ethernet */
96 char *wan
="eth1"; /* WAN/ISP interface */
97 char *wan_medium
="100Mbit"; /* 10Mbit/100Mbit ethernet */
98 char *qos_leaf
="sfq perturb 5"; /* leaf discipline */
99 char *qos_free_zone
=NULL
; /* QoS free zone */
100 int qos_proxy
=1; /* include proxy port to QoS */
101 int include_upload
=1; /* upload+download=total traffic */
102 char *proxy_ip
="192.168.1.1/32"; /* our IP with proxy port */
103 int proxy_port
=3128; /* proxy port number */
104 long long int line
=1024; /* WAN/ISP download in kbps */
105 long long int up
=1024; /* WAN/ISP upload in kbps */
106 int free_min
=32; /* minimum guaranted bandwidth for all undefined hosts */
107 int free_max
=64; /* maximum allowed bandwidth for all undefined hosts */
108 int qos_free_delay
=0; /* seconds to sleep before applying new QoS rules */
109 int digital_divide
=2; /* controls digital divide weirdness ratio, 1...3 */
110 int max_nesting
=3; /* maximum nesting of HTB clases, built-in maximum seems to be 4 */
112 int burst
=8; /* HTB burst (in kbits) */
115 int magic_priorities
=8; /* number of priority levels (soft shaping) */
116 int magic_treshold
=8; /* reduce ceil by X*magic_treshhold kbps (hard shaping) */
119 /* not yet implemented:
120 int fixed_packets=0; maximum number of pps per IP address (not class!)
121 int packet_limit=5; maximum number of pps to htn CEIL, not rate !!!
125 char *kwd
="via-prometheus"; /* /etc/hosts comment, eg. #qos-64-128 */
127 const int idxtable_treshold1
=24; /* this is no longer configurable */
128 const int idxtable_treshold2
=12; /* this is no longer configurable */
129 const int idxtable_bitmask1
=3; /* this is no longer configurable */
130 const int idxtable_bitmask2
=3; /* this is no longer configurable */
132 /* ==== This is C<<1 stuff - learn C<<1 first! http://cll1.arachne.cz ==== */
146 unsigned long long direct
;
147 unsigned long long proxy
;
148 unsigned long long upload
;
149 unsigned long long traffic
;
150 unsigned long long credit
;
151 unsigned long pktsup
;
152 unsigned long pktsdown
;
153 struct Keyword
*keyword
;
155 } *ips
=NULL
, *ip
, *sharedip
;
164 } *groups
=NULL
, *group
;
170 struct Index
*parent
;
174 } *idxs
=NULL
, *idx
, *metaindex
;
180 int asymetry_ratio
; /* ratio for ADSL-like upload */
181 int asymetry_fixed
; /* fixed treshold for ADSL-like upload */
182 int data_limit
; /* hard shaping: apply magic_treshold if max*data_limit MB exceeded */
183 int data_prio
; /* soft shaping (qos): reduce HTB prio if max*data_prio MB exceeded */
184 long fixed_limit
; /* fixed data limit for setting lower HTB ceil */
185 long fixed_prio
; /* fixed data lmit for setting lower HTB prio */
186 int reserve_min
; /* bonus for nominal HTB rate bandwidth (in kbps) */
187 int reserve_max
; /* malus for nominal HTB ceil (in kbps) */
188 // int divide_max; /* relative malus: new_ceil=rate+(old_ceil-rate)/divide_max */
189 // int htb_ceil_bonus_divide; /* relative bonus: new_ceil=old_ceil+old_ceil/htb_ceil_bonus_divide */
190 int default_prio
; /* default HTB priority for this keyword */
193 char *leaf_discipline
;
196 } *keyword
,*defaultkeyword
=NULL
,*keywords
=NULL
;
198 /* Damned, this must be object oriented! This looks almost like constructor ;-) */
208 ip
->mark
=ip
->min
=ip
->max
=ip
->desired
=ip
->credit
=0;
209 ip
->upload
=ip
->proxy
=ip
->direct
=ip
->traffic
=0;
210 ip
->pktsup
=ip
->pktsdown
=0;
211 ip
->keyword
=keywords
;
215 /* ====== iptables indexes are used to reduce complexity to log8(N) ===== */
217 char *very_ugly_ipv4_code(char *inip
,int bitmask
,int format_as_chainname
)
219 /* warning: this function was debugged only for bitmask values 20,24,28 !!!*/
221 char *ip
,*outip
,*outptr
,*fmt
;
224 /* debug printf("(%s,%d) -> ",ip,bitmask); */
226 if(ip
&& *ip
&& bitmask
>=0 && bitmask
<=32)
227 string(outip
,strlen(ip
)+10); /*fuck unicode? assertion: 10>strlen("_%d_%d") */
229 /* should never exit here */
236 if(dot
<(bitmask
/8-1))
238 if(format_as_chainname
)
247 char *cutdot
=strchr(ip
+1,'.'); /*for bitmask<24*/
248 if(cutdot
)*cutdot
='\0';
249 if(format_as_chainname
)
254 n
=atoi(ip
+1)-atoi(ip
+1)%(1<<(8-bitmask
%8));
258 /*debug printf("%d/%d => [_%d_%d]\n",atoi(ip+1),bitmask,n,bitmask); */
259 sprintf(outptr
,fmt
,n
,bitmask
);
260 if(!format_as_chainname
) while(bitmask
<24)
265 /* debug printf("[%s]\n",outip); */
276 /*should never exit here*/
281 char *hash_id(char *ip
,int bitmask
)
282 { return very_ugly_ipv4_code(ip
,bitmask
,1); }
284 char *subnet_id(char *ip
,int bitmask
)
285 { return very_ugly_ipv4_code(ip
,bitmask
,0); }
287 /* ================= Let's parse configuration file here =================== */
289 void reject_config_and_exit(char *filename
)
291 printf("Configuration file %s rejected - abnormal exit.",filename
);
295 void get_config(char *config_filename
)
299 printf("Configured keywords: ");
300 parse(config_filename
)
302 option("keyword",kwd
);
307 create(keyword
,Keyword
);
309 keyword
->asymetry_ratio
=1; /* ratio for ADSL-like upload */
310 keyword
->asymetry_fixed
=0; /* fixed treshold for ADSL-like upload */
311 keyword
->data_limit
=8; /* hard shaping: apply magic_treshold if max*data_limit MB exceeded */
312 keyword
->data_prio
=4; /* soft shaping (qos): reduce HTB prio if max*data_prio MB exceeded */
313 keyword
->fixed_limit
=0; /* fixed data limit for setting lower HTB ceil */
314 keyword
->fixed_prio
=0; /* fixed data limit for setting lower HTB prio */
315 keyword
->reserve_min
=8; /* bonus for nominal HTB rate bandwidth (in kbps) */
316 keyword
->reserve_max
=0; /* malus for nominal HTB ceil (in kbps) */
318 keyword->divide_max=0; relative malus: new_ceil=rate+(old_ceil-rate)/divide_max
319 keyword->htb_ceil_bonus_divide=0; relative bonus: new_ceil=old_ceil+old_ceil/htb_ceil_bonus_divide
321 keyword
->default_prio
=1;
322 keyword
->html_color
="000000";
324 keyword
->leaf_discipline
="";
326 push(keyword
,keywords
);
327 if(!defaultkeyword
) defaultkeyword
=keyword
;
332 else every(keyword
,keywords
)
334 int l
=strlen(keyword
->key
);
337 if(!strncmp(keyword
->key
,_
,l
) && strlen(_
)>l
+2)
339 char *tmptr
=_
; /* <---- l+1 ----> */
340 _
+=l
+1; /* via-prometheus-asymetry-ratio, etc. */
341 ioption("asymetry-ratio",keyword
->asymetry_ratio
);
342 ioption("asymetry-treshold",keyword
->asymetry_fixed
);
343 ioption("magic-relative-limit",keyword
->data_limit
);
344 ioption("magic-relative-prio",keyword
->data_prio
);
345 loption("magic-fixed-limit",keyword
->fixed_limit
);
346 loption("magic-fixed-prio",keyword
->fixed_prio
);
347 ioption("htb-default-prio",keyword
->default_prio
);
348 ioption("htb-rate-bonus",keyword
->reserve_min
);
349 ioption("htb-ceil-malus",keyword
->reserve_max
);
351 ioption("htb-ceil-divide",keyword->divide_max);
352 ioption("htb-ceil-bonus-divide",keyword->htb_ceil_bonus_divide);
354 option("leaf-discipline",keyword
->leaf_discipline
);
355 option("html-color",keyword
->html_color
);
358 if(keyword
->data_limit
|| keyword
->fixed_limit
||
359 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-html-directory",html_log_dir
);
385 option("log-traffic-url-path",log_url
);
386 option("qos-free-zone",qos_free_zone
);
387 ioption("qos-free-delay",qos_free_delay
);
388 ioption("qos-proxy-enable",qos_proxy
);
389 option("qos-proxy-ip",proxy_ip
);
390 option("htb-leaf-discipline",qos_leaf
);
391 ioption("qos-proxy-port",proxy_port
);
392 ioption("free-rate",free_min
);
393 ioption("free-ceil",free_max
);
394 ioption("htb-burst",burst
);
395 ioption("htb-burst-main",burst_main
);
396 ioption("htb-burst-group",burst_group
);
397 ioption("htb-nesting-limit",max_nesting
);
398 ioption("htb-r2q",htb_r2q
);
399 ioption("magic-include-upload",include_upload
);
400 ioption("magic-priorities",magic_priorities
);
401 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
,' ');
638 void parse_ip_log(int argc
, char **argv
)
640 char *month
,*year
,*str
,*name
,*ptr
,*ptr2
;
641 long traffic
,traffic_month
,total
=0;
642 int col
,col2
,y_ok
,m_ok
,accept_month
,i
=1,any_month
=0;
643 char mstr
[4],ystr
[5];
648 if(argv
[1][1]=='l') /* -l */
652 puts("Missing parameter(s)!\nUsage: prometheus -l Mmm YYYY (Mmm=Jan-Dec or Year, YYYY=year)");
658 if(eq(month
,"Year")) any_month
=1;
664 time_t t
= time(NULL
) - 3600*24 ; /* yesterday's timestamp*/
665 struct tm
*timep
= localtime(&t
);
667 if(argv
[1][1]=='m') /* -m yestarday - month */
669 strftime(mstr
, 4, "%b", timep
);
671 strftime(ystr
, 5, "%Y", timep
);
674 else /* -y yesterday - year */
678 strftime(ystr
, 5, "%Y", timep
);
682 printf("Analysing traffic for %s %s ...\n",month
,year
);
684 sprintf(str
,"%s %s/*.log",ls
,log_dir
);
688 ptr
=strrchr(str
,'\n');
690 printf("Parsing %s ...",str
);
696 valid_columns(ptr
,_
,'\t',col
) switch(col
)
698 case 2: name
=ptr
;break;
699 case 3: traffic
=atol(ptr
);break;
700 case 7: valid_columns(ptr2
,ptr
,' ',col2
) switch(col2
)
702 case 2: if(any_month
|| eq(ptr2
,month
)) m_ok
=1; break;
703 case 5: if(eq(ptr2
,year
)) y_ok
=1; break;
708 traffic_month
+=traffic
;
717 iplog
->traffic
=traffic_month
;
718 insert(iplog
,iplogs
,desc_order_by
,traffic
);
719 printf(" %ld MB\n",iplog
->traffic
);
722 puts(" no records.");
724 sprintf(str
,"%s/%s-%s.html",html_log_dir
,year
,month
);
725 printf("Writing %s ...",str
);
729 fprintf(f
,"<table border><tr><th colspan=\"4\">Data transfers - %s %s</th></tr>\n ",month
,year
);
733 fprintf(f
,"<tr><td align=\"right\">%d</td><th>%s</td><td align=\"right\">%ld MB</td><th align=\"right\">%ld GB</th></tr>\n",i
++,iplog
->name
,iplog
->traffic
,iplog
->traffic
>>10);
734 total
+=iplog
->traffic
>>10;
736 fprintf(f
,"<tr><th colspan=\"3\" align=\"left\">Total:</th><th align=\"right\">%ld GB</th></tr>\n",total
);
737 fputs("</table>\n",f
);
744 /*-----------------------------------------------------------------*/
745 /* Are you looking for int main (int argc, char **argv) ? :-)) */
746 /*-----------------------------------------------------------------*/
754 int class_count
=0,ip_count
=0;
758 int just_preview
=0; /* preview - generate just stats */
759 char *chain_forward
, *chain_postrouting
;
763 Prometheus QoS - \"fair-per-IP\" Quality of Service setup utility.\n\
764 Version %s - Copyright (C)2005-2008 Michael Polak (xChaos)\n\
765 iptables-restore & burst tunning & classify modification 0.7d by Ludva\n\
766 Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version
);
768 /*----- Boring... we have to check command line options first: ----*/
772 argument("-c") { nextargument(config
); }
773 argument("-h") { nextargument(althosts
);}
774 argument("-d") { dry_run
=1; }
775 argument("-f") { just_flush
=1; }
776 argument("-9") { just_flush
=9; }
777 argument("-p") { just_preview
=1; }
778 argument("-n") { nodelay
=1; }
779 argument("-l") { parse_ip_log(argc
,argv
); exit(0); }
780 argument("-m") { parse_ip_log(argc
,argv
); exit(0); }
781 argument("-y") { parse_ip_log(argc
,argv
); exit(0); }
782 argument("-?") { help(); exit(0); }
783 argument("--help") { help(); exit(0); }
784 argument("-v") { exit(0); }
785 argument("--version") { exit(0); }
789 puts("*** THIS IS JUST DRY RUN ! ***\n");
791 date(d
); /* this is typical cll1.h macro */
793 /*-----------------------------------------------------------------*/
794 printf("Parsing configuration file %s ...\n", config
);
795 /*-----------------------------------------------------------------*/
798 if(althosts
) hosts
=althosts
;
802 /*-----------------------------------------------------------------*/
803 puts("Parsing iptables verbose output ...");
804 /*-----------------------------------------------------------------*/
805 get_traffic_statistics();
808 /*-----------------------------------------------------------------*/
809 printf("Parsing class defintion file %s ...\n", hosts
);
810 /*-----------------------------------------------------------------*/
811 int groupidx
= FIRSTGROUPID
;
816 if(*str
<'0' || *str
>'9')
819 //Does this IP share QoS class with some other ?
820 substring
=strstr(str
,"sharing-");
823 substring
+=8; //"sharing-"
826 ip
->sharing
=substring
;
827 ip
->keyword
=defaultkeyword
; /* settings for default keyword */
828 while(*substring
&& *substring
!='\n')
834 //Do we have to create new QoS class for this IP ?
836 find(keyword
,keywords
,(substring
=strstr(str
,keyword
->key
)))
842 ip
->prio
=keyword
->default_prio
;
843 substring
+=strlen(keyword
->key
)+1;
845 while(*ptr
&& *ptr
!='-')
850 ip
->max
=ip
->desired
=atoi(ptr
+1);
852 ip
->min
=atoi(substring
);
855 puts("Illegal value of minimum bandwidth: 0 kbps.");
856 reject_config_and_exit(hosts
);
861 ip
->max
=ip
->min
+ip
->keyword
->reserve_min
;
865 ip
->max
-=ip
->keyword
->reserve_max
;
868 if(ip->keyword->divide_max>1)
869 ip->max=ip->min+(ip->max-ip->min)/ip->keyword->divide_max;
870 if(ip->keyword->htb_ceil_bonus_divide>0)
871 ip->max+=ip->max/ip->keyword->htb_ceil_bonus_divide;
876 ip
->mark
=FIRSTIPCLASS
+1+class_count
++;
878 find(group
,groups
,group
->min
==ip
->min
)
881 group
->desired
+=ip
->min
;
882 ip
->group
= group
->id
;
888 group
->id
= groupidx
++;
889 ip
->group
= group
->id
;
891 if(group
->min
<8) group
->min
=8;
892 /* Warning - this is maybe because of primitive tc namespace, can be fixed */
893 /* it is because class IDs are derived from min. bandwidth. - xCh */
894 //if(group->min>MAX_GUARANTED_KBPS) group->min=MAX_GUARANTED_KBPS;
897 group
->desired
=ip
->min
;
898 insert(group
,groups
,desc_order_by
,min
);
910 /*-----------------------------------------------------------------*/
911 /* cll1.h - let's allocate brand new character buffer... */
912 /*-----------------------------------------------------------------*/
915 /*-----------------------------------------------------------------*/
916 puts("Resolving shared connections ...");
917 /*-----------------------------------------------------------------*/
918 search(ip
,ips
,ip
->sharing
)
920 search(sharedip
,ips
,eq(sharedip
->name
,ip
->sharing
))
922 sharedip
->traffic
+=ip
->traffic
;
924 ip
->mark
=sharedip
->mark
;
928 printf("Unresolved shared connection: %s %s sharing-%s\n",ip
->addr
,ip
->name
,ip
->sharing
);
931 if(enable_credit
&& just_flush
<9)
933 /*-----------------------------------------------------------------*/
934 printf("Parsing credit file %s ...\n", credit
);
935 /*-----------------------------------------------------------------*/
938 ptr
=parse_datafile_line(_
);
941 find(ip
,ips
,eq(ip
->addr
,_
))
942 sscanf(ptr
,"%Lu",&(ip
->credit
));
950 /*-----------------------------------------------------------------*/
951 puts("Initializing iptables and tc classes ...");
952 /*-----------------------------------------------------------------*/
954 iptables_file
=fopen(iptablesfile
,"w");
955 if (iptables_file
== NULL
) {
956 puts("Cannot open iptablesfile!");
960 log_file
=fopen(cmdlog
,"w");
961 if (log_file
== NULL
) {
962 puts("Cannot open logfile!");
966 save_line(iptablespreamble
);
969 sprintf(str
,"%s qdisc del dev %s root 2>/dev/null",tc
,lan
);
972 sprintf(str
,"%s qdisc del dev %s root 2>/dev/null",tc
,wan
);
975 iptables_file
=fopen(iptablesfile
,"w");
976 save_line(iptablespreamble
);
978 if(qos_free_zone
&& *qos_free_zone
!='0')
982 sprintf(str
,"-A FORWARD -d %s -o %s -j ACCEPT", qos_free_zone
, wan
);
987 save_line(":post_noproxy - [0:0]");
988 sprintf(str
,"-A POSTROUTING -p ! tcp -o %s -j post_noproxy", lan
);
990 sprintf(str
,"-A POSTROUTING -s ! %s -o %s -j post_noproxy", proxy_ip
, lan
);
992 sprintf(str
,"-A POSTROUTING -s %s -p tcp --sport ! %d -o %s -j post_noproxy", proxy_ip
, proxy_port
, lan
);
995 chain
="post_noproxy";
1000 sprintf(str
,"-A %s -s %s -o %s -j ACCEPT", chain
, qos_free_zone
, lan
);
1004 if(ip_count
>idxtable_treshold1
&& !just_flush
)
1006 int idxcount
=0, bitmask
=32-idxtable_bitmask1
; /* default net mask: 255.255.255.240 */
1008 /*-----------------------------------------------------------------*/
1009 printf("Detected %d addresses - indexing iptables rules to improve performance...\n",ip_count
);
1010 /*-----------------------------------------------------------------*/
1012 save_line(":post_common - [0:0]");
1013 save_line(":forw_common - [0:0]");
1015 search(ip
,ips
,ip
->addr
&& *(ip
->addr
) && !eq(ip
->addr
,"0.0.0.0/0"))
1017 buf
=hash_id(ip
->addr
,bitmask
);
1018 find(idx
,idxs
,eq(idx
->id
,buf
))
1025 idx
->bitmask
=bitmask
;
1033 /* brutal perfomance optimalization */
1034 while(idxcount
>idxtable_treshold2
&& bitmask
>2*idxtable_bitmask2
)
1036 bitmask
-=idxtable_bitmask2
;
1038 search(idx
,idxs
,idx
->parent
==NULL
)
1040 buf
=hash_id(idx
->addr
,bitmask
);
1041 find(metaindex
,idxs
,eq(metaindex
->id
,buf
))
1042 metaindex
->children
++;
1045 create(metaindex
,Index
);
1046 metaindex
->addr
=idx
->addr
;
1048 metaindex
->bitmask
=bitmask
;
1049 metaindex
->parent
=NULL
;
1050 metaindex
->children
=0;
1052 push(metaindex
,idxs
);
1054 idx
->parent
=metaindex
;
1058 /* this should slightly optimize throughout ... */
1059 sort(idx
,idxs
,desc_order_by
,children
);
1060 sort(idx
,idxs
,order_by
,bitmask
);
1065 subnet
=subnet_id(idx
->addr
,idx
->bitmask
);
1066 printf("%d: %s/%d\n",++i
,subnet
,idx
->bitmask
);
1068 sprintf(str
,":post_%s - [0:0]", idx
->id
);
1071 sprintf(str
,":forw_%s - [0:0]", idx
->id
);
1076 string(buf
,strlen(idx
->parent
->id
)+6);
1077 sprintf(buf
,"post_%s",idx
->parent
->id
);
1082 sprintf(str
,"-A %s -d %s/%d -o %s -j post_%s", buf
, subnet
, idx
->bitmask
, lan
, idx
->id
);
1085 sprintf(str
,"-A %s -d %s/%d -o %s -j post_common", buf
, subnet
, idx
->bitmask
, lan
);
1090 string(buf
,strlen(idx
->parent
->id
)+6);
1091 sprintf(buf
,"forw_%s",idx
->parent
->id
);
1096 sprintf(str
,"-A %s -s %s/%d -o %s -j forw_%s", buf
, subnet
, idx
->bitmask
, wan
, idx
->id
);
1099 sprintf(str
,"-A %s -s %s/%d -o %s -j forw_common", buf
, subnet
, idx
->bitmask
, wan
);
1102 printf("Total indexed iptables chains created: %d\n", i
);
1104 sprintf(str
,"-A FORWARD -o %s -j forw_common", wan
);
1107 sprintf(str
,"-A POSTROUTING -o %s -j post_common", lan
);
1115 fclose(iptables_file
);
1116 if (log_file
) fclose(log_file
);
1117 puts("Just flushed iptables and tc classes - now exiting ...");
1123 if(!dry_run
&& !nodelay
&& qos_free_delay
)
1125 printf("Flushed iptables and tc classes - now sleeping for %d seconds...\n",qos_free_delay
);
1126 sleep(qos_free_delay
);
1129 sprintf(str
,"%s qdisc add dev %s root handle 1: htb r2q %d default 1",tc
,lan
,htb_r2q
);
1132 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
);
1135 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
);
1138 sprintf(str
,"%s qdisc add dev %s root handle 1: htb r2q %d default 1",tc
,wan
,htb_r2q
);
1141 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
);
1144 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
);
1148 /*-----------------------------------------------------------------*/
1149 puts("Locating suckers and generating root classes ...");
1150 /*-----------------------------------------------------------------*/
1151 sort(ip
,ips
,desc_order_by
,traffic
);
1154 /*-----------------------------------------------------------------*/
1155 /* sub-scope - local variables */
1157 long long int rate
=line
;
1158 long long int max
=line
;
1160 FILE *credit_file
=NULL
;
1162 if(!just_preview
&& !dry_run
&& enable_credit
) credit_file
=fopen(credit
,"w");
1170 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",
1171 tc
, lan
, parent
, group
->id
, rate
, max
, burst_group
, group
->desired
);
1175 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",
1176 tc
, wan
, parent
, group
->id
, rate
*up
/line
, max
*up
/line
, burst_group
, group
->desired
);
1180 if(group_count
++<max_nesting
) parent
=group
->id
;
1182 rate
-=digital_divide
*group
->min
;
1183 if(rate
<group
->min
)rate
=group
->min
;
1185 /*shaping of aggresive downloaders, with credit file support */
1188 int group_rate
=group
->min
, priority_sequence
=magic_priorities
+1;
1190 search(ip
, ips
, ip
->min
==group
->min
&& ip
->max
>ip
->min
)
1192 if( ip
->keyword
->data_limit
&& !ip
->fixedprio
&&
1193 ip
->traffic
>ip
->credit
+
1194 (ip
->min
*ip
->keyword
->data_limit
+(ip
->keyword
->fixed_limit
<<20)) )
1196 if(group_rate
<ip
->max
) ip
->max
=group_rate
;
1197 group_rate
+=magic_treshold
;
1198 ip
->prio
=magic_priorities
+2;
1199 if(ip
->prio
<3) ip
->prio
=3;
1203 if( ip
->keyword
->data_prio
&& !ip
->fixedprio
&&
1204 ip
->traffic
>ip
->credit
+
1205 (ip
->min
*ip
->keyword
->data_prio
+(ip
->keyword
->fixed_prio
<<20)) )
1207 ip
->prio
=priority_sequence
--;
1208 if(ip
->prio
<2) ip
->prio
=2;
1213 unsigned long long lcredit
=0;
1215 if((ip
->min
*ip
->keyword
->data_limit
+(ip
->keyword
->fixed_limit
<<20))>ip
->traffic
)
1216 lcredit
=(ip
->min
*ip
->keyword
->data_limit
+(ip
->keyword
->fixed_limit
<<20))-ip
->traffic
;
1217 fprintf(credit_file
,"%s %Lu\n",ip
->addr
,lcredit
);
1224 if(credit_file
)fclose(credit_file
);
1229 f
=fopen(preview
,"w");
1232 else if(!dry_run
&& !just_flush
)
1234 /*-----------------------------------------------------------------*/
1235 printf("Writing data transfer database ...\n");
1236 /*-----------------------------------------------------------------*/
1237 f
=fopen("/var/run/prometheus.previous","w");
1240 search(ip
,ips
,ip
->traffic
|| ip
->direct
|| ip
->proxy
||ip
->upload
)
1241 fprintf(f
,"%s %Lu %Lu %Lu %Lu\n",ip
->addr
,ip
->traffic
,ip
->direct
,ip
->proxy
,ip
->upload
);
1255 /*-----------------------------------------------------------------*/
1256 printf("Sorting data and generating statistics page %s ...\n",ptr
);
1257 /*-----------------------------------------------------------------*/
1259 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
);
1260 fprintf(f
,"<th colspan=\"%d\">data limits</th>\n",keywordcount
);
1265 printf("%d k group: %d bandwidth requested: %d k\n",group
->min
,group
->count
,group
->desired
);
1267 fprintf(f
,"<tr><td align=\"right\">%d</td><td align=\"right\">%d k</td>",count
,group
->min
);
1268 fprintf(f
,"<td align=\"right\">%d</td><td align=\"right\">%d k</td>",group
->count
,group
->desired
);
1270 every(keyword
,keywords
)
1271 fprintf(f
,"<td align=\"right\"><font color=\"#%s\">%d M</font></td>",keyword
->html_color
,group
->min
*keyword
->data_limit
);
1274 total
+=group
->count
;
1278 printf("Total groups: %d Total bandwidth requested: %d k\nAGGREGATION: 1/%d\n",count
,i
,i
/line
);
1280 fprintf(f
,"<tr><th colspan=\"2\" align=\"left\">Line %Ld k</td>",line
);
1281 fprintf(f
,"<th align=\"right\">%d</td><th align=\"right\">%d k</td>",total
,i
);
1283 every(keyword
,keywords
)
1284 fprintf(f
,"<th align=\"right\">%d IPs</th>",keyword
->ip_count
);
1286 fprintf(f
,"</tr><tr><th colspan=\"4\">Aggregation 1/%d</th>\n",(int)(0.5+i
/line
));
1287 fprintf(f
,"<th colspan=\"%d\">%d traffic classes</th></tr>\n",keywordcount
,total
);
1289 fputs("</table>\n",f
);
1291 else if(!dry_run
&& !just_flush
)
1297 unsigned long long total
=0, total_direct
=0, total_proxy
=0, total_upload
=0, tmp_sum
=0;
1298 int active_classes
=0;
1301 struct Sum
{unsigned long long l
; int i
; list(Sum
);} *sum
,*sums
=NULL
;
1308 fprintf(f
,"<p><table border>\n<tr><th colspan=\"%d\">%s",colspan
,title
);
1309 fprintf(f
," (%s)</th></tr>\n", d
);
1310 fputs("<tr><td align=\"right\">#</td><td>hostname</td>\
1311 <td align=\"right\">credit</td>\
1312 <td align=\"right\">limit</td>\
1313 <td align=\"right\">total</td>\
1314 <td align=\"right\">direct</td>\n",f
);
1316 fputs("<td align=\"right\">proxy</td>\n",f
);
1317 fputs("<td align=\"right\">upload</td>\
1318 <td align=\"right\">minimum</td>\
1319 <td align=\"right\">desired</td>\
1320 <td align=\"right\">maximum</td>\
1321 <td>prio</td></tr>\n",f
);
1325 char *f1
="", *f2
="";
1326 if(ip
->max
<ip
->desired
)
1328 f1
="<font color=\"red\">";
1333 f1
="<font color=\"brown\">";
1338 printf("%03d. %-22s %10Lu (%d/%d)\n",i
,ip
->name
, ip
->traffic
, ip
->min
, ip
->max
);
1340 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",
1341 ip
->name
, i
, log_url
, ip
->name
, ip
->name
, ip
->credit
);
1342 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)));
1343 fprintf(f
,"<td align=\"right\">%s%Lu M%s</td><td align=\"right\">%Lu M</td>\n", f1
, ip
->traffic
, f2
, ip
->direct
);
1345 fprintf(f
,"<td align=\"right\">%Lu M</td>\n", ip
->proxy
);
1346 fprintf(f
,"<td align=\"right\">%Lu M</td>\n", ip
->upload
);
1347 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
);
1349 total_direct
+=ip
->direct
;
1350 total_proxy
+=ip
->proxy
;
1351 total_upload
+=ip
->upload
;
1355 tmp_sum
+=ip
->traffic
;
1358 sum
->i
=active_classes
;
1359 insert(sum
,sums
,order_by
,i
);
1366 sprintf(str
,"%s/%s.log",log_dir
,ip
->name
);
1367 iplog
=fopen(str
,"a");
1370 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
);
1376 fprintf(f
,"<tr><th colspan=\"4 \"align=\"left\">SUMMARY:</td>");
1377 fprintf(f
,"<th align=\"right\">%Lu M</th>\
1378 <th align=\"right\">%Lu M</th>\n", total
, total_direct
);
1380 fprintf(f
,"<th align=\"right\">%Lu M</th>\n", total_proxy
);
1381 fprintf(f
,"<th align=\"right\">%Lu M</th>", total_upload
);
1382 fputs("<td colspan=\"4\"></td></th>\n</table>\n",f
);
1384 if(active_classes
>10)
1386 fputs("<a name=\"erp\"></a><p><table border><tr><th colspan=\"5\">Enterprise Research and Planning (ERP)</th></tr>\n",f
);
1387 fputs("<tr><td>Analytic category</td>\n",f
);
1388 fputs("<td colspan=\"2\" align=\"center\">Active Classes</td><td colspan=\"2\" align=\"center\">Data transfers</td></tr>\n",f
);
1390 find(sum
,sums
,sum
->l
>=total
/4)
1392 fprintf(f
,"<tr><td>Top 25%% of traffic</td>\n");
1393 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
);
1396 find(sum
,sums
,sum
->i
==10)
1398 fprintf(f
,"<tr><td>Top 10 downloaders</td>\n");
1399 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
);
1402 find(sum
,sums
,sum
->l
>=total
/2)
1404 fprintf(f
,"<tr><td>Top 50%% of traffic</td>\n");
1405 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
);
1408 find(sum
,sums
,sum
->l
>=4*total
/5)
1410 fprintf(f
,"<tr><td>Top 80%% of traffic</td>\n");
1411 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
);
1414 find (sum
,sums
,sum
->i
>=(active_classes
+1)/5)
1416 fprintf(f
,"<tr><td>Top 20%% downloaders</td>\n");
1417 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
);
1420 find(sum
,sums
,sum
->i
>=(active_classes
+1)/4)
1422 fprintf(f
,"<tr><td>Top 25%% downloaders</td>\n");
1423 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
);
1426 find(sum
,sums
,sum
->i
>=(active_classes
+1)/2)
1428 fprintf(f
,"<tr><td>Top 50%% downloaders</td>\n");
1429 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
);
1432 find(sum
,sums
,sum
->i
>=4*(active_classes
+1)/5)
1434 fprintf(f
,"<tr><td>Top 80%% downloaders</td>\n");
1435 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
);
1438 fprintf(f
,"<tr><td>All users, all traffic</td>\n");
1439 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
);
1440 fputs("</table>\n",f
);
1442 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
);
1448 puts("Statistics preview generated (-p switch) - now exiting ...");
1452 /*-----------------------------------------------------------------*/
1453 puts("Generating iptables and tc classes ...");
1454 /*-----------------------------------------------------------------*/
1457 printf("%-22s %-15s mark\n","name","ip");
1458 search(ip
,ips
,ip
->mark
>0)
1464 duplicate(ip
->addr
,buf
);
1465 buf
=hash_id(ip
->addr
,32-idxtable_bitmask1
);
1467 string(chain_forward
,6+strlen(buf
));
1468 strcpy(chain_forward
,"forw_");
1469 strcat(chain_forward
,buf
);
1471 string(chain_postrouting
,6+strlen(buf
));
1472 strcpy(chain_postrouting
,"post_");
1473 strcat(chain_postrouting
,buf
);
1479 chain_forward
="FORWARD";
1480 chain_postrouting
="POSTROUTING";
1483 printf("%-22s %-16s %04d ", ip
->name
, ip
->addr
, ip
->mark
);
1485 /* -------------------------------------------------------- mark download */
1487 sprintf(str
,"-A %s -d %s/32 -o %s -j %s%d",chain_postrouting
,ip
->addr
,lan
,mark_iptables
,ip
->mark
);
1488 /*sprintf(str,"-A %s -d %s/32 -o %s -j MARK --set-mark %d",chain_postrouting,ip->addr,lan,ip->mark);*/
1489 /* -m limit --limit 1/s */
1494 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
);
1495 /*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);*/
1499 sprintf(str
,"-A %s -d %s/32 -o %s -j ACCEPT",chain_postrouting
,ip
->addr
,lan
);
1502 /* -------------------------------------------------------- mark upload */
1503 sprintf(str
,"-A %s -s %s/32 -o %s -j %s%d",chain_forward
,ip
->addr
,wan
,mark_iptables
,ip
->mark
);
1504 /* sprintf(str,"-A %s -s %s/32 -o %s -j MARK --set-mark %d",chain_forward,ip->addr,wan,ip->mark);*/
1507 sprintf(str
,"-A %s -s %s/32 -o %s -j ACCEPT",chain_forward
,ip
->addr
,wan
);
1512 /* -------------------------------------------------------- download class */
1513 printf("(down: %dk-%dk ", ip
->min
, ip
->max
);
1515 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
);
1518 if (strcmpi(ip
->keyword
->leaf_discipline
, "none")){
1519 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*/
1523 if (filter_type
== 1){
1524 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle %d fw flowid 1:%d", tc
, lan
, ip
->mark
, ip
->mark
);
1528 /* -------------------------------------------------------- upload class */
1529 printf("up: %dk-%dk)\n", (int)((ip
->min
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
),
1530 (int)((ip
->max
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
));
1532 sprintf(str
,"%s class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit burst %dk prio %d",
1533 tc
, wan
, ip
->group
, ip
->mark
,
1534 (int)((ip
->min
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
),
1535 (int)((ip
->max
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
), burst
, ip
->prio
);
1538 if (strcmpi(ip
->keyword
->leaf_discipline
, "none")){
1539 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*/
1543 if (filter_type
== 1){
1544 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle %d fw flowid 1:%d",tc
, wan
, ip
->mark
, ip
->mark
);
1549 printf("(sharing %s)\n", ip
->sharing
);
1556 chain_forward
="forw_common";
1557 chain_postrouting
="post_common";
1561 chain_forward
="FORWARD";
1562 chain_postrouting
="POSTROUTING";
1565 /* -------------------------------------------------------- mark download */
1569 sprintf(str
,"-A %s -s %s -p tcp --sport %d -o %s -j MARK --set-mark 3",chain_postrouting
,proxy_ip
,proxy_port
,lan
);
1571 sprintf(str
,"-A %s -s %s -p tcp --sport %d -o %s -j ACCEPT",chain_postrouting
,proxy_ip
,proxy_port
,lan
);
1574 sprintf(str
,"-A %s -o %s -j MARK --set-mark 3",chain_postrouting
,lan
);
1576 sprintf(str
,"-A %s -o %s -j ACCEPT",chain_postrouting
,lan
);
1579 /* -------------------------------------------------------- mark upload */
1580 sprintf(str
,"-A %s -o %s -j MARK --set-mark 3",chain_forward
,wan
);
1582 sprintf(str
,"-A %s -o %s -j ACCEPT",chain_forward
,wan
);
1585 printf("Total IP count: %d\n", i
);
1587 /*-----------------------------------------------------------------*/
1588 puts("Generating free bandwith classes ...");
1589 /*-----------------------------------------------------------------*/
1591 /* ---------------------------------------- tc - free bandwith shared class */
1592 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
);
1595 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
);
1599 if (strcmpi(qos_leaf
, "none")){
1600 sprintf(str
,"%s qdisc add dev %s parent 1:3 handle 3 %s",tc
,lan
,qos_leaf
);
1603 sprintf(str
,"%s qdisc add dev %s parent 1:3 handle 3 %s",tc
,wan
,qos_leaf
);
1607 /* tc handle 1 fw flowid */
1608 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle 3 fw flowid 1:3",tc
,lan
);
1611 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle 3 fw flowid 1:3",tc
,wan
);
1616 if (log_file
) fclose(log_file
);
1619 /* that's all folks, thank you for reading it all the way up to this point ;-) */
1620 /* bad luck C<<1 is not yet finished, I promise no sprintf() next time... */
This page took 1.264025 seconds and 3 git commands to generate.