int
show_all_matched_objects(FILE * fp, const char *patmatch, oid * name, size_t * name_length, int f_desc, /* non-zero if descriptions should be shown */
                         int width)
{
    int             result = 0, count = 0;
    size_t          savlen = *name_length;
#ifndef NETSNMP_DISABLE_MIB_LOADING
    clear_tree_flags(get_tree_head());
#endif /* NETSNMP_DISABLE_MIB_LOADING */

    while (1) {
        *name_length = savlen;
#ifndef NETSNMP_DISABLE_MIB_LOADING
        result = get_wild_node(patmatch, name, name_length);
#endif /* NETSNMP_DISABLE_MIB_LOADING */
        if (!result)
            break;
        count++;

        fprint_objid(fp, name, *name_length);
#ifndef NETSNMP_DISABLE_MIB_LOADING
        if (f_desc)
            fprint_description(fp, name, *name_length, width);
#endif /* NETSNMP_DISABLE_MIB_LOADING */
    }

    return (count);
}
示例#2
0
int
show_all_matched_objects(FILE * fp, const char *patmatch, oid * name, size_t * name_length, int f_desc, /* non-zero if descriptions should be shown */
                         int width)
{
    int             result, count = 0;
    size_t          savlen = *name_length;
    clear_tree_flags(get_tree_head());

    while (1) {
        *name_length = savlen;
        result = get_wild_node(patmatch, name, name_length);
        if (!result)
            break;
        count++;

        fprint_objid(fp, name, *name_length);
        if (f_desc)
            fprint_description(fp, name, *name_length, width);
    }

    return (count);
}
示例#3
0
文件: snmpusm.c 项目: fenner/net-snmp
/*
 * setup_oid appends to the oid the index for the engineid/user 
 */
void
setup_oid(oid * it, size_t * len, u_char * id, size_t idlen,
          const char *user)
{
    int             i, itIndex = *len;

    *len = itIndex + 1 + idlen + 1 + strlen(user);

    it[itIndex++] = idlen;
    for (i = 0; i < (int) idlen; i++) {
        it[itIndex++] = id[i];
    }

    it[itIndex++] = strlen(user);
    for (i = 0; i < (int) strlen(user); i++) {
        it[itIndex++] = user[i];
    }

#ifdef NETSNMP_ENABLE_TESTING_CODE
    fprintf(stdout, "setup_oid: ");  
    fprint_objid(stdout, it, *len);  
    fprintf(stdout, "\n");  
#endif
}
示例#4
0
文件: snmpbulkget.c 项目: 274914765/C
int main (int argc, char *argv[])
{
    netsnmp_session session, *ss;

    netsnmp_pdu *pdu;

    netsnmp_pdu *response;

    netsnmp_variable_list *vars;

    int arg;

    int count;

    int status;

    int exitval = 0;

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

    names = argc - arg;
    if (names < non_repeaters)
    {
        fprintf (stderr, "snmpbulkget: need more objects than <nonrep>\n");
        exit (1);
    }

    namep = name = (struct nameStruct *) calloc (names, sizeof (*name));
    while (arg < argc)
    {
        namep->name_len = MAX_OID_LEN;
        if (snmp_parse_oid (argv[arg], namep->name, &namep->name_len) == NULL)
        {
            snmp_perror (argv[arg]);
            exit (1);
        }
        arg++;
        namep++;
    }

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

    /*
     * create PDU for GETBULK request and add object name to request 
     */
    pdu = snmp_pdu_create (SNMP_MSG_GETBULK);
    pdu->non_repeaters = non_repeaters;
    pdu->max_repetitions = max_repetitions;    /* fill the packet */
    for (arg = 0; arg < names; arg++)
        snmp_add_null_var (pdu, name[arg].name, name[arg].name_len);

    /*
     * do the request 
     */
    status = snmp_synch_response (ss, pdu, &response);
    if (status == STAT_SUCCESS)
    {
        if (response->errstat == SNMP_ERR_NOERROR)
        {
            /*
             * check resulting variables 
             */
            for (vars = response->variables; vars; vars = vars->next_variable)
                print_variable (vars->name, vars->name_length, vars);
        }
        else
        {
            /*
             * error in response, print it 
             */
            if (response->errstat == SNMP_ERR_NOSUCHNAME)
            {
                printf ("End of MIB.\n");
            }
            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++)
                         /*EMPTY*/;
                    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 ("snmpbulkget", ss);
        exitval = 1;
    }

    if (response)
        snmp_free_pdu (response);

    snmp_close (ss);
    SOCK_CLEANUP;
    return exitval;
}
示例#5
0
SaErrorT snmp_bc_bulk_selcache(	struct oh_handler_state *handle,
                                SaHpiResourceIdT id)
{
    struct snmp_bc_hnd *custom_handle;
    SaErrorT 	err;
    int 		isdst;
    sel_entry 	sel_entry;
    SaHpiEventT 	tmpevent;
    netsnmp_pdu	*pdu, *response;
    netsnmp_variable_list *vars;
    LogSource2ResourceT logsrc2res;
    int             count;
    int             running;
    int             status;
    char 		logstring[MAX_ASN_STR_LEN];
    char 		objoid[SNMP_BC_MAX_OID_LENGTH];
    oid             name[MAX_OID_LEN];
    oid             root[MAX_OID_LEN];
    size_t          rootlen;
    size_t          name_length;
    size_t 		str_len;
    int             reps;

    if (!handle) {
        err("Invalid parameter.");
        return(SA_ERR_HPI_INVALID_PARAMS);
    }

    str_len = MAX_ASN_STR_LEN;
    isdst=0;
    custom_handle = (struct snmp_bc_hnd *)handle->data;
    reps = custom_handle->count_per_getbulk;

    /* --------------------------------------------------- */
    /* Set initial Event Log Entry OID and root tree       */
    /* --------------------------------------------------- */

    if (custom_handle->platform == SNMP_BC_PLATFORM_RSA) {
        snprintf(objoid, SNMP_BC_MAX_OID_LENGTH, "%s", SNMP_BC_SEL_ENTRY_OID_RSA);
    } else {
        snprintf(objoid, SNMP_BC_MAX_OID_LENGTH, "%s",SNMP_BC_SEL_ENTRY_OID);
    }
    rootlen = MAX_OID_LEN;
    read_objid(objoid, root, &rootlen);

    /* --------------------------------------------------- */
    /* Object ID for GETBULK request                       */
    /* --------------------------------------------------- */
    g_memmove(name, root, rootlen * sizeof(oid));
    name_length = rootlen;

    running = 1;

    while (running) {

        /* --------------------------------------------------- */
        /* Create PDU for GETBULK request                      */
        /* --------------------------------------------------- */
        pdu = snmp_pdu_create(SNMP_MSG_GETBULK);

        status = snmp_getn_bulk(custom_handle->sessp,
                                name,
                                name_length,
                                pdu,
                                &response,
                                reps);

        if (pdu) snmp_free_pdu(pdu);

        if (status == STAT_SUCCESS) {
            if (response->errstat == SNMP_ERR_NOERROR) {
                for (vars = response->variables; vars;
                        vars = vars->next_variable) {

                    /* ------------------------------------------------- */
                    /* Check if this variable is of the same OID tree    */
                    /* ------------------------------------------------- */
                    if ((vars->name_length < rootlen)
                            || (memcmp(root, vars->name, rootlen * sizeof(oid)) != 0))
                    {
                        /* Exit vars processing */
                        running = 0;
                        continue;
                    }

                    if ((vars->type != SNMP_ENDOFMIBVIEW) &&
                            (vars->type != SNMP_NOSUCHOBJECT) &&
                            (vars->type != SNMP_NOSUCHINSTANCE)) {

                        if (snmp_oid_compare(name, name_length,
                                             vars->name,
                                             vars->name_length) >= 0) {
                            fprintf(stderr, "Error: OID not increasing: ");
                            fprint_objid(stderr, name, name_length);
                            fprintf(stderr, " >= ");
                            fprint_objid(stderr, vars->name,
                                         vars->name_length);
                            fprintf(stderr, "\n");
                            running = 0;
                        }
                        /* ---------------------------------- */
                        /* Check if last variable,            */
                        /* and if so, save for next request.  */
                        /* ---------------------------------- */
                        if (vars->next_variable == NULL) {
                            g_memmove(name, vars->name,
                                      vars->name_length * sizeof(oid));
                            name_length = vars->name_length;
                        }

                        /* ---------------------------------- */
                        /* ---------------------------------- */
                        /* ---------------------------------- */
                        if ((running == 1) && (vars->type == ASN_OCTET_STR)) {

                            if (vars->val_len < MAX_ASN_STR_LEN) str_len = vars->val_len;
                            else str_len = MAX_ASN_STR_LEN;

                            /* ---------------------------------- */
                            /* Guarantee NULL terminated string   */
                            /* ---------------------------------- */
                            // memcpy(logstring, vars->val.string, str_len);
                            g_memmove(logstring, vars->val.string, str_len);
                            logstring[str_len] = '\0';


                            err = snmp_bc_parse_sel_entry(handle,logstring, &sel_entry);
                            isdst = sel_entry.time.tm_isdst;
                            snmp_bc_log2event(handle, logstring, &tmpevent, isdst, &logsrc2res);
                            err = oh_el_prepend(handle->elcache, &tmpevent, NULL, NULL);
                            if (custom_handle->isFirstDiscovery == SAHPI_FALSE)
                                err = snmp_bc_add_to_eventq(handle, &tmpevent, SAHPI_TRUE);
                        }
                    } else {
                        /* Stop on an exception value */
                        running = 0;
                    }
                }  /* end for */
            } else {   /* if (response->errstat != SNMP_ERR_NOERROR) */

                /* --------------------------------------------- */
                /* Error condition is seen in response,          */
                /* for now, print the error then exit            */
                /* Not sure what to do for recovery              */
                running = 0;
                if (response->errstat == SNMP_ERR_NOSUCHNAME) {
                    printf("End of MIB\n");
                } 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");
                    }
                }
            }
        } else if (status == STAT_TIMEOUT) {
            fprintf(stderr, "Timeout: No Response\n");
            running = 0;
        } else {                /* status == STAT_ERROR */
            snmp_sess_perror("snmp_bulk_sel",custom_handle->sessp );
            running = 0;
        }

        if (response)
            snmp_free_pdu(response);
    }
    return(SA_OK);
}
示例#6
0
文件: snmpset.c 项目: DYFeng/infinidb
int
main(int argc, char *argv[])
{
    netsnmp_session session, *ss;
    netsnmp_pdu    *pdu, *response = NULL;
    netsnmp_variable_list *vars;
    int             arg;
    int             count;
    int             current_name = 0;
    int             current_type = 0;
    int             current_value = 0;
    char           *names[SNMP_MAX_CMDLINE_OIDS];
    char            types[SNMP_MAX_CMDLINE_OIDS];
    char           *values[SNMP_MAX_CMDLINE_OIDS];
    oid             name[MAX_OID_LEN];
    size_t          name_length;
    int             status;
    int             exitval = 0;

    putenv(strdup("POSIXLY_CORRECT=1"));

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

    if (arg >= argc) {
        fprintf(stderr, "Missing object name\n");
        usage();
        exit(1);
    }
    if ((argc - arg) > 3*SNMP_MAX_CMDLINE_OIDS) {
        fprintf(stderr, "Too many assignments specified. ");
        fprintf(stderr, "Only %d allowed in one request.\n", SNMP_MAX_CMDLINE_OIDS);
        usage();
        exit(1);
    }

    /*
     * get object names, types, and values 
     */
    for (; arg < argc; arg++) {
        DEBUGMSGTL(("snmp_parse_args", "handling (#%d): %s %s %s\n",
                    arg,argv[arg], arg+1 < argc ? argv[arg+1] : NULL,
                    arg+2 < argc ? argv[arg+2] : NULL));
        names[current_name++] = argv[arg++];
        if (arg < argc) {
            switch (*argv[arg]) {
            case '=':
            case 'i':
            case 'u':
            case 't':
            case 'a':
            case 'o':
            case 's':
            case 'x':
            case 'd':
            case 'b':
#ifdef OPAQUE_SPECIAL_TYPES
            case 'I':
            case 'U':
            case 'F':
            case 'D':
#endif                          /* OPAQUE_SPECIAL_TYPES */
                types[current_type++] = *argv[arg++];
                break;
            default:
                fprintf(stderr, "%s: Bad object type: %c\n", argv[arg - 1],
                        *argv[arg]);
                exit(1);
            }
        } else {
            fprintf(stderr, "%s: Needs type and value\n", argv[arg - 1]);
            exit(1);
        }
        if (arg < argc)
            values[current_value++] = argv[arg];
        else {
            fprintf(stderr, "%s: Needs value\n", argv[arg - 2]);
            exit(1);
        }
    }

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

    /*
     * create PDU for SET request and add object names and values to request 
     */
    pdu = snmp_pdu_create(SNMP_MSG_SET);
    for (count = 0; count < current_name; count++) {
        name_length = MAX_OID_LEN;
        if (snmp_parse_oid(names[count], name, &name_length) == NULL) {
            snmp_perror(names[count]);
            failures++;
        } else
            if (snmp_add_var
                (pdu, name, name_length, types[count], values[count])) {
            snmp_perror(names[count]);
            failures++;
        }
    }

    if (failures) {
        SOCK_CLEANUP;
        exit(1);
    }

    /*
     * do the request 
     */
    status = snmp_synch_response(ss, pdu, &response);
    if (status == STAT_SUCCESS) {
        if (response->errstat == SNMP_ERR_NOERROR) {
            if (!quiet) {
                for (vars = response->variables; vars;
                     vars = vars->next_variable)
                    print_variable(vars->name, vars->name_length, vars);
            }
        } 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("snmpset", ss);
        exitval = 1;
    }

    if (response)
        snmp_free_pdu(response);
    snmp_close(ss);
    SOCK_CLEANUP;
    return exitval;
}
示例#7
0
文件: snmpget.c 项目: AllardJ/Tomato
int
main(int argc, char *argv[])
{
    netsnmp_session session, *ss;
    netsnmp_pdu    *pdu;
    netsnmp_pdu    *response;
    netsnmp_variable_list *vars;
    int             arg;
    int             count;
    int             current_name = 0;
    char           *names[128];
    oid             name[MAX_OID_LEN];
    size_t          name_length;
    int             status;
    int             exitval = 0;

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

    if (arg >= argc) {
        fprintf(stderr, "Missing object name\n");
        usage();
        exit(1);
    }

    /*
     * get the object names 
     */
    for (; arg < argc; arg++)
        names[current_name++] = argv[arg];

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


    /*
     * Create PDU for GET request and add object names to request.
     */
    pdu = snmp_pdu_create(SNMP_MSG_GET);
    for (count = 0; count < current_name; count++) {
        name_length = MAX_OID_LEN;
        if (!snmp_parse_oid(names[count], name, &name_length)) {
            snmp_perror(names[count]);
            failures++;
        } else
            snmp_add_null_var(pdu, name, name_length);
    }
    if (failures) {
        SOCK_CLEANUP;
        exit(1);
    }


    /*
     * Perform the request.
     *
     * If the Get Request fails, note the OID that caused the error,
     * "fix" the PDU (removing the error-prone OID) and retry.
     */
  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)
                print_variable(vars->name, vars->name_length, vars);

        } 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++)
                    /*EMPTY*/;
                if (vars) {
                    fprint_objid(stderr, vars->name, vars->name_length);
		}
                fprintf(stderr, "\n");
            }
            exitval = 2;

            /*
             * 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;
		}
            }
        }                       /* endif -- SNMP_ERR_NOERROR */

    } else if (status == STAT_TIMEOUT) {
        fprintf(stderr, "Timeout: No Response from %s.\n",
                session.peername);
        exitval = 1;

    } else {                    /* status == STAT_ERROR */
        snmp_sess_perror("snmpget", ss);
        exitval = 1;

    }                           /* endif -- STAT_SUCCESS */


    if (response)
        snmp_free_pdu(response);
    snmp_close(ss);
    SOCK_CLEANUP;
    return exitval;

}                               /* end main() */
int
main(int argc, char *argv[])
{
    netsnmp_session session, *ss;
    netsnmp_pdu    *pdu, *response;
    netsnmp_variable_list *vars;
    int             arg;
    oid             name[MAX_OID_LEN];
    size_t          name_length;
    oid             root[MAX_OID_LEN];
    size_t          rootlen;
    int             count;
    int             running;
    int             status;
    int             check;
    int             exitval = 0;

    netsnmp_ds_register_config(ASN_BOOLEAN, "snmpwalk", "includeRequested",
			       NETSNMP_DS_APPLICATION_ID, 
			       NETSNMP_DS_WALK_INCLUDE_REQUESTED);
    netsnmp_ds_register_config(ASN_BOOLEAN, "snmpwalk", "printStatistics",
			       NETSNMP_DS_APPLICATION_ID, 
			       NETSNMP_DS_WALK_PRINT_STATISTICS);
    netsnmp_ds_register_config(ASN_BOOLEAN, "snmpwalk", "dontCheckOrdering",
			       NETSNMP_DS_APPLICATION_ID,
			       NETSNMP_DS_WALK_DONT_CHECK_LEXICOGRAPHIC);

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

    /*
     * get the initial object and subtree 
     */
    if (arg < argc) {
        /*
         * specified on the command line 
         */
        rootlen = MAX_OID_LEN;
        if (snmp_parse_oid(argv[arg], root, &rootlen) == NULL) {
            snmp_perror(argv[arg]);
            exit(1);
        }
    } else {
        /*
         * use default value 
         */
        memmove(root, objid_mib, sizeof(objid_mib));
        rootlen = sizeof(objid_mib) / sizeof(oid);
    }

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

    /*
     * setup initial object name 
     */
    memmove(name, root, rootlen * sizeof(oid));
    name_length = rootlen;

    running = 1;

    check = !netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
				    NETSNMP_DS_WALK_DONT_CHECK_LEXICOGRAPHIC);
    if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
			       NETSNMP_DS_WALK_INCLUDE_REQUESTED)) {
        snmp_get_and_print(ss, root, rootlen);
    }

    while (running) {
        /*
         * create PDU for GETBULK request and add object name to request 
         */
        pdu = snmp_pdu_create(SNMP_MSG_GETBULK);
        pdu->non_repeaters = non_reps;
        pdu->max_repetitions = reps;    /* fill the packet */
        snmp_add_null_var(pdu, name, name_length);

        /*
         * do the request 
         */
        status = snmp_synch_response(ss, pdu, &response);
        if (status == STAT_SUCCESS) {
            if (response->errstat == SNMP_ERR_NOERROR) {
                /*
                 * check resulting variables 
                 */
                for (vars = response->variables; vars;
                     vars = vars->next_variable) {
                    if ((vars->name_length < rootlen)
                        || (memcmp(root, vars->name, rootlen * sizeof(oid))
                            != 0)) {
                        /*
                         * not part of this subtree 
                         */
                        running = 0;
                        continue;
                    }
                    numprinted++;
                    print_variable(vars->name, vars->name_length, vars);
                    if ((vars->type != SNMP_ENDOFMIBVIEW) &&
                        (vars->type != SNMP_NOSUCHOBJECT) &&
                        (vars->type != SNMP_NOSUCHINSTANCE)) {
                        /*
                         * not an exception value 
                         */
                        if (check
                            && snmp_oid_compare(name, name_length,
                                                vars->name,
                                                vars->name_length) >= 0) {
                            fprintf(stderr, "Error: OID not increasing: ");
                            fprint_objid(stderr, name, name_length);
                            fprintf(stderr, " >= ");
                            fprint_objid(stderr, vars->name,
                                         vars->name_length);
                            fprintf(stderr, "\n");
                            running = 0;
                            exitval = 1;
                        }
                        /*
                         * Check if last variable, and if so, save for next request.  
                         */
                        if (vars->next_variable == NULL) {
                            memmove(name, vars->name,
                                    vars->name_length * sizeof(oid));
                            name_length = vars->name_length;
                        }
                    } else {
                        /*
                         * an exception value, so stop 
                         */
                        running = 0;
                    }
                }
            } else {
                /*
                 * error in response, print it 
                 */
                running = 0;
                if (response->errstat == SNMP_ERR_NOSUCHNAME) {
                    printf("End of MIB\n");
                } 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++)
                            /*EMPTY*/;
                        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);
            running = 0;
            exitval = 1;
        } else {                /* status == STAT_ERROR */
            snmp_sess_perror("snmpbulkwalk", ss);
            running = 0;
            exitval = 1;
        }
        if (response)
            snmp_free_pdu(response);
    }

    if (numprinted == 0 && status == STAT_SUCCESS) {
        /*
         * no printed successful results, which may mean we were
         * pointed at an only existing instance.  Attempt a GET, just
         * for get measure. 
         */
        snmp_get_and_print(ss, root, rootlen);
    }
    snmp_close(ss);

    if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
			       NETSNMP_DS_WALK_PRINT_STATISTICS)) {
        printf("Variables found: %d\n", numprinted);
    }

    SOCK_CLEANUP;
    return exitval;
}
示例#9
0
文件: snmpusm.c 项目: fenner/net-snmp
int
main(int argc, char *argv[])
{
    netsnmp_session session, *ss;
    netsnmp_pdu    *pdu = NULL, *response = NULL;

    int             arg;
    size_t          name_length = USM_OID_LEN;
    size_t          name_length2 = USM_OID_LEN;
    int             status;
    int             exitval = 1;
    int             rval;
    int             command = 0;
    long            longvar;

    size_t          oldKu_len = SNMP_MAXBUF_SMALL,
        newKu_len = SNMP_MAXBUF_SMALL,
        oldkul_len = SNMP_MAXBUF_SMALL,
        oldkulpriv_len = SNMP_MAXBUF_SMALL,
        newkulpriv_len = SNMP_MAXBUF_SMALL,
        newkul_len = SNMP_MAXBUF_SMALL,
        keychange_len = SNMP_MAXBUF_SMALL,
        keychangepriv_len = SNMP_MAXBUF_SMALL;

    char           *newpass = NULL, *oldpass = NULL;
    u_char          oldKu[SNMP_MAXBUF_SMALL],
        newKu[SNMP_MAXBUF_SMALL],
        oldkul[SNMP_MAXBUF_SMALL],
        oldkulpriv[SNMP_MAXBUF_SMALL],
        newkulpriv[SNMP_MAXBUF_SMALL],
        newkul[SNMP_MAXBUF_SMALL], keychange[SNMP_MAXBUF_SMALL],
        keychangepriv[SNMP_MAXBUF_SMALL];

    SOCK_STARTUP;

    authKeyChange = authKeyOid;
    privKeyChange = privKeyOid;

    /*
     * get the common command line arguments 
     */
    switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) {
    case NETSNMP_PARSE_ARGS_ERROR:
        goto out;
    case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
        exitval = 0;
        goto out;
    case NETSNMP_PARSE_ARGS_ERROR_USAGE:
        usage();
        goto out;
    default:
        break;
    }

    if (arg >= argc) {
        fprintf(stderr, "Please specify an operation to perform.\n");
        usage();
        goto out;
    }

    /*
     * open an SNMP session 
     */
    /*
     * Note:  this needs to obtain the engineID used below 
     */
    session.flags &= ~SNMP_FLAGS_DONT_PROBE;
    ss = snmp_open(&session);
    if (ss == NULL) {
        /*
         * diagnose snmp_open errors with the input netsnmp_session pointer 
         */
        snmp_sess_perror("snmpusm", &session);
        goto out;
    }

    /*
     * set usmUserEngineID from ss->contextEngineID
     *   if not already set (via -CE)
     */
    if (usmUserEngineID == NULL) {
      usmUserEngineID    = ss->contextEngineID;
      usmUserEngineIDLen = ss->contextEngineIDLen;
    }

    /*
     * create PDU for SET request and add object names and values to request 
     */
    pdu = snmp_pdu_create(SNMP_MSG_SET);
    if (!pdu) {
        fprintf(stderr, "Failed to create request\n");
        goto close_session;
    }


    if (strcmp(argv[arg], CMD_PASSWD_NAME) == 0) {

        /*
         * passwd: change a users password.
         *
         * XXX:  Uses the auth type of the calling user, a MD5 user can't
         *       change a SHA user's key.
         */
        char *passwd_user;

        command = CMD_PASSWD;
        oldpass = argv[++arg];
        newpass = argv[++arg];
        passwd_user = argv[++arg];

        if (doprivkey == 0 && doauthkey == 0)
            doprivkey = doauthkey = 1;

        if (newpass == NULL || strlen(newpass) < USM_LENGTH_P_MIN) {
            fprintf(stderr,
                    "New passphrase must be greater than %d characters in length.\n",
                    USM_LENGTH_P_MIN);
            goto close_session;
        }

        if (oldpass == NULL || strlen(oldpass) < USM_LENGTH_P_MIN) {
            fprintf(stderr,
                    "Old passphrase must be greater than %d characters in length.\n",
                    USM_LENGTH_P_MIN);
            goto close_session;
        }

        DEBUGMSGTL(("9:usm:passwd", "oldpass len %" NETSNMP_PRIz "d, newpass len %" NETSNMP_PRIz "d\n",
                    strlen(oldpass), strlen(newpass)));

        /* 
         * Change the user supplied on command line.
         */
        if ((passwd_user != NULL) && (strlen(passwd_user) > 0)) {
            session.securityName = passwd_user;
        } else {
            /*
             * Use own key object if no user was supplied.
             */
            authKeyChange = ownAuthKeyOid;
            privKeyChange = ownPrivKeyOid;
        }

        /*
         * do we have a securityName?  If not, copy the default 
         */
        if (session.securityName == NULL) {
            session.securityName = 
	      strdup(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
					   NETSNMP_DS_LIB_SECNAME));
        }

        /*
         * the old Ku is in the session, but we need the new one 
         */
        if (session.securityAuthProto == NULL) {
            /*
             * get .conf set default 
             */
            const oid      *def =
                get_default_authtype(&session.securityAuthProtoLen);
            session.securityAuthProto =
                snmp_duplicate_objid(def, session.securityAuthProtoLen);
        }
        if (session.securityAuthProto == NULL) {
            /*
             * assume MD5 
             */
#ifndef NETSNMP_DISABLE_MD5
            session.securityAuthProtoLen =
                sizeof(usmHMACMD5AuthProtocol) / sizeof(oid);
            session.securityAuthProto =
                snmp_duplicate_objid(usmHMACMD5AuthProtocol,
                                     session.securityAuthProtoLen);
#else
            session.securityAuthProtoLen =
                sizeof(usmHMACSHA1AuthProtocol) / sizeof(oid);
            session.securityAuthProto =
                snmp_duplicate_objid(usmHMACSHA1AuthProtocol,
                                     session.securityAuthProtoLen);
#endif

        }

	if (uselocalizedkey && (strncmp(oldpass, "0x", 2) == 0)) {
	    /*
	     * use the localized key from the command line
	     */
	    u_char *buf;
	    size_t buf_len = SNMP_MAXBUF_SMALL;
	    buf = (u_char *) malloc (buf_len * sizeof(u_char));

	    oldkul_len = 0; /* initialize the offset */
	    if (!snmp_hex_to_binary((u_char **) (&buf), &buf_len, &oldkul_len, 0, oldpass)) {
	      snmp_perror(argv[0]);
	      fprintf(stderr, "generating the old Kul from localized key failed\n");
	      goto close_session;
	    }
	    
	    memcpy(oldkul, buf, oldkul_len);
	    SNMP_FREE(buf);
	}
	else {
	    /*
	     * the old Ku is in the session, but we need the new one 
	     */
	    rval = generate_Ku(session.securityAuthProto,
			       session.securityAuthProtoLen,
			       (u_char *) oldpass, strlen(oldpass),
			       oldKu, &oldKu_len);
	    
	    if (rval != SNMPERR_SUCCESS) {
	        snmp_perror(argv[0]);
	        fprintf(stderr, "generating the old Ku failed\n");
	        goto close_session;
	    }

	    /*
	     * generate the two Kul's 
	     */
	    rval = generate_kul(session.securityAuthProto,
				session.securityAuthProtoLen,
				usmUserEngineID, usmUserEngineIDLen,
				oldKu, oldKu_len, oldkul, &oldkul_len);
	    
	    if (rval != SNMPERR_SUCCESS) {
	        snmp_perror(argv[0]);
		fprintf(stderr, "generating the old Kul failed\n");
		goto close_session;
	    }
            DEBUGMSGTL(("9:usm:passwd", "oldkul len %" NETSNMP_PRIz "d\n", oldkul_len));
	}
	if (uselocalizedkey && (strncmp(newpass, "0x", 2) == 0)) {
	    /*
	     * use the localized key from the command line
	     */
	    u_char *buf;
	    size_t buf_len = SNMP_MAXBUF_SMALL;
	    buf = (u_char *) malloc (buf_len * sizeof(u_char));

	    newkul_len = 0; /* initialize the offset */
	    if (!snmp_hex_to_binary((u_char **) (&buf), &buf_len, &newkul_len, 0, newpass)) {
	      snmp_perror(argv[0]);
	      fprintf(stderr, "generating the new Kul from localized key failed\n");
	      goto close_session;
	    }
	    
	    memcpy(newkul, buf, newkul_len);
	    SNMP_FREE(buf);
	} else {
            rval = generate_Ku(session.securityAuthProto,
                               session.securityAuthProtoLen,
                               (u_char *) newpass, strlen(newpass),
                               newKu, &newKu_len);

            if (rval != SNMPERR_SUCCESS) {
                snmp_perror(argv[0]);
                fprintf(stderr, "generating the new Ku failed\n");
                goto close_session;
            }

	    rval = generate_kul(session.securityAuthProto,
				session.securityAuthProtoLen,
				usmUserEngineID, usmUserEngineIDLen,
				newKu, newKu_len, newkul, &newkul_len);

	    if (rval != SNMPERR_SUCCESS) {
	        snmp_perror(argv[0]);
		fprintf(stderr, "generating the new Kul failed\n");
		goto close_session;
	    }
            DEBUGMSGTL(("9:usm:passwd", "newkul len %" NETSNMP_PRIz "d\n", newkul_len));
	}

        /*
         * for encryption, we may need to truncate the key to the proper length
         * so we need two copies.  For simplicity, we always just copy even if
         * they're the same lengths.
         */
        if (doprivkey) {
            int privtype, properlength;
            u_char *okp = oldkulpriv, *nkp = newkulpriv;
            if (!session.securityPrivProto) {
                snmp_log(LOG_ERR, "no encryption type specified, which I need in order to know to change the key\n");
                goto close_session;
            }

            privtype = sc_get_privtype(session.securityPrivProto,
                                       session.securityPrivProtoLen);
            properlength = sc_get_proper_priv_length_bytype(privtype);
            if (USM_CREATE_USER_PRIV_DES == privtype)
                properlength *= 2; /* ?? we store salt with key */
            DEBUGMSGTL(("9:usm:passwd", "proper len %d\n", properlength));
            oldkulpriv_len = oldkul_len;
            newkulpriv_len = newkul_len;
            memcpy(oldkulpriv, oldkul, oldkulpriv_len);
            memcpy(newkulpriv, newkul, newkulpriv_len);

            if (oldkulpriv_len > properlength) {
                oldkulpriv_len = newkulpriv_len = properlength;
            }
            else if (oldkulpriv_len < properlength) {
                rval = netsnmp_extend_kul(properlength,
                                          session.securityAuthProto,
                                          session.securityAuthProtoLen,
                                          privtype,
                                          usmUserEngineID, usmUserEngineIDLen,
                                          &okp, &oldkulpriv_len,
                                          sizeof(oldkulpriv));
                rval = netsnmp_extend_kul(properlength,
                                          session.securityAuthProto,
                                          session.securityAuthProtoLen,
                                          privtype,
                                          usmUserEngineID, usmUserEngineIDLen,
                                          &nkp, &newkulpriv_len,
                                          sizeof(newkulpriv));
            }
        }

        /*
         * create the keychange string 
         */
	if (doauthkey) {
	  rval = encode_keychange(session.securityAuthProto,
				  session.securityAuthProtoLen,
				  oldkul, oldkul_len,
				  newkul, newkul_len,
				  keychange, &keychange_len);

	  if (rval != SNMPERR_SUCCESS) {
	    snmp_perror(argv[0]);
            fprintf(stderr, "encoding the keychange failed\n");
            usage();
            goto close_session;
	  }
	}

        /* which is slightly different for encryption if lengths are
           different */
	if (doprivkey) {
            DEBUGMSGTL(("9:usm:passwd:encode", "proper len %" NETSNMP_PRIz "d, old_len %" NETSNMP_PRIz "d, new_len %" NETSNMP_PRIz "d\n",
                        oldkulpriv_len, oldkulpriv_len, newkulpriv_len));
	  rval = encode_keychange(session.securityAuthProto,
                                session.securityAuthProtoLen,
                                oldkulpriv, oldkulpriv_len,
                                newkulpriv, newkulpriv_len,
                                keychangepriv, &keychangepriv_len);

          DEBUGMSGTL(("9:usm:passwd:encode", "keychange len %" NETSNMP_PRIz "d\n",
                      keychangepriv_len));
	  if (rval != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr, "encoding the keychange failed\n");
            usage();
            goto close_session;
	  }
	}

        /*
         * add the keychange string to the outgoing packet 
         */
        if (doauthkey) {
            setup_oid(authKeyChange, &name_length,
                      usmUserEngineID, usmUserEngineIDLen,
                      session.securityName);
            snmp_pdu_add_variable(pdu, authKeyChange, name_length,
                                  ASN_OCTET_STR, keychange, keychange_len);
        }
        if (doprivkey) {
            setup_oid(privKeyChange, &name_length2,
                      usmUserEngineID, usmUserEngineIDLen,
                      session.securityName);
            snmp_pdu_add_variable(pdu, privKeyChange, name_length2,
                                  ASN_OCTET_STR,
                                  keychangepriv, keychangepriv_len);
        }

    } else if (strcmp(argv[arg], CMD_CREATE_NAME) == 0) {
        /*
         * create:  create a user
         *
         * create USER [CLONEFROM]
         */
        if (++arg >= argc) {
            fprintf(stderr, "You must specify the user name to create\n");
            usage();
            goto close_session;
        }

        command = CMD_CREATE;

        if (++arg < argc) {
            /*
             * clone the new user from an existing user
             *   (and make them active immediately)
             */
            setup_oid(usmUserStatus, &name_length,
                      usmUserEngineID, usmUserEngineIDLen, argv[arg-1]);
            if (docreateandwait) {
                longvar = RS_CREATEANDWAIT;
            } else {
                longvar = RS_CREATEANDGO;
            }
            snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                                  ASN_INTEGER, (u_char *) & longvar,
                                  sizeof(longvar));

            name_length = USM_OID_LEN;
            setup_oid(usmUserCloneFrom, &name_length,
                      usmUserEngineID, usmUserEngineIDLen,
                      argv[arg - 1]);
            setup_oid(usmUserSecurityName, &name_length2,
                      usmUserEngineID, usmUserEngineIDLen,
                      argv[arg]);
            snmp_pdu_add_variable(pdu, usmUserCloneFrom, name_length,
                                  ASN_OBJECT_ID,
                                  (u_char *) usmUserSecurityName,
                                  sizeof(oid) * name_length2);
        } else {
            /*
             * create a new (unauthenticated) user from scratch
             * The Net-SNMP agent won't allow such a user to be made active.
             */
            setup_oid(usmUserStatus, &name_length,
                      usmUserEngineID, usmUserEngineIDLen, argv[arg-1]);
            longvar = RS_CREATEANDWAIT;
            snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                                  ASN_INTEGER, (u_char *) & longvar,
                                  sizeof(longvar));
        }

    } else if (strcmp(argv[arg], CMD_CLONEFROM_NAME) == 0) {
        /*
         * create:  clone a user from another
         *
         * cloneFrom USER FROM
         */
        if (++arg >= argc) {
            fprintf(stderr,
                    "You must specify the user name to operate on\n");
            usage();
            goto close_session;
        }

        command = CMD_CLONEFROM;
        setup_oid(usmUserStatus, &name_length,
                  usmUserEngineID, usmUserEngineIDLen, argv[arg]);
        longvar = RS_ACTIVE;
        snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                              ASN_INTEGER, (u_char *) & longvar,
                              sizeof(longvar));
        name_length = USM_OID_LEN;
        setup_oid(usmUserCloneFrom, &name_length,
                  usmUserEngineID, usmUserEngineIDLen, argv[arg]);

        if (++arg >= argc) {
            fprintf(stderr,
                    "You must specify the user name to clone from\n");
            usage();
            goto close_session;
        }

        setup_oid(usmUserSecurityName, &name_length2,
                  usmUserEngineID, usmUserEngineIDLen, argv[arg]);
        snmp_pdu_add_variable(pdu, usmUserCloneFrom, name_length,
                              ASN_OBJECT_ID,
                              (u_char *) usmUserSecurityName,
                              sizeof(oid) * name_length2);

    } else if (strcmp(argv[arg], CMD_DELETE_NAME) == 0) {
        /*
         * delete:  delete a user
         *
         * delete USER
         */
        if (++arg >= argc) {
            fprintf(stderr, "You must specify the user name to delete\n");
            goto close_session;
        }

        command = CMD_DELETE;
        setup_oid(usmUserStatus, &name_length,
                  usmUserEngineID, usmUserEngineIDLen, argv[arg]);
        longvar = RS_DESTROY;
        snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                              ASN_INTEGER, (u_char *) & longvar,
                              sizeof(longvar));
    } else if (strcmp(argv[arg], CMD_ACTIVATE_NAME) == 0) {
        /*
         * activate:  activate a user
         *
         * activate USER
         */
        if (++arg >= argc) {
            fprintf(stderr, "You must specify the user name to activate\n");
            goto close_session;
        }

        command = CMD_ACTIVATE;
        setup_oid(usmUserStatus, &name_length,
                  usmUserEngineID, usmUserEngineIDLen, argv[arg]);
        longvar = RS_ACTIVE;
        snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                              ASN_INTEGER, (u_char *) & longvar,
                              sizeof(longvar));
    } else if (strcmp(argv[arg], CMD_DEACTIVATE_NAME) == 0) {
        /*
         * deactivate:  deactivate a user
         *
         * deactivate USER
         */
        if (++arg >= argc) {
            fprintf(stderr, "You must specify the user name to deactivate\n");
            goto close_session;
        }

        command = CMD_DEACTIVATE;
        setup_oid(usmUserStatus, &name_length,
                  usmUserEngineID, usmUserEngineIDLen, argv[arg]);
        longvar = RS_NOTINSERVICE;
        snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                              ASN_INTEGER, (u_char *) & longvar,
                              sizeof(longvar));
#if defined(HAVE_OPENSSL_DH_H) && defined(HAVE_LIBCRYPTO)
    } else if (strcmp(argv[arg], CMD_CHANGEKEY_NAME) == 0) {
        /*
         * change the key of a user if DH is available
         */

        char *passwd_user;
        netsnmp_pdu *dhpdu, *dhresponse = NULL;
        netsnmp_variable_list *vars, *dhvar;
        
        command = CMD_CHANGEKEY;
        name_length = DH_USM_OID_LEN;
        name_length2 = DH_USM_OID_LEN;

        passwd_user = argv[++arg];

        if (doprivkey == 0 && doauthkey == 0)
            doprivkey = doauthkey = 1;

        /* 
         * Change the user supplied on command line.
         */
        if ((passwd_user != NULL) && (strlen(passwd_user) > 0)) {
            session.securityName = passwd_user;
        } else {
            /*
             * Use own key object if no user was supplied.
             */
            dhauthKeyChange = usmDHUserOwnAuthKeyChange;
            dhprivKeyChange = usmDHUserOwnPrivKeyChange;
        }

        /*
         * do we have a securityName?  If not, copy the default 
         */
        if (session.securityName == NULL) {
            session.securityName = 
	      strdup(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
					   NETSNMP_DS_LIB_SECNAME));
        }

        /* fetch the needed diffie helman parameters */
        dhpdu = snmp_pdu_create(SNMP_MSG_GET);
        if (!dhpdu) {
            fprintf(stderr, "Failed to create DH request\n");
            goto close_session;
        }

        /* get the current DH parameters */
        snmp_add_null_var(dhpdu, usmDHParameters, usmDHParameters_len);
        
        /* maybe the auth key public value */
        if (doauthkey) {
            setup_oid(dhauthKeyChange, &name_length,
                      usmUserEngineID, usmUserEngineIDLen,
                      session.securityName);
            snmp_add_null_var(dhpdu, dhauthKeyChange, name_length);
        }
            
        /* maybe the priv key public value */
        if (doprivkey) {
            setup_oid(dhprivKeyChange, &name_length2,
                      usmUserEngineID, usmUserEngineIDLen,
                      session.securityName);
            snmp_add_null_var(dhpdu, dhprivKeyChange, name_length2);
        }

        /* fetch the values */
        status = snmp_synch_response(ss, dhpdu, &dhresponse);

        if (status != SNMPERR_SUCCESS || dhresponse == NULL ||
            dhresponse->errstat != SNMP_ERR_NOERROR ||
            dhresponse->variables->type != ASN_OCTET_STR) {
            snmp_sess_perror("snmpusm", ss);
            if (dhresponse && dhresponse->variables &&
                dhresponse->variables->type != ASN_OCTET_STR) {
                fprintf(stderr,
                        "Can't get diffie-helman exchange from the agent\n");
                fprintf(stderr,
                        "  (maybe it doesn't support the SNMP-USM-DH-OBJECTS-MIB MIB)\n");
            }
            exitval = 1;
            goto begone;
        }
        
        dhvar = dhresponse->variables;
        vars = dhvar->next_variable;
        /* complete the DH equation & print resulting keys */
        if (doauthkey) {
            if (get_USM_DH_key(vars, dhvar,
                               sc_get_properlength(ss->securityAuthProto,
                                                   ss->securityAuthProtoLen),
                               pdu, "auth",
                               dhauthKeyChange, name_length) != SNMPERR_SUCCESS)
                goto begone;
            vars = vars->next_variable;
        }
        if (doprivkey) {
            size_t dhprivKeyLen = 0;
            int privtype = sc_get_privtype(ss->securityPrivProto,
                                           ss->securityPrivProtoLen);
            dhprivKeyLen = sc_get_proper_priv_length_bytype(privtype);
            if (USM_CREATE_USER_PRIV_DES == privtype)
                dhprivKeyLen *= 2; /* ?? we store salt with key */
            if (get_USM_DH_key(vars, dhvar,
                               dhprivKeyLen,
                               pdu, "priv",
                               dhprivKeyChange, name_length2)
                != SNMPERR_SUCCESS)
                goto begone;
            vars = vars->next_variable;
        }
        /* snmp_free_pdu(dhresponse); */ /* parts still in use somewhere */
#endif /* HAVE_OPENSSL_DH_H && HAVE_LIBCRYPTO */
    } else {
        fprintf(stderr, "Unknown command\n");
        usage();
        goto close_session;
    }

    /*
     * add usmUserPublic if specified (via -Cp)
     */
    if (usmUserPublic_val) {
        name_length = USM_OID_LEN;
	setup_oid(usmUserPublic, &name_length,
		  usmUserEngineID, usmUserEngineIDLen,
		  session.securityName);
	snmp_pdu_add_variable(pdu, usmUserPublic, name_length,
			      ASN_OCTET_STR, usmUserPublic_val, 
			      strlen(usmUserPublic_val));	  
    }

    /*
     * do the request 
     */
    status = snmp_synch_response(ss, pdu, &response);
    if (status == STAT_SUCCESS) {
        if (response) {
            if (response->errstat == SNMP_ERR_NOERROR) {
                fprintf(stdout, "%s\n", successNotes[command - 1]);
            } else {
                fprintf(stderr, "Error in packet.\nReason: %s\n",
                        snmp_errstring(response->errstat));
                if (response->errindex != 0) {
                    int             count;
                    netsnmp_variable_list *vars;
                    fprintf(stderr, "Failed object: ");
                    for (count = 1, vars = response->variables;
                         vars && count != response->errindex;
                         vars = vars->next_variable, count++)
                        /*EMPTY*/;
                    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("snmpset", ss);
        exitval = 1;
    }

    exitval = 0;
#if defined(HAVE_OPENSSL_DH_H) && defined(HAVE_LIBCRYPTO)
  begone:
#endif /* HAVE_OPENSSL_DH_H && HAVE_LIBCRYPTO */
    if (response)
        snmp_free_pdu(response);

close_session:
    snmp_close(ss);

out:
    SOCK_CLEANUP;
    return exitval;
}
示例#10
0
gchar *
snmp_probe(gchar *peer, gint port, gchar *community)
{
    oid sysDescr[MAX_OID_LEN];
    size_t sysDescr_length;
    oid sysObjectID[MAX_OID_LEN];
    size_t sysObjectID_length;
    oid sysUpTime[MAX_OID_LEN];
    size_t sysUpTime_length;
    oid sysContact[MAX_OID_LEN];
    size_t sysContact_length;
    oid sysName[MAX_OID_LEN];
    size_t sysName_length;
    oid sysLocation[MAX_OID_LEN];
    size_t sysLocation_length;

    struct snmp_session session, *ss;
    struct snmp_pdu *pdu, *response;
    struct variable_list *vars;

    int count;
    int status;

    char textbuf[1024]; 
    char *result = NULL;
    char *tmp = NULL;

    /* transform interesting OIDs */
    sysDescr_length = MAX_OID_LEN;
    if (!snmp_parse_oid("system.sysDescr.0", sysDescr, &sysDescr_length))
	    printf("error parsing oid: system.sysDescr.0\n");

    sysObjectID_length = MAX_OID_LEN;
    if (!snmp_parse_oid("system.sysObjectID.0", sysObjectID, &sysObjectID_length))
	    printf("error parsing oid: system.sysObjectID.0\n");

    sysUpTime_length = MAX_OID_LEN;
    if (!snmp_parse_oid("system.sysUpTime.0", sysUpTime, &sysUpTime_length))
	    printf("error parsing oid: system.sysUpTime.0\n");

    sysContact_length = MAX_OID_LEN;
    if (!snmp_parse_oid("system.sysContact.0", sysContact, &sysContact_length))
	    printf("error parsing oid: system.sysContact.0\n");

    sysName_length = MAX_OID_LEN;
    if (!snmp_parse_oid("system.sysName.0", sysName, &sysName_length))
	    printf("error parsing oid: system.sysName.0\n");

    sysLocation_length = MAX_OID_LEN;
    if (!snmp_parse_oid("system.sysLocation.0", sysLocation, &sysLocation_length))
	    printf("error parsing oid: system.sysLocation.0\n");

    /* initialize session to default values */
    snmp_sess_init( &session );

    session.version = SNMP_VERSION_1;
    session.community = community;
    session.community_len = strlen(community);
    session.peername = peer;

#ifdef STREAM
    session.flags |= SNMP_FLAGS_STREAM_SOCKET;
    fprintf (stderr, "local port set to: %d\n", session.local_port);
#endif

    /* 
     * Open an SNMP session.
     */
    ss = snmp_open(&session);
    if (ss == NULL){
      fprintf (stderr, "local port set to: %d\n", session.local_port);
      snmp_sess_perror("snmp_open", &session);
      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, sysDescr, sysDescr_length);
    snmp_add_null_var(pdu, sysObjectID, sysObjectID_length);
    snmp_add_null_var(pdu, sysUpTime, sysUpTime_length);
    snmp_add_null_var(pdu, sysContact, sysContact_length);
    snmp_add_null_var(pdu, sysName, sysName_length);
    snmp_add_null_var(pdu, sysLocation, sysLocation_length);

    /* 
     * Perform the request.
     *
     * If the Get Request fails, note the OID that caused the error,
     * "fix" the PDU (removing the error-prone OID) and retry.
     */
retry:
    status = snmp_synch_response(ss, pdu, &response);
    if (status == STAT_SUCCESS){
      if (response->errstat == SNMP_ERR_NOERROR){
        /* just render all vars */
        for(vars = response->variables; vars; vars = vars->next_variable) {
	    snprint_variable(textbuf, 1023, vars->name, vars->name_length, vars);
	    textbuf[1023] = '\0';
	    if (result) {
	        tmp = result;
		result = g_strdup_printf("%s\n%s\n", tmp, textbuf);
		g_free(tmp);
	    } else {
		result = g_strdup_printf("%s\n", textbuf);
	    }
	}
                              
      } else {
        fprintf(stderr, "Error in packet\nReason: %s\n",
                snmp_errstring(response->errstat));

        if (response->errstat == SNMP_ERR_NOSUCHNAME){
          fprintf(stderr, "This name doesn't exist: ");
          for(count = 1, vars = response->variables; 
                vars && count != response->errindex;
                vars = vars->next_variable, count++)
            /*EMPTY*/ ;
          if (vars)
            fprint_objid(stderr, vars->name, vars->name_length);
          fprintf(stderr, "\n");
        }

        /* retry if the errored variable was successfully removed */
        pdu = snmp_fix_pdu(response, SNMP_MSG_GET);
        snmp_free_pdu(response);
        response = NULL;
        if (pdu != NULL)
          goto retry;

      }  /* endif -- SNMP_ERR_NOERROR */

    } else if (status == STAT_TIMEOUT){
        snmp_close(ss);
        return g_strdup_printf("Timeout: No Response from %s.\n", session.peername);

    } else {    /* status == STAT_ERROR */
      fprintf (stderr, "local port set to: %d\n", session.local_port);
      snmp_sess_perror("STAT_ERROR", ss);
      snmp_close(ss);
      return NULL;

    }  /* endif -- STAT_SUCCESS */

    if (response)
      snmp_free_pdu(response);
    snmp_close(ss);

    return result;
}
示例#11
0
文件: snmpget.c 项目: Einheri/wl500g
int main(int argc, char *argv[])
{
    struct snmp_session session, *ss;
    struct snmp_pdu *pdu;
    struct snmp_pdu *response;
    struct variable_list *vars;
    int arg;
    int count;
    int current_name = 0;
    char *names[128];
    oid name[MAX_OID_LEN];
    int name_length;
    int status;

    /* get the common command line arguments */
    arg = snmp_parse_args(argc, argv, &session);

    /* get the object names */
    for(; arg < argc; arg++)
      names[current_name++] = argv[arg];
    
    SOCK_STARTUP;

    /* open an SNMP session */
    snmp_synch_setup(&session);
    ss = snmp_open(&session);
    if (ss == NULL){
      snmp_perror("snmpget");
      SOCK_CLEANUP;
      exit(1);
    }

    /* create PDU for GET request and add object names to request */
    pdu = snmp_pdu_create(SNMP_MSG_GET);
    for(count = 0; count < current_name; count++){
      name_length = MAX_OID_LEN;
      if (!snmp_parse_oid(names[count], name, &name_length)) {
        fprintf(stderr, "Invalid object identifier: %s\n", names[count]);
        failures++;
      } else
        snmp_add_null_var(pdu, name, name_length);
    }
    if (failures) {
      SOCK_CLEANUP;
      exit(1);
    }

    /* 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)
          print_variable(vars->name, vars->name_length, vars);
      } else {
        fprintf(stderr, "Error in packet\nReason: %s\n",
                snmp_errstring(response->errstat));
        if (response->errstat == SNMP_ERR_NOSUCHNAME){
          fprintf(stderr, "This name doesn't exist: ");
          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");
        }
        if ((pdu = snmp_fix_pdu(response, SNMP_MSG_GET)) != NULL)
          goto retry;
      }
    } else if (status == STAT_TIMEOUT){
	fprintf(stderr,"Timeout: No Response from %s.\n", session.peername);
	snmp_close(ss);
	SOCK_CLEANUP;
	exit(1);
    } else {    /* status == STAT_ERROR */
      snmp_perror("snmpget");
      snmp_close(ss);
      SOCK_CLEANUP;
      exit(1);
    }

    if (response)
      snmp_free_pdu(response);
    snmp_close(ss);
    SOCK_CLEANUP;
    exit (0);
}
示例#12
0
int
main(int argc, char *argv[])
{
    netsnmp_session session, *ss;
    netsnmp_pdu    *pdu, *response;
    netsnmp_variable_list *vars;
    int             arg;
    char           *gateway;

    int             count;
    struct varInfo *vip;
    u_int           value = 0;
    struct counter64 c64value;
    float           printvalue;
    time_t          last_time = 0;
    time_t          this_time;
    time_t          delta_time;
    int             sum;        /* what the heck is this for, its never used? */
    char            filename[128] = { 0 };
    struct timeval  tv;
    struct tm       tm;
    char            timestring[64] = { 0 }, valueStr[64] = {
    0}, maxStr[64] = {
    0};
    char            outstr[256] = { 0 }, peakStr[64] = {
    0};
    int             status;
    int             begin, end, last_end;
    int             print = 1;
    int             exit_code = 1;

    SOCK_STARTUP;

    switch (arg = snmp_parse_args(argc, argv, &session, "C:", &optProc)) {
    case NETSNMP_PARSE_ARGS_ERROR:
        goto out;
    case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
        exit_code = 0;
        goto out;
    case NETSNMP_PARSE_ARGS_ERROR_USAGE:
        usage();
        goto out;
    default:
        break;
    }

    gateway = session.peername;

    for (; optind < argc; optind++) {
	if (current_name >= MAX_ARGS) {
	    fprintf(stderr, "%s: Too many variables specified (max %d)\n",
	    	argv[optind], MAX_ARGS);
	    goto out;
	}
        varinfo[current_name++].name = argv[optind];
    }

    if (current_name == 0) {
        usage();
        goto out;
    }

    if (dosum) {
	if (current_name >= MAX_ARGS) {
	    fprintf(stderr, "Too many variables specified (max %d)\n",
	    	MAX_ARGS);
	    goto out;
	}
        varinfo[current_name++].name = NULL;
    }

    /*
     * open an SNMP session 
     */
    ss = snmp_open(&session);
    if (ss == NULL) {
        /*
         * diagnose snmp_open errors with the input netsnmp_session pointer 
         */
        snmp_sess_perror("snmpdelta", &session);
        goto out;
    }

    if (tableForm && timestamp) {
        printf("%s", gateway);
    }
    for (count = 0; count < current_name; count++) {
        vip = varinfo + count;
        if (vip->name) {
            vip->oidlen = MAX_OID_LEN;
            vip->info_oid = (oid *) malloc(sizeof(oid) * vip->oidlen);
            if (snmp_parse_oid(vip->name, vip->info_oid, &vip->oidlen) ==
                NULL) {
                snmp_perror(vip->name);
                goto close_session;
            }
            sprint_descriptor(vip->descriptor, vip);
            if (tableForm)
                printf("\t%s", vip->descriptor);
        } else {
            vip->oidlen = 0;
            strlcpy(vip->descriptor, SumFile, sizeof(vip->descriptor));
        }
        vip->value = 0;
        zeroU64(&vip->c64value);
        vip->time = 0;
        vip->max = 0;
        if (peaks) {
            vip->peak_count = -1;
            vip->peak = 0;
            vip->peak_average = 0;
        }
    }

    wait_for_period(period);

    end = current_name;
    sum = 0;
    while (1) {
        pdu = snmp_pdu_create(SNMP_MSG_GET);

        if (deltat)
            snmp_add_null_var(pdu, sysUpTimeOid, sysUpTimeLen);

        if (end == current_name)
            count = 0;
        else
            count = end;
        begin = count;
        for (; count < current_name
             && count < begin + varbindsPerPacket - deltat; count++) {
            if (varinfo[count].oidlen)
                snmp_add_null_var(pdu, varinfo[count].info_oid,
                                  varinfo[count].oidlen);
        }
        last_end = end;
        end = count;

      retry:
        status = snmp_synch_response(ss, pdu, &response);
        if (status == STAT_SUCCESS) {
            if (response->errstat == SNMP_ERR_NOERROR) {
                if (timestamp) {
                    gettimeofday(&tv, (struct timezone *) 0);
                    memcpy(&tm, localtime((time_t *) & tv.tv_sec),
                           sizeof(tm));
                    if (((period % 60)
                         && (!peaks || ((period * peaks) % 60)))
                        || keepSeconds)
                        sprintf(timestring, " [%02d:%02d:%02d %d/%d]",
                                tm.tm_hour, tm.tm_min, tm.tm_sec,
                                tm.tm_mon + 1, tm.tm_mday);
                    else
                        sprintf(timestring, " [%02d:%02d %d/%d]",
                                tm.tm_hour, tm.tm_min,
                                tm.tm_mon + 1, tm.tm_mday);
                }

                vars = response->variables;
                if (deltat) {
                    if (!vars || !vars->val.integer) {
                        fprintf(stderr, "Missing variable in reply\n");
                        continue;
                    } else {
                        this_time = *(vars->val.integer);
                    }
                    vars = vars->next_variable;
                } else {
                    this_time = 1;
                }

                for (count = begin; count < end; count++) {
                    vip = varinfo + count;

                    if (vip->oidlen) {
                        if (!vars || !vars->val.integer) {
                            fprintf(stderr, "Missing variable in reply\n");
                            break;
                        }
                        vip->type = vars->type;
                        if (vars->type == ASN_COUNTER64) {
                            u64Subtract(vars->val.counter64,
                                        &vip->c64value, &c64value);
                            memcpy(&vip->c64value, vars->val.counter64,
                                   sizeof(struct counter64));
                        } else {
                            value = *(vars->val.integer) - vip->value;
                            vip->value = *(vars->val.integer);
                        }
                        vars = vars->next_variable;
                    } else {
                        value = sum;
                        sum = 0;
                    }
                    delta_time = this_time - vip->time;
                    if (delta_time <= 0)
                        delta_time = 100;
                    last_time = vip->time;
                    vip->time = this_time;
                    if (last_time == 0)
                        continue;

                    if (vip->oidlen && vip->type != ASN_COUNTER64) {
                        sum += value;
                    }

                    if (tableForm) {
                        if (count == begin) {
                            sprintf(outstr, "%s", timestring + 1);
                        } else {
                            outstr[0] = '\0';
                        }
                    } else {
                        sprintf(outstr, "%s %s", timestring,
                                vip->descriptor);
                    }

                    if (deltat || tableForm) {
                        if (vip->type == ASN_COUNTER64) {
                            fprintf(stderr,
                                    "time delta and table form not supported for counter64s\n");
                            goto close_session;
                        } else {
                            printvalue =
                                ((float) value * 100) / delta_time;
                            if (tableForm)
                                sprintf(valueStr, "\t%.2f", printvalue);
                            else
                                sprintf(valueStr, " /sec: %.2f",
                                        printvalue);
                        }
                    } else {
                        printvalue = (float) value;
                        sprintf(valueStr, " /%d sec: ", period);
                        if (vip->type == ASN_COUNTER64)
                            printU64(valueStr + strlen(valueStr),
                                     &c64value);
                        else
                            sprintf(valueStr + strlen(valueStr), "%u",
                                    value);
                    }

                    if (!peaks) {
                        strcat(outstr, valueStr);
                    } else {
                        print = 0;
                        if (vip->peak_count == -1) {
                            if (wait_for_peak_start(period, peaks) == 0)
                                vip->peak_count = 0;
                        } else {
                            vip->peak_average += printvalue;
                            if (vip->peak < printvalue)
                                vip->peak = printvalue;
                            if (++vip->peak_count == peaks) {
                                if (deltat)
                                    sprintf(peakStr,
                                            " /sec: %.2f	(%d sec Peak: %.2f)",
                                            vip->peak_average /
                                            vip->peak_count, period,
                                            vip->peak);
                                else
                                    sprintf(peakStr,
                                            " /%d sec: %.0f	(%d sec Peak: %.0f)",
                                            period,
                                            vip->peak_average /
                                            vip->peak_count, period,
                                            vip->peak);
                                vip->peak_average = 0;
                                vip->peak = 0;
                                vip->peak_count = 0;
                                print = 1;
                                strcat(outstr, peakStr);
                            }
                        }
                    }

                    if (printmax) {
                        if (printvalue > vip->max) {
                            vip->max = printvalue;
                        }
                        if (deltat)
                            sprintf(maxStr, "	(Max: %.2f)", vip->max);
                        else
                            sprintf(maxStr, "	(Max: %.0f)", vip->max);
                        strcat(outstr, maxStr);
                    }

                    if (print) {
                        if (fileout) {
                            sprintf(filename, "%s-%s", gateway,
                                    vip->descriptor);
                            print_log(filename, outstr + 1);
                        } else {
                            if (tableForm)
                                printf("%s", outstr);
                            else
                                printf("%s\n", outstr + 1);
                            fflush(stdout);
                        }
                    }
                }
                if (end == last_end && tableForm)
                    printf("\n");
            } else {
                if (response->errstat == SNMP_ERR_TOOBIG) {
                    if (response->errindex <= varbindsPerPacket
                        && response->errindex > 0) {
                        varbindsPerPacket = response->errindex - 1;
                    } else {
                        if (varbindsPerPacket > 30)
                            varbindsPerPacket -= 5;
                        else
                            varbindsPerPacket--;
                    }
                    if (varbindsPerPacket <= 0) {
                        exit_code = 5;
                        break;
                    }
                    end = last_end;
                    continue;
                } else 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");
                    /*
                     * Don't exit when OIDs from file are not found on agent
                     * exit_code = 1;
                     * break;
                     */
                } else {
                    fprintf(stderr, "Error in packet: %s\n",
                            snmp_errstring(response->errstat));
                    exit_code = 1;
                    break;
                }

                /*
                 * 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", gateway);
            response = NULL;
            exit_code = 1;
            break;
        } else {                /* status == STAT_ERROR */
            snmp_sess_perror("snmpdelta", ss);
            response = NULL;
            exit_code = 1;
            break;
        }

        if (response)
            snmp_free_pdu(response);
        if (end == current_name) {
            wait_for_period(period);
        }
    }

    exit_code = 0;

close_session:
    snmp_close(ss);

out:
    SOCK_CLEANUP;
    return (exit_code);
}
示例#13
0
文件: snmpvacm.c 项目: 274914765/C
int main (int argc, char *argv[])
{
    netsnmp_session session, *ss;

    netsnmp_pdu *pdu = NULL, *response = NULL;

#ifdef notused
    netsnmp_variable_list *vars;
#endif

    int arg;

#ifdef notused
    int count;

    int current_name = 0;

    int current_type = 0;

    int current_value = 0;

    char *names[128];

    char types[128];

    char *values[128];

    oid name[MAX_OID_LEN];
#endif
    size_t name_length;

    int status;

    int exitval = 0;

    int command = 0;

    long longvar;

    int secModel, secLevel, contextMatch;

    unsigned int val, i = 0;

    char *mask, *groupName, *prefix, *authtype;

    u_char viewMask[VACMSTRINGLEN];

    char *st;


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


    SOCK_STARTUP;

    /*
     * open an SNMP session 
     */
    /*
     * Note:  this wil obtain the engineID needed below 
     */
    ss = snmp_open (&session);
    if (ss == NULL)
    {
        /*
         * diagnose snmp_open errors with the input netsnmp_session pointer 
         */
        snmp_sess_perror ("snmpvacm", &session);
        exit (1);
    }

    /*
     * create PDU for SET request and add object names and values to request 
     */
    pdu = snmp_pdu_create (SNMP_MSG_SET);

    if (arg >= argc)
    {
        fprintf (stderr, "Please specify a operation to perform.\n");
        usage ();
        exit (1);
    }

    if (strcmp (argv[arg], CMD_DELETEVIEW_NAME) == 0)
        /*
         * deleteView: delete a view
         *
         * deleteView NAME SUBTREE
         *
         */
    {
        if (++arg + 2 != argc)
        {
            fprintf (stderr, "You must specify the view to delete\n");
            usage ();
            exit (1);
        }

        command = CMD_DELETEVIEW;
        name_length = VIEW_OID_LEN;
        view_oid (vacmViewTreeFamilyStatus, &name_length, argv[arg], argv[arg + 1]);
        longvar = RS_DESTROY;
        snmp_pdu_add_variable (pdu, vacmViewTreeFamilyStatus, name_length,
                               ASN_INTEGER, (u_char *) & longvar, sizeof (longvar));
    }
    else if (strcmp (argv[arg], CMD_CREATEVIEW_NAME) == 0)
        /*
         * createView: create a view
         *
         * createView NAME SUBTREE MASK
         *
         */
    {
        if (++arg + 2 > argc)
        {
            fprintf (stderr, "You must specify name, subtree and mask\n");
            usage ();
            exit (1);
        }
        command = CMD_CREATEVIEW;
        name_length = VIEW_OID_LEN;
        view_oid (vacmViewTreeFamilyStatus, &name_length, argv[arg], argv[arg + 1]);
        longvar = RS_CREATEANDGO;
        snmp_pdu_add_variable (pdu, vacmViewTreeFamilyStatus, name_length,
                               ASN_INTEGER, (u_char *) & longvar, sizeof (longvar));
        /*
         * Mask
         */
        if (arg + 3 == argc)
        {
            mask = argv[arg + 2];
            for (mask = strtok_r (mask, ".:", &st); mask; mask = strtok_r (NULL, ".:", &st))
            {
                if (i >= sizeof (viewMask))
                {
                    printf ("MASK too long\n");
                    exit (1);
                }
                if (sscanf (mask, "%x", &val) == 0)
                {
                    printf ("invalid MASK\n");
                    exit (1);
                }
                viewMask[i] = val;
                i++;
            }
        }
        else
        {
            for (i = 0; i < (name_length + 7) / 8; i++)
                viewMask[i] = (u_char) 0xff;
        }
        view_oid (vacmViewTreeFamilyMask, &name_length, argv[arg], argv[arg + 1]);
        snmp_pdu_add_variable (pdu, vacmViewTreeFamilyMask, name_length, ASN_OCTET_STR, viewMask, i);

        view_oid (vacmViewTreeFamilyType, &name_length, argv[arg], argv[arg + 1]);
        snmp_pdu_add_variable (pdu, vacmViewTreeFamilyType, name_length,
                               ASN_INTEGER, (u_char *) & viewTreeFamilyType, sizeof (viewTreeFamilyType));

    }
    else if (strcmp (argv[arg], CMD_DELETESEC2GROUP_NAME) == 0)
        /*
         * deleteSec2Group: delete security2group
         *
         * deleteSec2Group  MODEL SECURITYNAME
         *
         */
    {
        if (++arg + 2 != argc)
        {
            fprintf (stderr, "You must specify the sec2group to delete\n");
            usage ();
            exit (1);
        }

        command = CMD_DELETESEC2GROUP;
        name_length = SEC2GROUP_OID_LEN;
        if (sscanf (argv[arg], "%d", &secModel) == 0)
        {
            printf ("invalid security model\n");
            usage ();
            exit (1);
        }
        sec2group_oid (vacmSec2GroupStatus, &name_length, secModel, argv[arg + 1]);
        longvar = RS_DESTROY;
        snmp_pdu_add_variable (pdu, vacmSec2GroupStatus, name_length,
                               ASN_INTEGER, (u_char *) & longvar, sizeof (longvar));
    }
    else if (strcmp (argv[arg], CMD_CREATESEC2GROUP_NAME) == 0)
        /*
         * createSec2Group: create a security2group
         *
         * createSec2Group  MODEL SECURITYNAME GROUPNAME
         *
         */
    {
        if (++arg + 3 != argc)
        {
            fprintf (stderr, "You must specify model, security name and group name\n");
            usage ();
            exit (1);
        }

        command = CMD_CREATESEC2GROUP;
        name_length = SEC2GROUP_OID_LEN;
        if (sscanf (argv[arg], "%d", &secModel) == 0)
        {
            printf ("invalid security model\n");
            usage ();
            exit (1);
        }
        sec2group_oid (vacmSec2GroupStatus, &name_length, secModel, argv[arg + 1]);
        longvar = RS_CREATEANDGO;
        snmp_pdu_add_variable (pdu, vacmSec2GroupStatus, name_length,
                               ASN_INTEGER, (u_char *) & longvar, sizeof (longvar));
        sec2group_oid (vacmGroupName, &name_length, secModel, argv[arg + 1]);
        snmp_pdu_add_variable (pdu, vacmGroupName, name_length,
                               ASN_OCTET_STR, (u_char *) argv[arg + 2], strlen (argv[arg + 2]));
    }
    else if (strcmp (argv[arg], CMD_DELETEACCESS_NAME) == 0)
        /*
         * deleteAccess: delete access entry
         *
         * deleteAccess  GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL
         *
         */
    {
        if (++arg + 3 > argc)
        {
            fprintf (stderr, "You must specify the access entry to delete\n");
            usage ();
            exit (1);
        }

        command = CMD_DELETEACCESS;
        name_length = ACCESS_OID_LEN;
        groupName = argv[arg];
        if (arg + 4 == argc)
            prefix = argv[++arg];
        else
            prefix = NULL;

        if (sscanf (argv[arg + 1], "%d", &secModel) == 0)
        {
            printf ("invalid security model\n");
            usage ();
            exit (1);
        }
        if (sscanf (argv[arg + 2], "%d", &secLevel) == 0)
        {
            printf ("invalid security level\n");
            usage ();
            exit (1);
        }
        access_oid (vacmAccessStatus, &name_length, groupName, prefix, secModel, secLevel);
        longvar = RS_DESTROY;
        snmp_pdu_add_variable (pdu, vacmAccessStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof (longvar));
    }
    else if (strcmp (argv[arg], CMD_CREATEACCESS_NAME) == 0)
        /*
         * createAccess: create access entry
         *
         * createAccess  GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL CONTEXTMATCH READVIEWNAME WRITEVIEWNAME NOTIFYVIEWNAME
         *
         */
    {
        if (++arg + 7 > argc)
        {
            fprintf (stderr, "You must specify the access entry to create\n");
            usage ();
            exit (1);
        }

        command = CMD_CREATEACCESS;
        name_length = ACCESS_OID_LEN;
        groupName = argv[arg];
        if (arg + 8 == argc)
            prefix = argv[++arg];
        else
            prefix = NULL;

        if (sscanf (argv[arg + 1], "%d", &secModel) == 0)
        {
            printf ("invalid security model\n");
            usage ();
            exit (1);
        }
        if (sscanf (argv[arg + 2], "%d", &secLevel) == 0)
        {
            printf ("invalid security level\n");
            usage ();
            exit (1);
        }
        access_oid (vacmAccessStatus, &name_length, groupName, prefix, secModel, secLevel);
        longvar = RS_CREATEANDGO;
        snmp_pdu_add_variable (pdu, vacmAccessStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof (longvar));

        access_oid (vacmAccessContextMatch, &name_length, groupName, prefix, secModel, secLevel);
        if (sscanf (argv[arg + 3], "%d", &contextMatch) == 0)
        {
            printf ("invalid contextMatch\n");
            usage ();
            exit (1);
        }
        snmp_pdu_add_variable (pdu, vacmAccessContextMatch, name_length,
                               ASN_INTEGER, (u_char *) & contextMatch, sizeof (contextMatch));

        access_oid (vacmAccessReadViewName, &name_length, groupName, prefix, secModel, secLevel);
        snmp_pdu_add_variable (pdu, vacmAccessReadViewName, name_length,
                               ASN_OCTET_STR, (u_char *) argv[arg + 4], strlen (argv[arg + 4]));

        access_oid (vacmAccessWriteViewName, &name_length, groupName, prefix, secModel, secLevel);
        snmp_pdu_add_variable (pdu, vacmAccessWriteViewName, name_length,
                               ASN_OCTET_STR, (u_char *) argv[arg + 5], strlen (argv[arg + 5]));

        access_oid (vacmAccessNotifyViewName, &name_length, groupName, prefix, secModel, secLevel);
        snmp_pdu_add_variable (pdu, vacmAccessNotifyViewName, name_length,
                               ASN_OCTET_STR, (u_char *) argv[arg + 6], strlen (argv[arg + 6]));
    }
    else if (strcmp (argv[arg], CMD_DELETEAUTH_NAME) == 0)
        /*
         * deleteAuth: delete authAccess entry
         *
         * deleteAuth  GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL AUTHTYPE
         *
         */
    {
        if (++arg + 4 > argc)
        {
            fprintf (stderr, "You must specify the authAccess entry to delete\n");
            usage ();
            exit (1);
        }

        command = CMD_DELETEAUTH;
        name_length = AUTH_OID_LEN;
        groupName = argv[arg];
        if (arg + 5 == argc)
            prefix = argv[++arg];
        else
            prefix = NULL;

        if (sscanf (argv[arg + 1], "%d", &secModel) == 0)
        {
            printf ("invalid security model\n");
            usage ();
            exit (1);
        }
        if (sscanf (argv[arg + 2], "%d", &secLevel) == 0)
        {
            printf ("invalid security level\n");
            usage ();
            exit (1);
        }
        authtype = argv[arg + 3];
        auth_oid (nsVacmRowStatus, &name_length, groupName, prefix, secModel, secLevel, authtype);
        longvar = RS_DESTROY;
        snmp_pdu_add_variable (pdu, nsVacmRowStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof (longvar));
    }
    else if (strcmp (argv[arg], CMD_CREATEAUTH_NAME) == 0)
        /*
         * createAuth: create authAccess entry
         *
         * createAuth  GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL AUTHTYPE CONTEXTMATCH VIEWNAME
         *
         */
    {
        if (++arg + 6 > argc)
        {
            fprintf (stderr, "You must specify the authAccess entry to create\n");
            usage ();
            exit (1);
        }

        command = CMD_CREATEAUTH;
        name_length = AUTH_OID_LEN;
        groupName = argv[arg];
        if (arg + 7 == argc)
            prefix = argv[++arg];
        else
            prefix = NULL;

        if (sscanf (argv[arg + 1], "%d", &secModel) == 0)
        {
            printf ("invalid security model\n");
            usage ();
            exit (1);
        }
        if (sscanf (argv[arg + 2], "%d", &secLevel) == 0)
        {
            printf ("invalid security level\n");
            usage ();
            exit (1);
        }
        authtype = argv[arg + 3];
        auth_oid (nsVacmRowStatus, &name_length, groupName, prefix, secModel, secLevel, authtype);
        longvar = RS_CREATEANDGO;
        snmp_pdu_add_variable (pdu, nsVacmRowStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof (longvar));

        auth_oid (nsVacmContextPfx, &name_length, groupName, prefix, secModel, secLevel, authtype);
        if (sscanf (argv[arg + 4], "%d", &contextMatch) == 0)
        {
            printf ("invalid contextMatch\n");
            usage ();
            exit (1);
        }
        snmp_pdu_add_variable (pdu, nsVacmContextPfx, name_length,
                               ASN_INTEGER, (u_char *) & contextMatch, sizeof (contextMatch));

        auth_oid (nsVacmViewName, &name_length, groupName, prefix, secModel, secLevel, authtype);
        snmp_pdu_add_variable (pdu, nsVacmViewName, name_length,
                               ASN_OCTET_STR, (u_char *) argv[arg + 5], strlen (argv[arg + 5]));
    }
    else
    {
        printf ("Unknown command\n");
        usage ();
        exit (1);
    }

    /*
     * do the request 
     */
    status = snmp_synch_response (ss, pdu, &response);
    if (status == STAT_SUCCESS)
    {
        if (response)
        {
            if (response->errstat == SNMP_ERR_NOERROR)
            {
                fprintf (stderr, "%s\n", successNotes[command - 1]);
            }
            else
            {
                fprintf (stderr, "Error in packet.\nReason: %s\n", snmp_errstring (response->errstat));
                if (response->errindex != 0)
                {
                    int count;

                    struct variable_list *vars = response->variables;

                    fprintf (stderr, "Failed object: ");
                    for (count = 1; 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
    {
        snmp_sess_perror ("snmpset", ss);
        exitval = 1;
    }

    if (response)
        snmp_free_pdu (response);

    snmp_close (ss);
    SOCK_CLEANUP;
    return exitval;
}
示例#14
0
void
getbulk_table_entries(netsnmp_session * ss)
{
    int             running = 1;
    netsnmp_pdu    *pdu, *response;
    netsnmp_variable_list *vars, *last_var;
    int             count;
    int             status;
    int             i;
    int             row, col;
    char           *buf = NULL;
    size_t          buf_len = 0, out_len = 0;
    char           *cp;
    char           *name_p = NULL;
    char          **dp;

    while (running) {
        /*
         * create PDU for GETBULK request and add object name to request 
         */
        pdu = snmp_pdu_create(SNMP_MSG_GETBULK);
        pdu->non_repeaters = 0;
        pdu->max_repetitions = max_getbulk;
        snmp_add_null_var(pdu, name, name_length);

        /*
         * do the request 
         */
        status = snmp_synch_response(ss, pdu, &response);
        if (status == STAT_SUCCESS) {
            if (response->errstat == SNMP_ERR_NOERROR) {
                /*
                 * check resulting variables 
                 */
                vars = response->variables;
                last_var = NULL;
                while (vars) {
                    out_len = 0;
                    sprint_realloc_objid((u_char **)&buf, &buf_len, &out_len, 1,
                                         vars->name, vars->name_length);
                    if (vars->type == SNMP_ENDOFMIBVIEW ||
                        memcmp(vars->name, name,
                               rootlen * sizeof(oid)) != 0) {
                        if (localdebug) {
                            printf("%s => end of table\n",
                                   buf ? (char *) buf : "[NIL]");
                        }
                        running = 0;
                        break;
                    }
                    if (localdebug) {
                        printf("%s => taken\n",
                               buf ? (char *) buf : "[NIL]");
                    }
                    for (col = 0; col < fields; col++)
                        if (column[col].subid == vars->name[rootlen])
                            break;
		    if (col == fields) {
			extra_columns = 1;
			last_var = vars;
			vars = vars->next_variable;
			continue;
		    }
                    if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 
                                              NETSNMP_DS_LIB_EXTENDED_INDEX)) {
                        name_p = strchr(buf, '[');
                    } else {
                        switch (netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
                                                  NETSNMP_DS_LIB_OID_OUTPUT_FORMAT)) {
                        case NETSNMP_OID_OUTPUT_MODULE:
			case 0:
                            name_p = strchr(buf, ':')+1;
                            break;
                        case NETSNMP_OID_OUTPUT_SUFFIX:
                            name_p = buf;
                            break;
                        case NETSNMP_OID_OUTPUT_FULL:
                        case NETSNMP_OID_OUTPUT_NUMERIC:
                        case NETSNMP_OID_OUTPUT_UCD:
                            name_p = buf + strlen(table_name)+1;
                            name_p = strchr(name_p, '.')+1;
                            break;
			default:
			    fprintf(stderr, "Unrecognized -O option: %d\n",
				    netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
					              NETSNMP_DS_LIB_OID_OUTPUT_FORMAT));
			    exit(1);
                        }
                        name_p = strchr(name_p, '.');
                        if ( name_p == NULL ) {
                            /* The 'strchr' call above failed, i.e. the results
                             * don't seem to include instance subidentifiers! */
                            running = 0;
                            break;
                        }
                        name_p++;  /* Move on to the instance identifier */
                    }
                    for (row = 0; row < entries; row++)
                        if (strcmp(name_p, indices[row]) == 0)
                            break;
                    if (row == entries) {
                        entries++;
                        if (entries >= allocated) {
                            if (allocated == 0) {
                                allocated = 10;
                                data =
                                    (char **) malloc(allocated * fields *
                                                     sizeof(char *));
                                memset(data, 0,
                                       allocated * fields *
                                       sizeof(char *));
                                indices =
                                    (char **) malloc(allocated *
                                                     sizeof(char *));
                            } else {
                                allocated += 10;
                                data =
                                    (char **) realloc(data,
                                                      allocated * fields *
                                                      sizeof(char *));
                                memset(data + entries * fields, 0,
                                       (allocated -
                                        entries) * fields *
                                       sizeof(char *));
                                indices =
                                    (char **) realloc(indices,
                                                      allocated *
                                                      sizeof(char *));
                            }
                        }
                        indices[row] = strdup(name_p);
                        i = strlen(name_p);
                        if (i > index_width)
                            index_width = i;
                    }
                    dp = data + row * fields;
                    out_len = 0;
                    sprint_realloc_value((u_char **)&buf, &buf_len, &out_len, 1,
                                         vars->name, vars->name_length,
                                         vars);
                    for (cp = buf; *cp; cp++)
                        if (*cp == '\n')
                            *cp = ' ';
                    dp[col] = buf;
                    i = out_len;
                    buf = NULL;
                    buf_len = 0;
                    if (i > column[col].width)
                        column[col].width = i;
                    last_var = vars;
                    vars = vars->next_variable;
                }
                if (last_var) {
                    name_length = last_var->name_length;
                    memcpy(name, last_var->name,
                           name_length * sizeof(oid));
                }
            } else {
                /*
                 * error in response, print it 
                 */
                running = 0;
                if (response->errstat == SNMP_ERR_NOSUCHNAME) {
                    printf("End of MIB\n");
                } else {
                    fprintf(stderr, "Error in packet.\nReason: %s\n",
                            snmp_errstring(response->errstat));
                    if (response->errstat == SNMP_ERR_NOSUCHNAME) {
                        fprintf(stderr,
                                "The request for this object identifier failed: ");
                        for (count = 1, vars = response->variables;
                             vars && count != response->errindex;
                             vars = vars->next_variable, count++)
                            /*EMPTY*/;
                        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",
                    ss->peername);
            running = 0;
            exitval = 1;
        } else {                /* status == STAT_ERROR */
            snmp_sess_perror("snmptable", ss);
            running = 0;
            exitval = 1;
        }
        if (response)
            snmp_free_pdu(response);
    }
}
示例#15
0
void
get_table_entries(netsnmp_session * ss)
{
    int             running = 1;
    netsnmp_pdu    *pdu, *response;
    netsnmp_variable_list *vars;
    int             count;
    int             status;
    int             i;
    int             col;
    char           *buf = NULL;
    size_t          out_len = 0, buf_len = 0;
    char           *cp;
    char           *name_p = NULL;
    char          **dp;
    int             have_current_index;

    /*
     * TODO:
     *   1) Deal with multiple index fields
     *   2) Deal with variable length index fields
     *   3) optimize to remove a sparse column from get-requests
     */

    while (running &&
           ((max_width && !column_width) || (entries < max_getbulk))) {
        /*
         * create PDU for GETNEXT request and add object name to request 
         */
        pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
        for (i = 1; i <= fields; i++) {
            name[rootlen] = column[i - 1].subid;
            snmp_add_null_var(pdu, name, name_length);
        }

        /*
         * do the request 
         */
        status = snmp_synch_response(ss, pdu, &response);
        if (status == STAT_SUCCESS) {
            if (response->errstat == SNMP_ERR_NOERROR) {
                /*
                 * check resulting variables 
                 */
                vars = response->variables;
                entries++;
                if (entries >= allocated) {
                    if (allocated == 0) {
                        allocated = 10;
                        data =
                            (char **) malloc(allocated * fields *
                                             sizeof(char *));
                        memset(data, 0,
                               allocated * fields * sizeof(char *));
                        if (show_index)
                            indices =
                                (char **) malloc(allocated *
                                                 sizeof(char *));
                    } else {
                        allocated += 10;
                        data =
                            (char **) realloc(data,
                                              allocated * fields *
                                              sizeof(char *));
                        memset(data + entries * fields, 0,
                               (allocated -
                                entries) * fields * sizeof(char *));
                        if (show_index)
                            indices =
                                (char **) realloc(indices,
                                                  allocated *
                                                  sizeof(char *));
                    }
                }
                dp = data + (entries - 1) * fields;
                col = -1;
                end_of_table = 1;       /* assume end of table */
                have_current_index = 0;
                name_length = rootlen + 1;
                for (vars = response->variables; vars;
                     vars = vars->next_variable) {
                    col++;
                    name[rootlen] = column[col].subid;
                    if ((vars->name_length < name_length) ||
                        (vars->name[rootlen] != column[col].subid) ||
                        memcmp(name, vars->name,
                               name_length * sizeof(oid)) != 0
                        || vars->type == SNMP_ENDOFMIBVIEW) {
                        /*
                         * not part of this subtree 
                         */
                        if (localdebug) {
                            fprint_variable(stderr, vars->name,
                                            vars->name_length, vars);
                            fprintf(stderr, " => ignored\n");
                        }
                        continue;
                    }

                    /*
                     * save index off 
                     */
                    if (!have_current_index) {
                        end_of_table = 0;
                        have_current_index = 1;
                        name_length = vars->name_length;
                        memcpy(name, vars->name,
                               name_length * sizeof(oid));
                        out_len = 0;
                        if (!sprint_realloc_objid
                            ((u_char **)&buf, &buf_len, &out_len, 1, vars->name,
                             vars->name_length)) {
                            break;
                        }
                        i = vars->name_length - rootlen + 1;
                        if (localdebug || show_index) {
                            if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 
                                              NETSNMP_DS_LIB_EXTENDED_INDEX)) {
                                name_p = strchr(buf, '[');
                            } else {
                                switch (netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
                                                          NETSNMP_DS_LIB_OID_OUTPUT_FORMAT)) {
                                case NETSNMP_OID_OUTPUT_MODULE:
				case 0:
                                    name_p = strchr(buf, ':');
                                    break;
                                case NETSNMP_OID_OUTPUT_SUFFIX:
                                    name_p = buf;
                                    break;
                                case NETSNMP_OID_OUTPUT_FULL:
                                case NETSNMP_OID_OUTPUT_NUMERIC:
                                case NETSNMP_OID_OUTPUT_UCD:
                                    name_p = buf + strlen(table_name)+1;
                                    name_p = strchr(name_p, '.')+1;
                                    break;
				default:
				    fprintf(stderr, "Unrecognized -O option: %d\n",
					    netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
							      NETSNMP_DS_LIB_OID_OUTPUT_FORMAT));
				    exit(1);
                                }
                                name_p = strchr(name_p, '.') + 1;
                            }
                        }
                        if (localdebug) {
                            printf("Name: %s Index: %s\n", buf, name_p);
                        }
                        if (show_index) {
                            indices[entries - 1] = strdup(name_p);
                            i = strlen(name_p);
                            if (i > index_width)
                                index_width = i;
                        }
                    }

                    if (localdebug && buf) {
                        printf("%s => taken\n", buf);
                    }
                    out_len = 0;
                    sprint_realloc_value((u_char **)&buf, &buf_len, &out_len, 1,
                                         vars->name, vars->name_length,
                                         vars);
                    for (cp = buf; *cp; cp++) {
                        if (*cp == '\n') {
                            *cp = ' ';
                        }
                    }
                    dp[col] = buf;
                    i = out_len;
                    buf = NULL;
                    buf_len = 0;
                    if (i > column[col].width) {
                        column[col].width = i;
                    }
                }

                if (end_of_table) {
                    --entries;
                    /*
                     * not part of this subtree 
                     */
                    if (localdebug) {
                        printf("End of table: %s\n",
                               buf ? (char *) buf : "[NIL]");
                    }
                    running = 0;
                    continue;
                }
            } else {
                /*
                 * error in response, print it 
                 */
                running = 0;
                if (response->errstat == SNMP_ERR_NOSUCHNAME) {
                    printf("End of MIB\n");
                    end_of_table = 1;
                } 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++)
                            /*EMPTY*/;
                        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",
                    ss->peername);
            running = 0;
            exitval = 1;
        } else {                /* status == STAT_ERROR */
            snmp_sess_perror("snmptable", ss);
            running = 0;
            exitval = 1;
        }
        if (response)
            snmp_free_pdu(response);
    }
}
示例#16
0
int
main(int argc, char *argv[])
{
    netsnmp_session session, *ss;
    netsnmp_pdu    *pdu = NULL, *response = NULL;
#ifdef notused
    netsnmp_variable_list *vars;
#endif

    int             arg;
#ifdef notused
    int             count;
    int             current_name = 0;
    int             current_type = 0;
    int             current_value = 0;
    char           *names[128];
    char            types[128];
    char           *values[128];
    oid             name[MAX_OID_LEN];
#endif
    size_t          name_length = USM_OID_LEN;
    size_t          name_length2 = USM_OID_LEN;
    int             status;
    int             exitval = 0;
    int             rval;
    int             command = 0;
    long            longvar;

    size_t          oldKu_len = SNMP_MAXBUF_SMALL,
        newKu_len = SNMP_MAXBUF_SMALL,
        oldkul_len = SNMP_MAXBUF_SMALL,
        newkul_len = SNMP_MAXBUF_SMALL, keychange_len = SNMP_MAXBUF_SMALL;

    char           *newpass = NULL, *oldpass = NULL;
    u_char          oldKu[SNMP_MAXBUF_SMALL],
        newKu[SNMP_MAXBUF_SMALL],
        oldkul[SNMP_MAXBUF_SMALL],
        newkul[SNMP_MAXBUF_SMALL], keychange[SNMP_MAXBUF_SMALL];

    authKeyChange = authKeyOid;
    privKeyChange = privKeyOid;

    /*
     * get the common command line arguments 
     */
    switch (arg = 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 
     */
    /*
     * Note:  this wil obtain the engineID needed below 
     */
    ss = snmp_open(&session);
    if (ss == NULL) {
        /*
         * diagnose snmp_open errors with the input netsnmp_session pointer 
         */
        snmp_sess_perror("snmpusm", &session);
        exit(1);
    }

    /*
     * create PDU for SET request and add object names and values to request 
     */
    pdu = snmp_pdu_create(SNMP_MSG_SET);

    if (arg >= argc) {
        fprintf(stderr, "Please specify a operation to perform.\n");
        usage();
        exit(1);
    }

    if (strcmp(argv[arg], CMD_PASSWD_NAME) == 0) {

        /*
         * passwd: change a users password.
         *
         * XXX:  Uses the auth type of the calling user, a MD5 user can't
         *       change a SHA user's key.
         */
        command = CMD_PASSWD;
        oldpass = argv[++arg];
        newpass = argv[++arg];

        if (doprivkey == 0 && doauthkey == 0)
            doprivkey = doauthkey = 1;

        if (newpass == NULL || strlen(newpass) < USM_LENGTH_P_MIN) {
            fprintf(stderr,
                    "New passphrase must be greater than %d characters in length.\n",
                    USM_LENGTH_P_MIN);
            exit(1);
        }

        if (oldpass == NULL || strlen(oldpass) < USM_LENGTH_P_MIN) {
            fprintf(stderr,
                    "Old passphrase must be greater than %d characters in length.\n",
                    USM_LENGTH_P_MIN);
            exit(1);
        }

        /*
         * do we have a securityName?  If not, copy the default 
         */
        if (session.securityName == NULL) {
            session.securityName = 
	      strdup(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
					   NETSNMP_DS_LIB_SECNAME));
        }

        /*
         * the old Ku is in the session, but we need the new one 
         */
        if (session.securityAuthProto == NULL) {
            /*
             * get .conf set default 
             */
            const oid      *def =
                get_default_authtype(&session.securityAuthProtoLen);
            session.securityAuthProto =
                snmp_duplicate_objid(def, session.securityAuthProtoLen);
        }
        if (session.securityAuthProto == NULL) {
            /*
             * assume MD5 
             */
            session.securityAuthProtoLen =
                sizeof(usmHMACMD5AuthProtocol) / sizeof(oid);
            session.securityAuthProto =
                snmp_duplicate_objid(usmHMACMD5AuthProtocol,
                                     session.securityAuthProtoLen);
        }
        rval = generate_Ku(session.securityAuthProto,
                           session.securityAuthProtoLen,
                           (u_char *) newpass, strlen(newpass),
                           newKu, &newKu_len);

        if (rval != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr, "generating the old Ku failed\n");
            exit(1);
        }

        /*
         * the old Ku is in the session, but we need the new one 
         */
        rval = generate_Ku(session.securityAuthProto,
                           session.securityAuthProtoLen,
                           (u_char *) oldpass, strlen(oldpass),
                           oldKu, &oldKu_len);

        if (rval != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr, "generating the new Ku failed\n");
            exit(1);
        }

        /*
         * generate the two Kul's 
         */
        rval = generate_kul(session.securityAuthProto,
                            session.securityAuthProtoLen,
                            ss->contextEngineID, ss->contextEngineIDLen,
                            oldKu, oldKu_len, oldkul, &oldkul_len);

        if (rval != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr, "generating the old Kul failed\n");
            exit(1);
        }

        rval = generate_kul(session.securityAuthProto,
                            session.securityAuthProtoLen,
                            ss->contextEngineID, ss->contextEngineIDLen,
                            newKu, newKu_len, newkul, &newkul_len);

        if (rval != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr, "generating the new Kul failed\n");
            exit(1);
        }

        /*
         * create the keychange string 
         */
        rval = encode_keychange(session.securityAuthProto,
                                session.securityAuthProtoLen,
                                oldkul, oldkul_len,
                                newkul, newkul_len,
                                keychange, &keychange_len);

        if (rval != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr, "encoding the keychange failed\n");
            usage();
            exit(1);
        }

        /*
         * add the keychange string to the outgoing packet 
         */
        if (doauthkey) {
            setup_oid(authKeyChange, &name_length,
                      ss->contextEngineID, ss->contextEngineIDLen,
                      session.securityName);
            snmp_pdu_add_variable(pdu, authKeyChange, name_length,
                                  ASN_OCTET_STR, keychange, keychange_len);
        }
        if (doprivkey) {
            setup_oid(privKeyChange, &name_length,
                      ss->contextEngineID, ss->contextEngineIDLen,
                      session.securityName);
            snmp_pdu_add_variable(pdu, privKeyChange, name_length,
                                  ASN_OCTET_STR, keychange, keychange_len);
        }

    } else if (strcmp(argv[arg], CMD_CREATE_NAME) == 0) {
        /*
         * create:  create a user
         *
         * create USER [CLONEFROM]
         */
        if (++arg >= argc) {
            fprintf(stderr, "You must specify the user name to create\n");
            usage();
            exit(1);
        }

        command = CMD_CREATE;

        if (++arg < argc) {
            /*
             * clone the new user from an existing user
             *   (and make them active immediately)
             */
            setup_oid(usmUserStatus, &name_length,
                      ss->contextEngineID, ss->contextEngineIDLen, argv[arg-1]);
            longvar = RS_CREATEANDGO;
            snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                                  ASN_INTEGER, (u_char *) & longvar,
                                  sizeof(longvar));

            setup_oid(usmUserCloneFrom, &name_length,
                      ss->contextEngineID, ss->contextEngineIDLen,
                      argv[arg - 1]);
            setup_oid(usmUserSecurityName, &name_length2,
                      ss->contextEngineID, ss->contextEngineIDLen,
                      argv[arg]);
            snmp_pdu_add_variable(pdu, usmUserCloneFrom, name_length,
                                  ASN_OBJECT_ID,
                                  (u_char *) usmUserSecurityName,
                                  sizeof(oid) * name_length2);
        } else {
            /*
             * create a new (unauthenticated) user from scratch
             * The Net-SNMP agent won't allow such a user to be made active.
             */
            setup_oid(usmUserStatus, &name_length,
                      ss->contextEngineID, ss->contextEngineIDLen, argv[arg-1]);
            longvar = RS_CREATEANDWAIT;
            snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                                  ASN_INTEGER, (u_char *) & longvar,
                                  sizeof(longvar));
        }

    } else if (strcmp(argv[arg], CMD_CLONEFROM_NAME) == 0) {
        /*
         * create:  clone a user from another
         *
         * cloneFrom USER FROM
         */
        if (++arg >= argc) {
            fprintf(stderr,
                    "You must specify the user name to operate on\n");
            usage();
            exit(1);
        }

        command = CMD_CLONEFROM;
        setup_oid(usmUserStatus, &name_length,
                  ss->contextEngineID, ss->contextEngineIDLen, argv[arg]);
        longvar = RS_ACTIVE;
        snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                              ASN_INTEGER, (u_char *) & longvar,
                              sizeof(longvar));
        setup_oid(usmUserCloneFrom, &name_length,
                  ss->contextEngineID, ss->contextEngineIDLen, argv[arg]);

        if (++arg >= argc) {
            fprintf(stderr,
                    "You must specify the user name to clone from\n");
            usage();
            exit(1);
        }

        setup_oid(usmUserSecurityName, &name_length2,
                  ss->contextEngineID, ss->contextEngineIDLen, argv[arg]);
        snmp_pdu_add_variable(pdu, usmUserCloneFrom, name_length,
                              ASN_OBJECT_ID,
                              (u_char *) usmUserSecurityName,
                              sizeof(oid) * name_length2);

    } else if (strcmp(argv[arg], CMD_DELETE_NAME) == 0) {
        /*
         * delete:  delete a user
         *
         * delete USER
         */
        if (++arg >= argc) {
            fprintf(stderr, "You must specify the user name to delete\n");
            exit(1);
        }

        command = CMD_DELETE;
        setup_oid(usmUserStatus, &name_length,
                  ss->contextEngineID, ss->contextEngineIDLen, argv[arg]);
        longvar = RS_DESTROY;
        snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                              ASN_INTEGER, (u_char *) & longvar,
                              sizeof(longvar));
    } else {
        fprintf(stderr, "Unknown command\n");
        usage();
        exit(1);
    }


    /*
     * do the request 
     */
    status = snmp_synch_response(ss, pdu, &response);
    if (status == STAT_SUCCESS) {
        if (response) {
            if (response->errstat == SNMP_ERR_NOERROR) {
                fprintf(stderr, "%s\n", successNotes[command - 1]);
            } else {
                fprintf(stderr, "Error in packet.\nReason: %s\n",
                        snmp_errstring(response->errstat));
                if (response->errindex != 0) {
                    int             count;
                    netsnmp_variable_list *vars;
                    fprintf(stderr, "Failed object: ");
                    for (count = 1, vars = response->variables;
                         vars && count != response->errindex;
                         vars = vars->next_variable, count++)
                        /*EMPTY*/;
                    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("snmpset", ss);
        exitval = 1;
    }

    if (response)
        snmp_free_pdu(response);
    snmp_close(ss);
    SOCK_CLEANUP;
    return exitval;
}