OK. Here it is - PtP patch from Andrew J. Schorr. No problems with ospfd,
ripd might need some more testing though.
diff --git a/ripd/ChangeLog b/ripd/ChangeLog
index ee878ff..ae67e72 100644
--- a/ripd/ChangeLog
+++ b/ripd/ChangeLog
@@ -1,3 +1,15 @@
+2004-10-19 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+	* ripd.c: (rip_update_interface) if connected->destination is NULL,
+	  get the broadcast address with ipv4_broadcast_addr()
+	* rip_interface.c: (rip_interface_multicast_set)
+	  connected->destination may be NULL. Improve message if
+	  setsockopt_multicast_ipv4 fails. Improve message if bind fails.
+	  (rip_request_interface_send) If connected->destination is NULL,
+	  get the broadcast address with ipv4_broadcast_addr().
+	  (if_valid_neighbor) Handle PtP subnet addressing properly.
+	  Speed up code by using prefix_match properly.
+
 2004-10-13 Hasso Tepper <hasso at quagga.net>
 
 	* ripd_snmp.c: Remove defaults used to initialize smux connection to
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index 509d5ed..19f6f11 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -143,16 +143,16 @@
   int ret;
   struct servent *sp;
   struct sockaddr_in from;
-      struct in_addr addr;
+  struct in_addr addr;
   struct prefix_ipv4 *p;
 
   if (connected != NULL) 
     {
-  if (if_is_pointopoint(connected->ifp))
-    p = (struct prefix_ipv4 *) connected->destination;
-  else
-      p = (struct prefix_ipv4 *) connected->address;
-	  addr = p->prefix;
+      if (if_is_pointopoint(connected->ifp) && CONNECTED_DEST_HOST(connected))
+	p = (struct prefix_ipv4 *) connected->destination;
+      else
+	p = (struct prefix_ipv4 *) connected->address;
+      addr = p->prefix;
     }
   else 
     {
@@ -161,46 +161,52 @@
 
   if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF, addr, 0, 
                                  connected->ifp->ifindex) < 0) 
-	    {
-	      zlog_warn ("Can't setsockopt IP_MULTICAST_IF to fd %d, ifindex %d", 
-	                 sock, connected->ifp->ifindex);
-	      return;
-	    }
+    {
+      zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
+		 "source address %s for interface %s",
+		 sock, inet_ntoa(addr),
+		 (connected ? connected->ifp->name : "(unknown)"));
+      return;
+    }
 
-	  /* Bind myself. */
-	  memset (&from, 0, sizeof (struct sockaddr_in));
+  /* Bind myself. */
+  memset (&from, 0, sizeof (struct sockaddr_in));
 
-	  /* Set RIP port. */
-	  sp = getservbyname ("router", "udp");
-	  if (sp) 
-	    from.sin_port = sp->s_port;
-	  else 
-	    from.sin_port = htons (RIP_PORT_DEFAULT);
+  /* Set RIP port. */
+  sp = getservbyname ("router", "udp");
+  if (sp) 
+    from.sin_port = sp->s_port;
+  else 
+    from.sin_port = htons (RIP_PORT_DEFAULT);
 
   /* Address should be any address. */
-	  from.sin_family = AF_INET;
+  from.sin_family = AF_INET;
   if (connected)
-  addr = ((struct prefix_ipv4 *) connected->address)->prefix;
-	  from.sin_addr = addr;
+    addr = ((struct prefix_ipv4 *) connected->address)->prefix;
+  from.sin_addr = addr;
 #ifdef HAVE_SIN_LEN
-	  from.sin_len = sizeof (struct sockaddr_in);
+  from.sin_len = sizeof (struct sockaddr_in);
 #endif /* HAVE_SIN_LEN */
 
-    if (ripd_privs.change (ZPRIVS_RAISE))
-      zlog_err ("rip_interface_multicast_set: could not raise privs");
+  if (ripd_privs.change (ZPRIVS_RAISE))
+    zlog_err ("rip_interface_multicast_set: could not raise privs");
       
   ret = bind (sock, (struct sockaddr *) & from, sizeof (struct sockaddr_in));
-	  if (ret < 0)
-	    {
-	      zlog_warn ("Can't bind socket: %s", strerror (errno));
-	    }
+  if (ret < 0)
+    {
+      zlog_warn ("Can't bind socket fd %d to %s port %d for "
+		 "interface %s: %s",
+	      	 sock,inet_ntoa(from.sin_addr),
+		 (int)ntohs(from.sin_port),
+		 (connected ? connected->ifp->name : "(unknown)"),
+		  strerror (errno));
+    }
 
-    if (ripd_privs.change (ZPRIVS_LOWER))
-        zlog_err ("rip_interface_multicast_set: could not lower privs");
+  if (ripd_privs.change (ZPRIVS_LOWER))
+    zlog_err ("rip_interface_multicast_set: could not lower privs");
 
-	  return;
-
-	}
+  return;
+}
 
 /* Send RIP request packet to specified interface. */
 void
@@ -229,17 +235,22 @@
 
       for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
 	{
-	  struct prefix_ipv4 *p;
 	  struct connected *connected;
 
 	  connected = getdata (cnode);
-	  p = (struct prefix_ipv4 *) connected->destination;
 
-	  if (p->family == AF_INET)
+	  if (connected->address->family == AF_INET)
 	    {
 	      memset (&to, 0, sizeof (struct sockaddr_in));
 	      to.sin_port = htons (RIP_PORT_DEFAULT);
-	      to.sin_addr = p->prefix;
+              if (connected->destination)
+                /* use specified broadcast or point-to-point destination addr */
+                to.sin_addr = connected->destination->u.prefix4;
+              else
+	        /* calculate the appropriate broadcast address */
+                to.sin_addr.s_addr =
+		  ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
+				      connected->address->prefixlen);
 
 	      if (IS_RIP_DEBUG_EVENT)
 		zlog_info ("SEND request to %s", inet_ntoa (to.sin_addr));
@@ -439,6 +450,11 @@
   struct listnode *node;
   struct connected *connected = NULL;
   struct prefix_ipv4 *p;
+  struct prefix_ipv4 pa;
+
+  pa.family = AF_INET;
+  pa.prefix = addr;
+  pa.prefixlen = IPV4_MAX_PREFIXLEN;
 
   for (node = listhead (iflist); node; nextnode (node))
     {
@@ -449,9 +465,6 @@
 
       for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
 	{
-	  struct prefix *pxn = NULL; /* Prefix of the neighbor */
-	  struct prefix *pxc = NULL; /* Prefix of the connected network */
-
 	  connected = getdata (cnode);
 
 	  if (if_is_pointopoint (ifp))
@@ -464,34 +477,23 @@
 		    return 1;
 
 		  p = (struct prefix_ipv4 *) connected->destination;
-		  if (p && IPV4_ADDR_SAME (&p->prefix, &addr))
-		    return 1;
+		  if (p)
+		    {
+		      if (IPV4_ADDR_SAME (&p->prefix, &addr))
+			return 1;
+		    }
+		  else
+		    {
+		      if (prefix_match(connected->address,(struct prefix *)&pa))
+			return 1;
+		    }
 		}
 	    }
 	  else
 	    {
-	      p = (struct prefix_ipv4 *) connected->address;
-
-	      if (p->family != AF_INET)
-		continue;
-
-	      pxn = prefix_new();
-	      pxn->family = AF_INET;
-	      pxn->prefixlen = 32;
-	      pxn->u.prefix4 = addr;
-	      
-	      pxc = prefix_new();
-	      prefix_copy(pxc, (struct prefix *) p);
-	      apply_mask(pxc);
-	  
-	      if (prefix_match (pxc, pxn)) 
-		{
-		  prefix_free (pxn);
-		  prefix_free (pxc);
-		  return 1;
-		}
-	      prefix_free(pxc);
-	      prefix_free(pxn);
+	      if ((connected->address->family == AF_INET) &&
+		  prefix_match(connected->address,(struct prefix *)&pa))
+		return 1;
 	    }
 	}
     }
diff --git a/ripd/ripd.c b/ripd/ripd.c
index 2b4e1b2..94324f0 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -2391,7 +2391,6 @@
 rip_update_interface (struct interface *ifp, u_char version, int route_type,
                       struct connected *sconn)
 {
-  struct prefix_ipv4 *p;
   struct connected *connected;
   struct listnode *node;
   struct sockaddr_in to;
@@ -2415,15 +2414,18 @@
 	{	    
 	  connected = getdata (node);
 
-	  /* Fetch broadcast address or poin-to-point destination
-             address . */
-	  p = (struct prefix_ipv4 *) connected->destination;
-
-	  if (p->family == AF_INET)
+	  if (connected->address->family == AF_INET)
 	    {
 	      /* Destination address and port setting. */
 	      memset (&to, 0, sizeof (struct sockaddr_in));
-	      to.sin_addr = p->prefix;
+	      if (connected->destination)
+		/* use specified broadcast or point-to-point destination addr */
+	        to.sin_addr = connected->destination->u.prefix4;
+	      else
+		/* calculate the appropriate broadcast address */
+	        to.sin_addr.s_addr =
+		  ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
+				      connected->address->prefixlen);
 	      to.sin_port = htons (RIP_PORT_DEFAULT);
 
 	      if (IS_RIP_DEBUG_EVENT)