Blame apps/snmpstatus.c

Packit fcad23
/*
Packit fcad23
 * snmpstatus.c - retrieves a fixed set of management information from
Packit fcad23
 * a network entity.
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
#include <net-snmp/net-snmp-config.h>
Packit fcad23
Packit fcad23
#if HAVE_STDLIB_H
Packit fcad23
#include <stdlib.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_UNISTD_H
Packit fcad23
#include <unistd.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_STRING_H
Packit fcad23
#include <string.h>
Packit fcad23
#else
Packit fcad23
#include <strings.h>
Packit fcad23
#endif
Packit fcad23
#include <sys/types.h>
Packit fcad23
#if HAVE_NETINET_IN_H
Packit fcad23
#include <netinet/in.h>
Packit fcad23
#endif
Packit fcad23
#include <stdio.h>
Packit fcad23
#include <ctype.h>
Packit fcad23
#if TIME_WITH_SYS_TIME
Packit fcad23
# include <sys/time.h>
Packit fcad23
# include <time.h>
Packit fcad23
#else
Packit fcad23
# if HAVE_SYS_TIME_H
Packit fcad23
#  include <sys/time.h>
Packit fcad23
# else
Packit fcad23
#  include <time.h>
Packit fcad23
# endif
Packit fcad23
#endif
Packit fcad23
#if HAVE_SYS_SELECT_H
Packit fcad23
#include <sys/select.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_NETDB_H
Packit fcad23
#include <netdb.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_ARPA_INET_H
Packit fcad23
#include <arpa/inet.h>
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#include <net-snmp/utilities.h>
Packit fcad23
Packit fcad23
#include <net-snmp/net-snmp-includes.h>
Packit fcad23
Packit fcad23
oid             objid_sysDescr[] = { 1, 3, 6, 1, 2, 1, 1, 1, 0 };
Packit fcad23
size_t          length_sysDescr = sizeof(objid_sysDescr) / sizeof(oid);
Packit fcad23
oid             objid_sysUpTime[] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
Packit fcad23
size_t          length_sysUpTime = sizeof(objid_sysUpTime) / sizeof(oid);
Packit fcad23
oid             objid_ifOperStatus[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 8 };
Packit fcad23
size_t          length_ifOperStatus =
Packit fcad23
    sizeof(objid_ifOperStatus) / sizeof(oid);
Packit fcad23
oid             objid_ifInUCastPkts[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 11 };
Packit fcad23
size_t          length_ifInUCastPkts =
Packit fcad23
    sizeof(objid_ifInUCastPkts) / sizeof(oid);
Packit fcad23
oid             objid_ifInNUCastPkts[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 12 };
Packit fcad23
size_t          length_ifInNUCastPkts =
Packit fcad23
    sizeof(objid_ifInNUCastPkts) / sizeof(oid);
Packit fcad23
oid             objid_ifOutUCastPkts[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 17 };
Packit fcad23
size_t          length_ifOutUCastPkts =
Packit fcad23
    sizeof(objid_ifOutUCastPkts) / sizeof(oid);
Packit fcad23
oid             objid_ifOutNUCastPkts[] =
Packit fcad23
    { 1, 3, 6, 1, 2, 1, 2, 2, 1, 18 };
Packit fcad23
size_t          length_ifOutNUCastPkts =
Packit fcad23
    sizeof(objid_ifOutNUCastPkts) / sizeof(oid);
Packit fcad23
oid             objid_ipInReceives[] = { 1, 3, 6, 1, 2, 1, 4, 3, 0 };
Packit fcad23
size_t          length_ipInReceives =
Packit fcad23
    sizeof(objid_ipInReceives) / sizeof(oid);
Packit fcad23
oid             objid_ipOutRequests[] = { 1, 3, 6, 1, 2, 1, 4, 10, 0 };
Packit fcad23
size_t          length_ipOutRequests =
Packit fcad23
    sizeof(objid_ipOutRequests) / sizeof(oid);
Packit fcad23
Packit fcad23
#define NETSNMP_DS_APP_DONT_FIX_PDUS 0
Packit fcad23
Packit fcad23
static void
Packit fcad23
optProc(int argc, char *const *argv, int opt)
Packit fcad23
{
Packit fcad23
    switch (opt) {
Packit fcad23
    case 'C':
Packit fcad23
        while (*optarg) {
Packit fcad23
            switch (*optarg++) {
Packit fcad23
            case 'f':
Packit fcad23
                netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
					  NETSNMP_DS_APP_DONT_FIX_PDUS);
Packit fcad23
                break;
Packit fcad23
            default:
Packit fcad23
                fprintf(stderr, "Unknown flag passed to -C: %c\n",
Packit fcad23
                        optarg[-1]);
Packit fcad23
                exit(1);
Packit fcad23
            }
Packit fcad23
        }
Packit fcad23
        break;
Packit fcad23
    }
Packit fcad23
}
Packit fcad23
Packit fcad23
void
Packit fcad23
usage(void)
Packit fcad23
{
Packit fcad23
    fprintf(stderr, "USAGE: snmpstatus ");
Packit fcad23
    snmp_parse_args_usage(stderr);
Packit fcad23
    fprintf(stderr, "\n\n");
Packit fcad23
    snmp_parse_args_descriptions(stderr);
Packit fcad23
    fprintf(stderr,
Packit fcad23
            "  -C APPOPTS\t\tSet various application specific behaviours:\n");
Packit fcad23
    fprintf(stderr,
Packit fcad23
            "\t\t\t  f:  do not fix errors and retry the request\n");
Packit fcad23
}
Packit fcad23
Packit fcad23
Packit fcad23
int
Packit fcad23
main(int argc, char *argv[])
Packit fcad23
{
Packit fcad23
    netsnmp_session session, *ss;
Packit fcad23
    netsnmp_pdu    *pdu, *response;
Packit fcad23
    netsnmp_variable_list *vars;
Packit fcad23
    netsnmp_transport *transport = NULL;
Packit fcad23
    char           *sysdescr = NULL;
Packit fcad23
    u_long          uptime = 0;
Packit fcad23
    int             status;
Packit fcad23
    int             ipin = 0, ipout = 0, ipackets = 0, opackets = 0;
Packit fcad23
    int             good_var;
Packit fcad23
    int             down_interfaces = 0;
Packit fcad23
    char            buf[40];
Packit fcad23
    int             interfaces;
Packit fcad23
    int             count;
Packit fcad23
    int             exitval = 1;
Packit fcad23
Packit fcad23
    SOCK_STARTUP;
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * get the common command line arguments 
Packit fcad23
     */
Packit fcad23
    switch (snmp_parse_args(argc, argv, &session, "C:", &optProc)) {
Packit fcad23
    case NETSNMP_PARSE_ARGS_ERROR:
Packit fcad23
        goto out;
Packit fcad23
    case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
Packit fcad23
        exitval = 0;
Packit fcad23
        goto out;
Packit fcad23
    case NETSNMP_PARSE_ARGS_ERROR_USAGE:
Packit fcad23
        usage();
Packit fcad23
        goto out;
Packit fcad23
    default:
Packit fcad23
        break;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * open an SNMP session 
Packit fcad23
     */
Packit fcad23
    ss = snmp_open(&session);
Packit fcad23
    if (ss == NULL) {
Packit fcad23
        /*
Packit fcad23
         * diagnose snmp_open errors with the input netsnmp_session pointer 
Packit fcad23
         */
Packit fcad23
        snmp_sess_perror("snmpstatus", &session);
Packit fcad23
        goto out;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * create PDU for GET request and add object names to request 
Packit fcad23
     */
Packit fcad23
    pdu = snmp_pdu_create(SNMP_MSG_GET);
Packit fcad23
    snmp_add_null_var(pdu, objid_sysDescr, length_sysDescr);
Packit fcad23
    snmp_add_null_var(pdu, objid_sysUpTime, length_sysUpTime);
Packit fcad23
    snmp_add_null_var(pdu, objid_ipInReceives, length_ipInReceives);
Packit fcad23
    snmp_add_null_var(pdu, objid_ipOutRequests, length_ipOutRequests);
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * do the request 
Packit fcad23
     */
Packit fcad23
  retry:
Packit fcad23
    status = snmp_synch_response(ss, pdu, &response);
Packit fcad23
    if (status == STAT_SUCCESS) {
Packit fcad23
        if (response->errstat == SNMP_ERR_NOERROR) {
Packit fcad23
            for (vars = response->variables; vars;
Packit fcad23
                 vars = vars->next_variable) {
Packit fcad23
                if (vars->name_length == length_sysDescr
Packit fcad23
                    && !memcmp(objid_sysDescr, vars->name,
Packit fcad23
                               sizeof(objid_sysDescr))) {
Packit fcad23
                    sysdescr = (char *) malloc(vars->val_len + 1);
Packit fcad23
                    memcpy(sysdescr, vars->val.string, vars->val_len);
Packit fcad23
                    sysdescr[vars->val_len] = '\0';
Packit fcad23
                }
Packit fcad23
                if (vars->name_length == length_sysUpTime &&
Packit fcad23
                    !memcmp(objid_sysUpTime, vars->name,
Packit fcad23
                            sizeof(objid_sysUpTime)) &&
Packit fcad23
                    vars->val.integer) {
Packit fcad23
                    uptime = *vars->val.integer;
Packit fcad23
                }
Packit fcad23
                if (vars->name_length == length_ipInReceives &&
Packit fcad23
                    !memcmp(objid_ipInReceives, vars->name,
Packit fcad23
                            sizeof(objid_ipInReceives)) &&
Packit fcad23
                    vars->val.integer) {
Packit fcad23
                    ipin = *vars->val.integer;
Packit fcad23
                }
Packit fcad23
                if (vars->name_length == length_ipOutRequests &&
Packit fcad23
                    !memcmp(objid_ipOutRequests, vars->name,
Packit fcad23
                            sizeof(objid_ipOutRequests)) &&
Packit fcad23
                    vars->val.integer) {
Packit fcad23
                    ipout = *vars->val.integer;
Packit fcad23
                }
Packit fcad23
            }
Packit fcad23
        } else {
Packit fcad23
            fprintf(stderr, "Error in packet.\nReason: %s\n",
Packit fcad23
                    snmp_errstring(response->errstat));
Packit fcad23
            if (response->errindex != 0) {
Packit fcad23
                fprintf(stderr, "Failed object: ");
Packit fcad23
                for (count = 1, vars = response->variables;
Packit fcad23
                     vars && count != response->errindex;
Packit fcad23
                     vars = vars->next_variable, count++);
Packit fcad23
                if (vars)
Packit fcad23
                    fprint_objid(stderr, vars->name, vars->name_length);
Packit fcad23
                fprintf(stderr, "\n");
Packit fcad23
            }
Packit fcad23
Packit fcad23
            /*
Packit fcad23
             * retry if the errored variable was successfully removed 
Packit fcad23
             */
Packit fcad23
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
					NETSNMP_DS_APP_DONT_FIX_PDUS)) {
Packit fcad23
                pdu = snmp_fix_pdu(response, SNMP_MSG_GET);
Packit fcad23
                snmp_free_pdu(response);
Packit fcad23
                response = NULL;
Packit fcad23
                if (pdu != NULL)
Packit fcad23
                    goto retry;
Packit fcad23
            }
Packit fcad23
        }
Packit fcad23
    } else if (status == STAT_TIMEOUT) {
Packit fcad23
        fprintf(stderr, "Timeout: No Response from %s\n",
Packit fcad23
                session.peername);
Packit fcad23
        goto out;
Packit fcad23
    } else {                    /* status == STAT_ERROR */
Packit fcad23
        snmp_sess_perror("snmpstatus", ss);
Packit fcad23
        exitval = 2;
Packit fcad23
        goto out;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    exitval = 0;
Packit fcad23
Packit fcad23
    transport = snmp_sess_transport(snmp_sess_pointer(ss));
Packit fcad23
    if (transport != NULL && transport->f_fmtaddr != NULL) {
Packit fcad23
        char *addr_string = transport->f_fmtaddr(transport,
Packit fcad23
                                                 response->transport_data,
Packit fcad23
                                                 response->
Packit fcad23
                                                 transport_data_length);
Packit fcad23
        if (addr_string != NULL) {
Packit fcad23
            printf("[%s]=>[%s] Up: %s\n", addr_string, sysdescr,
Packit fcad23
                   uptime_string(uptime, buf));
Packit fcad23
            free(addr_string);
Packit fcad23
        }
Packit fcad23
    } else {
Packit fcad23
        printf("[<UNKNOWN>]=>[%s] Up: %s\n", sysdescr,
Packit fcad23
               uptime_string(uptime, buf));
Packit fcad23
    }
Packit fcad23
Packit fcad23
    if (response)
Packit fcad23
        snmp_free_pdu(response);
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * create PDU for GET request and add object names to request 
Packit fcad23
     */
Packit fcad23
    pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
Packit fcad23
    snmp_add_null_var(pdu, objid_ifOperStatus, length_ifOperStatus);
Packit fcad23
    snmp_add_null_var(pdu, objid_ifInUCastPkts, length_ifInUCastPkts);
Packit fcad23
    snmp_add_null_var(pdu, objid_ifInNUCastPkts, length_ifInNUCastPkts);
Packit fcad23
    snmp_add_null_var(pdu, objid_ifOutUCastPkts, length_ifOutUCastPkts);
Packit fcad23
    snmp_add_null_var(pdu, objid_ifOutNUCastPkts, length_ifOutNUCastPkts);
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * ?? note: this code is not quite complete 
Packit fcad23
     */
Packit fcad23
    good_var = 5;
Packit fcad23
    interfaces = 0;
Packit fcad23
    while (good_var == 5) {
Packit fcad23
        good_var = 0;
Packit fcad23
        status = snmp_synch_response(ss, pdu, &response);
Packit fcad23
        if (status == STAT_SUCCESS) {
Packit fcad23
            if (response->errstat == SNMP_ERR_NOERROR) {
Packit fcad23
                pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
Packit fcad23
                for (vars = response->variables; vars;
Packit fcad23
                     vars = vars->next_variable) {
Packit fcad23
                    if ((vars->type & 0xF0) == 0x80) {
Packit fcad23
			print_variable(vars->name, vars->name_length, vars);
Packit fcad23
                        continue;
Packit fcad23
                    }
Packit fcad23
                    if (vars->name_length >= length_ifOperStatus
Packit fcad23
                            && !memcmp(objid_ifOperStatus, vars->name,
Packit fcad23
                                    sizeof(objid_ifOperStatus))
Packit fcad23
                            && vars->type == ASN_INTEGER
Packit fcad23
                            && vars->val.integer) {
Packit fcad23
                        if (*vars->val.integer != MIB_IFSTATUS_UP)
Packit fcad23
                            down_interfaces++;
Packit fcad23
                        snmp_add_null_var(pdu, vars->name,
Packit fcad23
                                          vars->name_length);
Packit fcad23
                        good_var++;
Packit fcad23
                    } else if (vars->name_length >= length_ifInUCastPkts
Packit fcad23
                            &&!memcmp(objid_ifInUCastPkts, vars->name,
Packit fcad23
                                    sizeof(objid_ifInUCastPkts))
Packit fcad23
                            && vars->type == ASN_COUNTER
Packit fcad23
                            && vars->val.integer) {
Packit fcad23
                        ipackets += *vars->val.integer;
Packit fcad23
                        snmp_add_null_var(pdu, vars->name,
Packit fcad23
                                          vars->name_length);
Packit fcad23
                        good_var++;
Packit fcad23
                    } else if (vars->name_length >= length_ifInNUCastPkts
Packit fcad23
                               && !memcmp(objid_ifInNUCastPkts, vars->name,
Packit fcad23
                                          sizeof(objid_ifInNUCastPkts))
Packit fcad23
                               && vars->type == ASN_COUNTER
Packit fcad23
                               && vars->val.integer) {
Packit fcad23
                        ipackets += *vars->val.integer;
Packit fcad23
                        snmp_add_null_var(pdu, vars->name,
Packit fcad23
                                          vars->name_length);
Packit fcad23
                        good_var++;
Packit fcad23
                    } else if (vars->name_length >= length_ifOutUCastPkts
Packit fcad23
                               && !memcmp(objid_ifOutUCastPkts, vars->name,
Packit fcad23
                                          sizeof(objid_ifOutUCastPkts))
Packit fcad23
                               && vars->type == ASN_COUNTER
Packit fcad23
                               && vars->val.integer) {
Packit fcad23
                        opackets += *vars->val.integer;
Packit fcad23
                        snmp_add_null_var(pdu, vars->name,
Packit fcad23
                                          vars->name_length);
Packit fcad23
                        good_var++;
Packit fcad23
                    } else if (vars->name_length >= length_ifOutNUCastPkts
Packit fcad23
                               && !memcmp(objid_ifOutNUCastPkts,
Packit fcad23
                                          vars->name,
Packit fcad23
                                          sizeof(objid_ifOutNUCastPkts))
Packit fcad23
                               && vars->type == ASN_COUNTER
Packit fcad23
                               && vars->val.integer) {
Packit fcad23
                        opackets += *vars->val.integer;
Packit fcad23
                        snmp_add_null_var(pdu, vars->name,
Packit fcad23
                                          vars->name_length);
Packit fcad23
                        good_var++;
Packit fcad23
                    }
Packit fcad23
                }
Packit fcad23
                if (good_var == 5)
Packit fcad23
                    interfaces++;
Packit fcad23
            } else {
Packit fcad23
                fprintf(stderr, "Error in packet.\nReason: %s\n",
Packit fcad23
                        snmp_errstring(response->errstat));
Packit fcad23
                if (response->errindex != 0) {
Packit fcad23
                    fprintf(stderr, "Failed object: ");
Packit fcad23
                    for (count = 1, vars = response->variables;
Packit fcad23
                         vars && count != response->errindex;
Packit fcad23
                         vars = vars->next_variable, count++);
Packit fcad23
                    if (vars)
Packit fcad23
                        fprint_objid(stderr, vars->name,
Packit fcad23
                                     vars->name_length);
Packit fcad23
                    fprintf(stderr, "\n");
Packit fcad23
                }
Packit fcad23
                exitval = 2;
Packit fcad23
            }
Packit fcad23
        } else if (status == STAT_TIMEOUT) {
Packit fcad23
            fprintf(stderr, "Timeout: No Response from %s\n",
Packit fcad23
                    session.peername);
Packit fcad23
            exitval = 1;
Packit fcad23
        } else {                /* status == STAT_ERROR */
Packit fcad23
            snmp_sess_perror("snmpstatus", ss);
Packit fcad23
            exitval = 1;
Packit fcad23
        }
Packit fcad23
Packit fcad23
        if (response)
Packit fcad23
            snmp_free_pdu(response);
Packit fcad23
    }
Packit fcad23
    printf("Interfaces: %d, Recv/Trans packets: %d/%d | IP: %d/%d\n",
Packit fcad23
           interfaces, ipackets, opackets, ipin, ipout);
Packit fcad23
    if (down_interfaces > 0) {
Packit fcad23
        printf("%d interface%s down!\n",
Packit fcad23
               down_interfaces, down_interfaces > 1 ? "s are" : " is");
Packit fcad23
    }
Packit fcad23
Packit fcad23
    snmp_close(ss);
Packit fcad23
Packit fcad23
out:
Packit fcad23
    SOCK_CLEANUP;
Packit fcad23
    return exitval;
Packit fcad23
}