r1765 - in packages/libnet-patricia-perl/trunk: . debian demo libpatricia

Niko Tyni ntyni-guest at costa.debian.org
Tue Dec 27 18:37:14 UTC 2005


Author: ntyni-guest
Date: 2005-12-27 18:37:13 +0000 (Tue, 27 Dec 2005)
New Revision: 1765

Modified:
   packages/libnet-patricia-perl/trunk/Changes
   packages/libnet-patricia-perl/trunk/Patricia.pm
   packages/libnet-patricia-perl/trunk/Patricia.xs
   packages/libnet-patricia-perl/trunk/debian/changelog
   packages/libnet-patricia-perl/trunk/demo/demo.c
   packages/libnet-patricia-perl/trunk/libpatricia/patricia.c
   packages/libnet-patricia-perl/trunk/libpatricia/patricia.h
   packages/libnet-patricia-perl/trunk/test.pl
Log:
Update to Net::Patricia 1.014


Modified: packages/libnet-patricia-perl/trunk/Changes
===================================================================
--- packages/libnet-patricia-perl/trunk/Changes	2005-12-27 18:36:37 UTC (rev 1764)
+++ packages/libnet-patricia-perl/trunk/Changes	2005-12-27 18:37:13 UTC (rev 1765)
@@ -1,7 +1,30 @@
 Revision history for Perl extension Net::Patricia.
 
+TODO
+        - add AF_INET6 support
+        - add POD describing Graham Barr's API improvements
+
+1.014 Thu Dec  8 18:05 2005
+        - fixed the "climb_inorder" item in the POD
+
+1.013 Thu Dec  8 17:36 2005
+        - fixed a perl stack handling bug in the previous release.
+
+1.012 Wed Dec  7 14:59 2005
+        - added climb_inorder method requested by George Michaelson.
+	- included <sys/types.h> for u_* definitions on FreeBSD 5 as
+	  suggested by Brian McDonald.
+        - tested for windows environment to include winsock
+	- patched libpatricia to get u_* types on FreeBSD 5.x
+	  from Brian McDonald
+
+1.011 Mon Oct 30 15:13 2000
+	- applied api-patch from Graham Barr
+	- added description of match_string to BUGS section of POD
+	  from John Payne
+
 1.010 Mon Oct 30 09:51 2000
-	- applied patch from Graham Barr <gbarr at pobox.com> which
+	- applied patch from Graham Barr which
 	  contained a memory leak fix and removed the unnecessary
 	  Exporter and AutoLoader stuff.
 

Modified: packages/libnet-patricia-perl/trunk/Patricia.pm
===================================================================
--- packages/libnet-patricia-perl/trunk/Patricia.pm	2005-12-27 18:36:37 UTC (rev 1764)
+++ packages/libnet-patricia-perl/trunk/Patricia.pm	2005-12-27 18:37:13 UTC (rev 1765)
@@ -1,5 +1,5 @@
 #  Net::Patricia - Patricia Trie perl module for fast IP address lookups
-#  Copyright (C) 2000  Dave Plonka
+#  Copyright (C) 2000-2005  Dave Plonka
 #
 #  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
@@ -15,7 +15,7 @@
 #  along with this program; if not, write to the Free Software
 #  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-# $Id: Patricia.pm,v 1.10 2000/10/30 15:53:43 dplonka Exp $
+# $Id: Patricia.pm,v 1.14 2005/12/09 00:03:56 dplonka Exp $
 # Dave Plonka <plonka at doit.wisc.edu>
 
 package Net::Patricia;
@@ -23,18 +23,103 @@
 use strict;
 use Carp;
 use vars qw($VERSION @ISA);
+use Socket qw(AF_INET inet_aton);
 
 require DynaLoader;
 
 @ISA = qw(DynaLoader);
-'$Revision: 1.10 $' =~ m/(\d+)\.(\d+)/ && (( $VERSION ) = sprintf("%d.%03d", $1, $2));
+'$Revision: 1.14 $' =~ m/(\d+)\.(\d+)/ && (( $VERSION ) = sprintf("%d.%03d", $1, $2));
 
 bootstrap Net::Patricia $VERSION;
 
-# Preloaded methods go here.
+sub new {
+  my ($class, $type) = @_;
+  $type ||= AF_INET;
 
-# Autoload methods go after =cut, and are processed by the autosplit program.
+  if ($type == AF_INET) {
+    return bless _new(32), 'Net::Patricia::AF_INET';
+  }
 
+  undef;
+}
+
+##
+## Compat functions
+##
+
+sub _ip_bits {
+  my $str = shift;
+  my $bits = ($str =~ s,/(\d+)$,,) ? $1 : 32;
+  ($str,$bits);
+}
+
+sub add_string {
+  my ($self,$str,$data) = @_;
+  $data = $str unless @_ > 2;
+  $self->add(_ip_bits($str),$data);
+}
+
+sub match_string {
+  my ($self,$str) = @_;
+  $self->match(_ip_bits($str))
+}
+
+sub match_exact_string {
+  my ($self,$str) = @_;
+  $self->exact(_ip_bits($str))
+}
+
+sub match_exact_integer {
+  shift->exact_integer(@_)
+}
+
+sub remove_string {
+  my ($self,$str) = @_;
+  $self->remove(_ip_bits($str))
+}
+
+##
+## AF_INET
+##
+
+ at Net::Patricia::AF_INET::ISA = qw(Net::Patricia);
+
+sub Net::Patricia::AF_INET::add {
+  my ($self, $ip, $bits, $data) = @_;
+  $data ||= $bits ? "$ip/$bits" : $ip;
+  my $packed = inet_aton($ip) || croak("invalid key");
+  _add($self,AF_INET,$packed,$bits || 32, $data);
+}
+
+sub Net::Patricia::AF_INET::match_integer {
+  my ($self, $num, $bits) = @_;
+  _match($self,AF_INET,pack("N",$num),$bits || 32);
+}
+
+sub Net::Patricia::AF_INET::exact_integer {
+  my ($self, $num, $bits) = @_;
+  _exact($self,AF_INET,pack("N",$num),$bits || 32);
+}
+
+sub Net::Patricia::AF_INET::match {
+  my ($self, $ip, $bits) = @_;
+  my $packed = inet_aton($ip) || croak("invalid key");
+  _match($self,AF_INET,$packed,$bits || 32);
+}
+
+sub Net::Patricia::AF_INET::exact {
+  my ($self, $ip, $bits) = @_;
+  my $packed = inet_aton($ip) || croak("invalid key");
+  _exact($self,AF_INET,$packed,$bits || 32);
+}
+
+sub Net::Patricia::AF_INET::remove {
+  my ($self, $ip, $bits) = @_;
+  my $packed = inet_aton($ip) || return undef;
+  _remove($self,AF_INET,$packed,$bits || 32);
+}
+
+
 1;
 __END__
 # Below is the stub of documentation for your module. You better edit it!
@@ -192,7 +277,7 @@
    $pt->climb([CODEREF]);
 
 This method climbs the Patricia Trie, visiting each node as it does
-so.
+so.  It performs a non-recursive, "preorder" traversal.
 
 The CODEREF argument is optional.  It is a perl code reference used to
 specify a user-defined subroutine to be called when visiting each
@@ -213,27 +298,58 @@
 This method is called climb() rather than walk() because climbing trees
 (and therfore tries) is a more popular pass-time than walking them.
 
+=item B<climb_inorder>
+
+   $pt->climb_inorder([CODEREF]);
+
+This method climbs the Patricia Trie, visiting each node in order as it
+does so.  That is, it performs an "inorder" traversal.
+
+The CODEREF argument is optional.  It is a perl code reference used to
+specify a user-defined subroutine to be called when visiting each
+node.  The node's user data will be passed as the sole argument to that
+subroutine.
+
+This method returns the number of nodes successfully visited while
+climbing the Trie.  That is, without a CODEREF argument, it simply
+counts the number of nodes in the Patricia Trie.
+
+Note that currently the return value from your CODEREF subroutine is
+ignored.  In the future the climb method may return the number of times
+your subroutine returned non-zero, as it is called once per node.  So,
+if you are currently relying on the climb return value to accurately
+report a count of the number of nodes in the Patricia Trie, it would be
+prudent to have your subroutine return a non-zero value.
+
+This method is called climb() rather than walk() because climbing trees
+(and therfore tries) is a more popular pass-time than walking them.
+
 =back
 
 =head1 BUGS
 
-I've only had the opportunity to test this code on GNU/Linux and
-Solaris.  [Why is it that I have fewer platforms available to me in
-academia than I used to have in the private industry?  Ugh.]  As such I
-am somewhat concerned about the portability of the C code on which this
-module is based and whether or not the resulting objects will link on
-other platforms.  Please send me reports, preferably including fixes
-for my Makefile.PL files and such.
+The match_string method ignores the mask bits/width, if specified, in
+its argument.  So, if you add two prefixes with the same base address
+but different mask widths, this module will match the most-specific
+prefix even if that prefix doesn't wholly cotain the prefix specified
+by the match argument.  For example:
 
-This is the first XSUB perl extension that I have written.  Consider
-yourself warned! ;^)  I'm particularly concerned as to whether or not
-my XS code is correct and whether or not this code leaks memory.  I've
-made an effort to avoid leaks in my use of the C patricialib API and in
-my manipulation of perl xVs, but am not sure if I have been successful
-in either case.  If leaks are discovered please report them to me as
-they are surely my fault and not that of the authors of the code on
-which this module is based.
+   use Net::Patricia;
+   my $pt = new Net::Patricia;
+   $pt->add_string('192.168.0.0/25');
+   $pt->add_string('192.168.0.0/16');
+   print $pt->match_string('192.168.0.0/24'), "\n";
 
+prints "192.168.0.0/25", just as if you had called:
+
+   print $pt->match_string('192.168.0.0'), "\n";
+
+This issue was reported to me by John Payne, who also provided a
+candidate patch, but I have not applied it since I hesitate to change
+this behavior which was inherited from MRT.  Consequently, this module
+might seem to violate the principle of least surprise if you specific
+the mask bits when trying to find the best match.
+
 Methods to add or remove nodes using integer arguments are yet to be
 implemented.  This was a lower priority since it is less necessary to
 avoid the overhead involved in translation from a string representation
@@ -255,7 +371,7 @@
 
 Dave Plonka <plonka at doit.wisc.edu>
 
-Copyright (C) 2000  Dave Plonka.  This program is free software; you
+Copyright (C) 2000-2005  Dave Plonka.  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.

Modified: packages/libnet-patricia-perl/trunk/Patricia.xs
===================================================================
--- packages/libnet-patricia-perl/trunk/Patricia.xs	2005-12-27 18:36:37 UTC (rev 1764)
+++ packages/libnet-patricia-perl/trunk/Patricia.xs	2005-12-27 18:37:13 UTC (rev 1765)
@@ -10,11 +10,176 @@
 
 #include "libpatricia/patricia.h"
 
+static int
+not_here(s)
+char *s;
+{
+    croak("%s not implemented on this architecture", s);
+    return -1;
+}
+
+static double
+constant(name, arg)
+char *name;
+int arg;
+{
+    errno = 0;
+    switch (*name) {
+    case 'A':
+	break;
+    case 'B':
+	break;
+    case 'C':
+	break;
+    case 'D':
+	break;
+    case 'E':
+	break;
+    case 'F':
+	break;
+    case 'G':
+	break;
+    case 'H':
+	break;
+    case 'I':
+	break;
+    case 'J':
+	break;
+    case 'K':
+	break;
+    case 'L':
+	break;
+    case 'M':
+	break;
+    case 'N':
+	break;
+    case 'O':
+	break;
+    case 'P':
+	break;
+    case 'Q':
+	break;
+    case 'R':
+	break;
+    case 'S':
+	break;
+    case 'T':
+	break;
+    case 'U':
+	break;
+    case 'V':
+	break;
+    case 'W':
+	break;
+    case 'X':
+	break;
+    case 'Y':
+	break;
+    case 'Z':
+	break;
+    case 'a':
+	break;
+    case 'b':
+	break;
+    case 'c':
+	break;
+    case 'd':
+	break;
+    case 'e':
+	break;
+    case 'f':
+	break;
+    case 'g':
+	break;
+    case 'h':
+	break;
+    case 'i':
+	break;
+    case 'j':
+	break;
+    case 'k':
+	break;
+    case 'l':
+	break;
+    case 'm':
+	break;
+    case 'n':
+	break;
+    case 'o':
+	break;
+    case 'p':
+	break;
+    case 'q':
+	break;
+    case 'r':
+	break;
+    case 's':
+	break;
+    case 't':
+	break;
+    case 'u':
+	break;
+    case 'v':
+	break;
+    case 'w':
+	break;
+    case 'x':
+	break;
+    case 'y':
+	break;
+    case 'z':
+	break;
+    }
+    errno = EINVAL;
+    return 0;
+
+not_there:
+    errno = ENOENT;
+    return 0;
+}
+
+#define Fill_Prefix(p,f,a,b,mb) \
+	do { \
+		if (b <= 0 || b > mb) \
+		  croak("invalid key"); \
+		memcpy(&p.add.sin, a, (mb+7)/8); \
+		p.family = f; \
+		p.bitlen = b; \
+		p.ref_count = 0; \
+	} while (0)
+
 static void deref_data(SV *data) {
    SvREFCNT_dec(data);
    data = (void *)0;
 }
 
+static size_t
+patricia_walk_inorder_perl(patricia_node_t *node, SV *coderef) {
+    dSP;
+    size_t n = 0;
+
+    if (node->l) {
+         n += patricia_walk_inorder_perl(node->l, coderef);
+    }
+
+    if (node->prefix) {
+        if ((SV *)0 != coderef) {
+            PUSHMARK(SP);
+            XPUSHs(sv_mortalcopy((SV *)node->data));
+            PUTBACK;
+            perl_call_sv(coderef, G_VOID|G_DISCARD);
+            SPAGAIN;
+        }
+	n++;
+    }
+	
+    if (node->r) {
+         n += patricia_walk_inorder_perl(node->r, coderef);
+    }
+
+    return n;
+}
+
 typedef patricia_tree_t *Net__Patricia;
 typedef patricia_node_t *Net__PatriciaNode;
 
@@ -22,149 +187,97 @@
 
 PROTOTYPES: ENABLE
 
+double
+constant(name,arg)
+	char *		name
+	int		arg
+
 Net::Patricia
-new(class)
-	char *				class
+_new(size)
+	int				size
 	CODE:
-		RETVAL = New_Patricia(32); /* FIXME for AF_INET6 */
+		RETVAL = New_Patricia(size);
 	OUTPUT:	
 		RETVAL
 
 void
-add_string(tree, string, ...)
+_add(tree, family, addr, bits, data)
 	Net::Patricia			tree
-	char *				string
-	PROTOTYPE: $$;$
+	int				family
+	char *				addr
+	int				bits
+	SV *				data
+	PROTOTYPE: $$$$$
 	PREINIT:
-		/* FIXME for AF_INET6: */
-	   	prefix_t *prefix;
+	   	prefix_t prefix;
 	   	Net__PatriciaNode node;
 	PPCODE:
-	   	if ((prefix_t *)0 == (prefix = ascii2prefix(AF_INET, string))) {
-                   croak("invalid key");
-		}
-	   	node = patricia_lookup(tree, prefix);
-	   	Deref_Prefix(prefix);
+		Fill_Prefix(prefix, family, addr, bits, tree->maxbits);
+	   	node = patricia_lookup(tree, &prefix);
 		if ((patricia_node_t *)0 != node) {
 		   /* { */
 		   if (node->data) {
 		      deref_data(node->data);
 		   }
-		   node->data = newSVsv(ST(items-1));
+		   node->data = newSVsv(data);
 		   /* } */
-		   PUSHs((SV*)node->data);
+		   PUSHs(data);
 		} else {
 		   XSRETURN_UNDEF;
 		}
 
 void
-match_string(tree, string)
+_match(tree, family, addr, bits)
 	Net::Patricia			tree
-	char *				string
+	int				family
+	char *				addr
+	int				bits
+	PROTOTYPE: $$$$
+	PREINIT:
+	   	prefix_t prefix;
+	   	Net__PatriciaNode node;
 	PPCODE:
-		{
-		   patricia_node_t *node;
-	   	   prefix_t *prefix;
-		   /* FIXME for AF_INET6: */
-	   	   if ((prefix_t *)0 == (prefix = ascii2prefix(AF_INET, string))) {
-                      croak("invalid key");
-		   }
-		   node = patricia_search_best(tree, prefix);
-	   	   Deref_Prefix(prefix);
-                   if ((patricia_node_t *)0 != node) {
-		      XPUSHs((SV *)node->data);
-		   } else {
-		      XSRETURN_UNDEF;
-		   }
+		Fill_Prefix(prefix, family, addr, bits, tree->maxbits);
+		node = patricia_search_best(tree, &prefix);
+		if ((patricia_node_t *)0 != node) {
+		   XPUSHs((SV *)node->data);
+		} else {
+		   XSRETURN_UNDEF;
 		}
 
 void
-match_exact_string(tree, string)
+_exact(tree, family, addr, bits)
 	Net::Patricia			tree
-	char *				string
+	int				family
+	char *				addr
+	int				bits
+	PROTOTYPE: $$$$
+	PREINIT:
+	   	prefix_t prefix;
+	   	Net__PatriciaNode node;
 	PPCODE:
-		{
-		   patricia_node_t *node;
-	   	   prefix_t *prefix;
-		   /* FIXME for AF_INET6: */
-	   	   if ((prefix_t *)0 == (prefix = ascii2prefix(AF_INET, string))) {
-                      croak("invalid key");
-		   }
-		   node = patricia_search_exact(tree, prefix);
-	   	   Deref_Prefix(prefix);
-                   if ((patricia_node_t *)0 != node) {
-		      XPUSHs((SV *)node->data);
-		   } else {
-		      XSRETURN_UNDEF;
-		   }
+		Fill_Prefix(prefix, family, addr, bits, tree->maxbits);
+		node = patricia_search_exact(tree, &prefix);
+		if ((patricia_node_t *)0 != node) {
+		   XPUSHs((SV *)node->data);
+		} else {
+		   XSRETURN_UNDEF;
 		}
 
-void
-match_integer(tree, integer)
-	Net::Patricia			tree
-	unsigned long			integer
-	PPCODE:
-		{
-		   patricia_node_t *node;
-		   prefix_t prefix;
-		   unsigned long netlong = htonl(integer);
-		   memcpy(&prefix.add.sin, &netlong, sizeof netlong);
-		   prefix.family = AF_INET; /* FIXME for AF_INET6 */
-		   prefix.bitlen = 32; /* FIXME for AF_INET6 */
-		   prefix.ref_count = 0;
-		   node = patricia_search_best(tree, &prefix);
-                   if ((patricia_node_t *)0 != node) {
-		      XPUSHs((SV *)node->data);
-		   } else {
-		      XSRETURN_UNDEF;
-		   }
-		}
 
 void
-match_exact_integer(tree, integer, ...)
+_remove(tree, family, addr, bits)
 	Net::Patricia			tree
-	unsigned long			integer
-	PPCODE:
-		{
-		   patricia_node_t *node = (patricia_node_t *)0;
-		   prefix_t prefix;
-		   unsigned long netlong = htonl(integer);
-		   memcpy(&prefix.add.sin, &netlong, sizeof netlong);
-		   prefix.family = AF_INET; /* FIXME for AF_INET6 */
-		   if (items == 3) {
-		      prefix.bitlen = SvIV(ST(2));
-		      if (prefix.bitlen > 32) { /* FIXME for AF_INET6 */
-                         croak("mask length must be <= 32");
-		      }
-		   } else if (items > 3) {
-	              croak("Usage: Net::Patricia::match_exact_integer(tree,integer[,mask_length])");
-		   } else {
-		      prefix.bitlen = 32; /* FIXME for AF_INET6 */
-		   }
-		   prefix.ref_count = 0;
-		   node = patricia_search_exact(tree, &prefix);
-                   if ((patricia_node_t *)0 != node) {
-		      XPUSHs((SV *)node->data);
-		   } else {
-		      XSRETURN_UNDEF;
-		   }
-		}
-
-void
-remove_string(tree, string)
-	Net::Patricia			tree
-	char *				string
+	int				family
+	char *				addr
+	int				bits
+	PROTOTYPE: $$$$
 	PREINIT:
-		/* FIXME for AF_INET6: */
-	   	prefix_t *prefix;
+	   	prefix_t prefix;
 	   	Net__PatriciaNode node;
 	PPCODE:
-		/* FIXME for AF_INET6: */
-	   	if ((prefix_t *)0 == (prefix = ascii2prefix(AF_INET, string))) {
-                   croak("invalid key");
-		}
-	   	node = patricia_search_exact(tree, prefix);
-	   	Deref_Prefix(prefix);
+		Fill_Prefix(prefix, family, addr, bits, tree->maxbits);
+	   	node = patricia_search_exact(tree, &prefix);
 		if ((Net__PatriciaNode)0 != node) {
 		   XPUSHs(sv_mortalcopy((SV *)node->data));
 		   deref_data(node->data);
@@ -188,7 +301,7 @@
 		}
 		PATRICIA_WALK (tree->head, node) {
 		   if ((SV *)0 != func) {
-		      PUSHMARK(sp);
+		      PUSHMARK(SP);
 		      XPUSHs(sv_mortalcopy((SV *)node->data));
 		      PUTBACK;
 		      perl_call_sv(func, G_VOID|G_DISCARD);
@@ -200,6 +313,24 @@
 	OUTPUT:	
 		RETVAL
 
+size_t
+climb_inorder(tree, ...)
+	Net::Patricia			tree
+	PREINIT:
+		size_t n = 0;
+		SV *func = (SV *)0;
+	CODE:
+		func = (SV *)0;
+		if (2 == items) {
+		   func = ST(1);
+		} else if (2 < items) {
+	           croak("Usage: Net::Patricia::climb_inorder(tree[,CODEREF])");
+		}
+                n = patricia_walk_inorder_perl(tree->head, func);
+		RETVAL = n;
+	OUTPUT:	
+		RETVAL
+
 void
 DESTROY(tree)
 	Net::Patricia			tree

Modified: packages/libnet-patricia-perl/trunk/debian/changelog
===================================================================
--- packages/libnet-patricia-perl/trunk/debian/changelog	2005-12-27 18:36:37 UTC (rev 1764)
+++ packages/libnet-patricia-perl/trunk/debian/changelog	2005-12-27 18:37:13 UTC (rev 1765)
@@ -1,3 +1,9 @@
+libnet-patricia-perl (1.014-1) UNRELEASED; urgency=low
+
+  * (NOT RELEASED YET) New upstream release
+
+ -- Niko Tyni <ntyni at iki.fi>  Tue, 27 Dec 2005 20:36:43 +0200
+
 libnet-patricia-perl (1.010-5) unstable; urgency=low
 
   * Corrected Maintainer e-Mail Address

Modified: packages/libnet-patricia-perl/trunk/demo/demo.c
===================================================================
--- packages/libnet-patricia-perl/trunk/demo/demo.c	2005-12-27 18:36:37 UTC (rev 1764)
+++ packages/libnet-patricia-perl/trunk/demo/demo.c	2005-12-27 18:37:13 UTC (rev 1765)
@@ -1,5 +1,5 @@
 /*
- * $Id: demo.c,v 1.3 2000/10/12 05:18:55 dplonka Exp $
+ * $Id: demo.c,v 1.4 2005/12/07 20:55:52 dplonka Exp $
  *
  * This is based on "demo.c" provided with MRT-2.2.2a.
  */
@@ -8,6 +8,10 @@
 #include <stdio.h> /* printf */
 #include <stdlib.h> /* exit */
 
+void func(prefix_t *prefix) {
+    printf("node: %s/%d\n", prefix_toa(prefix), prefix->bitlen);
+}
+
 int
 main(void)
 {
@@ -25,6 +29,7 @@
     make_and_lookup(tree, "10.42.42.0/24");
     make_and_lookup(tree, "10.42.69.0/24");
     make_and_lookup(tree, "10.0.0.0/8");
+    make_and_lookup(tree, "10.0.0.0/9");
 
     try_search_best(tree, "10.42.42.0/24");
     try_search_best(tree, "10.10.10.10");
@@ -32,19 +37,27 @@
     try_search_exact(tree, "10.0.0.0");
     try_search_exact(tree, "10.0.0.0/8");
 
+#if 0
     PATRICIA_WALK(tree->head, node) {
        printf("node: %s/%d\n", 
               prefix_toa(node->prefix), node->prefix->bitlen);
     } PATRICIA_WALK_END;
+#else
+    printf("%u total nodes.\n", patricia_walk_inorder(tree->head, func));
+#endif
 
     lookup_then_remove(tree, "42.0.0.0/8");
     lookup_then_remove(tree, "10.0.0.0/8");
     try_search_exact(tree, "10.0.0.0");
 
+#if 0
     PATRICIA_WALK(tree->head, node) {
        printf("node: %s/%d\n", 
               prefix_toa(node->prefix), node->prefix->bitlen);
     } PATRICIA_WALK_END;
+#else
+    printf("%u total nodes.\n", patricia_walk_inorder(tree->head, func));
+#endif
 
     Destroy_Patricia(tree, (void *)0);
 

Modified: packages/libnet-patricia-perl/trunk/libpatricia/patricia.c
===================================================================
--- packages/libnet-patricia-perl/trunk/libpatricia/patricia.c	2005-12-27 18:36:37 UTC (rev 1764)
+++ packages/libnet-patricia-perl/trunk/libpatricia/patricia.c	2005-12-27 18:37:13 UTC (rev 1765)
@@ -1,5 +1,5 @@
 /*
- * $Id: patricia.c,v 1.4 2000/09/29 19:28:07 dplonka Exp $
+ * $Id: patricia.c,v 1.7 2005/12/07 20:46:41 dplonka Exp $
  * Dave Plonka <plonka at doit.wisc.edu>
  *
  * This product includes software developed by the University of Michigan,
@@ -24,7 +24,10 @@
 #include <stdio.h> /* sprintf, fprintf, stderr */
 #include <stdlib.h> /* free, atol, calloc */
 #include <string.h> /* memcpy, strchr, strlen */
-#include <arpa/inet.h> /* for inet_addr */
+#include <sys/types.h> /* BSD: for inet_addr */
+#include <sys/socket.h> /* BSD, Linux: for inet_addr */
+#include <netinet/in.h> /* BSD, Linux: for inet_addr */
+#include <arpa/inet.h> /* BSD, Linux, Solaris: for inet_addr */
 
 #include "patricia.h"
 
@@ -461,7 +464,29 @@
     } PATRICIA_WALK_END;
 }
 
+size_t
+patricia_walk_inorder(patricia_node_t *node, void_fn_t func)
+{
+    size_t n = 0;
+    assert(func);
 
+    if (node->l) {
+         n += patricia_walk_inorder(node->l, func);
+    }
+
+    if (node->prefix) {
+	func(node->prefix, node->data);
+	n++;
+    }
+	
+    if (node->r) {
+         n += patricia_walk_inorder(node->r, func);
+    }
+
+    return n;
+}
+
+
 patricia_node_t *
 patricia_search_exact (patricia_tree_t *patricia, prefix_t *prefix)
 {

Modified: packages/libnet-patricia-perl/trunk/libpatricia/patricia.h
===================================================================
--- packages/libnet-patricia-perl/trunk/libpatricia/patricia.h	2005-12-27 18:36:37 UTC (rev 1764)
+++ packages/libnet-patricia-perl/trunk/libpatricia/patricia.h	2005-12-27 18:37:13 UTC (rev 1765)
@@ -1,5 +1,5 @@
 /*
- * $Id: patricia.h,v 1.4 2000/09/29 19:28:07 dplonka Exp $
+ * $Id: patricia.h,v 1.6 2005/12/07 20:53:01 dplonka Exp $
  * Dave Plonka <plonka at doit.wisc.edu>
  *
  * This product includes software developed by the University of Michigan,
@@ -25,8 +25,16 @@
 
 #define addroute make_and_lookup
 
-#include <netinet/in.h> /* for struct in_addr */
+#include <sys/types.h> /* for u_* definitions (on FreeBSD 5) */
 
+#include <errno.h> /* for EAFNOSUPPORT */
+#ifndef EAFNOSUPPORT
+#  defined EAFNOSUPPORT WSAEAFNOSUPPORT
+#  include <winsock.h>
+#else
+#  include <netinet/in.h> /* for struct in_addr */
+#endif
+
 #include <sys/socket.h> /* for AF_INET */
 
 /* { from mrt.h */

Modified: packages/libnet-patricia-perl/trunk/test.pl
===================================================================
--- packages/libnet-patricia-perl/trunk/test.pl	2005-12-27 18:36:37 UTC (rev 1764)
+++ packages/libnet-patricia-perl/trunk/test.pl	2005-12-27 18:37:13 UTC (rev 1765)
@@ -54,7 +54,7 @@
 
 print("Destructor 10 should *not* have run yet.\n") if $debug;
 
-foreach my $subnet (qw(10.42.42.0/24 10.42.69.0/24)) {
+foreach my $subnet (qw(10.42.42.0/31 10.42.42.0/26 10.42.42.0/24 10.42.42.0/32 10.42.69.0/24)) {
    $t->add_string($subnet) || die
 }
 
@@ -113,7 +113,7 @@
 # print "YOU SHOULD SEE A USAGE ERROR HERE:\n";
 # $t->match_exact_integer(167772160, 8, 10);
 
-if (3 == $t->climb(sub { print "climbing at $_[0]\n" })) {
+if (6 == $t->climb_inorder(sub { print "climbing at $_[0]\n" })) {
    print "ok 17\n"
 } else {
    print "not ok 17\n"




More information about the Pkg-perl-cvs-commits mailing list