Пример #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) {
			warn("Snmp dialog");
			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);
}
Пример #2
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);
}
Пример #3
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);
}