X-Git-Url: http://git.harvie.cz/?a=blobdiff_plain;f=prometheus.c;h=0c0d93bbb7d85d6f81f6490f24ace26d95a62010;hb=9476091134bee3a9f4a5483a8b00b75b1406098a;hp=5b90528c7bad21025eb4c6bd12c08ae29f9ff623;hpb=2d1141371d8f714276b8b17ff3d55a5dfc91b900;p=svn%2FPrometheus-QoS%2F.git
diff --git a/prometheus.c b/prometheus.c
index 5b90528..0c0d93b 100644
--- a/prometheus.c
+++ b/prometheus.c
@@ -7,9 +7,9 @@
/* Credit: CZFree.Net,Martin Devera,Netdave,Aquarius,Gandalf */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-/* Modified: xChaos, 20080422
- ludva, 20080415
-
+/* Modified by: xChaos, 20110221
+ ludva, 20080415
+
Prometheus QoS is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2.1 of
@@ -31,16 +31,16 @@
#define FIRSTIPCLASS 2048
#undef DEBUG
-#include "cll1-0.6.h"
+#include "cll1-0.6.2.h"
-const char *version = "0.7.9-c";
+const char *version = "0.8.3";
-/* Version numbers: 0.7.9 will be last development ("beta"), 0.8.0 first stable */
+/* Version numbers: 0.8.3 is development releases ("beta"), 0.8.4 will be "stable" */
/* Debian(RPM) package versions/patchlevels: 0.7.9-2, 0.8.0-1, 0.8.0-2, etc. */
/* C source code development versions ("beta"): 0.7.9-a, 0.8.1-b, etc. */
/* C source code release versions: 0.8.0, 0.8.2, 0.8.4, etc. */
-const char *stats_html_signature = "Statistics generated by Prometheus QoS version %s
GPL+Copyright(C)2005-2008 Michael Polak, Arachne Labs\n";
+const char *stats_html_signature = "Statistics generated by Prometheus QoS version %s
GPL+Copyright(C)2005-2011 Michael Polak, Arachne Labs\n";
/* ======= All path names are defined here (for RPM patch) ======= */
@@ -48,7 +48,7 @@ char *tc = "/sbin/tc"; /* requires tc with HTB support */
char *iptables = "/sbin/iptables"; /* requires iptables utility */
char *iptablessave = "/sbin/iptables-save"; /* not yet required */
char *iptablesrestore = "/sbin/iptables-restore"; /* requires iptables-restore */
-char *ls = "/bin/ls"; /* this is not user configurable :-) */
+const char *ls = "/bin/ls"; /* this is not user configurable :-) */
char *config = "/etc/prometheus/prometheus.conf"; /* main configuration file */
char *hosts = "/etc/prometheus/hosts"; /* per-IP bandwidth definition file */
@@ -69,72 +69,70 @@ void help(void)
puts("Command line switches:\n\
\n\
-?, --help this help screen\n\
--v, --version show version number of this utility and exit\n\
--c filename force alternative /etc/prometheus.conf filename\n\
--h filename force alternative /etc/hosts filename (overrides hosts keyword)\n\
--f just flush iptables and tc classes and exit (stop shaping)\n\
+-v, --version show Version number of this utility and exit\n\
+-c filename force alternative /etc/prometheus.Conf filename\n\
+-h filename force alternative /etc/Hosts filename (overrides hosts keyword)\n\
+-f just Flush iptables and tc classes and exit (stop shaping)\n\
-9 emergency iptables flush (do not read data transfer statistics)\n\
--p just generate preview of data transfer statistics and exit\n\
--n no delay (overrides qos-free-delay keyword)\n\
--d dry run (preview tc and iptables commands on stdout)\n\
--l Mmm YYYY generate HTML summary of traffic logs (Mmm=Jan-Dec or Year, YYYY=year)\n\
--m generate HTML summary of traffic logs for yesterday's month\n\
--y generate HTML summary of traffic logs for yesterday's year\n");
+-p just generate Preview of data transfer statistics and exit\n\
+-d Dry run (preview tc and iptables commands on stdout)\n\
+-r Run (reset all statistics and start shaping)\n\
+-n run Now (start shaping without delay - overrides qos-free-delay keyword)\n\
+-l Mmm YYYY generate HTML summary of traffic Logs (Mmm=Jan-Dec or Year, YYYY=year)\n\
+-m generate HTML summary of traffic logs for yesterday's Month\n\
+-y generate HTML summary of traffic logs for yesterday's Year\n");
/* not yet implemented:
-s start shaping! (keep data transfer statistics - but apply shaping)\n\
--r just reload configuration (...and keep data transfer statistics)\n\
*/
}
-
/* === Configuraration file values defaults - stored in global variables ==== */
-int filter_type=1; /*1 mark, 2 classify*/
-char *mark="MARK";
-char *mark_iptables="MARK --set-mark ";
-int dry_run=0; /* preview - use puts() instead of system() */
-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]";
-FILE *iptables_file=NULL;
-int enable_credit=1; /* enable credit file */
-int use_credit=0; /* use credit file (if enabled)*/
-char *title="Hall of Fame - Greatest Suckers"; /* hall of fame title */
-int hall_of_fame=1; /* enable hall of fame */
-char *lan="eth0"; /* LAN interface */
-char *lan_medium="100Mbit"; /* 10Mbit/100Mbit ethernet */
-char *wan="eth1"; /* WAN/ISP interface */
-char *wan_medium="100Mbit"; /* 10Mbit/100Mbit ethernet */
-char *qos_leaf="sfq perturb 5"; /* leaf discipline */
-char *qos_free_zone=NULL; /* QoS free zone */
-int qos_proxy=1; /* include proxy port to QoS */
-int include_upload=1; /* upload+download=total traffic */
-char *proxy_ip="192.168.1.1/32"; /* our IP with proxy port */
-int proxy_port=3128; /* proxy port number */
-long long int line=1024; /* WAN/ISP download in kbps */
-long long int up=1024; /* WAN/ISP upload in kbps */
-int free_min=32; /* minimum guaranted bandwidth for all undefined hosts */
-int free_max=64; /* maximum allowed bandwidth for all undefined hosts */
-int qos_free_delay=0; /* seconds to sleep before applying new QoS rules */
-int digital_divide=2; /* controls digital divide weirdness ratio, 1...3 */
-int max_nesting=3; /* maximum nesting of HTB clases, built-in maximum seems to be 4 */
-int htb_r2q=1;
-int burst=8; /* HTB burst (in kbits) */
-int burst_main=64;
-int burst_group=32;
-int magic_priorities=8; /* number of priority levels (soft shaping) */
-int magic_treshold=8; /* reduce ceil by X*magic_treshhold kbps (hard shaping) */
-int keywordcount=0;
-
+int filter_type = 1; /*1 mark, 2 classify*/
+char *mark = "MARK";
+char *mark_iptables = "MARK --set-mark ";
+int dry_run = 0; /* preview - use puts() instead of system() */
+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]";
+FILE *iptables_file = NULL;
+int enable_credit = 1; /* enable credit file */
+int use_credit = 0; /* use credit file (if enabled)*/
+char *title = "Hall of Fame - Greatest Suckers"; /* hall of fame title */
+int hall_of_fame = 1; /* enable hall of fame */
+char *lan = "eth0"; /* LAN interface */
+char *lan_medium = "100Mbit"; /* 10Mbit/100Mbit ethernet */
+char *wan = "eth1"; /* WAN/ISP interface */
+char *wan_medium = "100Mbit"; /* 10Mbit/100Mbit ethernet */
+char *qos_leaf = "sfq perturb 5"; /* leaf discipline */
+char *qos_free_zone = NULL; /* QoS free zone */
+int qos_proxy = 1; /* include proxy port to QoS */
+int include_upload = 1; /* upload+download=total traffic */
+char *proxy_ip = "192.168.1.1/32"; /* our IP with proxy port */
+int proxy_port = 3128; /* proxy port number */
+long long int line = 1024; /* WAN/ISP download in kbps */
+long long int up = 1024; /* WAN/ISP upload in kbps */
+int free_min = 32; /* minimum guaranted bandwidth for all undefined hosts */
+int free_max = 64; /* maximum allowed bandwidth for all undefined hosts */
+int qos_free_delay = 0; /* seconds to sleep before applying new QoS rules */
+int digital_divide = 2; /* controls digital divide weirdness ratio, 1...3 */
+int max_nesting = 3; /* maximum nesting of HTB clases, built-in maximum seems to be 4 */
+int htb_r2q = 256; /* should work for leaf values 512 kbps to 8 Mbps */
+int burst = 8; /* HTB burst (in kbits) */
+int burst_main = 64;
+int burst_group = 32;
+int magic_treshold = 8; /* reduce ceil by X*magic_treshhold kbps (hard shaping) */
+int keywordcount = 0;
/* not yet implemented:
- int fixed_packets=0; maximum number of pps per IP address (not class!)
- int packet_limit=5; maximum number of pps to htn CEIL, not rate !!!
+int fixed_packets = 0; maximum number of pps per IP address (not class!)
+int packet_limit = 5; maximum number of pps to htn CEIL, not rate !!!
*/
-FILE *log_file=NULL;
-
-char *kwd="via-prometheus"; /* /etc/hosts comment, eg. #qos-64-128 */
+FILE *log_file = NULL;
+char *kwd = "via-prometheus"; /* /etc/hosts comment, eg. #qos-64-128 */
-const int idxtable_treshold1=24; /* this is no longer configurable */
-const int idxtable_treshold2=12; /* this is no longer configurable */
-const int idxtable_bitmask1=3; /* this is no longer configurable */
-const int idxtable_bitmask2=3; /* this is no longer configurable */
+const int highest_priority = 0; /* highest HTB priority (HTB built-in value is 0) */
+const int lowest_priority = 7; /* lowest HTB priority (HTB built-in value is 7) */
+const int idxtable_treshold1 = 24; /* this is no longer configurable */
+const int idxtable_treshold2 = 12; /* this is no longer configurable */
+const int idxtable_bitmask1 = 3; /* this is no longer configurable */
+const int idxtable_bitmask2 = 3; /* this is no longer configurable */
/* ==== This is C<<1 stuff - learn C<<1 first! http://cll1.arachne.cz ==== */
@@ -187,7 +185,7 @@ struct Keyword
int asymetry_ratio; /* ratio for ADSL-like upload */
int asymetry_fixed; /* fixed treshold for ADSL-like upload */
int data_limit; /* hard shaping: apply magic_treshold if max*data_limit MB exceeded */
- int data_prio; /* soft shaping (qos): reduce HTB prio if max*data_prio MB exceeded */
+ int data_prio; /* soft shaping (qos): reduce HTB prio if max*data_prio MB exceeded */
long fixed_limit; /* fixed data limit for setting lower HTB ceil */
long fixed_prio; /* fixed data lmit for setting lower HTB prio */
int reserve_min; /* bonus for nominal HTB rate bandwidth (in kbps) */
@@ -207,15 +205,23 @@ struct Keyword
void TheIP(void)
{
create(ip,IP);
- ip->name="";
- ip->addr="";
- ip->sharing=NULL;
- ip->prio=1;
- ip->fixedprio=0;
- ip->mark=ip->min=ip->max=ip->desired=ip->credit=0;
- ip->upload=ip->proxy=ip->direct=ip->traffic=0;
- ip->pktsup=ip->pktsdown=0;
- ip->keyword=keywords;
+ ip->name = "";
+ ip->addr = "";
+ ip->sharing = NULL;
+ ip->prio = highest_priority+1;
+ ip->fixedprio = 0;
+ ip->mark = \
+ ip->min = \
+ ip->max = \
+ ip->desired = \
+ ip->credit = \
+ ip->upload = \
+ ip->proxy = \
+ ip->direct = \
+ ip->traffic = \
+ ip->pktsup = \
+ ip->pktsdown = 0;
+ ip->keyword = keywords;
push(ip,ips);
}
@@ -316,16 +322,15 @@ void get_config(char *config_filename)
keyword->asymetry_ratio=1; /* ratio for ADSL-like upload */
keyword->asymetry_fixed=0; /* fixed treshold for ADSL-like upload */
keyword->data_limit=8; /* hard shaping: apply magic_treshold if max*data_limit MB exceeded */
- keyword->data_prio=4; /* soft shaping (qos): reduce HTB prio if max*data_prio MB exceeded */
+ keyword->data_prio=4; /* soft shaping (qos): reduce HTB prio if max*data_prio MB exceeded */
keyword->fixed_limit=0; /* fixed data limit for setting lower HTB ceil */
keyword->fixed_prio=0; /* fixed data limit for setting lower HTB prio */
keyword->reserve_min=8; /* bonus for nominal HTB rate bandwidth (in kbps) */
keyword->reserve_max=0; /* malus for nominal HTB ceil (in kbps) */
/* obsolete:
keyword->divide_max=0; relative malus: new_ceil=rate+(old_ceil-rate)/divide_max
- keyword->htb_ceil_bonus_divide=0; relative bonus: new_ceil=old_ceil+old_ceil/htb_ceil_bonus_divide
-*/
- keyword->default_prio=1;
+ keyword->htb_ceil_bonus_divide=0; relative bonus: new_ceil=old_ceil+old_ceil/htb_ceil_bonus_divide */
+ keyword->default_prio=highest_priority+1;
keyword->html_color="000000";
keyword->ip_count=0;
keyword->leaf_discipline="";
@@ -336,36 +341,39 @@ void get_config(char *config_filename)
kwd=NULL;
}
- else every(keyword,keywords)
+ else
{
- int l=strlen(keyword->key);
+ for_each(keyword,keywords)
+ {
+ int l=strlen(keyword->key);
- if(!strncmp(keyword->key,_,l) && strlen(_)>l+2)
- {
- char *tmptr=_; /* <---- l+1 ----> */
- _+=l+1; /* via-prometheus-asymetry-ratio, etc. */
- ioption("asymetry-ratio",keyword->asymetry_ratio);
- ioption("asymetry-treshold",keyword->asymetry_fixed);
- ioption("magic-relative-limit",keyword->data_limit);
- ioption("magic-relative-prio",keyword->data_prio);
- loption("magic-fixed-limit",keyword->fixed_limit);
- loption("magic-fixed-prio",keyword->fixed_prio);
- ioption("htb-default-prio",keyword->default_prio);
- ioption("htb-rate-bonus",keyword->reserve_min);
- ioption("htb-ceil-malus",keyword->reserve_max);
-/* obsolete:
- ioption("htb-ceil-divide",keyword->divide_max);
- ioption("htb-ceil-bonus-divide",keyword->htb_ceil_bonus_divide);
-*/
- option("leaf-discipline",keyword->leaf_discipline);
- option("html-color",keyword->html_color);
- _=tmptr;
-
- if(keyword->data_limit || keyword->fixed_limit ||
- keyword->data_prio || keyword->fixed_prio)
- use_credit=1;
- }
+ if(!strncmp(keyword->key,_,l) && strlen(_)>l+2)
+ {
+ char *tmptr=_; /* <---- l+1 ----> */
+ _+=l+1; /* via-prometheus-asymetry-ratio, etc. */
+ ioption("asymetry-ratio",keyword->asymetry_ratio);
+ ioption("asymetry-treshold",keyword->asymetry_fixed);
+ ioption("magic-relative-limit",keyword->data_limit);
+ ioption("magic-relative-prio",keyword->data_prio);
+ loption("magic-fixed-limit",keyword->fixed_limit);
+ loption("magic-fixed-prio",keyword->fixed_prio);
+ ioption("htb-default-prio",keyword->default_prio);
+ ioption("htb-rate-bonus",keyword->reserve_min);
+ ioption("htb-ceil-malus",keyword->reserve_max);
+ /* obsolete:
+ ioption("htb-ceil-divide",keyword->divide_max);
+ ioption("htb-ceil-bonus-divide",keyword->htb_ceil_bonus_divide);
+ */
+ option("leaf-discipline",keyword->leaf_discipline);
+ option("html-color",keyword->html_color);
+ _=tmptr;
+
+ if(keyword->data_limit || keyword->fixed_limit ||
+ keyword->data_prio || keyword->fixed_prio)
+ use_credit=1;
+ }
+ }
}
option("tc",tc);
@@ -404,7 +412,6 @@ void get_config(char *config_filename)
ioption("htb-nesting-limit",max_nesting);
ioption("htb-r2q",htb_r2q);
ioption("magic-include-upload",include_upload);
- ioption("magic-priorities",magic_priorities);
ioption("magic-treshold",magic_treshold);
option("filter-type", cnf);
@@ -422,9 +429,10 @@ void get_config(char *config_filename)
printf("\n");
/*leaf discipline for keywords*/
- every(keyword,keywords)
+ for_each(keyword,keywords)
{
- if (!strcmpi(keyword->leaf_discipline, "")){
+ if (!strcmpi(keyword->leaf_discipline, ""))
+ {
keyword->leaf_discipline = qos_leaf;
}
}
@@ -468,7 +476,7 @@ void get_traffic_statistics(void)
append(line,lines);
}
- every(line,lines)
+ for_each(line,lines)
{
int col, accept=0,proxyflag=0,valid=1,setchainname=0,commonflag=0;
unsigned long long traffic=0;
@@ -519,7 +527,8 @@ void get_traffic_statistics(void)
if(proxyflag)printf("(proxy) ");
else if(!downloadflag) printf("(upload) ");
printf("IP %s: %Lu M (%ld pkts)\n", ipaddr, traffic, pkts);
- find(ip,ips,eq(ip->addr,ipaddr));
+
+ if_exists(ip,ips,eq(ip->addr,ipaddr));
else
{
TheIP();
@@ -615,7 +624,11 @@ void parse_ip(char *str)
ptr++;
*ptr=0;
- find(ip,ips,eq(ip->addr,ipaddr)); else TheIP();
+ if_exists(ip,ips,eq(ip->addr,ipaddr));
+ else
+ {
+ TheIP();
+ }
ip->addr=ipaddr;
ip->name=ipname;
}
@@ -639,134 +652,207 @@ struct IpLog
char *name;
long traffic;
long guaranted;
+ int i;
+ long l;
list(IpLog);
} *iplog,*iplogs;
void parse_ip_log(int argc, char **argv)
{
- char *month, *year, *str, *name, *ptr, *ptr2;
- long traffic, traffic_month, total=0, guaranted;
+ char *month, *year, *str, *name="(undefined)", *ptr, *ptr2, *filename;
+ long traffic=0l, traffic_month, total=0, guaranted;
int col, col2, y_ok, m_ok, accept_month, i=1, any_month=0;
char mstr[4], ystr[5];
FILE *f;
string(str,STRLEN);
+ string(filename,STRLEN);
if(argv[1][1]=='l') /* -l */
{
- if(argc<4)
- {
- puts("Missing parameter(s)!\nUsage: prometheus -l Mmm YYYY (Mmm=Jan-Dec or Year, YYYY=year)");
- exit(-1);
- }
- else
- {
- month=argv[2];
- if(eq(month,"Year")) any_month=1;
- year=argv[3];
- }
+ if(argc<4)
+ {
+ puts("Missing parameter(s)!\nUsage: prometheus -l Mmm YYYY (Mmm=Jan-Dec or Year, YYYY=year)");
+ exit(-1);
+ }
+ else
+ {
+ month=argv[2];
+ if(eq(month,"Year")) any_month=1;
+ year=argv[3];
+ }
}
else
{
- time_t t = time(NULL) - 3600*24 ; /* yesterday's timestamp*/
- struct tm *timep = localtime(&t);
-
- if(argv[1][1]=='m') /* -m yestarday - month */
- {
- strftime(mstr, 4, "%b", timep);
- month=mstr;
- strftime(ystr, 5, "%Y", timep);
- year=ystr;
- }
- else /* -y yesterday - year */
- {
- month="Year";
- any_month=1;
- strftime(ystr, 5, "%Y", timep);
- year=ystr;
- }
+ time_t t = time(NULL) - 3600*24 ; /* yesterday's timestamp*/
+ struct tm *timep = localtime(&t);
+
+ if(argv[1][1]=='m') /* -m yestarday - month */
+ {
+ strftime(mstr, 4, "%b", timep);
+ month=mstr;
+ strftime(ystr, 5, "%Y", timep);
+ year=ystr;
+ }
+ else /* -y yesterday - year */
+ {
+ month="Year";
+ any_month=1;
+ strftime(ystr, 5, "%Y", timep);
+ year=ystr;
+ }
}
printf("Analysing traffic for %s %s ...\n",month,year);
- sprintf(str,"%s %s/*.log",ls,log_dir);
+ /* sorry... next release of C<<1 header file will include for_path_files(name,path) { } macro */
+ sprintf(str,"%s %s/",ls,log_dir);
shell(str);
-
- input(str,STRLEN)
+ input(str,STRLEN)
{
- ptr=strrchr(str,'\n');
- if(ptr) *ptr='\0';
- printf("Parsing %s ...",str);
- accept_month=0;
- traffic_month=0;
- guaranted = 0;
- parse(str)
+ if(strstr(str,".log"))
{
- y_ok=m_ok=0;
- valid_columns(ptr,_,'\t',col) switch(col)
- {
- case 2: name = ptr;break;
- case 3: traffic = atol(ptr);break;
- /* column number - was 7, now 10...*/
- case 7:
- case 8:
- case 9:
- case 10: if (isalpha(*ptr)) /* character, not numeric string = date, just one*/
- {
- valid_columns(ptr2,ptr,' ',col2) switch(col2)
+ ptr=strrchr(str,'\n');
+ if(ptr) *ptr='\0';
+ sprintf(filename,"%s/%s",log_dir,str);
+ printf("Parsing %s ...",filename);
+ accept_month=0;
+ traffic_month=0;
+ guaranted = 0;
+ parse(filename)
+ {
+ y_ok=m_ok=0;
+ valid_columns(ptr,_,'\t',col) switch(col)
+ {
+ case 2: name = ptr;break;
+ case 3: traffic = atol(ptr);break;
+ /* column number - was 7, now 10...*/
+ case 7:
+ case 8:
+ case 9:
+ case 10: if (isalpha(*ptr)) /* character, not numeric string = date, just one*/
{
- case 2: if(any_month || eq(ptr2,month)) m_ok = 1; break;
- case 5: if(eq(ptr2,year)) y_ok = 1; break;
+ valid_columns(ptr2,ptr,' ',col2) switch(col2)
+ {
+ case 2: if(any_month || eq(ptr2,month)) m_ok = 1; break;
+ case 5: if(eq(ptr2,year)) y_ok = 1; break;
+ }
}
- }
- else
- {
- if(col == 7) guaranted = atol(ptr);
- }
- }
-
- if(y_ok && m_ok)
- {
- traffic_month += traffic;
- accept_month = 1;
- }
- }
- done;
+ else
+ {
+ if(col == 7) guaranted = atol(ptr);
+ }
+ }
+
+ if(y_ok && m_ok)
+ {
+ traffic_month += traffic;
+ accept_month = 1;
+ }
+ }
+ done;
- if(accept_month)
- {
- create(iplog,IpLog);
- iplog->name = name;
- iplog->guaranted = guaranted;
- iplog->traffic = traffic_month;
- insert(iplog,iplogs,desc_order_by,traffic);
- printf(" %ld MB\n",iplog->traffic);
+ if(accept_month)
+ {
+ create(iplog,IpLog);
+ iplog->name = name;
+ iplog->guaranted = guaranted;
+ iplog->traffic = traffic_month;
+ insert(iplog,iplogs,desc_order_by,traffic);
+ printf(" %ld MB\n",iplog->traffic);
+ }
+ else
+ {
+ puts(" no records.");
+ }
}
- else
- puts(" no records.");
}
sprintf(str,"%s/%s-%s.html",html_log_dir,year,month);
printf("Writing %s ...",str);
f=fopen(str,"w");
if(f)
{
- fprintf(f,"