[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#694849: marked as done (unblock: ntop/3:4.99.3+ndpi5517+dfsg2-1)



Your message dated Sat, 01 Dec 2012 11:06:54 +0000
with message-id <34d7654776cbd95cd95440a28b2108fe@mail.adsl.funky-badger.org>
and subject line Re: Bug#694849: unblock: ntop/3:4.99.3+ndpi5517+dfsg2-1
has caused the Debian Bug report #694849,
regarding unblock: ntop/3:4.99.3+ndpi5517+dfsg2-1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
694849: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=694849
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package ntop

Needed to remove non-DFSG code: http://bugs.debian.org/692732

Changes:
- replace CC-BY-NC countmin.[ch] and prng.[ch] with the new version
  released under GPL-2. The difference is minimal, and mostly comments.
- the new countmin.[ch] and prng.[ch] are also included vanilla in the
  debian directory so that get-orig-source.sh can create the new orig
  tarball
- updated the Maintainer (moved myself from Uploader to Maintainer) as
  agreed with former Maintainer

Debdiff attached.

unblock ntop/3:4.99.3+ndpi5517+dfsg2-1

-- System Information:
Debian Release: wheezy/sid
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.2.0-4-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
diff -Nru ntop-4.99.3+ndpi5517+dfsg1/countmin.c ntop-4.99.3+ndpi5517+dfsg2/countmin.c
--- ntop-4.99.3+ndpi5517+dfsg1/countmin.c	2011-11-21 05:42:08.000000000 -0800
+++ ntop-4.99.3+ndpi5517+dfsg2/countmin.c	2012-11-30 00:16:18.000000000 -0800
@@ -1,20 +1,30 @@
 /********************************************************************
 Count-Min Sketches
 
-G. Cormode 2003,2004
+G. Cormode 2003,2004, 2010, 2012
 
-Updated: 2004-06 Added a floating point sketch and support for 
+Updated: 2004-06 Added a floating point sketch and support for
                  inner product point estimation
 Initial version: 2003-12
 
-This work is licensed under the Creative Commons
-Attribution-NonCommercial License. To view a copy of this license,
-visit http://creativecommons.org/licenses/by-nc/1.0/ or send a letter
-to Creative Commons, 559 Nathan Abbott Way, Stanford, California
-94305, USA. 
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *********************************************************************/
 
 #include <stdlib.h>
+#include "prng.h"
 #include "countmin.h"
 
 #define min(x,y)	((x) < (y) ? (x) : (y))
@@ -23,8 +33,6 @@
 double eps;	               /* 1+epsilon = approximation factor */
 double delta;                  /* probability of failure */
 
-//int bits=32;
-
 /************************************************************************/
 /* Routines to support Count-Min sketches                               */
 /************************************************************************/
@@ -36,7 +44,7 @@
   prng_type * prng;
 
   cm=(CM_type *) malloc(sizeof(CM_type));
-  prng=prng_Init(-abs(seed),2); 
+  prng=prng_Init(-abs(seed),2);
   // initialize the generator to pick the hash functions
 
   if (cm && prng)
@@ -44,7 +52,6 @@
       cm->depth=depth;
       cm->width=width;
       cm->count=0;
-      cm->prng = prng; /* L. Deri */
       cm->counts=(int **)calloc(sizeof(int *),cm->depth);
       cm->counts[0]=(int *)calloc(sizeof(int), cm->depth*cm->width);
       cm->hasha=(unsigned int *)calloc(sizeof(unsigned int),cm->depth);
@@ -61,6 +68,8 @@
 	}
       else cm=NULL;
     }
+  if (prng)
+      prng_Destroy(prng);
   return cm;
 }
 
@@ -105,7 +114,6 @@
     }
   if (cm->hasha) free(cm->hasha); cm->hasha=NULL;
   if (cm->hashb) free(cm->hashb); cm->hashb=NULL;
-  prng_Destroy(cm->prng); /* L.Deri */
   free(cm);  cm=NULL;
 }
 
@@ -187,9 +195,10 @@
   return 1;
 }
 
-int CM_InnerProd(CM_type * cm1, CM_type * cm2)
+long long CM_InnerProd(CM_type * cm1, CM_type * cm2)
 { // Estimate the inner product of two vectors by comparing their sketches
-  int i,j, tmp, result;
+  int i,j;
+  long long result, tmp;
 
   result=0;
   if (CM_Compatible(cm1,cm2))
@@ -207,9 +216,33 @@
   return result;
 }
 
+#if 0
+long long CM_F2Est(CM_type * cm)
+{ // Estimate the second frequency moment of the stream
+  int i,j;
+  long long result, tmp, *ans;
+
+  if (!cm) return 0;
+  ans=(long long *) calloc(1+cm->depth,sizeof(long long));
+
+  for (j=0;j<cm->depth;j++)
+    {
+      result=0;
+      for (i=0;i<cm->width;i+=2)
+	{
+	  tmp=(cm->counts[j][i]-cm->counts[j][i+1]);
+	  result+=tmp*tmp;
+	}
+      ans[j+1]=result;
+    }
+  result=LLMedSelect((cm->depth+1)/2,cm->depth,ans);
+  return result;
+}
+#endif
+
 int CM_Residue(CM_type * cm, unsigned int * Q)
 {
-// CM_Residue computes the sum of everything left after the points 
+// CM_Residue computes the sum of everything left after the points
 // from Q have been removed
 // Q is a list of points, where Q[0] gives the length of the list
 
@@ -224,7 +257,7 @@
       nextest=0;
       for (i=0;i<cm->width;i++)
 	bitmap[i]=0;
-      for (i=1;i<Q[0];i++)
+      for (i=1;i<(int) Q[0];i++)
 	bitmap[hash31(cm->hasha[j],cm->hashb[j],Q[i]) % cm->width]=1;
       for (i=0;i<cm->width;i++)
 	if (bitmap[i]==0) nextest+=cm->counts[j][i];
@@ -245,7 +278,7 @@
 
   cm=(CMF_type *) malloc(sizeof(CMF_type));
 
-  prng=prng_Init(-abs(seed),2); 
+  prng=prng_Init(-abs(seed),2);
   // initialize the generator to pick the hash functions
 
   if (cm && prng)
@@ -269,6 +302,8 @@
 	}
       else cm=NULL;
     }
+  if (prng)
+      prng_Destroy(prng);
   return cm;
 }
 
@@ -311,8 +346,6 @@
       free(cm->counts);
       cm->counts=NULL;
     }
-
-  
   if (cm->hasha) free(cm->hasha); cm->hasha=NULL;
   if (cm->hashb) free(cm->hashb); cm->hashb=NULL;
   free(cm);  cm=NULL;
@@ -339,10 +372,11 @@
   // this can be done more efficiently if the width is a power of two
 }
 
-int CMF_PointEst(CMF_type * cm, unsigned int query)
+double CMF_PointEst(CMF_type * cm, unsigned int query)
 {
   // return an estimate of the count of an item by taking the minimum
-  int j, ans;
+  int j;
+  double ans=0.;
 
   if (!cm) return 0;
   ans=cm->counts[0][hash31(cm->hasha[0],cm->hashb[0],query) % cm->width];
@@ -380,12 +414,12 @@
 	{
 	  loc=hash31(cm1->hasha[j],cm1->hashb[j],query) % cm1->width;
 	  tmp=cm1->counts[j][loc]*cm2->counts[j][loc];
-	  ans=min(ans,tmp); 
+	  ans=min(ans,tmp);
 	}
     }
   return (ans);
 }
- 
+
 double CMF_InnerProd(CMF_type * cm1, CMF_type * cm2)
 { // Estimate the inner product of two vectors by comparing their sketches
   int i,j;
@@ -413,7 +447,7 @@
 
 CMH_type * CMH_Init(int width, int depth, int U, int gran)
 {
-  // initialize a hierarchical set of sketches for range queries 
+  // initialize a hierarchical set of sketches for range queries
   // heavy hitters or quantiles
 
   CMH_type * cmh;
@@ -424,10 +458,10 @@
   // U is the log the size of the universe in bits
 
   if (gran>U || gran<1) return(NULL);
-  // gran is the granularity to look at the universe in 
+  // gran is the granularity to look at the universe in
   // check that the parameters make sense...
 
-  cmh=(CMH_type *) malloc(sizeof(CMH_type));
+  cmh=(CMH_type *) calloc(1,sizeof(CMH_type));
 
   prng=prng_Init(-12784,2);
   // initialize the generator for picking the hash functions
@@ -441,11 +475,11 @@
       cmh->gran=gran;
       cmh->levels=(int) ceil(((float) U)/((float) gran));
       for (j=0;j<cmh->levels;j++)
-	if (1<<(cmh->gran*j) <= cmh->depth*cmh->width)
+	if ((long long) 1<<(cmh->gran*j) <= cmh->depth*cmh->width)
 	  cmh->freelim=j;
       //find the level up to which it is cheaper to keep exact counts
       cmh->freelim=cmh->levels-cmh->freelim;
-      
+
       cmh->counts=(int **) calloc(sizeof(int *), 1+cmh->levels);
       cmh->hasha=(unsigned int **)calloc(sizeof(unsigned int *),1+cmh->levels);
       cmh->hashb=(unsigned int **)calloc(sizeof(unsigned int *),1+cmh->levels);
@@ -454,12 +488,12 @@
 	{
 	  if (i>=cmh->freelim)
 	    { // allocate space for representing things exactly at high levels
-	      cmh->counts[i]=calloc(1<<(cmh->gran*j),sizeof(int));
+	      cmh->counts[i]=(int *) calloc(1<<(cmh->gran*j),sizeof(int));
 	      j++;
 	      cmh->hasha[i]=NULL;
 	      cmh->hashb[i]=NULL;
 	    }
-	  else 
+	  else
 	    { // allocate space for a sketch
 	      cmh->counts[i]=(int *)calloc(sizeof(int), cmh->depth*cmh->width);
 	      cmh->hasha[i]=(unsigned int *)
@@ -476,11 +510,13 @@
 	    }
 	}
     }
+  if (prng)
+      prng_Destroy(prng);
   return cmh;
 }
 
 void CMH_Destroy(CMH_type * cmh)
-{  // free up the space 
+{  // free up the space
   int i;
   if (!cmh) return;
   for (i=0;i<cmh->levels;i++)
@@ -489,7 +525,7 @@
 	{
 	  free(cmh->counts[i]);
 	}
-      else 
+      else
 	{
 	  free(cmh->hasha[i]);
 	  free(cmh->hashb[i]);
@@ -513,14 +549,14 @@
     {
       offset=0;
       if (i>=cmh->freelim)
-	{
+	{ // level 0 = leaves, higher levels = internal nodes
 	  cmh->counts[i][item]+=diff;
-	  // keep exact counts at high levels in the hierarchy  
+	  // keep exact counts at high levels in the hierarchy
 	}
       else
 	for (j=0;j<cmh->depth;j++)
 	  {
-	    cmh->counts[i][(hash31(cmh->hasha[i][j],cmh->hashb[i][j],item) 
+	    cmh->counts[i][(hash31(cmh->hasha[i][j],cmh->hashb[i][j],item)
 			    % cmh->width) + offset]+=diff;
 	    // this can be done more efficiently if the width is a power of two
 	    offset+=cmh->width;
@@ -545,7 +581,7 @@
   return(admin + hashes + counts);
 }
 
-int CMH_count(CMH_type * cmh, int depth, int item)
+int CMH_count(CMH_type * cmh, int depth, unsigned int item)
 {
   // return an estimate of item at level depth
 
@@ -561,23 +597,23 @@
   // else, use the appropriate sketch to make an estimate
   offset=0;
   estimate=cmh->counts[depth][(hash31(cmh->hasha[depth][0],
-				      cmh->hashb[depth][0],item) 
+				      cmh->hashb[depth][0],item)
 			       % cmh->width) + offset];
   for (j=1;j<cmh->depth;j++)
     {
       offset+=cmh->width;
       estimate=min(estimate,
 		   cmh->counts[depth][(hash31(cmh->hasha[depth][j],
-					      cmh->hashb[depth][j],item) 
+					      cmh->hashb[depth][j],item)
 				       % cmh->width) + offset]);
     }
   return(estimate);
 }
 
-void CMH_recursive(CMH_type * cmh, int depth, int start, 
+void CMH_recursive(CMH_type * cmh, int depth, int start,
 		    int thresh, unsigned int * results)
 {
-  // for finding heavy hitters, recursively descend looking 
+  // for finding heavy hitters, recursively descend looking
   // for ranges that exceed the threshold
 
   int i;
@@ -586,11 +622,11 @@
   int itemshift;
 
   estcount=CMH_count(cmh,depth,start);
-  if (estcount>=thresh) 
-    { 
+  if (estcount>=thresh)
+    {
       if (depth==0)
 	{
-	  if (results[0]<cmh->width)
+	  if (results[0]<(unsigned int) cmh->width)
 	    {
 	      results[0]++;
 	      results[results[0]]=start;
@@ -607,7 +643,7 @@
     }
 }
 
-int * CMH_FindHH(CMH_type * cmh, int thresh)
+unsigned int * CMH_FindHH(CMH_type * cmh, int thresh)
 { // find all items whose estimated count is greater than phi n
 
   unsigned int * results;
@@ -618,27 +654,31 @@
   return(results);
 }
 
-int CMH_Rangesum(CMH_type * cmh, int start, int end)
+int CMH_Rangesum(CMH_type * cmh, long long start, long long end)
 {
-  // compute a range sum: 
+  // compute a range sum:
   // start at bottom level
   // compute any estimates needed at each level
   // work upwards
 
-  int leftend,rightend,i,depth, result, topend;
+  int depth, result;
+  long long range, leftend, rightend;
+  long long topend, i;
 
-  topend=1<<cmh->U;
+  topend=((long long) 1)<<cmh->U;
   end=min(topend,end);
-  if ((end>topend) && (start==0))
+  if ((end>topend) && (start==0)) {
     return cmh->count;
+  }
 
   end+=1; // adjust for end effects
   result=0;
   for (depth=0;depth<=cmh->levels;depth++)
     {
       if (start==end) break;
-      if ((end-start+1)<(1<<cmh->gran))
-	{ // at the highest level, avoid overcounting	
+      range=(end-start+1);
+      if ((unsigned int) (end-start+1)<(((unsigned int) 1)<<cmh->gran))
+	{ // if only a few nodes to probe at this level, probe them all
 	  for (i=start;i<end;i++)
 	    result+=CMH_count(cmh,depth,i);
 	  break;
@@ -646,6 +686,7 @@
       else
 	{  // figure out what needs to be done at each end
 	  leftend=(((start>>cmh->gran)+1)<<cmh->gran) - start;
+	  if (leftend>= 1<<cmh->gran) leftend=0;
 	  rightend=(end)-((end>>cmh->gran)<<cmh->gran);
 	  if ((leftend>0) && (start<end))
 	    for (i=0;i<leftend;i++)
@@ -665,19 +706,20 @@
   return result;
 }
 
-int CMH_FindRange(CMH_type * cmh, int sum)
+long long CMH_FindRange(CMH_type * cmh, int sum)
 {
-  unsigned long low, high, mid=0, est;
-  int i;
+  long long low, high, mid=0;
+  int i, est=0;
   // find a range starting from zero that adds up to sum
 
   if (cmh->count<sum) return 1<<(cmh->U);
   low=0;
-  high=1<<cmh->U;
+  high=((long long) 1)<<cmh->U;
+
   for (i=0;i<cmh->U;i++)
     {
       mid=(low+high)/2;
-      est=CMH_Rangesum(cmh,0,mid);
+      est=CMH_Rangesum(cmh,0,(unsigned int) mid);
       if (est>sum)
 	high=mid;
       else
@@ -687,18 +729,17 @@
 
 }
 
-int CMH_AltFindRange(CMH_type * cmh, int sum)
+long long CMH_AltFindRange(CMH_type * cmh, int sum)
 {
-  unsigned long low, high, mid=0, est, top;
-  int i;
+  long long low, high, mid=0,top;
+  int i, est=0;
   // find a range starting from the right hand side that adds up to sum
 
   if (cmh->count<sum) return 1<<(cmh->U);
   low=0;
-  top=1<<cmh->U;
+  top=((long long) 1)<<cmh->U;
   high=top;
-  for (i=0;i<cmh->U;i++)
-    {
+  for (i=0;i<cmh->U;i++) {
       mid=(low+high)/2;
       est=CMH_Rangesum(cmh,mid,top);
       if (est<sum)
@@ -710,17 +751,17 @@
 
 }
 
-int CMH_Quantile(CMH_type * cmh, float frac)
+long long CMH_Quantile(CMH_type * cmh, float frac)
 {
   // find a quantile by doing the appropriate range search
   if (frac<0) return 0;
-  if (frac>1) 
+  if (frac>1)
     return 1<<cmh->U;
-  return ((CMH_FindRange(cmh,cmh->count*frac)+
-	   CMH_AltFindRange(cmh,cmh->count*(1-frac)))/2);
+  return ((CMH_FindRange(cmh,(long long) (cmh->count*frac))+
+	   CMH_AltFindRange(cmh,(long long) (cmh->count*(1-frac))))/2);
   // each result gives a lower/upper bound on the location of the quantile
   // with high probability, these will be close: only a small number of values
-  // will be between the estimates. 
+  // will be between the estimates.
 }
 
 long long CMH_F2Est(CMH_type * cmh)
diff -Nru ntop-4.99.3+ndpi5517+dfsg1/countmin.h ntop-4.99.3+ndpi5517+dfsg2/countmin.h
--- ntop-4.99.3+ndpi5517+dfsg1/countmin.h	2012-02-21 15:51:02.000000000 -0800
+++ ntop-4.99.3+ndpi5517+dfsg2/countmin.h	2012-11-30 00:16:18.000000000 -0800
@@ -2,15 +2,8 @@
 //   1 -- The basic CM Sketch
 //   2 -- The hierarchical CM Sketch: with log n levels, for range sums etc. 
 
-#ifndef min
 #define min(x,y)	((x) < (y) ? (x) : (y))
-#endif
-
-#ifndef max
 #define max(x,y)	((x) > (y) ? (x) : (y))
-#endif
-
-#include "prng.h"
 
 typedef struct CM_type{
   long long count;
@@ -18,7 +11,6 @@
   int width;
   int ** counts;
   unsigned int *hasha, *hashb;
-  prng_type * prng; /* L. Deri */
 } CM_type;
 
 typedef struct CMF_type{ // shadow of above stucture with floats
@@ -37,8 +29,9 @@
 extern void CM_Update(CM_type *, unsigned int, int); 
 extern int CM_PointEst(CM_type *, unsigned int);
 extern int CM_PointMed(CM_type *, unsigned int);
-extern int CM_InnerProd(CM_type *, CM_type *);
+extern long long CM_InnerProd(CM_type *, CM_type *);
 extern int CM_Residue(CM_type *, unsigned int *);
+extern long long CM_F2Est(CM_type *);
 
 extern CMF_type * CMF_Init(int, int, int);
 extern CMF_type * CMF_Copy(CMF_type *);
@@ -57,7 +50,7 @@
   int depth;
   int width;
   int ** counts;
-  unsigned int **hasha, * *hashb;
+  unsigned int **hasha, **hashb;
 } CMH_type;
 
 extern CMH_type * CMH_Init(int, int, int, int);
@@ -66,9 +59,9 @@
 extern int CMH_Size(CMH_type *);
 
 extern void CMH_Update(CMH_type *, unsigned int, int);
-extern int * CMH_FindHH(CMH_type *, int);
-extern int CMH_Rangesum(CMH_type *, int, int);
+extern unsigned int * CMH_FindHH(CMH_type *, int);
+extern int CMH_Rangesum(CMH_type *, long long, long long);
 
-extern int CMH_FindRange(CMH_type * cmh, int);
-extern int CMH_Quantile(CMH_type *cmh,float);
+extern long long CMH_FindRange(CMH_type * cmh, int);
+extern long long CMH_Quantile(CMH_type *cmh,float);
 extern long long CMH_F2Est(CMH_type *);
diff -Nru ntop-4.99.3+ndpi5517+dfsg1/debian/changelog ntop-4.99.3+ndpi5517+dfsg2/debian/changelog
--- ntop-4.99.3+ndpi5517+dfsg1/debian/changelog	2012-06-27 00:25:38.000000000 -0700
+++ ntop-4.99.3+ndpi5517+dfsg2/debian/changelog	2012-11-30 00:37:15.000000000 -0800
@@ -1,3 +1,11 @@
+ntop (3:4.99.3+ndpi5517+dfsg2-1) unstable; urgency=medium
+
+  * Repackage upstream source replacing non-DFSG countmin code with the GPL
+    one (Closes: #692732).
+  * Update Maintainer and Uploaders.
+
+ -- Ludovico Cavedon <cavedon@debian.org>  Fri, 30 Nov 2012 00:07:10 -0800
+
 ntop (3:4.99.3+ndpi5517+dfsg1-1) unstable; urgency=low
 
   * Imported Upstream version 4.99.3 and nDPI r5517.
diff -Nru ntop-4.99.3+ndpi5517+dfsg1/debian/control ntop-4.99.3+ndpi5517+dfsg2/debian/control
--- ntop-4.99.3+ndpi5517+dfsg1/debian/control	2012-06-27 00:25:38.000000000 -0700
+++ ntop-4.99.3+ndpi5517+dfsg2/debian/control	2012-11-30 00:37:15.000000000 -0800
@@ -1,8 +1,7 @@
 Source: ntop
 Section: net
 Priority: optional
-Maintainer: Jordan Metzmeier <jordan@linuxgen.com>
-Uploaders: Ludovico Cavedon <cavedon@debian.org>
+Maintainer: Ludovico Cavedon <cavedon@debian.org>
 Build-Depends-Indep: groff
 Build-Depends: debhelper (>= 8), libpcap0.8-dev, autoconf, automake,
  libgdbm-dev, libpng-dev, libncurses5-dev, libtool, libwrap0-dev,
diff -Nru ntop-4.99.3+ndpi5517+dfsg1/debian/copyright ntop-4.99.3+ndpi5517+dfsg2/debian/copyright
--- ntop-4.99.3+ndpi5517+dfsg1/debian/copyright	2012-06-27 00:25:38.000000000 -0700
+++ ntop-4.99.3+ndpi5517+dfsg2/debian/copyright	2012-11-30 00:37:15.000000000 -0800
@@ -57,13 +57,9 @@
  WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
-Files: countmin.h
-Copyright: 2003-2004, G. Cormode
-License: CC-BY-NC
- This work is licensed under the Creative Commons Attribution-NonCommercial
- License. To view a copy of this license, visit
- http://creativecommons.org/licenses/by-nc/1.0/ or send a letter to Creative
- Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
+Files: countmin.h countmin.c prng.h prng.c
+Copyright: 2003-2004, 2010, 2012, G. Cormode
+License: GPL-2+
 
 Files: utils/xmldump.awk utils/processstruct.awk AutoConfigureNtop linuxrelease
  config_h.shm utildl.c
diff -Nru ntop-4.99.3+ndpi5517+dfsg1/debian/countmin.c ntop-4.99.3+ndpi5517+dfsg2/debian/countmin.c
--- ntop-4.99.3+ndpi5517+dfsg1/debian/countmin.c	1969-12-31 16:00:00.000000000 -0800
+++ ntop-4.99.3+ndpi5517+dfsg2/debian/countmin.c	2012-11-30 00:37:15.000000000 -0800
@@ -0,0 +1,788 @@
+/********************************************************************
+Count-Min Sketches
+
+G. Cormode 2003,2004, 2010, 2012
+
+Updated: 2004-06 Added a floating point sketch and support for
+                 inner product point estimation
+Initial version: 2003-12
+
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*********************************************************************/
+
+#include <stdlib.h>
+#include "prng.h"
+#include "countmin.h"
+
+#define min(x,y)	((x) < (y) ? (x) : (y))
+#define max(x,y)	((x) > (y) ? (x) : (y))
+
+double eps;	               /* 1+epsilon = approximation factor */
+double delta;                  /* probability of failure */
+
+/************************************************************************/
+/* Routines to support Count-Min sketches                               */
+/************************************************************************/
+
+CM_type * CM_Init(int width, int depth, int seed)
+{     // Initialize the sketch based on user-supplied size
+  CM_type * cm;
+  int j;
+  prng_type * prng;
+
+  cm=(CM_type *) malloc(sizeof(CM_type));
+  prng=prng_Init(-abs(seed),2);
+  // initialize the generator to pick the hash functions
+
+  if (cm && prng)
+    {
+      cm->depth=depth;
+      cm->width=width;
+      cm->count=0;
+      cm->counts=(int **)calloc(sizeof(int *),cm->depth);
+      cm->counts[0]=(int *)calloc(sizeof(int), cm->depth*cm->width);
+      cm->hasha=(unsigned int *)calloc(sizeof(unsigned int),cm->depth);
+      cm->hashb=(unsigned int *)calloc(sizeof(unsigned int),cm->depth);
+      if (cm->counts && cm->hasha && cm->hashb && cm->counts[0])
+	{
+	  for (j=0;j<depth;j++)
+	    {
+	      cm->hasha[j]=prng_int(prng) & MOD;
+	      cm->hashb[j]=prng_int(prng) & MOD;
+	      // pick the hash functions
+	      cm->counts[j]=(int *) cm->counts[0]+(j*cm->width);
+	    }
+	}
+      else cm=NULL;
+    }
+  if (prng)
+      prng_Destroy(prng);
+  return cm;
+}
+
+CM_type * CM_Copy(CM_type * cmold)
+{     // create a new sketch with the same parameters as an existing one
+  CM_type * cm;
+  int j;
+
+  if (!cmold) return(NULL);
+  cm=(CM_type *) malloc(sizeof(CM_type));
+  if (cm)
+    {
+      cm->depth=cmold->depth;
+      cm->width=cmold->width;
+      cm->count=0;
+      cm->counts=(int **)calloc(sizeof(int *),cm->depth);
+      cm->counts[0]=(int *)calloc(sizeof(int), cm->depth*cm->width);
+      cm->hasha=(unsigned int *)calloc(sizeof(unsigned int),cm->depth);
+      cm->hashb=(unsigned int *)calloc(sizeof(unsigned int),cm->depth);
+      if (cm->counts && cm->hasha && cm->hashb && cm->counts[0])
+	{
+	  for (j=0;j<cm->depth;j++)
+	    {
+	      cm->hasha[j]=cmold->hasha[j];
+	      cm->hashb[j]=cmold->hashb[j];
+	      cm->counts[j]=(int *) cm->counts[0]+(j*cm->width);
+	    }
+	}
+      else cm=NULL;
+    }
+  return cm;
+}
+
+void CM_Destroy(CM_type * cm)
+{     // get rid of a sketch and free up the space
+  if (!cm) return;
+  if (cm->counts)
+    {
+      if (cm->counts[0]) free(cm->counts[0]);
+      free(cm->counts);
+      cm->counts=NULL;
+    }
+  if (cm->hasha) free(cm->hasha); cm->hasha=NULL;
+  if (cm->hashb) free(cm->hashb); cm->hashb=NULL;
+  free(cm);  cm=NULL;
+}
+
+int CM_Size(CM_type * cm)
+{ // return the size of the sketch in bytes
+  int counts, hashes, admin;
+  if (!cm) return 0;
+  admin=sizeof(CM_type);
+  counts=cm->width*cm->depth*sizeof(int);
+  hashes=cm->depth*2*sizeof(unsigned int);
+  return(admin + hashes + counts);
+}
+
+void CM_Update(CM_type * cm, unsigned int item, int diff)
+{
+  int j;
+
+  if (!cm) return;
+  cm->count+=diff;
+  for (j=0;j<cm->depth;j++)
+    cm->counts[j][hash31(cm->hasha[j],cm->hashb[j],item) % cm->width]+=diff;
+  // this can be done more efficiently if the width is a power of two
+}
+
+int CM_PointEst(CM_type * cm, unsigned int query)
+{
+  // return an estimate of the count of an item by taking the minimum
+  int j, ans;
+
+  if (!cm) return 0;
+  ans=cm->counts[0][hash31(cm->hasha[0],cm->hashb[0],query) % cm->width];
+  for (j=1;j<cm->depth;j++)
+    ans=min(ans,cm->counts[j][hash31(cm->hasha[j],cm->hashb[j],query)%cm->width]);
+  // this can be done more efficiently if the width is a power of two
+  return (ans);
+}
+
+#if 0
+int CM_PointMed(CM_type * cm, unsigned int query)
+{
+  // return an estimate of the count by taking the median estimate
+  // useful when counts can become negative
+  // depth needs to be larger for this to work well
+  int j, * ans, result=0;
+
+  if (!cm) return 0;
+  ans=(int *) calloc(1+cm->depth,sizeof(int));
+  for (j=0;j<cm->depth;j++)
+    ans[j+1]=cm->counts[j][hash31(cm->hasha[j],cm->hashb[j],query)%cm->width];
+
+  if (cm->depth==1)
+    result=ans[1];
+  else
+    if (cm->depth==2)
+      {
+	//result=(ans[1]+ans[2])/2;
+	if (abs(ans[1]) < abs(ans[2]))
+	  result=ans[1]; else result=ans[2];
+	// special tweak for small depth sketches
+      }
+    else
+      result=(MedSelect(1+cm->depth/2,cm->depth,ans));
+  return result;
+  // need to adjust for routine starting at 1
+}
+#endif
+
+int CM_Compatible(CM_type * cm1, CM_type * cm2)
+{ // test whether two sketches are comparable (have same parameters)
+  int i;
+  if (!cm1 || !cm2) return 0;
+  if (cm1->width!=cm2->width) return 0;
+  if (cm1->depth!=cm2->depth) return 0;
+  for (i=0;i<cm1->depth;i++)
+    {
+      if (cm1->hasha[i]!=cm2->hasha[i]) return 0;
+      if (cm1->hashb[i]!=cm2->hashb[i]) return 0;
+    }
+  return 1;
+}
+
+long long CM_InnerProd(CM_type * cm1, CM_type * cm2)
+{ // Estimate the inner product of two vectors by comparing their sketches
+  int i,j;
+  long long result, tmp;
+
+  result=0;
+  if (CM_Compatible(cm1,cm2))
+    {
+      for (i=0;i<cm1->width;i++)
+	result+=cm1->counts[0][i]*cm2->counts[0][i];
+      for (j=1;j<cm1->depth;j++)
+	{
+	  tmp=0;
+	  for (i=0;i<cm1->width;i++)
+	    tmp+=cm1->counts[j][i]*cm2->counts[j][i];
+	  result=min(tmp,result);
+	}
+    }
+  return result;
+}
+
+#if 0
+long long CM_F2Est(CM_type * cm)
+{ // Estimate the second frequency moment of the stream
+  int i,j;
+  long long result, tmp, *ans;
+
+  if (!cm) return 0;
+  ans=(long long *) calloc(1+cm->depth,sizeof(long long));
+
+  for (j=0;j<cm->depth;j++)
+    {
+      result=0;
+      for (i=0;i<cm->width;i+=2)
+	{
+	  tmp=(cm->counts[j][i]-cm->counts[j][i+1]);
+	  result+=tmp*tmp;
+	}
+      ans[j+1]=result;
+    }
+  result=LLMedSelect((cm->depth+1)/2,cm->depth,ans);
+  return result;
+}
+#endif
+
+int CM_Residue(CM_type * cm, unsigned int * Q)
+{
+// CM_Residue computes the sum of everything left after the points
+// from Q have been removed
+// Q is a list of points, where Q[0] gives the length of the list
+
+  char * bitmap;
+  int i,j;
+  int estimate=0, nextest;
+
+  if (!cm) return 0;
+  bitmap=(char *) calloc(cm->width,sizeof(char));
+  for (j=0;j<cm->depth;j++)
+    {
+      nextest=0;
+      for (i=0;i<cm->width;i++)
+	bitmap[i]=0;
+      for (i=1;i<(int) Q[0];i++)
+	bitmap[hash31(cm->hasha[j],cm->hashb[j],Q[i]) % cm->width]=1;
+      for (i=0;i<cm->width;i++)
+	if (bitmap[i]==0) nextest+=cm->counts[j][i];
+      estimate=max(estimate,nextest);
+    }
+  return(estimate);
+}
+
+/************************************************************************/
+/* Routines to support Count-Min sketches with floating point data      */
+/************************************************************************/
+
+CMF_type * CMF_Init(int width, int depth, int seed)
+{     // Initialize the sketch based on user-supplied size
+  CMF_type * cm;
+  int j;
+  prng_type * prng;
+
+  cm=(CMF_type *) malloc(sizeof(CMF_type));
+
+  prng=prng_Init(-abs(seed),2);
+  // initialize the generator to pick the hash functions
+
+  if (cm && prng)
+    {
+      cm->depth=depth;
+      cm->width=width;
+      cm->count=0;
+      cm->counts=(double **)calloc(sizeof(double *),cm->depth);
+      cm->counts[0]=(double *)calloc(sizeof(double), cm->depth*cm->width);
+      cm->hasha=(unsigned int *)calloc(sizeof(unsigned int),cm->depth);
+      cm->hashb=(unsigned int *)calloc(sizeof(unsigned int),cm->depth);
+      if (cm->counts && cm->hasha && cm->hashb && cm->counts[0])
+	{
+	  for (j=0;j<depth;j++)
+	    {
+	      cm->hasha[j]=prng_int(prng) & MOD;
+	      cm->hashb[j]=prng_int(prng) & MOD;
+	      // pick the hash functions
+	      cm->counts[j]=(double *) cm->counts[0]+(j*cm->width);
+	    }
+	}
+      else cm=NULL;
+    }
+  if (prng)
+      prng_Destroy(prng);
+  return cm;
+}
+
+CMF_type * CMF_Copy(CMF_type * cmold)
+{     // create a new sketch with the same parameters as an existing one
+  CMF_type * cm;
+  int j;
+
+  if (!cmold) return(NULL);
+  cm=(CMF_type *) malloc(sizeof(CMF_type));
+  if (cm)
+    {
+      cm->depth=cmold->depth;
+      cm->width=cmold->width;
+      cm->count=0;
+      cm->counts=(double **)calloc(sizeof(double *),cm->depth);
+      cm->counts[0]=(double *)calloc(sizeof(double), cm->depth*cm->width);
+      cm->hasha=(unsigned int *)calloc(sizeof(unsigned int),cm->depth);
+      cm->hashb=(unsigned int *)calloc(sizeof(unsigned int),cm->depth);
+      if (cm->counts && cm->hasha && cm->hashb && cm->counts[0])
+	{
+	  for (j=0;j<cm->depth;j++)
+	    {
+	      cm->hasha[j]=cmold->hasha[j];
+	      cm->hashb[j]=cmold->hashb[j];
+	      cm->counts[j]=(double *) cm->counts[0]+(j*cm->width);
+	    }
+	}
+      else cm=NULL;
+    }
+  return cm;
+}
+
+void CMF_Destroy(CMF_type * cm)
+{     // get rid of a sketch and free up the space
+  if (!cm) return;
+  if (cm->counts)
+    {
+      if (cm->counts[0]) free(cm->counts[0]);
+      free(cm->counts);
+      cm->counts=NULL;
+    }
+  if (cm->hasha) free(cm->hasha); cm->hasha=NULL;
+  if (cm->hashb) free(cm->hashb); cm->hashb=NULL;
+  free(cm);  cm=NULL;
+}
+
+int CMF_Size(CMF_type * cm)
+{ // return the size of the sketch in bytes
+  int counts, hashes, admin;
+  if (!cm) return 0;
+  admin=sizeof(CM_type);
+  counts=cm->width*cm->depth*sizeof(double);
+  hashes=cm->depth*2*sizeof(unsigned int);
+  return(admin + hashes + counts);
+}
+
+void CMF_Update(CMF_type * cm, unsigned int item, double diff)
+{
+  int j;
+
+  if (!cm) return;
+  cm->count+=diff;
+  for (j=0;j<cm->depth;j++)
+    cm->counts[j][hash31(cm->hasha[j],cm->hashb[j],item) % cm->width]+=diff;
+  // this can be done more efficiently if the width is a power of two
+}
+
+double CMF_PointEst(CMF_type * cm, unsigned int query)
+{
+  // return an estimate of the count of an item by taking the minimum
+  int j;
+  double ans=0.;
+
+  if (!cm) return 0;
+  ans=cm->counts[0][hash31(cm->hasha[0],cm->hashb[0],query) % cm->width];
+  for (j=1;j<cm->depth;j++)
+    ans=min(ans,cm->counts[j][hash31(cm->hasha[j],cm->hashb[j],query)%cm->width]);
+  // this can be done more efficiently if the width is a power of two
+  return (ans);
+}
+
+int CMF_Compatible(CMF_type * cm1, CMF_type * cm2)
+{ // test whether two sketches are comparable (have same parameters)
+  int i;
+  if (!cm1 || !cm2) return 0;
+  if (cm1->width!=cm2->width) return 0;
+  if (cm1->depth!=cm2->depth) return 0;
+  for (i=0;i<cm1->depth;i++)
+    {
+      if (cm1->hasha[i]!=cm2->hasha[i]) return 0;
+      if (cm1->hashb[i]!=cm2->hashb[i]) return 0;
+    }
+  return 1;
+}
+
+double CMF_PointProd(CMF_type * cm1, CMF_type * cm2, unsigned int query)
+{ // Estimate the inner product of two vectors by comparing their sketches
+  int j, loc;
+  double tmp, ans;
+
+  ans=0.0;
+  if (CMF_Compatible(cm1,cm2))
+    {
+      loc=hash31(cm1->hasha[0],cm1->hashb[0],query) % cm1->width;
+      ans=cm1->counts[0][loc]*cm2->counts[0][loc];
+      for (j=1;j<cm1->depth;j++)
+	{
+	  loc=hash31(cm1->hasha[j],cm1->hashb[j],query) % cm1->width;
+	  tmp=cm1->counts[j][loc]*cm2->counts[j][loc];
+	  ans=min(ans,tmp);
+	}
+    }
+  return (ans);
+}
+
+double CMF_InnerProd(CMF_type * cm1, CMF_type * cm2)
+{ // Estimate the inner product of two vectors by comparing their sketches
+  int i,j;
+  double tmp, result;
+
+  result=0;
+  if (CMF_Compatible(cm1,cm2))
+    {
+      for (i=0;i<cm1->width;i++)
+	result+=cm1->counts[0][i]*cm2->counts[0][i];
+      for (j=1;j<cm1->depth;j++)
+	{
+	  tmp=0.0;
+	  for (i=0;i<cm1->width;i++)
+	    tmp+=cm1->counts[j][i]*cm2->counts[j][i];
+	  result=min(tmp,result);
+	}
+    }
+  return result;
+}
+
+/************************************************************************/
+/* Routines to support hierarchical Count-Min sketches                  */
+/************************************************************************/
+
+CMH_type * CMH_Init(int width, int depth, int U, int gran)
+{
+  // initialize a hierarchical set of sketches for range queries
+  // heavy hitters or quantiles
+
+  CMH_type * cmh;
+  int i,j,k;
+  prng_type * prng;
+
+  if (U<=0 || U>32) return(NULL);
+  // U is the log the size of the universe in bits
+
+  if (gran>U || gran<1) return(NULL);
+  // gran is the granularity to look at the universe in
+  // check that the parameters make sense...
+
+  cmh=(CMH_type *) calloc(1,sizeof(CMH_type));
+
+  prng=prng_Init(-12784,2);
+  // initialize the generator for picking the hash functions
+
+  if (cmh && prng)
+    {
+      cmh->depth=depth;
+      cmh->width=width;
+      cmh->count=0;
+      cmh->U=U;
+      cmh->gran=gran;
+      cmh->levels=(int) ceil(((float) U)/((float) gran));
+      for (j=0;j<cmh->levels;j++)
+	if ((long long) 1<<(cmh->gran*j) <= cmh->depth*cmh->width)
+	  cmh->freelim=j;
+      //find the level up to which it is cheaper to keep exact counts
+      cmh->freelim=cmh->levels-cmh->freelim;
+
+      cmh->counts=(int **) calloc(sizeof(int *), 1+cmh->levels);
+      cmh->hasha=(unsigned int **)calloc(sizeof(unsigned int *),1+cmh->levels);
+      cmh->hashb=(unsigned int **)calloc(sizeof(unsigned int *),1+cmh->levels);
+      j=1;
+      for (i=cmh->levels-1;i>=0;i--)
+	{
+	  if (i>=cmh->freelim)
+	    { // allocate space for representing things exactly at high levels
+	      cmh->counts[i]=(int *) calloc(1<<(cmh->gran*j),sizeof(int));
+	      j++;
+	      cmh->hasha[i]=NULL;
+	      cmh->hashb[i]=NULL;
+	    }
+	  else
+	    { // allocate space for a sketch
+	      cmh->counts[i]=(int *)calloc(sizeof(int), cmh->depth*cmh->width);
+	      cmh->hasha[i]=(unsigned int *)
+		calloc(sizeof(unsigned int),cmh->depth);
+	      cmh->hashb[i]=(unsigned int *)
+		calloc(sizeof(unsigned int),cmh->depth);
+
+	      if (cmh->hasha[i] && cmh->hashb[i])
+		for (k=0;k<cmh->depth;k++)
+		  { // pick the hash functions
+		    cmh->hasha[i][k]=prng_int(prng) & MOD;
+		    cmh->hashb[i][k]=prng_int(prng) & MOD;
+		  }
+	    }
+	}
+    }
+  if (prng)
+      prng_Destroy(prng);
+  return cmh;
+}
+
+void CMH_Destroy(CMH_type * cmh)
+{  // free up the space
+  int i;
+  if (!cmh) return;
+  for (i=0;i<cmh->levels;i++)
+    {
+      if (i>=cmh->freelim)
+	{
+	  free(cmh->counts[i]);
+	}
+      else
+	{
+	  free(cmh->hasha[i]);
+	  free(cmh->hashb[i]);
+	  free(cmh->counts[i]);
+	}
+    }
+  free(cmh->counts);
+  free(cmh->hasha);
+  free(cmh->hashb);
+  free(cmh);
+  cmh=NULL;
+}
+
+void CMH_Update(CMH_type * cmh, unsigned int item, int diff)
+{ // update with a new value
+  int i,j,offset;
+
+  if (!cmh) return;
+  cmh->count+=diff;
+  for (i=0;i<cmh->levels;i++)
+    {
+      offset=0;
+      if (i>=cmh->freelim)
+	{ // level 0 = leaves, higher levels = internal nodes
+	  cmh->counts[i][item]+=diff;
+	  // keep exact counts at high levels in the hierarchy
+	}
+      else
+	for (j=0;j<cmh->depth;j++)
+	  {
+	    cmh->counts[i][(hash31(cmh->hasha[i][j],cmh->hashb[i][j],item)
+			    % cmh->width) + offset]+=diff;
+	    // this can be done more efficiently if the width is a power of two
+	    offset+=cmh->width;
+	  }
+      item>>=cmh->gran;
+    }
+}
+
+int CMH_Size(CMH_type * cmh)
+{ // return the size used in bytes
+  int counts, hashes, admin,i;
+  if (!cmh) return 0;
+  admin=sizeof(CMH_type);
+  counts=cmh->levels*sizeof(int **);
+  for (i=0;i<cmh->levels;i++)
+    if (i>=cmh->freelim)
+      counts+=(1<<(cmh->gran*(cmh->levels-i)))*sizeof(int);
+    else
+      counts+=cmh->width*cmh->depth*sizeof(int);
+  hashes=(cmh->levels-cmh->freelim)*cmh->depth*2*sizeof(unsigned int);
+  hashes+=(cmh->levels)*sizeof(unsigned int *);
+  return(admin + hashes + counts);
+}
+
+int CMH_count(CMH_type * cmh, int depth, unsigned int item)
+{
+  // return an estimate of item at level depth
+
+  int j;
+  int offset;
+  int estimate;
+
+  if (depth>=cmh->levels) return(cmh->count);
+  if (depth>=cmh->freelim)
+    { // use an exact count if there is one
+      return(cmh->counts[depth][item]);
+    }
+  // else, use the appropriate sketch to make an estimate
+  offset=0;
+  estimate=cmh->counts[depth][(hash31(cmh->hasha[depth][0],
+				      cmh->hashb[depth][0],item)
+			       % cmh->width) + offset];
+  for (j=1;j<cmh->depth;j++)
+    {
+      offset+=cmh->width;
+      estimate=min(estimate,
+		   cmh->counts[depth][(hash31(cmh->hasha[depth][j],
+					      cmh->hashb[depth][j],item)
+				       % cmh->width) + offset]);
+    }
+  return(estimate);
+}
+
+void CMH_recursive(CMH_type * cmh, int depth, int start,
+		    int thresh, unsigned int * results)
+{
+  // for finding heavy hitters, recursively descend looking
+  // for ranges that exceed the threshold
+
+  int i;
+  int blocksize;
+  int estcount;
+  int itemshift;
+
+  estcount=CMH_count(cmh,depth,start);
+  if (estcount>=thresh)
+    {
+      if (depth==0)
+	{
+	  if (results[0]<(unsigned int) cmh->width)
+	    {
+	      results[0]++;
+	      results[results[0]]=start;
+	    }
+	}
+      else
+	{
+	  blocksize=1<<cmh->gran;
+	  itemshift=start<<cmh->gran;
+	  // assumes that gran is an exact multiple of the bit dept
+	  for (i=0;i<blocksize;i++)
+	    CMH_recursive(cmh,depth-1,itemshift+i,thresh,results);
+	}
+    }
+}
+
+unsigned int * CMH_FindHH(CMH_type * cmh, int thresh)
+{ // find all items whose estimated count is greater than phi n
+
+  unsigned int * results;
+  results=(unsigned int *) calloc(cmh->width,sizeof(unsigned int));
+  results[0]=0;
+
+  CMH_recursive(cmh,cmh->levels,0,thresh,results);
+  return(results);
+}
+
+int CMH_Rangesum(CMH_type * cmh, long long start, long long end)
+{
+  // compute a range sum:
+  // start at bottom level
+  // compute any estimates needed at each level
+  // work upwards
+
+  int depth, result;
+  long long range, leftend, rightend;
+  long long topend, i;
+
+  topend=((long long) 1)<<cmh->U;
+  end=min(topend,end);
+  if ((end>topend) && (start==0)) {
+    return cmh->count;
+  }
+
+  end+=1; // adjust for end effects
+  result=0;
+  for (depth=0;depth<=cmh->levels;depth++)
+    {
+      if (start==end) break;
+      range=(end-start+1);
+      if ((unsigned int) (end-start+1)<(((unsigned int) 1)<<cmh->gran))
+	{ // if only a few nodes to probe at this level, probe them all
+	  for (i=start;i<end;i++)
+	    result+=CMH_count(cmh,depth,i);
+	  break;
+	}
+      else
+	{  // figure out what needs to be done at each end
+	  leftend=(((start>>cmh->gran)+1)<<cmh->gran) - start;
+	  if (leftend>= 1<<cmh->gran) leftend=0;
+	  rightend=(end)-((end>>cmh->gran)<<cmh->gran);
+	  if ((leftend>0) && (start<end))
+	    for (i=0;i<leftend;i++)
+	      {
+		result+=CMH_count(cmh,depth,start+i);
+	      }
+	  if ((rightend>0) && (start<end))
+	    for (i=0;i<rightend;i++)
+	      {
+		result+=CMH_count(cmh,depth,end-i-1);
+	      }
+	  start=start>>cmh->gran;
+	  if (leftend>0) start++;
+	  end=end>>cmh->gran;
+	}
+    }
+  return result;
+}
+
+long long CMH_FindRange(CMH_type * cmh, int sum)
+{
+  long long low, high, mid=0;
+  int i, est=0;
+  // find a range starting from zero that adds up to sum
+
+  if (cmh->count<sum) return 1<<(cmh->U);
+  low=0;
+  high=((long long) 1)<<cmh->U;
+
+  for (i=0;i<cmh->U;i++)
+    {
+      mid=(low+high)/2;
+      est=CMH_Rangesum(cmh,0,(unsigned int) mid);
+      if (est>sum)
+	high=mid;
+      else
+	low=mid;
+    }
+  return mid;
+
+}
+
+long long CMH_AltFindRange(CMH_type * cmh, int sum)
+{
+  long long low, high, mid=0,top;
+  int i, est=0;
+  // find a range starting from the right hand side that adds up to sum
+
+  if (cmh->count<sum) return 1<<(cmh->U);
+  low=0;
+  top=((long long) 1)<<cmh->U;
+  high=top;
+  for (i=0;i<cmh->U;i++) {
+      mid=(low+high)/2;
+      est=CMH_Rangesum(cmh,mid,top);
+      if (est<sum)
+	high=mid;
+      else
+	low=mid;
+    }
+  return mid;
+
+}
+
+long long CMH_Quantile(CMH_type * cmh, float frac)
+{
+  // find a quantile by doing the appropriate range search
+  if (frac<0) return 0;
+  if (frac>1)
+    return 1<<cmh->U;
+  return ((CMH_FindRange(cmh,(long long) (cmh->count*frac))+
+	   CMH_AltFindRange(cmh,(long long) (cmh->count*(1-frac))))/2);
+  // each result gives a lower/upper bound on the location of the quantile
+  // with high probability, these will be close: only a small number of values
+  // will be between the estimates.
+}
+
+long long CMH_F2Est(CMH_type * cmh)
+{
+  // A heuristic for estimating the F2 of a stream
+  // tends to overestimate a great deal on non-skewed streams
+
+  int i,j,k;
+  long long est, result;
+
+  k=0; result=-1;
+  for (i=0;i<cmh->depth;i++)
+    {
+      est=0;
+      for (j=0;j<cmh->width;j++)
+	{
+	  est+=(long long) cmh->counts[0][k] * (long long) cmh->counts[0][k];
+	  k++;
+	}
+      if (result<0) result=est; else
+	result=min(result,est);
+    }
+  return result;
+}
diff -Nru ntop-4.99.3+ndpi5517+dfsg1/debian/countmin.h ntop-4.99.3+ndpi5517+dfsg2/debian/countmin.h
--- ntop-4.99.3+ndpi5517+dfsg1/debian/countmin.h	1969-12-31 16:00:00.000000000 -0800
+++ ntop-4.99.3+ndpi5517+dfsg2/debian/countmin.h	2012-11-30 00:37:15.000000000 -0800
@@ -0,0 +1,67 @@
+// Two different structures: 
+//   1 -- The basic CM Sketch
+//   2 -- The hierarchical CM Sketch: with log n levels, for range sums etc. 
+
+#define min(x,y)	((x) < (y) ? (x) : (y))
+#define max(x,y)	((x) > (y) ? (x) : (y))
+
+typedef struct CM_type{
+  long long count;
+  int depth;
+  int width;
+  int ** counts;
+  unsigned int *hasha, *hashb;
+} CM_type;
+
+typedef struct CMF_type{ // shadow of above stucture with floats
+  double count;
+  int depth;
+  int width;
+  double ** counts;
+  unsigned int *hasha, *hashb;
+} CMF_type;
+
+extern CM_type * CM_Init(int, int, int);
+extern CM_type * CM_Copy(CM_type *);
+extern void CM_Destroy(CM_type *);
+extern int CM_Size(CM_type *);
+
+extern void CM_Update(CM_type *, unsigned int, int); 
+extern int CM_PointEst(CM_type *, unsigned int);
+extern int CM_PointMed(CM_type *, unsigned int);
+extern long long CM_InnerProd(CM_type *, CM_type *);
+extern int CM_Residue(CM_type *, unsigned int *);
+extern long long CM_F2Est(CM_type *);
+
+extern CMF_type * CMF_Init(int, int, int);
+extern CMF_type * CMF_Copy(CMF_type *);
+extern void CMF_Destroy(CMF_type *);
+extern int CMF_Size(CMF_type *);
+extern void CMF_Update(CMF_type *, unsigned int, double); 
+extern double CMF_InnerProd(CMF_type *, CMF_type *);
+extern double CMF_PointProd(CMF_type *, CMF_type *, unsigned int);
+
+typedef struct CMH_type{
+  long long count;
+  int U; // size of the universe in bits
+  int gran; // granularity: eg 1, 4 or 8 bits
+  int levels; // function of U and gran
+  int freelim; // up to which level to keep exact counts
+  int depth;
+  int width;
+  int ** counts;
+  unsigned int **hasha, **hashb;
+} CMH_type;
+
+extern CMH_type * CMH_Init(int, int, int, int);
+extern CMH_type * CMH_Copy(CMH_type *);
+extern void CMH_Destroy(CMH_type *);
+extern int CMH_Size(CMH_type *);
+
+extern void CMH_Update(CMH_type *, unsigned int, int);
+extern unsigned int * CMH_FindHH(CMH_type *, int);
+extern int CMH_Rangesum(CMH_type *, long long, long long);
+
+extern long long CMH_FindRange(CMH_type * cmh, int);
+extern long long CMH_Quantile(CMH_type *cmh,float);
+extern long long CMH_F2Est(CMH_type *);
diff -Nru ntop-4.99.3+ndpi5517+dfsg1/debian/get-orig-source.sh ntop-4.99.3+ndpi5517+dfsg2/debian/get-orig-source.sh
--- ntop-4.99.3+ndpi5517+dfsg1/debian/get-orig-source.sh	2012-06-27 00:25:38.000000000 -0700
+++ ntop-4.99.3+ndpi5517+dfsg2/debian/get-orig-source.sh	2012-11-30 00:37:15.000000000 -0800
@@ -8,6 +8,8 @@
 
 UPSTREAM_DIR=$(echo -n $DEB_UPSTREAM_VERSION | sed -e 's/+rc[0-9]*//')
 
+curdir=$(dirname $0)
+
 if [ ! -f ../ntop_$DEB_SOURCE_VERSION.orig.tar.gz ]; then
     uscan --noconf --force-download --rename --download-current-version --destdir=.
     rm -rf ntop-$DEB_UPSTREAM_VERSION
@@ -23,6 +25,13 @@
     # remove binary-onyl files from MaxMind
     rm ntop-$UPSTREAM_DIR/3rd_party/Geo*.dat.gz
 
+    # replace non-DFSG countmin with the GPL one
+    rm ntop-$UPSTREAM_DIR/countmin.[ch]
+    rm ntop-$UPSTREAM_DIR/prng.[ch]
+
+    cp $curdir/countmin.[ch] ntop-$UPSTREAM_DIR/
+    cp $curdir/prng.[ch] ntop-$UPSTREAM_DIR/
+
     # remove non-DFSG-compliant part of ntop.h
     ed ntop-$UPSTREAM_DIR/ntop.h > /dev/null <<EOF
 /Declaration of POSIX directory browsing functions and types for Win32.
diff -Nru ntop-4.99.3+ndpi5517+dfsg1/debian/prng.c ntop-4.99.3+ndpi5517+dfsg2/debian/prng.c
--- ntop-4.99.3+ndpi5517+dfsg1/debian/prng.c	1969-12-31 16:00:00.000000000 -0800
+++ ntop-4.99.3+ndpi5517+dfsg2/debian/prng.c	2012-11-30 00:37:15.000000000 -0800
@@ -0,0 +1,525 @@
+/*********************************************************************
+
+prng: pseudo-random number generators and hashing routines
+
+G. Cormode 2003-2012
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+************************************************************************/
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "prng.h"
+
+#define PI 3.141592653589793
+
+long hash31(long long a, long long b, long long x)
+{
+
+  long long result;
+  long lresult;
+
+  // return a hash of x using a and b mod (2^31 - 1)
+// may need to do another mod afterwards, or drop high bits
+// depending on d, number of bad guys
+// 2^31 - 1 = 2147483647
+
+  //  result = ((long long) a)*((long long) x)+((long long) b);
+  result=(a * x) + b;
+  result = ((result >> HL) + result) & MOD;
+  lresult=(long) result;
+
+  return(lresult);
+}
+
+long fourwise(long long a, long long b, long long c, long long d, long long x)
+{
+  long long result;
+  long lresult;
+
+  // returns values that are 4-wise independent by repeated calls
+  // to the pairwise indpendent routine.
+
+  result = hash31(hash31(hash31(a,b,x),c,x),d,x);
+  lresult = (long) result;
+  return lresult;
+}
+
+
+/*************************************************************************/
+/* First, some pseudo-random number generators sourced from other places */
+/*************************************************************************/
+
+// There are *THREE* alternate implementations of PRNGs here.
+// One taken from Numerical Recipes in C, the second from www.agner.org
+// The third is an internal C random library, srand
+// The variable usenric controls which one is used: pick one
+// and stick with it, switching between the two will give unpredictable
+// results.  This is controlled by the randinit procedure, call it with
+// usenric == 1 to use the Numerical Recipes gens
+// usenric == 2 to use the agner.org PRNGs or
+// usenric == 3 to use the inbuilt C routines
+
+// from the math library:
+extern double sqrt(double);
+
+// following definitions needed for the random number generator
+#define IA 16807
+#define IM 2147483647
+#define AM (1.0/IM)
+#define IQ 127773
+#define IR 2836
+#define NDIV (1+(IM-1)/NTAB)
+#define EPS 1.2e-7
+#define RNMX (1.0-EPS)
+
+float ran1(prng_type * prng) {
+
+  // A Random Number Generator that picks a uniform [0,1] random number
+  // From Numerical Recipes, page 280
+  // Should be called with a NEGATIVE value of idum to initialize
+  // subsequent calls should not alter idum
+
+  int j;
+  long k;
+  float temp;
+
+  if (prng->floatidum <= 0 || !prng->iy) {
+    if (-(prng->floatidum) < 1) prng->floatidum=1;
+    else prng->floatidum = -(prng->floatidum);
+    for (j=NTAB+7;j>=0;j--) {
+      k=(prng->floatidum)/IQ;
+      prng->floatidum=IA*(prng->floatidum-k*IQ)-IR*k;
+      if (prng->floatidum < 0) prng->floatidum+=IM;
+      if (j<NTAB) prng->iv[j]=prng->floatidum;
+    }
+    prng->iy=prng->iv[0];
+  }
+  k = (prng->floatidum)/IQ;
+  prng->floatidum=IA*(prng->floatidum-k*IQ)-IR*k;
+  if (prng->floatidum<0) prng->floatidum += IM;
+  j = prng->iy/NDIV;
+  prng->iy=prng->iv[j];
+  prng->iv[j]=prng->floatidum;
+  if ((temp=AM*prng->iy) > RNMX) return RNMX;
+  else return temp;
+}
+
+long ran2(prng_type * prng) {
+
+  // A Random Number Generator that picks a uniform random number
+  // from the range of long integers.
+  // From Numerical Recipes, page 280
+  // Should be called with a NEGATIVE value of idum to initialize
+  // subsequent calls should not alter idum
+  // This is a hacked version of the above procedure, so proceed with
+  // caution.
+
+  int j;
+  long k;
+
+  if (prng->intidum <= 0 || !prng->iy) {
+    if (-(prng->intidum) < 1) prng->intidum=1;
+    else prng->intidum = -(prng->intidum);
+    for (j=NTAB+7;j>=0;j--) {
+      k=(prng->intidum)/IQ;
+      prng->intidum=IA*(prng->intidum-k*IQ)-IR*k;
+      if (prng->intidum < 0) prng->intidum+=IM;
+      if (j<NTAB) prng->iv[j]=prng->intidum;
+    }
+    prng->iy=prng->iv[0];
+  }
+  k = (prng->intidum)/IQ;
+  prng->intidum=IA*(prng->intidum-k*IQ)-IR*k;
+  if (prng->intidum<0) prng->intidum += IM;
+  j = prng->iy/NDIV;
+  prng->iy=prng->iv[j];
+  prng->iv[j]=prng->intidum;
+  return prng->iy;
+}
+
+/**********************************************************************/
+
+// Following routines are from www.agner.org
+
+/************************* RANROTB.C ******************** AgF 1999-03-03 *
+*  Random Number generator 'RANROT' type B                               *
+*                                                                        *
+*  This is a lagged-Fibonacci type of random number generator with       *
+*  rotation of bits.  The algorithm is:                                  *
+*  X[n] = ((X[n-j] rotl r1) + (X[n-k] rotl r2)) modulo 2^b               *
+*                                                                        *
+*  The last k values of X are stored in a circular buffer named          *
+*  randbuffer.                                                           *
+*                                                                        *
+*  This version works with any integer size: 16, 32, 64 bits etc.        *
+*  The integers must be unsigned. The resolution depends on the integer  *
+*  size.                                                                 *
+*                                                                        *
+*  Note that the function RanrotAInit must be called before the first    *
+*  call to RanrotA or iRanrotA                                           *
+*                                                                        *
+*  The theory of the RANROT type of generators is described at           *
+*  www.agner.org/random/ranrot.htm                                       *
+*                                                                        *
+*************************************************************************/
+
+// this should be almost verbatim from the above webpage.
+// although it's been hacked with a little bit...
+
+unsigned long rotl (unsigned long x, unsigned long r) {
+  return (x << r) | (x >> (sizeof(x)*8-r));}
+
+/* define parameters (R1 and R2 must be smaller than the integer size): */
+#define JJ  10
+#define R1   5
+#define R2   3
+
+/* returns some random bits */
+unsigned long ran3(prng_type * prng) {
+
+  unsigned long x;
+
+  /* generate next random number */
+
+  x = prng->randbuffer[prng->r_p1] = rotl(prng->randbuffer[prng->r_p2], R1)
+    +  rotl(prng->randbuffer[prng->r_p1], R2);
+  /* rotate list pointers */
+  if (--prng->r_p1 < 0) prng->r_p1 = KK - 1;
+  if (--prng->r_p2 < 0) prng->r_p2 = KK - 1;
+  /* conversion to float */
+  return x;
+}
+
+/* returns a random number between 0 and 1 */
+double ran4(prng_type * prng) {
+
+  /* conversion to floating point type */
+  return (ran3(prng) * prng->scale);
+}
+
+/* this function initializes the random number generator.      */
+/* Must be called before the first call to RanrotA or iRanrotA */
+void RanrotAInit (prng_type * prng, unsigned long seed) {
+
+  int i;
+
+  /* put semi-random numbers into the buffer */
+  for (i=0; i<KK; i++) {
+    prng->randbuffer[i] = seed;
+    seed = rotl(seed,5) + 97;}
+
+  /* initialize pointers to circular buffer */
+  prng->r_p1 = 0;  prng->r_p2 = JJ;
+
+  /* randomize */
+  for (i = 0;  i < 300;  i++) ran3(prng);
+  prng->scale = ldexp(1, -8*sizeof(unsigned long));
+}
+
+
+/**********************************************************************/
+/* These are wrapper procedures for the uniform random number gens    */
+/**********************************************************************/
+
+long prng_int(prng_type * prng) {
+
+  // returns a pseudo-random long integer.  Initialise the generator
+  // before use!
+
+  long response=0;
+
+  switch (prng->usenric)
+    {
+    case 1 : response=(ran2(prng)); break;
+    case 2 : response=(ran3(prng)); break;
+    case 3 : response=(lrand48()); break;
+    }
+  return response;
+}
+
+
+float prng_float(prng_type * prng) {
+
+  // returns a pseudo-random float in the range [0.0,1.0].
+  // Initialise the generator before use!
+  float result=0;
+
+  switch (prng->usenric)
+    {
+    case 1 : result=(ran1(prng)); break;
+    case 2 : result=(ran4(prng)); break;
+    case 3 : result=(drand48()); break;
+    }
+  return result;
+}
+
+prng_type * prng_Init(long seed, int nric) {
+
+  // Initialise the random number generators.  nric determines
+  // which algorithm to use, 1 for Numerical Recipes in C,
+  // 0 for the other one.
+  prng_type * result;
+
+  result=(prng_type *) calloc(1,sizeof(prng_type));
+
+  result->iy=0;
+  result->usenric=nric;
+  result->floatidum=-1;
+  result->intidum=-1;
+  result->iset=0;
+  // set a global variable to record which algorithm to use
+  switch (nric)
+    {
+    case 2 :
+      RanrotAInit(result,seed);
+      break;
+    case 1 :
+      if (seed>0) {
+	// to initialise the NRiC PRNGs, call it with a negative value
+	// so make sure it gets a negative value!
+	result->floatidum = -(seed);  result->intidum = -(seed);
+      } else {
+	result->floatidum=seed; result->intidum=seed;
+      }
+      break;
+    case 3 :
+      srand48(seed);
+      break;
+    }
+
+  prng_float(result);
+  prng_int(result);
+  // call the routines to actually initialise them
+  return(result);
+}
+
+void prng_Reseed(prng_type * prng, long seed)
+{
+  switch (prng->usenric)
+    {
+    case 2 :
+      RanrotAInit(prng,seed);
+      break;
+    case 1 :
+      if (seed>0) {
+	// to initialise the NRiC PRNGs, call it with a negative value
+	// so make sure it gets a negative value!
+	prng->floatidum = -(seed);  prng->intidum = -(seed);
+      } else {
+	prng->floatidum=seed; prng->intidum=seed;
+      }
+      break;
+    case 3 :
+      srand48(seed);
+      break;
+    }
+}
+
+void prng_Destroy(prng_type * prng)
+{
+  free(prng);
+}
+
+/**********************************************************************/
+/* Next, a load of routines that convert uniform random variables     */
+/* from [0,1] to stable distribitions, such as gaussian, levy or      */
+/* general                                                            */
+/**********************************************************************/
+
+double prng_normal(prng_type * prng) {
+
+  // Pick random values distributed N(0,1) using the Box-Muller transform
+  // Taken from numerical recipes in C p289
+  // picks two at a time, returns one per call (buffers the other)
+
+  double fac,rsq,v1,v2;
+  if (prng->iset == 0) {
+    do {
+      v1 = 2.0*prng_float(prng)-1.0;
+      v2 = 2.0*prng_float(prng)-1.0;
+      rsq=v1*v1+v2*v2;
+    } while (rsq >= 1.0 || rsq == 0.0);
+
+    fac = sqrt((double) -2.0*log((double)rsq)/rsq);
+    prng->gset=v1*fac;
+    prng->iset=1;
+    return v2*fac;
+  }
+  else {
+    prng->iset = 0;
+    return prng->gset;
+  }
+}
+
+double prng_stabledbn(prng_type * prng, double alpha) {
+
+  // From 'stable distributions', John Nolan, manuscript, p24
+  // we set beta = 0 by analogy with the normal and cauchy case
+  // identical to the above routine, but returns a double instead
+  // of a long double (you'll see this a lot...)
+
+  double theta, W, holder, left, right;
+
+  theta=PI*(prng_float(prng) - 0.5);
+  W = -log(prng_float(prng)); // takes natural log
+
+  //  printf("theta %Lf, W = %Lf \n", theta, W);
+
+  // some notes on Nolan's notes:
+  // if beta == 0 then c(alpha,beta)=1; theta_0 = 0
+  // expression reduces to sin alpha.theta / (cos theta) ^1/alpha
+  //  * (cos (theta - alpha theta)/W) ^(1-alpha)/alpha
+  left = (sin(alpha*theta)/pow(cos(theta), 1.0/alpha));
+  right= pow(cos(theta*(1.0 - alpha))/W, ((1.0-alpha)/alpha));
+  holder=left*right;
+  return(holder);
+}
+
+
+long double prng_cauchy(prng_type * prng) {
+
+  // return a value from the cauchy distribution
+  // using the formula in 'Stable Distributions', p23
+  // this is distributed Cauchy(1,0)
+
+  return(tan(PI*(prng_float(prng) - 0.5)));
+}
+
+
+double prng_altstab(prng_type * prng, double p)
+{
+  double u,v,result;
+
+  u=prng_float(prng);
+  v=prng_float(prng);
+  result=pow(u,p);
+  // result=exp(p*log(u));
+  if (v<0.5) result=-result;
+  return(result);
+}
+
+
+/*
+long double levy() {
+
+  // this would give the levy distribution, except it doesn't get used
+
+  long double z;
+
+  z=gasdev();
+  return (1.0/(z*z));
+  }
+
+*/
+
+double prng_stable(prng_type * prng, double alpha) {
+
+  // wrapper for the stable distributions above:
+  // call the appropriate routine based on the value of alpha given
+  // initialising it with the seed in idum
+
+  // randinit must be called before entering this procedure for
+  // the first time since it uses the random generators
+
+
+  if (alpha==2.0)
+    return(prng_normal(prng));
+  else if (alpha==1.0)
+    return(prng_cauchy(prng));
+  else if (alpha<0.01)
+    return(prng_altstab(prng,-50.0));
+  else return (prng_stabledbn(prng,alpha));
+}
+
+double zeta(long n, double theta)
+{
+
+  // the zeta function, used by the below zipf function
+  // (this is not often called from outside this library)
+  // ... but have made it public now to speed things up
+
+  int i;
+  double ans=0.0;
+
+  for (i=1; i <= n; i++)
+    ans += pow(1./(double)i, theta);
+  return(ans);
+}
+
+double fastzipf(double theta, long n, double zetan, prng_type * prng) {
+
+  // this draws values from the zipf distribution
+  // this is mainly useful for test generation purposes
+  // n is range, theta is skewness parameter
+  // theta = 0 gives uniform dbn,
+  // theta > 1 gives highly skewed dbn.
+  // original code due to Flip Korn, used with permission
+
+	double alpha;
+	double eta;
+	double u;
+	double uz;
+	long double val;
+
+  // randinit must be called before entering this procedure for
+  // the first time since it uses the random generators
+
+	alpha = 1. / (1. - theta);
+	eta = (1. - pow(2./((double) n), 1. - theta))
+	  / (1. - zeta(2,theta)/zetan);
+
+	u = prng_float(prng);
+	uz = u * zetan;
+	if (uz < 1.) val = 1;
+	else if (uz < (1. + pow(0.5, theta))) val = 2;
+	else val = 1 + (long long)(n * pow(eta*u - eta + 1., alpha));
+
+	return(val);
+}
+
+/*
+long double zipf(double theta, long n) {
+
+  // this draws values from the zipf distribution
+  // this is mainly useful for test generation purposes
+  // n is range, theta is skewness parameter
+  // theta = 0 gives uniform dbn,
+  // theta > 1 gives highly skewed dbn.
+
+	double alpha;
+	double zetan;
+	double eta;
+	double u;
+	double uz;
+	long double val;
+
+  // randinit must be called before entering this procedure for
+  // the first time since it uses the random generators
+
+	alpha = 1. / (1. - theta);
+	zetan = zeta(n, theta);
+	eta = (1. - pow(2./n, 1. - theta)) / (1. - zeta(2.,theta)/zetan);
+
+	u = randomfl();
+	uz = u * zetan;
+	if (uz < 1.) val = 1;
+	else if (uz < (1. + pow(0.5, theta))) val = 2;
+	else val = 1 + (long long)(n * pow(eta*u - eta + 1., alpha));
+
+	return(val);
+}
+*/
diff -Nru ntop-4.99.3+ndpi5517+dfsg1/debian/prng.h ntop-4.99.3+ndpi5517+dfsg2/debian/prng.h
--- ntop-4.99.3+ndpi5517+dfsg1/debian/prng.h	1969-12-31 16:00:00.000000000 -0800
+++ ntop-4.99.3+ndpi5517+dfsg2/debian/prng.h	2012-11-30 00:37:15.000000000 -0800
@@ -0,0 +1,53 @@
+// Probabilistic Random Number Generators
+// Collected from various sources by Graham Cormode, 2000-2003
+// 
+
+#include <math.h>
+
+#ifndef _PRNG
+
+#define MOD 2147483647
+#define HL 31
+
+extern long hash31(long long, long long, long long);
+extern long fourwise(long long, long long, long long, long long, long long);
+
+#define KK  17
+#define NTAB 32
+
+typedef struct prng_type{
+  int usenric; // which prng to use
+  float scale;             /* 2^(- integer size) */
+  long floatidum;
+  long intidum; // needed to keep track of where we are in the 
+  // nric random number generators
+  long iy;
+  long iv[NTAB];
+  /* global variables */
+  unsigned long randbuffer[KK];  /* history buffer */
+  int r_p1, r_p2;          /* indexes into history buffer */
+  int iset;
+  double gset;
+} prng_type;
+
+#define _PRNG 1
+
+#endif
+
+extern long prng_int(prng_type *);
+extern float prng_float(prng_type *);
+extern prng_type * prng_Init(long, int);
+extern void prng_Destroy(prng_type * prng);
+void prng_Reseed(prng_type *, long);
+
+//extern long double zipf(double, long) ;
+extern double fastzipf(double, long, double, prng_type *);
+extern double zeta(long, double);
+extern double prng_normal(prng_type * prng);
+extern double prng_stable(prng_type * prng, double);
+
+//extern double stable(double); // stable distributions 
+//extern double stabledevd(float) ;
+//extern long double stabledevl(float) ;
+//extern double altstab(double); 
+
diff -Nru ntop-4.99.3+ndpi5517+dfsg1/prng.c ntop-4.99.3+ndpi5517+dfsg2/prng.c
--- ntop-4.99.3+ndpi5517+dfsg1/prng.c	2012-02-21 15:51:02.000000000 -0800
+++ ntop-4.99.3+ndpi5517+dfsg2/prng.c	2012-11-30 00:16:18.000000000 -0800
@@ -1,3 +1,24 @@
+/*********************************************************************
+
+prng: pseudo-random number generators and hashing routines
+
+G. Cormode 2003-2012
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+************************************************************************/
+
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -9,7 +30,7 @@
 {
 
   long long result;
-  long lresult;  
+  long lresult;
 
   // return a hash of x using a and b mod (2^31 - 1)
 // may need to do another mod afterwards, or drop high bits
@@ -19,8 +40,8 @@
   //  result = ((long long) a)*((long long) x)+((long long) b);
   result=(a * x) + b;
   result = ((result >> HL) + result) & MOD;
-  lresult=(long) result; 
-  
+  lresult=(long) result;
+
   return(lresult);
 }
 
@@ -28,11 +49,11 @@
 {
   long long result;
   long lresult;
-  
+
   // returns values that are 4-wise independent by repeated calls
-  // to the pairwise indpendent routine. 
+  // to the pairwise indpendent routine.
 
-  result = hash31(hash31(hash31(x,a,b),x,c),x,d);
+  result = hash31(hash31(hash31(a,b,x),c,x),d,x);
   lresult = (long) result;
   return lresult;
 }
@@ -45,7 +66,7 @@
 // There are *THREE* alternate implementations of PRNGs here.
 // One taken from Numerical Recipes in C, the second from www.agner.org
 // The third is an internal C random library, srand
-// The variable usenric controls which one is used: pick one 
+// The variable usenric controls which one is used: pick one
 // and stick with it, switching between the two will give unpredictable
 // results.  This is controlled by the randinit procedure, call it with
 // usenric == 1 to use the Numerical Recipes gens
@@ -66,7 +87,7 @@
 #define RNMX (1.0-EPS)
 
 float ran1(prng_type * prng) {
- 
+
   // A Random Number Generator that picks a uniform [0,1] random number
   // From Numerical Recipes, page 280
   // Should be called with a NEGATIVE value of idum to initialize
@@ -75,7 +96,7 @@
   int j;
   long k;
   float temp;
-  
+
   if (prng->floatidum <= 0 || !prng->iy) {
     if (-(prng->floatidum) < 1) prng->floatidum=1;
     else prng->floatidum = -(prng->floatidum);
@@ -96,9 +117,9 @@
   if ((temp=AM*prng->iy) > RNMX) return RNMX;
   else return temp;
 }
- 
+
 long ran2(prng_type * prng) {
- 
+
   // A Random Number Generator that picks a uniform random number
   // from the range of long integers.
   // From Numerical Recipes, page 280
@@ -109,7 +130,7 @@
 
   int j;
   long k;
-  
+
   if (prng->intidum <= 0 || !prng->iy) {
     if (-(prng->intidum) < 1) prng->intidum=1;
     else prng->intidum = -(prng->intidum);
@@ -174,7 +195,7 @@
 
   /* generate next random number */
 
-  x = prng->randbuffer[prng->r_p1] = rotl(prng->randbuffer[prng->r_p2], R1) 
+  x = prng->randbuffer[prng->r_p1] = rotl(prng->randbuffer[prng->r_p2], R1)
     +  rotl(prng->randbuffer[prng->r_p1], R2);
   /* rotate list pointers */
   if (--prng->r_p1 < 0) prng->r_p1 = KK - 1;
@@ -225,7 +246,7 @@
     {
     case 1 : response=(ran2(prng)); break;
     case 2 : response=(ran3(prng)); break;
-  //  case 3 : response=(lrand48()); break;
+    case 3 : response=(lrand48()); break;
     }
   return response;
 }
@@ -233,7 +254,7 @@
 
 float prng_float(prng_type * prng) {
 
-  // returns a pseudo-random float in the range [0.0,1.0].  
+  // returns a pseudo-random float in the range [0.0,1.0].
   // Initialise the generator before use!
   float result=0;
 
@@ -241,7 +262,7 @@
     {
     case 1 : result=(ran1(prng)); break;
     case 2 : result=(ran4(prng)); break;
-   // case 3 : result=(drand48()); break;
+    case 3 : result=(drand48()); break;
     }
   return result;
 }
@@ -249,25 +270,25 @@
 prng_type * prng_Init(long seed, int nric) {
 
   // Initialise the random number generators.  nric determines
-  // which algorithm to use, 1 for Numerical Recipes in C, 
-  // 0 for the other one. 
+  // which algorithm to use, 1 for Numerical Recipes in C,
+  // 0 for the other one.
   prng_type * result;
 
   result=(prng_type *) calloc(1,sizeof(prng_type));
 
   result->iy=0;
-  result->usenric=nric; 
+  result->usenric=nric;
   result->floatidum=-1;
   result->intidum=-1;
   result->iset=0;
   // set a global variable to record which algorithm to use
   switch (nric)
-    { 
-    case 2 : 
+    {
+    case 2 :
       RanrotAInit(result,seed);
       break;
-    case 1 : 
-      if (seed>0) { 
+    case 1 :
+      if (seed>0) {
 	// to initialise the NRiC PRNGs, call it with a negative value
 	// so make sure it gets a negative value!
 	result->floatidum = -(seed);  result->intidum = -(seed);
@@ -275,26 +296,26 @@
 	result->floatidum=seed; result->intidum=seed;
       }
       break;
-    case 3 : 
-      srand(seed);
+    case 3 :
+      srand48(seed);
       break;
     }
 
   prng_float(result);
   prng_int(result);
   // call the routines to actually initialise them
-  return(result);  
+  return(result);
 }
 
 void prng_Reseed(prng_type * prng, long seed)
 {
   switch (prng->usenric)
-    { 
-    case 2 : 
+    {
+    case 2 :
       RanrotAInit(prng,seed);
       break;
-    case 1 : 
-      if (seed>0) { 
+    case 1 :
+      if (seed>0) {
 	// to initialise the NRiC PRNGs, call it with a negative value
 	// so make sure it gets a negative value!
 	prng->floatidum = -(seed);  prng->intidum = -(seed);
@@ -302,16 +323,15 @@
 	prng->floatidum=seed; prng->intidum=seed;
       }
       break;
-    case 3 : 
-      srand(seed);
+    case 3 :
+      srand48(seed);
       break;
     }
-} 
+}
 
 void prng_Destroy(prng_type * prng)
-{ 
+{
   free(prng);
-  prng=NULL;
 }
 
 /**********************************************************************/
@@ -333,7 +353,7 @@
       v2 = 2.0*prng_float(prng)-1.0;
       rsq=v1*v1+v2*v2;
     } while (rsq >= 1.0 || rsq == 0.0);
-    
+
     fac = sqrt((double) -2.0*log((double)rsq)/rsq);
     prng->gset=v1*fac;
     prng->iset=1;
@@ -349,7 +369,7 @@
 
   // From 'stable distributions', John Nolan, manuscript, p24
   // we set beta = 0 by analogy with the normal and cauchy case
-  // identical to the above routine, but returns a double instead 
+  // identical to the above routine, but returns a double instead
   // of a long double (you'll see this a lot...)
 
   double theta, W, holder, left, right;
@@ -380,10 +400,10 @@
 }
 
 
-double prng_altstab(prng_type * prng, double p) 
+double prng_altstab(prng_type * prng, double p)
 {
   double u,v,result;
-  
+
   u=prng_float(prng);
   v=prng_float(prng);
   result=pow(u,p);
@@ -402,7 +422,7 @@
 
   z=gasdev();
   return (1.0/(z*z));
-  } 
+  }
 
 */
 
@@ -416,7 +436,7 @@
   // the first time since it uses the random generators
 
 
-  if (alpha==2.0) 
+  if (alpha==2.0)
     return(prng_normal(prng));
   else if (alpha==1.0)
     return(prng_cauchy(prng));
@@ -425,7 +445,7 @@
   else return (prng_stabledbn(prng,alpha));
 }
 
-double zeta(long n, double theta) 
+double zeta(long n, double theta)
 {
 
   // the zeta function, used by the below zipf function
@@ -434,7 +454,7 @@
 
   int i;
   double ans=0.0;
-  
+
   for (i=1; i <= n; i++)
     ans += pow(1./(double)i, theta);
   return(ans);
@@ -444,9 +464,9 @@
 
   // this draws values from the zipf distribution
   // this is mainly useful for test generation purposes
-  // n is range, theta is skewness parameter 
+  // n is range, theta is skewness parameter
   // theta = 0 gives uniform dbn,
-  // theta > 1 gives highly skewed dbn. 
+  // theta > 1 gives highly skewed dbn.
   // original code due to Flip Korn, used with permission
 
 	double alpha;
@@ -459,7 +479,8 @@
   // the first time since it uses the random generators
 
 	alpha = 1. / (1. - theta);
-	eta = (1. - pow(2./n, 1. - theta)) / (1. - zeta(2.,theta)/zetan);
+	eta = (1. - pow(2./((double) n), 1. - theta))
+	  / (1. - zeta(2,theta)/zetan);
 
 	u = prng_float(prng);
 	uz = u * zetan;
@@ -475,9 +496,9 @@
 
   // this draws values from the zipf distribution
   // this is mainly useful for test generation purposes
-  // n is range, theta is skewness parameter 
+  // n is range, theta is skewness parameter
   // theta = 0 gives uniform dbn,
-  // theta > 1 gives highly skewed dbn. 
+  // theta > 1 gives highly skewed dbn.
 
 	double alpha;
 	double zetan;

--- End Message ---
--- Begin Message ---
On 01.12.2012 08:17, Ludovico Cavedon wrote:
Changes:
- replace CC-BY-NC countmin.[ch] and prng.[ch] with the new version
released under GPL-2. The difference is minimal, and mostly comments. - the new countmin.[ch] and prng.[ch] are also included vanilla in the
  debian directory so that get-orig-source.sh can create the new orig
  tarball
- updated the Maintainer (moved myself from Uploader to Maintainer) as
  agreed with former Maintainer

Unblocked; thanks.

Regards,

Adam

--- End Message ---

Reply to: