]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/smux.c
*: make consistent & update GPLv2 file headers
[mirror_frr.git] / lib / smux.c
index b7cd18d14d644a7a35fba38eae9b7d6711e9fbba..032801f6dfabf46c24eb95283c34b33365313ac7 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with GNU Zebra; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.  
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <zebra.h>
 
-#ifdef HAVE_SNMP
-#ifdef HAVE_NETSNMP
+#ifdef SNMP_SMUX
 #include <net-snmp/net-snmp-config.h>
 #include <net-snmp/net-snmp-includes.h>
-#else
-#include <asn1.h>
-#include <snmp.h>
-#include <snmp_impl.h>
-#endif
 
 #include "log.h"
 #include "thread.h"
 #include "sockunion.h"
 #include "smux.h"
 
+#define SMUX_PORT_DEFAULT 199
+
+#define SMUXMAXPKTSIZE    1500
+#define SMUXMAXSTRLEN      256
+
+#define SMUX_OPEN       (ASN_APPLICATION | ASN_CONSTRUCTOR | 0)
+#define SMUX_CLOSE      (ASN_APPLICATION | ASN_PRIMITIVE | 1)
+#define SMUX_RREQ       (ASN_APPLICATION | ASN_CONSTRUCTOR | 2)
+#define SMUX_RRSP       (ASN_APPLICATION | ASN_PRIMITIVE | 3)
+#define SMUX_SOUT       (ASN_APPLICATION | ASN_PRIMITIVE | 4)
+
+#define SMUX_GET        (ASN_CONTEXT | ASN_CONSTRUCTOR | 0)
+#define SMUX_GETNEXT    (ASN_CONTEXT | ASN_CONSTRUCTOR | 1)
+#define SMUX_GETRSP     (ASN_CONTEXT | ASN_CONSTRUCTOR | 2)
+#define SMUX_SET       (ASN_CONTEXT | ASN_CONSTRUCTOR | 3)
+#define SMUX_TRAP      (ASN_CONTEXT | ASN_CONSTRUCTOR | 4)
+
+#define SMUX_MAX_FAILURE 3
+
+/* SNMP tree. */
+struct subtree
+{
+  /* Tree's oid. */
+  oid name[MAX_OID_LEN];
+  u_char name_len;
+
+  /* List of the variables. */
+  struct variable *variables;
+
+  /* Length of the variables list. */
+  int variables_num;
+
+  /* Width of the variables list. */
+  int variables_width;
+
+  /* Registered flag. */
+  int registered;
+};
+
 #define min(A,B) ((A) < (B) ? (A) : (B))
 
 enum smux_event {SMUX_SCHEDULE, SMUX_CONNECT, SMUX_READ};
 
 void smux_event (enum smux_event, int);
-\f
+
 
 /* SMUX socket. */
 int smux_sock = -1;
@@ -80,63 +112,7 @@ static struct cmd_node smux_node =
 };
 
 /* thread master */
-static struct thread_master *master;
-\f
-void *
-oid_copy (void *dest, const void *src, size_t size)
-{
-  return memcpy (dest, src, size * sizeof (oid));
-}
-
-void
-oid2in_addr (oid oid[], int len, struct in_addr *addr)
-{
-  int i;
-  u_char *pnt;
-  
-  if (len == 0)
-    return;
-
-  pnt = (u_char *) addr;
-
-  for (i = 0; i < len; i++)
-    *pnt++ = oid[i];
-}
-
-void
-oid_copy_addr (oid oid[], struct in_addr *addr, int len)
-{
-  int i;
-  u_char *pnt;
-  
-  if (len == 0)
-    return;
-
-  pnt = (u_char *) addr;
-
-  for (i = 0; i < len; i++)
-    oid[i] = *pnt++;
-}
-
-int
-oid_compare (oid *o1, int o1_len, oid *o2, int o2_len)
-{
-  int i;
-
-  for (i = 0; i < min (o1_len, o2_len); i++)
-    {
-      if (o1[i] < o2[i])
-       return -1;
-      else if (o1[i] > o2[i])
-       return 1;
-    }
-  if (o1_len < o2_len)
-    return -1;
-  if (o1_len > o2_len)
-    return 1;
-
-  return 0;
-}
+static struct thread_master *smux_master;
 
 static int
 oid_compare_part (oid *o1, int o1_len, oid *o2, int o2_len)
@@ -155,7 +131,7 @@ oid_compare_part (oid *o1, int o1_len, oid *o2, int o2_len)
 
   return 0;
 }
-\f
+
 static void
 smux_oid_dump (const char *prefix, const oid *oid, size_t oid_len)
 {
@@ -177,16 +153,10 @@ static int
 smux_socket (void)
 {
   int ret;
-#ifdef HAVE_IPV6
   struct addrinfo hints, *res0, *res;
   int gai;
-#else
-  struct sockaddr_in serv;
-  struct servent *sp;
-#endif
   int sock = 0;
 
-#ifdef HAVE_IPV6
   memset(&hints, 0, sizeof(hints));
   hints.ai_family = PF_UNSPEC;
   hints.ai_socktype = SOCK_STREAM;
@@ -206,9 +176,7 @@ smux_socket (void)
   for(res=res0; res; res=res->ai_next)
     {
       if (res->ai_family != AF_INET 
-#ifdef HAVE_IPV6
          && res->ai_family != AF_INET6
-#endif /* HAVE_IPV6 */
          )
        continue;
 
@@ -229,40 +197,6 @@ smux_socket (void)
   freeaddrinfo(res0);
   if (sock < 0)
     zlog_warn ("Can't connect to SNMP agent with SMUX");
-#else
-  sock = socket (AF_INET, SOCK_STREAM, 0);
-  if (sock < 0)
-    {
-      zlog_warn ("Can't make socket for SNMP");
-      return -1;
-    }
-
-  memset (&serv, 0, sizeof (struct sockaddr_in));
-  serv.sin_family = AF_INET;
-#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
-  serv.sin_len = sizeof (struct sockaddr_in);
-#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
-
-  sp = getservbyname ("smux", "tcp");
-  if (sp != NULL) 
-    serv.sin_port = sp->s_port;
-  else
-    serv.sin_port = htons (SMUX_PORT_DEFAULT);
-
-  serv.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-
-  sockopt_reuseaddr (sock);
-  sockopt_reuseport (sock);
-
-  ret = connect (sock, (struct sockaddr *) &serv, sizeof (struct sockaddr_in));
-  if (ret < 0)
-    {
-      close (sock);
-      smux_sock = -1;
-      zlog_warn ("Can't connect to SNMP agent with SMUX");
-      return -1;
-    }
-#endif
   return sock;
 }
 
@@ -479,7 +413,7 @@ smux_set (oid *reqid, size_t *reqid_len,
                   if (write_method)
                     {
                       return (*write_method)(action, val, val_type, val_len,
-                                            statP, suffix, suffix_len, v);
+                                            statP, suffix, suffix_len);
                     }
                   else
                     {
@@ -945,7 +879,7 @@ smux_open (int sock)
   u_char *ptr;
   size_t len;
   long version;
-  const char progname[] = QUAGGA_PROGNAME "-" QUAGGA_VERSION;
+  const char progname[] = FRR_SMUX_NAME "-" FRR_VERSION;
 
   if (debug_smux)
     {
@@ -991,11 +925,18 @@ smux_open (int sock)
   return send (sock, buf, (ptr - buf), 0);
 }
 
+/* `ename` is ignored. Instead of using the provided enterprise OID,
+   the SMUX peer is used. This keep compatibility with the previous
+   versions of Quagga.
+
+   All other fields are used as they are intended. */
 int
-smux_trap (const oid *name, size_t namelen,
+smux_trap (struct variable *vp, size_t vp_len,
+          const oid *ename, size_t enamelen,
+          const oid *name, size_t namelen,
           const oid *iname, size_t inamelen,
           const struct trap_object *trapobj, size_t trapobjlen,
-          unsigned int tick, u_char sptrap)
+          u_char sptrap)
 {
   unsigned int i;
   u_char buf[BUFSIZ];
@@ -1246,7 +1187,7 @@ smux_stop (void)
       smux_sock = -1;
     }
 }
-\f
+
 
 
 void
@@ -1255,19 +1196,24 @@ smux_event (enum smux_event event, int sock)
   switch (event)
     {
     case SMUX_SCHEDULE:
-      smux_connect_thread = thread_add_event (master, smux_connect, NULL, 0);
+      smux_connect_thread = NULL;
+      thread_add_event(smux_master, smux_connect, NULL, 0,
+                       &smux_connect_thread);
       break;
     case SMUX_CONNECT:
-      smux_connect_thread = thread_add_timer (master, smux_connect, NULL, 10);
+      smux_connect_thread = NULL;
+      thread_add_timer(smux_master, smux_connect, NULL, 10,
+                       &smux_connect_thread);
       break;
     case SMUX_READ:
-      smux_read_thread = thread_add_read (master, smux_read, NULL, sock);
+      smux_read_thread = NULL;
+      thread_add_read(smux_master, smux_read, NULL, sock, &smux_read_thread);
       break;
     default:
       break;
     }
 }
-\f
+
 static int
 smux_str2oid (const char *str, oid *oid, size_t *oid_len)
 {
@@ -1360,32 +1306,6 @@ smux_peer_oid (struct vty *vty, const char *oid_str, const char *passwd_str)
   return 0;
 }
 
-int
-smux_header_generic (struct variable *v, oid *name, size_t *length, int exact,
-                    size_t *var_len, WriteMethod **write_method)
-{
-  oid fulloid[MAX_OID_LEN];
-  int ret;
-
-  oid_copy (fulloid, v->name, v->namelen);
-  fulloid[v->namelen] = 0;
-  /* Check against full instance. */
-  ret = oid_compare (name, *length, fulloid, v->namelen + 1);
-
-  /* Check single instance. */
-  if ((exact && (ret != 0)) || (!exact && (ret >= 0)))
-       return MATCH_FAILED;
-
-  /* In case of getnext, fill in full instance. */
-  memcpy (name, fulloid, (v->namelen + 1) * sizeof (oid));
-  *length = v->namelen + 1;
-
-  *write_method = 0;
-  *var_len = sizeof(long);    /* default to 'long' results */
-
-  return MATCH_SUCCEEDED;
-}
-
 static int
 smux_peer_default (void)
 {
@@ -1412,7 +1332,8 @@ DEFUN (smux_peer,
        "SNMP MUX peer settings\n"
        "Object ID used in SMUX peering\n")
 {
-  if (smux_peer_oid (vty, argv[0], NULL) == 0)
+  int idx_oid = 2;
+  if (smux_peer_oid (vty, argv[idx_oid]->arg, NULL) == 0)
     {
       smux_start();
       return CMD_SUCCESS;
@@ -1429,7 +1350,8 @@ DEFUN (smux_peer_password,
        "SMUX peering object ID\n"
        "SMUX peering password\n")
 {
-  if (smux_peer_oid (vty, argv[0], argv[1]) == 0)
+  int idx_oid = 2;
+  if (smux_peer_oid (vty, argv[idx_oid]->arg, argv[3]->rg) == 0)
     {
       smux_start();
       return CMD_SUCCESS;
@@ -1440,32 +1362,17 @@ DEFUN (smux_peer_password,
 
 DEFUN (no_smux_peer,
        no_smux_peer_cmd,
-       "no smux peer",
+       "no smux peer [OID [PASSWORD]]",
        NO_STR
        "SNMP MUX protocol settings\n"
-       "SNMP MUX peer settings\n")
+       "SNMP MUX peer settings\n"
+       "SMUX peering object ID\n"
+       "SMUX peering password\n")
 {
   smux_stop();
   return smux_peer_default ();
 }
 
-ALIAS (no_smux_peer,
-       no_smux_peer_oid_cmd,
-       "no smux peer OID",
-       NO_STR
-       "SNMP MUX protocol settings\n"
-       "SNMP MUX peer settings\n"
-       "SMUX peering object ID\n")
-
-ALIAS (no_smux_peer,
-       no_smux_peer_oid_password_cmd,
-       "no smux peer OID PASSWORD",
-       NO_STR
-       "SNMP MUX protocol settings\n"
-       "SNMP MUX peer settings\n"
-       "SMUX peering object ID\n"
-       "SMUX peering password\n")
-
 static int
 config_write_smux (struct vty *vty)
 {
@@ -1515,8 +1422,9 @@ smux_tree_cmp(struct subtree *tree1, struct subtree *tree2)
 void
 smux_init (struct thread_master *tm)
 {
+  assert (tm);
   /* copy callers thread master */
-  master = tm;
+  smux_master = tm;
   
   /* Make MIB tree. */
   treelist = list_new();
@@ -1541,4 +1449,4 @@ smux_start(void)
   /* Schedule first connection. */
   smux_event (SMUX_SCHEDULE, 0);
 }
-#endif /* HAVE_SNMP */
+#endif /* SNMP_SMUX */