X-Git-Url: http://git.harvie.cz/?a=blobdiff_plain;f=prometheus.c;h=814da9e4cb0fe9de6527fb98ad4e216d357961ba;hb=05a9080997b372eb6003e407fc20b8ec80b8c085;hp=64012559235dc72987d087318984737e747a92bf;hpb=5692c7757847ed4d412173d820392dbf2cfb5a70;p=svn%2FPrometheus-QoS%2F.git
diff --git a/prometheus.c b/prometheus.c
index 6401255..814da9e 100644
--- a/prometheus.c
+++ b/prometheus.c
@@ -7,7 +7,7 @@
/* Credit: CZFree.Net,Martin Devera,Netdave,Aquarius,Gandalf */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-/* Modified by: xChaos, 20120612
+/* Modified by: xChaos, 20121011
ludva, 20080415
Prometheus QoS is free software; you can redistribute it and/or
@@ -27,13 +27,12 @@
GNU General Public License is located in file COPYING */
#define STRLEN 512
-#define FIRSTGROUPID 1024
-#define FIRSTIPCLASS 2048
#undef DEBUG
#include "cll1-0.6.2.h"
+#include "ipstruct.h"
-const char *version = "0.8.3-f";
+const char *version = "0.8.3-g";
/* 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. */
@@ -42,6 +41,29 @@ const char *version = "0.8.3-f";
const char *stats_html_signature = "Statistics generated by Prometheus QoS version %s
GPL+Copyright(C)2005-2012 Michael Polak, Arachne Labs\n";
+/* ======= Help screen is hopefuly self-documenting part of code :-) ======= */
+
+void help(void)
+{
+ puts("Command line switches:\n\
+\n\
+-d Dry run (preview tc and iptables commands on stdout)\n\
+-r Run (reset all statistics and start shaping - daily usage)\n\
+-p just generate Preview of data transfer statistics and exit (after -r)\n\
+-s start Shaping FUP limits (keeps data transfer stat like -p) (after -r)\n\
+-n run Now (like -r delay - overrides qos-free-delay keyword, after boot)\n\
+-f just Flush iptables and tc classes and exit (stop shaping, no QiS)\n\
+-9 emergency iptables flush (like -f, but dumps data transfer statistics)\n\
+\n\
+-c filename force alternative /etc/prometheus/prometheus.conf filename\n\
+-h filename force alternative /etc/hosts filename (overrides hosts keyword)\n\
+-l Mmm YYYY generate HTML summary of Logged traffic (Mmm=Jan-Dec) (and exit)\n\
+-m generate HTML summary of traffic for yesterday's Month (and exit)\n\
+-y generate HTML summary of traffic for yesterday's Year (and exit)\n\
+-? --help show this help scree (and exit)\n\
+-v --version show Version number of this utility (and exit)\n");
+}
+
/* ======= All path names are defined here (for RPM patch) ======= */
const char *tc = "/sbin/tc"; /* requires tc with HTB support */
@@ -58,7 +80,7 @@ char *credit = "/var/lib/misc/prometheus.credit"; /* credit log file */
char *classmap = "/var/lib/misc/prometheus.classes"; /* credit log file */
char *html = "/var/www/traffic.html"; /* hall of fame - html version */
char *preview = "/var/www/preview.html"; /* hall of fame preview - html version */
-char *json = "/var/www/logs/traffic.json"; /* hall of fame - json version */
+char *json_traffic = "/var/www/logs/traffic.json"; /* hall of fame - json version */
char *json_preview = "/var/www/logs/preview.json"; /* hall of fame preview - json version */
char *cmdlog = "/var/log/prometheuslog"; /* command log filename */
char *log_dir = "/var/www/logs/"; /* log directory pathname, ended with slash */
@@ -69,47 +91,7 @@ char *jquery_url = "http://code.jquery.com/jquery-latest.js";
char *lms_url = "/lms/?m=customerinfo&id=";
int use_jquery_popups = 1;
int row_odd_even = 0; /*
*/
-
-
-void parse_ip_log(int argc, char **argv);
-/* implementid in parselog.c */
-
-const char *tr_odd_even(void)
-{
- row_odd_even = 1 - row_odd_even;
- if(row_odd_even)
- {
- return "
\n";
- }
- else
- {
- return "
\n";
- }
-}
-
-/* ======= Help screen is hopefuly self-documenting part of code :-) ======= */
-
-void help(void)
-{
- puts("Command line switches:\n\
-\n\
--d Dry run (preview tc and iptables commands on stdout)\n\
--r Run (reset all statistics and start shaping - daily usage)\n\
--p just generate Preview of data transfer statistics and exit (after -r)\n\
--s start Shaping FUP limits (keeps data transfer stat like -p) (after -r)\n\
--n run Now (like -r delay - overrides qos-free-delay keyword, after boot)\n\
--f just Flush iptables and tc classes and exit (stop shaping, no QiS)\n\
--9 emergency iptables flush (like -f, but dumps data transfer statistics)\n\
-\n\
--c filename force alternative /etc/prometheus/prometheus.conf filename\n\
--h filename force alternative /etc/hosts filename (overrides hosts keyword)\n\
--l Mmm YYYY generate HTML summary of Logged traffic (Mmm=Jan-Dec) (and exit)\n\
--m generate HTML summary of traffic for yesterday's Month (and exit)\n\
--y generate HTML summary of traffic for yesterday's Year (and exit)\n\
--? --help show this help scree (and exit)\n\
--v --version show Version number of this utility (and exit)\n");
-}
-
+
/* === Configuraration file values defaults - stored in global variables ==== */
int filter_type = 1; /*1 mark, 2 classify*/
@@ -146,6 +128,8 @@ int burst_main = 64;
int burst_group = 32;
int magic_treshold = 8; /* reduce ceil by X*magic_treshhold kbps (hard shaping) */
int keywordcount = 0;
+int class_count = 0;
+int ip_count = 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 !!!
@@ -160,40 +144,33 @@ 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! https://dev.arachne.cz/svn/cll1h ==== */
+struct IP *ips = NULL, *ip, *sharedip;
+struct Group *groups = NULL, *group;
+struct Keyword *keyword, *defaultkeyword=NULL, *keywords=NULL;
-struct IP
-{
- char *addr;
- char *name;
- char *sharing;
- int min;
- int desired;
- int max;
- int mark;
- int prio;
- int fixedprio;
- int group;
- int lmsid;
- unsigned long long direct;
- unsigned long long proxy;
- unsigned long long upload;
- unsigned long long traffic;
- unsigned long long credit;
- unsigned long pktsup;
- unsigned long pktsdown;
- struct Keyword *keyword;
- list(IP);
-} *ips=NULL, *ip, *sharedip;
-
-struct Group
+void parse_ip_log(int argc, char **argv);
+/* implemented in parselog.c */
+
+void parse_hosts(char *hosts);
+/* implemented in parsehosts.c */
+
+void write_json_traffic(char *json);
+/* implemented in json.c */
+
+const char *tr_odd_even(void)
{
- int min;
- int count;
- int desired;
- int id;
- list(Group);
-} *groups=NULL, *group;
+ row_odd_even = 1 - row_odd_even;
+ if(row_odd_even)
+ {
+ return "
\n";
+ }
+ else
+ {
+ return "
\n";
+ }
+}
+
+/* ==== This is C<<1 stuff - learn C<<1 first! https://dev.arachne.cz/svn/cll1h ==== */
struct Index
{
@@ -205,155 +182,18 @@ struct Index
list(Index);
} *idxs=NULL, *idx, *metaindex;
-struct Keyword
-{
- char *key;
-
- 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 */
- 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) */
- int reserve_max; /* malus for nominal HTB ceil (in kbps) */
-// int divide_max; /* relative malus: new_ceil=rate+(old_ceil-rate)/divide_max */
-// int htb_ceil_bonus_divide; /* relative bonus: new_ceil=old_ceil+old_ceil/htb_ceil_bonus_divide */
- int default_prio; /* default HTB priority for this keyword */
- char *html_color;
- int ip_count;
- char *leaf_discipline;
-
- list(Keyword);
-} *keyword,*defaultkeyword=NULL,*keywords=NULL;
-
-/* Damned, this must be object oriented! This looks almost like constructor ;-) */
-
-void TheIP(void)
-{
- create(ip,IP);
- ip->name = "";
- ip->addr = "";
- ip->sharing = NULL;
- ip->prio = highest_priority+1;
- ip->lmsid = -1;
- ip->fixedprio = \
- 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);
-}
+void TheIP(void);
+/* function implemented in parsehosts.c */
/* ====== iptables indexes are used to reduce complexity to log8(N) ===== */
-char *very_ugly_ipv4_code(char *inip,int bitmask,int format_as_chainname)
-{
- /* warning: this function was debugged only for bitmask values 20,24,28 !!!*/
- int dot=0, n;
- char *ip,*outip,*outptr,*fmt;
+char *index_id(char *ip, int bitmask);
+/* function implemented in ipv4subnets.c */
- duplicate(inip,ip);
- /* debug printf("(%s,%d) -> ",ip,bitmask); */
+char *subnet_id(char *ip, int bitmask);
+/* function implemented in ipv4subnets.c */
- if(ip && *ip && bitmask>=0 && bitmask<=32)
- {
- string(outip,strlen(ip)+10); /*fuck unicode? assertion: 10>strlen("_%d_%d") */
- }
- else
- {
- /* should never exit here */
- return "undefined";
- }
- outptr=outip;
- while(ip && *ip)
- {
- if(*ip=='.')
- {
- if(dot<(bitmask/8-1))
- {
- if(format_as_chainname)
- {
- *outptr='_';
- }
- else
- {
- *outptr='.';
- }
- outptr++;
- dot++;
- }
- else
- {
- char *cutdot=strchr(ip+1,'.'); /*for bitmask<24*/
- if(cutdot)
- {
- *cutdot = '\0';
- }
-
- if(format_as_chainname)
- {
- fmt = "_%d_%d";
- }
- else
- {
- fmt = ".%d";
- }
-
- if(bitmask%8)
- {
- n = atoi(ip+1)-atoi(ip+1)%(1<<(8-bitmask%8));
- }
- else
- {
- n = 0;
- }
-
- /*debug printf("%d/%d => [_%d_%d]\n",atoi(ip+1),bitmask,n,bitmask); */
- sprintf(outptr,fmt,n,bitmask);
- if(!format_as_chainname)
- {
- while(bitmask<24)
- {
- strcat(outip,".0");
- bitmask+=8;
- }
- }
- /* debug printf("[%s]\n",outip); */
- return outip;
- }
- }
- else
- {
- *outptr=*ip;
- outptr++;
- }
- ip++;
- }
- /*should never exit here*/
- *outptr='\0';
- return outip;
-}
-
-char *hash_id(char *ip,int bitmask)
-{
- return very_ugly_ipv4_code(ip,bitmask,1);
-}
-
-char *subnet_id(char *ip,int bitmask)
-{
- return very_ugly_ipv4_code(ip,bitmask,0);
-}
-
-/* ================= Let's parse configuration file here =================== */
+/* ================= Let's parse configuration file here ================ */
void reject_config_and_exit(char *filename)
{
@@ -441,7 +281,7 @@ void get_config(char *config_filename)
ioption("hall-of-fame-enable",hall_of_fame);
option("hall-of-fame-title",title);
option("hall-of-fame-filename",html);
- option("json-filename",json);
+ option("json-filename",json_traffic);
option("hall-of-fame-preview",preview);
option("json-preview",json_preview);
option("log-filename",cmdlog);
@@ -712,57 +552,6 @@ void run_restore(void)
free(restor);
}
-/* == This function strips extra characters after IP address and stores it = */
-
-void parse_ip(char *str)
-{
- char *ptr,*ipaddr=NULL,*ipname=NULL,*lmsid=NULL;
-
- ptr=strchr(str,'{');
- if(ptr)
- {
- lmsid=++ptr;
- while(*ptr && *ptr!='}')
- {
- ptr++;
- }
- *ptr=0;
- }
-
- ptr=str;
- while(*ptr && *ptr!=' ' && *ptr!=9)
- {
- ptr++;
- }
-
- *ptr=0;
- ipaddr=str;
- ptr++;
- while(*ptr && (*ptr==' ' || *ptr==9))
- {
- ptr++;
- }
- ipname=ptr;
- while(*ptr && *ptr!=' ' && *ptr!=9)
- {
- ptr++;
- }
- *ptr=0;
-
- if_exists(ip,ips,eq(ip->addr,ipaddr));
- else
- {
- TheIP();
- }
- ip->addr=ipaddr;
- ip->name=ipname;
- if(lmsid)
- {
- ip->lmsid=atoi(lmsid);
- found_lmsid=1;
- }
-}
-
char *parse_datafile_line(char *str)
{
char *ptr=strchr(str,' ');
@@ -779,9 +568,6 @@ char *parse_datafile_line(char *str)
}
}
-
-
-
void append_log(struct IP *self) /*using global variables*/
{
char *d, *str;
@@ -804,7 +590,6 @@ void append_log(struct IP *self) /*using global variables*/
}
}
-
/*-----------------------------------------------------------------*/
/* Are you looking for int main(int argc, char **argv) ? :-)) */
/*-----------------------------------------------------------------*/
@@ -815,7 +600,7 @@ program
FILE *f=NULL; /* everything is just stream of bytes... */
char *str, *ptr, *d; /* LET A$=B$ :-) */
char *substring;
- int class_count=0,ip_count=0;
+
int parent=1;
int just_flush=FALSE; /* deactivates all previous actions */
int nodelay=FALSE;
@@ -894,107 +679,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);
/*-----------------------------------------------------------------*/
printf("Parsing class defintion file %s ...\n", hosts);
/*-----------------------------------------------------------------*/
- int groupidx = FIRSTGROUPID;
- parse(hosts)
- {
- str=_;
-
- if(*str<'0' || *str>'9')
- {
- /* any line starting with non-number is comment ...*/
- continue;
- }
-
- //Does this IP share QoS class with some other ?
- substring=strstr(str,"sharing-");
- if(substring)
- {
- substring+=8; //"sharing-"
- parse_ip(str);
- ip_count++;
- ip->sharing=substring;
- ip->keyword=defaultkeyword; /* settings for default keyword */
- while(*substring && *substring!='\n')
- {
- substring++;
- }
- *substring=0;
- }
- else
- {
- //Do we have to create new QoS class for this IP ?
-
- if_exists(keyword,keywords,(substring=strstr(str,keyword->key)))
- {
- parse_ip(str);
- ip_count++;
- ip->keyword=keyword;
- keyword->ip_count++;
- ip->prio=keyword->default_prio;
- substring+=strlen(keyword->key)+1;
- ptr=substring;
- while(*ptr && *ptr!='-')
- {
- ptr++;
- }
- if(*ptr=='-')
- {
- *ptr=0;
- ip->max = ip->desired=atoi(ptr+1);
- }
- ip->min = atoi(substring);
- if(ip->min <= 0)
- {
- printf(" %s: Illegal value of minimum bandwidth 0 kbps, using %d kb/s\n",
- str, free_min);
- ip->min = free_min;
- }
- if(ip->max <= ip->min)
- {
- ip->fixedprio = 1;
- ip->max = ip->min+ip->keyword->reserve_min;
- }
- else
- {
- ip->max -= ip->keyword->reserve_max;
- if(ip->maxmin)
- {
- ip->max=ip->min;
- }
- }
- ip->mark=FIRSTIPCLASS+1+class_count++;
-
- if_exists(group,groups,group->min==ip->min)
- {
- group->count++;
- group->desired += ip->min;
- ip->group = group->id;
- }
- else
- {
- create(group,Group);
- group->min = ip->min;
- group->id = groupidx++;
- ip->group = group->id;
-
- if(group->min<8) group->min=8;
- /* Warning - this is maybe because of primitive tc namespace, can be fixed */
- /* it is because class IDs are derived from min. bandwidth. - xCh */
- //if(group->min>MAX_GUARANTED_KBPS) group->min=MAX_GUARANTED_KBPS;
-
- group->count=1;
- group->desired=ip->min;
- insert(group,groups,desc_order_by,min);
- }
- }//endif keyword-
- }//endif sharing-
- }
- fail
- {
- perror(hosts);
- exit(-1);
- }
- done; /* ugly macro end */
+ parse_hosts(hosts);
/*-----------------------------------------------------------------*/
/* cll1.h - let's allocate brand new character buffer... */
@@ -1014,7 +699,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);
ip->lmsid=sharedip->lmsid;
break;
}
- if(!sharedip)
+ if(not sharedip)
{
printf("Unresolved shared connection: %s %s sharing-%s\n",
ip->addr, ip->name, ip->sharing);
@@ -1082,11 +767,11 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);
if(qos_proxy)
{
save_line(":post_noproxy - [0:0]");
- sprintf(str,"-A POSTROUTING -p ! tcp -o %s -j post_noproxy", lan);
+ sprintf(str,"-A POSTROUTING ! -p tcp -o %s -j post_noproxy", lan);
save_line(str);
- sprintf(str,"-A POSTROUTING -s ! %s -o %s -j post_noproxy", proxy_ip, lan);
+ sprintf(str,"-A POSTROUTING ! -s %s -o %s -j post_noproxy", proxy_ip, lan);
save_line(str);
- sprintf(str,"-A POSTROUTING -s %s -p tcp --sport ! %d -o %s -j post_noproxy", proxy_ip, proxy_port, lan);
+ sprintf(str,"-A POSTROUTING -s %s -p tcp ! --sport %d -o %s -j post_noproxy", proxy_ip, proxy_port, lan);
save_line(str);
chain="post_noproxy";
@@ -1113,7 +798,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);
for_each(ip,ips) if(ip->addr && *(ip->addr) && !eq(ip->addr,"0.0.0.0/0"))
{
- buf=hash_id(ip->addr,bitmask);
+ buf=index_id(ip->addr,bitmask);
if_exists(idx,idxs,eq(idx->id,buf))
{
idx->children++;
@@ -1139,7 +824,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);
for_each(idx,idxs) if(idx->parent == NULL)
{
- buf=hash_id(idx->addr,bitmask);
+ buf=index_id(idx->addr,bitmask);
if_exists(metaindex,idxs,eq(metaindex->id,buf))
{
metaindex->children++;
@@ -1404,41 +1089,15 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);
done; /* ugly macro end */
}
html=preview;
- json=json_preview;
+ json_traffic=json_preview;
}
if(!dry_run && !just_flush)
{
/*-----------------------------------------------------------------*/
- printf("Writing json overview %s ... ", json);
+ printf("Writing json traffic overview %s ... ", json_traffic);
/*-----------------------------------------------------------------*/
- f=fopen(json, "w");
- if(f > 0)
- {
- int jsoncount=0;
- fprintf(f, "{\n");
- for_each(ip, ips)
- {
- if( ip->lmsid > 0
- && (ip->traffic || ip->direct || ip->proxy || ip->upload))
- {
- if(jsoncount)
- {
- fprintf(f, ",\n");
- }
- fprintf(f, " \"%s\":{ \"lms\": %d, \"ip\":\"%s\", \"total\":%Lu, \"down\":%Lu, \"proxy\":%Lu, \"up\":%Lu, \"min\":%d, \"max\":%d, \"limit\":%d }",
- ip->name, ip->lmsid, ip->addr, ip->traffic, ip->direct, ip->proxy, ip->upload, ip->min, ip->desired, ip->max);
- jsoncount++;
- }
- }
- fprintf(f, "}\n");
- fclose(f);
- puts("done.");
- }
- else
- {
- perror(json);
- }
+ write_json_traffic(json_traffic);
}
f=fopen(html,"w");
@@ -1853,7 +1512,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);
{
char *buf;
duplicate(ip->addr,buf);
- buf=hash_id(ip->addr,32-idxtable_bitmask1);
+ buf=index_id(ip->addr,32-idxtable_bitmask1);
string(chain_forward,6+strlen(buf));
strcpy(chain_forward,"forw_");