summaryrefslogtreecommitdiff
path: root/snmplib/snmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'snmplib/snmp.c')
-rw-r--r--snmplib/snmp.c462
1 files changed, 462 insertions, 0 deletions
diff --git a/snmplib/snmp.c b/snmplib/snmp.c
new file mode 100644
index 0000000..c3763e9
--- /dev/null
+++ b/snmplib/snmp.c
@@ -0,0 +1,462 @@
+/*
+ * Simple Network Management Protocol (RFC 1067).
+ *
+ */
+/**********************************************************************
+ Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+
+#include <net-snmp/net-snmp-config.h>
+#include <ctype.h>
+
+#ifdef KINETICS
+#include "gw.h"
+#include "ab.h"
+#include "inet.h"
+#include "fp4/cmdmacro.h"
+#include "fp4/pbuf.h"
+#include "glob.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifndef NULL
+#define NULL 0
+#endif
+
+#if HAVE_DMALLOC_H
+#include <dmalloc.h>
+#endif
+
+#ifdef vms
+#include <in.h>
+#endif
+
+#include <net-snmp/types.h>
+#include <net-snmp/output_api.h>
+
+#include <net-snmp/library/asn1.h>
+#include <net-snmp/library/snmp.h> /* for "internal" definitions */
+#include <net-snmp/library/snmp_api.h>
+#include <net-snmp/library/mib.h>
+
+/** @mainpage Net-SNMP Coding Documentation
+ * @section Introduction
+
+ This is the Net-SNMP coding and API reference documentation. It is
+ incomplete, but when combined with the manual page set and
+ tutorials forms a pretty comprehensive starting point.
+
+ @section Starting out
+
+ The best places to start learning are the @e Net-SNMP @e tutorial
+ (http://www.Net-SNMP.org/tutorial-5/) and the @e Modules and @e
+ Examples sections of this document.
+
+*/
+
+void
+xdump(const void * data, size_t length, const char *prefix)
+{
+ const u_char * const cp = (const u_char*)data;
+ int col, count;
+ char *buffer;
+
+ buffer = (char *) malloc(strlen(prefix) + 80);
+ if (!buffer) {
+ snmp_log(LOG_NOTICE,
+ "xdump: malloc failed. packet-dump skipped\n");
+ return;
+ }
+
+ count = 0;
+ while (count < (int) length) {
+ strcpy(buffer, prefix);
+ sprintf(buffer + strlen(buffer), "%.4d: ", count);
+
+ for (col = 0; ((count + col) < (int) length) && col < 16; col++) {
+ sprintf(buffer + strlen(buffer), "%02X ", cp[count + col]);
+ if (col % 4 == 3)
+ strcat(buffer, " ");
+ }
+ for (; col < 16; col++) { /* pad end of buffer with zeros */
+ strcat(buffer, " ");
+ if (col % 4 == 3)
+ strcat(buffer, " ");
+ }
+ strcat(buffer, " ");
+ for (col = 0; ((count + col) < (int) length) && col < 16; col++) {
+ buffer[col + 60] =
+ isprint(cp[count + col]) ? cp[count + col] : '.';
+ }
+ buffer[col + 60] = '\n';
+ buffer[col + 60 + 1] = 0;
+ snmp_log(LOG_DEBUG, "%s", buffer);
+ count += col;
+ }
+ snmp_log(LOG_DEBUG, "\n");
+ free(buffer);
+
+} /* end xdump() */
+
+/*
+ * u_char * snmp_parse_var_op(
+ * u_char *data IN - pointer to the start of object
+ * oid *var_name OUT - object id of variable
+ * int *var_name_len IN/OUT - length of variable name
+ * u_char *var_val_type OUT - type of variable (int or octet string) (one byte)
+ * int *var_val_len OUT - length of variable
+ * u_char **var_val OUT - pointer to ASN1 encoded value of variable
+ * int *listlength IN/OUT - number of valid bytes left in var_op_list
+ */
+
+u_char *
+snmp_parse_var_op(u_char * data,
+ oid * var_name,
+ size_t * var_name_len,
+ u_char * var_val_type,
+ size_t * var_val_len,
+ u_char ** var_val, size_t * listlength)
+{
+ u_char var_op_type;
+ size_t var_op_len = *listlength;
+ u_char *var_op_start = data;
+
+ data = asn_parse_sequence(data, &var_op_len, &var_op_type,
+ (ASN_SEQUENCE | ASN_CONSTRUCTOR), "var_op");
+ if (data == NULL) {
+ /*
+ * msg detail is set
+ */
+ return NULL;
+ }
+ DEBUGDUMPHEADER("recv", "Name");
+ data =
+ asn_parse_objid(data, &var_op_len, &var_op_type, var_name,
+ var_name_len);
+ DEBUGINDENTLESS();
+ if (data == NULL) {
+ ERROR_MSG("No OID for variable");
+ return NULL;
+ }
+ if (var_op_type !=
+ (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID))
+ return NULL;
+ *var_val = data; /* save pointer to this object */
+ /*
+ * find out what type of object this is
+ */
+ data = asn_parse_header(data, &var_op_len, var_val_type);
+ if (data == NULL) {
+ ERROR_MSG("No header for value");
+ return NULL;
+ }
+ /*
+ * XXX no check for type!
+ */
+ *var_val_len = var_op_len;
+ data += var_op_len;
+ *listlength -= (int) (data - var_op_start);
+ return data;
+}
+
+/*
+ * u_char * snmp_build_var_op(
+ * u_char *data IN - pointer to the beginning of the output buffer
+ * oid *var_name IN - object id of variable
+ * int *var_name_len IN - length of object id
+ * u_char var_val_type IN - type of variable
+ * int var_val_len IN - length of variable
+ * u_char *var_val IN - value of variable
+ * int *listlength IN/OUT - number of valid bytes left in
+ * output buffer
+ */
+
+u_char *
+snmp_build_var_op(u_char * data,
+ oid * var_name,
+ size_t * var_name_len,
+ u_char var_val_type,
+ size_t var_val_len,
+ u_char * var_val, size_t * listlength)
+{
+ size_t dummyLen, headerLen;
+ u_char *dataPtr;
+
+ dummyLen = *listlength;
+ dataPtr = data;
+#if 0
+ data = asn_build_sequence(data, &dummyLen,
+ (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR),
+ 0);
+ if (data == NULL) {
+ return NULL;
+ }
+#endif
+ if (dummyLen < 4)
+ return NULL;
+ data += 4;
+ dummyLen -= 4;
+
+ headerLen = data - dataPtr;
+ *listlength -= headerLen;
+ DEBUGDUMPHEADER("send", "Name");
+ data = asn_build_objid(data, listlength,
+ (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
+ ASN_OBJECT_ID), var_name,
+ *var_name_len);
+ DEBUGINDENTLESS();
+ if (data == NULL) {
+ ERROR_MSG("Can't build OID for variable");
+ return NULL;
+ }
+ DEBUGDUMPHEADER("send", "Value");
+ switch (var_val_type) {
+ case ASN_INTEGER:
+ data = asn_build_int(data, listlength, var_val_type,
+ (long *) var_val, var_val_len);
+ break;
+ case ASN_GAUGE:
+ case ASN_COUNTER:
+ case ASN_TIMETICKS:
+ case ASN_UINTEGER:
+ data = asn_build_unsigned_int(data, listlength, var_val_type,
+ (u_long *) var_val, var_val_len);
+ break;
+#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
+ case ASN_OPAQUE_COUNTER64:
+ case ASN_OPAQUE_U64:
+#endif
+ case ASN_COUNTER64:
+ data = asn_build_unsigned_int64(data, listlength, var_val_type,
+ (struct counter64 *) var_val,
+ var_val_len);
+ break;
+ case ASN_OCTET_STR:
+ case ASN_IPADDRESS:
+ case ASN_OPAQUE:
+ case ASN_NSAP:
+ data = asn_build_string(data, listlength, var_val_type,
+ var_val, var_val_len);
+ break;
+ case ASN_OBJECT_ID:
+ data = asn_build_objid(data, listlength, var_val_type,
+ (oid *) var_val, var_val_len / sizeof(oid));
+ break;
+ case ASN_NULL:
+ data = asn_build_null(data, listlength, var_val_type);
+ break;
+ case ASN_BIT_STR:
+ data = asn_build_bitstring(data, listlength, var_val_type,
+ var_val, var_val_len);
+ break;
+ case SNMP_NOSUCHOBJECT:
+ case SNMP_NOSUCHINSTANCE:
+ case SNMP_ENDOFMIBVIEW:
+ data = asn_build_null(data, listlength, var_val_type);
+ break;
+#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
+ case ASN_OPAQUE_FLOAT:
+ data = asn_build_float(data, listlength, var_val_type,
+ (float *) var_val, var_val_len);
+ break;
+ case ASN_OPAQUE_DOUBLE:
+ data = asn_build_double(data, listlength, var_val_type,
+ (double *) var_val, var_val_len);
+ break;
+ case ASN_OPAQUE_I64:
+ data = asn_build_signed_int64(data, listlength, var_val_type,
+ (struct counter64 *) var_val,
+ var_val_len);
+ break;
+#endif /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */
+ default:
+ {
+ char error_buf[64];
+ snprintf(error_buf, sizeof(error_buf),
+ "wrong type in snmp_build_var_op: %d", var_val_type);
+ ERROR_MSG(error_buf);
+ data = NULL;
+ }
+ }
+ DEBUGINDENTLESS();
+ if (data == NULL) {
+ return NULL;
+ }
+ dummyLen = (data - dataPtr) - headerLen;
+
+ asn_build_sequence(dataPtr, &dummyLen,
+ (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR),
+ dummyLen);
+ return data;
+}
+
+#ifdef NETSNMP_USE_REVERSE_ASNENCODING
+int
+snmp_realloc_rbuild_var_op(u_char ** pkt, size_t * pkt_len,
+ size_t * offset, int allow_realloc,
+ const oid * var_name, size_t * var_name_len,
+ u_char var_val_type,
+ u_char * var_val, size_t var_val_len)
+{
+ size_t start_offset = *offset;
+ int rc = 0;
+
+ /*
+ * Encode the value.
+ */
+ DEBUGDUMPHEADER("send", "Value");
+
+ switch (var_val_type) {
+ case ASN_INTEGER:
+ rc = asn_realloc_rbuild_int(pkt, pkt_len, offset, allow_realloc,
+ var_val_type, (long *) var_val,
+ var_val_len);
+ break;
+
+ case ASN_GAUGE:
+ case ASN_COUNTER:
+ case ASN_TIMETICKS:
+ case ASN_UINTEGER:
+ rc = asn_realloc_rbuild_unsigned_int(pkt, pkt_len, offset,
+ allow_realloc, var_val_type,
+ (u_long *) var_val,
+ var_val_len);
+ break;
+
+#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
+ case ASN_OPAQUE_COUNTER64:
+ case ASN_OPAQUE_U64:
+#endif
+ case ASN_COUNTER64:
+ rc = asn_realloc_rbuild_unsigned_int64(pkt, pkt_len, offset,
+ allow_realloc, var_val_type,
+ (struct counter64 *)
+ var_val, var_val_len);
+ break;
+
+ case ASN_OCTET_STR:
+ case ASN_IPADDRESS:
+ case ASN_OPAQUE:
+ case ASN_NSAP:
+ rc = asn_realloc_rbuild_string(pkt, pkt_len, offset, allow_realloc,
+ var_val_type, var_val, var_val_len);
+ break;
+
+ case ASN_OBJECT_ID:
+ rc = asn_realloc_rbuild_objid(pkt, pkt_len, offset, allow_realloc,
+ var_val_type, (oid *) var_val,
+ var_val_len / sizeof(oid));
+ break;
+
+ case ASN_NULL:
+ rc = asn_realloc_rbuild_null(pkt, pkt_len, offset, allow_realloc,
+ var_val_type);
+ break;
+
+ case ASN_BIT_STR:
+ rc = asn_realloc_rbuild_bitstring(pkt, pkt_len, offset,
+ allow_realloc, var_val_type,
+ var_val, var_val_len);
+ break;
+
+ case SNMP_NOSUCHOBJECT:
+ case SNMP_NOSUCHINSTANCE:
+ case SNMP_ENDOFMIBVIEW:
+ rc = asn_realloc_rbuild_null(pkt, pkt_len, offset, allow_realloc,
+ var_val_type);
+ break;
+
+#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
+ case ASN_OPAQUE_FLOAT:
+ rc = asn_realloc_rbuild_float(pkt, pkt_len, offset, allow_realloc,
+ var_val_type, (float *) var_val,
+ var_val_len);
+ break;
+
+ case ASN_OPAQUE_DOUBLE:
+ rc = asn_realloc_rbuild_double(pkt, pkt_len, offset, allow_realloc,
+ var_val_type, (double *) var_val,
+ var_val_len);
+ break;
+
+ case ASN_OPAQUE_I64:
+ rc = asn_realloc_rbuild_signed_int64(pkt, pkt_len, offset,
+ allow_realloc, var_val_type,
+ (struct counter64 *) var_val,
+ var_val_len);
+ break;
+#endif /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */
+ default:
+ {
+ char error_buf[64];
+ snprintf(error_buf, sizeof(error_buf),
+ "wrong type in snmp_realloc_rbuild_var_op: %d", var_val_type);
+ ERROR_MSG(error_buf);
+ rc = 0;
+ }
+ }
+ DEBUGINDENTLESS();
+
+ if (rc == 0) {
+ return 0;
+ }
+
+ /*
+ * Build the OID.
+ */
+
+ DEBUGDUMPHEADER("send", "Name");
+ rc = asn_realloc_rbuild_objid(pkt, pkt_len, offset, allow_realloc,
+ (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
+ ASN_OBJECT_ID), var_name,
+ *var_name_len);
+ DEBUGINDENTLESS();
+ if (rc == 0) {
+ ERROR_MSG("Can't build OID for variable");
+ return 0;
+ }
+
+ /*
+ * Build the sequence header.
+ */
+
+ rc = asn_realloc_rbuild_sequence(pkt, pkt_len, offset, allow_realloc,
+ (u_char) (ASN_SEQUENCE |
+ ASN_CONSTRUCTOR),
+ *offset - start_offset);
+ return rc;
+}
+
+#endif /* NETSNMP_USE_REVERSE_ASNENCODING */