* 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>
-#endif
-#include <asn1.h>
-#include <snmp.h>
-#include <snmp_impl.h>
+#include <net-snmp/net-snmp-includes.h>
#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;
int fail = 0;
/* SMUX node. */
-struct cmd_node smux_node =
+static struct cmd_node smux_node =
{
SMUX_NODE,
"" /* SMUX has no interface. */
};
/* thread master */
-static struct thread_master *master;
-\f
-void *
-oid_copy (void *dest, 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;
+static struct thread_master *smux_master;
- return 0;
-}
-
-int
+static int
oid_compare_part (oid *o1, int o1_len, oid *o2, int o2_len)
{
int i;
return 0;
}
-\f
-void
-smux_oid_dump (const char *prefix, oid *oid, size_t oid_len)
+
+static void
+smux_oid_dump (const char *prefix, const oid *oid, size_t oid_len)
{
unsigned int i;
int first = 1;
sprintf (buf + strlen (buf), "%s%d", first ? "" : ".", (int) oid[i]);
first = 0;
}
- zlog_info ("%s: %s", prefix, buf);
+ zlog_debug ("%s: %s", prefix, buf);
}
-int
-smux_socket ()
+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;
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;
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_SIN_LEN
- serv.sin_len = sizeof (struct sockaddr_in);
-#endif /* HAVE_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;
}
-void
+static void
smux_getresp_send (oid objid[], size_t objid_len, long reqid, long errstat,
long errindex, u_char val_type, void *arg, size_t arg_len)
{
- int ret;
u_char buf[BUFSIZ];
u_char *ptr, *h1, *h1e, *h2, *h2e;
- int len, length;
+ size_t len, length;
ptr = buf;
len = BUFSIZ;
if (debug_smux)
{
- zlog_info ("SMUX GETRSP send");
- zlog_info ("SMUX GETRSP reqid: %ld", reqid);
+ zlog_debug ("SMUX GETRSP send");
+ zlog_debug ("SMUX GETRSP reqid: %ld", reqid);
}
h1 = ptr;
&reqid, sizeof (reqid));
if (debug_smux)
- zlog_info ("SMUX GETRSP errstat: %ld", errstat);
+ zlog_debug ("SMUX GETRSP errstat: %ld", errstat);
ptr = asn_build_int (ptr, &len,
(u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
&errstat, sizeof (errstat));
if (debug_smux)
- zlog_info ("SMUX GETRSP errindex: %ld", errindex);
+ zlog_debug ("SMUX GETRSP errindex: %ld", errindex);
ptr = asn_build_int (ptr, &len,
(u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
asn_build_sequence(h1,&length,(u_char)SMUX_GETRSP,ptr-h1e);
if (debug_smux)
- zlog_info ("SMUX getresp send: %d", ptr - buf);
+ zlog_debug ("SMUX getresp send: %td", (ptr - buf));
- ret = send (smux_sock, buf, (ptr - buf), 0);
+ send (smux_sock, buf, (ptr - buf), 0);
}
-char *
-smux_var (char *ptr, int len, oid objid[], size_t *objid_len,
+static u_char *
+smux_var (u_char *ptr, size_t len, oid objid[], size_t *objid_len,
size_t *var_val_len,
u_char *var_val_type,
void **var_value)
u_char *val;
if (debug_smux)
- zlog_info ("SMUX var parse: len %d", len);
+ zlog_debug ("SMUX var parse: len %zd", len);
/* Parse header. */
ptr = asn_parse_header (ptr, &len, &type);
if (debug_smux)
{
- zlog_info ("SMUX var parse: type %d len %d", type, len);
- zlog_info ("SMUX var parse: type must be %d",
+ zlog_debug ("SMUX var parse: type %d len %zd", type, len);
+ zlog_debug ("SMUX var parse: type must be %d",
(ASN_SEQUENCE | ASN_CONSTRUCTOR));
}
smux_oid_dump ("Request OID", objid, *objid_len);
if (debug_smux)
- zlog_info ("SMUX val_type: %d", val_type);
+ zlog_debug ("SMUX val_type: %d", val_type);
/* Check request value type. */
if (debug_smux)
case ASN_NULL:
/* In case of SMUX_GET or SMUX_GET_NEXT val_type is set to
ASN_NULL. */
- zlog_info ("ASN_NULL");
+ zlog_debug ("ASN_NULL");
break;
case ASN_INTEGER:
- zlog_info ("ASN_INTEGER");
+ zlog_debug ("ASN_INTEGER");
break;
case ASN_COUNTER:
case ASN_GAUGE:
case ASN_TIMETICKS:
case ASN_UINTEGER:
- zlog_info ("ASN_COUNTER");
+ zlog_debug ("ASN_COUNTER");
break;
case ASN_COUNTER64:
- zlog_info ("ASN_COUNTER64");
+ zlog_debug ("ASN_COUNTER64");
break;
case ASN_IPADDRESS:
- zlog_info ("ASN_IPADDRESS");
+ zlog_debug ("ASN_IPADDRESS");
break;
case ASN_OCTET_STR:
- zlog_info ("ASN_OCTET_STR");
+ zlog_debug ("ASN_OCTET_STR");
break;
case ASN_OPAQUE:
case ASN_NSAP:
case ASN_OBJECT_ID:
- zlog_info ("ASN_OPAQUE");
+ zlog_debug ("ASN_OPAQUE");
break;
case SNMP_NOSUCHOBJECT:
- zlog_info ("SNMP_NOSUCHOBJECT");
+ zlog_debug ("SNMP_NOSUCHOBJECT");
break;
case SNMP_NOSUCHINSTANCE:
- zlog_info ("SNMP_NOSUCHINSTANCE");
+ zlog_debug ("SNMP_NOSUCHINSTANCE");
break;
case SNMP_ENDOFMIBVIEW:
- zlog_info ("SNMP_ENDOFMIBVIEW");
+ zlog_debug ("SNMP_ENDOFMIBVIEW");
break;
case ASN_BIT_STR:
- zlog_info ("ASN_BIT_STR");
+ zlog_debug ("ASN_BIT_STR");
break;
default:
- zlog_info ("Unknown type");
+ zlog_debug ("Unknown type");
break;
}
return ptr;
ucd-snmp smux and as such suppose, that the peer receives in the message
only one variable. Fortunately, IBM seems to do the same in AIX. */
-int
+static int
smux_set (oid *reqid, size_t *reqid_len,
u_char val_type, void *val, size_t val_len, int action)
{
struct variable *v;
int subresult;
oid *suffix;
- int suffix_len;
+ size_t suffix_len;
int result;
u_char *statP = NULL;
WriteMethod *write_method = NULL;
- struct listnode *node;
+ struct listnode *node, *nnode;
/* Check */
- for (node = treelist->head; node; node = node->next)
+ for (ALL_LIST_ELEMENTS (treelist, node, nnode, subtree))
{
- subtree = node->data;
subresult = oid_compare_part (reqid, *reqid_len,
subtree->name, subtree->name_len);
if (result == 0)
{
if (debug_smux)
- zlog_info ("SMUX function call index is %d", v->magic);
+ zlog_debug ("SMUX function call index is %d", v->magic);
statP = (*v->findVar) (v, suffix, &suffix_len, 1,
&val_len, &write_method);
if (write_method)
{
return (*write_method)(action, val, val_type, val_len,
- statP, suffix, suffix_len, v);
+ statP, suffix, suffix_len);
}
else
{
return SNMP_ERR_NOSUCHNAME;
}
-int
+static int
smux_get (oid *reqid, size_t *reqid_len, int exact,
u_char *val_type,void **val, size_t *val_len)
{
struct variable *v;
int subresult;
oid *suffix;
- int suffix_len;
+ size_t suffix_len;
int result;
WriteMethod *write_method=NULL;
- struct listnode *node;
+ struct listnode *node, *nnode;
/* Check */
- for (node = treelist->head; node; node = node->next)
+ for (ALL_LIST_ELEMENTS (treelist, node, nnode,subtree))
{
- subtree = node->data;
subresult = oid_compare_part (reqid, *reqid_len,
subtree->name, subtree->name_len);
if (result == 0)
{
if (debug_smux)
- zlog_info ("SMUX function call index is %d", v->magic);
+ zlog_debug ("SMUX function call index is %d", v->magic);
*val = (*v->findVar) (v, suffix, &suffix_len, exact,
val_len, &write_method);
return SNMP_ERR_NOSUCHNAME;
}
-int
+static int
smux_getnext (oid *reqid, size_t *reqid_len, int exact,
u_char *val_type,void **val, size_t *val_len)
{
struct variable *v;
int subresult;
oid *suffix;
- int suffix_len;
+ size_t suffix_len;
int result;
WriteMethod *write_method=NULL;
- struct listnode *node;
+ struct listnode *node, *nnode;
/* Save incoming request. */
savelen = *reqid_len;
/* Check */
- for (node = treelist->head; node; node = node->next)
+ for (ALL_LIST_ELEMENTS (treelist, node, nnode, subtree))
{
- subtree = node->data;
subresult = oid_compare_part (reqid, *reqid_len,
subtree->name, subtree->name_len);
if (result <= 0)
{
if (debug_smux)
- zlog_info ("SMUX function call index is %d", v->magic);
+ zlog_debug ("SMUX function call index is %d", v->magic);
if(result<0)
{
oid_copy(suffix, v->name, v->namelen);
}
/* GET message header. */
-char *
-smux_parse_get_header (char *ptr, size_t *len, long *reqid)
+static u_char *
+smux_parse_get_header (u_char *ptr, size_t *len, long *reqid)
{
u_char type;
long errstat;
ptr = asn_parse_int (ptr, len, &type, reqid, sizeof (*reqid));
if (debug_smux)
- zlog_info ("SMUX GET reqid: %d len: %d", (int) *reqid, (int) *len);
+ zlog_debug ("SMUX GET reqid: %d len: %d", (int) *reqid, (int) *len);
/* Error status. */
ptr = asn_parse_int (ptr, len, &type, &errstat, sizeof (errstat));
if (debug_smux)
- zlog_info ("SMUX GET errstat %ld len: %d", errstat, *len);
+ zlog_debug ("SMUX GET errstat %ld len: %zd", errstat, *len);
/* Error index. */
ptr = asn_parse_int (ptr, len, &type, &errindex, sizeof (errindex));
if (debug_smux)
- zlog_info ("SMUX GET errindex %ld len: %d", errindex, *len);
+ zlog_debug ("SMUX GET errindex %ld len: %zd", errindex, *len);
return ptr;
}
-void
-smux_parse_set (char *ptr, size_t len, int action)
+static void
+smux_parse_set (u_char *ptr, size_t len, int action)
{
long reqid;
oid oid[MAX_OID_LEN];
int ret;
if (debug_smux)
- zlog_info ("SMUX SET(%s) message parse: len %d",
+ zlog_debug ("SMUX SET(%s) message parse: len %zd",
(RESERVE1 == action) ? "RESERVE1" : ((FREE == action) ? "FREE" : "COMMIT"),
len);
ret = smux_set (oid, &oid_len, val_type, val, val_len, action);
if (debug_smux)
- zlog_info ("SMUX SET ret %d", ret);
+ zlog_debug ("SMUX SET ret %d", ret);
/* Return result. */
if (RESERVE1 == action)
smux_getresp_send (oid, oid_len, reqid, ret, 3, ASN_NULL, NULL, 0);
}
-void
-smux_parse_get (char *ptr, size_t len, int exact)
+static void
+smux_parse_get (u_char *ptr, size_t len, int exact)
{
long reqid;
oid oid[MAX_OID_LEN];
int ret;
if (debug_smux)
- zlog_info ("SMUX GET message parse: len %d", len);
+ zlog_debug ("SMUX GET message parse: len %zd", len);
/* Parse GET message header. */
ptr = smux_parse_get_header (ptr, &len, &reqid);
}
/* Parse SMUX_CLOSE message. */
-void
-smux_parse_close (char *ptr, int len)
+static void
+smux_parse_close (u_char *ptr, int len)
{
long reason = 0;
}
/* SMUX_RRSP message. */
-void
-smux_parse_rrsp (char *ptr, int len)
+static void
+smux_parse_rrsp (u_char *ptr, size_t len)
{
- char val;
+ u_char val;
long errstat;
ptr = asn_parse_int (ptr, &len, &val, &errstat, sizeof (errstat));
if (debug_smux)
- zlog_info ("SMUX_RRSP value: %d errstat: %ld", val, errstat);
+ zlog_debug ("SMUX_RRSP value: %d errstat: %ld", val, errstat);
}
/* Parse SMUX message. */
-int
-smux_parse (char *ptr, int len)
+static int
+smux_parse (u_char *ptr, size_t len)
{
/* This buffer we'll use for SOUT message. We could allocate it with
malloc and save only static pointer/lenght, but IMHO static
ptr = asn_parse_header (ptr, &len, &type);
if (debug_smux)
- zlog_info ("SMUX message received type: %d rest len: %d", type, len);
+ zlog_debug ("SMUX message received type: %d rest len: %zd", type, len);
switch (type)
{
case SMUX_SOUT:
/* SMUX_SOUT message is now valied for us. */
if (debug_smux)
- zlog_info ("SMUX_SOUT(%s)", rollback ? "rollback" : "commit");
+ zlog_debug ("SMUX_SOUT(%s)", rollback ? "rollback" : "commit");
if (sout_save_len > 0)
{
case SMUX_CLOSE:
/* Close SMUX connection. */
if (debug_smux)
- zlog_info ("SMUX_CLOSE");
+ zlog_debug ("SMUX_CLOSE");
smux_parse_close (ptr, len);
return -1;
break;
case SMUX_RRSP:
/* This is response for register message. */
if (debug_smux)
- zlog_info ("SMUX_RRSP");
+ zlog_debug ("SMUX_RRSP");
smux_parse_rrsp (ptr, len);
break;
case SMUX_GET:
/* Exact request for object id. */
if (debug_smux)
- zlog_info ("SMUX_GET");
+ zlog_debug ("SMUX_GET");
smux_parse_get (ptr, len, 1);
break;
case SMUX_GETNEXT:
/* Next request for object id. */
if (debug_smux)
- zlog_info ("SMUX_GETNEXT");
+ zlog_debug ("SMUX_GETNEXT");
smux_parse_get (ptr, len, 0);
break;
case SMUX_SET:
/* SMUX_SET is supported with some limitations. */
if (debug_smux)
- zlog_info ("SMUX_SET");
+ zlog_debug ("SMUX_SET");
/* save the data for future SMUX_SOUT */
memcpy (sout_save_buff, ptr, len);
}
/* SMUX message read function. */
-int
+static int
smux_read (struct thread *t)
{
int sock;
smux_read_thread = NULL;
if (debug_smux)
- zlog_info ("SMUX read start");
+ zlog_debug ("SMUX read start");
/* Read message from SMUX socket. */
len = recv (sock, buf, SMUXMAXPKTSIZE, 0);
if (len < 0)
{
- zlog_warn ("Can't read all SMUX packet: %s", strerror (errno));
+ zlog_warn ("Can't read all SMUX packet: %s", safe_strerror (errno));
close (sock);
smux_sock = -1;
smux_event (SMUX_CONNECT, 0);
}
if (debug_smux)
- zlog_info ("SMUX read len: %d", len);
+ zlog_debug ("SMUX read len: %d", len);
/* Parse the message. */
ret = smux_parse (buf, len);
return 0;
}
-int
+static int
smux_open (int sock)
{
u_char buf[BUFSIZ];
u_char *ptr;
- int len;
- u_long version;
- u_char progname[] = QUAGGA_PROGNAME "-" QUAGGA_VERSION;
+ size_t len;
+ long version;
+ const char progname[] = FRR_SMUX_NAME "-" FRR_VERSION;
if (debug_smux)
{
smux_oid_dump ("SMUX open oid", smux_oid, smux_oid_len);
- zlog_info ("SMUX open progname: %s", progname);
- zlog_info ("SMUX open password: %s", smux_passwd);
+ zlog_debug ("SMUX open progname: %s", progname);
+ zlog_debug ("SMUX open password: %s", smux_passwd);
}
ptr = buf;
version = 0;
ptr = asn_build_int (ptr, &len,
(u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
- &version, sizeof (u_long));
+ &version, sizeof (version));
/* SMUX connection oid. */
ptr = asn_build_objid (ptr, &len,
ptr = asn_build_string (ptr, &len,
(u_char)
(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OCTET_STR),
- progname, strlen (progname));
+ (const u_char *) progname, strlen (progname));
/* SMUX connection password. */
ptr = asn_build_string (ptr, &len,
(u_char)
(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OCTET_STR),
- smux_passwd, strlen (smux_passwd));
+ (u_char *)smux_passwd, strlen (smux_passwd));
/* Fill in real SMUX header. We exclude ASN header size (2). */
len = BUFSIZ;
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 (oid *name, size_t namelen,
- oid *iname, size_t inamelen,
- struct trap_object *trapobj, size_t trapobjlen,
- unsigned int tick, u_char sptrap)
+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,
+ u_char sptrap)
{
unsigned int i;
u_char buf[BUFSIZ];
u_char *ptr;
- int len, length;
+ size_t len, length;
struct in_addr addr;
unsigned long val;
u_char *h1, *h1e;
ptr = asn_build_string (ptr, &len,
(u_char)
(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_IPADDRESS),
- (u_char *)&addr, sizeof (struct in_addr));
+ (u_char *)&addr, sizeof (addr));
/* Generic trap integer. */
val = SNMP_TRAP_ENTERPRISESPECIFIC;
ptr = asn_build_int (ptr, &len,
(u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
- &val, sizeof (int));
+ (long *)&val, sizeof (val));
/* Specific trap integer. */
val = sptrap;
ptr = asn_build_int (ptr, &len,
(u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
- &val, sizeof (int));
+ (long *)&val, sizeof (val));
/* Timeticks timestamp. */
val = 0;
ptr = asn_build_unsigned_int (ptr, &len,
(u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_TIMETICKS),
- &val, sizeof (int));
+ &val, sizeof (val));
/* Variables. */
h1 = ptr;
u_char val_type;
/* Make OID. */
- oid_copy (oid, name, namelen);
- oid_copy (oid + namelen, trapobj[i].name, trapobj[i].namelen);
- oid_copy (oid + namelen + trapobj[i].namelen, iname, inamelen);
- oid_len = namelen + trapobj[i].namelen + inamelen;
+ if (trapobj[i].namelen > 0)
+ {
+ oid_copy (oid, name, namelen);
+ oid_copy (oid + namelen, trapobj[i].name, trapobj[i].namelen);
+ oid_copy (oid + namelen + trapobj[i].namelen, iname, inamelen);
+ oid_len = namelen + trapobj[i].namelen + inamelen;
+ }
+ else
+ {
+ oid_copy (oid, name, namelen);
+ oid_copy (oid + namelen, trapobj[i].name, trapobj[i].namelen * (-1));
+ oid_len = namelen + trapobj[i].namelen * (-1) ;
+ }
- if (debug_smux)
- smux_oid_dump ("Trap", oid, oid_len);
+ if (debug_smux)
+ {
+ smux_oid_dump ("Trap", name, namelen);
+ if (trapobj[i].namelen < 0)
+ smux_oid_dump ("Trap",
+ trapobj[i].name, (- 1) * (trapobj[i].namelen));
+ else
+ {
+ smux_oid_dump ("Trap", trapobj[i].name, (trapobj[i].namelen));
+ smux_oid_dump ("Trap", iname, inamelen);
+ }
+ smux_oid_dump ("Trap", oid, oid_len);
+ zlog_info ("BUFSIZ: %d // oid_len: %lu", BUFSIZ, (u_long)oid_len);
+ }
ret = smux_get (oid, &oid_len, 1, &val_type, &val, &val_len);
if (debug_smux)
- zlog_info ("smux_get result %d", ret);
+ zlog_debug ("smux_get result %d", ret);
if (ret == 0)
ptr = snmp_build_var_op (ptr, oid, &oid_len,
return send (smux_sock, buf, (ptr - buf), 0);
}
-int
+static int
smux_register (int sock)
{
u_char buf[BUFSIZ];
u_char *ptr;
- int len, ret;
+ int ret;
+ size_t len;
long priority;
long operation;
struct subtree *subtree;
- struct listnode *node;
+ struct listnode *node, *nnode;
ret = 0;
- for (node = treelist->head; node; node = node->next)
+ for (ALL_LIST_ELEMENTS (treelist, node, nnode, subtree))
{
ptr = buf;
len = BUFSIZ;
- subtree = node->data;
-
/* SMUX RReq Header. */
ptr = asn_build_header (ptr, &len, (u_char) SMUX_RREQ, 0);
priority = -1;
ptr = asn_build_int (ptr, &len,
(u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
- &priority, sizeof (u_long));
+ &priority, sizeof (priority));
/* Operation. */
operation = 2; /* Register R/W */
ptr = asn_build_int (ptr, &len,
(u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
- &operation, sizeof (u_long));
+ &operation, sizeof (operation));
if (debug_smux)
{
smux_oid_dump ("SMUX register oid", subtree->name, subtree->name_len);
- zlog_info ("SMUX register priority: %ld", priority);
- zlog_info ("SMUX register operation: %ld", operation);
+ zlog_debug ("SMUX register priority: %ld", priority);
+ zlog_debug ("SMUX register operation: %ld", operation);
}
len = BUFSIZ;
}
/* Try to connect to SNMP agent. */
-int
+static int
smux_connect (struct thread *t)
{
int ret;
if (debug_smux)
- zlog_info ("SMUX connect try %d", fail + 1);
+ zlog_debug ("SMUX connect try %d", fail + 1);
/* Clear thread poner of myself. */
smux_connect_thread = NULL;
ret = smux_open (smux_sock);
if (ret < 0)
{
- zlog_warn ("SMUX open message send failed: %s", strerror (errno));
+ zlog_warn ("SMUX open message send failed: %s", safe_strerror (errno));
close (smux_sock);
smux_sock = -1;
if (++fail < SMUX_MAX_FAILURE)
ret = smux_register (smux_sock);
if (ret < 0)
{
- zlog_warn ("SMUX register message send failed: %s", strerror (errno));
+ zlog_warn ("SMUX register message send failed: %s", safe_strerror (errno));
close (smux_sock);
smux_sock = -1;
if (++fail < SMUX_MAX_FAILURE)
}
/* Clear all SMUX related resources. */
-void
-smux_stop ()
+static void
+smux_stop (void)
{
if (smux_read_thread)
- thread_cancel (smux_read_thread);
+ {
+ thread_cancel (smux_read_thread);
+ smux_read_thread = NULL;
+ }
+
if (smux_connect_thread)
- thread_cancel (smux_connect_thread);
+ {
+ thread_cancel (smux_connect_thread);
+ smux_connect_thread = NULL;
+ }
if (smux_sock >= 0)
{
smux_sock = -1;
}
}
-\f
+
void
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
-int
+
+static int
smux_str2oid (const char *str, oid *oid, size_t *oid_len)
{
int len;
return 0;
}
-oid *
+static oid *
smux_oid_dup (oid *objid, size_t objid_len)
{
oid *new;
return new;
}
-int
+static int
smux_peer_oid (struct vty *vty, const char *oid_str, const char *passwd_str)
{
int ret;
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;
-}
-
-int
-smux_peer_default ()
+static int
+smux_peer_default (void)
{
if (smux_oid)
{
"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;
"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;
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")
-
-int
+static int
config_write_smux (struct vty *vty)
{
int first = 1;
listnode_add_sort(treelist, tree);
}
-void
-smux_reset ()
-{
- /* Setting configuration to default. */
- smux_peer_default ();
-}
-
/* Compare function to keep treelist sorted */
static int
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();
void
smux_start(void)
{
+ /* Close any existing connections. */
+ smux_stop();
+
/* Schedule first connection. */
smux_event (SMUX_SCHEDULE, 0);
}
-#endif /* HAVE_SNMP */
+#endif /* SNMP_SMUX */