[prev in list] [next in list] [prev in thread] [next in thread] 

List:       quagga-dev
Subject:    [quagga-dev 5232] New md5 signature patch for bgp...
From:       "Michael H. Warfield" <mhw () wittsend ! com>
Date:       2008-01-28 19:50:47
Message-ID: 1201549847.8592.68.camel () canyon ! wittsend ! com
[Download RAW message or body]

[Attachment #2 (multipart/signed)]

[Attachment #4 (multipart/mixed)]


Hello all!

	Building on the efforts of Leigh Brown and the earlier works on an MD5
signature patch for bgpd, I've incorporated the autoconf efforts by
Sargun Dhillon on top of my own changes for IPv6 along with filling in a
few missing spots in the autoconf stuff myself.  Leigh had released a v7
and I subsequently released a v8 patch for md5 signatures for Linux and
BSD to deal with conflicts with IPv6.  This is now a v9 patch
incorporating some of the changes from Sargun and adding a few of my own
to complete the autoconf changes.

	This patch is still against 0.99.9 but should patch cleanly against
CVS.

	This adds a configure option, --enable-tcp-md5, to enable tcp md5
signatures.  This is not qualified against the operating system on which
it is being built.  The patch should work on BSD and Linux.  Other
operation systems are a crap shoot.  I don't know.  I presume some other
errors will occur on other operating systems which do not support MD5
signatures in this manner.  Since they're not supported now, this is no
great loss.  Someone might want to test this in other environments,
though, and enhance it for those other environments.

	Attached...

	quagga_md5_bsd_linux_v9.diff

	http://www.wittsend.com/mhw/md5sig/quagga_md5_bsd_linux_v9.diff

	Is there anything left that needs to be done before this can be
committed to CVS?  Can someone with commit privs please do the honors?

	Regards,
	Mike
-- 
Michael H. Warfield (AI4NB) | (770) 985-6132 |  mhw@WittsEnd.com
   /\/\|=mhw=|\/\/          | (678) 463-0932 |  http://www.wittsend.com/mhw/
   NIC whois: MHW9          | An optimist believes we live in the best of all
 PGP Key: 0xDF1DD471        | possible worlds.  A pessimist is sure of it!


["quagga_md5_bsd_linux_v9.diff" (quagga_md5_bsd_linux_v9.diff)]

diff -ruN quagga-0.99.9/bgpd/bgpd.c quagga-0.99.9-v9/bgpd/bgpd.c
--- quagga-0.99.9/bgpd/bgpd.c	2007-07-25 12:49:06.000000000 -0400
+++ quagga-0.99.9-v9/bgpd/bgpd.c	2007-09-24 20:28:55.000000000 -0400
@@ -788,6 +788,7 @@
   peer->status = Idle;
   peer->ostatus = Idle;
   peer->weight = 0;
+  peer->password = NULL;
   peer->bgp = bgp;
   peer = peer_lock (peer); /* initial reference */
 
@@ -1202,6 +1203,20 @@
   peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
   bgp_stop (peer);
   bgp_fsm_change_status (peer, Deleted);
+
+#ifdef HAVE_TCP_MD5SIG
+  /* Password configuration */
+  if (peer->password)
+    {
+      free (peer->password);
+      peer->password = NULL;
+
+      if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
+          && sockunion_family (&peer->su) == AF_INET)
+       bgp_md5_set (bm->sock, &peer->su.sin, NULL);
+    }
+#endif /* HAVE_TCP_MD5SIG */
+ 
   bgp_timer_set (peer); /* stops all timers for Deleted */
   
   /* Delete from all peer list. */
@@ -1417,6 +1432,27 @@
   else
     peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
 
+#ifdef HAVE_TCP_MD5SIG
+  /* password apply */
+  if (CHECK_FLAG (conf->flags, PEER_FLAG_PASSWORD))
+    {
+      if (peer->password)
+	free (peer->password);
+      peer->password = strdup (conf->password);
+
+      if (sockunion_family (&peer->su) == AF_INET)
+	bgp_md5_set (bm->sock, &peer->su.sin, peer->password);
+    }
+  else if (peer->password)
+    {
+      free (peer->password);
+      peer->password = NULL;
+
+      if (sockunion_family (&peer->su) == AF_INET)
+        bgp_md5_set (bm->sock, &peer->su.sin, NULL);
+    }
+#endif /* HAVE_TCP_MD5SIG */
+
   /* maximum-prefix */
   peer->pmax[afi][safi] = conf->pmax[afi][safi];
   peer->pmax_threshold[afi][safi] = conf->pmax_threshold[afi][safi];
@@ -3379,6 +3415,125 @@
   return 0;
 }
 
+#ifdef HAVE_TCP_MD5SIG
+/* Set password for authenticating with the peer. */
+int
+peer_password_set (struct peer *peer, const char *password)
+{
+  struct peer_group *group;
+  struct listnode *nn, *nnode;
+  int len = password ? strlen(password) : 0;
+
+  if ((len < PEER_PASSWORD_MINLEN) || (len > PEER_PASSWORD_MAXLEN))
+    return BGP_ERR_INVALID_VALUE;
+
+  if (peer->password && strcmp (peer->password, password) == 0
+      && ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+	return 0;
+
+  SET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
+  if (peer->password)
+    free (peer->password);
+  peer->password = strdup (password);
+
+  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+    {
+      if (peer->status == Established)
+          bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+      else
+        BGP_EVENT_ADD (peer, BGP_Stop);
+
+      if (sockunion_family (&peer->su) == AF_INET)
+	bgp_md5_set (bm->sock, &peer->su.sin, peer->password);
+      return 0;
+    }
+
+  group = peer->group;
+  /* #42# LIST_LOOP (group->peer, peer, nn) */
+  for (ALL_LIST_ELEMENTS (group->peer, nn, nnode, peer))
+    {
+      if (peer->password && strcmp (peer->password, password) == 0)
+	continue;
+
+      SET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
+      if (peer->password)
+        free (peer->password);
+      peer->password = strdup (password);
+
+      if (peer->status == Established)
+        bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+      else
+        BGP_EVENT_ADD (peer, BGP_Stop);
+
+      if (sockunion_family (&peer->su) == AF_INET)
+	bgp_md5_set (bm->sock, &peer->su.sin, peer->password);
+    }
+
+  return 0;
+}
+
+int
+peer_password_unset (struct peer *peer)
+{
+  struct peer_group *group;
+  struct listnode *nn, *nnode;
+
+  if (! CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD)
+      && ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+    return 0;
+
+  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+    {
+      if (peer_group_active (peer)
+	  && CHECK_FLAG (peer->group->conf->flags, PEER_FLAG_PASSWORD))
+	return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
+
+      if (peer->status == Established)
+        bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+      else
+        BGP_EVENT_ADD (peer, BGP_Stop);
+
+      if (sockunion_family (&peer->su) == AF_INET)
+	bgp_md5_set (bm->sock, &peer->su.sin, NULL);
+
+      UNSET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
+      if (peer->password)
+	free (peer->password);
+      peer->password = NULL;
+
+      return 0;
+    }
+
+  UNSET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
+  if (peer->password)
+    free (peer->password);
+  peer->password = NULL;
+
+  group = peer->group;
+  /* #42# LIST_LOOP (group->peer, peer, nn) */
+  for (ALL_LIST_ELEMENTS (group->peer, nn, nnode, peer))
+    {
+      if (! CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
+	continue;
+
+      if (peer->status == Established)
+        bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+      else
+        BGP_EVENT_ADD (peer, BGP_Stop);
+
+      if (sockunion_family (&peer->su) == AF_INET)
+	bgp_md5_set (bm->sock, &peer->su.sin, NULL);
+
+      UNSET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
+      if (peer->password)
+        free (peer->password);
+      peer->password = NULL;
+    }
+
+  return 0;
+}
+#endif /* HAVE_TCP_MD5SIG */
+
 /* Set distribute list to the peer. */
 int
 peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct, 
@@ -4416,6 +4571,16 @@
 	    ! CHECK_FLAG (g_peer->flags, PEER_FLAG_SHUTDOWN))
 	  vty_out (vty, " neighbor %s shutdown%s", addr, VTY_NEWLINE);
 
+#ifdef HAVE_TCP_MD5SIG
+      /* Password. */
+      if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
+	if (! peer_group_active (peer)
+	    || ! CHECK_FLAG (g_peer->flags, PEER_FLAG_PASSWORD)
+	    || strcmp (peer->password, g_peer->password) != 0)
+	  vty_out (vty, " neighbor %s password %s%s", addr, peer->password,
+		   VTY_NEWLINE);
+#endif /* HAVE_TCP_MD5SIG */
+
       /* BGP port. */
       if (peer->port != BGP_PORT_DEFAULT)
 	vty_out (vty, " neighbor %s port %d%s", addr, peer->port, 
@@ -4951,6 +5116,9 @@
   bm->port = BGP_PORT_DEFAULT;
   bm->master = thread_master_create ();
   bm->start_time = time (NULL);
+#ifdef HAVE_TCP_MD5SIG
+  bm->sock = -1;
+#endif /* HAVE_TCP_MD5SIG */
 }
 
 
diff -ruN quagga-0.99.9/bgpd/bgpd.h quagga-0.99.9-v9/bgpd/bgpd.h
--- quagga-0.99.9/bgpd/bgpd.h	2007-08-06 11:22:43.000000000 -0400
+++ quagga-0.99.9-v9/bgpd/bgpd.h	2007-09-24 20:28:55.000000000 -0400
@@ -52,6 +52,11 @@
 #define BGP_OPT_NO_FIB                   (1 << 0)
 #define BGP_OPT_MULTIPLE_INSTANCE        (1 << 1)
 #define BGP_OPT_CONFIG_CISCO             (1 << 2)
+
+#ifdef HAVE_TCP_MD5SIG
+  /* bgp receive socket */
+  int sock;
+#endif /* HAVE_TCP_MD5SIG */
 };
 
 /* BGP instance structure.  */
@@ -349,6 +354,7 @@
 
   /* NSF mode (graceful restart) */
   u_char nsf[AFI_MAX][SAFI_MAX];
+#define PEER_FLAG_PASSWORD                  (1 << 9) /* password */
 
   /* Per AF configuration flags. */
   u_int32_t af_flags[AFI_MAX][SAFI_MAX];
@@ -370,6 +376,9 @@
 #define PEER_FLAG_MAX_PREFIX_WARNING        (1 << 15) /* maximum prefix warning-only */
 #define PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED   (1 << 16) /* leave link-local nexthop unchanged */ 
 
+  /* MD5 password */
+  char *password;
+
   /* default-originate route-map.  */
   struct
   {
@@ -525,6 +534,13 @@
 #define PEER_RMAP_TYPE_EXPORT         (1 << 7) /* neighbor route-map export */
 };
 
+#if defined(HAVE_TCP_MD5SIG)
+
+#define PEER_PASSWORD_MINLEN	(1)
+#define PEER_PASSWORD_MAXLEN	(80)
+
+#endif /* HAVE_TCP_MD5SIG */
+
 /* This structure's member directly points incoming packet data
    stream. */
 struct bgp_nlri
@@ -913,6 +929,11 @@
 extern int peer_route_map_unset (struct peer *, afi_t, safi_t, int);
 
 extern int peer_unsuppress_map_set (struct peer *, afi_t, safi_t, const char *);
+#ifdef HAVE_TCP_MD5SIG
+extern int peer_password_set (struct peer *, const char *);
+extern int peer_password_unset (struct peer *);
+#endif /* HAVE_TCP_MD5SIG */
+
 extern int peer_unsuppress_map_unset (struct peer *, afi_t, safi_t);
 
 extern int peer_maximum_prefix_set (struct peer *, afi_t, safi_t, u_int32_t, u_char, int, u_int16_t);
diff -ruN quagga-0.99.9/bgpd/bgp_network.c quagga-0.99.9-v9/bgpd/bgp_network.c
--- quagga-0.99.9/bgpd/bgp_network.c	2007-05-09 16:59:33.000000000 -0400
+++ quagga-0.99.9-v9/bgpd/bgp_network.c	2007-09-27 18:50:49.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include "thread.h"
 #include "sockunion.h"
+#include "sockopt.h"
 #include "memory.h"
 #include "log.h"
 #include "if.h"
@@ -38,6 +39,34 @@
 extern struct zebra_privs_t bgpd_privs;
 
 
+#if defined(HAVE_TCP_MD5SIG)
+/*
+ * Set MD5 key for the socket, for the given IPv4 peer address.
+ * If the password is NULL or zero-length, the option will be disabled.
+ */
+int
+bgp_md5_set (int sock, struct sockaddr_in *sin, const char *password)
+{
+  int ret, en;
+
+  if ( bgpd_privs.change (ZPRIVS_RAISE) )
+    zlog_err ("bgp_md5_set: could not raise privs");
+
+  ret = sockopt_tcp_signature (sock, sin, password);
+  en  = errno;
+
+  if (bgpd_privs.change (ZPRIVS_LOWER) )
+    zlog_err ("bgp_md5_set: could not lower privs");
+
+  if (ret < 0)
+    zlog (NULL, LOG_WARNING, "can't set TCP_MD5SIG option on socket %d: %s",
+	  sock, safe_strerror (en));
+
+  return ret;
+}
+
+#endif /* HAVE_TCP_MD5SIG */
+
 /* Accept bgp connection. */
 static int
 bgp_accept (struct thread *thread)
@@ -238,6 +267,12 @@
   sockopt_reuseaddr (peer->fd);
   sockopt_reuseport (peer->fd);
 
+#ifdef HAVE_TCP_MD5SIG
+  if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
+    if (sockunion_family (&peer->su) == AF_INET)
+      bgp_md5_set (peer->fd, &peer->su.sin, peer->password);
+#endif /* HAVE_TCP_MD5SIG */
+
   /* Bind socket. */
   bgp_bind (peer);
 
@@ -288,6 +323,10 @@
   struct addrinfo req;
   struct addrinfo *ainfo;
   struct addrinfo *ainfo_save;
+#if defined(HAVE_TCP_MD5SIG) && defined(IPV6_V6ONLY)
+  struct sockaddr_in sin;
+  int socklen, on = 1;
+#endif
   int sock = 0;
   char port_str[BUFSIZ];
 
@@ -323,6 +362,21 @@
       sockopt_reuseaddr (sock);
       sockopt_reuseport (sock);
       
+#if defined(HAVE_TCP_MD5SIG) && defined(IPV6_V6ONLY)
+/*	We can not apply MD5SIG to an IPv6 socket.  If this is an AF_INET6
+	socket, we'll have to create another socket for IPv4*/
+
+      if (ainfo->ai_family == AF_INET6) {
+/*	Mark this one for IPv6 only	*/
+          ret = setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, 
+		    (void *) &on, sizeof (on));
+          if( ret < 0 ) {
+              en = errno;
+	      zlog_err ("setsockopt V6ONLY: %s", safe_strerror (en));
+          }
+      }
+#endif
+
       if (bgpd_privs.change (ZPRIVS_RAISE) )
         zlog_err ("bgp_socket: could not raise privs");
 
@@ -346,7 +400,65 @@
 	  continue;
 	}
 
+#if defined(HAVE_TCP_MD5SIG) && defined(IPV6_V6ONLY)
+      thread_add_read (master, bgp_accept, bgp, sock);
+
+      if (ainfo->ai_family != AF_INET6)
+	continue;
+     
+      /* If first socket was an IPv6 socket, we need to create an IPv4
+	socket for use by the TCP_MD5SIG logic.  This code is blatently
+	copied and modified from the alternate IPv4 only code from below... */
+
+      sock = socket (AF_INET, SOCK_STREAM, 0);
+      if (sock < 0)
+        {
+          zlog_err ("socket: %s", safe_strerror (errno));
+          continue;
+        }
+
+      sockopt_reuseaddr (sock);
+      sockopt_reuseport (sock);
+
+      memset (&sin, 0, sizeof (struct sockaddr_in));
+
+      sin.sin_family = AF_INET;
+      sin.sin_port = htons (port);
+      socklen = sizeof (struct sockaddr_in);
+#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
+      sin.sin_len = socklen;
+#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
+
+      if ( bgpd_privs.change (ZPRIVS_RAISE) )
+        zlog_err ("bgp_socket: could not raise privs");
+
+      ret = bind (sock, (struct sockaddr *) &sin, socklen);
+      en = errno;
+      if (bgpd_privs.change (ZPRIVS_LOWER) )
+	zlog_err ("bgp_bind_address: could not lower privs");
+
+      if (ret < 0)
+	{
+	  zlog_err ("bind: %s", safe_strerror (en));
+	  close(sock);
+	  continue;
+	}
+      
+      ret = listen (sock, 3);
+      if (ret < 0) 
+	{
+	  zlog_err ("listen: %s", safe_strerror (errno));
+	  close (sock);
+	  continue;
+	}
+#endif
+
+#ifdef HAVE_TCP_MD5SIG
+      bm->sock = sock;
+#endif /* HAVE_TCP_MD5SIG */
+
       thread_add_read (master, bgp_accept, bgp, sock);
+
     }
   while ((ainfo = ainfo->ai_next) != NULL);
 
@@ -406,6 +518,9 @@
       close (sock);
       return ret;
     }
+#ifdef HAVE_TCP_MD5SIG
+  bm->sock = sock;
+#endif /* HAVE_TCP_MD5SIG */
 
   thread_add_read (bm->master, bgp_accept, bgp, sock);
 
diff -ruN quagga-0.99.9/bgpd/bgp_network.h quagga-0.99.9-v9/bgpd/bgp_network.h
--- quagga-0.99.9/bgpd/bgp_network.h	2007-06-29 09:41:43.000000000 -0400
+++ quagga-0.99.9-v9/bgpd/bgp_network.h	2007-09-24 20:28:55.000000000 -0400
@@ -21,6 +21,10 @@
 #ifndef _QUAGGA_BGP_NETWORK_H
 #define _QUAGGA_BGP_NETWORK_H
 
+#if defined(HAVE_TCP_MD5SIG) 
+extern int bgp_md5_set (int, struct sockaddr_in *, const char *);
+#endif /* HAVE_TCP_MD5SIG */
+
 extern int bgp_socket (struct bgp *, unsigned short);
 extern int bgp_connect (struct peer *);
 extern void bgp_getsockname (struct peer *);
diff -ruN quagga-0.99.9/bgpd/bgp_vty.c quagga-0.99.9-v9/bgpd/bgp_vty.c
--- quagga-0.99.9/bgpd/bgp_vty.c	2007-08-06 11:17:46.000000000 -0400
+++ quagga-0.99.9-v9/bgpd/bgp_vty.c	2007-09-24 20:28:55.000000000 -0400
@@ -1479,6 +1479,46 @@
        "AS number used as local AS\n"
        "Do not prepend local-as to updates from ebgp peers\n")
 
+#ifdef HAVE_TCP_MD5SIG
+DEFUN (neighbor_password,
+       neighbor_password_cmd,
+       NEIGHBOR_CMD2 "password LINE",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Set a password\n"
+       "The password\n")
+{
+  struct peer *peer;
+  int ret;
+
+  peer = peer_and_group_lookup_vty (vty, argv[0]);
+  if (! peer)
+    return CMD_WARNING;
+
+  ret = peer_password_set (peer, argv[1]);
+  return bgp_vty_return (vty, ret);
+}
+
+DEFUN (no_neighbor_password,
+       no_neighbor_password_cmd,
+       NO_NEIGHBOR_CMD2 "password",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Set a password\n")
+{
+  struct peer *peer;
+  int ret;
+
+  peer = peer_and_group_lookup_vty (vty, argv[0]);
+  if (! peer)
+    return CMD_WARNING;
+
+  ret = peer_password_unset (peer);
+  return bgp_vty_return (vty, ret);
+}
+#endif /* HAVE_TCP_MD5SIG */
+
 DEFUN (neighbor_activate,
        neighbor_activate_cmd,
        NEIGHBOR_CMD2 "activate",
@@ -8894,6 +8934,12 @@
   install_element (BGP_NODE, &no_neighbor_local_as_val_cmd);
   install_element (BGP_NODE, &no_neighbor_local_as_val2_cmd);
 
+#ifdef HAVE_TCP_MD5SIG
+  /* "neighbor password" commands. */
+  install_element (BGP_NODE, &neighbor_password_cmd);
+  install_element (BGP_NODE, &no_neighbor_password_cmd);
+#endif /* HAVE_TCP_MD5SIG */
+
   /* "neighbor activate" commands. */
   install_element (BGP_NODE, &neighbor_activate_cmd);
   install_element (BGP_IPV4_NODE, &neighbor_activate_cmd);
diff -ruN quagga-0.99.9/config.h.in quagga-0.99.9-v9/config.h.in
--- quagga-0.99.9/config.h.in	2007-09-07 12:56:20.000000000 -0400
+++ quagga-0.99.9-v9/config.h.in	2008-01-28 13:47:20.000000000 -0500
@@ -487,6 +487,9 @@
 /* Use TCP for zebra communication */
 #undef HAVE_TCP_ZEBRA
 
+/* Define to 1 for TCP MD5 Signatures */
+#undef HAVE_TCP_MD5SIG
+
 /* Define to 1 if you have the <ucontext.h> header file. */
 #undef HAVE_UCONTEXT_H
 
diff -ruN quagga-0.99.9/configure.ac quagga-0.99.9-v9/configure.ac
--- quagga-0.99.9/configure.ac	2007-09-07 12:54:01.000000000 -0400
+++ quagga-0.99.9-v9/configure.ac	2008-01-28 13:59:59.000000000 -0500
@@ -211,6 +211,8 @@
 [  --with-libpam           use libpam for PAM support in vtysh])
 AC_ARG_ENABLE(tcp-zebra,
 [  --enable-tcp-zebra      enable TCP/IP socket connection between zebra and protocol daemon])
+AC_ARG_ENABLE(tcp-md5,
+[  --enable-tcp-md5        enable TCP/IP md5 in BGPd])
 AC_ARG_ENABLE(opaque-lsa,
 [  --enable-opaque-lsa     enable OSPF Opaque-LSA with OSPFAPI support (RFC2370)])
 AC_ARG_ENABLE(ospfapi,
@@ -281,6 +283,10 @@
   AC_DEFINE(HAVE_TCP_ZEBRA,,Use TCP for zebra communication)
 fi
 
+if test "${enable_tcp_md5}" = "yes"; then
+  AC_DEFINE(HAVE_TCP_MD5SIG,1,Enable TCP MD5 Signatures)
+fi
+
 if test "${enable_opaque_lsa}" = "yes"; then
   AC_DEFINE(HAVE_OPAQUE_LSA,,OSPF Opaque LSA)
 fi
Binary files quagga-0.99.9/.configure.ac.swp and quagga-0.99.9-v9/.configure.ac.swp differ
diff -ruN quagga-0.99.9/lib/sockopt.c quagga-0.99.9-v9/lib/sockopt.c
--- quagga-0.99.9/lib/sockopt.c	2007-08-22 12:22:54.000000000 -0400
+++ quagga-0.99.9-v9/lib/sockopt.c	2007-09-24 20:28:55.000000000 -0400
@@ -480,3 +480,36 @@
 
   iph->ip_id = ntohs(iph->ip_id);
 }
+
+#if defined(HAVE_TCP_MD5SIG)
+int
+sockopt_tcp_signature (int sock, struct sockaddr_in *sin, const char *password)
+{
+  int keylen = password ? strlen(password) : 0;
+
+#if defined(GNU_LINUX)
+
+  struct tcp_md5sig md5sig;
+
+  bzero ((char *)&md5sig, sizeof(md5sig));
+  memcpy (&md5sig.tcpm_addr, sin, sizeof(*sin));
+  md5sig.tcpm_keylen = keylen;
+  if (keylen)
+    memcpy (md5sig.tcpm_key, password, keylen);
+
+  return setsockopt (sock, IPPROTO_TCP, TCP_MD5SIG, &md5sig, sizeof md5sig);
+
+#else /* !GNU_LINUX */
+
+  int enable = keylen ? (TCP_SIG_SPI_BASE + sin->sin_port) : 0;
+
+  /*
+   * XXX Need to do PF_KEY operation here to add/remove an SA entry,
+   * and add/remove an SP entry for this peer's packet flows also.
+   */
+  return setsockopt (sock, IPPROTO_TCP, TCP_MD5SIG, &enable,
+		     sizeof(enable));
+
+#endif /* !GNU_LINUX */
+}
+#endif /* HAVE_TCP_MD5SIG */
diff -ruN quagga-0.99.9/lib/sockopt.h quagga-0.99.9-v9/lib/sockopt.h
--- quagga-0.99.9/lib/sockopt.h	2007-08-22 12:22:54.000000000 -0400
+++ quagga-0.99.9-v9/lib/sockopt.h	2007-09-24 20:28:55.000000000 -0400
@@ -98,4 +98,32 @@
 extern void sockopt_iphdrincl_swab_htosys (struct ip *iph);
 extern void sockopt_iphdrincl_swab_systoh (struct ip *iph);
 
+#if defined(HAVE_TCP_MD5SIG)
+
+#if defined(GNU_LINUX) && !defined(TCP_MD5SIG)
+
+/* XXX these will come from <linux/tcp.h> eventually */
+
+#define TCP_MD5SIG		14
+#define TCP_MD5SIG_MAXKEYLEN	80
+
+struct tcp_md5sig {
+        struct sockaddr_storage tcpm_addr;      /* address associated */
+        __u16   __tcpm_pad1;                            /* zero */
+        __u16   tcpm_keylen;                            /* key length */
+        __u32   __tcpm_pad2;                            /* zero */
+        __u8    tcpm_key[TCP_MD5SIG_MAXKEYLEN];         /* key (binary) */
+};
+
+#endif /* defined(GNU_LINUX) && !defined(TCP_MD5SIG) */
+
+#if !defined(GNU_LINUX) && !defined(TCP_SIG_SPI_BASE)
+#define TCP_SIG_SPI_BASE 1000 /* XXX this will go away */
+#endif
+
+extern int sockopt_tcp_signature(int sock, struct sockaddr_in *sin,
+                                 const char *password);
+
+#endif /* HAVE_TCP_MD5SIG */
+
 #endif /*_ZEBRA_SOCKOPT_H */

["signature.asc" (application/pgp-signature)]
-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.


_______________________________________________
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
http://lists.quagga.net/mailman/listinfo/quagga-dev

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic