/*
 * snmptest.c - send snmp requests to a network entity.
 *
 * Usage: snmptest -v 1 [-q] hostname community [objectID]
 *
 */
/***********************************************************************
	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/net-snmp-includes.h>

int             command = SNMP_MSG_GET;

int             input_variable(netsnmp_variable_list *);

void
usage(void)
{
    fprintf(stderr, "USAGE: snmptest ");
    snmp_parse_args_usage(stderr);
    fprintf(stderr, "\n\n");
    snmp_parse_args_descriptions(stderr);
}

int
main(int argc, char *argv[])
{
    netsnmp_session session, *ss;
    netsnmp_pdu    *pdu = NULL, *response, *copy = NULL;
    netsnmp_variable_list *vars, *vp;
    netsnmp_transport *transport = NULL;
    int             ret;
    int             status, count;
    char            input[128];
    int             varcount, nonRepeaters = -1, maxRepetitions;

    /*
     * get the common command line arguments 
     */
    switch (snmp_parse_args(argc, argv, &session, NULL, NULL)) {
    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("snmptest", &session);
        SOCK_CLEANUP;
        exit(1);
    }

    varcount = 0;
    while (1) {
        vars = NULL;
        for (ret = 1; ret != 0;) {
            vp = (netsnmp_variable_list *)
                malloc(sizeof(netsnmp_variable_list));
            memset(vp, 0, sizeof(netsnmp_variable_list));

            while ((ret = input_variable(vp)) == -1);
            if (ret == 1) {
                varcount++;
                /*
                 * add it to the list 
                 */
                if (vars == NULL) {
                    /*
                     * if first variable 
                     */
                    pdu = snmp_pdu_create(command);
                    pdu->variables = vp;
                } else {
                    vars->next_variable = vp;
                }
                vars = vp;
            } else {
                /*
                 * free the last (unused) variable 
                 */
                if (vp->name)
                    free((char *) vp->name);
                if (vp->val.string)
                    free((char *) vp->val.string);
                free((char *) vp);

                if (command == SNMP_MSG_GETBULK) {
                    if (nonRepeaters == -1) {
                        nonRepeaters = varcount;
                        ret = -1;       /* so we collect more variables */
                        printf("Now input the repeating variables\n");
                    } else {
                        printf("What repeat count? ");
                        fflush(stdout);
                        fgets(input, sizeof(input), stdin);
                        maxRepetitions = atoi(input);
                        pdu->non_repeaters = nonRepeaters;
                        pdu->max_repetitions = maxRepetitions;
                    }
                }
            }
            if (varcount == 0 && ret == 0) {
                if (!copy) {
                    printf("No PDU to send.\n");
                    ret = -1;
                } else {
                    pdu = snmp_clone_pdu(copy);
                    printf("Resending last PDU.\n");
                }
            }
        }
        copy = snmp_clone_pdu(pdu);
        if (command == SNMP_MSG_TRAP2) {
            /*
             * No response needed 
             */
            if (!snmp_send(ss, pdu)) {
                snmp_free_pdu(pdu);
                snmp_sess_perror("snmptest", ss);
            }
        } else {
            status = snmp_synch_response(ss, pdu, &response);
            if (status == STAT_SUCCESS) {
                if (command == SNMP_MSG_INFORM &&
                    response->errstat == SNMP_ERR_NOERROR) {
                    printf("Inform Acknowledged\n");
                } else {
                    switch (response->command) {
                    case SNMP_MSG_GET:
                        printf("Received Get Request ");
                        break;
                    case SNMP_MSG_GETNEXT:
                        printf("Received Getnext Request ");
                        break;
                    case SNMP_MSG_RESPONSE:
                        printf("Received Get Response ");
                        break;
                    case SNMP_MSG_SET:
                        printf("Received Set Request ");
                        break;
                    case SNMP_MSG_TRAP:
                        printf("Received Trap Request ");
                        break;
                    case SNMP_MSG_GETBULK:
                        printf("Received Bulk Request ");
                        break;
                    case SNMP_MSG_INFORM:
                        printf("Received Inform Request ");
                        break;
                    case SNMP_MSG_TRAP2:
                        printf("Received SNMPv2 Trap Request ");
                        break;
                    }
                    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("from %s\n", addr_string);
                            free(addr_string);
                        }
                    } else {
                        printf("from <UNKNOWN>\n");
                    }
                    printf
                        ("requestid 0x%lX errstat 0x%lX errindex 0x%lX\n",
                         response->reqid, response->errstat,
                         response->errindex);
                    if (response->errstat == SNMP_ERR_NOERROR) {
                        for (vars = response->variables; vars;
                             vars = vars->next_variable)
                            print_variable(vars->name, vars->name_length,
                                           vars);
                    } else {
                        printf("Error in packet.\nReason: %s\n",
                               snmp_errstring(response->errstat));
                        if (response->errindex != 0) {
                            for (count = 1, vars = response->variables;
                                 vars && count != response->errindex;
                                 vars = vars->next_variable, count++);
                            if (vars) {
                                printf("Failed object: ");
                                print_objid(vars->name, vars->name_length);
                            }
                            printf("\n");
                        }
                    }
                }
            } else if (status == STAT_TIMEOUT) {
                printf("Timeout: No Response from %s\n", session.peername);
            } else {            /* status == STAT_ERROR */
                snmp_sess_perror("snmptest", ss);
            }

            if (response)
                snmp_free_pdu(response);
        }
        varcount = 0;
        nonRepeaters = -1;
    }
    SOCK_CLEANUP;
    return 0;
}

int
input_variable(netsnmp_variable_list * vp)
{
    char            buf[256];
    size_t          val_len;
    u_char          value[256], ch;
    oid             name[MAX_OID_LEN];

    printf("Variable: ");
    fflush(stdout);
    if (!fgets(buf, sizeof(buf), stdin)) {
        printf("Quitting,  Goobye\n");
        SOCK_CLEANUP;
        exit(0);
    }
    val_len = strlen(buf);

    if (val_len == 0 || *buf == '\n') {
        vp->name_length = 0;
        return 0;
    }
    if (buf[val_len - 1] == '\n')
        buf[--val_len] = 0;
    if (*buf == '$') {
        switch (toupper(buf[1])) {
        case 'G':
            command = SNMP_MSG_GET;
            printf("Request type is Get Request\n");
            break;
        case 'N':
            command = SNMP_MSG_GETNEXT;
            printf("Request type is Getnext Request\n");
            break;
        case 'S':
            command = SNMP_MSG_SET;
            printf("Request type is Set Request\n");
            break;
        case 'B':
            command = SNMP_MSG_GETBULK;
            printf("Request type is Bulk Request\n");
            printf
                ("Enter a blank line to terminate the list of non-repeaters\n");
            printf("and to begin the repeating variables\n");
            break;
        case 'I':
            command = SNMP_MSG_INFORM;
            printf("Request type is Inform Request\n");
            printf("(Are you sending to the right port?)\n");
            break;
        case 'T':
            command = SNMP_MSG_TRAP2;
            printf("Request type is SNMPv2 Trap Request\n");
            printf("(Are you sending to the right port?)\n");
            break;
        case 'D':
            if (snmp_get_dump_packet()) {
                snmp_set_dump_packet(0);
                printf("Turned packet dump off\n");
            } else {
                snmp_set_dump_packet(1);
                printf("Turned packet dump on\n");
            }
            break;
        case 'Q':
            switch ((toupper(buf[2]))) {
            case '\n':
            case 0:
                printf("Quitting,  Goodbye\n");
                SOCK_CLEANUP;
                exit(0);
                break;
            case 'P':
                if (snmp_get_quick_print()) {
                    snmp_set_quick_print(0);
                    printf("Turned quick printing off\n");
                } else {
                    snmp_set_quick_print(1);
                    printf("Turned quick printing on\n");
                }
                break;
            }
            break;
        default:
            printf("Bad command\n");
        }
        return -1;
    }
    vp->name_length = MAX_OID_LEN;
    if (!snmp_parse_oid(buf, name, &vp->name_length)) {
        snmp_perror(buf);
        return -1;
    }
    vp->name = (oid *) malloc(vp->name_length * sizeof(oid));
    memmove(vp->name, name, vp->name_length * sizeof(oid));

    if (command == SNMP_MSG_SET || command == SNMP_MSG_INFORM
        || command == SNMP_MSG_TRAP2) {
        printf("Type [i|u|s|x|d|n|o|t|a]: ");
        fflush(stdout);
        fgets(buf, sizeof(buf), stdin);
        ch = *buf;
        switch (ch) {
        case 'i':
            vp->type = ASN_INTEGER;
            break;
        case 'u':
            vp->type = ASN_UNSIGNED;
            break;
        case 's':
            vp->type = ASN_OCTET_STR;
            break;
        case 'x':
            vp->type = ASN_OCTET_STR;
            break;
        case 'd':
            vp->type = ASN_OCTET_STR;
            break;
        case 'n':
            vp->type = ASN_NULL;
            break;
        case 'o':
            vp->type = ASN_OBJECT_ID;
            break;
        case 't':
            vp->type = ASN_TIMETICKS;
            break;
        case 'a':
            vp->type = ASN_IPADDRESS;
            break;
        default:
            printf
                ("bad type \"%c\", use \"i\", \"u\", \"s\", \"x\", \"d\", \"n\", \"o\", \"t\", or \"a\".\n",
                 *buf);
            return -1;
        }
      getValue:
        printf("Value: ");
        fflush(stdout);
        fgets(buf, sizeof(buf), stdin);
        switch (vp->type) {
        case ASN_INTEGER:
            vp->val.integer = (long *) malloc(sizeof(long));
            *(vp->val.integer) = atoi(buf);
            vp->val_len = sizeof(long);
            break;
        case ASN_UNSIGNED:
            vp->val.integer = (long *) malloc(sizeof(long));
            *(vp->val.integer) = strtoul(buf, NULL, 0);
            vp->val_len = sizeof(long);
            break;
        case ASN_OCTET_STR:
            if (ch == 'd') {
                size_t          buf_len = 256;
                val_len = 0;
                if ((vp->val.string = (u_char *) malloc(buf_len)) == NULL) {
                    printf("malloc failure\n");
                    goto getValue;
                }
                if (!snmp_decimal_to_binary(&(vp->val.string), &buf_len,
                                            &val_len, 1, buf)) {
                    printf("Bad value or no sub-identifier > 255\n");
                    free(vp->val.string);
                    goto getValue;
                }
                vp->val_len = val_len;
            } else if (ch == 's') {
                /*
                 * -1 to omit trailing newline  
                 */
                vp->val.string = (u_char *) malloc(strlen(buf) - 1);
                if (vp->val.string == NULL) {
                    printf("malloc failure\n");
                    goto getValue;
                }
                memcpy(vp->val.string, buf, strlen(buf) - 1);
                vp->val.string[sizeof(vp->val.string)-1] = 0;
                vp->val_len = strlen(buf) - 1;
            } else if (ch == 'x') {
                size_t          buf_len = 256;
                val_len = 0;
                if ((vp->val.string = (u_char *) malloc(buf_len)) == NULL) {
                    printf("malloc failure\n");
                    goto getValue;
                }
                if (!snmp_hex_to_binary(&(vp->val.string), &buf_len,
                                        &val_len, 1, buf)) {
                    printf("Bad value (need pairs of hex digits)\n");
                    free(vp->val.string);
                    goto getValue;
                }
                vp->val_len = val_len;
            }
            break;
        case ASN_NULL:
            vp->val_len = 0;
            vp->val.string = NULL;
            break;
        case ASN_OBJECT_ID:
            if ('\n' == buf[strlen(buf) - 1])
                buf[strlen(buf) - 1] = '\0';
            vp->val_len = MAX_OID_LEN;;
            if (0 == read_objid(buf, (oid *) value, &vp->val_len)) {
                printf("Unrecognised OID value\n");
                goto getValue;
            }
            vp->val_len *= sizeof(oid);
            vp->val.objid = (oid *) malloc(vp->val_len);
            memmove(vp->val.objid, value, vp->val_len);
            break;
        case ASN_TIMETICKS:
            vp->val.integer = (long *) malloc(sizeof(long));
            *(vp->val.integer) = atoi(buf);
            vp->val_len = sizeof(long);
            break;
        case ASN_IPADDRESS:
            vp->val.integer = (long *) malloc(sizeof(long));
            *(vp->val.integer) = inet_addr(buf);
            vp->val_len = sizeof(long);
            break;
        default:
            printf("Internal error\n");
            break;
        }
    } else {                    /* some form of get message */
        vp->type = ASN_NULL;
        vp->val_len = 0;
    }
    return 1;
}
