X-Git-Url: http://git.harvie.cz/?p=svn%2FPrometheus-QoS%2F.git;a=blobdiff_plain;f=prometheus.c;h=70bea1f2355559c9dca504dde27523d95bc36558;hp=780b15858c8dadec585d28a63b31ffe8c0350205;hb=f64d54310ae39276c552b80183ae2320789bb4be;hpb=0db8e99319ee2e9798ba7fb58a7666791cf81414
diff --git a/prometheus.c b/prometheus.c
index 780b158..70bea1f 100644
--- a/prometheus.c
+++ b/prometheus.c
@@ -1,13 +1,13 @@
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- /* Prometheus QoS - you can "steal fire" from your ISP */
-/* "fair-per-IP" quality of service (QoS) utility */
-/* requires Linux 2.4.x or 2.6.x with HTB support */
-/* Copyright(C) 2005-2012 Michael Polak, Arachne Labs */
-/* iptables-restore support Copyright(C) 2007-2008 ludva */
-/* Credit: CZFree.Net,Martin Devera,Netdave,Aquarius,Gandalf */
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-/* Modified by: xChaos, 20121011
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+/* Prometheus QoS - you can "steal fire" from your ISP */
+/* "fair-per-IP" quality of service (QoS) utility */
+/* requires Linux 2.4.x or 2.6.x with HTB support */
+/* Copyright(C) 2005-2013 Michael Polak, Arachne Aerospace */
+/* iptables-restore support Copyright(C) 2007-2008 ludva */
+/* Credit: CZFree.Net,Martin Devera,Netdave,Aquarius,Gandalf */
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+/* Modified by: xChaos, 20130116
ludva, 20080415
Prometheus QoS is free software; you can redistribute it and/or
@@ -26,56 +26,40 @@
GNU General Public License is located in file COPYING */
-#define STRLEN 512
-#undef DEBUG
-
#include "cll1-0.6.2.h"
#include "ipstruct.h"
-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. */
-/* 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 *version = "0.8.3-h";
-const char *stats_html_signature = "Statistics generated by Prometheus QoS version %s
GPL+Copyright(C)2005-2012 Michael Polak, Arachne Labs\n";
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+/* Versions: 0.8.3 is development release, 0.8.4 will be "stable" */
+/* Official Trac URL: https://dev.arachne.cz/svn/prometheus */
+/* Official SVN URL: https://dev.arachne.cz/repos/prometheus */
+/* BTC donations account: 19rriLx8vR19wGefPaMhakqnCYNYwjLvxq */
+/* CZK donations account: 2900242944/2010 (transparent account) */
+/* Warning: unofficial Github mirror is not supported by author! */
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-/* ======= Help screen is hopefuly self-documenting part of code :-) ======= */
+const char *stats_html_signature = "Statistics generated by Prometheus QoS version %s
GPL+Copyright(C)2005-2013 Michael Polak, Arachne Labs\n";
-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");
-}
+#define STRLEN 512
+#undef DEBUG
/* ======= All path names are defined here (for RPM patch) ======= */
-const char *tc = "/sbin/tc"; /* requires tc with HTB support */
-const char *iptables = "/sbin/iptables"; /* requires iptables utility */
-const char *iptablessave = "/sbin/iptables-save"; /* not yet required */
-const char *iptablesrestore = "/sbin/iptables-restore"; /* requires iptables-restore */
-const char *ls = "/bin/ls"; /* this is not user configurable :-) */
+const char *tc = "/sbin/tc"; /* requires tc with HTB support */
+const char *iptables = "/sbin/iptables"; /* requires iptables utility */
+const char *ip6tables = "/sbin/ip6tables"; /* requires iptables utility */
+const char *iptablessave = "/sbin/iptables-save"; /* not yet required */
+const char *iptablesrestore = "/sbin/iptables-restore"; /* requires iptables-restore */
+const char *ip6tablessave = "/sbin/ip6tables-save"; /* not yet required */
+const char *ip6tablesrestore = "/sbin/ip6tables-restore"; /* requires iptables-restore */
+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 */
-
char *iptablesfile = "/var/spool/prometheus.iptables"; /* temporary file for iptables-restore*/
+char *ip6tablesfile = "/var/spool/prometheus.ip6tables"; /* temporary file for ip6tables-restore*/
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 */
@@ -107,6 +91,7 @@ int hall_of_fame = TRUE; /* enable hall of fame */
char *lan = "eth0"; /* LAN interface */
char *lan_medium = "100Mbit"; /* 10Mbit/100Mbit ethernet */
char *wan = "eth1"; /* WAN/ISP interface */
+char *ip6prefix = NULL; /* Prefix for global /48 IPv6 subnet */
char *wan_medium = "100Mbit"; /* 10Mbit/100Mbit ethernet */
char *qos_leaf = "sfq perturb 5"; /* leaf discipline */
char *qos_free_zone = NULL; /* QoS free zone */
@@ -148,6 +133,12 @@ struct IP *ips = NULL, *ip, *sharedip;
struct Group *groups = NULL, *group;
struct Keyword *keyword, *defaultkeyword=NULL, *keywords=NULL;
+void help(void);
+/* implemented in help.c */
+
+void get_traffic_statistics(const char *whichiptables);
+/* implemented in parseiptables.c */
+
void parse_ip_log(int argc, char **argv);
/* implemented in parselog.c */
@@ -174,6 +165,7 @@ const char *tr_odd_even(void)
}
/* ==== This is C<<1 stuff - learn C<<1 first! https://dev.arachne.cz/svn/cll1h ==== */
+/* (except that this code uses obsolete, archaic version of this header file...) */
struct Index
{
@@ -185,8 +177,6 @@ struct Index
list(Index);
} *idxs=NULL, *idx, *metaindex;
-void TheIP(void);
-/* function implemented in parsehosts.c */
/* ====== iptables indexes are used to reduce complexity to log8(N) ===== */
@@ -232,7 +222,10 @@ void get_config(char *config_filename)
keyword->leaf_discipline="";
push(keyword,keywords);
- if(!defaultkeyword) defaultkeyword=keyword;
+ if(!defaultkeyword)
+ {
+ defaultkeyword=keyword;
+ }
keywordcount++;
kwd=NULL;
@@ -271,12 +264,17 @@ void get_config(char *config_filename)
option("tc",tc);
option("iptables",iptables);
- option("iptables-save",iptablessave); /* new */
- option("iptables-restore",iptablesrestore); /* new */
- option("iptables-in-filename",iptablesfile); /* new */
+ option("iptables-save",iptablessave);
+ option("iptables-restore",iptablesrestore);
+ option("ip6tables",ip6tables);
+ option("ip6tables-save",ip6tablessave);
+ option("ip6tables-restore",ip6tablesrestore);
+ option("iptables-in-filename",iptablesfile);
+ option("ip6tables-in-filename",ip6tablesfile);
option("hosts",hosts);
option("lan-interface",lan);
option("wan-interface",wan);
+ option("ip6-prefix",ip6prefix);
option("lan-medium",lan_medium);
option("wan-medium",wan_medium);
lloption("wan-download",line);
@@ -356,155 +354,6 @@ void get_config(char *config_filename)
}
}
-/* ===================== traffic analyser - uses iptables ================ */
-
-void get_traffic_statistics(void)
-{
- char *str,*cmd;
- int downloadflag=0;
-
- textfile(Pipe,str) *line,*lines=NULL;
- string(str,STRLEN);
- string(cmd,STRLEN);
-
- sprintf(cmd,"%s -L -v -x -n -t mangle",iptables);
- shell(cmd);
- input(str,STRLEN)
- {
- create(line,Pipe);
- line->str=str;
- string(str,STRLEN);
- append(line,lines);
- }
-
- for_each(line,lines)
- {
- int col, accept=0,proxyflag=0,valid=1,setchainname=0,commonflag=0;
- unsigned long long traffic=0;
- unsigned long pkts=0;
- char *ipaddr=NULL,*ptr;
-
- /* debug puts(line->str); */
- valid_columns(ptr,line->str,' ',col)
- if(valid) switch(col)
- {
- case 1: if(eq(ptr,"Chain"))
- {
- setchainname=1;
- }
- else if(eq(ptr,"pkts"))
- {
- valid=0;
- }
- else
- {
- sscanf(ptr,"%lu",&pkts);
- }
- break;
- case 2: if(setchainname)
- {
- if(!strncmp(ptr,"post_",5) || eq(ptr,"POSTROUTING"))
- {
- downloadflag = 1;
- }
- else
- {
- if(!strncmp(ptr,"forw_",5) || eq(ptr,"FORWARD"))
- {
- downloadflag = 0;
- }
- }
- if(eq(ptr,"post_common") || eq(ptr,"forw_common"))
- {
- commonflag = 1;
- }
- }
- else
- {
- sscanf(ptr,"%Lu",&traffic);
- traffic += (1<<19);
- traffic >>= 20;
- }
- break;
- case 3: if((strncmp(ptr,"post_",5) && strncmp(ptr,"forw_",5)) || commonflag)
- {
- accept=eq(ptr,mark);
- }
- /*if(filter_type==1) accept=eq(ptr,"MARK"); else accept=eq(ptr,"CLASSIFY");*/
- break;
- case 8: if(downloadflag)
- {
- if(strstr(proxy_ip,ptr))
- {
- proxyflag=1;
- }
- }
- else
- {
- ipaddr=ptr;
- }
- break;
- case 9: if(downloadflag)ipaddr=ptr;break;
- }
-
- if(accept && traffic>0 && ipaddr)
- {
- if(proxyflag)
- {
- printf("(proxy) ");
- }
- else if(!downloadflag)
- {
- printf("(upload) ");
- }
- printf("IP %s: %Lu MB (%ld pkts)\n", ipaddr, traffic, pkts);
-
- if_exists(ip,ips,eq(ip->addr,ipaddr));
- else
- {
- TheIP();
- ip->addr=ipaddr;
- if(eq(ip->addr,"0.0.0.0/0"))
- {
- ip->name="(unregistered)";
- ip->min=free_min;
- ip->max=ip->desired=free_max;
- }
- }
-
- if(downloadflag)
- {
- if(proxyflag)
- {
- ip->proxy=traffic;
- }
- else
- {
- ip->traffic+=traffic;
- }
- ip->direct=ip->traffic-ip->upload-ip->proxy;
- ip->pktsdown=pkts;
- }
- else
- {
- ip->upload=traffic;
- ip->pktsup=pkts;
- if(include_upload)
- {
- ip->traffic+=traffic;
- }
- else
- {
- if(traffic>ip->traffic)
- {
- ip->traffic=traffic;
- }
- }
- }
- }
- }
- free(cmd);
-}
/* ========== This function executes, logs OR ALSO prints command ========== */
@@ -655,7 +504,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);
/*-----------------------------------------------------------------*/
puts("Parsing iptables verbose output ...");
/*-----------------------------------------------------------------*/
- get_traffic_statistics();
+ get_traffic_statistics(iptables);
}
/*-----------------------------------------------------------------*/
@@ -713,17 +562,17 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);
puts("Initializing iptables and tc classes ...");
/*-----------------------------------------------------------------*/
- iptables_file=fopen(iptablesfile,"w");
+ iptables_file = fopen(iptablesfile, "w");
if(iptables_file == NULL)
{
- puts("Cannot open iptablesfile!");
+ perror(iptablesfile);
exit(-1);
}
- log_file=fopen(cmdlog,"w");
+ log_file = fopen(cmdlog, "w");
if(log_file == NULL)
{
- puts("Cannot open logfile!");
+ perror(cmdlog);
exit(-1);
}
@@ -767,7 +616,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);
save_line(str);
}
- if(ip_count>idxtable_treshold1 && !just_flush)
+ if(ip_count > idxtable_treshold1 && !just_flush)
{
int idxcount=0, bitmask=32-idxtable_bitmask1; /* default net mask: 255.255.255.240 */
char *subnet, *buf;
@@ -778,7 +627,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);
save_line(":post_common - [0:0]");
save_line(":forw_common - [0:0]");
- for_each(ip,ips) if(ip->addr && *(ip->addr) && !eq(ip->addr,"0.0.0.0/0"))
+ for_each(ip,ips) if(ip->addr && *(ip->addr) && !eq(ip->addr,"0.0.0.0/0") && !strchr(ip->addr,':')) /* only IPv4 */
{
buf=index_id(ip->addr,bitmask);
if_exists(idx,idxs,eq(idx->id,buf))
@@ -799,14 +648,14 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);
}
/* brutal perfomance optimalization */
- while(idxcount>idxtable_treshold2 && bitmask>2*idxtable_bitmask2)
+ while(idxcount > idxtable_treshold2 && bitmask > 2*idxtable_bitmask2)
{
- bitmask-=idxtable_bitmask2;
- idxcount=0;
+ bitmask -= idxtable_bitmask2;
+ idxcount = 0;
for_each(idx,idxs) if(idx->parent == NULL)
{
- buf=index_id(idx->addr,bitmask);
+ buf = index_id(idx->addr,bitmask);
if_exists(metaindex,idxs,eq(metaindex->id,buf))
{
metaindex->children++;
@@ -826,7 +675,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);
}
}
- /* this should slightly optimize throughout ... */
+ /* this should slightly optimize throughput ... */
sort(idx,idxs,desc_order_by,children);
sort(idx,idxs,order_by,bitmask);
@@ -1115,7 +964,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);
puts("Generating iptables and tc classes ... ");
/*-----------------------------------------------------------------*/
- for_each(ip, ips) if(ip->mark > 0)
+ for_each(ip, ips) if(ip->mark > 0 && !strchr(ip->addr,':')) /* works only for IPv4 so far */
{
if(idxs)
{