/*
 * snmpstatus.c - send snmp GET requests to a network entity.
 *
 */
/***********************************************************************
	Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University

                      All Rights Reserved

Permission to use, copy, modify, and distribute this software and its 
documentation for any purpose and without fee is hereby granted, 
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in 
supporting documentation, and that the name of CMU not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.  

CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
******************************************************************/
#include <net-snmp/net-snmp-config.h>

#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#include <sys/types.h>
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#include <stdio.h>
#include <ctype.h>
#if TIME_WITH_SYS_TIME
# ifdef WIN32
#  include <sys/timeb.h>
# else
#  include <sys/time.h>
# endif
# include <time.h>
#else
# if HAVE_SYS_TIME_H
#  include <sys/time.h>
# else
#  include <time.h>
# endif
#endif
#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#if HAVE_WINSOCK_H
#include <winsock.h>
#endif
#if HAVE_NETDB_H
#include <netdb.h>
#endif
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif

#include <net-snmp/utilities.h>

#include <net-snmp/net-snmp-includes.h>

oid             objid_sysDescr[] = { 1, 3, 6, 1, 2, 1, 1, 1, 0 };
size_t          length_sysDescr = sizeof(objid_sysDescr) / sizeof(oid);
oid             objid_sysUpTime[] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
size_t          length_sysUpTime = sizeof(objid_sysUpTime) / sizeof(oid);
oid             objid_ifOperStatus[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 8 };
size_t          length_ifOperStatus =
    sizeof(objid_ifOperStatus) / sizeof(oid);
oid             objid_ifInUCastPkts[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 11 };
size_t          length_ifInUCastPkts =
    sizeof(objid_ifInUCastPkts) / sizeof(oid);
oid             objid_ifInNUCastPkts[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 12 };
size_t          length_ifInNUCastPkts =
    sizeof(objid_ifInNUCastPkts) / sizeof(oid);
oid             objid_ifOutUCastPkts[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 17 };
size_t          length_ifOutUCastPkts =
    sizeof(objid_ifOutUCastPkts) / sizeof(oid);
oid             objid_ifOutNUCastPkts[] =
    { 1, 3, 6, 1, 2, 1, 2, 2, 1, 18 };
size_t          length_ifOutNUCastPkts =
    sizeof(objid_ifOutNUCastPkts) / sizeof(oid);
oid             objid_ipInReceives[] = { 1, 3, 6, 1, 2, 1, 4, 3, 0 };
size_t          length_ipInReceives =
    sizeof(objid_ipInReceives) / sizeof(oid);
oid             objid_ipOutRequests[] = { 1, 3, 6, 1, 2, 1, 4, 10, 0 };
size_t          length_ipOutRequests =
    sizeof(objid_ipOutRequests) / sizeof(oid);

#define NETSNMP_DS_APP_DONT_FIX_PDUS 0

static void
optProc(int argc, char *const *argv, int opt)
{
    switch (opt) {
    case 'C':
        while (*optarg) {
            switch (*optarg++) {
            case 'f':
                netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
					  NETSNMP_DS_APP_DONT_FIX_PDUS);
                break;
            default:
                fprintf(stderr, "Unknown flag passed to -C: %c\n",
                        optarg[-1]);
                exit(1);
            }
        }
        break;
    }
}

void
usage(void)
{
    fprintf(stderr, "USAGE: snmpstatus ");
    snmp_parse_args_usage(stderr);
    fprintf(stderr, "\n\n");
    snmp_parse_args_descriptions(stderr);
    fprintf(stderr,
            "  -C APPOPTS\t\tSet various application specific behaviours:\n");
    fprintf(stderr,
            "\t\t\t  f:  do not fix errors and retry the request\n");
}


int
main(int argc, char *argv[])
{
    netsnmp_session session, *ss;
    netsnmp_pdu    *pdu, *response;
    netsnmp_variable_list *vars;
    netsnmp_transport *transport = NULL;
    char           *sysdescr = NULL;
    u_long          uptime = 0;
    int             status;
    int             ipin = 0, ipout = 0, ipackets = 0, opackets = 0;
    int             good_var;
    int             down_interfaces = 0;
    char            buf[40];
    int             interfaces;
    int             count;
    int             exitval = 0;

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

    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("snmpstatus", &session);
        SOCK_CLEANUP;
        exit(1);
    }

    /*
     * create PDU for GET request and add object names to request 
     */
    pdu = snmp_pdu_create(SNMP_MSG_GET);
    snmp_add_null_var(pdu, objid_sysDescr, length_sysDescr);
    snmp_add_null_var(pdu, objid_sysUpTime, length_sysUpTime);
    snmp_add_null_var(pdu, objid_ipInReceives, length_ipInReceives);
    snmp_add_null_var(pdu, objid_ipOutRequests, length_ipOutRequests);

    /*
     * do the request 
     */
  retry:
    status = snmp_synch_response(ss, pdu, &response);
    if (status == STAT_SUCCESS) {
        if (response->errstat == SNMP_ERR_NOERROR) {
            for (vars = response->variables; vars;
                 vars = vars->next_variable) {
                if (vars->name_length == length_sysDescr
                    && !memcmp(objid_sysDescr, vars->name,
                               sizeof(objid_sysDescr))) {
                    sysdescr = (char *) malloc(vars->val_len + 1);
                    memcpy(sysdescr, vars->val.string, vars->val_len);
                    sysdescr[vars->val_len] = '\0';
                }
                if (vars->name_length == length_sysUpTime &&
                    !memcmp(objid_sysUpTime, vars->name,
                            sizeof(objid_sysUpTime)) &&
                    vars->val.integer) {
                    uptime = *vars->val.integer;
                }
                if (vars->name_length == length_ipInReceives &&
                    !memcmp(objid_ipInReceives, vars->name,
                            sizeof(objid_ipInReceives)) &&
                    vars->val.integer) {
                    ipin = *vars->val.integer;
                }
                if (vars->name_length == length_ipOutRequests &&
                    !memcmp(objid_ipOutRequests, vars->name,
                            sizeof(objid_ipOutRequests)) &&
                    vars->val.integer) {
                    ipout = *vars->val.integer;
                }
            }
        } 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++);
                if (vars)
                    fprint_objid(stderr, vars->name, vars->name_length);
                fprintf(stderr, "\n");
            }

            /*
             * retry if the errored variable was successfully removed 
             */
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
					NETSNMP_DS_APP_DONT_FIX_PDUS)) {
                pdu = snmp_fix_pdu(response, SNMP_MSG_GET);
                snmp_free_pdu(response);
                response = NULL;
                if (pdu != NULL)
                    goto retry;
            }
        }
    } else if (status == STAT_TIMEOUT) {
        fprintf(stderr, "Timeout: No Response from %s\n",
                session.peername);
        SOCK_CLEANUP;
        exit(1);
    } else {                    /* status == STAT_ERROR */
        snmp_sess_perror("snmpstatus", ss);
        SOCK_CLEANUP;
        exit(2);
    }

    transport = snmp_sess_transport(snmp_sess_pointer(ss));
    if (transport != NULL && transport->f_fmtaddr != NULL) {
        char *addr_string = transport->f_fmtaddr(transport,
                                                 response->transport_data,
                                                 response->
                                                 transport_data_length);
        if (addr_string != NULL) {
            printf("[%s]=>[%s] Up: %s\n", addr_string, sysdescr,
                   uptime_string(uptime, buf));
            free(addr_string);
        }
    } else {
        printf("[<UNKNOWN>]=>[%s] Up: %s\n", sysdescr,
               uptime_string(uptime, buf));
    }

    if (response)
        snmp_free_pdu(response);

    /*
     * create PDU for GET request and add object names to request 
     */
    pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
    snmp_add_null_var(pdu, objid_ifOperStatus, length_ifOperStatus);
    snmp_add_null_var(pdu, objid_ifInUCastPkts, length_ifInUCastPkts);
    snmp_add_null_var(pdu, objid_ifInNUCastPkts, length_ifInNUCastPkts);
    snmp_add_null_var(pdu, objid_ifOutUCastPkts, length_ifOutUCastPkts);
    snmp_add_null_var(pdu, objid_ifOutNUCastPkts, length_ifOutNUCastPkts);

    /*
     * ?? note: this code is not quite complete 
     */
    good_var = 5;
    interfaces = 0;
    while (good_var == 5) {
        good_var = 0;
        status = snmp_synch_response(ss, pdu, &response);
        if (status == STAT_SUCCESS) {
            if (response->errstat == SNMP_ERR_NOERROR) {
                pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
                for (vars = response->variables; vars;
                     vars = vars->next_variable) {
                    if ((vars->type & 0xF0) == 0x80) {
			print_variable(vars->name, vars->name_length, vars);
                        continue;
                    }
                    if (vars->name_length >= length_ifOperStatus
                        && !memcmp(objid_ifOperStatus, vars->name,
                                   sizeof(objid_ifOperStatus))) {
                        if (*vars->val.integer != MIB_IFSTATUS_UP)
                            down_interfaces++;
                        snmp_add_null_var(pdu, vars->name,
                                          vars->name_length);
                        good_var++;
                    } else if (vars->name_length >= length_ifInUCastPkts &&
                               !memcmp(objid_ifInUCastPkts, vars->name,
                                       sizeof(objid_ifInUCastPkts))) {
                        ipackets += *vars->val.integer;
                        snmp_add_null_var(pdu, vars->name,
                                          vars->name_length);
                        good_var++;
                    } else if (vars->name_length >= length_ifInNUCastPkts
                               && !memcmp(objid_ifInNUCastPkts, vars->name,
                                          sizeof(objid_ifInNUCastPkts))) {
                        ipackets += *vars->val.integer;
                        snmp_add_null_var(pdu, vars->name,
                                          vars->name_length);
                        good_var++;
                    } else if (vars->name_length >= length_ifOutUCastPkts
                               && !memcmp(objid_ifOutUCastPkts, vars->name,
                                          sizeof(objid_ifOutUCastPkts))) {
                        opackets += *vars->val.integer;
                        snmp_add_null_var(pdu, vars->name,
                                          vars->name_length);
                        good_var++;
                    } else if (vars->name_length >= length_ifOutNUCastPkts
                               && !memcmp(objid_ifOutNUCastPkts,
                                          vars->name,
                                          sizeof(objid_ifOutNUCastPkts))) {
                        opackets += *vars->val.integer;
                        snmp_add_null_var(pdu, vars->name,
                                          vars->name_length);
                        good_var++;
                    }
                }
                if (good_var == 5)
                    interfaces++;
            } 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++);
                    if (vars)
                        fprint_objid(stderr, vars->name,
                                     vars->name_length);
                    fprintf(stderr, "\n");
                }
                exitval = 2;
            }
        } else if (status == STAT_TIMEOUT) {
            fprintf(stderr, "Timeout: No Response from %s\n",
                    session.peername);
            exitval = 1;
        } else {                /* status == STAT_ERROR */
            snmp_sess_perror("snmpstatus", ss);
            exitval = 1;
        }

        if (response)
            snmp_free_pdu(response);
    }
    printf("Interfaces: %d, Recv/Trans packets: %d/%d | IP: %d/%d\n",
           interfaces, ipackets, opackets, ipin, ipout);
    if (down_interfaces > 0) {
        printf("%d interface%s down!\n",
               down_interfaces, down_interfaces > 1 ? "s are" : " is");
    }

    snmp_close(ss);
    SOCK_CLEANUP;
    return exitval;
}
