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, 20080422
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.9.2"; /*0.7.9 will be last development, 0.8.0 first stable */
39 /* ======= All path names are defined here (for RPM patch) ======= */
41 char *tc
= "/sbin/tc"; /* requires tc with HTB support */
42 char *iptables
= "/sbin/iptables"; /* requires iptables utility */
43 char *iptablessave
= "/sbin/iptables-save"; /* not yet required */
44 char *iptablesrestore
= "/sbin/iptables-restore"; /* requires iptables-restore */
45 char *ls
= "/bin/ls"; /* this is not user configurable :-) */
47 char *config
= "/etc/prometheus/prometheus.conf"; /* main configuration file */
48 char *hosts
= "/etc/prometheus/hosts"; /* per-IP bandwidth definition file */
50 char *iptablesfile
= "/var/spool/prometheus.iptables"; /* temporary file for iptables-restore*/
51 char *credit
= "/var/lib/misc/prometheus.credit"; /* credit log file */
52 char *html
= "/var/www/traffic.html"; /* hall of fame filename */
53 char *preview
= "/var/www/preview.html"; /* hall of fame preview */
54 char *cmdlog
= "/var/log/prometheuslog"; /* command log filename */
55 char *log_dir
= "/var/www/logs/"; /* log directory pathname, ended with slash */
56 char *log_url
= "logs/"; /* log directory relative URI prefix (partial URL) */
57 char *html_log_dir
= "/var/www/logs/html/";
59 /* ======= Help screen is hopefuly self-documenting part of code :-) ======= */
63 puts("Command line switches:\n\
65 -?, --help this help screen\n\
66 -v, --version show version number of this utility and exit\n\
67 -c filename force alternative /etc/prometheus.conf filename\n\
68 -h filename force alternative /etc/hosts filename (overrides hosts keyword)\n\
69 -f just flush iptables and tc classes and exit (stop shaping)\n\
70 -9 emergency iptables flush (do not read data transfer statistics)\n\
71 -p just generate preview of data transfer statistics and exit\n\
72 -n no delay (overrides qos-free-delay keyword)\n\
73 -d dry run (preview tc and iptables commands on stdout)\n\
74 -l Mmm YYYY generate HTML summary of traffic logs (Mmm=Jan-Dec or Year, YYYY=year)\n\
75 -m generate HTML summary of traffic logs for yesterday's month\n\
76 -y generate HTML summary of traffic logs for yesterday's year\n");
77 /* not yet implemented:
78 -s start shaping! (keep data transfer statistics - but apply shaping)\n\
79 -r just reload configuration (...and keep data transfer statistics)\n\
83 /* === Configuraration file values defaults - stored in global variables ==== */
85 int filter_type
=1; /*1 mark, 2 classify*/
87 char *mark_iptables
="MARK --set-mark ";
88 int dry_run
=0; /* preview - use puts() instead of system() */
89 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]";
90 FILE *iptables_file
=NULL
;
91 int enable_credit
=1; /* enable credit file */
92 int use_credit
=0; /* use credit file (if enabled)*/
93 char *title
="Hall of Fame - Greatest Suckers"; /* hall of fame title */
94 int hall_of_fame
=1; /* enable hall of fame */
95 char *lan
="eth0"; /* LAN interface */
96 char *lan_medium
="100Mbit"; /* 10Mbit/100Mbit ethernet */
97 char *wan
="eth1"; /* WAN/ISP interface */
98 char *wan_medium
="100Mbit"; /* 10Mbit/100Mbit ethernet */
99 char *qos_leaf
="sfq perturb 5"; /* leaf discipline */
100 char *qos_free_zone
=NULL
; /* QoS free zone */
101 int qos_proxy
=1; /* include proxy port to QoS */
102 int include_upload
=1; /* upload+download=total traffic */
103 char *proxy_ip
="192.168.1.1/32"; /* our IP with proxy port */
104 int proxy_port
=3128; /* proxy port number */
105 long long int line
=1024; /* WAN/ISP download in kbps */
106 long long int up
=1024; /* WAN/ISP upload in kbps */
107 int free_min
=32; /* minimum guaranted bandwidth for all undefined hosts */
108 int free_max
=64; /* maximum allowed bandwidth for all undefined hosts */
109 int qos_free_delay
=0; /* seconds to sleep before applying new QoS rules */
110 int digital_divide
=2; /* controls digital divide weirdness ratio, 1...3 */
111 int max_nesting
=3; /* maximum nesting of HTB clases, built-in maximum seems to be 4 */
113 int burst
=8; /* HTB burst (in kbits) */
116 int magic_priorities
=8; /* number of priority levels (soft shaping) */
117 int magic_treshold
=8; /* reduce ceil by X*magic_treshhold kbps (hard shaping) */
120 /* not yet implemented:
121 int fixed_packets=0; maximum number of pps per IP address (not class!)
122 int packet_limit=5; maximum number of pps to htn CEIL, not rate !!!
126 char *kwd
="via-prometheus"; /* /etc/hosts comment, eg. #qos-64-128 */
128 const int idxtable_treshold1
=24; /* this is no longer configurable */
129 const int idxtable_treshold2
=12; /* this is no longer configurable */
130 const int idxtable_bitmask1
=3; /* this is no longer configurable */
131 const int idxtable_bitmask2
=3; /* this is no longer configurable */
133 /* ==== This is C<<1 stuff - learn C<<1 first! http://cll1.arachne.cz ==== */
147 unsigned long long direct
;
148 unsigned long long proxy
;
149 unsigned long long upload
;
150 unsigned long long traffic
;
151 unsigned long long credit
;
152 unsigned long pktsup
;
153 unsigned long pktsdown
;
154 struct Keyword
*keyword
;
156 } *ips
=NULL
, *ip
, *sharedip
;
165 } *groups
=NULL
, *group
;
171 struct Index
*parent
;
175 } *idxs
=NULL
, *idx
, *metaindex
;
181 int asymetry_ratio
; /* ratio for ADSL-like upload */
182 int asymetry_fixed
; /* fixed treshold for ADSL-like upload */
183 int data_limit
; /* hard shaping: apply magic_treshold if max*data_limit MB exceeded */
184 int data_prio
; /* soft shaping (qos): reduce HTB prio if max*data_prio MB exceeded */
185 long fixed_limit
; /* fixed data limit for setting lower HTB ceil */
186 long fixed_prio
; /* fixed data lmit for setting lower HTB prio */
187 int reserve_min
; /* bonus for nominal HTB rate bandwidth (in kbps) */
188 int reserve_max
; /* malus for nominal HTB ceil (in kbps) */
189 // int divide_max; /* relative malus: new_ceil=rate+(old_ceil-rate)/divide_max */
190 // int htb_ceil_bonus_divide; /* relative bonus: new_ceil=old_ceil+old_ceil/htb_ceil_bonus_divide */
191 int default_prio
; /* default HTB priority for this keyword */
194 char *leaf_discipline
;
197 } *keyword
,*defaultkeyword
=NULL
,*keywords
=NULL
;
199 /* Damned, this must be object oriented! This looks almost like constructor ;-) */
209 ip
->mark
=ip
->min
=ip
->max
=ip
->desired
=ip
->credit
=0;
210 ip
->upload
=ip
->proxy
=ip
->direct
=ip
->traffic
=0;
211 ip
->pktsup
=ip
->pktsdown
=0;
212 ip
->keyword
=keywords
;
216 /* ====== iptables indexes are used to reduce complexity to log8(N) ===== */
218 char *very_ugly_ipv4_code(char *inip
,int bitmask
,int format_as_chainname
)
220 /* warning: this function was debugged only for bitmask values 20,24,28 !!!*/
222 char *ip
,*outip
,*outptr
,*fmt
;
225 /* debug printf("(%s,%d) -> ",ip,bitmask); */
227 if(ip
&& *ip
&& bitmask
>=0 && bitmask
<=32)
228 string(outip
,strlen(ip
)+10); /*fuck unicode? assertion: 10>strlen("_%d_%d") */
230 /* should never exit here */
237 if(dot
<(bitmask
/8-1))
239 if(format_as_chainname
)
248 char *cutdot
=strchr(ip
+1,'.'); /*for bitmask<24*/
249 if(cutdot
)*cutdot
='\0';
250 if(format_as_chainname
)
255 n
=atoi(ip
+1)-atoi(ip
+1)%(1<<(8-bitmask
%8));
259 /*debug printf("%d/%d => [_%d_%d]\n",atoi(ip+1),bitmask,n,bitmask); */
260 sprintf(outptr
,fmt
,n
,bitmask
);
261 if(!format_as_chainname
) while(bitmask
<24)
266 /* debug printf("[%s]\n",outip); */
277 /*should never exit here*/
282 char *hash_id(char *ip
,int bitmask
)
283 { return very_ugly_ipv4_code(ip
,bitmask
,1); }
285 char *subnet_id(char *ip
,int bitmask
)
286 { return very_ugly_ipv4_code(ip
,bitmask
,0); }
288 /* ================= Let's parse configuration file here =================== */
290 void reject_config_and_exit(char *filename
)
292 printf("Configuration file %s rejected - abnormal exit.",filename
);
296 void get_config(char *config_filename
)
300 printf("Configured keywords: ");
301 parse(config_filename
)
303 option("keyword",kwd
);
308 create(keyword
,Keyword
);
310 keyword
->asymetry_ratio
=1; /* ratio for ADSL-like upload */
311 keyword
->asymetry_fixed
=0; /* fixed treshold for ADSL-like upload */
312 keyword
->data_limit
=8; /* hard shaping: apply magic_treshold if max*data_limit MB exceeded */
313 keyword
->data_prio
=4; /* soft shaping (qos): reduce HTB prio if max*data_prio MB exceeded */
314 keyword
->fixed_limit
=0; /* fixed data limit for setting lower HTB ceil */
315 keyword
->fixed_prio
=0; /* fixed data limit for setting lower HTB prio */
316 keyword
->reserve_min
=8; /* bonus for nominal HTB rate bandwidth (in kbps) */
317 keyword
->reserve_max
=0; /* malus for nominal HTB ceil (in kbps) */
319 keyword->divide_max=0; relative malus: new_ceil=rate+(old_ceil-rate)/divide_max
320 keyword->htb_ceil_bonus_divide=0; relative bonus: new_ceil=old_ceil+old_ceil/htb_ceil_bonus_divide
322 keyword
->default_prio
=1;
323 keyword
->html_color
="000000";
325 keyword
->leaf_discipline
="";
327 push(keyword
,keywords
);
328 if(!defaultkeyword
) defaultkeyword
=keyword
;
333 else every(keyword
,keywords
)
335 int l
=strlen(keyword
->key
);
338 if(!strncmp(keyword
->key
,_
,l
) && strlen(_
)>l
+2)
340 char *tmptr
=_
; /* <---- l+1 ----> */
341 _
+=l
+1; /* via-prometheus-asymetry-ratio, etc. */
342 ioption("asymetry-ratio",keyword
->asymetry_ratio
);
343 ioption("asymetry-treshold",keyword
->asymetry_fixed
);
344 ioption("magic-relative-limit",keyword
->data_limit
);
345 ioption("magic-relative-prio",keyword
->data_prio
);
346 loption("magic-fixed-limit",keyword
->fixed_limit
);
347 loption("magic-fixed-prio",keyword
->fixed_prio
);
348 ioption("htb-default-prio",keyword
->default_prio
);
349 ioption("htb-rate-bonus",keyword
->reserve_min
);
350 ioption("htb-ceil-malus",keyword
->reserve_max
);
352 ioption("htb-ceil-divide",keyword->divide_max);
353 ioption("htb-ceil-bonus-divide",keyword->htb_ceil_bonus_divide);
355 option("leaf-discipline",keyword
->leaf_discipline
);
356 option("html-color",keyword
->html_color
);
359 if(keyword
->data_limit
|| keyword
->fixed_limit
||
360 keyword
->data_prio
|| keyword
->fixed_prio
)
366 option("iptables",iptables
);
367 option("iptables-save",iptablessave
); /* new */
368 option("iptables-restore",iptablesrestore
); /* new */
369 option("iptables-file",iptablesfile
); /* new */
370 option("hosts",hosts
);
371 option("lan-interface",lan
);
372 option("wan-interface",wan
);
373 option("lan-medium",lan_medium
);
374 option("wan-medium",wan_medium
);
375 lloption("wan-download",line
);
376 lloption("wan-upload",up
);
377 ioption("hall-of-fame-enable",hall_of_fame
);
378 option("hall-of-fame-title",title
);
379 option("hall-of-fame-filename",html
);
380 option("hall-of-fame-preview",preview
);
381 option("log-filename",cmdlog
);
382 option("credit-filename",credit
);
383 ioption("credit-enable",enable_credit
);
384 option("log-traffic-directory",log_dir
);
385 option("log-traffic-html-directory",html_log_dir
);
386 option("log-traffic-url-path",log_url
);
387 option("qos-free-zone",qos_free_zone
);
388 ioption("qos-free-delay",qos_free_delay
);
389 ioption("qos-proxy-enable",qos_proxy
);
390 option("qos-proxy-ip",proxy_ip
);
391 option("htb-leaf-discipline",qos_leaf
);
392 ioption("qos-proxy-port",proxy_port
);
393 ioption("free-rate",free_min
);
394 ioption("free-ceil",free_max
);
395 ioption("htb-burst",burst
);
396 ioption("htb-burst-main",burst_main
);
397 ioption("htb-burst-group",burst_group
);
398 ioption("htb-nesting-limit",max_nesting
);
399 ioption("htb-r2q",htb_r2q
);
400 ioption("magic-include-upload",include_upload
);
401 ioption("magic-priorities",magic_priorities
);
402 ioption("magic-treshold",magic_treshold
);
403 option("filter-type", cnf
);
405 /* not yet implemented:
406 ioption("magic-fixed-packets",fixed_packets);
407 ioption("magic-relative-packets",packet_limit);
412 perror(config_filename
);
413 puts("Warning - using built-in defaults instead ...");
418 /*leaf discipline for keywords*/
419 every(keyword
,keywords
)
421 if (!strcmpi(keyword
->leaf_discipline
, "")){
422 keyword
->leaf_discipline
= qos_leaf
;
426 if (strcmpi(cnf
, "mark")){
429 mark_iptables
= "CLASSIFY --set-class 1:";
433 mark_iptables
= "MARK --set-mark ";
436 /* are supplied values meaningful ?*/
439 puts("Illegal value of wan bandwidth: 0 kbps.");
440 reject_config_and_exit(config_filename
);
444 /* ===================== traffic analyser - uses iptables ================ */
446 void get_traffic_statistics(void)
451 textfile(Pipe
,str
) *line
,*lines
=NULL
;
455 sprintf(cmd
,"%s -L -v -x -n -t mangle",iptables
);
467 int col
, accept
=0,proxyflag
=0,valid
=1,setchainname
=0,commonflag
=0;
468 unsigned long long traffic
=0;
469 unsigned long pkts
=0;
470 char *ipaddr
=NULL
,*ptr
;
472 /* debug puts(line->str); */
473 valid_columns(ptr
,line
->str
,' ',col
)
474 if(valid
) switch(col
)
476 case 1: if(eq(ptr
,"Chain"))
478 else if(eq(ptr
,"pkts"))
481 sscanf(ptr
,"%lu",&pkts
);
483 case 2: if(setchainname
)
485 if(!strncmp(ptr
,"post_",5) || eq(ptr
,"POSTROUTING"))
488 if(!strncmp(ptr
,"forw_",5) || eq(ptr
,"FORWARD"))
491 if(eq(ptr
,"post_common") || eq(ptr
,"forw_common"))
495 sscanf(ptr
,"%Lu",&traffic
); traffic
+=(1<<19); traffic
>>=20;
497 case 3: if((strncmp(ptr
,"post_",5) && strncmp(ptr
,"forw_",5)) || commonflag
)
499 /*if (filter_type==1) accept=eq(ptr,"MARK"); else accept=eq(ptr,"CLASSIFY");*/
501 case 8: if(downloadflag
)
503 if(strstr(proxy_ip
,ptr
))proxyflag
=1;
508 case 9: if(downloadflag
)ipaddr
=ptr
;break;
511 if(accept
&& traffic
>0 && ipaddr
)
513 if(proxyflag
)printf("(proxy) ");
514 else if(!downloadflag
) printf("(upload) ");
515 printf("IP %s: %Lu M (%ld pkts)\n", ipaddr
, traffic
, pkts
);
516 find(ip
,ips
,eq(ip
->addr
,ipaddr
));
521 if(eq(ip
->addr
,"0.0.0.0/0"))
523 ip
->name
="(unregistered)";
525 ip
->max
=ip
->desired
=free_max
;
534 ip
->traffic
+=traffic
;
535 ip
->direct
=ip
->traffic
-ip
->upload
-ip
->proxy
;
543 ip
->traffic
+=traffic
;
545 if(traffic
>ip
->traffic
)
555 /* ========== This function executes, logs OR ALSO prints command ========== */
557 void safe_run(char *cmd
)
559 if(dry_run
) printf("\n=>%s\n",cmd
); else system(cmd
);
560 if(log_file
) fprintf(log_file
,"%s\n",cmd
);
563 void save_line(char *line
)
565 fprintf(iptables_file
,"%s\n",line
);
568 void run_restore(void)
571 string(restor
,STRLEN
);
573 /*-----------------------------------------------------------------*/
574 printf("Running %s <%s ...\n",iptablesrestore
,iptablesfile
);
575 /*-----------------------------------------------------------------*/
578 fclose(iptables_file
);
588 sprintf(restor
,"%s <%s",iptablesrestore
, iptablesfile
);
594 /* == This function strips extra characters after IP address and stores it = */
596 void parse_ip(char *str
)
598 char *ptr
=str
,*ipaddr
=NULL
,*ipname
=NULL
;;
600 while(*ptr
&& *ptr
!=' ' && *ptr
!=9)
606 while(*ptr
&& (*ptr
==' ' || *ptr
==9))
609 while(*ptr
&& *ptr
!=' ' && *ptr
!=9)
613 find(ip
,ips
,eq(ip
->addr
,ipaddr
)); else TheIP();
618 char *parse_datafile_line(char *str
)
620 char *ptr
=strchr(str
,' ');
639 void parse_ip_log(int argc
, char **argv
)
641 char *month
,*year
,*str
,*name
,*ptr
,*ptr2
;
642 long traffic
,traffic_month
,total
=0;
643 int col
,col2
,y_ok
,m_ok
,accept_month
,i
=1,any_month
=0;
644 char mstr
[4],ystr
[5];
649 if(argv
[1][1]=='l') /* -l */
653 puts("Missing parameter(s)!\nUsage: prometheus -l Mmm YYYY (Mmm=Jan-Dec or Year, YYYY=year)");
659 if(eq(month
,"Year")) any_month
=1;
665 time_t t
= time(NULL
) - 3600*24 ; /* yesterday's timestamp*/
666 struct tm
*timep
= localtime(&t
);
668 if(argv
[1][1]=='m') /* -m yestarday - month */
670 strftime(mstr
, 4, "%b", timep
);
672 strftime(ystr
, 5, "%Y", timep
);
675 else /* -y yesterday - year */
679 strftime(ystr
, 5, "%Y", timep
);
683 printf("Analysing traffic for %s %s ...\n",month
,year
);
685 sprintf(str
,"%s %s/*.log",ls
,log_dir
);
689 ptr
=strrchr(str
,'\n');
691 printf("Parsing %s ...",str
);
697 valid_columns(ptr
,_
,'\t',col
) switch(col
)
699 case 2: name
=ptr
;break;
700 case 3: traffic
=atol(ptr
);break;
701 case 7: valid_columns(ptr2
,ptr
,' ',col2
) switch(col2
)
703 case 2: if(any_month
|| eq(ptr2
,month
)) m_ok
=1; break;
704 case 5: if(eq(ptr2
,year
)) y_ok
=1; break;
709 traffic_month
+=traffic
;
718 iplog
->traffic
=traffic_month
;
719 insert(iplog
,iplogs
,desc_order_by
,traffic
);
720 printf(" %ld MB\n",iplog
->traffic
);
723 puts(" no records.");
725 sprintf(str
,"%s/%s-%s.html",html_log_dir
,year
,month
);
726 printf("Writing %s ...",str
);
730 fprintf(f
,"<table border><tr><th colspan=\"4\">Data transfers - %s %s</th></tr>\n ",month
,year
);
734 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);
735 total
+=iplog
->traffic
>>10;
737 fprintf(f
,"<tr><th colspan=\"3\" align=\"left\">Total:</th><th align=\"right\">%ld GB</th></tr>\n",total
);
738 fputs("</table>\n",f
);
745 /*-----------------------------------------------------------------*/
746 /* Are you looking for int main (int argc, char **argv) ? :-)) */
747 /*-----------------------------------------------------------------*/
755 int class_count
=0,ip_count
=0;
759 int just_preview
=0; /* preview - generate just stats */
760 int just_logs
=0; /* just parse logs */
762 char *chain_forward
, *chain_postrouting
;
766 Prometheus QoS - \"fair-per-IP\" Quality of Service setup utility.\n\
767 Version %s - Copyright (C)2005-2008 Michael Polak (xChaos)\n\
768 iptables-restore & burst tunning & classify modification 0.7d by Ludva\n\
769 Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version
);
771 /*----- Boring... we have to check command line options first: ----*/
775 argument("-c") { nextargument(config
); }
776 argument("-h") { nextargument(althosts
);}
777 argument("-d") { dry_run
=1; }
778 argument("-f") { just_flush
=1; }
779 argument("-9") { just_flush
=9; }
780 argument("-p") { just_preview
=1; }
781 argument("-n") { nodelay
=1; }
782 argument("-l") { just_logs
=1; }
783 argument("-m") { just_logs
=1; }
784 argument("-y") { just_logs
=1; }
785 argument("-?") { help(); exit(0); }
786 argument("--help") { help(); exit(0); }
787 argument("-v") { exit(0); }
788 argument("--version") { exit(0); }
792 puts("*** THIS IS JUST DRY RUN ! ***\n");
794 date(d
); /* this is typical cll1.h macro */
796 /*-----------------------------------------------------------------*/
797 printf("Parsing configuration file %s ...\n", config
);
798 /*-----------------------------------------------------------------*/
803 parse_ip_log(argc
,argv
);
807 if(althosts
) hosts
=althosts
;
811 /*-----------------------------------------------------------------*/
812 puts("Parsing iptables verbose output ...");
813 /*-----------------------------------------------------------------*/
814 get_traffic_statistics();
817 /*-----------------------------------------------------------------*/
818 printf("Parsing class defintion file %s ...\n", hosts
);
819 /*-----------------------------------------------------------------*/
820 int groupidx
= FIRSTGROUPID
;
825 if(*str
<'0' || *str
>'9')
828 //Does this IP share QoS class with some other ?
829 substring
=strstr(str
,"sharing-");
832 substring
+=8; //"sharing-"
835 ip
->sharing
=substring
;
836 ip
->keyword
=defaultkeyword
; /* settings for default keyword */
837 while(*substring
&& *substring
!='\n')
843 //Do we have to create new QoS class for this IP ?
845 find(keyword
,keywords
,(substring
=strstr(str
,keyword
->key
)))
851 ip
->prio
=keyword
->default_prio
;
852 substring
+=strlen(keyword
->key
)+1;
854 while(*ptr
&& *ptr
!='-')
859 ip
->max
=ip
->desired
=atoi(ptr
+1);
861 ip
->min
=atoi(substring
);
864 printf(" %s: Illegal value of minimum bandwidth 0 kbps, using %d kbps\n",str
,free_min
);
870 ip
->max
=ip
->min
+ip
->keyword
->reserve_min
;
874 ip
->max
-=ip
->keyword
->reserve_max
;
877 if(ip->keyword->divide_max>1)
878 ip->max=ip->min+(ip->max-ip->min)/ip->keyword->divide_max;
879 if(ip->keyword->htb_ceil_bonus_divide>0)
880 ip->max+=ip->max/ip->keyword->htb_ceil_bonus_divide;
885 ip
->mark
=FIRSTIPCLASS
+1+class_count
++;
887 find(group
,groups
,group
->min
==ip
->min
)
890 group
->desired
+=ip
->min
;
891 ip
->group
= group
->id
;
897 group
->id
= groupidx
++;
898 ip
->group
= group
->id
;
900 if(group
->min
<8) group
->min
=8;
901 /* Warning - this is maybe because of primitive tc namespace, can be fixed */
902 /* it is because class IDs are derived from min. bandwidth. - xCh */
903 //if(group->min>MAX_GUARANTED_KBPS) group->min=MAX_GUARANTED_KBPS;
906 group
->desired
=ip
->min
;
907 insert(group
,groups
,desc_order_by
,min
);
919 /*-----------------------------------------------------------------*/
920 /* cll1.h - let's allocate brand new character buffer... */
921 /*-----------------------------------------------------------------*/
924 /*-----------------------------------------------------------------*/
925 puts("Resolving shared connections ...");
926 /*-----------------------------------------------------------------*/
927 search(ip
,ips
,ip
->sharing
)
929 search(sharedip
,ips
,eq(sharedip
->name
,ip
->sharing
))
931 sharedip
->traffic
+=ip
->traffic
;
933 ip
->mark
=sharedip
->mark
;
937 printf("Unresolved shared connection: %s %s sharing-%s\n",ip
->addr
,ip
->name
,ip
->sharing
);
940 if(enable_credit
&& just_flush
<9)
942 /*-----------------------------------------------------------------*/
943 printf("Parsing credit file %s ...\n", credit
);
944 /*-----------------------------------------------------------------*/
947 ptr
=parse_datafile_line(_
);
950 find(ip
,ips
,eq(ip
->addr
,_
))
951 sscanf(ptr
,"%Lu",&(ip
->credit
));
959 /*-----------------------------------------------------------------*/
960 puts("Initializing iptables and tc classes ...");
961 /*-----------------------------------------------------------------*/
963 iptables_file
=fopen(iptablesfile
,"w");
964 if (iptables_file
== NULL
) {
965 puts("Cannot open iptablesfile!");
969 log_file
=fopen(cmdlog
,"w");
970 if (log_file
== NULL
) {
971 puts("Cannot open logfile!");
975 save_line(iptablespreamble
);
978 sprintf(str
,"%s qdisc del dev %s root 2>/dev/null",tc
,lan
);
981 sprintf(str
,"%s qdisc del dev %s root 2>/dev/null",tc
,wan
);
984 iptables_file
=fopen(iptablesfile
,"w");
985 save_line(iptablespreamble
);
987 if(qos_free_zone
&& *qos_free_zone
!='0')
991 sprintf(str
,"-A FORWARD -d %s -o %s -j ACCEPT", qos_free_zone
, wan
);
996 save_line(":post_noproxy - [0:0]");
997 sprintf(str
,"-A POSTROUTING -p ! tcp -o %s -j post_noproxy", lan
);
999 sprintf(str
,"-A POSTROUTING -s ! %s -o %s -j post_noproxy", proxy_ip
, lan
);
1001 sprintf(str
,"-A POSTROUTING -s %s -p tcp --sport ! %d -o %s -j post_noproxy", proxy_ip
, proxy_port
, lan
);
1004 chain
="post_noproxy";
1007 chain
="POSTROUTING";
1009 sprintf(str
,"-A %s -s %s -o %s -j ACCEPT", chain
, qos_free_zone
, lan
);
1013 if(ip_count
>idxtable_treshold1
&& !just_flush
)
1015 int idxcount
=0, bitmask
=32-idxtable_bitmask1
; /* default net mask: 255.255.255.240 */
1017 /*-----------------------------------------------------------------*/
1018 printf("Detected %d addresses - indexing iptables rules to improve performance...\n",ip_count
);
1019 /*-----------------------------------------------------------------*/
1021 save_line(":post_common - [0:0]");
1022 save_line(":forw_common - [0:0]");
1024 search(ip
,ips
,ip
->addr
&& *(ip
->addr
) && !eq(ip
->addr
,"0.0.0.0/0"))
1026 buf
=hash_id(ip
->addr
,bitmask
);
1027 find(idx
,idxs
,eq(idx
->id
,buf
))
1034 idx
->bitmask
=bitmask
;
1042 /* brutal perfomance optimalization */
1043 while(idxcount
>idxtable_treshold2
&& bitmask
>2*idxtable_bitmask2
)
1045 bitmask
-=idxtable_bitmask2
;
1047 search(idx
,idxs
,idx
->parent
==NULL
)
1049 buf
=hash_id(idx
->addr
,bitmask
);
1050 find(metaindex
,idxs
,eq(metaindex
->id
,buf
))
1051 metaindex
->children
++;
1054 create(metaindex
,Index
);
1055 metaindex
->addr
=idx
->addr
;
1057 metaindex
->bitmask
=bitmask
;
1058 metaindex
->parent
=NULL
;
1059 metaindex
->children
=0;
1061 push(metaindex
,idxs
);
1063 idx
->parent
=metaindex
;
1067 /* this should slightly optimize throughout ... */
1068 sort(idx
,idxs
,desc_order_by
,children
);
1069 sort(idx
,idxs
,order_by
,bitmask
);
1074 subnet
=subnet_id(idx
->addr
,idx
->bitmask
);
1075 printf("%d: %s/%d\n",++i
,subnet
,idx
->bitmask
);
1077 sprintf(str
,":post_%s - [0:0]", idx
->id
);
1080 sprintf(str
,":forw_%s - [0:0]", idx
->id
);
1085 string(buf
,strlen(idx
->parent
->id
)+6);
1086 sprintf(buf
,"post_%s",idx
->parent
->id
);
1091 sprintf(str
,"-A %s -d %s/%d -o %s -j post_%s", buf
, subnet
, idx
->bitmask
, lan
, idx
->id
);
1094 sprintf(str
,"-A %s -d %s/%d -o %s -j post_common", buf
, subnet
, idx
->bitmask
, lan
);
1099 string(buf
,strlen(idx
->parent
->id
)+6);
1100 sprintf(buf
,"forw_%s",idx
->parent
->id
);
1105 sprintf(str
,"-A %s -s %s/%d -o %s -j forw_%s", buf
, subnet
, idx
->bitmask
, wan
, idx
->id
);
1108 sprintf(str
,"-A %s -s %s/%d -o %s -j forw_common", buf
, subnet
, idx
->bitmask
, wan
);
1111 printf("Total indexed iptables chains created: %d\n", i
);
1113 sprintf(str
,"-A FORWARD -o %s -j forw_common", wan
);
1116 sprintf(str
,"-A POSTROUTING -o %s -j post_common", lan
);
1124 fclose(iptables_file
);
1125 if (log_file
) fclose(log_file
);
1126 puts("Just flushed iptables and tc classes - now exiting ...");
1132 if(!dry_run
&& !nodelay
&& qos_free_delay
)
1134 printf("Flushed iptables and tc classes - now sleeping for %d seconds...\n",qos_free_delay
);
1135 sleep(qos_free_delay
);
1138 sprintf(str
,"%s qdisc add dev %s root handle 1: htb r2q %d default 1",tc
,lan
,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
,lan
,lan_medium
,lan_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
,lan
,line
,line
,burst_main
);
1147 sprintf(str
,"%s qdisc add dev %s root handle 1: htb r2q %d default 1",tc
,wan
,htb_r2q
);
1150 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
);
1153 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
);
1157 /*-----------------------------------------------------------------*/
1158 puts("Locating suckers and generating root classes ...");
1159 /*-----------------------------------------------------------------*/
1160 sort(ip
,ips
,desc_order_by
,traffic
);
1163 /*-----------------------------------------------------------------*/
1164 /* sub-scope - local variables */
1166 long long int rate
=line
;
1167 long long int max
=line
;
1169 FILE *credit_file
=NULL
;
1171 if(!just_preview
&& !dry_run
&& enable_credit
) credit_file
=fopen(credit
,"w");
1179 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",
1180 tc
, lan
, parent
, group
->id
, rate
, max
, burst_group
, group
->desired
);
1184 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",
1185 tc
, wan
, parent
, group
->id
, rate
*up
/line
, max
*up
/line
, burst_group
, group
->desired
);
1189 if(group_count
++<max_nesting
) parent
=group
->id
;
1191 rate
-=digital_divide
*group
->min
;
1192 if(rate
<group
->min
)rate
=group
->min
;
1194 /*shaping of aggresive downloaders, with credit file support */
1197 int group_rate
=group
->min
, priority_sequence
=magic_priorities
+1;
1199 search(ip
, ips
, ip
->min
==group
->min
&& ip
->max
>ip
->min
)
1201 if( ip
->keyword
->data_limit
&& !ip
->fixedprio
&&
1202 ip
->traffic
>ip
->credit
+
1203 (ip
->min
*ip
->keyword
->data_limit
+(ip
->keyword
->fixed_limit
<<20)) )
1205 if(group_rate
<ip
->max
) ip
->max
=group_rate
;
1206 group_rate
+=magic_treshold
;
1207 ip
->prio
=magic_priorities
+2;
1208 if(ip
->prio
<3) ip
->prio
=3;
1212 if( ip
->keyword
->data_prio
&& !ip
->fixedprio
&&
1213 ip
->traffic
>ip
->credit
+
1214 (ip
->min
*ip
->keyword
->data_prio
+(ip
->keyword
->fixed_prio
<<20)) )
1216 ip
->prio
=priority_sequence
--;
1217 if(ip
->prio
<2) ip
->prio
=2;
1222 unsigned long long lcredit
=0;
1224 if((ip
->min
*ip
->keyword
->data_limit
+(ip
->keyword
->fixed_limit
<<20))>ip
->traffic
)
1225 lcredit
=(ip
->min
*ip
->keyword
->data_limit
+(ip
->keyword
->fixed_limit
<<20))-ip
->traffic
;
1226 fprintf(credit_file
,"%s %Lu\n",ip
->addr
,lcredit
);
1233 if(credit_file
)fclose(credit_file
);
1238 f
=fopen(preview
,"w");
1241 else if(!dry_run
&& !just_flush
)
1243 /*-----------------------------------------------------------------*/
1244 printf("Writing data transfer database ...\n");
1245 /*-----------------------------------------------------------------*/
1246 f
=fopen("/var/run/prometheus.previous","w");
1249 search(ip
,ips
,ip
->traffic
|| ip
->direct
|| ip
->proxy
||ip
->upload
)
1250 fprintf(f
,"%s %Lu %Lu %Lu %Lu\n",ip
->addr
,ip
->traffic
,ip
->direct
,ip
->proxy
,ip
->upload
);
1264 /*-----------------------------------------------------------------*/
1265 printf("Sorting data and generating statistics page %s ...\n",ptr
);
1266 /*-----------------------------------------------------------------*/
1268 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
);
1269 fprintf(f
,"<th colspan=\"%d\">data limits</th>\n",keywordcount
);
1274 printf("%d k group: %d bandwidth requested: %d k\n",group
->min
,group
->count
,group
->desired
);
1276 fprintf(f
,"<tr><td align=\"right\">%d</td><td align=\"right\">%d k</td>",count
,group
->min
);
1277 fprintf(f
,"<td align=\"right\">%d</td><td align=\"right\">%d k</td>",group
->count
,group
->desired
);
1279 every(keyword
,keywords
)
1280 fprintf(f
,"<td align=\"right\"><font color=\"#%s\">%d M</font></td>",keyword
->html_color
,group
->min
*keyword
->data_limit
);
1283 total
+=group
->count
;
1287 printf("Total groups: %d Total bandwidth requested: %d k\nAGGREGATION: 1/%d\n",count
,i
,i
/line
);
1289 fprintf(f
,"<tr><th colspan=\"2\" align=\"left\">Line %Ld k</td>",line
);
1290 fprintf(f
,"<th align=\"right\">%d</td><th align=\"right\">%d k</td>",total
,i
);
1292 every(keyword
,keywords
)
1293 fprintf(f
,"<th align=\"right\">%d IPs</th>",keyword
->ip_count
);
1295 fprintf(f
,"</tr><tr><th colspan=\"4\">Aggregation 1/%d</th>\n",(int)(0.5+i
/line
));
1296 fprintf(f
,"<th colspan=\"%d\">%d traffic classes</th></tr>\n",keywordcount
,total
);
1298 fputs("</table>\n",f
);
1300 else if(!dry_run
&& !just_flush
)
1306 unsigned long long total
=0, total_direct
=0, total_proxy
=0, total_upload
=0, tmp_sum
=0;
1307 int active_classes
=0;
1310 struct Sum
{unsigned long long l
; int i
; list(Sum
);} *sum
,*sums
=NULL
;
1317 fprintf(f
,"<p><table border>\n<tr><th colspan=\"%d\">%s",colspan
,title
);
1318 fprintf(f
," (%s)</th></tr>\n", d
);
1319 fputs("<tr><td align=\"right\">#</td><td>hostname</td>\
1320 <td align=\"right\">credit</td>\
1321 <td align=\"right\">limit</td>\
1322 <td align=\"right\">total</td>\
1323 <td align=\"right\">direct</td>\n",f
);
1325 fputs("<td align=\"right\">proxy</td>\n",f
);
1326 fputs("<td align=\"right\">upload</td>\
1327 <td align=\"right\">minimum</td>\
1328 <td align=\"right\">desired</td>\
1329 <td align=\"right\">maximum</td>\
1330 <td>prio</td></tr>\n",f
);
1334 char *f1
="", *f2
="";
1335 if(ip
->max
<ip
->desired
)
1337 f1
="<font color=\"red\">";
1342 f1
="<font color=\"brown\">";
1347 printf("%03d. %-22s %10Lu (%d/%d)\n",i
,ip
->name
, ip
->traffic
, ip
->min
, ip
->max
);
1349 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",
1350 ip
->name
, i
, log_url
, ip
->name
, ip
->name
, ip
->credit
);
1351 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)));
1352 fprintf(f
,"<td align=\"right\">%s%Lu M%s</td><td align=\"right\">%Lu M</td>\n", f1
, ip
->traffic
, f2
, ip
->direct
);
1354 fprintf(f
,"<td align=\"right\">%Lu M</td>\n", ip
->proxy
);
1355 fprintf(f
,"<td align=\"right\">%Lu M</td>\n", ip
->upload
);
1356 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
);
1358 total_direct
+=ip
->direct
;
1359 total_proxy
+=ip
->proxy
;
1360 total_upload
+=ip
->upload
;
1364 tmp_sum
+=ip
->traffic
;
1367 sum
->i
=active_classes
;
1368 insert(sum
,sums
,order_by
,i
);
1375 sprintf(str
,"%s/%s.log",log_dir
,ip
->name
);
1376 iplog
=fopen(str
,"a");
1379 fprintf(iplog
,"%ld\t%s\t%Lu\t%Lu\t%Lu\t%Lu\t%d\t%d\t%d\t%s",
1380 time(NULL
),ip
->name
,ip
->traffic
,ip
->direct
,ip
->proxy
,ip
->upload
,ip
->min
,ip
->max
,ip
->desired
,d
); /* d = date*/
1386 fprintf(f
,"<tr><th colspan=\"4 \"align=\"left\">SUMMARY:</td>");
1387 fprintf(f
,"<th align=\"right\">%Lu M</th>\
1388 <th align=\"right\">%Lu M</th>\n", total
, total_direct
);
1390 fprintf(f
,"<th align=\"right\">%Lu M</th>\n", total_proxy
);
1391 fprintf(f
,"<th align=\"right\">%Lu M</th>", total_upload
);
1392 fputs("<td colspan=\"4\"></td></th>\n</table>\n",f
);
1394 if(active_classes
>10)
1396 fputs("<a name=\"erp\"></a><p><table border><tr><th colspan=\"5\">Enterprise Research and Planning (ERP)</th></tr>\n",f
);
1397 fputs("<tr><td>Analytic category</td>\n",f
);
1398 fputs("<td colspan=\"2\" align=\"center\">Active Classes</td><td colspan=\"2\" align=\"center\">Data transfers</td></tr>\n",f
);
1400 find(sum
,sums
,sum
->l
>=total
/4)
1402 fprintf(f
,"<tr><td>Top 25%% of traffic</td>\n");
1403 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
);
1406 find(sum
,sums
,sum
->i
==10)
1408 fprintf(f
,"<tr><td>Top 10 downloaders</td>\n");
1409 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
);
1412 find(sum
,sums
,sum
->l
>=total
/2)
1414 fprintf(f
,"<tr><td>Top 50%% of traffic</td>\n");
1415 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
);
1418 find(sum
,sums
,sum
->l
>=4*total
/5)
1420 fprintf(f
,"<tr><td>Top 80%% of traffic</td>\n");
1421 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
);
1424 find (sum
,sums
,sum
->i
>=(active_classes
+1)/5)
1426 fprintf(f
,"<tr><td>Top 20%% downloaders</td>\n");
1427 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
);
1430 find(sum
,sums
,sum
->i
>=(active_classes
+1)/4)
1432 fprintf(f
,"<tr><td>Top 25%% downloaders</td>\n");
1433 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
);
1436 find(sum
,sums
,sum
->i
>=(active_classes
+1)/2)
1438 fprintf(f
,"<tr><td>Top 50%% downloaders</td>\n");
1439 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
);
1442 find(sum
,sums
,sum
->i
>=4*(active_classes
+1)/5)
1444 fprintf(f
,"<tr><td>Top 80%% downloaders</td>\n");
1445 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
);
1448 fprintf(f
,"<tr><td>All users, all traffic</td>\n");
1449 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
);
1450 fputs("</table>\n",f
);
1452 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
);
1458 puts("Statistics preview generated (-p switch) - now exiting ...");
1462 /*-----------------------------------------------------------------*/
1463 puts("Generating iptables and tc classes ...");
1464 /*-----------------------------------------------------------------*/
1467 printf("%-22s %-15s mark\n","name","ip");
1468 search(ip
,ips
,ip
->mark
>0)
1474 duplicate(ip
->addr
,buf
);
1475 buf
=hash_id(ip
->addr
,32-idxtable_bitmask1
);
1477 string(chain_forward
,6+strlen(buf
));
1478 strcpy(chain_forward
,"forw_");
1479 strcat(chain_forward
,buf
);
1481 string(chain_postrouting
,6+strlen(buf
));
1482 strcpy(chain_postrouting
,"post_");
1483 strcat(chain_postrouting
,buf
);
1489 chain_forward
="FORWARD";
1490 chain_postrouting
="POSTROUTING";
1493 printf("%-22s %-16s %04d ", ip
->name
, ip
->addr
, ip
->mark
);
1495 /* -------------------------------------------------------- mark download */
1497 sprintf(str
,"-A %s -d %s/32 -o %s -j %s%d",chain_postrouting
,ip
->addr
,lan
,mark_iptables
,ip
->mark
);
1498 /*sprintf(str,"-A %s -d %s/32 -o %s -j MARK --set-mark %d",chain_postrouting,ip->addr,lan,ip->mark);*/
1499 /* -m limit --limit 1/s */
1504 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
);
1505 /*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);*/
1509 sprintf(str
,"-A %s -d %s/32 -o %s -j ACCEPT",chain_postrouting
,ip
->addr
,lan
);
1512 /* -------------------------------------------------------- mark upload */
1513 sprintf(str
,"-A %s -s %s/32 -o %s -j %s%d",chain_forward
,ip
->addr
,wan
,mark_iptables
,ip
->mark
);
1514 /* sprintf(str,"-A %s -s %s/32 -o %s -j MARK --set-mark %d",chain_forward,ip->addr,wan,ip->mark);*/
1517 sprintf(str
,"-A %s -s %s/32 -o %s -j ACCEPT",chain_forward
,ip
->addr
,wan
);
1522 /* -------------------------------------------------------- download class */
1523 printf("(down: %dk-%dk ", ip
->min
, ip
->max
);
1525 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
);
1528 if (strcmpi(ip
->keyword
->leaf_discipline
, "none")){
1529 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*/
1533 if (filter_type
== 1){
1534 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle %d fw flowid 1:%d", tc
, lan
, ip
->mark
, ip
->mark
);
1538 /* -------------------------------------------------------- upload class */
1539 printf("up: %dk-%dk)\n", (int)((ip
->min
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
),
1540 (int)((ip
->max
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
));
1542 sprintf(str
,"%s class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit burst %dk prio %d",
1543 tc
, wan
, ip
->group
, ip
->mark
,
1544 (int)((ip
->min
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
),
1545 (int)((ip
->max
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
), burst
, ip
->prio
);
1548 if (strcmpi(ip
->keyword
->leaf_discipline
, "none")){
1549 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*/
1553 if (filter_type
== 1){
1554 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle %d fw flowid 1:%d",tc
, wan
, ip
->mark
, ip
->mark
);
1559 printf("(sharing %s)\n", ip
->sharing
);
1566 chain_forward
="forw_common";
1567 chain_postrouting
="post_common";
1571 chain_forward
="FORWARD";
1572 chain_postrouting
="POSTROUTING";
1575 /* -------------------------------------------------------- mark download */
1579 sprintf(str
,"-A %s -s %s -p tcp --sport %d -o %s -j %s%d",chain_postrouting
,proxy_ip
,proxy_port
,lan
,mark_iptables
,3);
1581 sprintf(str
,"-A %s -s %s -p tcp --sport %d -o %s -j ACCEPT",chain_postrouting
,proxy_ip
,proxy_port
,lan
);
1584 sprintf(str
,"-A %s -o %s -j %s%d",chain_postrouting
,lan
,mark_iptables
,3);
1586 sprintf(str
,"-A %s -o %s -j ACCEPT",chain_postrouting
,lan
);
1589 /* -------------------------------------------------------- mark upload */
1590 sprintf(str
,"-A %s -o %s -j %s%d",chain_forward
,wan
,mark_iptables
,3);
1592 sprintf(str
,"-A %s -o %s -j ACCEPT",chain_forward
,wan
);
1595 printf("Total IP count: %d\n", i
);
1597 /*-----------------------------------------------------------------*/
1598 puts("Generating free bandwith classes ...");
1599 /*-----------------------------------------------------------------*/
1601 /* ---------------------------------------- tc - free bandwith shared class */
1602 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
);
1605 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
);
1609 if (strcmpi(qos_leaf
, "none")){
1610 sprintf(str
,"%s qdisc add dev %s parent 1:3 handle 3 %s",tc
,lan
,qos_leaf
);
1613 sprintf(str
,"%s qdisc add dev %s parent 1:3 handle 3 %s",tc
,wan
,qos_leaf
);
1617 /* tc handle 1 fw flowid */
1618 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle 3 fw flowid 1:3",tc
,lan
);
1621 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle 3 fw flowid 1:3",tc
,wan
);
1626 if (log_file
) fclose(log_file
);
1629 /* that's all folks, thank you for reading it all the way up to this point ;-) */
1630 /* bad luck C<<1 is not yet finished, I promise no sprintf() next time... */
This page took 1.169821 seconds and 5 git commands to generate.