version 1.0.0.-a - significat iptables parsing speed improvement
[svn/Prometheus-QoS/.git] / networks.c
index 3308943b68d590b010ca3d6667b4161bc7151ee7..6039ee6a48ba9bb98b603af2b2298d47f6546011 100644 (file)
@@ -5,13 +5,13 @@
 
 #define STRLEN 512
 
-extern struct IP *ips, *networks;
+extern struct IP *ip, *ips, *networks;
 
-void update_network(char *look_for, struct IP* ip)
+struct IP *locate_network(char *look_for)
 {
  struct IP *network;
  char *netaddr, *lastnum, *ipaddr;
- int ipnum, netnum;
+ int ipnum, netnum, total;
 
  duplicate(look_for, ipaddr);
  lastnum = strrchr(ipaddr, '.');
@@ -25,93 +25,166 @@ void update_network(char *look_for, struct IP* ip)
  {
   duplicate(network->addr, netaddr);
   lastnum = strrchr(netaddr, '.');
-  if(lastnum)
+  if(lastnum or total)
   {
    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)
+   if(    eq(netaddr, ipaddr)
+      and netnum + (1<<(32-network->mask)) > ipnum
+      and netnum <= ipnum)
    {
-    network->group += 1;
-    network->min += ip->min;
-    network->direct += ip->max>>10; /* sum of Mbps, not kbps*/
+    return network;
+   }       
+  }
+ }
+ return NULL;
+}
 
-    if(ip->max > network->max)
-    {
-     network->max = ip->max;
-    }
 
-    if(network->max > network->min)
-    {
-     network->desired = network->max>>10;
-    }
-    else
-    {
-     network->desired = network->min>>10;
-    }
-    return;
-   }       
+void update_network_direct(struct IP *network, struct IP *ip)
+{
+ if(ip and network)
+ {
+  network->group += 1;
+  network->min += ip->min;
+  network->direct += ip->max>>10; /* sum of Mbps, not kbps */
+
+  if(ip->max > network->max)
+  {
+   network->max = ip->max;
+  }
+
+  if(network->max > network->min)
+  {
+   network->desired = network->max>>10;
+  }
+  else
+  {
+   network->desired = network->min>>10;
   }
  }
 }
 
+
+void update_network(char *look_for, struct IP* ip)
+{
+ update_network_direct(locate_network(look_for),ip);
+}
+
+
 void analyse_topology(char *traceroute)
 {
- char *buf, *netaddr, *ptr, *lastnum, *str;
- int col, gateway, netnum, tracert;
- struct IP *network=NULL, *ip;
+ char *buf, *netaddr, *ptr, *lastnum, *str, *redundant;
+ int col, gateway, netnum, tracert, distance;
+ struct IP *network = NULL, *uplink = NULL;
+
+ string(redundant, STRLEN);
+ string(str, STRLEN); 
 
  /*-----------------------------------------------------------------*/
  puts("Analysing network topology ...");
  /*-----------------------------------------------------------------*/
- for_each(ip, networks)
+ for_each(ip, networks) if(ip->group) /* just non-empty networks */
  { 
-  printf("%s/%d %s\n",ip->addr, ip->mask, ip->name);
+  printf("%s/%d %s ", 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);
+   *redundant = 0;
+   distance = 1;
+   uplink = NULL;
    input(str,STRLEN)
    {
-    if(    not strstr(str, "traceroute")
-       and not strstr(str, "* * *"))
+    if(not strstr(str, "traceroute")) /*skip header */
     {
+#ifdef DEBUG
      printf("%s",str);
+#endif
      duplicate(str, buf);
      valid_columns(ptr, buf, ' ', col)
-     if(*ptr=='*')
+     if(*ptr == '*')
      {
-      col--;
+      col -= 1;
      }
-     else if(col==2)
+     else if(col==2 and not strstr(redundant, ptr))
      {
-//#ifdef DEBUG
-      printf("via [%s]\n", ptr);
-//#endif
-      update_network(ptr, ip);
+#ifdef DEBUG
+      printf("[%s] ", ptr);
+#endif
+      network = locate_network(ptr);
+      if(network)
+      {
+       printf("[%s/%d] ", network->addr, network->mask);
+       network->mark = distance;
+       distance += 1;
+       if(uplink)
+       {
+        network->uplink = uplink;
+#ifdef DEBUG
+        printf("[%d: uplink of %s/%d is %s/%d] ",
+               network->mark, network->addr, network->mask, network->uplink->addr, network->uplink->mask);
+#endif
+       }
+       uplink = network;
+      }
+
+      if(strlen(redundant) < STRLEN - 17)
+      {
+       strcat(redundant, ptr);
+       strcat(redundant, " ");
+      }
      }
     }
+   }//end input loop
+
+//   ip->mark = distance;
+//   if(uplink)
+//   {
+//    ip->uplink = uplink;
+//   }
+   if(distance == 1)
+   {
+    printf("fail! \n");
+   }
+   else
+   {
+    printf("done. \n");
    }
   }
+ }//end for_each()
+
+ TheIP("0.0.0.0", TRUE);
+ ip->name = "TOTAL";
+ ip->mask = 0;
+
+ sort(network, networks, desc_order_by, mark); /* most distant networks first */
+ for_each(network, networks)
+ {
+  if(not network->uplink)
+  {
+   network->uplink = ip; /* global checksum */  
+  }
+  printf("(%d) uplink of %s/%d is %s/%d \n",
+         network->mark, network->addr, network->mask, network->uplink->addr, network->uplink->mask);
+  update_network_direct(network->uplink, network);
  }
- sort(network, networks, desc_order_by, min);
- sort(network, networks, desc_order_by, desired);
+
+ sort(network, networks, desc_order_by, min); /* secondary ordering  */
+ sort(network, networks, desc_order_by, desired); /* primary ordering  */
 
  /*-----------------------------------------------------------------*/
- puts("Requested network parameters are:");
+ puts("\nRequested network parameters are:");
  /*-----------------------------------------------------------------*/
  for_each(ip, networks) if(ip->desired)
  {
   printf("%s/%d %s REQUESTED=%dM (classes=%d, sum_min=%dk, max_1=%dk, sum_max=%LuM, agreg.=1:%d)\n",
          ip->addr, ip->mask, ip->name, ip->desired, ip->group, ip->min, ip->max, ip->direct,
-         (int)((float)((ip->direct)/ip->desired)+.5));
+         (int)(ip->direct/(float)(ip->desired)+.5));
  }
  exit(-1);
 }
This page took 0.14301 seconds and 4 git commands to generate.