network analyzer - first attempt
authorxchaos <xchaos@251d49ef-1d17-4917-a970-b30cf55b089b>
Tue, 29 Oct 2013 01:32:04 +0000 (01:32 +0000)
committerxchaos <xchaos@251d49ef-1d17-4917-a970-b30cf55b089b>
Tue, 29 Oct 2013 01:32:04 +0000 (01:32 +0000)
git-svn-id: https://dev.arachne.cz/repos/prometheus/trunk@227 251d49ef-1d17-4917-a970-b30cf55b089b

Makefile
check-kernel-qos [deleted file]
help.c
ipstruct.h
networks.c [new file with mode: 0644]
parsehosts.c
parseiptables.c
prometheus.c

index 0ca93d5cd3b21ef3d869194d64526361bc48d543..5f3a608531644f255fbc4d231dcaba0fb9defd01 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ prefix=/usr
 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
diff --git a/check-kernel-qos b/check-kernel-qos
deleted file mode 100755 (executable)
index e2ac020..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/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
-
diff --git a/help.c b/help.c
index af7368fa01a10e0dd027d4b5b8c0910ba850ac32..c8edf23cf25b648b69ecb104a1e4a0366dcd1258 100644 (file)
--- a/help.c
+++ b/help.c
@@ -24,6 +24,7 @@ void help(void)
 -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");
 }
index ea797499a7d2328e0b97cf116a3973c73c1d73a9..a80946d4acd96971478e4963d6ecabb42add59ca 100644 (file)
@@ -21,6 +21,7 @@ struct IP
  unsigned long pktsdown;\r
  struct Keyword *keyword;\r
  int v6;\r
+ int mask;\r
  list(IP);\r
 };\r
 \r
@@ -55,5 +56,5 @@ struct Keyword
  list(Keyword);\r
 };\r
 \r
-void TheIP(char *ipaddr);\r
+void TheIP(char *ipaddr, int is_network);\r
 /* function implemented in parsehosts.c */\r
diff --git a/networks.c b/networks.c
new file mode 100644 (file)
index 0000000..2c7df01
--- /dev/null
@@ -0,0 +1,107 @@
+/* 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);
+}
index 1e8dbe6773502e9b18f580570257cba552fe20df..04fce9ffca9714d2fbfbc474f49d91211477d154 100644 (file)
@@ -1,4 +1,4 @@
-/* Modified by: xChaos, 20121007 */\r
+/* Modified by: xChaos, 20131028 */\r
 \r
 #include "cll1-0.6.2.h"\r
 #include "ipstruct.h"\r
@@ -7,7 +7,7 @@
 #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
@@ -17,8 +17,11 @@ extern int free_min;
 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
@@ -40,14 +43,22 @@ void TheIP(char *ipaddr)
  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
@@ -104,7 +115,7 @@ parse_ip(char *str)
   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
@@ -119,10 +130,10 @@ parse_ip(char *str)
   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
@@ -138,6 +149,7 @@ void parse_hosts(char *hosts)
  int groupidx = FIRSTGROUPID;\r
  char *str, *ptr;\r
  char *substring;\r
+ struct IP *network;\r
 \r
  parse(hosts)\r
  {\r
@@ -154,7 +166,7 @@ void parse_hosts(char *hosts)
   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
@@ -170,75 +182,116 @@ void parse_hosts(char *hosts)
   }\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
index 1f22d132226dcfefc637f6ba8cc02b890c81282f..946707d3bd084aa4fca852e241eb8723bb4998d3 100644 (file)
@@ -41,7 +41,7 @@ void get_traffic_statistics(const char *whichiptables, int ipv6)
   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
@@ -150,7 +150,7 @@ void get_traffic_statistics(const char *whichiptables, int ipv6)
    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
index b7b3a04620b9f55b3a6252728a44baf8c7094287..045c182bfca6b686a97cf7aab9db2ebd5ffff791 100644 (file)
@@ -132,7 +132,7 @@ const int idxtable_treshold2 = 12;      /* this is no longer configurable */
 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
@@ -154,6 +154,10 @@ void write_json_traffic(char *json);
 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
@@ -337,10 +341,10 @@ void get_config(char *config_filename)
  /* 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
@@ -468,6 +472,7 @@ program
  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
@@ -502,6 +507,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);
   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
@@ -536,7 +542,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);
 \r
  if(althosts)\r
  {\r
-  hosts=althosts;\r
+  hosts = althosts;\r
  }\r
 \r
  if(just_flush<9)\r
@@ -555,21 +561,26 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);
  }\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
This page took 0.304989 seconds and 4 git commands to generate.