2005-06-03 Paul Jakma <paul.jakma@sun.com>

	* ripd.c: (rip_create_socket) Make it static.
	  Remove the getservbyname stuff, as RFC2453 3.9.2 says non-RIP
	  port messages should be discarded, quagga doesnt accept them,
	  no need to lookup port.
	  Take a 'to' argument, if socket should be bound to something else.
	  setsockopt_so_recvbuf might need privs, move it to the raised
	  privileges section.
	  dont forget to close the socket if bind fails.
	  (rip_send_packet) use strncpy, just in case (address is under
	  our control anyway, but still).
	  dont duplicate rip_create_socket - just use it.
	  (rip_create) rip_create_socket takes an argument now, modify.
diff --git a/ripd/ChangeLog b/ripd/ChangeLog
index ebd9325..4bdc8de 100644
--- a/ripd/ChangeLog
+++ b/ripd/ChangeLog
@@ -1,8 +1,18 @@
 2005-06-03 Paul Jakma <paul.jakma@sun.com>
 
 	* ripd.c: (rip_create_socket) move it up so rip_send_packet
-	  can use it too.
-
+	  can use it too. Make it static. Remove the getservbyname stuff,
+	  as RFC2453 3.9.2 says non-RIP port messages should be discarded,
+	  quagga doesnt accept them, no need to lookup port.
+	  Take a 'to' argument, if socket should be bound to something else.
+	  setsockopt_so_recvbuf might need privs, move it to the raised
+	  privileges section.
+	  dont forget to close the socket if bind fails.
+	  (rip_send_packet) use strncpy, just in case (address is under
+	  our control anyway, but still).
+	  dont duplicate rip_create_socket - just use it.
+	  (rip_create) rip_create_socket takes an argument now, modify.
+	  
 2005-06-01 Paul Jakma <paul.jakma@sun.com>
 
 	* rip_interface.c: Fix authentication, no-auth impossible to specify
diff --git a/ripd/ripd.c b/ripd/ripd.c
index c40e2ac..fdb2644 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -1320,27 +1320,22 @@
 }
 
 /* Make socket for RIP protocol. */
-int 
-rip_create_socket ()
+static int 
+rip_create_socket (struct sockaddr_in *to)
 {
   int ret;
   int sock;
   struct sockaddr_in addr;
-  struct servent *sp;
-
-  memset (&addr, 0, sizeof (struct sockaddr_in));
-
-  /* Set RIP port. */
-  sp = getservbyname ("router", "udp");
-  if (sp) 
-    addr.sin_port = sp->s_port;
-  else 
-    addr.sin_port = htons (RIP_PORT_DEFAULT);
-
-  /* Address shoud be any address. */
-  addr.sin_family = AF_INET;
-  addr.sin_addr.s_addr = INADDR_ANY;
-
+  
+  if (!to)
+    {
+      memset (&addr, 0, sizeof (struct sockaddr_in));
+      addr.sin_family = AF_INET;
+      addr.sin_port = htons (RIP_PORT_DEFAULT);
+      addr.sin_family = AF_INET;
+      addr.sin_addr.s_addr = INADDR_ANY;
+    }
+  
   /* Make datagram socket. */
   sock = socket (AF_INET, SOCK_DGRAM, 0);
   if (sock < 0) 
@@ -1352,23 +1347,25 @@
   sockopt_broadcast (sock);
   sockopt_reuseaddr (sock);
   sockopt_reuseport (sock);
-  setsockopt_so_recvbuf (sock, RIP_UDP_RCV_BUF);
 #ifdef RIP_RECVMSG
   setsockopt_pktinfo (sock);
 #endif /* RIP_RECVMSG */
 
   if (ripd_privs.change (ZPRIVS_RAISE))
       zlog_err ("rip_create_socket: could not raise privs");
-  ret = bind (sock, (struct sockaddr *) & addr, sizeof (addr));
-  if (ret < 0)
+  setsockopt_so_recvbuf (sock, RIP_UDP_RCV_BUF);
+  if ( (ret = bind (sock, (struct sockaddr *) & addr, sizeof (addr))) < 0)
+  
     {
       int save_errno = errno;
       if (ripd_privs.change (ZPRIVS_LOWER))
         zlog_err ("rip_create_socket: could not lower privs");
       zlog_err("cannot bind to port %d: %s",
 	       (int)ntohs(addr.sin_port), safe_strerror(save_errno));
+      close (sock);
       return ret;
     }
+  
   if (ripd_privs.change (ZPRIVS_LOWER))
       zlog_err ("rip_create_socket: could not lower privs");
       
@@ -1390,20 +1387,25 @@
   
   if (IS_RIP_DEBUG_PACKET)
     {
-      char dst[20];
+#define ADDRESS_SIZE 20
+      char dst[ADDRESS_SIZE];
+      dst[ADDRESS_SIZE - 1] = '\0';
+      
       if (to)
         {
-          strcpy(dst, inet_ntoa(to->sin_addr));
+          strncpy (dst, inet_ntoa(to->sin_addr), ADDRESS_SIZE - 1);
         }
       else
         {
           sin.sin_addr.s_addr = htonl (INADDR_RIP_GROUP);
-          strcpy(dst, inet_ntoa(sin.sin_addr));
+          strncpy (dst, inet_ntoa(sin.sin_addr), ADDRESS_SIZE - 1);
         }
+#undef ADDRESS_SIZE
       zlog_debug("rip_send_packet %s > %s (%s)",
                 inet_ntoa(ifc->address->u.prefix4),
                 dst, ifc->ifp->name);
     }
+  
   if ( CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY) )
     {
       /*
@@ -1447,19 +1449,11 @@
        * is the most portable way to bind to a different source
        * ipv4 address for each packet. 
        */
-      send_sock = socket(AF_INET, SOCK_DGRAM, 0);
-      if (send_sock < 0)
+      if ( (send_sock = rip_create_socket (&sin)) < 0)
         {
-          zlog_warn("rip_send_packet could not create socket %s",
-                    safe_strerror(errno));
+          zlog_warn("rip_send_packet could not create socket.");
           return -1;
-    }
-      sockopt_broadcast (send_sock);
-      sockopt_reuseaddr (send_sock);
-      sockopt_reuseport (send_sock);
-#ifdef RIP_RECVMSG
-      setsockopt_pktinfo (send_sock);
-#endif /* RIP_RECVMSG */
+        }
       rip_interface_multicast_set (send_sock, ifc);
     }
 
@@ -2691,7 +2685,7 @@
   rip->obuf = stream_new (1500);
 
   /* Make socket. */
-  rip->sock = rip_create_socket ();
+  rip->sock = rip_create_socket (NULL);
   if (rip->sock < 0)
     return rip->sock;