mandir=$(prefix)/share/man
sbindir=$(prefix)/sbin
sysconfdir=/etc
-OBJECTS=parsehosts.o parseiptables.o parselogs.o ipv4subnets.o ipv6subnets.o json.o htmlandlogs.o help.o prometheus.o
+OBJECTS=parsehosts.o networks.o parseiptables.o parselogs.o ipv4subnets.o ipv6subnets.o json.o htmlandlogs.o help.o prometheus.o
HEADERS=cll1-0.6.2.h ipstruct.h
main: prometheus
+++ /dev/null
-#!/bin/bash
-
-echo -n "Checking for HTB support (2.6.x Linux kernel series only) ..."
-HTB=`cat /proc/config.gz |gunzip|grep CONFIG_NET_SCH_HTB`
-if [ "$HTB" = "CONFIG_NET_SCH_HTB=y" ] || [ "$HTB" = "CONFIG_NET_SCH_HTB=m" ]
-then
- echo " ok."
-else
- echo " failed!"
- echo "** Missing /proc/config.gz, missing gunzip, or missing HTB support in kernel.. **"
- echo "** You are likely to get RTNETLINK error messages when running Prometheus QoS. **"
-fi
-
-echo -n "Checking for SFQ support (2.6.x Linux kernel series only) ..."
-SFQ=`cat /proc/config.gz |gunzip|grep CONFIG_NET_SCH_SFQ`
-if [ "$SFQ" = "CONFIG_NET_SCH_SFQ=y" ] || [ "$SFQ" = "CONFIG_NET_SCH_SFQ=m" ]
-then
- echo " ok."
-else
- echo " failed!"
- echo "** Missing /proc/config.gz, missing gunzip, or missing SFQ support in kernel.. **"
- echo "** You are likely to get RTNETLINK error messages when running Prometheus QoS. **"
-fi
-
-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\
+-a analyse network topology (agregation statistics, using traceroute)\n\
-? --help show this help scree (and exit)\n\
-v --version show Version number of this utility (and exit)\n");
}
unsigned long pktsdown;\r
struct Keyword *keyword;\r
int v6;\r
+ int mask;\r
list(IP);\r
};\r
\r
list(Keyword);\r
};\r
\r
-void TheIP(char *ipaddr);\r
+void TheIP(char *ipaddr, int is_network);\r
/* function implemented in parsehosts.c */\r
--- /dev/null
+/* Modified by: xChaos, 20131028 */
+
+#include "cll1-0.6.2.h"
+#include "ipstruct.h"
+
+#define STRLEN 512
+
+extern struct IP *ips, *networks;
+
+struct IP* find_network_for_ip(char *ipaddr_orig)
+{
+ struct IP *network;
+ char *netaddr, *lastnum, *ipaddr;
+ int ipnum, netnum;
+
+ duplicate(ipaddr_orig, ipaddr);
+ lastnum = strrchr(ipaddr, '.');
+ if(lastnum)
+ {
+ ipnum = atoi(lastnum + 1);
+ *lastnum = 0;
+ }
+
+ for_each(network, networks)
+ {
+ duplicate(network->addr, netaddr);
+ lastnum = strrchr(netaddr, '.');
+ if(lastnum)
+ {
+ netnum = atoi(lastnum + 1);
+ *lastnum = 0;
+// printf("%s/%d + %d\n",network->addr,network->mask,(1<<(32-network->mask)));
+ if( eq(netaddr, ipaddr)
+ and netnum + (1<<(32-network->mask)) > ipnum
+ and netnum <= ipnum)
+ {
+ return network;
+ }
+ }
+ }
+ return NULL;
+}
+
+void analyse_topology(char *traceroute)
+{
+ char *buf, *netaddr, *ptr, *lastnum, *str;
+ int col, gateway, netnum, tracert;
+ struct IP *network=NULL, *ip;
+
+ for_each(ip, networks)
+ {
+ printf("%s/%d %s min=%d max=%d sum=%d\n",ip->addr, ip->mask, ip->name, ip->min, ip->max, ip->desired);
+ }
+
+ /*-----------------------------------------------------------------*/
+ puts("Analysing network topology ...");
+ /*-----------------------------------------------------------------*/
+ for_each(ip, networks)
+ {
+ printf("%s/%d %s\n",ip->addr, ip->mask, ip->name);
+ duplicate(ip->addr, buf);
+ lastnum = strrchr(buf, '.');
+ if(lastnum)
+ {
+ gateway = atoi(lastnum + 1) + 1; /* this is just common rule... */
+ *lastnum = 0;
+ string(str,STRLEN);
+ sprintf(str, traceroute, buf, gateway);
+ shell(str);
+ input(str,STRLEN)
+ {
+ if( not strstr(str, "traceroute")
+ and not strstr(str, "* * *"))
+ {
+ printf("%s",str);
+ duplicate(str, buf);
+ valid_columns(ptr, buf, ' ', col)
+ if(*ptr=='*')
+ {
+ col--;
+ }
+ else if(col==2)
+ {
+ printf("via [%s]\n", ptr);
+ network = find_network_for_ip(ptr);
+ if(network)
+ {
+ network->min += ip->min;
+ network->desired += ip->max;
+ if(ip->max > network->max)
+ {
+ network->max = ip->max;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ sort(network, networks, desc_order_by, min);
+ sort(network, networks, desc_order_by, max);
+ for_each(ip, networks)
+ {
+ printf("%s/%d %s min=%d max=%d sum=%d\n",ip->addr, ip->mask, ip->name, ip->min, ip->max, ip->desired);
+ }
+ exit(-1);
+}
-/* Modified by: xChaos, 20121007 */\r
+/* Modified by: xChaos, 20131028 */\r
\r
#include "cll1-0.6.2.h"\r
#include "ipstruct.h"\r
#define FIRSTIPCLASS 2048\r
\r
/* globals declared in prometheus.c */\r
-extern struct IP *ips, *ip, *sharedip;\r
+extern struct IP *ips, *ip, *sharedip, *networks;\r
extern struct Group *groups, *group;\r
extern struct Keyword *keyword, *defaultkeyword, *keywords;\r
extern int class_count;\r
extern const int highest_priority;\r
extern char *ip6prefix;\r
\r
+struct IP* find_network_for_ip(char *ipaddr_orig);\r
+/* implemented in networks.c */\r
+\r
/* This must be object oriented! This looks almost like constructor ;-) */\r
-void TheIP(char *ipaddr)\r
+void TheIP(char *ipaddr, int is_network)\r
{\r
create(ip,IP);\r
ip->name = "";\r
ip->pktsdown = 0;\r
ip->keyword = keywords;\r
ip->v6 = (strchr(ip->addr,':')!=NULL);\r
- push(ip,ips);\r
+ ip->mask = ((ip->v6)?64:32);\r
+ if(is_network)\r
+ {\r
+ push(ip, networks);\r
+ }\r
+ else\r
+ {\r
+ push(ip, ips); \r
+ }\r
ip_count++;\r
}\r
\r
struct IP *lastIP6;\r
\r
/* == This function strips extra characters after IPv4 address and stores it = */\r
-parse_ip(char *str)\r
+void parse_and_append_ip(char *str, struct IP *listhead)\r
{\r
char *ptr, *ipaddr, *ip6range = NULL, *ipname = NULL, *lmsid = NULL;\r
\r
if_exists(ip, ips, eq(ip->addr,ip6range));\r
else\r
{\r
- TheIP(ip6range);\r
+ TheIP(ip6range, FALSE);\r
}\r
ip->name = ip6range;\r
ip->keyword = defaultkeyword; /* settings for default keyword */\r
lastIP6 = NULL;\r
}\r
\r
- if_exists(ip, ips, eq(ip->addr,ipaddr));\r
+ if_exists(ip, listhead, eq(ip->addr,ipaddr));\r
else\r
{\r
- TheIP(ipaddr);\r
+ TheIP(ipaddr, (listhead==networks));\r
}\r
ip->name = ipname;\r
if(lmsid)\r
int groupidx = FIRSTGROUPID;\r
char *str, *ptr;\r
char *substring;\r
+ struct IP *network;\r
\r
parse(hosts)\r
{\r
if(substring)\r
{ \r
substring += 8; /* "sharing-" */\r
- parse_ip(str);\r
+ parse_and_append_ip(str, ips);\r
ip->sharing = substring;\r
ip->keyword = defaultkeyword; /* settings for default keyword */\r
if(lastIP6)\r
}\r
else\r
{\r
- /*Do we have to create new QoS class for this IP ? */\r
-\r
- if_exists(keyword,keywords,(substring=strstr(str,keyword->key)))\r
+ substring = strstr(str, "#255.");\r
+ if(substring and not strstr(str, "#255.255.255.255")) /* do not ping /32 ranges */\r
{\r
- parse_ip(str);\r
- if(lastIP6)\r
- {\r
- lastIP6->sharing = ip->name;\r
- lastIP6 = NULL;\r
- }\r
- ip->keyword = keyword;\r
- keyword->ip_count++;\r
- ip->prio = keyword->default_prio;\r
- substring += strlen(keyword->key)+1;\r
- ptr = substring;\r
- while(*ptr and *ptr != '-')\r
- {\r
- ptr++;\r
- }\r
- if(*ptr == '-')\r
+ /* netmask detected - save network*/\r
+ unsigned bit;\r
+ unsigned num, mask = 8;\r
+ substring += 5;\r
+ while(substring && *substring)\r
{\r
- *ptr=0;\r
- ip->max = ip->desired = atoi(ptr+1);\r
- }\r
- ip->min = atoi(substring);\r
- if(ip->min <= 0)\r
- {\r
- printf(" %s: Illegal value of minimum bandwidth 0 kbps, using %d kb/s\n",\r
- str, free_min);\r
- ip->min = free_min;\r
- }\r
- if(ip->max <= ip->min)\r
- {\r
- ip->fixedprio = TRUE;\r
- ip->max = ip->min + ip->keyword->reserve_min;\r
- }\r
- else \r
- {\r
- ip->max -= ip->keyword->reserve_max;\r
- if(ip->max<ip->min)\r
+ ptr = substring;\r
+ substring = strchr(substring, '.');\r
+ if(substring)\r
+ {\r
+ *substring = 0;\r
+ substring += 1;\r
+ }\r
+ num = atoi(ptr);\r
+ for(bit = 1; bit <=128 ; bit<<=1)\r
{\r
- ip->max=ip->min;\r
+ if(bit & num)\r
+ {\r
+ mask++;\r
+ }\r
}\r
- }\r
- ip->mark = FIRSTIPCLASS+1+class_count++;\r
-\r
- if_exists(group,groups,(group->min == ip->min)) \r
- { \r
- group->count++; \r
- group->desired += ip->min;\r
- ip->group = group->id; \r
- }\r
- else\r
+ } \r
+ parse_and_append_ip(str, networks);\r
+ ip->mask = mask;\r
+ }\r
+ else\r
+ {\r
+ /*Do we have to create new QoS class for this IP ? */\r
+ if_exists(keyword,keywords,(substring=strstr(str,keyword->key)))\r
{\r
- create(group,Group);\r
- group->min = ip->min;\r
- group->id = groupidx++;\r
- ip->group = group->id;\r
-\r
- if(group->min < 8) group->min = 8;\r
- /* Warning - this is maybe because of primitive tc namespace, can be fixed */\r
- /* it is because class IDs are derived from min. bandwidth. - xCh */\r
- //if(group->min>MAX_GUARANTED_KBPS) group->min=MAX_GUARANTED_KBPS;\r
- \r
- group->count = 1;\r
- group->desired = ip->min; \r
- insert(group, groups, desc_order_by,min);\r
- }\r
- }//endif keyword-\r
+ parse_and_append_ip(str, ips);\r
+ if(lastIP6)\r
+ {\r
+ lastIP6->sharing = ip->name;\r
+ lastIP6 = NULL;\r
+ }\r
+ ip->keyword = keyword;\r
+ keyword->ip_count++;\r
+ ip->prio = keyword->default_prio;\r
+ substring += strlen(keyword->key)+1;\r
+ ptr = substring;\r
+ while(*ptr and *ptr != '-')\r
+ {\r
+ ptr++;\r
+ }\r
+ if(*ptr == '-')\r
+ {\r
+ *ptr=0;\r
+ ip->max = ip->desired = atoi(ptr+1);\r
+ }\r
+ ip->min = atoi(substring);\r
+ if(ip->min <= 0)\r
+ {\r
+ printf(" %s: Illegal value of minimum bandwidth 0 kbps, using %d kb/s\n",\r
+ str, free_min);\r
+ ip->min = free_min;\r
+ }\r
+ if(ip->max <= ip->min)\r
+ {\r
+ ip->fixedprio = TRUE;\r
+ ip->max = ip->min + ip->keyword->reserve_min;\r
+ }\r
+ else \r
+ {\r
+ ip->max -= ip->keyword->reserve_max;\r
+ if(ip->max<ip->min)\r
+ {\r
+ ip->max=ip->min;\r
+ }\r
+ }\r
+ ip->mark = FIRSTIPCLASS+1+class_count++;\r
+\r
+ network = find_network_for_ip(ip->addr);\r
+ if(network)\r
+ {\r
+ network->min += ip->min;\r
+ network->desired += ip->max;\r
+ if(ip->max > network->max)\r
+ {\r
+ network->max = ip->max;\r
+ }\r
+ }\r
+\r
+ if_exists(group,groups,(group->min == ip->min)) \r
+ { \r
+ group->count++; \r
+ group->desired += ip->min;\r
+ ip->group = group->id; \r
+ }\r
+ else\r
+ {\r
+ create(group,Group);\r
+ group->min = ip->min;\r
+ group->id = groupidx++;\r
+ ip->group = group->id;\r
+\r
+ if(group->min < 8) group->min = 8;\r
+ /* Warning - this is maybe because of primitive tc namespace, can be fixed */\r
+ /* it is because class IDs are derived from min. bandwidth. - xCh */\r
+ //if(group->min>MAX_GUARANTED_KBPS) group->min=MAX_GUARANTED_KBPS;\r
+ \r
+ group->count = 1;\r
+ group->desired = ip->min; \r
+ insert(group, groups, desc_order_by,min);\r
+ }\r
+ }//endif keyword-\r
+ }//endif netmask\r
}//endif sharing-\r
}\r
fail\r
unsigned long pkts = 0;\r
char *ipaddr = NULL,*ptr;\r
\r
- valid_columns(ptr, line->str, ' ', col) \r
+ valid_columns(ptr, line->str, ' ', col)\r
if(valid) switch(col)\r
{ \r
case 1: if(eq(ptr,"Chain"))\r
if_exists(ip, ips, eqi(ip->addr,ipaddr)); \r
else \r
{\r
- TheIP(ipaddr);\r
+ TheIP(ipaddr, FALSE);\r
if(eq(ip->addr,"0.0.0.0/0"))\r
{\r
ip->name = "(unregistered)";\r
const int idxtable_bitmask1 = 3; /* this is no longer configurable */\r
const int idxtable_bitmask2 = 3; /* this is no longer configurable */\r
\r
-struct IP *ips = NULL, *ip, *sharedip;\r
+struct IP *ips = NULL, *networks = NULL, *ip, *sharedip;\r
struct Group *groups = NULL, *group;\r
struct Keyword *keyword, *defaultkeyword=NULL, *keywords=NULL;\r
\r
void write_htmlandlogs(char *html, char *d, int total, int just_preview);\r
/* implemented in htmlandlogs.c */\r
\r
+void analyse_topology(char *traceroute);\r
+/* implemented in networks.c */\r
+\r
+\r
const char *tr_odd_even(void)\r
{\r
row_odd_even = 1 - row_odd_even;\r
/* leaf discipline for keywords */\r
for_each(keyword,keywords)\r
{\r
- if(!strcmpi(keyword->leaf_discipline, ""))\r
- {\r
- keyword->leaf_discipline = qos_leaf;\r
- }\r
+ if(!strcmpi(keyword->leaf_discipline, ""))\r
+ {\r
+ keyword->leaf_discipline = qos_leaf;\r
+ }\r
}\r
\r
if(strcmpi(cnf, "mark"))\r
char *substring;\r
\r
int parent = 1;\r
+ int just_networks = FALSE; \r
int just_flush = FALSE; /* deactivates all previous actions */\r
int nodelay = FALSE;\r
int just_preview = FALSE; /* preview - generate just stats */\r
argument("-s") { run=TRUE; just_preview=TRUE; start_shaping=TRUE; }\r
argument("-r") { run=TRUE; }\r
argument("-n") { run=TRUE; nodelay=TRUE; }\r
+ argument("-a") { run=TRUE; just_networks=TRUE; }\r
argument("-l") { just_logs=TRUE; }\r
argument("-m") { just_logs=TRUE; }\r
argument("-y") { just_logs=TRUE; }\r
\r
if(althosts)\r
{\r
- hosts=althosts;\r
+ hosts = althosts;\r
}\r
\r
if(just_flush<9)\r
}\r
\r
/*-----------------------------------------------------------------*/\r
- printf("Parsing class defintion file %s ...\n", hosts);\r
+ /* cll1.h - let's allocate brand new character buffer... */\r
/*-----------------------------------------------------------------*/\r
- parse_hosts(hosts);\r
+ string(str,STRLEN); \r
\r
/*-----------------------------------------------------------------*/\r
- /* cll1.h - let's allocate brand new character buffer... */\r
+ printf("Parsing class defintion file %s ...\n", hosts);\r
/*-----------------------------------------------------------------*/\r
- string(str,STRLEN); \r
+ parse_hosts(hosts);\r
+ if(just_networks)\r
+ {\r
+ analyse_topology("/usr/sbin/traceroute -n -m 10 -w 2 %s.%d");\r
+ exit(-1); \r
+ }\r
\r
/*-----------------------------------------------------------------*/\r
puts("Resolving shared connections ...");\r
/*-----------------------------------------------------------------*/\r
- for_each(ip,ips) if(ip->sharing)\r
+ for_each(ip, ips) if(ip->sharing)\r
{\r
- for_each(sharedip,ips) if(eq(sharedip->name, ip->sharing))\r
+ for_each(sharedip, ips) if(eq(sharedip->name, ip->sharing))\r
{\r
sharedip->traffic += ip->traffic;\r
ip->traffic = 0;\r