more IPs allowed in identical IPv6 uplink network
[svn/Prometheus-QoS/.git] / networks.c
index 965b2de339fb0fe1d7f85ca8dfd1f41c3cba18c3..6039ee6a48ba9bb98b603af2b2298d47f6546011 100644 (file)
@@ -5,15 +5,15 @@
 
 #define STRLEN 512
 
-extern struct IP *ips, *networks;
+extern struct IP *ip, *ips, *networks;
 
-struct IP* find_network_for_ip(char *ipaddr_orig)
+struct IP *locate_network(char *look_for)
 {
  struct IP *network;
  char *netaddr, *lastnum, *ipaddr;
- int ipnum, netnum;
+ int ipnum, netnum, total;
 
- duplicate(ipaddr_orig, ipaddr);
+ duplicate(look_for, ipaddr);
  lastnum = strrchr(ipaddr, '.');
  if(lastnum)
  {
@@ -25,14 +25,13 @@ struct IP* find_network_for_ip(char *ipaddr_orig)
  {
   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)
    {
     return network;
    }       
@@ -41,67 +40,151 @@ struct IP* find_network_for_ip(char *ipaddr_orig)
  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)
+void update_network_direct(struct IP *network, struct IP *ip)
+{
+ if(ip and network)
  {
-  printf("%s/%d %s min=%d max=%d sum=%d\n",ip->addr, ip->mask, ip->name, ip->min, ip->max, ip->desired); 
+  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, *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))
      {
-      printf("via [%s]\n", ptr);
-      network = find_network_for_ip(ptr);
+#ifdef DEBUG
+      printf("[%s] ", ptr);
+#endif
+      network = locate_network(ptr);
       if(network)
       {
-       network->min += ip->min;
-       network->desired += ip->max;
-       if(ip->max > network->max)
+       printf("[%s/%d] ", network->addr, network->mask);
+       network->mark = distance;
+       distance += 1;
+       if(uplink)
        {
-        network->max = ip->max;
+        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, max);
- for_each(ip, networks)
+
+ sort(network, networks, desc_order_by, min); /* secondary ordering  */
+ sort(network, networks, desc_order_by, desired); /* primary ordering  */
+
+ /*-----------------------------------------------------------------*/
+ puts("\nRequested network parameters are:");
+ /*-----------------------------------------------------------------*/
+ for_each(ip, networks) if(ip->desired)
  {
-  printf("%s/%d %s min=%d max=%d sum=%d\n",ip->addr, ip->mask, ip->name, ip->min, ip->max, 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)(ip->direct/(float)(ip->desired)+.5));
  }
  exit(-1);
 }
This page took 0.165695 seconds and 4 git commands to generate.