Blame snmplib/snmp.c

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