d8eaef2d44f4dee405ef9d603ce9b082cffdca43
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-c";
38 /* Version numbers: 0.7.9 will be last development ("beta"), 0.8.0 first stable */
39 /* Debian(RPM) package versions/patchlevels: 0.7.9-2, 0.8.0-1, 0.8.0-2, etc. */
40 /* C source code development versions ("beta"): 0.7.9-a, 0.8.1-b, etc. */
41 /* C source code release versions: 0.8.0, 0.8.2, 0.8.4, etc. */
43 /* ======= All path names are defined here (for RPM patch) ======= */
45 char *tc
= "/sbin/tc"; /* requires tc with HTB support */
46 char *iptables
= "/sbin/iptables"; /* requires iptables utility */
47 char *iptablessave
= "/sbin/iptables-save"; /* not yet required */
48 char *iptablesrestore
= "/sbin/iptables-restore"; /* requires iptables-restore */
49 char *ls
= "/bin/ls"; /* this is not user configurable :-) */
51 char *config
= "/etc/prometheus/prometheus.conf"; /* main configuration file */
52 char *hosts
= "/etc/prometheus/hosts"; /* per-IP bandwidth definition file */
54 char *iptablesfile
= "/var/spool/prometheus.iptables"; /* temporary file for iptables-restore*/
55 char *credit
= "/var/lib/misc/prometheus.credit"; /* credit log file */
56 char *html
= "/var/www/traffic.html"; /* hall of fame filename */
57 char *preview
= "/var/www/preview.html"; /* hall of fame preview */
58 char *cmdlog
= "/var/log/prometheuslog"; /* command log filename */
59 char *log_dir
= "/var/www/logs/"; /* log directory pathname, ended with slash */
60 char *log_url
= "logs/"; /* log directory relative URI prefix (partial URL) */
61 char *html_log_dir
= "/var/www/logs/html/";
63 /* ======= Help screen is hopefuly self-documenting part of code :-) ======= */
67 puts("Command line switches:\n\
69 -?, --help this help screen\n\
70 -v, --version show version number of this utility and exit\n\
71 -c filename force alternative /etc/prometheus.conf filename\n\
72 -h filename force alternative /etc/hosts filename (overrides hosts keyword)\n\
73 -f just flush iptables and tc classes and exit (stop shaping)\n\
74 -9 emergency iptables flush (do not read data transfer statistics)\n\
75 -p just generate preview of data transfer statistics and exit\n\
76 -n no delay (overrides qos-free-delay keyword)\n\
77 -d dry run (preview tc and iptables commands on stdout)\n\
78 -l Mmm YYYY generate HTML summary of traffic logs (Mmm=Jan-Dec or Year, YYYY=year)\n\
79 -m generate HTML summary of traffic logs for yesterday's month\n\
80 -y generate HTML summary of traffic logs for yesterday's year\n");
81 /* not yet implemented:
82 -s start shaping! (keep data transfer statistics - but apply shaping)\n\
83 -r just reload configuration (...and keep data transfer statistics)\n\
87 /* === Configuraration file values defaults - stored in global variables ==== */
89 int filter_type
=1; /*1 mark, 2 classify*/
91 char *mark_iptables
="MARK --set-mark ";
92 int dry_run
=0; /* preview - use puts() instead of system() */
93 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]";
94 FILE *iptables_file
=NULL
;
95 int enable_credit
=1; /* enable credit file */
96 int use_credit
=0; /* use credit file (if enabled)*/
97 char *title
="Hall of Fame - Greatest Suckers"; /* hall of fame title */
98 int hall_of_fame
=1; /* enable hall of fame */
99 char *lan
="eth0"; /* LAN interface */
100 char *lan_medium
="100Mbit"; /* 10Mbit/100Mbit ethernet */
101 char *wan
="eth1"; /* WAN/ISP interface */
102 char *wan_medium
="100Mbit"; /* 10Mbit/100Mbit ethernet */
103 char *qos_leaf
="sfq perturb 5"; /* leaf discipline */
104 char *qos_free_zone
=NULL
; /* QoS free zone */
105 int qos_proxy
=1; /* include proxy port to QoS */
106 int include_upload
=1; /* upload+download=total traffic */
107 char *proxy_ip
="192.168.1.1/32"; /* our IP with proxy port */
108 int proxy_port
=3128; /* proxy port number */
109 long long int line
=1024; /* WAN/ISP download in kbps */
110 long long int up
=1024; /* WAN/ISP upload in kbps */
111 int free_min
=32; /* minimum guaranted bandwidth for all undefined hosts */
112 int free_max
=64; /* maximum allowed bandwidth for all undefined hosts */
113 int qos_free_delay
=0; /* seconds to sleep before applying new QoS rules */
114 int digital_divide
=2; /* controls digital divide weirdness ratio, 1...3 */
115 int max_nesting
=3; /* maximum nesting of HTB clases, built-in maximum seems to be 4 */
117 int burst
=8; /* HTB burst (in kbits) */
120 int magic_priorities
=8; /* number of priority levels (soft shaping) */
121 int magic_treshold
=8; /* reduce ceil by X*magic_treshhold kbps (hard shaping) */
124 /* not yet implemented:
125 int fixed_packets=0; maximum number of pps per IP address (not class!)
126 int packet_limit=5; maximum number of pps to htn CEIL, not rate !!!
130 char *kwd
="via-prometheus"; /* /etc/hosts comment, eg. #qos-64-128 */
132 const int idxtable_treshold1
=24; /* this is no longer configurable */
133 const int idxtable_treshold2
=12; /* this is no longer configurable */
134 const int idxtable_bitmask1
=3; /* this is no longer configurable */
135 const int idxtable_bitmask2
=3; /* this is no longer configurable */
137 /* ==== This is C<<1 stuff - learn C<<1 first! http://cll1.arachne.cz ==== */
151 unsigned long long direct
;
152 unsigned long long proxy
;
153 unsigned long long upload
;
154 unsigned long long traffic
;
155 unsigned long long credit
;
156 unsigned long pktsup
;
157 unsigned long pktsdown
;
158 struct Keyword
*keyword
;
160 } *ips
=NULL
, *ip
, *sharedip
;
169 } *groups
=NULL
, *group
;
175 struct Index
*parent
;
179 } *idxs
=NULL
, *idx
, *metaindex
;
185 int asymetry_ratio
; /* ratio for ADSL-like upload */
186 int asymetry_fixed
; /* fixed treshold for ADSL-like upload */
187 int data_limit
; /* hard shaping: apply magic_treshold if max*data_limit MB exceeded */
188 int data_prio
; /* soft shaping (qos): reduce HTB prio if max*data_prio MB exceeded */
189 long fixed_limit
; /* fixed data limit for setting lower HTB ceil */
190 long fixed_prio
; /* fixed data lmit for setting lower HTB prio */
191 int reserve_min
; /* bonus for nominal HTB rate bandwidth (in kbps) */
192 int reserve_max
; /* malus for nominal HTB ceil (in kbps) */
193 // int divide_max; /* relative malus: new_ceil=rate+(old_ceil-rate)/divide_max */
194 // int htb_ceil_bonus_divide; /* relative bonus: new_ceil=old_ceil+old_ceil/htb_ceil_bonus_divide */
195 int default_prio
; /* default HTB priority for this keyword */
198 char *leaf_discipline
;
201 } *keyword
,*defaultkeyword
=NULL
,*keywords
=NULL
;
203 /* Damned, this must be object oriented! This looks almost like constructor ;-) */
213 ip
->mark
=ip
->min
=ip
->max
=ip
->desired
=ip
->credit
=0;
214 ip
->upload
=ip
->proxy
=ip
->direct
=ip
->traffic
=0;
215 ip
->pktsup
=ip
->pktsdown
=0;
216 ip
->keyword
=keywords
;
220 /* ====== iptables indexes are used to reduce complexity to log8(N) ===== */
222 char *very_ugly_ipv4_code(char *inip
,int bitmask
,int format_as_chainname
)
224 /* warning: this function was debugged only for bitmask values 20,24,28 !!!*/
226 char *ip
,*outip
,*outptr
,*fmt
;
229 /* debug printf("(%s,%d) -> ",ip,bitmask); */
231 if(ip
&& *ip
&& bitmask
>=0 && bitmask
<=32)
232 string(outip
,strlen(ip
)+10); /*fuck unicode? assertion: 10>strlen("_%d_%d") */
234 /* should never exit here */
241 if(dot
<(bitmask
/8-1))
243 if(format_as_chainname
)
252 char *cutdot
=strchr(ip
+1,'.'); /*for bitmask<24*/
253 if(cutdot
)*cutdot
='\0';
254 if(format_as_chainname
)
259 n
=atoi(ip
+1)-atoi(ip
+1)%(1<<(8-bitmask
%8));
263 /*debug printf("%d/%d => [_%d_%d]\n",atoi(ip+1),bitmask,n,bitmask); */
264 sprintf(outptr
,fmt
,n
,bitmask
);
265 if(!format_as_chainname
) while(bitmask
<24)
270 /* debug printf("[%s]\n",outip); */
281 /*should never exit here*/
286 char *hash_id(char *ip
,int bitmask
)
287 { return very_ugly_ipv4_code(ip
,bitmask
,1); }
289 char *subnet_id(char *ip
,int bitmask
)
290 { return very_ugly_ipv4_code(ip
,bitmask
,0); }
292 /* ================= Let's parse configuration file here =================== */
294 void reject_config_and_exit(char *filename
)
296 printf("Configuration file %s rejected - abnormal exit.",filename
);
300 void get_config(char *config_filename
)
304 printf("Configured keywords: ");
305 parse(config_filename
)
307 option("keyword",kwd
);
312 create(keyword
,Keyword
);
314 keyword
->asymetry_ratio
=1; /* ratio for ADSL-like upload */
315 keyword
->asymetry_fixed
=0; /* fixed treshold for ADSL-like upload */
316 keyword
->data_limit
=8; /* hard shaping: apply magic_treshold if max*data_limit MB exceeded */
317 keyword
->data_prio
=4; /* soft shaping (qos): reduce HTB prio if max*data_prio MB exceeded */
318 keyword
->fixed_limit
=0; /* fixed data limit for setting lower HTB ceil */
319 keyword
->fixed_prio
=0; /* fixed data limit for setting lower HTB prio */
320 keyword
->reserve_min
=8; /* bonus for nominal HTB rate bandwidth (in kbps) */
321 keyword
->reserve_max
=0; /* malus for nominal HTB ceil (in kbps) */
323 keyword->divide_max=0; relative malus: new_ceil=rate+(old_ceil-rate)/divide_max
324 keyword->htb_ceil_bonus_divide=0; relative bonus: new_ceil=old_ceil+old_ceil/htb_ceil_bonus_divide
326 keyword
->default_prio
=1;
327 keyword
->html_color
="000000";
329 keyword
->leaf_discipline
="";
331 push(keyword
,keywords
);
332 if(!defaultkeyword
) defaultkeyword
=keyword
;
337 else every(keyword
,keywords
)
339 int l
=strlen(keyword
->key
);
342 if(!strncmp(keyword
->key
,_
,l
) && strlen(_
)>l
+2)
344 char *tmptr
=_
; /* <---- l+1 ----> */
345 _
+=l
+1; /* via-prometheus-asymetry-ratio, etc. */
346 ioption("asymetry-ratio",keyword
->asymetry_ratio
);
347 ioption("asymetry-treshold",keyword
->asymetry_fixed
);
348 ioption("magic-relative-limit",keyword
->data_limit
);
349 ioption("magic-relative-prio",keyword
->data_prio
);
350 loption("magic-fixed-limit",keyword
->fixed_limit
);
351 loption("magic-fixed-prio",keyword
->fixed_prio
);
352 ioption("htb-default-prio",keyword
->default_prio
);
353 ioption("htb-rate-bonus",keyword
->reserve_min
);
354 ioption("htb-ceil-malus",keyword
->reserve_max
);
356 ioption("htb-ceil-divide",keyword->divide_max);
357 ioption("htb-ceil-bonus-divide",keyword->htb_ceil_bonus_divide);
359 option("leaf-discipline",keyword
->leaf_discipline
);
360 option("html-color",keyword
->html_color
);
363 if(keyword
->data_limit
|| keyword
->fixed_limit
||
364 keyword
->data_prio
|| keyword
->fixed_prio
)
370 option("iptables",iptables
);
371 option("iptables-save",iptablessave
); /* new */
372 option("iptables-restore",iptablesrestore
); /* new */
373 option("iptables-file",iptablesfile
); /* new */
374 option("hosts",hosts
);
375 option("lan-interface",lan
);
376 option("wan-interface",wan
);
377 option("lan-medium",lan_medium
);
378 option("wan-medium",wan_medium
);
379 lloption("wan-download",line
);
380 lloption("wan-upload",up
);
381 ioption("hall-of-fame-enable",hall_of_fame
);
382 option("hall-of-fame-title",title
);
383 option("hall-of-fame-filename",html
);
384 option("hall-of-fame-preview",preview
);
385 option("log-filename",cmdlog
);
386 option("credit-filename",credit
);
387 ioption("credit-enable",enable_credit
);
388 option("log-traffic-directory",log_dir
);
389 option("log-traffic-html-directory",html_log_dir
);
390 option("log-traffic-url-path",log_url
);
391 option("qos-free-zone",qos_free_zone
);
392 ioption("qos-free-delay",qos_free_delay
);
393 ioption("qos-proxy-enable",qos_proxy
);
394 option("qos-proxy-ip",proxy_ip
);
395 option("htb-leaf-discipline",qos_leaf
);
396 ioption("qos-proxy-port",proxy_port
);
397 ioption("free-rate",free_min
);
398 ioption("free-ceil",free_max
);
399 ioption("htb-burst",burst
);
400 ioption("htb-burst-main",burst_main
);
401 ioption("htb-burst-group",burst_group
);
402 ioption("htb-nesting-limit",max_nesting
);
403 ioption("htb-r2q",htb_r2q
);
404 ioption("magic-include-upload",include_upload
);
405 ioption("magic-priorities",magic_priorities
);
406 ioption("magic-treshold",magic_treshold
);
407 option("filter-type", cnf
);
409 /* not yet implemented:
410 ioption("magic-fixed-packets",fixed_packets);
411 ioption("magic-relative-packets",packet_limit);
416 perror(config_filename
);
417 puts("Warning - using built-in defaults instead ...");
422 /*leaf discipline for keywords*/
423 every(keyword
,keywords
)
425 if (!strcmpi(keyword
->leaf_discipline
, "")){
426 keyword
->leaf_discipline
= qos_leaf
;
430 if (strcmpi(cnf
, "mark")){
433 mark_iptables
= "CLASSIFY --set-class 1:";
437 mark_iptables
= "MARK --set-mark ";
440 /* are supplied values meaningful ?*/
443 puts("Illegal value of LAN or WAN bandwidth: 0 kbps.");
444 reject_config_and_exit(config_filename
);
448 /* ===================== traffic analyser - uses iptables ================ */
450 void get_traffic_statistics(void)
455 textfile(Pipe
,str
) *line
,*lines
=NULL
;
459 sprintf(cmd
,"%s -L -v -x -n -t mangle",iptables
);
471 int col
, accept
=0,proxyflag
=0,valid
=1,setchainname
=0,commonflag
=0;
472 unsigned long long traffic
=0;
473 unsigned long pkts
=0;
474 char *ipaddr
=NULL
,*ptr
;
476 /* debug puts(line->str); */
477 valid_columns(ptr
,line
->str
,' ',col
)
478 if(valid
) switch(col
)
480 case 1: if(eq(ptr
,"Chain"))
482 else if(eq(ptr
,"pkts"))
485 sscanf(ptr
,"%lu",&pkts
);
487 case 2: if(setchainname
)
489 if(!strncmp(ptr
,"post_",5) || eq(ptr
,"POSTROUTING"))
492 if(!strncmp(ptr
,"forw_",5) || eq(ptr
,"FORWARD"))
495 if(eq(ptr
,"post_common") || eq(ptr
,"forw_common"))
499 sscanf(ptr
,"%Lu",&traffic
); traffic
+=(1<<19); traffic
>>=20;
501 case 3: if((strncmp(ptr
,"post_",5) && strncmp(ptr
,"forw_",5)) || commonflag
)
503 /*if (filter_type==1) accept=eq(ptr,"MARK"); else accept=eq(ptr,"CLASSIFY");*/
505 case 8: if(downloadflag
)
507 if(strstr(proxy_ip
,ptr
))proxyflag
=1;
512 case 9: if(downloadflag
)ipaddr
=ptr
;break;
515 if(accept
&& traffic
>0 && ipaddr
)
517 if(proxyflag
)printf("(proxy) ");
518 else if(!downloadflag
) printf("(upload) ");
519 printf("IP %s: %Lu M (%ld pkts)\n", ipaddr
, traffic
, pkts
);
520 find(ip
,ips
,eq(ip
->addr
,ipaddr
));
525 if(eq(ip
->addr
,"0.0.0.0/0"))
527 ip
->name
="(unregistered)";
529 ip
->max
=ip
->desired
=free_max
;
538 ip
->traffic
+=traffic
;
539 ip
->direct
=ip
->traffic
-ip
->upload
-ip
->proxy
;
547 ip
->traffic
+=traffic
;
549 if(traffic
>ip
->traffic
)
559 /* ========== This function executes, logs OR ALSO prints command ========== */
561 void safe_run(char *cmd
)
563 if(dry_run
) printf("\n=>%s\n",cmd
); else system(cmd
);
564 if(log_file
) fprintf(log_file
,"%s\n",cmd
);
567 void save_line(char *line
)
569 fprintf(iptables_file
,"%s\n",line
);
572 void run_restore(void)
575 string(restor
,STRLEN
);
577 /*-----------------------------------------------------------------*/
578 printf("Running %s <%s ...\n",iptablesrestore
,iptablesfile
);
579 /*-----------------------------------------------------------------*/
582 fclose(iptables_file
);
592 sprintf(restor
,"%s <%s",iptablesrestore
, iptablesfile
);
598 /* == This function strips extra characters after IP address and stores it = */
600 void parse_ip(char *str
)
602 char *ptr
=str
,*ipaddr
=NULL
,*ipname
=NULL
;;
604 while(*ptr
&& *ptr
!=' ' && *ptr
!=9)
610 while(*ptr
&& (*ptr
==' ' || *ptr
==9))
613 while(*ptr
&& *ptr
!=' ' && *ptr
!=9)
617 find(ip
,ips
,eq(ip
->addr
,ipaddr
)); else TheIP();
622 char *parse_datafile_line(char *str
)
624 char *ptr
=strchr(str
,' ');
643 void parse_ip_log(int argc
, char **argv
)
645 char *month
,*year
,*str
,*name
,*ptr
,*ptr2
;
646 long traffic
,traffic_month
,total
=0;
647 int col
,col2
,y_ok
,m_ok
,accept_month
,i
=1,any_month
=0;
648 char mstr
[4],ystr
[5];
653 if(argv
[1][1]=='l') /* -l */
657 puts("Missing parameter(s)!\nUsage: prometheus -l Mmm YYYY (Mmm=Jan-Dec or Year, YYYY=year)");
663 if(eq(month
,"Year")) any_month
=1;
669 time_t t
= time(NULL
) - 3600*24 ; /* yesterday's timestamp*/
670 struct tm
*timep
= localtime(&t
);
672 if(argv
[1][1]=='m') /* -m yestarday - month */
674 strftime(mstr
, 4, "%b", timep
);
676 strftime(ystr
, 5, "%Y", timep
);
679 else /* -y yesterday - year */
683 strftime(ystr
, 5, "%Y", timep
);
687 printf("Analysing traffic for %s %s ...\n",month
,year
);
689 sprintf(str
,"%s %s/*.log",ls
,log_dir
);
694 ptr
=strrchr(str
,'\n');
696 printf("Parsing %s ...",str
);
702 valid_columns(ptr
,_
,'\t',col
) switch(col
)
704 case 2: name
=ptr
;break;
705 case 3: traffic
=atol(ptr
);break;
706 /* column number - was 7, now 9...*/
709 case 9: if (isalnum(*ptr
)) /* alphanumeric string = date, just one*/
711 valid_columns(ptr2
,ptr
,' ',col2
) switch(col2
)
713 case 2: if(any_month
|| eq(ptr2
,month
)) m_ok
=1; break;
714 case 5: if(eq(ptr2
,year
)) y_ok
=1; break;
721 traffic_month
+=traffic
;
731 iplog
->traffic
=traffic_month
;
732 insert(iplog
,iplogs
,desc_order_by
,traffic
);
733 printf(" %ld MB\n",iplog
->traffic
);
736 puts(" no records.");
738 sprintf(str
,"%s/%s-%s.html",html_log_dir
,year
,month
);
739 printf("Writing %s ...",str
);
743 fprintf(f
,"<table border><tr><th colspan=\"4\">Data transfers - %s %s</th></tr>\n ",month
,year
);
747 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);
748 total
+=iplog
->traffic
>>10;
750 fprintf(f
,"<tr><th colspan=\"3\" align=\"left\">Total:</th><th align=\"right\">%ld GB</th></tr>\n",total
);
751 fputs("</table>\n",f
);
758 /*-----------------------------------------------------------------*/
759 /* Are you looking for int main (int argc, char **argv) ? :-)) */
760 /*-----------------------------------------------------------------*/
768 int class_count
=0,ip_count
=0;
772 int just_preview
=0; /* preview - generate just stats */
773 int just_logs
=0; /* just parse logs */
775 char *chain_forward
, *chain_postrouting
;
779 Prometheus QoS - \"fair-per-IP\" Quality of Service setup utility.\n\
780 Version %s - Copyright (C)2005-2008 Michael Polak (xChaos)\n\
781 iptables-restore & burst tunning & classify modification 0.7d by Ludva\n\
782 Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version
);
784 /*----- Boring... we have to check command line options first: ----*/
788 argument("-c") { nextargument(config
); }
789 argument("-h") { nextargument(althosts
);}
790 argument("-d") { dry_run
=1; }
791 argument("-f") { just_flush
=1; }
792 argument("-9") { just_flush
=9; }
793 argument("-p") { just_preview
=1; }
794 argument("-n") { nodelay
=1; }
795 argument("-l") { just_logs
=1; }
796 argument("-m") { just_logs
=1; }
797 argument("-y") { just_logs
=1; }
798 argument("-?") { help(); exit(0); }
799 argument("--help") { help(); exit(0); }
800 argument("-v") { exit(0); }
801 argument("--version") { exit(0); }
805 puts("*** THIS IS JUST DRY RUN ! ***\n");
807 date(d
); /* this is typical cll1.h macro */
809 /*-----------------------------------------------------------------*/
810 printf("Parsing configuration file %s ...\n", config
);
811 /*-----------------------------------------------------------------*/
816 parse_ip_log(argc
,argv
);
820 if(althosts
) hosts
=althosts
;
824 /*-----------------------------------------------------------------*/
825 puts("Parsing iptables verbose output ...");
826 /*-----------------------------------------------------------------*/
827 get_traffic_statistics();
830 /*-----------------------------------------------------------------*/
831 printf("Parsing class defintion file %s ...\n", hosts
);
832 /*-----------------------------------------------------------------*/
833 int groupidx
= FIRSTGROUPID
;
838 if(*str
<'0' || *str
>'9')
841 //Does this IP share QoS class with some other ?
842 substring
=strstr(str
,"sharing-");
845 substring
+=8; //"sharing-"
848 ip
->sharing
=substring
;
849 ip
->keyword
=defaultkeyword
; /* settings for default keyword */
850 while(*substring
&& *substring
!='\n')
856 //Do we have to create new QoS class for this IP ?
858 find(keyword
,keywords
,(substring
=strstr(str
,keyword
->key
)))
864 ip
->prio
=keyword
->default_prio
;
865 substring
+=strlen(keyword
->key
)+1;
867 while(*ptr
&& *ptr
!='-')
872 ip
->max
=ip
->desired
=atoi(ptr
+1);
874 ip
->min
=atoi(substring
);
877 printf(" %s: Illegal value of minimum bandwidth 0 kbps, using %d kbps\n",str
,free_min
);
883 ip
->max
=ip
->min
+ip
->keyword
->reserve_min
;
887 ip
->max
-=ip
->keyword
->reserve_max
;
890 if(ip->keyword->divide_max>1)
891 ip->max=ip->min+(ip->max-ip->min)/ip->keyword->divide_max;
892 if(ip->keyword->htb_ceil_bonus_divide>0)
893 ip->max+=ip->max/ip->keyword->htb_ceil_bonus_divide;
898 ip
->mark
=FIRSTIPCLASS
+1+class_count
++;
900 find(group
,groups
,group
->min
==ip
->min
)
903 group
->desired
+=ip
->min
;
904 ip
->group
= group
->id
;
910 group
->id
= groupidx
++;
911 ip
->group
= group
->id
;
913 if(group
->min
<8) group
->min
=8;
914 /* Warning - this is maybe because of primitive tc namespace, can be fixed */
915 /* it is because class IDs are derived from min. bandwidth. - xCh */
916 //if(group->min>MAX_GUARANTED_KBPS) group->min=MAX_GUARANTED_KBPS;
919 group
->desired
=ip
->min
;
920 insert(group
,groups
,desc_order_by
,min
);
932 /*-----------------------------------------------------------------*/
933 /* cll1.h - let's allocate brand new character buffer... */
934 /*-----------------------------------------------------------------*/
937 /*-----------------------------------------------------------------*/
938 puts("Resolving shared connections ...");
939 /*-----------------------------------------------------------------*/
940 search(ip
,ips
,ip
->sharing
)
942 search(sharedip
,ips
,eq(sharedip
->name
,ip
->sharing
))
944 sharedip
->traffic
+=ip
->traffic
;
946 ip
->mark
=sharedip
->mark
;
950 printf("Unresolved shared connection: %s %s sharing-%s\n",ip
->addr
,ip
->name
,ip
->sharing
);
953 if(enable_credit
&& just_flush
<9)
955 /*-----------------------------------------------------------------*/
956 printf("Parsing credit file %s ...\n", credit
);
957 /*-----------------------------------------------------------------*/
960 ptr
=parse_datafile_line(_
);
963 find(ip
,ips
,eq(ip
->addr
,_
))
964 sscanf(ptr
,"%Lu",&(ip
->credit
));
972 /*-----------------------------------------------------------------*/
973 puts("Initializing iptables and tc classes ...");
974 /*-----------------------------------------------------------------*/
976 iptables_file
=fopen(iptablesfile
,"w");
977 if (iptables_file
== NULL
) {
978 puts("Cannot open iptablesfile!");
982 log_file
=fopen(cmdlog
,"w");
983 if (log_file
== NULL
) {
984 puts("Cannot open logfile!");
988 save_line(iptablespreamble
);
991 sprintf(str
,"%s qdisc del dev %s root 2>/dev/null",tc
,lan
);
994 sprintf(str
,"%s qdisc del dev %s root 2>/dev/null",tc
,wan
);
997 iptables_file
=fopen(iptablesfile
,"w");
998 save_line(iptablespreamble
);
1000 if(qos_free_zone
&& *qos_free_zone
!='0')
1004 sprintf(str
,"-A FORWARD -d %s -o %s -j ACCEPT", qos_free_zone
, wan
);
1009 save_line(":post_noproxy - [0:0]");
1010 sprintf(str
,"-A POSTROUTING -p ! tcp -o %s -j post_noproxy", lan
);
1012 sprintf(str
,"-A POSTROUTING -s ! %s -o %s -j post_noproxy", proxy_ip
, lan
);
1014 sprintf(str
,"-A POSTROUTING -s %s -p tcp --sport ! %d -o %s -j post_noproxy", proxy_ip
, proxy_port
, lan
);
1017 chain
="post_noproxy";
1020 chain
="POSTROUTING";
1022 sprintf(str
,"-A %s -s %s -o %s -j ACCEPT", chain
, qos_free_zone
, lan
);
1026 if(ip_count
>idxtable_treshold1
&& !just_flush
)
1028 int idxcount
=0, bitmask
=32-idxtable_bitmask1
; /* default net mask: 255.255.255.240 */
1030 /*-----------------------------------------------------------------*/
1031 printf("Detected %d addresses - indexing iptables rules to improve performance...\n",ip_count
);
1032 /*-----------------------------------------------------------------*/
1034 save_line(":post_common - [0:0]");
1035 save_line(":forw_common - [0:0]");
1037 search(ip
,ips
,ip
->addr
&& *(ip
->addr
) && !eq(ip
->addr
,"0.0.0.0/0"))
1039 buf
=hash_id(ip
->addr
,bitmask
);
1040 find(idx
,idxs
,eq(idx
->id
,buf
))
1047 idx
->bitmask
=bitmask
;
1055 /* brutal perfomance optimalization */
1056 while(idxcount
>idxtable_treshold2
&& bitmask
>2*idxtable_bitmask2
)
1058 bitmask
-=idxtable_bitmask2
;
1060 search(idx
,idxs
,idx
->parent
==NULL
)
1062 buf
=hash_id(idx
->addr
,bitmask
);
1063 find(metaindex
,idxs
,eq(metaindex
->id
,buf
))
1064 metaindex
->children
++;
1067 create(metaindex
,Index
);
1068 metaindex
->addr
=idx
->addr
;
1070 metaindex
->bitmask
=bitmask
;
1071 metaindex
->parent
=NULL
;
1072 metaindex
->children
=0;
1074 push(metaindex
,idxs
);
1076 idx
->parent
=metaindex
;
1080 /* this should slightly optimize throughout ... */
1081 sort(idx
,idxs
,desc_order_by
,children
);
1082 sort(idx
,idxs
,order_by
,bitmask
);
1087 subnet
=subnet_id(idx
->addr
,idx
->bitmask
);
1088 printf("%d: %s/%d\n",++i
,subnet
,idx
->bitmask
);
1090 sprintf(str
,":post_%s - [0:0]", idx
->id
);
1093 sprintf(str
,":forw_%s - [0:0]", idx
->id
);
1098 string(buf
,strlen(idx
->parent
->id
)+6);
1099 sprintf(buf
,"post_%s",idx
->parent
->id
);
1104 sprintf(str
,"-A %s -d %s/%d -o %s -j post_%s", buf
, subnet
, idx
->bitmask
, lan
, idx
->id
);
1107 sprintf(str
,"-A %s -d %s/%d -o %s -j post_common", buf
, subnet
, idx
->bitmask
, lan
);
1112 string(buf
,strlen(idx
->parent
->id
)+6);
1113 sprintf(buf
,"forw_%s",idx
->parent
->id
);
1118 sprintf(str
,"-A %s -s %s/%d -o %s -j forw_%s", buf
, subnet
, idx
->bitmask
, wan
, idx
->id
);
1121 sprintf(str
,"-A %s -s %s/%d -o %s -j forw_common", buf
, subnet
, idx
->bitmask
, wan
);
1124 printf("Total indexed iptables chains created: %d\n", i
);
1126 sprintf(str
,"-A FORWARD -o %s -j forw_common", wan
);
1129 sprintf(str
,"-A POSTROUTING -o %s -j post_common", lan
);
1137 fclose(iptables_file
);
1138 if (log_file
) fclose(log_file
);
1139 puts("Just flushed iptables and tc classes - now exiting ...");
1145 if(!dry_run
&& !nodelay
&& qos_free_delay
)
1147 printf("Flushed iptables and tc classes - now sleeping for %d seconds...\n",qos_free_delay
);
1148 sleep(qos_free_delay
);
1151 sprintf(str
,"%s qdisc add dev %s root handle 1: htb r2q %d default 1",tc
,lan
,htb_r2q
);
1154 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
);
1157 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
);
1160 sprintf(str
,"%s qdisc add dev %s root handle 1: htb r2q %d default 1",tc
,wan
,htb_r2q
);
1163 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
);
1166 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
);
1170 /*-----------------------------------------------------------------*/
1171 puts("Locating suckers and generating root classes ...");
1172 /*-----------------------------------------------------------------*/
1173 sort(ip
,ips
,desc_order_by
,traffic
);
1176 /*-----------------------------------------------------------------*/
1177 /* sub-scope - local variables */
1179 long long int rate
=line
;
1180 long long int max
=line
;
1182 FILE *credit_file
=NULL
;
1184 if(!just_preview
&& !dry_run
&& enable_credit
) credit_file
=fopen(credit
,"w");
1192 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",
1193 tc
, lan
, parent
, group
->id
, rate
, max
, burst_group
, group
->desired
);
1197 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",
1198 tc
, wan
, parent
, group
->id
, rate
*up
/line
, max
*up
/line
, burst_group
, group
->desired
);
1202 if(group_count
++<max_nesting
) parent
=group
->id
;
1204 rate
-=digital_divide
*group
->min
;
1205 if(rate
<group
->min
)rate
=group
->min
;
1207 /*shaping of aggresive downloaders, with credit file support */
1210 int group_rate
=group
->min
, priority_sequence
=magic_priorities
+1;
1212 search(ip
, ips
, ip
->min
==group
->min
&& ip
->max
>ip
->min
)
1214 if( ip
->keyword
->data_limit
&& !ip
->fixedprio
&&
1215 ip
->traffic
>ip
->credit
+
1216 (ip
->min
*ip
->keyword
->data_limit
+(ip
->keyword
->fixed_limit
<<20)) )
1218 if(group_rate
<ip
->max
) ip
->max
=group_rate
;
1219 group_rate
+=magic_treshold
;
1220 ip
->prio
=magic_priorities
+2;
1221 if(ip
->prio
<3) ip
->prio
=3;
1225 if( ip
->keyword
->data_prio
&& !ip
->fixedprio
&&
1226 ip
->traffic
>ip
->credit
+
1227 (ip
->min
*ip
->keyword
->data_prio
+(ip
->keyword
->fixed_prio
<<20)) )
1229 ip
->prio
=priority_sequence
--;
1230 if(ip
->prio
<2) ip
->prio
=2;
1235 unsigned long long lcredit
=0;
1237 if((ip
->min
*ip
->keyword
->data_limit
+(ip
->keyword
->fixed_limit
<<20))>ip
->traffic
)
1238 lcredit
=(ip
->min
*ip
->keyword
->data_limit
+(ip
->keyword
->fixed_limit
<<20))-ip
->traffic
;
1239 fprintf(credit_file
,"%s %Lu\n",ip
->addr
,lcredit
);
1246 if(credit_file
)fclose(credit_file
);
1251 f
=fopen(preview
,"w");
1254 else if(!dry_run
&& !just_flush
)
1256 /*-----------------------------------------------------------------*/
1257 printf("Writing data transfer database ...\n");
1258 /*-----------------------------------------------------------------*/
1259 f
=fopen("/var/run/prometheus.previous","w");
1262 search(ip
,ips
,ip
->traffic
|| ip
->direct
|| ip
->proxy
||ip
->upload
)
1263 fprintf(f
,"%s %Lu %Lu %Lu %Lu\n",ip
->addr
,ip
->traffic
,ip
->direct
,ip
->proxy
,ip
->upload
);
1277 /*-----------------------------------------------------------------*/
1278 printf("Sorting data and generating statistics page %s ...\n",ptr
);
1279 /*-----------------------------------------------------------------*/
1281 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
);
1282 fprintf(f
,"<th colspan=\"%d\">data limits</th>\n",keywordcount
);
1287 printf("%d k group: %d bandwidth requested: %d k\n",group
->min
,group
->count
,group
->desired
);
1289 fprintf(f
,"<tr><td align=\"right\">%d</td><td align=\"right\">%d k</td>",count
,group
->min
);
1290 fprintf(f
,"<td align=\"right\">%d</td><td align=\"right\">%d k</td>",group
->count
,group
->desired
);
1292 every(keyword
,keywords
)
1293 fprintf(f
,"<td align=\"right\"><font color=\"#%s\">%d M</font></td>",keyword
->html_color
,group
->min
*keyword
->data_limit
);
1296 total
+=group
->count
;
1300 printf("Total groups: %d Total bandwidth requested: %d k\nAGGREGATION: 1/%d\n",count
,i
,i
/line
);
1302 fprintf(f
,"<tr><th colspan=\"2\" align=\"left\">Line %Ld k</td>",line
);
1303 fprintf(f
,"<th align=\"right\">%d</td><th align=\"right\">%d k</td>",total
,i
);
1305 every(keyword
,keywords
)
1306 fprintf(f
,"<th align=\"right\">%d IPs</th>",keyword
->ip_count
);
1308 fprintf(f
,"</tr><tr><th colspan=\"4\">Aggregation 1/%d</th>\n",(int)(0.5+i
/line
));
1309 fprintf(f
,"<th colspan=\"%d\">%d traffic classes</th></tr>\n",keywordcount
,total
);
1311 fputs("</table>\n",f
);
1313 else if(!dry_run
&& !just_flush
)
1319 unsigned long long total
=0, total_direct
=0, total_proxy
=0, total_upload
=0, tmp_sum
=0;
1320 int active_classes
=0;
1323 struct Sum
{unsigned long long l
; int i
; list(Sum
);} *sum
,*sums
=NULL
;
1330 fprintf(f
,"<p><table border>\n<tr><th colspan=\"%d\">%s",colspan
,title
);
1331 fprintf(f
," (%s)</th></tr>\n", d
);
1332 fputs("<tr><td align=\"right\">#</td><td>hostname</td>\
1333 <td align=\"right\">credit</td>\
1334 <td align=\"right\">limit</td>\
1335 <td align=\"right\">total</td>\
1336 <td align=\"right\">direct</td>\n",f
);
1338 fputs("<td align=\"right\">proxy</td>\n",f
);
1339 fputs("<td align=\"right\">upload</td>\
1340 <td align=\"right\">minimum</td>\
1341 <td align=\"right\">desired</td>\
1342 <td align=\"right\">maximum</td>\
1343 <td>prio</td></tr>\n",f
);
1347 char *f1
="", *f2
="";
1348 if(ip
->max
<ip
->desired
)
1350 f1
="<font color=\"red\">";
1355 f1
="<font color=\"brown\">";
1360 printf("%03d. %-22s %10Lu (%d/%d)\n",i
,ip
->name
, ip
->traffic
, ip
->min
, ip
->max
);
1362 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",
1363 ip
->name
, i
, log_url
, ip
->name
, ip
->name
, ip
->credit
);
1364 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)));
1365 fprintf(f
,"<td align=\"right\">%s%Lu M%s</td><td align=\"right\">%Lu M</td>\n", f1
, ip
->traffic
, f2
, ip
->direct
);
1367 fprintf(f
,"<td align=\"right\">%Lu M</td>\n", ip
->proxy
);
1368 fprintf(f
,"<td align=\"right\">%Lu M</td>\n", ip
->upload
);
1369 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
);
1371 total_direct
+=ip
->direct
;
1372 total_proxy
+=ip
->proxy
;
1373 total_upload
+=ip
->upload
;
1377 tmp_sum
+=ip
->traffic
;
1380 sum
->i
=active_classes
;
1381 insert(sum
,sums
,order_by
,i
);
1388 sprintf(str
,"%s/%s.log",log_dir
,ip
->name
);
1389 iplog
=fopen(str
,"a");
1392 fprintf(iplog
,"%ld\t%s\t%Lu\t%Lu\t%Lu\t%Lu\t%d\t%d\t%d\t%s",
1393 time(NULL
),ip
->name
,ip
->traffic
,ip
->direct
,ip
->proxy
,ip
->upload
,ip
->min
,ip
->max
,ip
->desired
,d
); /* d = date*/
1399 fprintf(f
,"<tr><th colspan=\"4 \"align=\"left\">SUMMARY:</td>");
1400 fprintf(f
,"<th align=\"right\">%Lu M</th>\
1401 <th align=\"right\">%Lu M</th>\n", total
, total_direct
);
1403 fprintf(f
,"<th align=\"right\">%Lu M</th>\n", total_proxy
);
1404 fprintf(f
,"<th align=\"right\">%Lu M</th>", total_upload
);
1405 fputs("<td colspan=\"4\"></td></th>\n</table>\n",f
);
1407 if(active_classes
>10)
1409 fputs("<a name=\"erp\"></a><p><table border><tr><th colspan=\"5\">Enterprise Research and Planning (ERP)</th></tr>\n",f
);
1410 fputs("<tr><td>Analytic category</td>\n",f
);
1411 fputs("<td colspan=\"2\" align=\"center\">Active Classes</td><td colspan=\"2\" align=\"center\">Data transfers</td></tr>\n",f
);
1413 find(sum
,sums
,sum
->l
>=total
/4)
1415 fprintf(f
,"<tr><td>Top 25%% of traffic</td>\n");
1416 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
);
1419 find(sum
,sums
,sum
->i
==10)
1421 fprintf(f
,"<tr><td>Top 10 downloaders</td>\n");
1422 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
);
1425 find(sum
,sums
,sum
->l
>=total
/2)
1427 fprintf(f
,"<tr><td>Top 50%% of traffic</td>\n");
1428 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
);
1431 find(sum
,sums
,sum
->l
>=4*total
/5)
1433 fprintf(f
,"<tr><td>Top 80%% of traffic</td>\n");
1434 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
);
1437 find (sum
,sums
,sum
->i
>=(active_classes
+1)/5)
1439 fprintf(f
,"<tr><td>Top 20%% downloaders</td>\n");
1440 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
);
1443 find(sum
,sums
,sum
->i
>=(active_classes
+1)/4)
1445 fprintf(f
,"<tr><td>Top 25%% downloaders</td>\n");
1446 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
);
1449 find(sum
,sums
,sum
->i
>=(active_classes
+1)/2)
1451 fprintf(f
,"<tr><td>Top 50%% downloaders</td>\n");
1452 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
);
1455 find(sum
,sums
,sum
->i
>=4*(active_classes
+1)/5)
1457 fprintf(f
,"<tr><td>Top 80%% downloaders</td>\n");
1458 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
);
1461 fprintf(f
,"<tr><td>All users, all traffic</td>\n");
1462 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
);
1463 fputs("</table>\n",f
);
1465 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
);
1471 puts("Statistics preview generated (-p switch) - now exiting ...");
1475 /*-----------------------------------------------------------------*/
1476 puts("Generating iptables and tc classes ...");
1477 /*-----------------------------------------------------------------*/
1480 printf("%-22s %-15s mark\n","name","ip");
1481 search(ip
,ips
,ip
->mark
>0)
1487 duplicate(ip
->addr
,buf
);
1488 buf
=hash_id(ip
->addr
,32-idxtable_bitmask1
);
1490 string(chain_forward
,6+strlen(buf
));
1491 strcpy(chain_forward
,"forw_");
1492 strcat(chain_forward
,buf
);
1494 string(chain_postrouting
,6+strlen(buf
));
1495 strcpy(chain_postrouting
,"post_");
1496 strcat(chain_postrouting
,buf
);
1502 chain_forward
="FORWARD";
1503 chain_postrouting
="POSTROUTING";
1506 printf("%-22s %-16s %04d ", ip
->name
, ip
->addr
, ip
->mark
);
1508 /* -------------------------------------------------------- mark download */
1510 sprintf(str
,"-A %s -d %s/32 -o %s -j %s%d",chain_postrouting
,ip
->addr
,lan
,mark_iptables
,ip
->mark
);
1511 /*sprintf(str,"-A %s -d %s/32 -o %s -j MARK --set-mark %d",chain_postrouting,ip->addr,lan,ip->mark);*/
1512 /* -m limit --limit 1/s */
1517 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
);
1518 /*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);*/
1522 sprintf(str
,"-A %s -d %s/32 -o %s -j ACCEPT",chain_postrouting
,ip
->addr
,lan
);
1525 /* -------------------------------------------------------- mark upload */
1526 sprintf(str
,"-A %s -s %s/32 -o %s -j %s%d",chain_forward
,ip
->addr
,wan
,mark_iptables
,ip
->mark
);
1527 /* sprintf(str,"-A %s -s %s/32 -o %s -j MARK --set-mark %d",chain_forward,ip->addr,wan,ip->mark);*/
1530 sprintf(str
,"-A %s -s %s/32 -o %s -j ACCEPT",chain_forward
,ip
->addr
,wan
);
1535 /* -------------------------------------------------------- download class */
1536 printf("(down: %dk-%dk ", ip
->min
, ip
->max
);
1538 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
);
1541 if (strcmpi(ip
->keyword
->leaf_discipline
, "none")){
1542 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*/
1546 if (filter_type
== 1){
1547 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle %d fw flowid 1:%d", tc
, lan
, ip
->mark
, ip
->mark
);
1551 /* -------------------------------------------------------- upload class */
1552 printf("up: %dk-%dk)\n", (int)((ip
->min
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
),
1553 (int)((ip
->max
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
));
1555 sprintf(str
,"%s class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit burst %dk prio %d",
1556 tc
, wan
, ip
->group
, ip
->mark
,
1557 (int)((ip
->min
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
),
1558 (int)((ip
->max
/ip
->keyword
->asymetry_ratio
)-ip
->keyword
->asymetry_fixed
), burst
, ip
->prio
);
1561 if (strcmpi(ip
->keyword
->leaf_discipline
, "none")){
1562 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*/
1566 if (filter_type
== 1){
1567 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle %d fw flowid 1:%d",tc
, wan
, ip
->mark
, ip
->mark
);
1572 printf("(sharing %s)\n", ip
->sharing
);
1579 chain_forward
="forw_common";
1580 chain_postrouting
="post_common";
1584 chain_forward
="FORWARD";
1585 chain_postrouting
="POSTROUTING";
1588 /* -------------------------------------------------------- mark download */
1592 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);
1594 sprintf(str
,"-A %s -s %s -p tcp --sport %d -o %s -j ACCEPT",chain_postrouting
,proxy_ip
,proxy_port
,lan
);
1597 sprintf(str
,"-A %s -o %s -j %s%d",chain_postrouting
,lan
,mark_iptables
,3);
1599 sprintf(str
,"-A %s -o %s -j ACCEPT",chain_postrouting
,lan
);
1602 /* -------------------------------------------------------- mark upload */
1603 sprintf(str
,"-A %s -o %s -j %s%d",chain_forward
,wan
,mark_iptables
,3);
1605 sprintf(str
,"-A %s -o %s -j ACCEPT",chain_forward
,wan
);
1608 printf("Total IP count: %d\n", i
);
1610 /*-----------------------------------------------------------------*/
1611 puts("Generating free bandwith classes ...");
1612 /*-----------------------------------------------------------------*/
1614 /* ---------------------------------------- tc - free bandwith shared class */
1615 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
);
1618 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
);
1622 if (strcmpi(qos_leaf
, "none")){
1623 sprintf(str
,"%s qdisc add dev %s parent 1:3 handle 3 %s",tc
,lan
,qos_leaf
);
1626 sprintf(str
,"%s qdisc add dev %s parent 1:3 handle 3 %s",tc
,wan
,qos_leaf
);
1630 /* tc handle 1 fw flowid */
1631 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle 3 fw flowid 1:3",tc
,lan
);
1634 sprintf(str
,"%s filter add dev %s parent 1:0 protocol ip handle 3 fw flowid 1:3",tc
,wan
);
1639 if (log_file
) fclose(log_file
);
1642 /* that's all folks, thank you for reading it all the way up to this point ;-) */
1643 /* bad luck C<<1 is not yet finished, I promise no sprintf() next time... */
This page took 1.355793 seconds and 4 git commands to generate.