Ejemplo n.º 1
0
static int
snmptool_get(struct snmp_toolinfo *snmptoolctx)
{
	struct snmp_pdu req, resp;

	snmp_pdu_create(&req, GET_PDUTYPE(snmptoolctx));

	while ((snmp_pdu_add_bindings(snmptoolctx, snmpget_verify_vbind,
	     snmptool_add_vbind, &req, SNMP_MAX_BINDINGS)) > 0) {

		if (GET_PDUTYPE(snmptoolctx) == SNMP_PDU_GETBULK)
			snmpget_fix_getbulk(&req, GET_MAXREP(snmptoolctx),
			    GET_NONREP(snmptoolctx));

		if (snmp_dialog(&req, &resp) == -1) {
			warnx("Snmp dialog - %s", strerror(errno));
			break;
		}

		if (snmp_parse_resp(&resp, &req) >= 0) {
			snmp_output_resp(snmptoolctx, &resp, NULL);
			break;
		}

		snmp_output_err_resp(snmptoolctx, &resp);
		if (GET_PDUTYPE(snmptoolctx) == SNMP_PDU_GETBULK ||
		    !ISSET_RETRY(snmptoolctx))
			break;

		/*
		 * Loop through the object list and set object->error to the
		 * varbinding that caused the error.
		 */
		if (snmp_object_seterror(snmptoolctx,
		    &(resp.bindings[resp.error_index - 1]),
		    resp.error_status) <= 0)
			break;

		fprintf(stderr, "Retrying...\n");
		snmp_pdu_free(&resp);
		snmp_pdu_create(&req, GET_PDUTYPE(snmptoolctx));
	}

	snmp_pdu_free(&resp);

	return (0);
}
Ejemplo n.º 2
0
void dump_pdu(snmp_pdu_t* pdu, enum snmp_version version, u_int type) {
	
    char hextable[] = "0123456789abcdef";

	char buf[10000];
	int i;
	asn_buf_t buffer;
	pdu->version = version;
	pdu->pdu_type = type;
	pdu->request_id = 234;

	append_bindings(pdu, oid1, sizeof(oid1)/sizeof(asn_subid_t), SNMP_SYNTAX_NULL);
	append_bindings(pdu, oid1, sizeof(oid1)/sizeof(asn_subid_t), SNMP_SYNTAX_INTEGER);
	pdu->bindings[pdu->nbindings-1].v.integer = 12;

	append_bindings(pdu, oid1, sizeof(oid1)/sizeof(asn_subid_t), SNMP_SYNTAX_OCTETSTRING);
	pdu->bindings[pdu->nbindings-1].v.octetstring.octets = strdup("1234567890");
	pdu->bindings[pdu->nbindings-1].v.octetstring.len = strlen("1234567890");

	append_bindings(pdu, oid1, sizeof(oid1)/sizeof(asn_subid_t), SNMP_SYNTAX_OID);
	memcpy(pdu->bindings[pdu->nbindings-1].v.oid.subs, oid2, sizeof(oid2));
	pdu->bindings[pdu->nbindings-1].v.oid.len = sizeof(oid2)/sizeof(asn_subid_t);
	
	append_bindings(pdu, oid1, sizeof(oid1)/sizeof(asn_subid_t), SNMP_SYNTAX_IPADDRESS);
	memcpy(pdu->bindings[pdu->nbindings-1].v.ipaddress, "\1\2\3\4", 4);
	append_bindings(pdu, oid1, sizeof(oid1)/sizeof(asn_subid_t), SNMP_SYNTAX_COUNTER);
	pdu->bindings[pdu->nbindings-1].v.uint32 = 2235683;
	append_bindings(pdu, oid1, sizeof(oid1)/sizeof(asn_subid_t), SNMP_SYNTAX_GAUGE);
	pdu->bindings[pdu->nbindings-1].v.uint32 = 1235683;
	append_bindings(pdu, oid1, sizeof(oid1)/sizeof(asn_subid_t), SNMP_SYNTAX_TIMETICKS);
	pdu->bindings[pdu->nbindings-1].v.uint32 = 1235683;
	append_bindings(pdu, oid1, sizeof(oid1)/sizeof(asn_subid_t), SNMP_SYNTAX_COUNTER64);
	pdu->bindings[pdu->nbindings-1].v.counter64 = 12352121212122683;

	snmp_printf("\r\n------------------\r\n");
	snmp_pdu_dump(pdu);
	snmp_printf("\r\n------------------\r\n");
	buffer.asn_len = sizeof(buf);
	buffer.asn_ptr = (u_char*) buf;
	snmp_pdu_encode(pdu, &buffer);

    for(i = 0;i < (buffer.asn_ptr - (u_char*)buf); ++i) {
		char v1 = (buf[i]>>4)&0x0f;
		char v2 = buf[i]&0x0f;
		snmp_printf("%c", hextable[v1]);
		snmp_printf("%c", hextable[v2]);
    }

	snmp_printf("\r\n\r\n");


	
	snmp_pdu_free(pdu);
}
Ejemplo n.º 3
0
/* static */ SNMP_pdu *request_create(char *community, int type, char *error_label)
{
	SNMP_pdu *request;


	error_label[0] = '\0';

	switch(type)
	{
		case GET_REQ_MSG:
		case GETNEXT_REQ_MSG:
		case SET_REQ_MSG:
			break;

		default:
			sprintf(error_label, "BUG: request_create(): bad type (0x%x)",
				type);
			return NULL;
	}

	request = snmp_pdu_new(error_label);
	if(request == NULL)
	{
		return NULL;
	}

	request->version = SNMP_VERSION_1;
	request->community = strdup(community);
	if(request->community == NULL)
	{
		sprintf(error_label, ERR_MSG_ALLOC);
		snmp_pdu_free(request);
		return NULL;
	}
	request->type = type;
	request->request_id = request_id++;


	return request;
}
Ejemplo n.º 4
0
void dump_snmpv3_user(snmp_pdu_t* pdu, u_int type, snmp_user_t* user) {
	snmp_pdu_init(pdu);
	strcpy(pdu->context_name, "testcontextname");
	strcpy((char*)pdu->context_engine, "testcontextengine");
	pdu->context_engine_len = strlen("testcontextengine");
	
	memcpy(pdu->engine.engine_id, "01234567890123456789012345678901234567890123456789",
		SNMP_ENGINE_ID_SIZ);
	pdu->engine.engine_len = SNMP_ENGINE_ID_SIZ;
	pdu->engine.engine_boots = 3;
	pdu->engine.engine_time = 1234;
	pdu->engine.max_msg_size = 10007;

	pdu->security_model = SNMP_SECMODEL_USM;
	
	snmp_auth_to_localization_keys(user, pdu->engine.engine_id, pdu->engine.engine_len);
	snmp_priv_to_localization_keys(user, pdu->engine.engine_id, pdu->engine.engine_len);
	memcpy(&pdu->user, user, sizeof(*user));
	snmp_pdu_init_secparams(pdu);

	dump_pdu(pdu, SNMP_V3, type);
	snmp_pdu_free(pdu);
}
Ejemplo n.º 5
0
void dump_snmpv1orv2(snmp_pdu_t* pdu, enum snmp_version version, u_int type) {
	snmp_pdu_init(pdu);
	strcpy(pdu->community, "123987");
	dump_pdu(pdu, version, type);
	snmp_pdu_free(pdu);
}
Ejemplo n.º 6
0
int request_snmpEnableAuthTraps(char *error_label)
{
	static int my_ip_address_initialized = False;
	static IPAddress my_ip_address;
	SNMP_pdu *request;
	SNMP_pdu *response;
	SNMP_variable *variable;
	int snmpEnableAuthTraps;
	struct timeval timeout;

	timeout.tv_sec = 5;
	timeout.tv_usec = 0;


	error_label[0] = '\0';

	if(my_ip_address_initialized == False)
	{
		if(get_my_ip_address(&my_ip_address, error_label))
		{
			return -1;
		}

		my_ip_address_initialized = True;
	}

	request = request_create("public", GET_REQ_MSG, error_label);
	if(request == NULL)
	{
		return -1;
	}

	if(snmp_pdu_append_null_variable(request, &snmpEnableAuthTraps_name, error_label) == NULL)
	{
		snmp_pdu_free(request);
		return -1;
	}

	response = request_send_to_port_time_out_blocking(&my_ip_address, \
		SNMP_PORT, &timeout, request, error_label);
	if(response == NULL)
	{
		snmp_pdu_free(request);
		return -1;
	}
	snmp_pdu_free(request);

	if(response->error_status)
	{
		sprintf(error_label, "%s",
			error_status_string(response->error_status));
		snmp_pdu_free(response);
		return -1;
	}

	variable = response->first_variable;
	if(variable->next_variable
		|| SSAOidCmp(&(variable->name), &snmpEnableAuthTraps_name)
		|| (variable->type != INTEGER)
		|| (variable->val.integer == NULL)
		|| (variable->val_len != sizeof(int32_t)) )
	{
		sprintf(error_label, ERR_MSG_BAD_RESPONSE);
		snmp_pdu_free(response);
		return -1;
	}
	snmpEnableAuthTraps = *(variable->val.integer);
	snmp_pdu_free(response);

	if(trace_level > 0)
	{
		trace("snmpAuthTraps: %s\n\n",
			(snmpEnableAuthTraps == 1)? "enabled(1)": "disabled(2)");
	}

	switch(snmpEnableAuthTraps)
	{
		case 1: /* enabled(1) */
			return TRUE;
		case 2: /* disable(2) */
			return FALSE;
		default:
			sprintf(error_label, ERR_MSG_BAD_VALUE);
			return -1;
	}
}
Ejemplo n.º 7
0
int32_t request_sysUpTime(char *error_label, char *community_name)
{
	static int my_ip_address_initialized = False;
	static IPAddress my_ip_address;
	SNMP_pdu *request;
	SNMP_pdu *response;
	SNMP_variable *variable;
	static int32_t sysUpTime = 0;
	static clock_t last = 0;
	clock_t now;
	struct tms buffer;


	error_label[0] = '\0';

	now = times(&buffer);
	if( (last == 0) || ((now - last) > 360000) )	/* 1 hour */
	{
		if(my_ip_address_initialized == False)
		{
			if(get_my_ip_address(&my_ip_address, error_label))
			{
				return 0;
			}

			my_ip_address_initialized = True;
		}

		if(community_name == NULL)
			request = request_create("public", GET_REQ_MSG, error_label);
		else
			request = request_create(community_name, GET_REQ_MSG, error_label);

		if(request == NULL)
		{
			return 0;
		}

		if(snmp_pdu_append_null_variable(request, &sysUptime_instance, error_label) == NULL)
		{
			snmp_pdu_free(request);
			return 0;
		}

		response = request_send_blocking(&my_ip_address, request, error_label);
		if(response == NULL)
		{
			snmp_pdu_free(request);
			return 0;
		}
		snmp_pdu_free(request);

		if(response->error_status)
		{
			sprintf(error_label, "%s",
				error_status_string(response->error_status));
			snmp_pdu_free(response);
			return 0;
		}

		variable = response->first_variable;
		if(variable->next_variable
			|| SSAOidCmp(&(variable->name), &sysUptime_instance)
			|| (variable->type != TIMETICKS)
			|| (variable->val.integer == NULL)
			|| (variable->val_len != sizeof(int32_t)) )
		{
			sprintf(error_label, ERR_MSG_BAD_RESPONSE);
			snmp_pdu_free(response);
			return 0;
		}
		sysUpTime = *(variable->val.integer);
		last = now;
		snmp_pdu_free(response);

		if(trace_level > 0)
		{
			trace("sysUpTime: %d\n\n", sysUpTime);
		}

		return sysUpTime;
	}

	/* LINTED */
	return (sysUpTime + (int32_t)(now - last));
}
Ejemplo n.º 8
0
/*
 * Fetch a table. Returns 0 if ok, -1 on errors.
 * This is the synchronous variant.
 */
int
snmp_table_fetch(const struct snmp_table *descr, void *list)
{
	struct snmp_pdu resp;
	struct tabwork work;
	int ret;

	work.descr = descr;
	work.table = (struct table *)list;
	work.iter = 0;
	TAILQ_INIT(work.table);
	TAILQ_INIT(&work.worklist);
	work.callback = NULL;
	work.arg = NULL;

  again:
	/*
	 * We come to this label when the code detects that the table
	 * has changed while fetching it.
	 */
	work.first = 1;
	work.last_change = 0;
	table_init_pdu(descr, &work.pdu);

	for (;;) {
		if (snmp_dialog(&work.pdu, &resp)) {
			table_free(&work, 1);
			return (-1);
		}
		if ((ret = table_check_response(&work, &resp)) == 0) {
			snmp_pdu_free(&resp);
			break;
		}
		if (ret == -1) {
			snmp_pdu_free(&resp);
			table_free(&work, 1);
			return (-1);
		}
		if (ret == -2) {
			snmp_pdu_free(&resp);
			goto again;
		}

		work.pdu.bindings[work.pdu.nbindings - 1].var =
		    resp.bindings[resp.nbindings - 1].var;

		snmp_pdu_free(&resp);
	}

	if ((ret = table_check_cons(&work)) == -1) {
		table_free(&work, 1);
		return (-1);
	}
	if (ret == -2) {
		table_free(&work, 1);
		goto again;
	}
	/*
	 * Free index list
	 */
	table_free(&work, 0);
	return (0);
}
Ejemplo n.º 9
0
/*
 * Do a 'snmp walk' - according to command line options request for values lexicographically
 * subsequent and subrooted at a common node. Send a GetNext PDU requesting the value for each
 * next variable and print the responce. Stop when a Responce PDU is received that contains
 * the value of a variable not subrooted at the variable the walk started.
 */
int
main(int argc, char ** argv)
{
    struct snmp_toolinfo *tool;
    struct snmp_client *client_context;
    struct asn_oid root; /* keep the inital oid */
    struct snmp_pdu pdu_to_send, pdu_to_recv;
    int oid, opt_num, outputs;

    tool = snmptool_init(helptxt);
    client_context = tool->client;

    if ((opt_num = snmpwalk_parse_options(tool, argc, argv)) < 0) {
        snmp_tool_freeall(tool);
        exit(0);
    }

    if (snmp_import_all(tool) < 0) {
        snmp_tool_freeall(tool);
        exit(0);
    }

    oid = argc - opt_num - 1;

    switch (oid) {
    case 0:
        if (snmp_object_add(tool, snmpwalk_add_default, NULL) < 0) {
            snmp_tool_freeall(tool);
            errx(1, "Error setting default tree OID to walk");
        }
        break;
    case 1:
        /* last command line argument will always be the OID to start the walk from */
        if ((snmp_object_add(tool, snmpwalk_parse_oid, argv[argc - 1])) < 0) {
            snmp_tool_freeall(tool);
            exit(1);
        }
        break;
    default:
        snmp_tool_freeall(tool);
        errx(1, "Only one OID allowed");
    }

    snmp_pdu_create(client_context, &pdu_to_send, SNMP_PDU_GETNEXT);

    if (snmp_pdu_add_bindings(tool, (snmp_verify_vbind_f) NULL,
                              snmpwalk_add_vbind, &pdu_to_send) < 0) {
        snmp_tool_freeall(tool);
        exit(1);
    }

    if (snmp_open(client_context, NULL, NULL, NULL, NULL)) {
        snmp_tool_freeall(tool);
        err(1, "Failed to open snmp session");
    }

    /* remember the root where the walk started from */
    memset(&root, 0 ,sizeof(struct asn_oid));
    asn_append_oid(&root, &(pdu_to_send.bindings[0].var));

    outputs = 0;
    while (snmp_dialog(client_context, &pdu_to_send, &pdu_to_recv) >= 0) {

        if ((snmp_parse_resp(client_context, &pdu_to_recv, &pdu_to_send)) < 0) {
            snmp_output_err_resp(tool, &pdu_to_recv);
            snmp_pdu_free(&pdu_to_recv);
            outputs = -1;
            break;
        }

        if (!(asn_is_suboid(&root, &(pdu_to_recv.bindings[0].var)))) {
            snmp_pdu_free(&pdu_to_recv);
            break;
        }
        snmp_output_resp(tool, &pdu_to_recv);
        outputs++;
        snmp_pdu_free(&pdu_to_recv);

        snmpwalk_nextpdu_create(client_context, SNMP_PDU_GETNEXT,
                                &(pdu_to_recv.bindings[0].var), &pdu_to_send);
    }

    /* Just a case our root was a leaf */
    if (outputs == 0) {

        snmpwalk_nextpdu_create(client_context, SNMP_PDU_GET, &root, &pdu_to_send);

        if (snmp_dialog(client_context, &pdu_to_send, &pdu_to_recv) == SNMP_CODE_OK /* 0 */) {

            if(snmp_parse_resp(client_context, &pdu_to_recv,&pdu_to_send)  < 0)
                snmp_output_err_resp(tool, &pdu_to_recv);
            else
                snmp_output_resp(tool, &(pdu_to_recv));

            snmp_pdu_free(&pdu_to_recv);
        } else
            err(1, "Snmp dialog");
    }

    snmp_tool_freeall(tool);

    exit(0);
}
Ejemplo n.º 10
0
struct snmp_pdu *snmp_fix_pdu(struct snmp_pdu *pdu, int command)
{
  struct variable_list *var, *newvar;
  struct snmp_pdu *newpdu;
  int index;
  int copied = 0;

#ifdef DEBUG_PDU
  printf("PDU %x:  Fixing.  Err index is %d\n", 
	 (unsigned int)pdu, (unsigned int)pdu->errindex);
#endif

  if (pdu->command != SNMP_PDU_RESPONSE || 
      pdu->errstat == SNMP_ERR_NOERROR || 
      pdu->errindex <= 0) {
    snmp_set_api_error(SNMPERR_UNABLE_TO_FIX);
    return(NULL);
  }

  /* clone the pdu */
  newpdu            = snmp_pdu_clone(pdu);
  if (newpdu == NULL)
    return(NULL);

  newpdu->variables = 0;
  newpdu->command   = command;
  newpdu->reqid     = SNMP_DEFAULT_REQID;
  newpdu->errstat   = SNMP_ERR_NOERROR;
  newpdu->errindex  = 0; /* XXXXX Is this right? */

  /* Loop through the variables, removing whatever isn't necessary */

  var   = pdu->variables;
  index = 1;

  /* skip first variable if necessary*/
  if (pdu->errindex == index) {
    var = var->next_variable;
    index++;
  }

  if (var != NULL) {

    /* VAR is the first uncopied variable */

    /* Clone this variable */
    newpdu->variables = snmp_var_clone(var);
    if (newpdu->variables == NULL) {
      snmp_pdu_free(newpdu);
      return(NULL);
    }
    copied++;

    newvar = newpdu->variables;

    /* VAR has been copied to NEWVAR. */
    while(var->next_variable) {

      /* Skip the item that was bad */
      if (++index == pdu->errindex) {
	var = var->next_variable;
	continue;
      }

      /* Copy this var */
      newvar->next_variable = snmp_var_clone(var->next_variable);
      if (newvar->next_variable == NULL) {
	snmp_pdu_free(newpdu);
	return(NULL);
      }

      /* Move to the next one */
      newvar = newvar->next_variable;
      var = var->next_variable;
      copied++;
    }
    newvar->next_variable = NULL;
  }

  /* If we didn't copy anything, free the new pdu. */
  if (index < pdu->errindex || copied == 0) {
    snmp_free_pdu(newpdu);
    snmp_set_api_error(SNMPERR_UNABLE_TO_FIX);
    return(NULL);
  }

#ifdef DEBUG_PDU
  printf("PDU %x:  Fixed PDU is %x\n", 
	 (unsigned int)pdu, (unsigned int)newpdu);
#endif
  return(newpdu);
}