Logo Search packages:      
Sourcecode: mbrowse version File versions  Download package

snmpstuff.c

/*
 * snmpstuff.c
 *
 * $Revision: 1.13 $
 *
 * These functions deal with processing mib/snmp data.
 * A bunch of this is ucd-snmp code hacked to deal with
 * a GUI interface.
 *
 * Last Modified:
 *   $Author: ahodgen $
 *   $Date: 2002/06/21 11:45:18 $
 *
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "callbacks.h"
#include "interface.h"
#include "details.h"
#include "configuration.h"
#include "snmpstuff.h"

#define GTK_SNMP_PERROR disperror(snmp_api_errstring(snmp_errno));

#ifdef HAVE_BROKEN_API
#  define snprint_variable(a,b,c,d,e) \
     sprint_variable(binit(NULL, a, b),c,d,e);
#  define snprint_objid(a,b,c,d) \
     sprint_variable(binit(NULL,a,b),c,d);
#else
#  ifndef HAVE_NETSNMP
#    define snprint_variable(a,b,c,d,e) \
       sprint_variable(a,c,d,e);
#    define snprint_objid(a,b,c,d) \
       sprint_objid(a,c,d)
#  endif
#endif


oid objid_mib[] = {1, 3, 6, 1};

int numprinted;
struct tree *mibtree;

#define READ_ONLY 0
#define READ_WRITE      1

struct snmp_session *mbrowse_create_snmp_session(struct snmp_session *session,int comm_type) {

  config_t *config;

  config = get_config();
  snmp_sess_init(session);
  session->version = config->snmp_ver;
  session->peername = get_hostname();
  session->retries = config->snmp_retries;
  session->timeout = config->snmp_timeout * 1000000L;
  session->remote_port = config->snmp_port; 
  switch(comm_type) {
    case READ_WRITE:
      session->community = get_writecomm();
      break;
    case READ_ONLY:
    default:
      session->community = get_readcomm();
      break;
  }
  session->community_len = strlen(session->community);
  return(snmp_open(session));
}

struct tree *init_mbrowse_snmp(void) {

  snmp_set_save_descriptions(1);
  init_snmp("browser");
/*  init_mib_internals();
  adopt_orphans();*/
  mibtree = read_all_mibs();
  snmp_set_suffix_only(1);
  return(mibtree);
}

static void _snmpget(struct snmp_session *ss, oid *theoid, 
              size_t theoid_len, gpointer window) {

  struct snmp_pdu *pdu, *response;
  struct variable_list *vars;
  int status;
  char buf[SPRINT_MAX_LEN];

  pdu = snmp_pdu_create(SNMP_MSG_GET);
  snmp_add_null_var(pdu, theoid, theoid_len);

  status = snmp_synch_response(ss, pdu, &response);
  if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
    for(vars = response->variables; vars; vars = vars->next_variable) {
      numprinted++;
      snprint_variable(buf, sizeof(buf),vars->name,vars->name_length,vars);
      strcat(buf,"\n");
      gtk_text_insert(window,NULL,NULL,NULL,buf,-1);
    }
  }
  if (response)
    snmp_free_pdu(response);
}

void snmpget(char *host,char *object,char *community,gpointer user_data) {

  char buf[SPRINT_MAX_LEN],temp[SPRINT_MAX_LEN];
  char *error;
  struct snmp_session session, *ss;
  struct snmp_pdu *pdu;
  struct snmp_pdu *response = NULL;
  struct variable_list *vars;
  int count;
  oid name[MAX_OID_LEN];
  size_t name_length = MAX_OID_LEN;
  int status;

  ss = mbrowse_create_snmp_session(&session,READ_ONLY);
  if (ss == NULL){
    /* diagnose snmp_open errors with the input struct snmp_session pointer */
    snmp_error(&session,NULL,NULL,&error);
    disperror(error);
    return;
  }
  pdu = snmp_pdu_create(SNMP_MSG_GET);
  if (!snmp_parse_oid(object, name, &name_length)) {
    GTK_SNMP_PERROR;
    return;
  } else
    snmp_add_null_var(pdu, name, name_length);

    status = snmp_synch_response(ss, pdu, &response);
    if (status == STAT_SUCCESS){
      if (response->errstat == SNMP_ERR_NOERROR){
        for(vars = response->variables; vars; vars = vars->next_variable) {
        snprint_variable(buf,sizeof(buf),vars->name,vars->name_length,vars);
          gtk_text_insert(user_data,NULL,NULL,NULL,buf,-1);
        }
      } else {
        sprintf(buf,"Error in Packet: %s",snmp_errstring(response->errstat));
        disperror(buf);
        if (response->errstat == SNMP_ERR_NOSUCHNAME){
          sprintf(temp,"This name doesn't exist: ");
          for(count = 1, vars = response->variables;
                vars && count != response->errindex;
                vars = vars->next_variable, count++)
          if (vars) {
          snprint_objid(buf,sizeof(buf),vars->name,vars->name_length);
            strcat(temp,buf);
          }
          disperror(temp);
        }
      }  /* endif -- SNMP_ERR_NOERROR */
    } else if (status == STAT_TIMEOUT){
      disperror("Timed out. (Check community string)");
      snmp_close(ss);
      return;
    } else {    /* status == STAT_ERROR */
      snmp_error(&session,NULL,NULL,&error);
      disperror(error);
      snmp_close(ss);
      return;
    }  /* endif -- STAT_SUCCESS */
    if (response)
      snmp_free_pdu(response);
    snmp_close(ss);
}

void snmpwalk(char *host,char *object,char *community,gpointer user_data) {

  char buf[SPRINT_MAX_LEN],temp[SPRINT_MAX_LEN];
  char *error;
  struct snmp_session session, *ss;
  struct snmp_pdu *pdu;
  struct snmp_pdu *response = NULL;
  struct variable_list *vars;
  int count;
  oid root[MAX_OID_LEN];
  size_t rootlen = MAX_OID_LEN;
  oid name[MAX_OID_LEN];
  size_t name_length = MAX_OID_LEN;
  int status = 0;
  int notdone = 1;

  numprinted=0;
  ss = mbrowse_create_snmp_session(&session,READ_ONLY);
  if (ss == NULL){
   /* diagnose snmp_open errors with the input struct snmp_session pointer */
    snmp_error(&session,NULL,NULL,&error);
    disperror(error);
    return;
  }
  
  if (object && strlen(object)) {
    if (!snmp_parse_oid(object, root, &rootlen)) {
      GTK_SNMP_PERROR;
      return;
    }
  } else {
   memmove(root, objid_mib, sizeof(objid_mib));
   rootlen = sizeof(objid_mib) / sizeof(oid);
  }
  memmove(name, root, rootlen * sizeof(oid));
  name_length = rootlen;
  _snmpget(ss, root, rootlen, user_data);
  while(notdone) {
    pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
    snmp_add_null_var(pdu, name, name_length);

    /* do the request */
    status = snmp_synch_response(ss, pdu, &response);
      if (status == STAT_SUCCESS){
        if (response->errstat == SNMP_ERR_NOERROR){
          /* check resulting variables */
          for(vars = response->variables; vars; vars = vars->next_variable){
            if ((vars->name_length < rootlen) ||
                (memcmp(root, vars->name, rootlen * sizeof(oid))!=0)) {
              /* not part of this subtree */
              notdone = 0;
              continue;
            }
            numprinted++;
          snprint_variable(buf,sizeof(buf),vars->name,vars->name_length,vars);
            strcat(buf,"\n");
            gtk_text_insert(user_data,NULL,NULL,NULL,buf,-1);
            if ((vars->type != SNMP_ENDOFMIBVIEW) &&
                (vars->type != SNMP_NOSUCHOBJECT) &&
                (vars->type != SNMP_NOSUCHINSTANCE)){
              /* not an exception value */
              memmove((char *)name, (char *)vars->name,
              vars->name_length * sizeof(oid));
              name_length = vars->name_length;
            } else
              /* an exception value, so stop */
              notdone = 0;
          }
        } else {
          /* error in response, print it */
          notdone = 0;
          if (response->errstat == SNMP_ERR_NOSUCHNAME){
            gtk_text_insert(user_data,NULL,NULL,NULL,"End of MIB\n",-1);
          } else {
            sprintf(buf,"Error in Packet: %s",
                     snmp_errstring(response->errstat));
            disperror(buf);
            if (response->errstat == SNMP_ERR_NOSUCHNAME) {
              sprintf(temp,"The request for this object identifier failed: ");
              for(count = 1, vars = response->variables;
                    vars && count != response->errindex;
                    vars = vars->next_variable, count++)
              if (vars) {
            snprint_objid(buf,sizeof(buf),vars->name,vars->name_length);
                strcat(temp,buf);
              }
              disperror(temp);
            }
          }
        }
      } else if (status == STAT_TIMEOUT){
        disperror("Timed out. (Check community string)");
        notdone = 0;
        snmp_close(ss);
        return;
      } else {    /* status == STAT_ERROR */
        snmp_sess_perror("snmpwalk", ss);
        notdone = 0;
      }
      if (response)
        snmp_free_pdu(response);
    }
    if (numprinted == 0 && status == STAT_SUCCESS) {
        /* no printed successful results, which may mean we were
           pointed at an only existing instance.  Attempt a GET, just
           for get measure. */
        _snmpget(ss, root, rootlen, user_data);
    }
    snmp_close(ss);
    sprintf(buf,"Variables found: %d", numprinted);
    disperror(buf);
}

void snmpset(char *host,char *object,char *community,char *value,
             gpointer window) {

  char buf[SPRINT_MAX_LEN];
  char *error;
  struct snmp_session session,*ss;
  struct snmp_pdu *pdu;
  struct snmp_pdu *response;
  struct variable_list *vars;
  struct tree *subtree;
  oid name[MAX_OID_LEN];
  size_t name_length = MAX_OID_LEN;
  int status;
  char type = 0;
  char *as;

  if (!value || (*value == 0)) {
    disperror("Value is required for a set.");
    return;
  }
  if (!read_objid(object,name,&name_length)) {
    disperror("Invalid Object ID");
    return;
  }
  subtree = get_tree(name,name_length,get_tree_head());
  as = get_as();
  if (as && *as) {
    switch(*as) {
      case 'S':
      type = 's';
      break;
      case 'I':
      type = 'd';
      break;
      case 'H':
      type = 'x';
      break;
      default:
      type = '=';
      break;
    }
  } else {
    switch(subtree->type) {
      case TYPE_OBJID:
      type = 'o';
      break;
      case TYPE_OCTETSTR:
      type = 's';
      break;
      case TYPE_IPADDR:
      type = 'a';
      break;
      case TYPE_TIMETICKS:
      type = 't';
      break;
      case TYPE_COUNTER:
      case TYPE_COUNTER64:
      case TYPE_GAUGE:
      case TYPE_INTEGER:
      case TYPE_UINTEGER:
      case TYPE_INTEGER32:
      case TYPE_UNSIGNED32:
      type='i';
      break;
      case TYPE_OPAQUE:
      case TYPE_NULL:
      case TYPE_BITSTRING:
      case TYPE_NSAPADDRESS:
      case TYPE_NETADDR:
      case TYPE_OTHER:
      default:
       break;
    }
  }
  if (type == 0) {
    disperror("Cannot handle object type at this time.");
    return;
  }
  ss = mbrowse_create_snmp_session(&session,READ_WRITE);
  if (ss == NULL) {
    snmp_error(&session,NULL,NULL,&error);
    disperror(error);
    return;
  }
  pdu = snmp_pdu_create(SNMP_MSG_SET);
  if (!snmp_parse_oid(object,name,&name_length)) {
    GTK_SNMP_PERROR;
    return;
  } else {
     if (snmp_add_var(pdu,name,name_length,type,value)) {
       GTK_SNMP_PERROR;
       return;
     }
  }
  status = snmp_synch_response(ss,pdu,&response);
  if (status == STAT_SUCCESS) {
    if (response->errstat == SNMP_ERR_NOERROR) {
      for(vars = response->variables; vars; vars = vars->next_variable) {
      snprint_variable(buf,sizeof(buf),vars->name,vars->name_length,vars);
        strcat(buf,"\n");
        gtk_text_insert(window,NULL,NULL,NULL,buf,-1);
      }
    } else {
      sprintf(buf,"Error in Packet: %s",snmp_errstring(response->errstat));
      disperror(buf);
    }
  } else if (status == STAT_TIMEOUT) {
    disperror("Timed out. (Check community string)");
    snmp_close(ss);
    return;
  } else {
    snmp_error(&session,NULL,NULL,&error);
    disperror(error);
    snmp_close(ss);
  }
  if (response)
    snmp_free_pdu(response);
  snmp_close(ss);
}

Generated by  Doxygen 1.6.0   Back to index