cidr

Started by Paul A Vixieover 27 years ago62 messageshackers
Jump to latest
#1Paul A Vixie
vixie@vix.com

i didn't realize that anybody else was working on an IP address
data type or i'd've posted this six months ago when i first wrote
it. it lacks only the stuff needed to make it usable as a UNIQUE
KEY. it depends on BIND-8's libraries.

#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1998-07-19 12:25 PDT by <vixie@bb.rc.vix.com>.
# Source directory was `/tmp_mnt/mb/mb0/user/vixie/src/postgres-cidrtype'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 671 -r--r--r-- Makefile
# 4572 -r--r--r-- cidr.c
# 2877 -r--r--r-- cidr.source
# 3068 -r--r--r-- cidr.sql
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
if test "$gettext_dir" = FAILED && test -f $dir/gettext \
&& ($dir/gettext --version >/dev/null 2>&1)
then
set `$dir/gettext --version 2>&1`
if test "$3" = GNU
then
gettext_dir=$dir
fi
fi
if test "$locale_dir" = FAILED && test -f $dir/shar \
&& ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
then
locale_dir=`$dir/shar --print-text-domain-dir`
fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
echo=echo
else
TEXTDOMAINDIR=$locale_dir
export TEXTDOMAINDIR
TEXTDOMAIN=sharutils
export TEXTDOMAIN
echo="$gettext_dir/gettext -s"
fi
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
shar_touch=touch
else
shar_touch=:
echo
$echo 'WARNING: not restoring timestamps. Consider getting and'
$echo "installing GNU \`touch', distributed in GNU File Utilities..."
echo
fi
rm -f 1231235999 $$.touch
#
if mkdir _sh17086; then
$echo 'x -' 'creating lock directory'
else
$echo 'failed to create lock directory'
exit 1
fi
# ============= Makefile ==============
if test -f 'Makefile' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'Makefile' '(file already exists)'
else
$echo 'x -' extracting 'Makefile' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
ifndef PGDIR
PGDIR= /db0/local/postgresql-6.2
endif
X
SRCDIR= $(PGDIR)/src
X
include $(SRCDIR)/Makefile.global
X
CFLAGS+= -I$(PGDIR)/include -I$(PGDIR)/src/include -I$(LIBPQDIR)
CFLAGS+= -I/usr/local/bind/include
X
CLIBS+= -L/usr/local/bind/lib -lbind
X
TARGETS= cidr.sql cidr${DLSUFFIX}
X
DLSUFFIX=.so
X
all: $(TARGETS)
X
cidr${DLSUFFIX}: cidr.o
X shlicc2 -r -o cidr${DLSUFFIX} cidr.o -L/usr/local/bind/lib -lbind
X
install:
X $(MAKE) all
X cp -p cidr$(DLSUFFIX) $(LIBDIR)
X
%.sql: %.source
X rm -f $@; C=`pwd`; O=$$C; \
X if [ -d ${LIBDIR} ]; then O=${LIBDIR}; fi; \
X sed -e "s:_OBJWD_:$$O:g" \
X -e "s:_DLSUFFIX_:$(DLSUFFIX):g" \
X < $< > $@
X
clean:
X rm -f $(TARGETS) cidr.o
X
SHAR_EOF
$shar_touch -am 1108213897 'Makefile' &&
chmod 0444 'Makefile' ||
$echo 'restore of' 'Makefile' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'Makefile:' 'MD5 check failed'
ecb325bcab4a92f4fd5657cdc29a9f63 Makefile
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'Makefile'`"
test 671 -eq "$shar_count" ||
$echo 'Makefile:' 'original size' '671,' 'current size' "$shar_count!"
fi
fi
# ============= cidr.c ==============
if test -f 'cidr.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'cidr.c' '(file already exists)'
else
$echo 'x -' extracting 'cidr.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'cidr.c' &&
/*
X * cidr.c - Internal Classless InterDomain Routing entities for PostGreSQL
X *
X * Paul Vixie <paul@vix.com>, Internet Software Consortium, October 1997.
X *
X * $Id: cidr.c,v 1.4 1998/07/15 19:36:56 vixie Exp $
X */
X
/* Import. */
X
#include <sys/types.h>
#include <sys/socket.h>
X
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
X
#include <netinet/in.h>
#include <arpa/inet.h>
#include <isc/misc.h>
X
#include "postgres.h"
#include "utils/palloc.h"
X
/* Define. */
X
#define cidr_min(a, b) (((a) < (b)) ? (a) : (b))
X
typedef struct {
X unsigned char family;
X unsigned char bits;
X unsigned char bytes[1]; /* This is really an open array. */
} cidr;
X
#define cidr_addrsize(fam) ((fam) == AF_INET ? 4 : -1)
#define cidr_size(addrsize) (sizeof(cidr) - sizeof(unsigned char) + addrsize)
X
/* Export. */
X
cidr * cidr_in(const char *);
char * cidr_out(const cidr *);
X
bool cidr_eq(const cidr *, const cidr *);
bool cidr_ne(const cidr *, const cidr *);
bool cidr_lt(const cidr *, const cidr *);
bool cidr_gt(const cidr *, const cidr *);
bool cidr_le(const cidr *, const cidr *);
bool cidr_ge(const cidr *, const cidr *);
bool cidr_sub(const cidr *, const cidr *);
bool cidr_subeq(const cidr *, const cidr *);
bool cidr_sup(const cidr *, const cidr *);
bool cidr_supeq(const cidr *, const cidr *);
int4 cidr_span(const cidr *, const cidr *);
int4 cidr_cmp(const cidr *, const cidr *);
X
/* Functions. */
X
cidr *
cidr_in(const char *src) {
X int bits, bytes;
X cidr *dst;
X
X bytes = cidr_addrsize(AF_INET);
X if (bytes == -1) {
X elog(WARN, "Programming error in cidr_in()");
X return (NULL);
X }
X dst = palloc(cidr_size(bytes));
X if (dst == NULL) {
X elog(WARN, "Unable to allocate memory in cidr_in()");
X return (NULL);
X }
X bits = inet_net_pton(AF_INET, src, &dst->bytes, bytes);
X if (bits < 0 || bits > 32) {
X elog(WARN, "Bad CIDR expression (%s)", src);
X pfree(dst);
X return (NULL);
X }
X dst->bits = (unsigned char)bits;
X return (dst);
}
X
char *
cidr_out(const cidr *src) {
X char *dst, tmp[sizeof "255.255.255.255/32"];
X
X if (inet_net_ntop(AF_INET, &src->bytes, src->bits,
X tmp, sizeof tmp) < 0) {
X elog(WARN, "Unable to format CIDR (%s)", strerror(errno));
X pfree(dst);
X return (NULL);
X }
X dst = palloc(strlen(tmp) + 1);
X if (dst == NULL) {
X elog(WARN, "Unable to allocate memory in cidr_out()");
X return (NULL);
X }
X strcpy(dst, tmp);
X return (dst);
}
X
/* Equality. */
X
bool
cidr_eq(const cidr *lhs, const cidr *rhs) {
X return (lhs->bits == rhs->bits &&
X bitncmp(lhs->bytes, rhs->bytes, lhs->bits) == 0);
}
X
bool
cidr_ne(const cidr *lhs, const cidr *rhs) {
X return (!cidr_eq(lhs, rhs));
}
X
/* Ordering. */
X
bool
cidr_lt(const cidr *lhs, const cidr *rhs) {
X int x = bitncmp(lhs->bytes, rhs->bytes,
X cidr_min(lhs->bits, rhs->bits));
X
X return (x < 0 || (x == 0 && lhs->bits < rhs->bits));
}
X
bool
cidr_le(const cidr *lhs, const cidr *rhs) {
X return (cidr_lt(lhs, rhs) || cidr_eq(lhs, rhs));
}
X
bool
cidr_gt(const cidr *lhs, const cidr *rhs) {
X int x = bitncmp(lhs->bytes, rhs->bytes,
X cidr_min(lhs->bits, rhs->bits));
X
X return (x > 0 || (x == 0 && lhs->bits > rhs->bits));
}
X
bool
cidr_ge(const cidr *lhs, const cidr *rhs) {
X return (cidr_gt(lhs, rhs) || cidr_eq(lhs, rhs));
}
X
/* Subnetting. */
X
bool
cidr_sub(const cidr *lhs, const cidr *rhs) {
X return (lhs->bits > rhs->bits &&
X bitncmp(lhs->bytes, rhs->bytes, rhs->bits) == 0);
}
X
bool
cidr_subeq(const cidr *lhs, const cidr *rhs) {
X return (lhs->bits >= rhs->bits &&
X bitncmp(lhs->bytes, rhs->bytes, rhs->bits) == 0);
}
X
/* Supernetting. */
X
bool
cidr_sup(const cidr *lhs, const cidr *rhs) {
X return (lhs->bits < rhs->bits &&
X bitncmp(lhs->bytes, rhs->bytes, lhs->bits) == 0);
}
X
bool
cidr_supeq(const cidr *lhs, const cidr *rhs) {
X return (lhs->bits <= rhs->bits &&
X bitncmp(lhs->bytes, rhs->bytes, lhs->bits) == 0);
}
X
int4
cidr_span(const cidr *lhs, const cidr *rhs) {
X const u_char *l = lhs->bytes, *r = rhs->bytes;
X int n = cidr_min(lhs->bits, rhs->bits);
X int b = n >> 3;
X int4 result = 0;
X u_int lb, rb;
X
X /* Find out how many full octets match. */
X while (b > 0 && *l == *r)
X b--, l++, r++, result += 8;
X /* Find out how many bits to check. */
X if (b == 0)
X b = n & 07;
X else
X b = 8;
X /* Find out how many bits match. */
X lb = *l, rb = *r;
X while (b > 0 && (lb & 0x80) == (rb & 0x80))
X b--, lb <<= 1, rb <<= 1, result++;
X return (result);
}
X
int4
cidr_cmp(const cidr *lhs, const cidr *rhs) {
X int x = bitncmp(lhs->bytes, rhs->bytes,
X cidr_min(lhs->bits, rhs->bits));
X
X if (x < 0)
X return (-1);
X if (x > 0)
X return (1);
X return (0);
}
SHAR_EOF
$shar_touch -am 0715123698 'cidr.c' &&
chmod 0444 'cidr.c' ||
$echo 'restore of' 'cidr.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'cidr.c:' 'MD5 check failed'
f8fd720dbffa7ab05d594c9953b75170 cidr.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'cidr.c'`"
test 4572 -eq "$shar_count" ||
$echo 'cidr.c:' 'original size' '4572,' 'current size' "$shar_count!"
fi
fi
# ============= cidr.source ==============
if test -f 'cidr.source' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'cidr.source' '(file already exists)'
else
$echo 'x -' extracting 'cidr.source' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'cidr.source' &&
---------------------------------------------------------------------------
--
-- cidr.sql-
-- This file defines operators Classless InterDomain Routing entities.
--
---------------------------------------------------------------------------
X
LOAD '_OBJWD_/cidr_DLSUFFIX_';
X
CREATE FUNCTION cidr_in(opaque)
X RETURNS cidr
X AS '_OBJWD_/cidr_DLSUFFIX_'
X LANGUAGE 'c';
X
CREATE FUNCTION cidr_out(opaque)
X RETURNS opaque
X AS '_OBJWD_/cidr_DLSUFFIX_'
X LANGUAGE 'c';
X
CREATE TYPE cidr (
X internallength = 6,
X input = cidr_in,
X output = cidr_out
);
X
CREATE FUNCTION cidr_cmp(cidr, cidr)
X RETURNS int4
X AS '_OBJWD_/cidr_DLSUFFIX_'
X LANGUAGE 'c';
X
-----------------------------
-- Create operators
-----------------------------
X
-- equality (=)
X
CREATE FUNCTION cidr_eq(cidr, cidr)
X RETURNS bool
X AS '_OBJWD_/cidr_DLSUFFIX_'
X LANGUAGE 'c';
X
CREATE OPERATOR = (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_eq,
X commutator = =
);
X
-- inequality (<>)
X
CREATE FUNCTION cidr_ne(cidr, cidr)
X RETURNS bool
X AS '_OBJWD_/cidr_DLSUFFIX_'
X LANGUAGE 'c';
X
CREATE OPERATOR <> (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_ne,
X commutator = <>
);
X
-- less (<, <=)
X
CREATE FUNCTION cidr_lt(cidr, cidr)
X RETURNS bool
X AS '_OBJWD_/cidr_DLSUFFIX_'
X LANGUAGE 'c';
X
CREATE OPERATOR < (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_lt
);
X
CREATE FUNCTION cidr_le(cidr, cidr)
X RETURNS bool
X AS '_OBJWD_/cidr_DLSUFFIX_'
X LANGUAGE 'c';
X
CREATE OPERATOR <= (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_le
);
X
-- greater (>, >=)
X
CREATE FUNCTION cidr_gt(cidr, cidr)
X RETURNS bool
X AS '_OBJWD_/cidr_DLSUFFIX_'
X LANGUAGE 'c';
X
CREATE OPERATOR > (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_gt
);
X
CREATE FUNCTION cidr_ge(cidr, cidr)
X RETURNS bool
X AS '_OBJWD_/cidr_DLSUFFIX_'
X LANGUAGE 'c';
X
CREATE OPERATOR >= (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_ge
);
X
-- subnet (<<, <<=)
X
CREATE FUNCTION cidr_sub(cidr, cidr)
X RETURNS bool
X AS '_OBJWD_/cidr_DLSUFFIX_'
X LANGUAGE 'c';
X
CREATE OPERATOR << (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_sub
);
X
CREATE FUNCTION cidr_subeq(cidr, cidr)
X RETURNS bool
X AS '_OBJWD_/cidr_DLSUFFIX_'
X LANGUAGE 'c';
X
CREATE OPERATOR <<= (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_subeq
);
X
-- supernet (>>, >>=)
X
CREATE FUNCTION cidr_sup(cidr, cidr)
X RETURNS bool
X AS '_OBJWD_/cidr_DLSUFFIX_'
X LANGUAGE 'c';
X
CREATE OPERATOR >> (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_sup
);
X
CREATE FUNCTION cidr_supeq(cidr, cidr)
X RETURNS bool
X AS '_OBJWD_/cidr_DLSUFFIX_'
X LANGUAGE 'c';
X
CREATE OPERATOR >>= (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_supeq
);
X
-- spanning (length of prefix match)
X
CREATE FUNCTION cidr_span(cidr, cidr)
X RETURNS int4
X AS '_OBJWD_/cidr_DLSUFFIX_'
X LANGUAGE 'c';
X
CREATE FUNCTION cidr_masklen(cidr)
X RETURNS int2
X AS '_OBJWD_/cidr_DLSUFFIX_'
X LANGUAGE 'c';
SHAR_EOF
$shar_touch -am 0719122498 'cidr.source' &&
chmod 0444 'cidr.source' ||
$echo 'restore of' 'cidr.source' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'cidr.source:' 'MD5 check failed'
dca27b8d433d030e5049bb04ad15df03 cidr.source
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'cidr.source'`"
test 2877 -eq "$shar_count" ||
$echo 'cidr.source:' 'original size' '2877,' 'current size' "$shar_count!"
fi
fi
# ============= cidr.sql ==============
if test -f 'cidr.sql' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'cidr.sql' '(file already exists)'
else
$echo 'x -' extracting 'cidr.sql' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'cidr.sql' &&
---------------------------------------------------------------------------
--
-- cidr.sql-
-- This file defines operators Classless InterDomain Routing entities.
--
---------------------------------------------------------------------------
X
LOAD '/var/home/vixie/postgres-cidrtype/cidr.so';
X
CREATE FUNCTION cidr_in(opaque)
X RETURNS cidr
X AS '/var/home/vixie/postgres-cidrtype/cidr.so'
X LANGUAGE 'c';
X
CREATE FUNCTION cidr_out(opaque)
X RETURNS opaque
X AS '/var/home/vixie/postgres-cidrtype/cidr.so'
X LANGUAGE 'c';
X
CREATE TYPE cidr (
X internallength = 5,
X input = cidr_in,
X output = cidr_out
);
X
CREATE FUNCTION cidr_cmp(cidr, cidr)
X RETURNS int4
X AS '/var/home/vixie/postgres-cidrtype/cidr.so'
X LANGUAGE 'c';
X
-----------------------------
-- Create operators
-----------------------------
X
-- equality (=)
X
CREATE FUNCTION cidr_eq(cidr, cidr)
X RETURNS bool
X AS '/var/home/vixie/postgres-cidrtype/cidr.so'
X LANGUAGE 'c';
X
CREATE OPERATOR = (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_eq,
X commutator = =
);
X
-- inequality (<>)
X
CREATE FUNCTION cidr_ne(cidr, cidr)
X RETURNS bool
X AS '/var/home/vixie/postgres-cidrtype/cidr.so'
X LANGUAGE 'c';
X
CREATE OPERATOR <> (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_ne,
X commutator = <>
);
X
-- less (<, <=)
X
CREATE FUNCTION cidr_lt(cidr, cidr)
X RETURNS bool
X AS '/var/home/vixie/postgres-cidrtype/cidr.so'
X LANGUAGE 'c';
X
CREATE OPERATOR < (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_lt
);
X
CREATE FUNCTION cidr_le(cidr, cidr)
X RETURNS bool
X AS '/var/home/vixie/postgres-cidrtype/cidr.so'
X LANGUAGE 'c';
X
CREATE OPERATOR <= (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_le
);
X
-- greater (>, >=)
X
CREATE FUNCTION cidr_gt(cidr, cidr)
X RETURNS bool
X AS '/var/home/vixie/postgres-cidrtype/cidr.so'
X LANGUAGE 'c';
X
CREATE OPERATOR > (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_gt
);
X
CREATE FUNCTION cidr_ge(cidr, cidr)
X RETURNS bool
X AS '/var/home/vixie/postgres-cidrtype/cidr.so'
X LANGUAGE 'c';
X
CREATE OPERATOR >= (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_ge
);
X
-- subnet (<<, <<=)
X
CREATE FUNCTION cidr_sub(cidr, cidr)
X RETURNS bool
X AS '/var/home/vixie/postgres-cidrtype/cidr.so'
X LANGUAGE 'c';
X
CREATE OPERATOR << (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_sub
);
X
CREATE FUNCTION cidr_subeq(cidr, cidr)
X RETURNS bool
X AS '/var/home/vixie/postgres-cidrtype/cidr.so'
X LANGUAGE 'c';
X
CREATE OPERATOR <<= (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_subeq
);
X
-- supernet (>>, >>=)
X
CREATE FUNCTION cidr_sup(cidr, cidr)
X RETURNS bool
X AS '/var/home/vixie/postgres-cidrtype/cidr.so'
X LANGUAGE 'c';
X
CREATE OPERATOR >> (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_sup
);
X
CREATE FUNCTION cidr_supeq(cidr, cidr)
X RETURNS bool
X AS '/var/home/vixie/postgres-cidrtype/cidr.so'
X LANGUAGE 'c';
X
CREATE OPERATOR >>= (
X leftarg = cidr,
X rightarg = cidr,
X procedure = cidr_supeq
);
X
-- spanning (length of prefix match)
X
CREATE FUNCTION cidr_span(cidr, cidr)
X RETURNS int4
X AS '/var/home/vixie/postgres-cidrtype/cidr.so'
X LANGUAGE 'c';
SHAR_EOF
$shar_touch -am 1201183797 'cidr.sql' &&
chmod 0444 'cidr.sql' ||
$echo 'restore of' 'cidr.sql' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'cidr.sql:' 'MD5 check failed'
097a4f0f2b5915fc5478976233c714f3 cidr.sql
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'cidr.sql'`"
test 3068 -eq "$shar_count" ||
$echo 'cidr.sql:' 'original size' '3068,' 'current size' "$shar_count!"
fi
fi
rm -fr _sh17086
exit 0

#2Tom Ivar Helbekkmo
tih+mail@Hamartun.Priv.NO
In reply to: Paul A Vixie (#1)
Re: [HACKERS] cidr

Paul A Vixie <vixie@vix.com> writes:

i didn't realize that anybody else was working on an IP address
data type or i'd've posted this six months ago when i first wrote
it. it lacks only the stuff needed to make it usable as a UNIQUE
KEY. it depends on BIND-8's libraries.

Interesting -- looks nice at first glance, and does some things that
neither Aleksei nor I had thought of. I guess a merge of the three
variations is in order. At least I'll be doing that locally, and will
make the result available.

-tih
--
Popularity is the hallmark of mediocrity. --Niles Crane, "Frasier"

#3Bruce Momjian
bruce@momjian.us
In reply to: Tom Ivar Helbekkmo (#2)
Re: [HACKERS] cidr

Paul A Vixie <vixie@vix.com> writes:

i didn't realize that anybody else was working on an IP address
data type or i'd've posted this six months ago when i first wrote
it. it lacks only the stuff needed to make it usable as a UNIQUE
KEY. it depends on BIND-8's libraries.

Interesting -- looks nice at first glance, and does some things that
neither Aleksei nor I had thought of. I guess a merge of the three
variations is in order. At least I'll be doing that locally, and will
make the result available.

OK, perhaps I will not apply the patch, and wait for a merged version.

Comments?

-- 
Bruce Momjian                          |  830 Blythe Avenue
maillist@candle.pha.pa.us              |  Drexel Hill, Pennsylvania 19026
  +  If your life is a hard drive,     |  (610) 353-9879(w)
  +  Christ can be your backup.        |  (610) 853-3000(h)
#4Paul A Vixie
vixie@vix.com
In reply to: Tom Ivar Helbekkmo (#2)
Re: [HACKERS] cidr

i didn't realize that anybody else was working on an IP address
data type or i'd've posted this six months ago when i first wrote
it. it lacks only the stuff needed to make it usable as a UNIQUE
KEY. it depends on BIND-8's libraries.

Interesting -- looks nice at first glance, and does some things that
neither Aleksei nor I had thought of. I guess a merge of the three
variations is in order. At least I'll be doing that locally, and will
make the result available.

i would be happy if given a chance to consult with whomever wants to do
the work of merging the various ipaddr proposals, and would even do some
work if appropriate. i would like an indexable "cidr" data type (you
ought not call it an ipaddr, it can be either a net or a host, and the
net is variable sized, so it really is a "cidr") to become part of the
standard postgres system. but i mostly want to use it in apps, and i
mostly wanted to learn how to extend postgres -- i have no undying love
for the implementation i posted here, nor do i know the process for making
this a standard data type. so, i will help if someone else is driving.

#5Bruce Momjian
bruce@momjian.us
In reply to: Paul A Vixie (#4)
Re: [HACKERS] cidr

i didn't realize that anybody else was working on an IP address
data type or i'd've posted this six months ago when i first wrote
it. it lacks only the stuff needed to make it usable as a UNIQUE
KEY. it depends on BIND-8's libraries.

Interesting -- looks nice at first glance, and does some things that
neither Aleksei nor I had thought of. I guess a merge of the three
variations is in order. At least I'll be doing that locally, and will
make the result available.

i would be happy if given a chance to consult with whomever wants to do
the work of merging the various ipaddr proposals, and would even do some
work if appropriate. i would like an indexable "cidr" data type (you
ought not call it an ipaddr, it can be either a net or a host, and the
net is variable sized, so it really is a "cidr") to become part of the
standard postgres system. but i mostly want to use it in apps, and i
mostly wanted to learn how to extend postgres -- i have no undying love
for the implementation i posted here, nor do i know the process for making
this a standard data type. so, i will help if someone else is driving.

Sounds like a plan. Paul is a DNS expert, and we have people involved
who know PostgreSQL well.

As far as the name, we just want a name that makes it clear to novices
what the module does. ip_and_mac is pretty clear. I have no idea what
a cidr is. If you can think of a more descriptive name, let's go for
it.

-- 
Bruce Momjian                          |  830 Blythe Avenue
maillist@candle.pha.pa.us              |  Drexel Hill, Pennsylvania 19026
  +  If your life is a hard drive,     |  (610) 353-9879(w)
  +  Christ can be your backup.        |  (610) 853-3000(h)
#6Paul A Vixie
vixie@vix.com
In reply to: Bruce Momjian (#5)
Re: [HACKERS] cidr

As far as the name, we just want a name that makes it clear to novices what
the module does. ip_and_mac is pretty clear. I have no idea what a cidr
is. If you can think of a more descriptive name, let's go for it.

cidr = classless internet domain routing. it's the "204.152.184/21" notation.

i'm not sure we need a type name that makes sense to novices. what we need
is an example in the "type range" column. if we can say that int2's allowed
ranges are 0 to 65535 and have folks get what we mean without further intro,
then we can teach novices about cidr by saying that allowable ranges are 0/0
through 255.255.255.255/32.

#7The Hermit Hacker
scrappy@hub.org
In reply to: Paul A Vixie (#6)
Re: [HACKERS] cidr

On Mon, 20 Jul 1998, Paul A Vixie wrote:

As far as the name, we just want a name that makes it clear to novices what
the module does. ip_and_mac is pretty clear. I have no idea what a cidr
is. If you can think of a more descriptive name, let's go for it.

cidr = classless internet domain routing. it's the "204.152.184/21" notation.

i'm not sure we need a type name that makes sense to novices. what we need
is an example in the "type range" column. if we can say that int2's allowed
ranges are 0 to 65535 and have folks get what we mean without further intro,
then we can teach novices about cidr by saying that allowable ranges are 0/0
through 255.255.255.255/32.

I have to agree with Paul here...its like mis-representing tuples
as rows and fields as columns. It means the same, but it *isn't* the
proper terminology. By using 'ip_and_mac' where it should be 'cidr', we
are just propogating incorrect terminology...

With that in mind, can we work at having a 'cidr' type as part of
the overall system, vs contrib? I know that *I* would use it alot more if
I didn't have to think of loading it seperately...and I can think of at
least two of my projects that I'd use it in...

Considering that we are now up to three ppl out there that are
willing to work on this, I think we should be able to come up with a
'consensus' as to what we are going to be considering "the standard" for
the base implementation?

Marc G. Fournier
Systems Administrator @ hub.org
primary: scrappy@hub.org secondary: scrappy@{freebsd|postgresql}.org

#8Bruce Momjian
bruce@momjian.us
In reply to: The Hermit Hacker (#7)
Re: [HACKERS] cidr

On Mon, 20 Jul 1998, Paul A Vixie wrote:

As far as the name, we just want a name that makes it clear to novices what
the module does. ip_and_mac is pretty clear. I have no idea what a cidr
is. If you can think of a more descriptive name, let's go for it.

cidr = classless internet domain routing. it's the "204.152.184/21" notation.

i'm not sure we need a type name that makes sense to novices. what we need
is an example in the "type range" column. if we can say that int2's allowed
ranges are 0 to 65535 and have folks get what we mean without further intro,
then we can teach novices about cidr by saying that allowable ranges are 0/0
through 255.255.255.255/32.

Paul, yes, I have seen this address style on several machines, and I
understand it supersede the class A,B,C addresses by allowing arbitrary
netmasks.

We can call it cidr. That is fine. I was just concerned that if we put
it in contrib, that people who have never heard of cidr, like me, can
recognize the usefulness of the type for their applications.

Also, I would assume we can handle old-style non-cidr address just as
cleanly, so both cidr and non-cidr can use the same type and functions.

I have to agree with Paul here...its like mis-representing tuples
as rows and fields as columns. It means the same, but it *isn't* the
proper terminology. By using 'ip_and_mac' where it should be 'cidr', we
are just propagating incorrect terminology...

With that in mind, can we work at having a 'cidr' type as part of
the overall system, vs contrib? I know that *I* would use it alot more if
I didn't have to think of loading it separately...and I can think of at
least two of my projects that I'd use it in...

Considering that we are now up to three ppl out there that are
willing to work on this, I think we should be able to come up with a
'consensus' as to what we are going to be considering "the standard" for
the base implementation?

Yes, I agree, this is a HOT type, and should be installed in the default
system. Contrib is for testing/narrow audience, and this type certainly
should be mainstream. This is the third generation of the type, with a
wide audience. int8 is also coming into the main tree via Thomas.

-- 
Bruce Momjian                          |  830 Blythe Avenue
maillist@candle.pha.pa.us              |  Drexel Hill, Pennsylvania 19026
  +  If your life is a hard drive,     |  (610) 353-9879(w)
  +  Christ can be your backup.        |  (610) 853-3000(h)
#9Bruce Momjian
bruce@momjian.us
In reply to: Paul A Vixie (#6)
Re: [HACKERS] cidr

As far as the name, we just want a name that makes it clear to novices what
the module does. ip_and_mac is pretty clear. I have no idea what a cidr
is. If you can think of a more descriptive name, let's go for it.

cidr = classless internet domain routing. it's the "204.152.184/21" notation.

i'm not sure we need a type name that makes sense to novices. what we need
is an example in the "type range" column. if we can say that int2's allowed
ranges are 0 to 65535 and have folks get what we mean without further intro,
then we can teach novices about cidr by saying that allowable ranges are 0/0
through 255.255.255.255/32.

If we make it a standard type, not contrib, we can add a pg_description
entry for it so \dT shows the valid range of values.
Functions/operators also get descriptions for \do and \df. Should be
easy.

-- 
Bruce Momjian                          |  830 Blythe Avenue
maillist@candle.pha.pa.us              |  Drexel Hill, Pennsylvania 19026
  +  If your life is a hard drive,     |  (610) 353-9879(w)
  +  Christ can be your backup.        |  (610) 853-3000(h)
#10The Hermit Hacker
scrappy@hub.org
In reply to: Bruce Momjian (#8)
Re: [HACKERS] cidr

On Mon, 20 Jul 1998, Bruce Momjian wrote:

We can call it cidr. That is fine. I was just concerned that if we put
it in contrib, that people who have never heard of cidr, like me, can
recognize the usefulness of the type for their applications.

IMHO, those that will use it, will know what it is...AFAIK, CIDR
is a pretty generic/standard term, one that I've known for at least 6
years now, so it isn't really "new-style".

Yes, I agree, this is a HOT type, and should be installed in the default
system. Contrib is for testing/narrow audience, and this type certainly
should be mainstream. This is the third generation of the type, with a
wide audience. int8 is also coming into the main tree via Thomas.

Contrib for v6.4, mainstream by v6.5?

Marc G. Fournier
Systems Administrator @ hub.org
primary: scrappy@hub.org secondary: scrappy@{freebsd|postgresql}.org

#11Bruce Momjian
bruce@momjian.us
In reply to: The Hermit Hacker (#10)
Re: [HACKERS] cidr

On Mon, 20 Jul 1998, Bruce Momjian wrote:

We can call it cidr. That is fine. I was just concerned that if we put
it in contrib, that people who have never heard of cidr, like me, can
recognize the usefulness of the type for their applications.

IMHO, those that will use it, will know what it is...AFAIK, CIDR
is a pretty generic/standard term, one that I've known for at least 6
years now, so it isn't really "new-style".

Yes, I agree, this is a HOT type, and should be installed in the default
system. Contrib is for testing/narrow audience, and this type certainly
should be mainstream. This is the third generation of the type, with a
wide audience. int8 is also coming into the main tree via Thomas.

Contrib for v6.4, mainstream by v6.5?

ip_and_mac was contrib for 6.3. Why not mainstream for 6.4?

-- 
Bruce Momjian                          |  830 Blythe Avenue
maillist@candle.pha.pa.us              |  Drexel Hill, Pennsylvania 19026
  +  If your life is a hard drive,     |  (610) 353-9879(w)
  +  Christ can be your backup.        |  (610) 853-3000(h)
#12Matthew N. Dodd
winter@jurai.net
In reply to: Bruce Momjian (#5)
Re: [HACKERS] cidr

On Mon, 20 Jul 1998, Bruce Momjian wrote:

As far as the name, we just want a name that makes it clear to novices
what the module does. ip_and_mac is pretty clear. I have no idea what
a cidr is. If you can think of a more descriptive name, let's go for
it.

I think most people who would use the IP related types do know what a CIDR
is.

An IP address should be just that, a discrete IP, no netmask, nothing.

A CIDR is a type able to represent a range of IP addresses (what one of
the previous patches did by storing an address and a netmask.)

MAC addresses speak for themselves.

I'll let others describe all the nifty functions that the first two types
will/can have (IP - IP, IP - CIDR, CIDR - CIDR).

/*
Matthew N. Dodd | A memory retaining a love you had for life
winter@jurai.net | As cruel as it seems nothing ever seems to
http://www.jurai.net/~winter | go right - FLA M 3.1:53
*/

#13The Hermit Hacker
scrappy@hub.org
In reply to: Bruce Momjian (#11)
Re: [HACKERS] cidr

On Mon, 20 Jul 1998, Bruce Momjian wrote:

On Mon, 20 Jul 1998, Bruce Momjian wrote:

We can call it cidr. That is fine. I was just concerned that if we put
it in contrib, that people who have never heard of cidr, like me, can
recognize the usefulness of the type for their applications.

IMHO, those that will use it, will know what it is...AFAIK, CIDR
is a pretty generic/standard term, one that I've known for at least 6
years now, so it isn't really "new-style".

Yes, I agree, this is a HOT type, and should be installed in the default
system. Contrib is for testing/narrow audience, and this type certainly
should be mainstream. This is the third generation of the type, with a
wide audience. int8 is also coming into the main tree via Thomas.

Contrib for v6.4, mainstream by v6.5?

ip_and_mac was contrib for 6.3. Why not mainstream for 6.4?

That works even better...:)

Marc G. Fournier
Systems Administrator @ hub.org
primary: scrappy@hub.org secondary: scrappy@{freebsd|postgresql}.org

#14D'Arcy J.M. Cain
darcy@druid.net
In reply to: Bruce Momjian (#8)
Re: [HACKERS] cidr

Thus spake Bruce Momjian

Paul, yes, I have seen this address style on several machines, and I
understand it supersede the class A,B,C addresses by allowing arbitrary
netmasks.

Exactly.

We can call it cidr. That is fine. I was just concerned that if we put
it in contrib, that people who have never heard of cidr, like me, can
recognize the usefulness of the type for their applications.

CIDR is getting to be pretty well known. Most people who need the type
should understand it.

Also, I would assume we can handle old-style non-cidr address just as
cleanly, so both cidr and non-cidr can use the same type and functions.

Yes. The old class system is just 3 special cases (Well, 4 really) of
CIDR.

Yes, I agree, this is a HOT type, and should be installed in the default
system. Contrib is for testing/narrow audience, and this type certainly
should be mainstream. This is the third generation of the type, with a
wide audience. int8 is also coming into the main tree via Thomas.

I missed some of the earlier discussion. Is there going to be a separate
IP type or is that just x.x.x.x/32? I like the idea of a host type as
well. I would love to sort my IPs and have 198.96.119.99 precede
198.96.119.100.

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#15Paul A Vixie
vixie@vix.com
In reply to: The Hermit Hacker (#7)
Re: [HACKERS] cidr

With that in mind, can we work at having a 'cidr' type as part of
the overall system, vs contrib? I know that *I* would use it alot more if
I didn't have to think of loading it seperately...and I can think of at
least two of my projects that I'd use it in...

me too. i'm already using it in fact. i just don't know how to make it
indexable. having it be a standard type, with someone who knows postgres
making it indexable, would be really great for the MAPS project and for
some WHOIS/LDAP stuff we're doing here.

Considering that we are now up to three ppl out there that are
willing to work on this, I think we should be able to come up with a
'consensus' as to what we are going to be considering "the standard" for
the base implementation?

i remain ready to help anyone who promises to drive this thing. and while
i feel that "cidr" is the right name, i don't feel it strongly enough to
refuse to help unless that name is chosen. i need the functionality, and
if it appears under some other name i will use it under that name.

#16Paul A Vixie
vixie@vix.com
In reply to: Bruce Momjian (#8)
Re: [HACKERS] cidr

Also, I would assume we can handle old-style non-cidr address just as
cleanly, so both cidr and non-cidr can use the same type and functions.

the implementation i sent around yesterday does this just fine. or rather
it makes useful assumptions if no "/" is given, and it always prints the "/".

#17Bruce Momjian
bruce@momjian.us
In reply to: D'Arcy J.M. Cain (#14)
Re: [HACKERS] cidr

Yes, I agree, this is a HOT type, and should be installed in the default
system. Contrib is for testing/narrow audience, and this type certainly
should be mainstream. This is the third generation of the type, with a
wide audience. int8 is also coming into the main tree via Thomas.

I missed some of the earlier discussion. Is there going to be a separate
IP type or is that just x.x.x.x/32? I like the idea of a host type as
well. I would love to sort my IPs and have 198.96.119.99 precede
198.96.119.100.

My guess is that it is going to output x.x.x.x/32, but we should supply
a function so they can get just the IP or the mask from the type. That
way, people who don't want the cidr format can pull out the part they
want.

If they don't specify a netmask when they load the value, perhaps we use
the standard class A,B,C netmasks. How you specify a HOST address using
the non-cidr format, I really don't know. I am sure the experts will
hash it out before 6.4 beta on September 1.

-- 
Bruce Momjian                          |  830 Blythe Avenue
maillist@candle.pha.pa.us              |  Drexel Hill, Pennsylvania 19026
  +  If your life is a hard drive,     |  (610) 353-9879(w)
  +  Christ can be your backup.        |  (610) 853-3000(h)
#18Bruce Momjian
bruce@momjian.us
In reply to: Paul A Vixie (#15)
Re: [HACKERS] cidr

With that in mind, can we work at having a 'cidr' type as part of
the overall system, vs contrib? I know that *I* would use it alot more if
I didn't have to think of loading it seperately...and I can think of at
least two of my projects that I'd use it in...

me too. i'm already using it in fact. i just don't know how to make it
indexable. having it be a standard type, with someone who knows postgres
making it indexable, would be really great for the MAPS project and for
some WHOIS/LDAP stuff we're doing here.

Considering that we are now up to three ppl out there that are
willing to work on this, I think we should be able to come up with a
'consensus' as to what we are going to be considering "the standard" for
the base implementation?

i remain ready to help anyone who promises to drive this thing. and while
i feel that "cidr" is the right name, i don't feel it strongly enough to
refuse to help unless that name is chosen. i need the functionality, and
if it appears under some other name i will use it under that name.

We will keep the 'cidr' name, as far as I am concerned. People seem to
know what it means, and we will mention it is for IP network/host
addresses.

In fact, if it is installed in the system, it will be hard for anyone
looking for an IP type to miss.

-- 
Bruce Momjian                          |  830 Blythe Avenue
maillist@candle.pha.pa.us              |  Drexel Hill, Pennsylvania 19026
  +  If your life is a hard drive,     |  (610) 353-9879(w)
  +  Christ can be your backup.        |  (610) 853-3000(h)
#19Paul A Vixie
vixie@vix.com
In reply to: D'Arcy J.M. Cain (#14)
Re: [HACKERS] cidr

I missed some of the earlier discussion. Is there going to be a separate
IP type or is that just x.x.x.x/32? I like the idea of a host type as
well. I would love to sort my IPs and have 198.96.119.99 precede
198.96.119.100.

the ordering functions given in the implementation i posted here yesterday
do that, and they also show 192.5.5/24 as being "before" 192.5.5.0/32, which
is important for those of us who import routing tables into database tables.

i don't see a need for a separate type for /32's; if someone enters just the
dotted quad (198.96.119.100 for example) the "/32" will be assumed. i'd be
willing to see the "/32" stripped off in the output function since it's a bit
redundant -- i didn't do that but it's out of habit rather than strong belief.

if folks really can't get behind "CIDR" then may i suggest "INET"? it's not
a "NET" or an "IPADDR" or "INADDR" or "INNET" or "HOST". it is capable of
representing either a network or a host, classlessly. that makes it a CIDR
to those in the routing or registry business. and before someone asks: no,
it is not IPv4-specific. my implementation encodes the address family and
is capable of supporting IPv6 if the "internallength" wants to be 13 or if
someone knows how to make it variable-length.

#20Bruce Momjian
bruce@momjian.us
In reply to: Paul A Vixie (#15)
Re: [HACKERS] cidr

With that in mind, can we work at having a 'cidr' type as part of
the overall system, vs contrib? I know that *I* would use it alot more if
I didn't have to think of loading it seperately...and I can think of at
least two of my projects that I'd use it in...

me too. i'm already using it in fact. i just don't know how to make it
indexable. having it be a standard type, with someone who knows postgres
making it indexable, would be really great for the MAPS project and for
some WHOIS/LDAP stuff we're doing here.

Considering that we are now up to three ppl out there that are
willing to work on this, I think we should be able to come up with a
'consensus' as to what we are going to be considering "the standard" for
the base implementation?

i remain ready to help anyone who promises to drive this thing. and while
i feel that "cidr" is the right name, i don't feel it strongly enough to
refuse to help unless that name is chosen. i need the functionality, and
if it appears under some other name i will use it under that name.

This could clearly be a KILLER APP/TYPE for us. This is a pretty
sophisticated use of our type system. Indexing should present no
problems. We supply the comparison routines and plug them in, and the
optimizer automatically uses the indexes.

-- 
Bruce Momjian                          |  830 Blythe Avenue
maillist@candle.pha.pa.us              |  Drexel Hill, Pennsylvania 19026
  +  If your life is a hard drive,     |  (610) 353-9879(w)
  +  Christ can be your backup.        |  (610) 853-3000(h)
#21Paul A Vixie
vixie@vix.com
In reply to: Bruce Momjian (#17)
#22Paul A Vixie
vixie@vix.com
In reply to: Bruce Momjian (#20)
#23Bruce Momjian
bruce@momjian.us
In reply to: Paul A Vixie (#19)
#24Bruce Momjian
bruce@momjian.us
In reply to: Paul A Vixie (#21)
#25Bruce Momjian
bruce@momjian.us
In reply to: Paul A Vixie (#22)
#26Paul A Vixie
vixie@vix.com
In reply to: Bruce Momjian (#23)
#27The Hermit Hacker
scrappy@hub.org
In reply to: Paul A Vixie (#16)
#28The Hermit Hacker
scrappy@hub.org
In reply to: Bruce Momjian (#23)
#29The Hermit Hacker
scrappy@hub.org
In reply to: Paul A Vixie (#26)
#30Matthew N. Dodd
winter@jurai.net
In reply to: Paul A Vixie (#19)
#31Nick Bastin
nbastin@rbbsystems.com
In reply to: Paul A Vixie (#26)
#32Bruce Momjian
bruce@momjian.us
In reply to: Paul A Vixie (#26)
#33Bruce Momjian
bruce@momjian.us
In reply to: The Hermit Hacker (#27)
#34Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#33)
#35Vince Vielhaber
vev@michvhf.com
In reply to: The Hermit Hacker (#29)
#36Bruce Momjian
bruce@momjian.us
In reply to: Matthew N. Dodd (#30)
#37Bruce Momjian
bruce@momjian.us
In reply to: Nick Bastin (#31)
#38Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#34)
#39Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#38)
#40Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#39)
#41D'Arcy J.M. Cain
darcy@druid.net
In reply to: Bruce Momjian (#33)
#42Paul A Vixie
vixie@vix.com
In reply to: Matthew N. Dodd (#30)
#43Vince Vielhaber
vev@michvhf.com
In reply to: Paul A Vixie (#42)
#44Bruce Momjian
bruce@momjian.us
In reply to: Paul A Vixie (#42)
#45Bruce Momjian
bruce@momjian.us
In reply to: Vince Vielhaber (#43)
#46D'Arcy J.M. Cain
darcy@druid.net
In reply to: Bruce Momjian (#45)
#47Hal Snyder
hal@roxor.org
In reply to: Paul A Vixie (#21)
#48The Hermit Hacker
scrappy@hub.org
In reply to: Tom Lane (#34)
#49The Hermit Hacker
scrappy@hub.org
In reply to: Bruce Momjian (#45)
#50Bruce Momjian
bruce@momjian.us
In reply to: D'Arcy J.M. Cain (#46)
#51Bruce Momjian
bruce@momjian.us
In reply to: The Hermit Hacker (#49)
#52The Hermit Hacker
scrappy@hub.org
In reply to: Bruce Momjian (#50)
#53D'Arcy J.M. Cain
darcy@druid.net
In reply to: Bruce Momjian (#50)
#54Bruce Momjian
bruce@momjian.us
In reply to: D'Arcy J.M. Cain (#53)
#55D'Arcy J.M. Cain
darcy@druid.net
In reply to: Bruce Momjian (#54)
#56Bruce Momjian
bruce@momjian.us
In reply to: D'Arcy J.M. Cain (#55)
#57Paul A Vixie
paul@vix.com
In reply to: Bruce Momjian (#50)
#58D'Arcy J.M. Cain
darcy@druid.net
In reply to: Bruce Momjian (#56)
#59D'Arcy J.M. Cain
darcy@druid.net
In reply to: Paul A Vixie (#57)
#60Bruce Momjian
bruce@momjian.us
In reply to: D'Arcy J.M. Cain (#58)
#61D'Arcy J.M. Cain
darcy@druid.net
In reply to: Bruce Momjian (#60)
#62Bruce Momjian
bruce@momjian.us
In reply to: D'Arcy J.M. Cain (#61)