OK. Here it is - PtP patch from Andrew J. Schorr. No problems with ospfd,
ripd might need some more testing though.
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 31fb15b..d0a33d4 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,18 @@
+2004-10-19 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+	* zclient.c: (zebra_interface_address_read) If the destination address
+	  is encoded as all zeroes, load it as a NULL pointer.
+	* if.h: Add comment describing struct connected destination field
+	  and indicating that it may be NULL.  Define macros
+	  CONNECTED_DEST_HOST and CONNECTED_POINTOPOINT_HOST to help
+	  with PtP logic (distinguish between host and subnet addressing).
+	* if.c: (if_lookup_address) Fix PtP logic to handle subnet addressing
+	  properly,
+	  (connected_lookup_address) ditto.
+	  (connected_add_by_prefix) Handle case where destination is NULL,
+	* prefix.[c|h]: New functions ipv4_network_addr and
+	  ipv4_broadcast_addr.
+
 2004-10-13 Hasso Tepper <hasso at quagga.net>
 
 	* command.c: Make CMD_ERR_NOTHING_TODO nonfatal if reading
diff --git a/lib/if.c b/lib/if.c
index 259b842..5519b2a 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -258,17 +258,13 @@
 {
   struct listnode *node;
   struct prefix addr;
-  struct prefix best;
+  int bestlen = 0;
   struct listnode *cnode;
   struct interface *ifp;
   struct prefix *p;
   struct connected *c;
   struct interface *match;
 
-  /* Zero structures - get rid of rubbish from stack */
-  memset(&addr, 0, sizeof(addr));
-  memset(&best, 0, sizeof(best));
-
   addr.family = AF_INET;
   addr.u.prefix4 = src;
   addr.prefixlen = IPV4_MAX_BITLEN;
@@ -283,31 +279,22 @@
 	{
 	  c = getdata (cnode);
 
-	  if (if_is_pointopoint (ifp))
+	  if (c->address && (c->address->family == AF_INET))
 	    {
-	      p = c->address;
-
-	      if (p && p->family == AF_INET)
+	      if (CONNECTED_POINTOPOINT_HOST(c))
 		{
-#ifdef OLD_RIB	 /* PTP  links are conventionally identified 
-		     by the address of the far end - MAG */
-		  if (IPV4_ADDR_SAME (&p->u.prefix4, &src))
-		    return ifp;
-#endif
-		  p = c->destination;
-		  if (p && IPV4_ADDR_SAME (&p->u.prefix4, &src))
+		 /* PTP  links are conventionally identified 
+		    by the address of the far end - MAG */
+		  if (IPV4_ADDR_SAME (&c->destination->u.prefix4, &src))
 		    return ifp;
 		}
-	    }
-	  else
-	    {
-	      p = c->address;
-
-	      if (p->family == AF_INET)
+	      else
 		{
-		  if (prefix_match (p, &addr) && p->prefixlen > best.prefixlen)
+		  p = c->address;
+
+		  if (prefix_match (p, &addr) && p->prefixlen > bestlen)
 		    {
-		      best = *p;
+		      bestlen = p->prefixlen;
 		      match = ifp;
 		    }
 		}
@@ -680,16 +667,11 @@
 connected_lookup_address (struct interface *ifp, struct in_addr dst)
 {
   struct prefix addr;
-  struct prefix best;
   struct listnode *cnode;
   struct prefix *p;
   struct connected *c;
   struct connected *match;
 
-  /* Zero structures - get rid of rubbish from stack */
-  memset(&addr, 0, sizeof(addr));
-  memset(&best, 0, sizeof(best));
-
   addr.family = AF_INET;
   addr.u.prefix4 = dst;
   addr.prefixlen = IPV4_MAX_BITLEN;
@@ -700,35 +682,24 @@
     {
       c = getdata (cnode);
 
-      if (if_is_pointopoint (ifp))
-	{
-	  p = c->address;
-
-	  if (p && p->family == AF_INET)
+      if (c->address && (c->address->family == AF_INET))
+        {
+	  if (CONNECTED_POINTOPOINT_HOST(c))
 	    {
-#ifdef OLD_RIB	 /* PTP  links are conventionally identified 
-		    by the address of the far end - MAG */
-	      if (IPV4_ADDR_SAME (&p->u.prefix4, &dst))
-		return c;
-#endif
-	      p = c->destination;
-	      if (p && IPV4_ADDR_SAME (&p->u.prefix4, &dst))
+		     /* PTP  links are conventionally identified 
+			by the address of the far end - MAG */
+	      if (IPV4_ADDR_SAME (&c->destination->u.prefix4, &dst))
 		return c;
 	    }
-	}
-      else
-	{
-	  p = c->address;
-
-	  if (p->family == AF_INET)
+	  else
 	    {
-	      if (prefix_match (p, &addr) && p->prefixlen > best.prefixlen)
-		{
-		  best = *p;
-		  match = c;
-		}
+	      p = c->address;
+
+	      if (prefix_match (p, &addr) &&
+	      	  (!match || (p->prefixlen > match->address->prefixlen)))
+		match = c;
 	    }
-	}
+        }
     }
   return match;
 }
@@ -748,8 +719,11 @@
   memcpy (ifc->address, p, sizeof(struct prefix));
 
   /* Fetch dest address */
-  ifc->destination = prefix_new();
-  memcpy (ifc->destination, destination, sizeof(struct prefix));
+  if (destination)
+    {
+      ifc->destination = prefix_new();
+      memcpy (ifc->destination, destination, sizeof(struct prefix));
+    }
 
   /* Add connected address to the interface. */
   listnode_add (ifp->connected, ifc);
diff --git a/lib/if.h b/lib/if.h
index 218f102..7afb2ae 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -148,12 +148,23 @@
 
   /* Address of connected network. */
   struct prefix *address;
-  struct prefix *destination;
+  struct prefix *destination; /* broadcast or peer address; may be NULL */
 
   /* Label for Linux 2.2.X and upper. */
   char *label;
 };
 
+/* Given an IPV4 struct connected, this macro determines whether a /32
+   peer address has been supplied (i.e. there is no subnet assigned) */
+#define CONNECTED_DEST_HOST(C) \
+	((C)->destination && ((C)->address->prefixlen == IPV4_MAX_PREFIXLEN))
+
+/* Given an IPV4 struct connected, this macro determins whether it is
+   a point-to-point link with a /32 peer address (i.e. there
+   is no dedicated subnet for the PtP link) */
+#define CONNECTED_POINTOPOINT_HOST(C) \
+	(((C)->ifp->flags & IFF_POINTOPOINT) && CONNECTED_DEST_HOST(C))
+
 /* Interface hook sort. */
 #define IF_NEW_HOOK   0
 #define IF_DELETE_HOOK 1
diff --git a/lib/prefix.c b/lib/prefix.c
index d9751e3..3f3c4e8 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -247,7 +247,7 @@
 
       /* Get prefix length. */
       plen = (u_char) atoi (++pnt);
-      if (plen > 32)
+      if (plen > IPV4_MAX_PREFIXLEN)
 	return 0;
 
       p->family = AF_INET;
@@ -648,7 +648,7 @@
   
   destination = ntohl (p->prefix.s_addr);
   
-  if (p->prefixlen == 32);
+  if (p->prefixlen == IPV4_MAX_PREFIXLEN);
   /* do nothing for host routes */
   else if (IN_CLASSC (destination)) 
     {
@@ -667,6 +667,28 @@
     }
 }
 
+in_addr_t
+ipv4_network_addr (in_addr_t hostaddr, int masklen)
+{
+  struct in_addr mask;
+
+  masklen2ip (masklen, &mask);
+  return hostaddr & mask.s_addr;
+}
+
+in_addr_t
+ipv4_broadcast_addr (in_addr_t hostaddr, int masklen)
+{
+  struct in_addr mask;
+
+  masklen2ip (masklen, &mask);
+  return (masklen != IPV4_MAX_PREFIXLEN-1) ?
+	 /* normal case */
+         (hostaddr | ~mask.s_addr) :
+	 /* special case for /31 */
+         (hostaddr ^ ~mask.s_addr);
+}
+
 /* Utility function to convert ipv4 netmask to prefixes 
    ex.) "1.1.0.0" "255.255.0.0" => "1.1.0.0/16"
    ex.) "1.0.0.0" NULL => "1.0.0.0/8"                   */
diff --git a/lib/prefix.h b/lib/prefix.h
index e4f17ab..0546095 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -153,6 +153,14 @@
 
 u_char ip_masklen (struct in_addr);
 void masklen2ip (int, struct in_addr *);
+/* returns the network portion of the host address */
+in_addr_t ipv4_network_addr (in_addr_t hostaddr, int masklen);
+/* given the address of a host on a network and the network mask length,
+ * calculate the broadcast address for that network;
+ * special treatment for /31: returns the address of the other host
+ * on the network by flipping the host bit */
+in_addr_t ipv4_broadcast_addr (in_addr_t hostaddr, int masklen);
+
 int netmask_str2prefix_str (const char *, const char *, char *);
 
 #ifdef HAVE_IPV6
diff --git a/lib/zclient.c b/lib/zclient.c
index 98829f6..dfb2f2f 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -644,6 +644,17 @@
   ifp->bandwidth = stream_getl (s);
 }
 
+static int
+memconstant(const void *s, int c, size_t n)
+{
+  const u_char *p = s;
+
+  while (n-- > 0)
+    if (*p++ != c)
+      return 0;
+  return 1;
+}
+
 struct connected *
 zebra_interface_address_read (int type, struct stream *s)
 {
@@ -688,7 +699,9 @@
 
   if (type == ZEBRA_INTERFACE_ADDRESS_ADD) 
     {
-       ifc = connected_add_by_prefix(ifp, &p, &d);
+       /* N.B. NULL destination pointers are encoded as all zeroes */
+       ifc = connected_add_by_prefix(ifp, &p,(memconstant(&d.u.prefix,0,plen) ?
+					      NULL : &d));
        if (ifc != NULL)
        ifc->flags = ifc_flags;
     }