Example #1
0
void init_master(void)
{
    struct snmp_session sess, *session;

    if ( ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE) != MASTER_AGENT )
	return;

    DEBUGMSGTL(("agentx/master","initializing...\n"));
    snmp_sess_init( &sess );
    sess.version  = AGENTX_VERSION_1;
    sess.flags  |= SNMP_FLAGS_STREAM_SOCKET;
    if ( ds_get_string(DS_APPLICATION_ID, DS_AGENT_X_SOCKET) )
	sess.peername = strdup(ds_get_string(DS_APPLICATION_ID, DS_AGENT_X_SOCKET));
    else
	sess.peername = strdup(AGENTX_SOCKET);

    if ( sess.peername[0] == '/' ) {
			/*
			 *  If this is a Unix pathname,
			 *  try and create the directory first.
			 */
	if (mkdirhier(sess.peername, AGENT_DIRECTORY_MODE, 1)) {
	    snmp_log(LOG_ERR,
		"Failed to create the directory for the agentX socket: %s\n",
                 sess.peername);
	}
    }
			/*
			 *  Otherwise, let 'snmp_open' interpret the string.
			 */
    sess.local_port  = AGENTX_PORT;         /* Indicate server & set default port */
    sess.remote_port = 0;
    sess.callback = handle_master_agentx_packet;
    session = snmp_open_ex( &sess, 0, agentx_parse, 0, agentx_build,
                            agentx_check_packet );

    if ( session == NULL && sess.s_errno == EADDRINUSE ) {
		/*
		 * Could be a left-over socket (now deleted)
		 * Try again
		 */
        session = snmp_open_ex( &sess, 0, agentx_parse, 0, agentx_build,
                            agentx_check_packet );
    }

    if ( session == NULL ) {
      /* diagnose snmp_open errors with the input struct snmp_session pointer */
	snmp_sess_perror("init_master", &sess);
        if (!ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS))
          exit(1);
    }

    DEBUGMSGTL(("agentx/master","initializing...   DONE\n"));
}
Example #2
0
/*******************************************************************-o-******
 * snmp_check_packet
 *
 * Parameters:
 *	session, from
 *
 * Returns:
 *	1	On success.
 *	0	On error.
 *
 * Handler for all incoming messages (a.k.a. packets) for the agent.  If using
 * the libwrap utility, log the connection and deny/allow the access. Print
 * output when appropriate, and increment the incoming counter.
 *
 */
int
snmp_check_packet(struct snmp_session *session,
                  snmp_ipaddr from)
{
    struct sockaddr_in *fromIp = (struct sockaddr_in *)&from;

#ifdef USE_LIBWRAP
    const char *addr_string;
    /*
     * Log the message and/or dump the message.
     * Optionally cache the network address of the sender.
     */
    addr_string = inet_ntoa(fromIp->sin_addr);

    if(!addr_string) {
        addr_string = STRING_UNKNOWN;
    }
    if(hosts_ctl("snmpd", addr_string, addr_string, STRING_UNKNOWN)) {
        snmp_log(allow_severity, "Connection from %s\n", addr_string);
    } else {
        snmp_log(deny_severity, "Connection from %s REFUSED\n", addr_string);
        return(0);
    }
#endif	/* USE_LIBWRAP */

    snmp_increment_statistic(STAT_SNMPINPKTS);

    if (log_addresses || ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE)) {
        int count;

        for(count = 0; count < ADDRCACHE; count++) {
            if (addrCache[count].status > UNUSED /* used or old */
                    && fromIp->sin_addr.s_addr == addrCache[count].addr)
                break;
        }

        if (count >= ADDRCACHE ||
                ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE)) {
            snmp_log(LOG_INFO, "Received SNMP packet(s) from %s\n",
                     inet_ntoa(fromIp->sin_addr));
            for(count = 0; count < ADDRCACHE; count++) {
                if (addrCache[count].status == UNUSED) {
                    addrCache[count].addr = fromIp->sin_addr.s_addr;
                    addrCache[count].status = USED;
                    break;
                }
            }
        } else {
            addrCache[count].status = USED;
        }
    }

    return ( 1 );
}
Example #3
0
int
init_master_agent(int dest_port, 
                  int (*pre_parse) (struct snmp_session *, snmp_ipaddr),
                  int (*post_parse) (struct snmp_session *, struct snmp_pdu *,int))
{
    struct snmp_session sess, *session;

    if ( ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE) != MASTER_AGENT )
	return 0; /* no error if ! MASTER_AGENT */

    DEBUGMSGTL(("snmpd","installing master agent on port %d\n", dest_port));

    snmp_sess_init( &sess );
    
    sess.version = SNMP_DEFAULT_VERSION;
    sess.peername = SNMP_DEFAULT_PEERNAME;
    sess.community_len = SNMP_DEFAULT_COMMUNITY_LEN;
     
    sess.local_port = dest_port;
    sess.callback = handle_snmp_packet;
    sess.authenticator = NULL;
    sess.flags = ds_get_int(DS_APPLICATION_ID, DS_AGENT_FLAGS);
    session = snmp_open_ex( &sess, pre_parse, 0, post_parse, 0, 0 );

    if ( session == NULL ) {
      /* diagnose snmp_open errors with the input struct snmp_session pointer */
	snmp_sess_perror("init_master_agent", &sess);
		return 1;
    }
    main_session = session;
	return 0;
}
void
snmp_log_string (int priority, const char *string)
{
    char sbuf[40];
    struct snmp_log_message slm;

#if HAVE_SYSLOG_H
  if (do_syslogging) {
    syslog(priority, string);
  }
#endif

  if (do_log_callback) {
      slm.priority = priority;
      slm.msg = string;
      snmp_call_callbacks(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_LOGGING, &slm);
  }

  if (do_filelogging || do_stderrlogging) {

    if (ds_get_boolean(DS_LIBRARY_ID, DS_LIB_LOG_TIMESTAMP) && newline) {
      sprintf_stamp(NULL, (char *)&sbuf);
    } else {
      strcpy(sbuf, "");
    }
    newline = string[strlen(string)-1] == '\n';

    if (do_filelogging)
      fprintf(logfile, "%s%s", sbuf, string);

    if (do_stderrlogging)
      fprintf(stderr, "%s%s", sbuf, string);
  }
}
void init_agent_read_config (const char *app)
{
  if ( app != NULL )
      ds_set_string(DS_LIBRARY_ID, DS_LIB_APPTYPE, app);

  register_app_config_handler("authtrapenable",
                          snmpd_parse_config_authtrap, NULL,
                          "1 | 2\t\t(1 = enable, 2 = disable)");

  if ( ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE) == MASTER_AGENT ) {
      register_app_config_handler("trapsink",
                          snmpd_parse_config_trapsink, snmpd_free_trapsinks,
                          "host [community]");
      register_app_config_handler("trap2sink",
                          snmpd_parse_config_trap2sink, NULL,
                          "host [community]");
      register_app_config_handler("informsink",
                          snmpd_parse_config_informsink, NULL,
                          "host [community]");
  }
  register_app_config_handler("trapcommunity",
                          snmpd_parse_config_trapcommunity,
                          snmpd_free_trapcommunity,
                          "community-string");
#include "mib_module_dot_conf.h"
#ifdef TESTING
  print_config_handlers();
#endif
}
Example #6
0
void setup_tree (void)
{
#ifdef USING_AGENTX_SUBAGENT_MODULE
  int role;

  role = ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE);
  ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, MASTER_AGENT);
#endif

  register_mib("", NULL, 0, 0,
	root_subtrees[0].name,  root_subtrees[0].namelen);
  register_mib("", NULL, 0, 0,
	root_subtrees[1].name,  root_subtrees[1].namelen);
  register_mib("", NULL, 0, 0,
	root_subtrees[2].name,  root_subtrees[2].namelen);

  /* Support for 'static' subtrees (subtrees_old) has now been dropped */

  /* No longer necessary to sort the mib tree - this is inherent in
     the construction of the subtree structure */

#ifdef USING_AGENTX_SUBAGENT_MODULE
  ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, role);
#endif
}
Example #7
0
void
init_agent (const char *app)
{
  /* get current time (ie, the time the agent started) */
  gettimeofday(&starttime, NULL);
  starttime.tv_sec--;
  starttime.tv_usec += 1000000L;

  /* we handle alarm signals ourselves in the select loop */
  ds_set_boolean(DS_LIBRARY_ID, DS_LIB_ALARM_DONT_USE_SIG, 1);

#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
  usm_set_reportErrorOnUnknownID(1);
#endif

#ifdef CAN_USE_NLIST
  init_kmem("/dev/kmem");
#endif

  setup_tree();

  init_agent_read_config(app);

#ifdef TESTING
  auto_nlist_print_tree(-2, 0);
#endif

  /* initialize agentx subagent if necessary. */
#ifdef USING_AGENTX_SUBAGENT_MODULE
  if(ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE) == SUB_AGENT)
      subagent_pre_init();
#endif

}  /* end init_agent() */
Example #8
0
void
init_kmem(const char *file)
{
#if HAVE_KVM_OPENFILES
    char err[4096];
    kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, err);
    if (kd == NULL && !ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS)) {
	snmp_log(LOG_CRIT, "init_kmem: kvm_openfiles failed: %s\n", err);
	exit(1);
    }
#else
    kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL);
    if (!kd && !ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS)) {
	snmp_log(LOG_CRIT, "init_kmem: kvm_open failed: %s\n", strerror(errno));
	exit(1);
    }
#endif	/* HAVE_KVM_OPENFILES */
}
Example #9
0
void
read_premib_configs (void)
{
  DEBUGMSGTL(("read_config","reading premib configuration tokens\n"));

  if (!ds_get_boolean(DS_LIBRARY_ID, DS_LIB_DONT_READ_CONFIGS))
    read_config_files(PREMIB_CONFIG);

  snmp_call_callbacks(SNMP_CALLBACK_LIBRARY,
                      SNMP_CALLBACK_POST_PREMIB_READ_CONFIG,
                      NULL);
}
Example #10
0
int
snmp_check_parse( struct snmp_session *session,
                  struct snmp_pdu     *pdu,
                  int    result)
{
    if ( result == 0 ) {
        if ( ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE) &&
                snmp_get_do_logging() ) {
            char c_oid [SPRINT_MAX_LEN];
            struct variable_list *var_ptr;

            switch (pdu->command) {
            case SNMP_MSG_GET:
                snmp_log(LOG_DEBUG, "  GET message\n");
                break;
            case SNMP_MSG_GETNEXT:
                snmp_log(LOG_DEBUG, "  GETNEXT message\n");
                break;
            case SNMP_MSG_RESPONSE:
                snmp_log(LOG_DEBUG, "  RESPONSE message\n");
                break;
            case SNMP_MSG_SET:
                snmp_log(LOG_DEBUG, "  SET message\n");
                break;
            case SNMP_MSG_TRAP:
                snmp_log(LOG_DEBUG, "  TRAP message\n");
                break;
            case SNMP_MSG_GETBULK:
                snmp_log(LOG_DEBUG, "  GETBULK message, non-rep=%d, max_rep=%d\n",
                         pdu->errstat, pdu->errindex);
                break;
            case SNMP_MSG_INFORM:
                snmp_log(LOG_DEBUG, "  INFORM message\n");
                break;
            case SNMP_MSG_TRAP2:
                snmp_log(LOG_DEBUG, "  TRAP2 message\n");
                break;
            case SNMP_MSG_REPORT:
                snmp_log(LOG_DEBUG, "  REPORT message\n");
                break;
            }

            for ( var_ptr = pdu->variables ;
                    var_ptr != NULL ; var_ptr=var_ptr->next_variable )
            {
                sprint_objid (c_oid, var_ptr->name, var_ptr->name_length);
                snmp_log(LOG_DEBUG, "    -- %s\n", c_oid);
            }
        }
        return 1;
    }
    return 0; /* XXX: does it matter what the return value is? */
}
Example #11
0
void
init_kmem(const char *file)
{
  kmem = open(file, O_RDONLY);
  if (kmem < 0 && !ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS)){
    snmp_log_perror(file);
    exit(1);
  }
  fcntl(kmem,F_SETFD,1);
  mem = open("/dev/mem",O_RDONLY);    
  if (mem < 0 && !ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS)){
    snmp_log_perror("/dev/mem");
    exit(1);
  }
  fcntl(mem,F_SETFD,1);
#ifdef DMEM_LOC
  swap = open(DMEM_LOC,O_RDONLY);
  if (swap < 0 && !ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS)){
    snmp_log_perror(DMEM_LOC);
    exit(1);
  }
  fcntl(swap,F_SETFD,1);
#endif
}
Example #12
0
void
read_configs (void)
{

  char *optional_config = ds_get_string(DS_LIBRARY_ID, DS_LIB_OPTIONALCONFIG);
  char *type = ds_get_string(DS_LIBRARY_ID, DS_LIB_APPTYPE);

  DEBUGMSGTL(("read_config","reading normal configuration tokens\n"));
  
  if (!ds_get_boolean(DS_LIBRARY_ID, DS_LIB_DONT_READ_CONFIGS))
    read_config_files(NORMAL_CONFIG);

 /* do this even when the normal above wasn't done */
  if (optional_config && type)
    read_config_with_type(optional_config, type);

  snmp_call_callbacks(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_POST_READ_CONFIG,
                      NULL);
}
Example #13
0
void
set_an_alarm(void) {
  int nexttime = get_next_alarm_delay_time();
  
  /* we don't use signals if they asked us nicely not to.  It's
     expected they'll check the next alarm time and do their own
     calling of run_alarms(). */
  if (!ds_get_boolean(DS_LIBRARY_ID, DS_LIB_ALARM_DONT_USE_SIG) && nexttime) {
#ifndef WIN32
#ifdef SIGALRM
//FIXMEHMTHMT    alarm(nexttime);
    DEBUGMSGTL(("snmp_alarm_set_an_alarm","setting an alarm for %d seconds from now\n",nexttime));
    signal(SIGALRM, alarm_handler);
#endif /* SIGALRM */
#endif

  } else {
    DEBUGMSGTL(("snmp_alarm_set_an_alarm","no alarms found to handle\n"));
  }
}
Example #14
0
void
init_sysORTable(void) {
  /* register ourselves with the agent to handle our mib tree */

#ifdef USING_AGENTX_SUBAGENT_MODULE
  if ( ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE) == MASTER_AGENT )
	(void)register_mib_priority("mibII/sysORTable",
		(struct variable *) sysORTable_variables,
		sizeof(struct variable2),
		sizeof(sysORTable_variables)/sizeof(struct variable2),
		sysORTable_variables_oid,
		sizeof(sysORTable_variables_oid)/sizeof(oid), 1);
  else
#endif
    REGISTER_MIB("mibII/sysORTable", sysORTable_variables, variable2, sysORTable_variables_oid);

#ifdef USING_MIBII_SYSTEM_MIB_MODULE
  if ( ++system_module_count == 3 )
	REGISTER_SYSOR_TABLE( system_module_oid, system_module_oid_len,
		"The MIB module for SNMPv2 entities");
#endif

  gettimeofday(&sysOR_lastchange, NULL);
}
Example #15
0
struct variable_list*
register_index(struct variable_list *varbind, int flags, struct snmp_session *ss )
{
    struct snmp_index *new_index, *idxptr, *idxptr2;
    struct snmp_index *prev_oid_ptr, *prev_idx_ptr;
    int res, res2, i;

#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(TESTING)
    if (ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE) == SUB_AGENT )
	return( agentx_register_index( ss, varbind, flags ));
#endif
		/* Look for the requested OID entry */
    prev_oid_ptr = NULL;
    prev_idx_ptr = NULL;
    res  = 1;
    res2 = 1;
    for( idxptr = snmp_index_head ; idxptr != NULL;
			 prev_oid_ptr = idxptr, idxptr = idxptr->next_oid) {
	if ((res = snmp_oid_compare(varbind->name, varbind->name_length,
					idxptr->varbind.name,
					idxptr->varbind.name_length)) <= 0 )
		break;
    }

		/*  Found the OID - now look at the registered indices */
    if ( res == 0 && idxptr ) {
	if ( varbind->type != idxptr->varbind.type )
	    return NULL;		/* wrong type */

			/*
			 * If we've been asked for an arbitrary new value,
			 *	then find the end of the list.
			 * If we've been asked for any arbitrary value,
			 *	then look for an unused entry, and use that.
			 *      If there aren't any, continue as for new.
			 * Otherwise, locate the given value in the (sorted)
			 *	list of already allocated values
			 */
	if ( flags & ALLOCATE_ANY_INDEX ) {
            for(idxptr2 = idxptr ; idxptr2 != NULL;
		 prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) {
		if ( flags == ALLOCATE_ANY_INDEX && idxptr2->session == NULL ) {
		    idxptr2->session = ss ;
		    return &idxptr2->varbind;
		}
	    }
	}
	else {
            for(idxptr2 = idxptr ; idxptr2 != NULL;
		 prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) {
	        switch ( varbind->type ) {
		    case ASN_INTEGER:
			res2 = (*varbind->val.integer - *idxptr2->varbind.val.integer);
			break;
		    case ASN_OCTET_STR:
			i = SNMP_MIN(varbind->val_len, idxptr2->varbind.val_len);
			res2 = memcmp(varbind->val.string, idxptr2->varbind.val.string, i);
			break;
		    case ASN_OBJECT_ID:
			res2 = snmp_oid_compare(varbind->val.objid, varbind->val_len/sizeof(oid),
					idxptr2->varbind.val.objid,
					idxptr2->varbind.val_len/sizeof(oid));
			break;
		    default:
	    		return NULL;		/* wrong type */
	        }
	        if ( res2 <= 0 )
		    break;
	    }
	    if ( res2 == 0 )
		return NULL;			/* duplicate value */
	}
    }

		/*
		 * OK - we've now located where the new entry needs to
		 *	be fitted into the index registry tree		
		 * To recap:
		 *	'prev_oid_ptr' points to the head of the OID index
		 *	    list prior to this one.  If this is null, then
		 *	    it means that this is the first OID in the list.
		 *	'idxptr' points either to the head of this OID list,
		 *	    or the next OID (if this is a new OID request)
		 *	    These can be distinguished by the value of 'res'.
		 *
		 *	'prev_idx_ptr' points to the index entry that sorts
		 *	    immediately prior to the requested value (if any).
		 *	    If an arbitrary value is required, then this will
		 *	    point to the last allocated index.
		 *	    If this pointer is null, then either this is a new
		 *	    OID request, or the requested value is the first
		 *	    in the list.
		 *	'idxptr2' points to the next sorted index (if any)
		 *	    but is not actually needed any more.
		 *
		 *  Clear?  Good!
		 *	I hope you've been paying attention.
		 *	    There'll be a test later :-)
		 */

		/*
		 *	We proceed by creating the new entry
		 *	   (by copying the entry provided)
		 */
	new_index = (struct snmp_index *)malloc( sizeof( struct snmp_index ));
	if (new_index == NULL)
	    return NULL;
	if (snmp_clone_var( varbind, &new_index->varbind ) != 0 ) {
	    free( new_index );
	    return NULL;
	}
	new_index->session = ss;

	if ( varbind->type == ASN_OCTET_STR && flags == ALLOCATE_THIS_INDEX )
	    new_index->varbind.val.string[new_index->varbind.val_len] = 0;

		/*
		 * If we've been given a value, then we can use that, but
		 *    otherwise, we need to create a new value for this entry.
		 * Note that ANY_INDEX and NEW_INDEX are both covered by this
		 *   test (since NEW_INDEX & ANY_INDEX = ANY_INDEX, remember?)
		 */
	if ( flags & ALLOCATE_ANY_INDEX ) {
	    if ( prev_idx_ptr ) {
		if ( snmp_clone_var( &prev_idx_ptr->varbind, &new_index->varbind ) != 0 ) {
		    free( new_index );
		    return NULL;
		}
	    }
	    else
		new_index->varbind.val.string = new_index->varbind.buf;

	    switch ( varbind->type ) {
		case ASN_INTEGER:
		    if ( prev_idx_ptr ) {
			(*new_index->varbind.val.integer)++; 
		    }
		    else
			*(new_index->varbind.val.integer) = 1;
		    new_index->varbind.val_len = sizeof(long);
		    break;
		case ASN_OCTET_STR:
		    if ( prev_idx_ptr ) {
			i =  new_index->varbind.val_len-1;
			while ( new_index->varbind.buf[ i ] == 'z' ) {
			    new_index->varbind.buf[ i ] = 'a';
			    i--;
			    if ( i < 0 ) {
				i =  new_index->varbind.val_len;
			        new_index->varbind.buf[ i ] = 'a';
			        new_index->varbind.buf[ i+1 ] = 0;
			    }
			}
			new_index->varbind.buf[ i ]++;
		    }
		    else
		        strcpy((char *)new_index->varbind.buf, "aaaa");
		    new_index->varbind.val_len = strlen((char *)new_index->varbind.buf);
		    break;
		case ASN_OBJECT_ID:
		    if ( prev_idx_ptr ) {
			i =  prev_idx_ptr->varbind.val_len/sizeof(oid) -1;
			while ( new_index->varbind.val.objid[ i ] == 255 ) {
			    new_index->varbind.val.objid[ i ] = 1;
			    i--;
			    if ( i == 0 && new_index->varbind.val.objid[0] == 2 ) {
			        new_index->varbind.val.objid[ 0 ] = 1;
				i =  new_index->varbind.val_len/sizeof(oid);
			        new_index->varbind.val.objid[ i ] = 0;
				new_index->varbind.val_len += sizeof(oid);
			    }
			}
			new_index->varbind.val.objid[ i ]++;
		    }
		    else {
			/* If the requested OID name is small enough,
			 *   append another OID (1) and use this as the
			 *   default starting value for new indexes.
			 */
		        if ( (varbind->name_length+1) * sizeof(oid) <= 40 ) {
			    for ( i = 0 ; i < (int)varbind->name_length ; i++ )
			        new_index->varbind.val.objid[i] = varbind->name[i];
			    new_index->varbind.val.objid[varbind->name_length] = 1;
			    new_index->varbind.val_len =
					(varbind->name_length+1) * sizeof(oid);
		        }
		        else {
			    /* Otherwise use '.1.1.1.1...' */
			    i = 40/sizeof(oid);
			    if ( i > 4 )
				i = 4;
			    new_index->varbind.val_len = i * (sizeof(oid));
			    for (i-- ; i>=0 ; i-- )
			        new_index->varbind.val.objid[i] = 1;
		        }
		    }
		    break;
		default:
		    free( new_index );
		    return NULL;	/* Index type not supported */
	    }
	}

		/*
		 * Right - we've set up the new entry.
		 * All that remains is to link it into the tree.
		 * There are a number of possible cases here,
		 *   so watch carefully.
		 */
	if ( prev_idx_ptr ) {
	    new_index->next_idx = prev_idx_ptr->next_idx;
	    new_index->next_oid = prev_idx_ptr->next_oid;
	    prev_idx_ptr->next_idx = new_index;
	}
	else {
	    if ( res == 0 && idxptr ) {
	        new_index->next_idx = idxptr;
	        new_index->next_oid = idxptr->next_oid;
	    }
	    else {
	        new_index->next_idx = NULL;
	        new_index->next_oid = idxptr;
	    }

	    if ( prev_oid_ptr ) {
		while ( prev_oid_ptr ) {
		    prev_oid_ptr->next_oid = new_index;
		    prev_oid_ptr = prev_oid_ptr->next_idx;
		}
	    }
	    else
	        snmp_index_head = new_index;
	}
    return &new_index->varbind;
}
Example #16
0
/*******************************************************************-o-******
 * read_config
 *
 * Parameters:
 *	*filename
 *	*line_handler
 *	 when
 *
 * Read <filename> and process each line in accordance with the list of
 * <line_handler> functions.
 *
 *
 * For each line in <filename>, search the list of <line_handler>'s 
 * for an entry that matches the first token on the line.  This comparison is
 * case insensitive.
 *
 * For each match, check that <when> is the designated time for the
 * <line_handler> function to be executed before processing the line.
 */
void read_config(const char *filename,
		 struct config_line *line_handler,
		 int when)
{
#ifdef CYGPKG_SNMPLIB_FILESYSTEM_SUPPORT

  FILE *ifile;
  char line[STRINGMAX], token[STRINGMAX], tmpbuf[STRINGMAX];
  char *cptr;
  int i, done;
  struct config_line *lptr;

  linecount = 0;
  curfilename = filename;
  
  if ((ifile = fopen(filename, "r")) == NULL) {
#ifdef ENOENT
    if (errno == ENOENT) {
      DEBUGMSGTL(("read_config", "%s: %s\n", filename, strerror(errno)));
    } else
#endif /* ENOENT */
#ifdef EACCES
    if (errno == EACCES) {
      DEBUGMSGTL(("read_config", "%s: %s\n", filename, strerror(errno)));
    } else
#endif /* EACCES */
#if defined(ENOENT) || defined(EACCES)
    {
      snmp_log_perror(filename);
    }
#else /* defined(ENOENT) || defined(EACCES) */
    snmp_log_perror(filename);
#endif /* ENOENT */
    return;
  } else {
    DEBUGMSGTL(("read_config", "Reading configuration %s\n", filename));
  }

  while (fgets(line, sizeof(line), ifile) != NULL) 
    {
      lptr = line_handler;
      linecount++;
      cptr = line;
      i = strlen(line)-1;
      if (line[i] == '\n')
        line[i] = 0;
      /* check blank line or # comment */
      if ((cptr = skip_white(cptr)))
	{
          cptr = copy_word(cptr,token);
          if (cptr == NULL) {
            sprintf(tmpbuf,"Blank line following %s token.", token);
            config_perror(tmpbuf);
          } else {
            for(lptr = line_handler, done=0;
                lptr != NULL && !done;
                lptr = lptr->next) {
              if (!strcasecmp(token,lptr->config_token)) {
                if (when == EITHER_CONFIG || lptr->config_time == when) {
                    DEBUGMSGTL(("read_config", "%s:%d Parsing: %s\n",
                                filename, linecount, line));
                    (*(lptr->parse_line))(token,cptr);
                }
                done = 1;
              }
            }
            if (!done && when != PREMIB_CONFIG &&
                !ds_get_boolean(DS_LIBRARY_ID, DS_LIB_NO_TOKEN_WARNINGS)) {
              sprintf(tmpbuf,"Unknown token: %s.", token);
              config_pwarn(tmpbuf);
            }
          }
	}
    }
  fclose(ifile);
#endif
  return;

}  /* end read_config() */
Example #17
0
int
unregister_index(struct variable_list *varbind, int remember, struct snmp_session *ss)
{
    struct snmp_index *idxptr, *idxptr2;
    struct snmp_index *prev_oid_ptr, *prev_idx_ptr;
    int res, res2, i;

#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(TESTING)
    if (ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE) == SUB_AGENT )
	return( agentx_unregister_index( ss, varbind ));
#endif
		/* Look for the requested OID entry */
    prev_oid_ptr = NULL;
    prev_idx_ptr = NULL;
    res  = 1;
    res2 = 1;
    for( idxptr = snmp_index_head ; idxptr != NULL;
			 prev_oid_ptr = idxptr, idxptr = idxptr->next_oid) {
	if ((res = snmp_oid_compare(varbind->name, varbind->name_length,
					idxptr->varbind.name,
					idxptr->varbind.name_length)) <= 0 )
		break;
    }

    if ( res != 0 )
	return INDEX_ERR_NOT_ALLOCATED;
    if ( varbind->type != idxptr->varbind.type )
	return INDEX_ERR_WRONG_TYPE;

    for(idxptr2 = idxptr ; idxptr2 != NULL;
		prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) {
	i = SNMP_MIN(varbind->val_len, idxptr2->varbind.val_len);
	res2 = memcmp(varbind->val.string, idxptr2->varbind.val.string, i);
	if ( res2 <= 0 )
	    break;
    }
    if ( res2 != 0 )
	return INDEX_ERR_NOT_ALLOCATED;
    if ( ss != idxptr2->session )
	return INDEX_ERR_WRONG_SESSION;

		/*
		 *  If this is a "normal" index unregistration,
		 *	mark the index entry as unused, but leave
		 *	it in situ.  This allows differentiation
		 *	between ANY_INDEX and NEW_INDEX
		 */
    if ( remember ) {
	idxptr2->session = NULL;	/* Unused index */
	return SNMP_ERR_NOERROR;
    }
		/*
		 *  If this is a failed attempt to register a
		 *	number of indexes, the successful ones
		 *	must be removed completely.
		 */
    if ( prev_idx_ptr ) {
	prev_idx_ptr->next_idx = idxptr2->next_idx;
    }
    else if ( prev_oid_ptr ) {
	if ( idxptr2->next_idx )	/* Use p_idx_ptr as a temp variable */
	    prev_idx_ptr = idxptr2->next_idx;
	else
	    prev_idx_ptr = idxptr2->next_oid;
	while ( prev_oid_ptr ) {
	    prev_oid_ptr->next_oid = prev_idx_ptr;
	    prev_oid_ptr = prev_oid_ptr->next_idx;
	}
    }
    else {
	if ( idxptr2->next_idx )
	    snmp_index_head = idxptr2->next_idx;
	else
	    snmp_index_head = idxptr2->next_oid;
    }
    snmp_free_var( (struct variable_list *)idxptr2 );
    return SNMP_ERR_NOERROR;
}
Example #18
0
int
main(int argc, char *argv[])
{
    int             arg;
    char           *current_name = NULL, *cp = NULL;
    oid             name[MAX_OID_LEN];
    size_t          name_length;
    int             description = 0;
    int             print = 0;
    int             find_all = 0;
    int             width = 1000000;

    /*
     * usage: snmptranslate name
     */
    while ((arg = getopt(argc, argv, "Vhm:M:w:D:P:T:O:I:")) != EOF) {
        switch (arg) {
        case 'h':
            usage();
            exit(1);

        case 'm':
            setenv("MIBS", optarg, 1);
            break;
        case 'M':
            setenv("MIBDIRS", optarg, 1);
            break;
        case 'D':
            debug_register_tokens(optarg);
            snmp_set_do_debugging(1);
            break;
        case 'V':
            fprintf(stderr, "NET-SNMP version: %s\n",
                    netsnmp_get_version());
            exit(0);
            break;
        case 'P':
            cp = snmp_mib_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr, "Unknown parser option to -P: %c.\n", *cp);
                usage();
                exit(1);
            }
            break;
        case 'O':
            cp = snmp_out_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr, "Unknown OID option to -O: %c.\n", *cp);
                usage();
                exit(1);
            }
            break;
        case 'I':
            cp = snmp_in_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr, "Unknown OID option to -I: %c.\n", *cp);
                usage();
                exit(1);
            }
            break;
        case 'T':
            for (cp = optarg; *cp; cp++) {
                switch (*cp) {
                case 'l':
                    print = 3;
#ifdef __vms
                    print_oid_report_en_labeledoid();
#else
                    print_oid_report_enable_labeledoid();
#endif                    break;
                case 'o':
                    print = 3;
                    print_oid_report_enable_oid();
                    break;
                case 's':
                    print = 3;
#ifdef __vms
                    print_oid_report_en_symbolic();
#else
                    print_oid_report_enable_symbolic();
#endif
                    break;
                case 't':
                    print = 3;
                    print_oid_report_enable_suffix();
                    break;
                case 'd':
                    description = 1;
                    snmp_set_save_descriptions(1);
                    break;
                case 'B':
                    find_all = 1;
                    break;
                case 'p':
                    print = 1;
                    break;
                case 'a':
                    print = 2;
                    break;
                default:
                    fprintf(stderr, "Invalid -T<lostpad> character: %c\n",
                            *cp);
                    usage();
                    exit(1);
                    break;
                }
            }
            break;
        default:
            fprintf(stderr, "invalid option: -%c\n", arg);
            usage();
            exit(1);
            break;
        }
    }

    init_snmp("snmpapp");
    if (optind < argc)
        current_name = argv[optind];

    if (current_name == NULL) {
        switch (print) {
        default:
            usage();
            exit(1);
        case 1:
            print_mib_tree(stdout, get_tree_head(), width);
            break;
        case 2:
            print_ascii_dump(stdout);
            break;
        case 3:
            print_oid_report(stdout);
            break;
        }
        exit(0);
    }

    do {
        name_length = MAX_OID_LEN;
        if (snmp_get_random_access()) {
            if (!get_node(current_name, name, &name_length)) {
                fprintf(stderr, "Unknown object identifier: %s\n",
                        current_name);
                exit(2);
            }
        } else if (find_all) {
            if (0 == show_all_matched_objects(stdout, current_name,
                                              name, &name_length,
                                              description, width)) {
                fprintf(stderr,
                        "Unable to find a matching object identifier for \"%s\"\n",
                        current_name);
                exit(1);
            }
            exit(0);
        } else if (ds_get_boolean(DS_LIBRARY_ID, DS_LIB_REGEX_ACCESS)) {
            if (0 == get_wild_node(current_name, name, &name_length)) {
                fprintf(stderr,
                        "Unable to find a matching object identifier for \"%s\"\n",
                        current_name);
                exit(1);
            }
        } else {
            if (!read_objid(current_name, name, &name_length)) {
                snmp_perror(current_name);
                exit(2);
            }
        }


        if (print == 1) {
            struct tree    *tp;
            tp = get_tree(name, name_length, get_tree_head());
            print_mib_tree(stdout, tp, width);
        } else {
            print_objid(name, name_length);
            if (description) {
                print_description(name, name_length, width);
            }
        }
        current_name = argv[++optind];
        if (current_name != NULL)
            printf("\n");
    } while (optind < argc);

    return (0);
}
Example #19
0
int
main(int argc, char *argv[])
{
    int             arg, i;
    int             ret;
    u_short         dest_port = SNMP_PORT;
    int             dont_fork = 0;
    char            logfile[SNMP_MAXBUF_SMALL];
    char           *cptr, **argvptr;
    char           *pid_file = NULL;
#if HAVE_GETPID
    FILE           *PID;
#endif
    int             dont_zero_log = 0;
    int             stderr_log=0, syslog_log=0;
    int             uid=0, gid=0;

    logfile[0]		= 0;

#ifdef LOGFILE
    strcpy(logfile, LOGFILE);
#endif


    /*
     * usage: snmpd
     */
    for (arg = 1; arg < argc; arg++)
    {
        if (argv[arg][0] == '-') {
            switch (argv[arg][1]) {

            case 'c':
                if (++arg == argc)
                    usage(argv[0]);
                ds_set_string(DS_LIBRARY_ID, DS_LIB_OPTIONALCONFIG,
                              argv[arg]);
                break;

            case 'C':
                ds_set_boolean(DS_LIBRARY_ID, DS_LIB_DONT_READ_CONFIGS, 1);
                break;

            case 'd':
                snmp_set_dump_packet(++snmp_dump_packet);
                ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE, 1);
                break;

            case 'q':
                snmp_set_quick_print(1);
                break;

            case 'T':
                if (argv[arg][2] != '\0')
                    cptr = &argv[arg][2];
                else if (++arg>argc) {
                    fprintf(stderr,"Need UDP or TCP after -T flag.\n");
                    usage(argv[0]);
                    exit(1);
                } else {
                    cptr = argv[arg];
                }
                if (strcasecmp(cptr,"TCP") == 0) {
                    ds_set_int(DS_APPLICATION_ID, DS_AGENT_FLAGS,
                               ds_get_int(DS_APPLICATION_ID, DS_AGENT_FLAGS)
                               | SNMP_FLAGS_STREAM_SOCKET);
                } else if (strcasecmp(cptr,"UDP") == 0) {
                    /* default, do nothing */
                } else {
                    fprintf(stderr,
                            "Unknown transport \"%s\" after -T flag.\n",
                            cptr);
                    usage(argv[0]);
                    exit(1);
                }
                break;

            case 'D':
                debug_register_tokens(&argv[arg][2]);
                snmp_set_do_debugging(1);
                break;

            case 'p':
                if (++arg == argc)
                    usage(argv[0]);
                dest_port = atoi(argv[arg]);
                if (dest_port <= 0)
                    usage(argv[0]);
                break;

            case 'x':
                if (++arg == argc)
                    usage(argv[0]);
                ds_set_string(DS_APPLICATION_ID, DS_AGENT_X_SOCKET, argv[arg]);
                break;

            case 'r':
                ds_set_boolean(DS_APPLICATION_ID,
                               DS_AGENT_NO_ROOT_ACCESS, 1);
                break;

            case 'P':
                if (++arg == argc)
                    usage(argv[0]);
                pid_file = argv[arg];

            case 'a':
                log_addresses++;
                break;

            case 'V':
                ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE, 1);
                break;

            case 'f':
                dont_fork = 1;
                break;

            case 'l':
                if (++arg == argc)
                    usage(argv[0]);
                strcpy(logfile, argv[arg]);
                break;

            case 'L':
                stderr_log=1;
                break;

            case 's':
                syslog_log=1;
                break;

            case 'A':
                dont_zero_log = 1;
                break;
#if HAVE_UNISTD_H
            case 'u':
                if (++arg == argc) usage(argv[0]);
                uid = atoi(argv[arg]);
                break;
            case 'g':
                if (++arg == argc) usage(argv[0]);
                gid = atoi(argv[arg]);
                break;
#endif
            case 'h':
                usage(argv[0]);
                break;
            case 'H':
                init_agent("snmpd");   /* register our .conf handlers */
                init_mib_modules();
                init_snmp("snmpd");
                fprintf(stderr, "Configuration directives understood:\n");
                read_config_print_usage("  ");
                exit(0);
            case 'v':
                printf("\nUCD-snmp version:  %s\n",VersionInfo);
                printf("Author:            Wes Hardaker\n");
                printf("Email:             [email protected]\n\n");
                exit (0);
            case '-':
                switch(argv[arg][2]) {
                case 'v':
                    printf("\nUCD-snmp version:  %s\n",VersionInfo);
                    printf("Author:            Wes Hardaker\n");
                    printf("Email:             [email protected]\n\n");
                    exit (0);
                case 'h':
                    usage(argv[0]);
                    exit(0);
                }

            default:
                printf("invalid option: %s\n", argv[arg]);
                usage(argv[0]);
                break;
            }
            continue;
        }
    }  /* end-for */

    /*
     * Initialize a argv set to the current for restarting the agent.
     */
    argvrestartp = (char **) malloc((argc + 2) * sizeof(char *));
    argvptr = argvrestartp;
    for (i = 0, ret = 1; i < argc; i++) {
        ret += strlen(argv[i]) + 1;
    }
    argvrestart = (char *) malloc(ret);
    argvrestartname = (char *) malloc(strlen(argv[0]) + 1);
    strcpy(argvrestartname, argv[0]);
    if ( strstr(argvrestartname, "agentxd") != NULL)
        ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, SUB_AGENT);
    else
        ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, MASTER_AGENT);
    for (cptr = argvrestart, i = 0; i < argc; i++) {
        strcpy(cptr, argv[i]);
        *(argvptr++) = cptr;
        cptr += strlen(argv[i]) + 1;
    }
    *cptr = 0;
    *argvptr = NULL;


    /*
     * Open the logfile if necessary.
     */

    /* Should open logfile and/or syslog based on arguments */
    if (logfile[0])
        snmp_enable_filelog(logfile, dont_zero_log);
    if (syslog_log)
        snmp_enable_syslog();
#ifdef BUFSIZ
    setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
#endif
    /*
     * Initialize the world.  Detach from the shell.
     * Create initial user.
     */
#if HAVE_FORK
    if (!dont_fork && fork() != 0) {
        exit(0);
    }
#endif

#if HAVE_GETPID
    if (pid_file != NULL) {
        if ((PID = fopen(pid_file, "w")) == NULL) {
            snmp_log_perror("fopen");
            if (!ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS))
                exit(1);
        }
        else {
            fprintf(PID, "%d\n", (int)getpid());
            fclose(PID);
        }
    }
#endif

#else /* __ECOS environment: */
void snmpd( void *initfunc( void ) ) {
    int             ret;
    u_short         dest_port = SNMP_PORT;
#define stderr_log 1
#endif

    // ---------
    // En-bloc reinitialization of statics.
    running = 1;
    // ---------

    SOCK_STARTUP;
    init_agent("snmpd");		/* do what we need to do first. */
    init_mib_modules();


    /* start library */
    init_snmp("snmpd");

    ret = init_master_agent( dest_port,
                             snmp_check_packet,
                             snmp_check_parse );
    if( ret != 0 )
        Exit(1); /* Exit logs exit val for us */

#ifdef SIGTERM
    signal(SIGTERM, SnmpdShutDown);
#endif
#ifdef SIGINT
    signal(SIGINT, SnmpdShutDown);
#endif
#ifdef SIGHUP
    signal(SIGHUP, SnmpdReconfig);
#endif
#ifdef SIGUSR1
    signal(SIGUSR1, SnmpdDump);
#endif

    /* send coldstart trap via snmptrap(1) if possible */
    send_easy_trap (0, 0);

#if HAVE_UNISTD_H
    if (gid) {
        DEBUGMSGTL(("snmpd", "Changing gid to %d.\n", gid));
        if (setgid(gid)==-1) {
            snmp_log_perror("setgid failed");
            if (!ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS))
                exit(1);
        }
    }
    if (uid) {
        DEBUGMSGTL(("snmpd", "Changing uid to %d.\n", uid));
        if(setuid(uid)==-1) {
            snmp_log_perror("setuid failed");
            if (!ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS))
                exit(1);
        }
    }
#endif

    /* honor selection of standard error output */
    if (!stderr_log)
        snmp_disable_stderrlog();

    /* we're up, log our version number */
    snmp_log(LOG_INFO, "UCD-SNMP version %s\n", VersionInfo);

    memset(addrCache, 0, sizeof(addrCache));

    /*
     * Call initialization function if necessary
     */
    DEBUGMSGTL(("snmpd", "Calling initfunc().\n"));
    if ( initfunc )
        (initfunc)();

    /*
     * Forever monitor the dest_port for incoming PDUs.
     */
    DEBUGMSGTL(("snmpd", "We're up.  Starting to process data.\n"));
    receive();
#include "mib_module_shutdown.h"
    DEBUGMSGTL(("snmpd", "sending shutdown trap\n"));
    SnmpTrapNodeDown();
    DEBUGMSGTL(("snmpd", "Bye...\n"));
    snmp_shutdown("snmpd");

}  /* End main() -- snmpd */
Example #20
0
int
handle_var_list(struct agent_snmp_session  *asp)
{
    struct variable_list *varbind_ptr;
    u_char  statType;
    u_char *statP;
    size_t  statLen;
    u_short acl;
    WriteMethod *write_method;
    AddVarMethod *add_method;
    int	    noSuchObject = TRUE;
    int     count, view;
    
    count = 0;
    varbind_ptr = asp->start;
    if ( !varbind_ptr ) {
	return SNMP_ERR_NOERROR;
    }

    while (1) {
    
	count++;
statp_loop:
	statP = getStatPtr(  varbind_ptr->name,
			   &varbind_ptr->name_length,
			   &statType, &statLen, &acl,
			   asp->exact, &write_method, asp->pdu, &noSuchObject);
			   
	if (statP == NULL && (asp->rw != WRITE || write_method == NULL)) {
	        /*  Careful -- if the varbind was lengthy, it will have
		    allocated some memory.  */
	        snmp_set_var_value(varbind_ptr, NULL, 0);
	    	varbind_ptr->val.integer   = NULL;
	    	varbind_ptr->val_len = 0;
		if ( asp->exact ) {
	            if ( noSuchObject == TRUE ){
		        statType = SNMP_NOSUCHOBJECT;
		    } else {
		        statType = SNMP_NOSUCHINSTANCE;
		    }
		} else {
	            statType = SNMP_ENDOFMIBVIEW;
		}
		if (asp->pdu->version == SNMP_VERSION_1) {
		    asp->pdu->errstat = SNMP_ERR_NOSUCHNAME;
		    asp->pdu->errindex = count;
		    return SNMP_ERR_NOSUCHNAME;
		}
		else if (asp->rw == WRITE) {
		    asp->pdu->errstat =
			( noSuchObject	? SNMP_ERR_NOTWRITABLE
					: SNMP_ERR_NOCREATION );
		    asp->pdu->errindex = count;
		    return asp->pdu->errstat;
		}
		else
		    varbind_ptr->type = statType;
	}
                /* Delegated variables should be added to the
                   relevant outgoing request */
        else if ( IS_DELEGATED(statType)) {
                add_method = (AddVarMethod*)statP;
                statType = (*add_method)( asp, varbind_ptr );
        }
		/* GETNEXT/GETBULK should just skip inaccessible entries */
	else if ((view = in_a_view(varbind_ptr->name, &varbind_ptr->name_length,
				   asp->pdu, varbind_ptr->type))
			 && !asp->exact) {
		if (view != 5) send_easy_trap(SNMP_TRAP_AUTHFAIL, 0);
		goto statp_loop;
	}
		/* Other access problems are permanent */
	else if (( asp->rw == WRITE && !(acl & 2)) || view) {
	    if (asp->pdu->version == SNMP_VERSION_1 || asp->rw != WRITE) {
		if (ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE))
                  DEBUGMSGTL(("snmp_agent", "    >> noSuchName (read-only)\n"));
		ERROR_MSG("read-only");
		statType = SNMP_ERR_NOSUCHNAME;
	    }
	    else {
		if (ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE))
                  DEBUGMSGTL(("snmp_agent", "    >> notWritable\n"));
		ERROR_MSG("Not Writable");
		statType = SNMP_ERR_NOTWRITABLE;
	    }
	    asp->pdu->errstat = statType;
	    asp->pdu->errindex = count;
	    send_easy_trap(SNMP_TRAP_AUTHFAIL, 0);
	    return statType;
        }
	else {
            /* dump verbose info */
	    if (ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE) && statP)
	        dump_var(varbind_ptr->name, varbind_ptr->name_length,
				statType, statP, statLen);

		/*  FINALLY we can act on SET requests ....*/
	    if ( asp->rw == WRITE ) {
	        if ( write_method != NULL ) {
		    statType = (*write_method)(asp->mode,
                                               varbind_ptr->val.string,
                                               varbind_ptr->type,
                                               varbind_ptr->val_len, statP,
                                               varbind_ptr->name,
                                               varbind_ptr->name_length);
                    if (statType != SNMP_ERR_NOERROR) {
                      asp->pdu->errstat = statType;
                      asp->pdu->errindex = count;
                      return statType;
                    }
		}
		else {
                    if (!goodValue(varbind_ptr->type, varbind_ptr->val_len,
                                    statType, statLen)){
                        if (asp->pdu->version == SNMP_VERSION_1)
                            statType = SNMP_ERR_BADVALUE;
                        else
                            statType = SNMP_ERR_WRONGTYPE; /* poor approximation */
			asp->pdu->errstat = statType;
			asp->pdu->errindex = count;
			return statType;
                    }
                    /* actually do the set if necessary */
                    if (asp->mode == COMMIT)
                        setVariable(varbind_ptr->val.string, varbind_ptr->type,
                                    varbind_ptr->val_len, statP, statLen);
                }
	    }
		/* ... or save the results from assorted GETs */
	    else {
		     snmp_set_var_value(varbind_ptr, statP, statLen);
		     varbind_ptr->type = statType;
	    }
	}
	
	if ( varbind_ptr == asp->end )
	     return SNMP_ERR_NOERROR;
	varbind_ptr = varbind_ptr->next_variable;
	if ( asp->mode == RESERVE1 )
	    snmp_vars_inc++;
    }
}
Example #21
0
int
main(int argc, char *argv[])
{
    netsnmp_session session, *ss;
    netsnmp_pdu    *pdu;
    netsnmp_pdu    *response;
    netsnmp_variable_list *vars;
    int             arg;
    int             count;
    int             current_name = 0;
    char           *names[128];
    oid             name[MAX_OID_LEN];
    size_t          name_length;
    int             status;
    int             exitval = 0;

    /*
     * get the common command line arguments 
     */
    switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) {
    case -2:
        exit(0);
    case -1:
        usage();
        exit(1);
    default:
        break;
    }

    if (arg >= argc) {
        fprintf(stderr, "Missing object name\n");
        usage();
        exit(1);
    }

    /*
     * get the object names 
     */
    for (; arg < argc; arg++)
        names[current_name++] = argv[arg];

    SOCK_STARTUP;


    /*
     * Open an SNMP session.
     */
    ss = snmp_open(&session);
    if (ss == NULL) {
        /*
         * diagnose snmp_open errors with the input netsnmp_session pointer 
         */
        snmp_sess_perror("snmpget", &session);
        SOCK_CLEANUP;
        exit(1);
    }


    /*
     * Create PDU for GET request and add object names to request.
     */
    pdu = snmp_pdu_create(SNMP_MSG_GET);
    for (count = 0; count < current_name; count++) {
        name_length = MAX_OID_LEN;
        if (!snmp_parse_oid(names[count], name, &name_length)) {
            snmp_perror(names[count]);
            failures++;
        } else
            snmp_add_null_var(pdu, name, name_length);
    }
    if (failures) {
        SOCK_CLEANUP;
        exit(1);
    }


    /*
     * Perform the request.
     *
     * If the Get Request fails, note the OID that caused the error,
     * "fix" the PDU (removing the error-prone OID) and retry.
     */
  retry:
    status = snmp_synch_response(ss, pdu, &response);
    if (status == STAT_SUCCESS) {
	struct sockaddr_in  *in	= response->transport_data;
printf ("Peername = %s\n", ss->peername);
printf ("Response Address = %lx\n", in->sin_addr.S_un.S_addr);
        if (response->errstat == SNMP_ERR_NOERROR) {
            for (vars = response->variables; vars;
                 vars = vars->next_variable)
                print_variable(vars->name, vars->name_length, vars);

        } else {
            fprintf(stderr, "Error in packet\nReason: %s\n",
                    snmp_errstring(response->errstat));

            if (response->errindex != 0) {
                fprintf(stderr, "Failed object: ");
                for (count = 1, vars = response->variables;
                     vars && count != response->errindex;
                     vars = vars->next_variable, count++)
                    /*EMPTY*/;
                if (vars)
                    fprint_objid(stderr, vars->name, vars->name_length);
                fprintf(stderr, "\n");
            }
            exitval = 2;

            /*
             * retry if the errored variable was successfully removed 
             */
            if (!ds_get_boolean(DS_APPLICATION_ID, DS_APP_DONT_FIX_PDUS)) {
                pdu = snmp_fix_pdu(response, SNMP_MSG_GET);
                snmp_free_pdu(response);
                response = NULL;
                if (pdu != NULL)
                    goto retry;
            }
        }                       /* endif -- SNMP_ERR_NOERROR */

    } else if (status == STAT_TIMEOUT) {
        fprintf(stderr, "Timeout: No Response from %s.\n",
                session.peername);
        exitval = 1;

    } else {                    /* status == STAT_ERROR */
        snmp_sess_perror("snmpget", ss);
        exitval = 1;

    }                           /* endif -- STAT_SUCCESS */


    if (response)
        snmp_free_pdu(response);
    snmp_close(ss);
    SOCK_CLEANUP;
    return exitval;

}                               /* end main() */