Exemple #1
0
/*! \fn char *snmp_getnext(host_t *current_host, char *snmp_oid)
 *  \brief performs a single snmp_getnext for a specific snmp OID
 *
 *	This function will poll a specific snmp OID for a host.  The host snmp
 *  session must already be established.
 *
 *  \return returns the character representaton of the snmp OID, or "U" if
 *  unsuccessful.
 *
 */
char *snmp_getnext(host_t *current_host, char *snmp_oid) {
	struct snmp_pdu *pdu       = NULL;
	struct snmp_pdu *response  = NULL;
	struct variable_list *vars = NULL;
	size_t anOID_len           = MAX_OID_LEN;
	oid    anOID[MAX_OID_LEN];
	int    status;
	char   *result_string;

	if (!(result_string = (char *) malloc(RESULTS_BUFFER))) {
		die("ERROR: Fatal malloc error: snmp.c snmp_get!");
	}
	result_string[0] = '\0';

	status           = STAT_DESCRIP_ERROR;

	if (current_host->snmp_session != NULL) {
		anOID_len = MAX_OID_LEN;
		pdu       = snmp_pdu_create(SNMP_MSG_GETNEXT);

		if (!snmp_parse_oid(snmp_oid, anOID, &anOID_len)) {
			SPINE_LOG(("ERROR: Problems parsing SNMP OID\n"));
			SET_UNDEFINED(result_string);
			return result_string;
		}else{
			snmp_add_null_var(pdu, anOID, anOID_len);
		}

		/* poll host */
		status = snmp_sess_synch_response(current_host->snmp_session, pdu, &response);

		/* liftoff, successful poll, process it!! */
		if (status == STAT_SUCCESS) {
			if (response == NULL) {
				SPINE_LOG(("ERROR: An internal Net-Snmp error condition detected in Cacti snmp_get\n"));

				SET_UNDEFINED(result_string);
				status = STAT_ERROR;
			}else{
				if (response->errstat == SNMP_ERR_NOERROR) {
					vars = response->variables;

					#ifdef USE_NET_SNMP
					snprint_value(result_string, RESULTS_BUFFER, anOID, anOID_len, vars);
					#else
					sprint_value(result_string, anOID, anOID_len, vars);
					#endif
				}
			}
		}

		if (response) {
			snmp_free_pdu(response);
			response = NULL;
		}
	}else{
		status = STAT_DESCRIP_ERROR;
	}

	if (status != STAT_SUCCESS) {
		current_host->ignore_host = TRUE;

		SET_UNDEFINED(result_string);
	}

	return result_string;
}
Exemple #2
0
/**
 * Get snmp value to the structure my_oid_result array.
 * Author : lining 15810423651 [email protected] 
 * @param peername  : the remote host ip address.
 * @param oid_argvs : the oids pointer array.
 * @param my_oid_result oid_result : the return values. 
 * @return 0 on success, or others on failure.
 * @return 1 on failure, the argument value error.
 * @return 2 on failure, snmp_open return error.
 * @return 3 on failure, snmp_parse_oid return error.
 * @return 4 on failure, snmp_synch_response return status time out.
 * @return 5 on failure, snmp_synch_response return status others.
 */
int my_snmp_get(const char *peername, 
				const char *community, 
				const char *oid_argv, 
				my_oid_result *oid_result) {
	
	netsnmp_session	session;
	netsnmp_session *sess_handle;
	netsnmp_pdu	*pdu;
	netsnmp_pdu	*response;
	netsnmp_variable_list	*vars;
	
	oid oids[MAX_OID_LEN];
    size_t	oids_length;

    int	status;
    int	failures = 0;
	oids_length = 0;
	
	if (peername == NULL) {
		printf("[ERROR] my_snmp_get: the peername pointer is null\n");
		return 1;
	}
	if (community == NULL) {
		printf("[ERROR] my_snmp_get: the community pointer is null\n");
		return 1;
	}
	if (oid_argv == NULL) {
		printf("[ERROR] my_snmp_get: the oid_argv pointer is null\n");
		return 1;
	}
	
	init_snmp("snmpget");
	snmp_sess_init(&session);
	session.version = SNMP_VERSION_2c;
	session.community = (char*)community;
	session.community_len = strlen(session.community);
	session.peername = (char*)peername;
	session.timeout = 3000000;
	session.retries = 1;
	
    SOCK_STARTUP;

    sess_handle = snmp_open(&session);
    if (sess_handle == NULL) {
        SOCK_CLEANUP;
		printf("[ERROR] my_snmp_get: call snmp_open function failed, return sess_handle is null\n");
        return 2;
    }

    pdu = snmp_pdu_create(SNMP_MSG_GET);

	oids_length = MAX_OID_LEN;

	if (!snmp_parse_oid(oid_argv, oids, &oids_length)) {
		snmp_perror(oid_argv);
		failures++;
	} else {
		snmp_add_null_var(pdu, oids, oids_length);
	}
    if (failures) {
        SOCK_CLEANUP;
		printf("[ERROR] my_snmp_get: call snmp_parse_oid function failed\n");
        return 3;
    }
	
    status = snmp_synch_response(sess_handle, pdu, &response);
	
    if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
	
		for (vars = response->variables; vars; vars = vars->next_variable) {
			get_oid_value(vars, &oid_result);
		}
		
    } else if (status == STAT_TIMEOUT) {
		printf("[ERROR] my_snmp_get: call snmp_synch_response function failed, return status time out\n");
        return 4;
    } else {
		printf("[ERROR] my_snmp_get: call snmp_synch_response function failed, return status others\n");
        return 5;
    }

    if (response) {
        snmp_free_pdu(response);
	}
    snmp_close(sess_handle);
    SOCK_CLEANUP;
	
    return 0;
}
Exemple #3
0
void *poller(void *thread_args)
{
    worker_t *worker = (worker_t *) thread_args;
    crew_t *crew = worker->crew;
    target_t *entry = NULL;
    void *sessp = NULL;
    struct snmp_session session;
    struct snmp_pdu *pdu = NULL;
    struct snmp_pdu *response = NULL;
    oid anOID[MAX_OID_LEN];
    size_t anOID_len = MAX_OID_LEN;
    struct variable_list *vars = NULL;
    unsigned long long result = 0;
    unsigned long long last_value = 0;
    unsigned long long insert_val = 0;
    int status = 0, bits = 0, init = 0;
    char query[BUFSIZE];
    char storedoid[BUFSIZE];
    char result_string[BUFSIZE];

    if (set.verbose >= HIGH)
	printf("Thread [%d] starting.\n", worker->index);
    if (MYSQL_VERSION_ID > 40000)
       mysql_thread_init();
    else 
       my_thread_init();

    while (1) {
	if (set.verbose >= DEVELOP)
	    printf("Thread [%d] locking (wait on work)\n", worker->index);

	PT_MUTEX_LOCK(&crew->mutex);

	while (current == NULL) {
		PT_COND_WAIT(&crew->go, &crew->mutex);
	}
	if (set.verbose >= DEVELOP)
	    printf("Thread [%d] done waiting, received go (work cnt: %d)\n", worker->index, crew->work_count);

	if (current != NULL) {
	    if (set.verbose >= HIGH)
	      printf("Thread [%d] processing %s %s (%d work units remain in queue)\n", worker->index, current->host, current->objoid, crew->work_count);
	    snmp_sess_init(&session);
		if (set.snmp_ver == 2)
	      session.version = SNMP_VERSION_2c;
		else
	      session.version = SNMP_VERSION_1;
	    session.peername = current->host;
		session.remote_port = set.snmp_port;
	    session.community = current->community;
	    session.community_len = strlen(session.community);

	    sessp = snmp_sess_open(&session);
	    anOID_len = MAX_OID_LEN;
	    pdu = snmp_pdu_create(SNMP_MSG_GET);
	    read_objid(current->objoid, anOID, &anOID_len);
	    entry = current;
	    last_value = current->last_value;
	    init = current->init;
	    insert_val = 0;
	    bits = current->bits;
	    strncpy(storedoid, current->objoid, sizeof(storedoid));
		current = getNext();
	}
	if (set.verbose >= DEVELOP)
	    printf("Thread [%d] unlocking (done grabbing current)\n", worker->index);
	PT_MUTEX_UNLOCK(&crew->mutex);
	snmp_add_null_var(pdu, anOID, anOID_len);
	if (sessp != NULL) 
	   status = snmp_sess_synch_response(sessp, pdu, &response);
	else
	   status = STAT_DESCRIP_ERROR;

	/* Collect response and process stats */
	PT_MUTEX_LOCK(&stats.mutex);
	if (status == STAT_DESCRIP_ERROR) {
	    stats.errors++;
            printf("*** SNMP Error: (%s) Bad descriptor.\n", session.peername);
	} else if (status == STAT_TIMEOUT) {
	    stats.no_resp++;
	    printf("*** SNMP No response: (%s@%s).\n", session.peername,
	       storedoid);
	} else if (status != STAT_SUCCESS) {
	    stats.errors++;
	    printf("*** SNMP Error: (%s@%s) Unsuccessuful (%d).\n", session.peername,
	       storedoid, status);
	} else if (status == STAT_SUCCESS && response->errstat != SNMP_ERR_NOERROR) {
	    stats.errors++;
	    printf("*** SNMP Error: (%s@%s) %s\n", session.peername,
	       storedoid, snmp_errstring(response->errstat));
	} else if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
	    stats.polls++;
	} 
	PT_MUTEX_UNLOCK(&stats.mutex);

	/* Liftoff, successful poll, process it */
	if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
	    vars = response->variables;
#ifdef OLD_UCD_SNMP
            sprint_value(result_string, anOID, anOID_len, vars);
#else
	    snprint_value(result_string, BUFSIZE, anOID, anOID_len, vars);
#endif
	    switch (vars->type) {
		/*
		 * Switch over vars->type and modify/assign result accordingly.
		 */
		case ASN_COUNTER64:
		    if (set.verbose >= DEBUG) printf("64-bit result: (%s@%s) %s\n", session.peername, storedoid, result_string);
		    result = vars->val.counter64->high;
		    result = result << 32;
		    result = result + vars->val.counter64->low;
		    break;
		case ASN_COUNTER:
		    if (set.verbose >= DEBUG) printf("32-bit result: (%s@%s) %s\n", session.peername, storedoid, result_string);
		    result = (unsigned long) *(vars->val.integer);
		    break;
		case ASN_INTEGER:
		    if (set.verbose >= DEBUG) printf("Integer result: (%s@%s) %s\n", session.peername, storedoid, result_string);
		    result = (unsigned long) *(vars->val.integer);
		    break;
		case ASN_GAUGE:
		    if (set.verbose >= DEBUG) printf("32-bit gauge: (%s@%s) %s\n", session.peername, storedoid, result_string);
		    result = (unsigned long) *(vars->val.integer);
		    break;
		case ASN_TIMETICKS:
		    if (set.verbose >= DEBUG) printf("Timeticks result: (%s@%s) %s\n", session.peername, storedoid, result_string);
		    result = (unsigned long) *(vars->val.integer);
		    break;
		case ASN_OPAQUE:
		    if (set.verbose >= DEBUG) printf("Opaque result: (%s@%s) %s\n", session.peername, storedoid, result_string);
		    result = (unsigned long) *(vars->val.integer);
		    break;
		default:
		    if (set.verbose >= DEBUG) printf("Unknown result type: (%s@%s) %s\n", session.peername, storedoid, result_string);
	    }

		/* Gauge Type */
		if (bits == 0) {
			if (result != last_value) {
				insert_val = result;
				if (set.verbose >= HIGH)
					printf("Thread [%d]: Gauge change from %lld to %lld\n", worker->index, last_value, insert_val);
			} else {
				if (set.withzeros) 
					insert_val = result;
				if (set.verbose >= HIGH)
					printf("Thread [%d]: Gauge steady at %lld\n", worker->index, insert_val);
			}
	    /* Counter Wrap Condition */
	    } else if (result < last_value) {
			PT_MUTEX_LOCK(&stats.mutex);
              stats.wraps++;
			PT_MUTEX_UNLOCK(&stats.mutex);
	      if (bits == 32) insert_val = (THIRTYTWO - last_value) + result;
	      else if (bits == 64) insert_val = (SIXTYFOUR - last_value) + result;
	      if (set.verbose >= LOW) {
	         printf("*** Counter Wrap (%s@%s) [poll: %llu][last: %llu][insert: %llu]\n",
	         session.peername, storedoid, result, last_value, insert_val);
	      }
	    /* Not a counter wrap and this is not the first poll */
	    } else if ((last_value >= 0) && (init != NEW)) {
		insert_val = result - last_value;
	        /* Print out SNMP result if verbose */
	        if (set.verbose == DEBUG)
		  printf("Thread [%d]: (%lld-%lld) = %llu\n", worker->index, result, last_value, insert_val);
	        if (set.verbose == HIGH)
		  printf("Thread [%d]: %llu\n", worker->index, insert_val);
            /* last_value < 0, so this must be the first poll */
	    } else {
                if (set.verbose >= HIGH) printf("Thread [%d]: First Poll, Normalizing\n", worker->index);
	    }

		/* Check for bogus data, either negative or unrealistic */
	    if (insert_val > entry->maxspeed || result < 0) {
			if (set.verbose >= LOW) printf("*** Out of Range (%s@%s) [insert_val: %llu] [oor: %lld]\n",
				session.peername, storedoid, insert_val, entry->maxspeed);
			insert_val = 0;
			PT_MUTEX_LOCK(&stats.mutex);
			stats.out_of_range++;
			PT_MUTEX_UNLOCK(&stats.mutex);
	    }

		if (!(set.dboff)) {
			if ( (insert_val > 0) || (set.withzeros) ) {
				PT_MUTEX_LOCK(&crew->mutex);
				snprintf(query, sizeof(query), "INSERT INTO %s VALUES (%d, NOW(), %llu)",
					entry->table, entry->iid, insert_val);
				if (set.verbose >= DEBUG) printf("SQL: %s\n", query);
				status = mysql_query(&mysql, query);
				if (status) printf("*** MySQL Error: %s\n", mysql_error(&mysql));
				PT_MUTEX_UNLOCK(&crew->mutex);

				if (!status) {
					PT_MUTEX_LOCK(&stats.mutex);
					stats.db_inserts++;
					PT_MUTEX_UNLOCK(&stats.mutex);
				} 
			} /* insert_val > 0 or withzeros */	
		} /* !dboff */

	} /* STAT_SUCCESS */

        if (sessp != NULL) {
           snmp_sess_close(sessp);
           if (response != NULL) snmp_free_pdu(response);
        }

	if (set.verbose >= DEVELOP)
	    printf("Thread [%d] locking (update work_count)\n", worker->index);
	PT_MUTEX_LOCK(&crew->mutex);
	crew->work_count--;
	/* Only if we received a positive result back do we update the
	   last_value object */
	if (status == STAT_SUCCESS) entry->last_value = result;
	if (init == NEW) entry->init = LIVE;
	if (crew->work_count <= 0) {
	    if (set.verbose >= HIGH) printf("Queue processed. Broadcasting thread done condition.\n");
		PT_COND_BROAD(&crew->done);
	}
	if (set.verbose >= DEVELOP)
	    printf("Thread [%d] unlocking (update work_count)\n", worker->index);

		PT_MUTEX_UNLOCK(&crew->mutex);
    }				/* while(1) */
}
Exemple #4
0
/*
 * response handler
 */
int asynch_response(int operation, struct snmp_session *sp, int reqid, struct snmp_pdu *pdu, void *magic)
{
	struct req_t *req = (struct req_t *)magic;

	if (operation == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) {
		struct snmp_pdu *snmpreq = NULL;
		int okoid = 1;

		if (dataoperation == GET_KEYS) {
			/* 
			 * We're doing GETNEXT's when retrieving keys, so we will get a response
			 * which has nothing really to do with the data we're looking for. In that
			 * case, we should NOT process data from this response.
			 */
			struct variable_list *vp = pdu->variables;

			okoid = ((vp->name_length >= req->currentkey->indexmethod->rootoidlen) && 
			         (memcmp(req->currentkey->indexmethod->rootoid, vp->name, req->currentkey->indexmethod->rootoidlen * sizeof(oid)) == 0));
		}

		switch (pdu->errstat) {
		  case SNMP_ERR_NOERROR:
			/* Pick up the results, but only if the OID is valid */
			if (okoid) print_result(STAT_SUCCESS, req, pdu);
			break;

		  case SNMP_ERR_NOSUCHNAME:
			dbgprintf("Host %s item %s: No such name\n", req->hostname, req->curr_oid->devname);
			if (req->hostip[req->hostipidx+1]) {
				req->hostipidx++;
				startonehost(req, 1);
			}
			break;

		  case SNMP_ERR_TOOBIG:
			toobigcount++;
			errprintf("Host %s item %s: Response too big\n", req->hostname, req->curr_oid->devname);
			break;

		  default:
			errorcount++;
			errprintf("Host %s item %s: SNMP error %d\n",  req->hostname, req->curr_oid->devname, pdu->errstat);
			break;
		}

		/* Now see if we should send another request */
		switch (dataoperation) {
		  case GET_KEYS:
			/*
			 * While fetching keys, walk the current key-table until we reach the end of the table.
			 * When we reach the end of one key-table, start with the next.
			 * FIXME: Could optimize so we dont fetch the whole table, but only those rows we need.
			 */
			if (pdu->errstat == SNMP_ERR_NOERROR) {
				struct variable_list *vp = pdu->variables;

				if ( (vp->name_length >= req->currentkey->indexmethod->rootoidlen) && 
				     (memcmp(req->currentkey->indexmethod->rootoid, vp->name, req->currentkey->indexmethod->rootoidlen * sizeof(oid)) == 0) ) {
					/* Still more data in the current key table, get the next row */
					snmpreq = snmp_pdu_create(SNMP_MSG_GETNEXT);
					pducount++;
					/* Probably only one variable to fetch, but never mind ... */
					while (vp) {
						varcount++;
						snmp_add_null_var(snmpreq, vp->name, vp->name_length);
						vp = vp->next_variable;
					}
				}
				else {
					/* End of current key table. If more keys to be found, start the next table. */
					do { 
						req->currentkey = req->currentkey->next;
					} while (req->currentkey && req->currentkey->indexoid);

					if (req->currentkey) {
						snmpreq = snmp_pdu_create(SNMP_MSG_GETNEXT);
						pducount++;
						snmp_add_null_var(snmpreq, 
								  req->currentkey->indexmethod->rootoid, 
								  req->currentkey->indexmethod->rootoidlen);
					}
				}
			}
			break;

		  case GET_DATA:
			/* Generate a request for the next dataset, if any */
			if (req->next_oid) {
				snmpreq = generate_datarequest(req);
			}
			else {
				dbgprintf("No more oids left\n");
			}
			break;
		}

		/* Send the request we just made */
		if (snmpreq) {
			if (snmp_send(req->sess, snmpreq))
				goto finish;
			else {
				snmp_sess_perror("snmp_send", req->sess);
				snmp_free_pdu(snmpreq);
			}
		}
	}
	else {
		dbgprintf("operation not succesful: %d\n", operation);
		print_result(STAT_TIMEOUT, req, pdu);
	}

	/* 
	 * Something went wrong (or end of variables).
	 * This host not active any more
	 */
	dbgprintf("Finished host %s\n", req->hostname);
	active_requests--;

finish:
	/* Start some more hosts */
	starthosts(0);

	return 1;
}
Exemple #5
0
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;
}
Exemple #6
0
int main(int argc, char ** argv)
{
    netsnmp_session session, *ss;
    netsnmp_pdu *pdu;
    netsnmp_pdu *response;

    oid anOID[MAX_OID_LEN];
    size_t anOID_len;

    netsnmp_variable_list *vars;
    int status;
    int count=1;

    /*
     * Initialize the SNMP library
     */
    init_snmp("snmpdemoapp");

    /*
     * Initialize a "session" that defines who we're going to talk to
     */
    snmp_sess_init( &session );                   /* set up defaults */
    session.peername = strdup("test.net-snmp.org");

    /* set up the authentication parameters for talking to the server */

#ifdef DEMO_USE_SNMP_VERSION_3

    /* Use SNMPv3 to talk to the experimental server */

    /* set the SNMP version number */
    session.version=SNMP_VERSION_3;
        
    /* set the SNMPv3 user name */
    session.securityName = strdup("MD5User");
    session.securityNameLen = strlen(session.securityName);

    /* set the security level to authenticated, but not encrypted */
    session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;

    /* set the authentication method to MD5 */
    session.securityAuthProto = usmHMACMD5AuthProtocol;
    session.securityAuthProtoLen = sizeof(usmHMACMD5AuthProtocol)/sizeof(oid);
    session.securityAuthKeyLen = USM_AUTH_KU_LEN;

    /* set the authentication key to a MD5 hashed version of our
       passphrase "The Net-SNMP Demo Password" (which must be at least 8
       characters long) */
    if (generate_Ku(session.securityAuthProto,
                    session.securityAuthProtoLen,
                    (u_char *) our_v3_passphrase, strlen(our_v3_passphrase),
                    session.securityAuthKey,
                    &session.securityAuthKeyLen) != SNMPERR_SUCCESS) {
        snmp_perror(argv[0]);
        snmp_log(LOG_ERR,
                 "Error generating Ku from authentication pass phrase. \n");
        exit(1);
    }
    
#else /* we'll use the insecure (but simplier) SNMPv1 */

    /* set the SNMP version number */
    session.version = SNMP_VERSION_1;

    /* set the SNMPv1 community name used for authentication */
    session.community = "demopublic";
    session.community_len = strlen(session.community);

#endif /* SNMPv1 */

    /*
     * Open the session
     */
    SOCK_STARTUP;
    ss = snmp_open(&session);                     /* establish the session */

    if (!ss) {
      snmp_sess_perror("ack", &session);
      SOCK_CLEANUP;
      exit(1);
    }
    
    /*
     * Create the PDU for the data for our request.
     *   1) We're going to GET the system.sysDescr.0 node.
     */
    pdu = snmp_pdu_create(SNMP_MSG_GET);
    anOID_len = MAX_OID_LEN;
    if (!snmp_parse_oid(".1.3.6.1.2.1.1.1.0", anOID, &anOID_len)) {
      snmp_perror(".1.3.6.1.2.1.1.1.0");
      SOCK_CLEANUP;
      exit(1);
    }
#if OTHER_METHODS
    /*
     *  These are alternatives to the 'snmp_parse_oid' call above,
     *    e.g. specifying the OID by name rather than numerically.
     */
    read_objid(".1.3.6.1.2.1.1.1.0", anOID, &anOID_len);
    get_node("sysDescr.0", anOID, &anOID_len);
    read_objid("system.sysDescr.0", anOID, &anOID_len);
#endif

    snmp_add_null_var(pdu, anOID, anOID_len);
  
    /*
     * Send the Request out.
     */
    status = snmp_synch_response(ss, pdu, &response);

    /*
     * Process the response.
     */
    if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
      /*
       * SUCCESS: Print the result variables
       */

      for(vars = response->variables; vars; vars = vars->next_variable)
        print_variable(vars->name, vars->name_length, vars);

      /* manipuate the information ourselves */
      for(vars = response->variables; vars; vars = vars->next_variable) {
        if (vars->type == ASN_OCTET_STR) {
	  char *sp = (char *)malloc(1 + vars->val_len);
	  memcpy(sp, vars->val.string, vars->val_len);
	  sp[vars->val_len] = '\0';
          printf("value #%d is a string: %s\n", count++, sp);
	  free(sp);
	}
        else
          printf("value #%d is NOT a string! Ack!\n", count++);
      }
    } else {
      /*
       * FAILURE: print what went wrong!
       */

      if (status == STAT_SUCCESS)
        fprintf(stderr, "Error in packet\nReason: %s\n",
                snmp_errstring(response->errstat));
      else if (status == STAT_TIMEOUT)
        fprintf(stderr, "Timeout: No response from %s.\n",
                session.peername);
      else
        snmp_sess_perror("snmpdemoapp", ss);

    }

    /*
     * Clean up:
     *  1) free the response.
     *  2) close the session.
     */
    if (response)
      snmp_free_pdu(response);
    snmp_close(ss);

    SOCK_CLEANUP;
    return (0);
} /* main() */
Exemple #7
0
int main (int argc, char *argv[])
{
    netsnmp_session session, *ss;

    netsnmp_pdu *pdu, *response;

    oid name[MAX_OID_LEN];

    size_t name_length;

    int arg;

    int status;

    char *trap = NULL;

    char *prognam;

    int exitval = 0;

#ifndef NETSNMP_DISABLE_SNMPV1
    char *specific = NULL, *description = NULL, *agent = NULL;

    in_addr_t *pdu_in_addr_t;
#endif

    prognam = strrchr (argv[0], '/');
    if (prognam)
        prognam++;
    else
        prognam = argv[0];

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

    if (strcmp (prognam, "snmpinform") == 0)
        inform = 1;
    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;

    session.callback = snmp_input;
    session.callback_magic = NULL;

    /*
     * setup the local engineID which may be for either or both of the
     * contextEngineID and/or the securityEngineID.
     */
    setup_engineID (NULL, NULL);

    /* if we don't have a contextEngineID set via command line
       arguments, use our internal engineID as the context. */
    if (session.contextEngineIDLen == 0 || session.contextEngineID == NULL)
    {
        session.contextEngineID = snmpv3_generate_engineID (&session.contextEngineIDLen);
    }

    if (session.version == SNMP_VERSION_3 && !inform)
    {
        /*
         * for traps, we use ourselves as the authoritative engine
         * which is really stupid since command line apps don't have a
         * notion of a persistent engine.  Hence, our boots and time
         * values are probably always really wacked with respect to what
         * a manager would like to see.
         * 
         * The following should be enough to:
         * 
         * 1) prevent the library from doing discovery for engineid & time.
         * 2) use our engineid instead of the remote engineid for
         * authoritative & privacy related operations.
         * 3) The remote engine must be configured with users for our engineID.
         * 
         * -- Wes 
         */

        /*
         * pick our own engineID 
         */
        if (session.securityEngineIDLen == 0 || session.securityEngineID == NULL)
        {
            session.securityEngineID = snmpv3_generate_engineID (&session.securityEngineIDLen);
        }

        /*
         * set boots and time, which will cause problems if this
         * machine ever reboots and a remote trap receiver has cached our
         * boots and time...  I'll cause a not-in-time-window report to
         * be sent back to this machine. 
         */
        if (session.engineBoots == 0)
            session.engineBoots = 1;
        if (session.engineTime == 0)    /* not really correct, */
            session.engineTime = get_uptime ();    /* but it'll work. Sort of. */
    }

    ss = snmp_add (&session, netsnmp_transport_open_client ("snmptrap", session.peername), NULL, NULL);
    if (ss == NULL)
    {
        /*
         * diagnose netsnmp_transport_open_client and snmp_add errors with
         * the input netsnmp_session pointer
         */
        snmp_sess_perror ("snmptrap", &session);
        SOCK_CLEANUP;
        exit (1);
    }

#ifndef NETSNMP_DISABLE_SNMPV1
    if (session.version == SNMP_VERSION_1)
    {
        if (inform)
        {
            fprintf (stderr, "Cannot send INFORM as SNMPv1 PDU\n");
            SOCK_CLEANUP;
            exit (1);
        }
        pdu = snmp_pdu_create (SNMP_MSG_TRAP);
        if (!pdu)
        {
            fprintf (stderr, "Failed to create trap PDU\n");
            SOCK_CLEANUP;
            exit (1);
        }
        pdu_in_addr_t = (in_addr_t *) pdu->agent_addr;
        if (arg == argc)
        {
            fprintf (stderr, "No enterprise oid\n");
            usage ();
            SOCK_CLEANUP;
            exit (1);
        }
        if (argv[arg][0] == 0)
        {
            pdu->enterprise = (oid *) malloc (sizeof (objid_enterprise));
            memcpy (pdu->enterprise, objid_enterprise, sizeof (objid_enterprise));
            pdu->enterprise_length = sizeof (objid_enterprise) / sizeof (oid);
        }
        else
        {
            name_length = MAX_OID_LEN;
            if (!snmp_parse_oid (argv[arg], name, &name_length))
            {
                snmp_perror (argv[arg]);
                usage ();
                SOCK_CLEANUP;
                exit (1);
            }
            pdu->enterprise = (oid *) malloc (name_length * sizeof (oid));
            memcpy (pdu->enterprise, name, name_length * sizeof (oid));
            pdu->enterprise_length = name_length;
        }
        if (++arg >= argc)
        {
            fprintf (stderr, "Missing agent parameter\n");
            usage ();
            SOCK_CLEANUP;
            exit (1);
        }
        agent = argv[arg];
        if (agent != NULL && strlen (agent) != 0)
        {
            int ret = netsnmp_gethostbyname_v4 (agent, pdu_in_addr_t);

            if (ret < 0)
            {
                fprintf (stderr, "unknown host: %s\n", agent);
                exit (1);
            }
        }
        else
        {
            *pdu_in_addr_t = get_myaddr ();
        }
        if (++arg == argc)
        {
            fprintf (stderr, "Missing generic-trap parameter\n");
            usage ();
            SOCK_CLEANUP;
            exit (1);
        }
        trap = argv[arg];
        pdu->trap_type = atoi (trap);
        if (++arg == argc)
        {
            fprintf (stderr, "Missing specific-trap parameter\n");
            usage ();
            SOCK_CLEANUP;
            exit (1);
        }
        specific = argv[arg];
        pdu->specific_type = atoi (specific);
        if (++arg == argc)
        {
            fprintf (stderr, "Missing uptime parameter\n");
            usage ();
            SOCK_CLEANUP;
            exit (1);
        }
        description = argv[arg];
        if (description == NULL || *description == 0)
            pdu->time = get_uptime ();
        else
            pdu->time = atol (description);
    }
    else
#endif
    {
        long sysuptime;

        char csysuptime[20];

        pdu = snmp_pdu_create (inform ? SNMP_MSG_INFORM : SNMP_MSG_TRAP2);
        if (!pdu)
        {
            fprintf (stderr, "Failed to create notification PDU\n");
            SOCK_CLEANUP;
            exit (1);
        }
        if (arg == argc)
        {
            fprintf (stderr, "Missing up-time parameter\n");
            usage ();
            SOCK_CLEANUP;
            exit (1);
        }
        trap = argv[arg];
        if (*trap == 0)
        {
            sysuptime = get_uptime ();
            sprintf (csysuptime, "%ld", sysuptime);
            trap = csysuptime;
        }
        snmp_add_var (pdu, objid_sysuptime, sizeof (objid_sysuptime) / sizeof (oid), 't', trap);
        if (++arg == argc)
        {
            fprintf (stderr, "Missing trap-oid parameter\n");
            usage ();
            SOCK_CLEANUP;
            exit (1);
        }
        if (snmp_add_var (pdu, objid_snmptrap, sizeof (objid_snmptrap) / sizeof (oid), 'o', argv[arg]) != 0)
        {
            snmp_perror (argv[arg]);
            SOCK_CLEANUP;
            exit (1);
        }
    }
    arg++;

    while (arg < argc)
    {
        arg += 3;
        if (arg > argc)
        {
            fprintf (stderr, "%s: Missing type/value for variable\n", argv[arg - 3]);
            SOCK_CLEANUP;
            exit (1);
        }
        name_length = MAX_OID_LEN;
        if (!snmp_parse_oid (argv[arg - 3], name, &name_length))
        {
            snmp_perror (argv[arg - 3]);
            SOCK_CLEANUP;
            exit (1);
        }
        if (snmp_add_var (pdu, name, name_length, argv[arg - 2][0], argv[arg - 1]) != 0)
        {
            snmp_perror (argv[arg - 3]);
            SOCK_CLEANUP;
            exit (1);
        }
    }

    if (inform)
        status = snmp_synch_response (ss, pdu, &response);
    else
        status = snmp_send (ss, pdu) == 0;
    if (status)
    {
        snmp_sess_perror (inform ? "snmpinform" : "snmptrap", ss);
        if (!inform)
            snmp_free_pdu (pdu);
        exitval = 1;
    }
    else if (inform)
        snmp_free_pdu (response);

    snmp_close (ss);
    snmp_shutdown ("snmpapp");
    SOCK_CLEANUP;
    return exitval;
}
Exemple #8
0
int main(int argc, char **argv) {
    if ( argc < 2) {
        ip = fgets(cm,sizeof cm,stdin);
        // remove \n
        cm[strlen(cm)-1] = '\0';
        //fprintf(stdout, "IP length: %li\n", strlen(cm) );
        if(strlen(cm)< 2) {
        printf("Missing CM IP\nUSAGE: %s <CM_IP>\n", argv[0]);
        exit(1);
        } else {
          printf("Using %s IP\n",ip);
}
    } else {
        strncpy(cm,argv[1],sizeof cm);
    }
    init_snmp("snmpapp");
    snmp_sess_init( &session );
    session.peername = cm;
    session.version=SNMP_VERSION_2c;
    session.community=(unsigned char *) "public";
    session.community_len = strlen((const char *) session.community);
    ss = snmp_open(&session);
    if (!ss) {
       snmp_perror("ack");
       snmp_log(LOG_ERR, "Unable to open snmp session!!\n");
       exit(2);
   }

    pdu = snmp_pdu_create(SNMP_MSG_GET);
    read_objid(".1.3.6.1.2.1.1.1.0", anOID, &anOID_len);
    snmp_add_null_var(pdu, anOID, anOID_len);
    status = snmp_synch_response(ss, pdu, &response);
    if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
     /*
      * SUCCESS: Print the result variables
      */
    //for(vars = response->variables; vars; vars = vars->next_variable)
     //  print_variable(vars->name,vars->name_length, vars);
      /* manipulate the information ourselves */
     for(vars = response->variables; vars; vars = vars->next_variable) {
       int count=1;
       if (vars->type == ASN_OCTET_STR) {
         char *sp = malloc(1 + vars->val_len);
         memcpy(sp, vars->val.string, vars->val_len);
         sp[vars->val_len] = '\0';
         //printf("%d: %s\n", count++, sp);
         printf("%s\n", sp);
         free(sp);
       }
       else
         printf("value #%d is NOT a string! Ack!\n", count++);
     }
        } else {
     /*
      * FAILURE: print what went wrong!
      */

     if (status == STAT_SUCCESS)
       fprintf(stderr, "Error in packet\nReason: %s\n",
               snmp_errstring(response->errstat));
     else
       snmp_sess_perror("snmpget", ss);

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

   /* windows32 specific cleanup (is a noop on unix) */
   SOCK_CLEANUP;

   return EXIT_SUCCESS;

}
Exemple #9
0
int
main(int argc, char *argv[])
{
    netsnmp_session session, *ss;
    netsnmp_pdu    *pdu;
    netsnmp_pdu    *response;
    int             arg;
    oid             base[MAX_OID_LEN];
    size_t          base_length;
    int             status;
    netsnmp_variable_list *saved = NULL, *vlp = saved, *vlp2;
    int             count = 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;
    }

    if (arg != argc) {
	fprintf(stderr, "snmpdf: extra argument: %s\n", argv[arg]);
	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("snmpdf", &session);
        SOCK_CLEANUP;
        exit(1);
    }

    printf("%-18s %15s %15s %15s %5s\n", "Description", "size (kB)",
           "Used", "Available", "Used%");
    if (ucd_mib == 0) {
        /*
         * * Begin by finding all the storage pieces that are of
         * * type hrStorageFixedDisk, which is a standard disk.
         */
        pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
        base_length =
            add(pdu, "HOST-RESOURCES-MIB:hrStorageIndex", NULL, 0);
        memcpy(base, pdu->variables->name, base_length * sizeof(oid));

        vlp = collect(ss, pdu, base, base_length);

        while (vlp) {
            size_t          units;
            unsigned long   hssize, hsused;
            char            descr[SPRINT_MAX_LEN];
	    int             len;

            pdu = snmp_pdu_create(SNMP_MSG_GET);

            add(pdu, "HOST-RESOURCES-MIB:hrStorageDescr",
                &(vlp->name[base_length]), vlp->name_length - base_length);
            add(pdu, "HOST-RESOURCES-MIB:hrStorageAllocationUnits",
                &(vlp->name[base_length]), vlp->name_length - base_length);
            add(pdu, "HOST-RESOURCES-MIB:hrStorageSize",
                &(vlp->name[base_length]), vlp->name_length - base_length);
            add(pdu, "HOST-RESOURCES-MIB:hrStorageUsed",
                &(vlp->name[base_length]), vlp->name_length - base_length);

            status = snmp_synch_response(ss, pdu, &response);
            if (status != STAT_SUCCESS || !response) {
                snmp_sess_perror("snmpdf", ss);
                exit(1);
            }

            vlp2 = response->variables;
	    len = vlp2->val_len;
	    if (len >= SPRINT_MAX_LEN) len = SPRINT_MAX_LEN-1;
            memcpy(descr, vlp2->val.string, len);
            descr[len] = '\0';

            vlp2 = vlp2->next_variable;
            units = vlp2->val.integer ? *(vlp2->val.integer) : 0;

            vlp2 = vlp2->next_variable;
            hssize = vlp2->val.integer ? *(vlp2->val.integer) : 0;

            vlp2 = vlp2->next_variable;
            hsused = vlp2->val.integer ? *(vlp2->val.integer) : 0;

            printf("%-18s %15lu %15lu %15lu %4lu%%\n", descr,
                   units ? convert_units(hssize, units, 1024) : hssize,
                   units ? convert_units(hsused, units, 1024) : hsused,
                   units ? convert_units(hssize-hsused, units, 1024) : hssize -
                   hsused, hssize ? convert_units(hsused, 100, hssize) :
                   hsused);

            vlp = vlp->next_variable;
            snmp_free_pdu(response);
            count++;
        }
    }

    if (count == 0) {
        size_t          units = 0;
        /*
         * the host resources mib must not be supported.  Lets try the
         * UCD-SNMP-MIB and its dskTable 
         */

        pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
        base_length = add(pdu, "UCD-SNMP-MIB:dskIndex", NULL, 0);
        memcpy(base, pdu->variables->name, base_length * sizeof(oid));

        vlp = collect(ss, pdu, base, base_length);

        while (vlp) {
            unsigned long   hssize, hsused;
            char            descr[SPRINT_MAX_LEN];

            pdu = snmp_pdu_create(SNMP_MSG_GET);

            add(pdu, "UCD-SNMP-MIB:dskPath",
                &(vlp->name[base_length]), vlp->name_length - base_length);
            add(pdu, "UCD-SNMP-MIB:dskTotal",
                &(vlp->name[base_length]), vlp->name_length - base_length);
            add(pdu, "UCD-SNMP-MIB:dskUsed",
                &(vlp->name[base_length]), vlp->name_length - base_length);

            status = snmp_synch_response(ss, pdu, &response);
            if (status != STAT_SUCCESS || !response) {
                snmp_sess_perror("snmpdf", ss);
                exit(1);
            }

            vlp2 = response->variables;
            memcpy(descr, vlp2->val.string, vlp2->val_len);
            descr[vlp2->val_len] = '\0';

            vlp2 = vlp2->next_variable;
            hssize = *(vlp2->val.integer);

            vlp2 = vlp2->next_variable;
            hsused = *(vlp2->val.integer);

            printf("%-18s %15lu %15lu %15lu %4lu%%\n", descr,
                   units ? convert_units(hssize, units, 1024) : hssize,
                   units ? convert_units(hsused, units, 1024) : hsused,
                   units ? convert_units(hssize-hsused, units, 1024) : hssize -
                   hsused, hssize ? convert_units(hsused, 100, hssize) :
                   hsused);

            vlp = vlp->next_variable;
            snmp_free_pdu(response);
            count++;
        }
    }

    if (count == 0) {
        fprintf(stderr, "Failed to locate any partitions.\n");
        exit(1);
    }

    snmp_close(ss);
    SOCK_CLEANUP;
    return 0;

}                               /* end main() */
Exemple #10
0
QtNetSNMP::SNMPPDU *QtNetSNMP::QSNMPCore::createPDU(SNMPPDUType type, QVector<QSNMPObject *>& objs, unsigned short nrepeaters, unsigned short mrepetitions) throw(QSNMPException)
{
    SNMPPDU *pdu;

    if(type != SNMPPDUGet && type != SNMPPDUGetNext && type != SNMPPDUGetBulk && type != SNMPPDUSet)
        throw QSNMPException("QSNMPCore :: Create PDU :: Unknown PDU type");

    if(objs.empty())
        throw QSNMPException("QSNMPCore :: Create PDU :: SNMP objects vector is empty");

    pdu = snmp_pdu_create(type);

    foreach (QSNMPObject *object, objs) {
        if(type == SNMPPDUSet) {
            if(object -> data() -> type() == SNMPDataUnknown)
                throw QSNMPException("QSNMPCore :: Create PDU :: Unknown SNMP data type");

            char dataType;

            switch(object -> data() -> type()) {
            case SNMPDataInteger:
                dataType = 'i';
                break;
            case SNMPDataUnsigned:
                dataType = 'u';
                break;
            case SNMPDataBits:
                dataType = 'b';
                break;
            case SNMPDataCounter:
                dataType = 'c';
                break;
            case SNMPDataTimeTicks:
                dataType = 't';
                break;
            case SNMPDataCounter64:
                dataType = 'C';
                break;
            case SNMPDataBitString:
                dataType = 'b';
                break;
            case SNMPDataOctetString:
                dataType = 's';
                break;
            case SNMPDataIPAddress:
                dataType = 'a';
                break;
            case SNMPDataObjectId:
                dataType = 'o';
                break;
            default:
                dataType = '=';
            }

            snmp_add_var(pdu, object -> objID() -> numOID() -> data(), static_cast<size_t>(object -> objID() -> numOID() -> size()), dataType, static_cast<const char *>(object -> data() -> value()));

        } else
            snmp_add_null_var(pdu, object -> objID() -> numOID() -> data(), static_cast<size_t>(object -> objID() -> numOID() -> size()));
    }

    if(type == SNMPPDUGetBulk) {
        pdu -> errstat = nrepeaters;
        pdu -> errindex = mrepetitions;
    }

    return pdu;
}
Exemple #11
0
/**
 * This function allows you to make a distinction between generic 
 * traps from different classes of equipment. For example, you may want 
 * to handle a SNMP_TRAP_LINKDOWN trap for a particular device in a 
 * different manner to a generic system SNMP_TRAP_LINKDOWN trap.
 *   
 *
 * @param trap is the generic trap type.  The trap types are:
 *		- SNMP_TRAP_COLDSTART:
 *			cold start
 *		- SNMP_TRAP_WARMSTART:
 *			warm start
 *		- SNMP_TRAP_LINKDOWN:
 *			link down
 *		- SNMP_TRAP_LINKUP:
 *			link up
 *		- SNMP_TRAP_AUTHFAIL:
 *			authentication failure
 *		- SNMP_TRAP_EGPNEIGHBORLOSS:
 *			egp neighbor loss
 *		- SNMP_TRAP_ENTERPRISESPECIFIC:
 *			enterprise specific
 *			
 * @param specific is the specific trap value.
 *
 * @param enterprise is an enterprise oid in which you want to send specifc 
 *	traps from. 
 *
 * @param enterprise_length is the length of the enterprise oid, use macro,
 *	OID_LENGTH, to compute length.
 *
 * @param vars is used to supply list of variable bindings to form an SNMPv2 
 *	trap.
 *
 * @param context currently unused 
 *
 * @param flags currently unused 
 *
 * @return void
 *
 * @see send_easy_trap
 * @see send_v2trap
 */
int
netsnmp_send_traps(int trap, int specific,
                          oid * enterprise, int enterprise_length,
                          netsnmp_variable_list * vars,
                          char * context, int flags)
{
    netsnmp_pdu           *template_v1pdu;
    netsnmp_pdu           *template_v2pdu;
    netsnmp_variable_list *vblist = NULL;
    netsnmp_variable_list *trap_vb;
    netsnmp_variable_list *var;
    in_addr_t             *pdu_in_addr_t;
    u_long                 uptime;
    struct trap_sink *sink;

    DEBUGMSGTL(( "trap", "send_trap %d %d ", trap, specific));
    DEBUGMSGOID(("trap", enterprise, enterprise_length));
    DEBUGMSG(( "trap", "\n"));

    if (vars) {
        vblist = snmp_clone_varbind( vars );
        if (!vblist) {
            snmp_log(LOG_WARNING,
                     "send_trap: failed to clone varbind list\n");
            return -1;
        }
    }

    if ( trap == -1 ) {
        /*
         * Construct the SNMPv2-style notification PDU
         */
        if (!vblist) {
            snmp_log(LOG_WARNING,
                     "send_trap: called with NULL v2 information\n");
            return -1;
        }
        template_v2pdu = snmp_pdu_create(SNMP_MSG_TRAP2);
        if (!template_v2pdu) {
            snmp_log(LOG_WARNING,
                     "send_trap: failed to construct v2 template PDU\n");
            snmp_free_varbind(vblist);
            return -1;
        }

        /*
         * Check the varbind list we've been given.
         * If it starts with a 'sysUptime.0' varbind, then use that.
         * Otherwise, prepend a suitable 'sysUptime.0' varbind.
         */
        if (!snmp_oid_compare( vblist->name,    vblist->name_length,
                               sysuptime_oid, sysuptime_oid_len )) {
            template_v2pdu->variables = vblist;
            trap_vb  = vblist->next_variable;
        } else {
            uptime   = netsnmp_get_agent_uptime();
            var = NULL;
            snmp_varlist_add_variable( &var,
                           sysuptime_oid, sysuptime_oid_len,
                           ASN_TIMETICKS, (u_char*)&uptime, sizeof(uptime));
            if (!var) {
                snmp_log(LOG_WARNING,
                     "send_trap: failed to insert sysUptime varbind\n");
                snmp_free_pdu(template_v2pdu);
                snmp_free_varbind(vblist);
                return -1;
            }
            template_v2pdu->variables = var;
            var->next_variable        = vblist;
            trap_vb  = vblist;
        }

        /*
         * 'trap_vb' should point to the snmpTrapOID.0 varbind,
         *   identifying the requested trap.  If not then bomb out.
         * If it's a 'standard' trap, then we need to append an
         *   snmpEnterprise varbind (if there isn't already one).
         */
        if (!trap_vb ||
            snmp_oid_compare(trap_vb->name, trap_vb->name_length,
                             snmptrap_oid,  snmptrap_oid_len)) {
            snmp_log(LOG_WARNING,
                     "send_trap: no v2 trapOID varbind provided\n");
            snmp_free_pdu(template_v2pdu);
            return -1;
        }
        if (!snmp_oid_compare(vblist->val.objid, OID_LENGTH(trap_prefix),
                              trap_prefix,       OID_LENGTH(trap_prefix))) {
            var = find_varbind_in_list( template_v2pdu->variables,
                                        snmptrapenterprise_oid,
                                        snmptrapenterprise_oid_len);
            if (!var &&
                !snmp_varlist_add_variable( &(template_v2pdu->variables),
                     snmptrapenterprise_oid, snmptrapenterprise_oid_len,
                     ASN_OBJECT_ID,
                     (char*)enterprise, enterprise_length*sizeof(oid))) {
                snmp_log(LOG_WARNING,
                     "send_trap: failed to add snmpEnterprise to v2 trap\n");
                snmp_free_pdu(template_v2pdu);
                return -1;
            }
        }
            

        /*
         * If everything's OK, convert the v2 template into an SNMPv1 trap PDU.
         */
        template_v1pdu = convert_v2pdu_to_v1( template_v2pdu );
        if (!template_v1pdu) {
            snmp_log(LOG_WARNING,
                     "send_trap: failed to convert v2->v1 template PDU\n");
        }

    } else {
        /*
         * Construct the SNMPv1 trap PDU....
         */
        template_v1pdu = snmp_pdu_create(SNMP_MSG_TRAP);
        if (!template_v1pdu) {
            snmp_log(LOG_WARNING,
                     "send_trap: failed to construct v1 template PDU\n");
            snmp_free_varbind(vblist);
            return -1;
        }
        template_v1pdu->trap_type     = trap;
        template_v1pdu->specific_type = specific;
        template_v1pdu->time          = netsnmp_get_agent_uptime();

        if (snmp_clone_mem((void **) &template_v1pdu->enterprise,
                       enterprise, enterprise_length * sizeof(oid))) {
            snmp_log(LOG_WARNING,
                     "send_trap: failed to set v1 enterprise OID\n");
            snmp_free_varbind(vblist);
            snmp_free_pdu(template_v1pdu);
            return -1;
        }
        template_v1pdu->enterprise_length = enterprise_length;

        template_v1pdu->flags    |= UCD_MSG_FLAG_FORCE_PDU_COPY;
        template_v1pdu->variables = vblist;

        /*
         * ... and convert it into an SNMPv2-style notification PDU.
         */

        template_v2pdu = convert_v1pdu_to_v2( template_v1pdu );
        if (!template_v2pdu) {
            snmp_log(LOG_WARNING,
                     "send_trap: failed to convert v1->v2 template PDU\n");
        }
    }

    /*
     * Check whether we're ignoring authFail traps
     */
    if (template_v1pdu) {
      if (template_v1pdu->trap_type == SNMP_TRAP_AUTHFAIL &&
        snmp_enableauthentraps == SNMP_AUTHENTICATED_TRAPS_DISABLED) {
        snmp_free_pdu(template_v1pdu);
        snmp_free_pdu(template_v2pdu);
        return 0;
      }

    /*
     * Ensure that the v1 trap PDU includes the local IP address
     */
       pdu_in_addr_t = (in_addr_t *) template_v1pdu->agent_addr;
      *pdu_in_addr_t = get_myaddr();
    }


    /*
     *  Now loop through the list of trap sinks
     *   and call the trap callback routines,
     *   providing an appropriately formatted PDU in each case
     */
    for (sink = sinks; sink; sink = sink->next) {
#ifndef NETSNMP_DISABLE_SNMPV1
        if (sink->version == SNMP_VERSION_1) {
          if (template_v1pdu) {
            send_trap_to_sess(sink->sesp, template_v1pdu);
          }
        } else {
#endif
          if (template_v2pdu) {
            template_v2pdu->command = sink->pdutype;
            send_trap_to_sess(sink->sesp, template_v2pdu);
          }
#ifndef NETSNMP_DISABLE_SNMPV1
        }
#endif
    }
    if (template_v1pdu)
        snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
                        SNMPD_CALLBACK_SEND_TRAP1, template_v1pdu);
    if (template_v2pdu)
        snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
                        SNMPD_CALLBACK_SEND_TRAP2, template_v2pdu);
    snmp_free_pdu(template_v1pdu);
    snmp_free_pdu(template_v2pdu);
    return 0;
}
Exemple #12
0
/*
 * Configure special parameters on the session.
 * Currently takes the parameter configured and changes it if something 
 * was configured.  It becomes "-c" if the community string from the pdu
 * is placed on the session.
 */
int
proxy_fill_in_session(netsnmp_mib_handler *handler,
                      netsnmp_agent_request_info *reqinfo,
                      void **configured)
{
    netsnmp_session *session;
    struct simple_proxy *sp;

    sp = (struct simple_proxy *) handler->myvoid;
    if (!sp) {
        return 0;
    }
    session = sp->sess;
    if (!session) {
        return 0;
    }

#if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C)
#if defined(DISABLE_SNMPV1)
    if (session->version == SNMP_VERSION_2c) {
#else
#if defined(DISABLE_SNMPV2C)
    if (session->version == SNMP_VERSION_1) {
#else
    if (session->version == SNMP_VERSION_1 ||
        session->version == SNMP_VERSION_2c) {
#endif
#endif

        /*
         * Check if session has community string defined for it.
         * If not, need to extract community string from the pdu.
         * Copy to session and set 'configured' to indicate this.
         */
        if (session->community_len == 0) {
            DEBUGMSGTL(("proxy", "session has no community string\n"));
            if (reqinfo->asp == NULL || reqinfo->asp->pdu == NULL ||
                reqinfo->asp->pdu->community_len == 0) {
                return 0;
            }

            *configured = malloc(strlen("-c") + 1);
            strcpy(*configured, "-c");
            DEBUGMSGTL(("proxy", "pdu has community string\n"));
            session->community_len = reqinfo->asp->pdu->community_len;
            session->community = malloc(session->community_len + 1);
            strncpy((char *)session->community,
                    (const char *)reqinfo->asp->pdu->community,
                    session->community_len);
        }
    }
#endif

    return 1;
}

/*
 * Free any specially configured parameters used on the session.
 */
void
proxy_free_filled_in_session_args(netsnmp_session *session, void **configured)
{

    /* Only do comparisions, etc., if something was configured */
    if (*configured == NULL) {
        return;
    }

    /* If used community string from pdu, release it from session now */
    if (strcmp((const char *)(*configured), "-c") == 0) {
        free(session->community);
        session->community = NULL;
        session->community_len = 0;
    }

    free((u_char *)(*configured));
    *configured = NULL;
}

void
init_proxy(void)
{
    snmpd_register_config_handler("proxy", proxy_parse_config,
                                  proxy_free_config,
                                  "[snmpcmd args] host oid [remoteoid]");
}

void
shutdown_proxy(void)
{
    proxy_free_config();
}

int
proxy_handler(netsnmp_mib_handler *handler,
              netsnmp_handler_registration *reginfo,
              netsnmp_agent_request_info *reqinfo,
              netsnmp_request_info *requests)
{

    netsnmp_pdu    *pdu;
    struct simple_proxy *sp;
    oid            *ourname;
    size_t          ourlength;
    netsnmp_request_info *request = requests;
    u_char         *configured = NULL;

    DEBUGMSGTL(("proxy", "proxy handler starting, mode = %d\n",
                reqinfo->mode));

    switch (reqinfo->mode) {
    case MODE_GET:
    case MODE_GETNEXT:
    case MODE_GETBULK:         /* WWWXXX */
        pdu = snmp_pdu_create(reqinfo->mode);
        break;

    case MODE_SET_ACTION:
        pdu = snmp_pdu_create(SNMP_MSG_SET);
        break;

    case MODE_SET_UNDO:
        /*
         *  If we set successfully (status == NOERROR),
         *     we can't back out again, so need to report the fact.
         *  If we failed to set successfully, then we're fine.
         */
        for (request = requests; request; request=request->next) {
            if (request->status == SNMP_ERR_NOERROR) {
                netsnmp_set_request_error(reqinfo, requests,
                                          SNMP_ERR_UNDOFAILED);
                return SNMP_ERR_UNDOFAILED;
	    }
	}
        return SNMP_ERR_NOERROR;

    case MODE_SET_RESERVE1:
    case MODE_SET_RESERVE2:
    case MODE_SET_FREE:
    case MODE_SET_COMMIT:
        /*
         *  Nothing to do in this pass
         */
        return SNMP_ERR_NOERROR;

    default:
        snmp_log(LOG_WARNING, "unsupported mode for proxy called (%d)\n",
                               reqinfo->mode);
        return SNMP_ERR_NOERROR;
    }

    sp = (struct simple_proxy *) handler->myvoid;

    if (!pdu || !sp) {
        netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
        return SNMP_ERR_NOERROR;
    }

    while (request) {
        ourname = request->requestvb->name;
        ourlength = request->requestvb->name_length;

        if (sp->base_len > 0) {
            if ((ourlength - sp->name_len + sp->base_len) > MAX_OID_LEN) {
                /*
                 * too large 
                 */
                snmp_log(LOG_ERR,
                         "proxy oid request length is too long\n");
                return SNMP_ERR_NOERROR;
            }
            /*
             * suffix appended? 
             */
            DEBUGMSGTL(("proxy", "length=%d, base_len=%d, name_len=%d\n",
                        ourlength, sp->base_len, sp->name_len));
            if (ourlength > (int) sp->name_len)
                memcpy(&(sp->base[sp->base_len]), &(ourname[sp->name_len]),
                       sizeof(oid) * (ourlength - sp->name_len));
            ourlength = ourlength - sp->name_len + sp->base_len;
            ourname = sp->base;
        }

        snmp_pdu_add_variable(pdu, ourname, ourlength,
                              request->requestvb->type,
                              request->requestvb->val.string,
                              request->requestvb->val_len);
        request->delegated = 1;
        request = request->next;
    }

    /*
     * Customize session parameters based on request information
     */
    if (!proxy_fill_in_session(handler, reqinfo, (void **)&configured)) {
        netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
        return SNMP_ERR_NOERROR;
    }

    /*
     * send the request out 
     */
    DEBUGMSGTL(("proxy", "sending pdu\n"));
    snmp_async_send(sp->sess, pdu, proxy_got_response,
                    netsnmp_create_delegated_cache(handler, reginfo,
                                                   reqinfo, requests,
                                                   (void *) sp));

    /* Free any special parameters generated on the session */
    proxy_free_filled_in_session_args(sp->sess, (void **)&configured);

    return SNMP_ERR_NOERROR;
}
Exemple #13
0
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;
}
Exemple #14
0
/*! \fn char *snmp_get_multi(host_t *current_host, snmp_oids_t *snmp_oids, int num_oids)
 *  \brief performs multiple OID snmp_get's in a single network call
 *
 *	This function will a group of snmp OID's for a host.  The host snmp
 *  session must already be established.  The function will modify elements of
 *  the snmp_oids array with the results from the snmp api call.
 *
 */
void snmp_get_multi(host_t *current_host, snmp_oids_t *snmp_oids, int num_oids) {
	struct snmp_pdu *pdu       = NULL;
	struct snmp_pdu *response  = NULL;
	struct variable_list *vars = NULL;
	int status;
	int i;
	int max_repetitions = 1;
	int non_repeaters   = 0;
	int array_count;
	int index_count;

	/* get rid of some compiler warnings */
	errstat  = 0;
	errindex = 0;

	struct nameStruct {
	    oid             name[MAX_OID_LEN];
	    size_t          name_len;
	} *name, *namep;

	/* load up oids */
	namep = name = (struct nameStruct *) calloc(num_oids, sizeof(*name));
	pdu = snmp_pdu_create(SNMP_MSG_GET);
	for (i = 0; i < num_oids; i++) {
		namep->name_len = MAX_OID_LEN;

		if (!snmp_parse_oid(snmp_oids[i].oid, namep->name, &namep->name_len)) {
 			SPINE_LOG(("Host[%i] ERROR: Problems parsing Multi SNMP OID! (oid: %s)\n", current_host->id, snmp_oids[i].oid));

 			/* Mark this OID as "bad" */
			SET_UNDEFINED(snmp_oids[i].result);
		}else{
			snmp_add_null_var(pdu, namep->name, namep->name_len);
		}

		namep++;
	}

	status = STAT_DESCRIP_ERROR;

	/* execute the multi-get request */
	retry:
	status = snmp_sess_synch_response(current_host->snmp_session, pdu, &response);

	/* liftoff, successful poll, process it!! */
	if (status == STAT_SUCCESS) {
		if (response == NULL) {
			SPINE_LOG(("ERROR: An internal Net-Snmp error condition detected in Cacti snmp_get_multi\n"));
			status = STAT_ERROR;
		}else{
			if (response->errstat == SNMP_ERR_NOERROR) {
				vars = response->variables;

				for(i = 0; i < num_oids && vars; i++) {
					if (!IS_UNDEFINED(snmp_oids[i].result)) {
						#ifdef USE_NET_SNMP
						snmp_snprint_value(snmp_oids[i].result, RESULTS_BUFFER, vars->name, vars->name_length, vars);
						#else
						sprint_value(snmp_oids[i].result, vars->name, vars->name_length, vars);
						#endif

						vars = vars->next_variable;
					}
				}
			}else{
				if (response->errindex != 0) {
					index_count = 1;
					array_count = 0;

					/* Find our index against errindex */
					while (array_count < num_oids) {
						if (IS_UNDEFINED(snmp_oids[array_count].result) ) {
							array_count++;
						}else{
							/* if we have found our error, exit */
							if (index_count == response->errindex) {
								SET_UNDEFINED(snmp_oids[array_count].result);

								break;
							}
							array_count++;
							index_count++;
						}

					}

					/* remote the invalid OID from the PDU */
					pdu = snmp_fix_pdu(response, SNMP_MSG_GET);

					/* free the previous response */
					snmp_free_pdu(response);

					response = NULL;
					if (pdu != NULL) {
						/* retry the request */
						goto retry;
					}else{
					    /* all OID's errored out so exit cleanly */
						status = STAT_SUCCESS;
					}
				}else{
					status = STAT_DESCRIP_ERROR;
				}
			}
		}
	}

	if (status != STAT_SUCCESS) {
		current_host->ignore_host = 1;
		for (i = 0; i < num_oids; i++) {
			SET_UNDEFINED(snmp_oids[i].result);
		}
	}

	if (response != NULL) {
		snmp_free_pdu(response);
	}
}
Exemple #15
0
void
build_valuetable(void)
{
    struct expExpressionTable_data *expstorage, *expfound;
    struct expObjectTable_data *objstorage, *objfound = NULL;
    struct header_complex_index *hcindex, *object_hcindex;
    char           *expression;
    size_t          expression_len;
    oid            *index;


    char           *result, *resultbak;
    char           *temp, *tempbak;
    int             i = 0, j, l;
    temp = malloc(100);
    result = malloc(100);
    tempbak = temp;
    memset(result, 0, 100);
    *result = '\0';
    resultbak = result;


    DEBUGMSGTL(("expValueTable", "building valuetable...  \n"));

    for (hcindex = expExpressionTableStorage; hcindex != NULL;
         hcindex = hcindex->next) {
        expstorage = (struct expExpressionTable_data *) hcindex->data;
        if (expstorage->expExpressionEntryStatus == RS_ACTIVE) {
            expression = expstorage->expExpression;
            expression_len = expstorage->expExpressionLen;
            while (*expression != '\0') {
                if (*expression == '$') {
                    i++;
                    for (j = 1; j < 100; j++) {
                        if ((*(expression + j) == '+') ||
                            (*(expression + j) == '-') ||
                            (*(expression + j) == '*') ||
                            (*(expression + j) == '/') ||
                            (*(expression + j) == '(') ||
                            (*(expression + j) == ')') ||
                            *(expression + j) == '\0') {
                            break;
                        }
                    }
                    strncpy(temp, expression + 1, j - 1);
                    *(temp + j - 1) = '\0';
                    l = atoi(temp);
                    for (object_hcindex = expObjectTableStorage;
                         object_hcindex != NULL;
                         object_hcindex = object_hcindex->next) {
                        objstorage =
                            (struct expObjectTable_data *) object_hcindex->
                            data;
                        if (!strcmp
                            (objstorage->expExpressionOwner,
                             expstorage->expExpressionOwner)
                            && (objstorage->expExpressionOwnerLen ==
                                expstorage->expExpressionOwnerLen)
                            && !strcmp(objstorage->expExpressionName,
                                       expstorage->expExpressionName)
                            && (objstorage->expExpressionNameLen ==
                                expstorage->expExpressionNameLen)
                            && (l == objstorage->expObjectIndex)) {
                            if (objfound == NULL) {
                                expfound = expstorage;
                                objfound = objstorage;
                            }
                            if (objstorage->expObjectIDWildcard ==
                                EXPOBJCETIDWILDCARD_TRUE)
                                objfound = objstorage;
                        }
                    }
                    expression = expression + j;
                } else {
                    expression++;
                }
            };
        }

        if (!objfound) {
            continue;
        }
        if (objfound->expObjectIDWildcard == EXPOBJCETIDWILDCARD_FALSE) {
            index = calloc(1, MAX_OID_LEN);
            *index = 0;
            *(index + 1) = 0;
            *(index + 2) = 0;
            expValueTable_add(expstorage, objfound->expExpressionOwner,
                              objfound->expExpressionOwnerLen,
                              objfound->expExpressionName,
                              objfound->expExpressionNameLen, index, 3);
        } else {
            oid            *targetOID;
            size_t          taggetOID_len;
            targetOID = objfound->expObjectID;
            struct snmp_pdu *pdu;
            struct snmp_pdu *response;
            oid            *next_OID;
            size_t          next_OID_len;
            taggetOID_len = objfound->expObjectIDLen;
            int             status;
            struct snmp_session *ss;
            /*
             * Initialize the SNMP library
             */


            /*
             * set the SNMP version number 
             */
            session.version = expstorage->pdu_version;

            /*
             * set the SNMPv1 community name used for authentication 
             */
            session.community = expstorage->pdu_community;
            session.community_len = expstorage->pdu_community_len;

            /*
             * Open the session
             */
            SOCK_STARTUP;
            ss = snmp_open(&session);   /* establish the session */
            if (!ss) {
                snmp_perror("ack");
                snmp_log(LOG_ERR, "something horrible happened!!!\n");
                exit(2);
            }

            next_OID = targetOID;
            next_OID_len = taggetOID_len;
            do {
                index = calloc(1, MAX_OID_LEN);
                pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);

                snmp_add_null_var(pdu, next_OID, next_OID_len);

                /*
                 * Send the Request out.
                 */
                status = snmp_synch_response(ss, pdu, &response);

                /*
                 * Process the response.
                 */
                if (status == STAT_SUCCESS
                    && response->errstat == SNMP_ERR_NOERROR) {
                    /*
                     * SUCCESS: Print the result variables
                     */

                    if (((response->variables->type >= SNMP_NOSUCHOBJECT &&
                          response->variables->type <= SNMP_ENDOFMIBVIEW)
                         || snmp_oid_compare(targetOID, taggetOID_len,
                                             response->variables->name,
                                             taggetOID_len) != 0)) {
                        break;
                    }
                    /* add to expValueTable */

                    *index = 0;
                    *(index + 1) = 0;
                    memcpy(index + 2,
                           response->variables->name + taggetOID_len,
                           (response->variables->name_length -
                            taggetOID_len) * sizeof(oid));
                    expValueTable_add(expstorage,
                                      objfound->expExpressionOwner,
                                      objfound->expExpressionOwnerLen,
                                      objfound->expExpressionName,
                                      objfound->expExpressionNameLen,
                                      index,
                                      response->variables->name_length -
                                      taggetOID_len + 2);

                    next_OID = response->variables->name;

                    next_OID_len = response->variables->name_length;




                } else {
                    /*
                     * FAILURE: print what went wrong!
                     */
                    if (status == STAT_SUCCESS)
                        fprintf(stderr, "Error in packet\nReason: %s\n",
                                snmp_errstring(response->errstat));
                    else
                        snmp_sess_perror("snmpget", ss);
                }
            } while (TRUE);

        }

    }

}
int 
get_ilo_oid_list (struct snmp_session *session, oid *target_oid, 
		  size_t target_oid_len, char **error_ptr)
{
  int status;
  int running = TRUE;
  oid cur_oid[MAX_OID_LEN];
  size_t cur_oid_len;

  struct snmp_pdu *pdu_ptr, *response_ptr;
  netsnmp_variable_list	*var_list,*var_list_prev=NULL;
  struct ilo_oid_list *oid_list;

  struct ilo_snmp_priv *priv_ptr = container_of(error_ptr, 
						struct ilo_snmp_priv, err_str);

  if (priv_ptr == NULL) 
    {
      ILO_ERR_DEBUG(error_ptr, "priv_ptr is NULL!\n");
      return NAGIOS_ILO_FAIL_STATUS;
    }

  oid_copy(cur_oid, &cur_oid_len, target_oid, target_oid_len);

  while (running) 
    {
      pdu_ptr = snmp_pdu_create(SNMP_MSG_GETBULK);

      /* Max-repetitions: Tell get-bulk to attemp up to 'errindex' 
	   get-next operations to get the remaining objects.  */
      pdu_ptr->errindex = SNMP_GETBULK_ERRINDEX;

      /* Non-repeater.  */
      pdu_ptr->errstat = 0;

      snmp_add_null_var(pdu_ptr, cur_oid, cur_oid_len);

      status = snmp_synch_response(session, pdu_ptr, &response_ptr);
 
      if (status == STAT_SUCCESS && response_ptr->errstat == SNMP_ERR_NOERROR) 
	{

	  var_list = var_list_prev =response_ptr->variables;
		
	  /* Add each element of the netsnmp variable list to 
	     struct ilo_oid_list.  */
	  while (var_list) 
	    {
	      if (netsnmp_oid_is_subtree(target_oid, 
	  				 target_oid_len,
					 var_list->name, 
					 var_list->name_length) != 0) 
		{
		  running = FALSE;
		  break;
		}
		
	      oid_list = alloc_oid_list(var_list, error_ptr);
			  
	      if (oid_list == NULL) 
		{
		  ILO_ERR_DEBUG(error_ptr, "oid_list is NULL!\n");
		  return NAGIOS_ILO_FAIL_STATUS;
		}

	      oid_list_add(&priv_ptr->oid_list, oid_list);
	      var_list_prev = var_list;
	      var_list = var_list->next_variable;
	    }
	    var_list=var_list_prev;

	  if ((var_list->type == SNMP_ENDOFMIBVIEW) ||
	      (var_list->type == SNMP_NOSUCHOBJECT) ||
	      (var_list->type == SNMP_NOSUCHINSTANCE)) 
	    {
	      running = FALSE;
	    } 
	  else 
	    {
		oid_copy(cur_oid, &cur_oid_len, var_list->name,var_list->name_length);
	    }
	} 
      else 
	{ /* Cannot get the response */
	  if (status == STAT_SUCCESS) 
	    {
	      ILO_ERR_DEBUG(error_ptr, "Cannot get the response: %s\n",
			    snmp_errstring(response_ptr->errstat));
	    } 
	  else 
	    {
	      snmp_error(session, &session->s_errno, &session->s_snmp_errno, 
		 	 error_ptr);
	    }

	   return NAGIOS_ILO_FAIL_STATUS;

	}
	  
      if (response_ptr)
	snmp_free_pdu(response_ptr);	

    }

  return NAGIOS_ILO_SUCCESS_STATUS;
}
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             running;
    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 
             */
            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("snmpbulkget", ss);
        running = 0;
        exitval = 1;
    }

    if (response)
        snmp_free_pdu(response);

    snmp_close(ss);
    SOCK_CLEANUP;
    return exitval;
}
/*
 *
 * AgentX State diagram.  [mode] = internal mode it's mapped from:
 *
 * TESTSET -success-> COMMIT -success-> CLEANUP
 * [RESERVE1]         [ACTION]          [COMMIT]
 *    |                 |
 *    |                 \--failure-> UNDO
 *    |                              [UNDO]
 *    |
 *     --failure-> CLEANUP
 *                 [FREE]
 */
int
agentx_master_handler(netsnmp_mib_handler *handler,
                      netsnmp_handler_registration *reginfo,
                      netsnmp_agent_request_info *reqinfo,
                      netsnmp_request_info *requests)
{
    netsnmp_session *ax_session = (netsnmp_session *) handler->myvoid;
    netsnmp_request_info *request = requests;
    netsnmp_pdu    *pdu;
    void           *cb_data;
    int             result;

    DEBUGMSGTL(("agentx/master",
                "agentx master handler starting, mode = 0x%02x\n",
                reqinfo->mode));

    if (!ax_session) {
        netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
        return SNMP_ERR_NOERROR;
    }        

    /*
     * build a new pdu based on the pdu type coming in 
     */
    switch (reqinfo->mode) {
    case MODE_GET:
        pdu = snmp_pdu_create(AGENTX_MSG_GET);
        break;

    case MODE_GETNEXT:
        pdu = snmp_pdu_create(AGENTX_MSG_GETNEXT);
        break;

    case MODE_GETBULK:         /* WWWXXX */
        pdu = snmp_pdu_create(AGENTX_MSG_GETNEXT);
        break;

    case MODE_SET_RESERVE1:
        pdu = snmp_pdu_create(AGENTX_MSG_TESTSET);
        break;

    case MODE_SET_RESERVE2:
        /*
         * don't do anything here for AgentX.  Assume all is fine
         * and go on since AgentX only has one test phase. 
         */
        return SNMP_ERR_NOERROR;

    case MODE_SET_ACTION:
        pdu = snmp_pdu_create(AGENTX_MSG_COMMITSET);
        break;

    case MODE_SET_UNDO:
        pdu = snmp_pdu_create(AGENTX_MSG_UNDOSET);
        break;

    case MODE_SET_COMMIT:
    case MODE_SET_FREE:
        pdu = snmp_pdu_create(AGENTX_MSG_CLEANUPSET);
        break;

    default:
        snmp_log(LOG_WARNING,
                 "unsupported mode for agentx/master called\n");
        return SNMP_ERR_NOERROR;
    }

    if (!pdu) {
        netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
        return SNMP_ERR_NOERROR;
    }

    pdu->version = AGENTX_VERSION_1;
    pdu->reqid = snmp_get_next_transid();
    pdu->transid = reqinfo->asp->pdu->transid;
    pdu->sessid = ax_session->subsession->sessid;
    if (reginfo->contextName) {
        pdu->community = (u_char *) strdup(reginfo->contextName);
        pdu->community_len = strlen(reginfo->contextName);
        pdu->flags |= AGENTX_MSG_FLAG_NON_DEFAULT_CONTEXT;
    }
    if (ax_session->subsession->flags & AGENTX_MSG_FLAG_NETWORK_BYTE_ORDER)
        pdu->flags |= AGENTX_MSG_FLAG_NETWORK_BYTE_ORDER;

    while (request) {

        size_t nlen = request->requestvb->name_length;
        oid   *nptr = request->requestvb->name;
        
        DEBUGMSGTL(("agentx/master","request for variable ("));
        DEBUGMSGOID(("agentx/master", nptr, nlen));
        DEBUGMSG(("agentx/master", ")\n"));
        
        /*
         * loop through all the requests and create agentx ones out of them 
         */

        if (reqinfo->mode == MODE_GETNEXT || reqinfo->mode == MODE_GETBULK) {

            if (snmp_oid_compare(nptr, nlen, request->subtree->start_a,
                                 request->subtree->start_len) < 0) {
                DEBUGMSGTL(("agentx/master","inexact request preceeding region ("));
                DEBUGMSGOID(("agentx/master", request->subtree->start_a,
                             request->subtree->start_len));
                DEBUGMSG(("agentx/master", ")\n"));
                nptr = request->subtree->start_a;
                nlen = request->subtree->start_len;
                request->inclusive = 1;
            }

            if (request->inclusive) {
                DEBUGMSGTL(("agentx/master", "INCLUSIVE varbind "));
                DEBUGMSGOID(("agentx/master", nptr, nlen));
                DEBUGMSG(("agentx/master", " scoped to "));
                DEBUGMSGOID(("agentx/master", request->range_end,
                             request->range_end_len));
                DEBUGMSG(("agentx/master", "\n"));
                snmp_pdu_add_variable(pdu, nptr, nlen, ASN_PRIV_INCL_RANGE,
                                      (u_char *) request->range_end,
                                      request->range_end_len *
                                      sizeof(oid));
                request->inclusive = 0;
            } else {
                DEBUGMSGTL(("agentx/master", "EXCLUSIVE varbind "));
                DEBUGMSGOID(("agentx/master", nptr, nlen));
                DEBUGMSG(("agentx/master", " scoped to "));
                DEBUGMSGOID(("agentx/master", request->range_end,
                             request->range_end_len));
                DEBUGMSG(("agentx/master", "\n"));
                snmp_pdu_add_variable(pdu, nptr, nlen, ASN_PRIV_EXCL_RANGE,
                                      (u_char *) request->range_end,
                                      request->range_end_len *
                                      sizeof(oid));
            }
        } else {
            snmp_pdu_add_variable(pdu, request->requestvb->name,
                                  request->requestvb->name_length,
                                  request->requestvb->type,
                                  request->requestvb->val.string,
                                  request->requestvb->val_len);
        }

        /*
         * mark the request as delayed 
         */
        if (pdu->command != AGENTX_MSG_CLEANUPSET)
            request->delegated = REQUEST_IS_DELEGATED;
        else
            request->delegated = REQUEST_IS_NOT_DELEGATED;

        /*
         * next... 
         */
        request = request->next;
    }

    /*
     * When the master sends a CleanupSet PDU, it will never get a response
     * back from the subagent. So we shouldn't allocate the
     * netsnmp_delegated_cache structure in this case.
     */
    if (pdu->command != AGENTX_MSG_CLEANUPSET)
        cb_data = netsnmp_create_delegated_cache(handler, reginfo,
                                                 reqinfo, requests,
                                                 (void *) ax_session);
    else
        cb_data = NULL;

    /*
     * send the requests out.
     */
    DEBUGMSGTL(("agentx", "sending pdu (req=0x%x,trans=0x%x,sess=0x%x)\n",
                (unsigned)pdu->reqid, (unsigned)pdu->transid, (unsigned)pdu->sessid));
    result = snmp_async_send(ax_session, pdu, agentx_got_response, cb_data);
    if (result == 0) {
        snmp_free_pdu(pdu);
    }

    return SNMP_ERR_NOERROR;
}
/**
 * Bulk walk snmp value to the structure my_oid_result array.
 * Author : lining 15810423651 [email protected] 
 * @param peername  : the remote host ip address.
 * @param oid_argv : the char *oid pointer.
 * @param my_oid_result oid_results : the return values array.
 * @param my_oid_result oid_results_nums : the values array numbers. 
 * @return 0 on success, or others on failure.
 * @return 1 on failure, the argument error.
 * @return 2 on failure, snmp_open return error.
 * @return 3 on failure, snmp_parse_oid return error.
 * @return 4 on failure, snmp_synch_response return status time out.
 * @return 5 on failure, snmp_synch_response return status others.
 * @return 6 on failure, response->errstat end of mib.
 * @return 7 on failure, response->errstat others.
 */
int my_snmp_bulkwalk(const char *peername, 
				     const char *community, 
				     const char *oid_argv, 
				     my_oid_result *oid_results, 
				     unsigned int *oid_results_nums) {

  	if(peername == NULL) {
		printf("[ERROR] my_snmp_walk: the peername pointer is null\n");
		return 1;
	}
	
	if(community == NULL) {
		printf("[ERROR] my_snmp_walk: the community pointer is null\n");
		return 1;
	}
	
	if(oid_argv == NULL) {
		printf("[ERROR] my_snmp_walk: the oid_argv pointer is null\n");	
		return 1;
	}

	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	numprinted = 0;
	int	reps = 10, non_reps = 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);


	init_snmp("snmpapp");
	snmp_sess_init(&session);
	session.version = SNMP_VERSION_2c;
	session.community = (char*)community;
	session.community_len = strlen(session.community);
	session.peername = (char*)peername;
	session.timeout = 1000000;
	session.retries = 1;

	rootlen = MAX_OID_LEN;
	if(snmp_parse_oid(oid_argv, root, &rootlen) == NULL) {
		printf("[ERROR] my_snmp_bulkwalk: call snmp_parse_oid function failed\n");
		snmp_close(ss);
        SOCK_CLEANUP;		
		return 2;
	}

    SOCK_STARTUP;
    ss = snmp_open(&session);
    if(ss == NULL) {
        printf("[ERROR] my_snmp_bulkwalk: cakk snnp_open function failed\n");
		snmp_close(ss);
        SOCK_CLEANUP;
        return 3;
    }


    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);

    while(running) {

        pdu = snmp_pdu_create(SNMP_MSG_GETBULK);
        pdu->non_repeaters = non_reps;
        pdu->max_repetitions = reps;
        snmp_add_null_var(pdu, name, name_length);

        status = snmp_synch_response(ss, pdu, &response);
        if(status == STAT_SUCCESS) {
            if(response->errstat == SNMP_ERR_NOERROR) {

                for(vars = response->variables; vars; vars = vars->next_variable) {
                    if((vars->name_length < rootlen) || (memcmp(root, vars->name, rootlen * sizeof(oid)) != 0)) {
                        running = 0;
                        continue;
                    }
		
					get_bulkwalk_oid_values(vars, &oid_results[numprinted]);
                    numprinted++;
			
                    if((vars->type != SNMP_ENDOFMIBVIEW) && (vars->type != SNMP_NOSUCHOBJECT) && (vars->type != SNMP_NOSUCHINSTANCE)) {
                        if(check && snmp_oid_compare(name, name_length, vars->name, vars->name_length) >= 0) {
                            running = 0;
                        }
                        if(vars->next_variable == NULL) {
							
							unsigned int count;
							for(count = 0; count < vars->name_length; count++) {
								oid_results[numprinted - 1].oid_name[count] = vars->name[count];
								oid_results[numprinted - 1].oid_name_length = vars->name_length;
							}
                            memmove(name, vars->name, vars->name_length * sizeof(oid));
                            name_length = vars->name_length;
                        }
                    } else {
                        running = 0;
                    }
                }
            } else {
                running = 0;
                if(response->errstat == SNMP_ERR_NOSUCHNAME) {
					printf("[ERROR] my_snmp_bulkwalk: have reached the end of MIB file\n");
					*oid_results_nums = numprinted;
					snmp_close(ss);
					SOCK_CLEANUP;		
					return 6;
                } else {
					printf("[ERROR] my_snmp_bulkwalk: return response->errstat others error\n");
					*oid_results_nums = numprinted;
					snmp_close(ss);
					SOCK_CLEANUP;			
					return 7;
                }
            }
        } else if(status == STAT_TIMEOUT) {
			printf("[ERROR] my_snmp_bulkwalk: return status is session time out\n");
			running = 0;
			*oid_results_nums = numprinted;
			snmp_close(ss);
			SOCK_CLEANUP;			
			return 4;
        } else {
			printf("[ERROR] my_snmp_bulkwalk: return session response error\n");
            running = 0;
			*oid_results_nums = numprinted;
			snmp_close(ss);
			SOCK_CLEANUP;
			return 5;
        }
		
        if(response) {
            snmp_free_pdu(response);
		}
    }
	
	*oid_results_nums = numprinted;
    snmp_close(ss);
    SOCK_CLEANUP;
	
    return 0;	
}
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;
}
int main(int argc, char * argv[]){
    returncode = 0;
    int status;
    struct tree * mib_tree;

    if(argv[1] != NULL && strcmp("-h", argv[1]) == 0 || strcmp("--help", argv[1]) == 0){
        PrintHelp();
        return 0;
    }
    if(argv[1] == NULL || argv[2] == NULL || argv[3] == NULL || argv[4]== NULL) {
        printf("Argument invalide (hostname, variable, warning, critical)\n");
    }

    snmp_sess_init(&session);
    session.version = SNMP_VERSION_1;
    session.community = "public";
    session.community_len = strlen(session.community);
    session.peername = argv[1];

    session_handle = snmp_open(&session);
    add_mibdir("/usr/share/snmp/mibs/");

    pdu = snmp_pdu_create(SNMP_MSG_GET);

    char variable[50];
    snprintf(variable, 50, argv[2]);

    if(strcmp("CPULOAD", variable) == 0){
		processSnmpGet("NETWORK-APPLIANCE-MIB::cpuBusyTimePerCent.0");
		int result = atoi(resultString + 2);
        if(result >= atoi(argv[4])){
            returncode = 2;
        }
        else if (result >= atoi(argv[3])){
            returncode = 1;
        }
        printf("CPU Load : %d %% | cpu_load=%d %%\n", result, result);
    }
    else if(strcmp("PS", variable) == 0){
        processSnmpGet("NETWORK-APPLIANCE-MIB::envFailedPowerSupplyCount.0");
        int result = atoi(resultString);
        if(result >= atoi(argv[4])){
            returncode = 2;
        }
        else if (result >= atoi(argv[3])){
            returncode = 1;
        }
        printf("Failed Power Supply : %d\n", result);

    }
    else if(strcmp("FAN", variable) == 0){
        processSnmpGet("NETWORK-APPLIANCE-MIB::envFailedFanCount.0");
        int result = atoi(resultString);
        if(result >= atoi(argv[4])){
            returncode = 2;
        }
        else if (result >= atoi(argv[3])){
            returncode = 1;
        }
        printf("Failed FAN : %d\n", result);
    }
	else if(strcmp("TEMP", variable) == 0){
		processSnmpGet("NETWORK-APPLIANCE-MIB::envOverTemperature.0");
        int result = atoi(resultString);
        if(result == 2){
            returncode = 2;
			printf("Over Temperatur : YES");
        }
        else{
            printf("Over Temperatur : NO");
        }
	}
	else if(strcmp("NVRAM", variable) == 0){
		processSnmpGet("NETWORK-APPLIANCE-MIB::nvramBatteryStatus.0");
        int result = atoi(resultString);
		if(result > 1){
		    returncode = 2;
		}
		printf("NVRAM battery status: %d\n", result);
	}
    else{
        printf("Invalid argument");
        freeSession();
        return 3;
    }
    freeSession();
    return returncode;
}
Exemple #22
0
static void send_v2_trap (struct snmp_session *ss,
			  int trap, 
			  int specific, 
			  int type)
{
    struct snmp_pdu *pdu;
    struct variable_list *var;
    struct timeval now, diff;
    static oid objid_sysuptime[] = {1, 3, 6, 1, 2, 1, 1, 3, 0};
    static oid objid_snmptrap[] = {1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0};
    static oid objid_trapoid[] = {1, 3, 6, 1, 6, 3, 1, 1, 5, 1};

    gettimeofday(&now, NULL);
    now.tv_sec--;
    now.tv_usec += 1000000L;
    diff.tv_sec = now.tv_sec - starttime.tv_sec;
    diff.tv_usec = now.tv_usec - starttime.tv_usec;
    if (diff.tv_usec > 1000000L){
	diff.tv_usec -= 1000000L;
	diff.tv_sec++;
    }

    pdu = snmp_pdu_create (type);

    pdu->variables = var = (struct variable_list *)malloc(sizeof(struct variable_list));
    var->next_variable = NULL;
    var->name = (oid *)malloc(sizeof(objid_sysuptime));
    memcpy (var->name, objid_sysuptime, sizeof(objid_sysuptime));
    var->name_length = sizeof(objid_sysuptime)/sizeof(objid_sysuptime[0]);
    var->type = ASN_TIMETICKS;
    var->val.integer = (long *)malloc(sizeof(long));
    *var->val.integer = diff.tv_sec*100 + diff.tv_usec/10000;
    var->val_len = sizeof(long);

    var->next_variable = (struct variable_list *)malloc(sizeof(struct variable_list));
    var = var->next_variable;
    var->next_variable = NULL;
    if (trap == 6) {
	objid_enterprisetrap[length_enterprisetrap-1] = specific;
	var->name = (oid *)malloc(sizeof(objid_snmptrap));
	var->name_length = length_enterprisetrap;
	memcpy(var->name, objid_snmptrap, sizeof(objid_snmptrap));
	var->type = ASN_OBJECT_ID;
	var->val.objid = (oid *)malloc(sizeof(objid_enterprisetrap));
	var->val_len = sizeof(objid_enterprisetrap);
	memcpy(var->val.objid, objid_enterprisetrap, sizeof(objid_enterprisetrap));
    }
    else {
	objid_trapoid[9] = trap+1;
	var->name = (oid *)malloc(sizeof(objid_snmptrap));
	var->name_length = sizeof(objid_snmptrap)/sizeof(objid_snmptrap[0]);
	memcpy(var->name, objid_snmptrap, sizeof(objid_snmptrap));
	var->type = ASN_OBJECT_ID;
	var->val.objid = (oid *)malloc(sizeof(objid_trapoid));
	var->val_len = sizeof(objid_trapoid);
	memcpy(var->val.objid, objid_trapoid, sizeof(objid_trapoid));
    }

    if (snmp_send (ss, pdu) == 0) {
        snmp_perror ("snmpd: send_v2_trap");
    }
#ifdef USING_MIBII_SNMP_MIB_MODULE       
    snmp_outtraps++;
#endif
}
Exemple #23
0
void startonehost(struct req_t *req, int ipchange)
{
	struct snmp_session s;
	struct snmp_pdu *snmpreq = NULL;

	if ((dataoperation < GET_DATA) && !req->currentkey) return;

	/* Are we retrying a cluster with a new IP? Then drop the current session */
	if (req->sess && ipchange) {
		/*
		 * Apparently, we cannot close a session while in a callback.
		 * So leave this for now - it will leak some memory, but
		 * this is not a problem as long as we only run once.
		 */
		/* snmp_close(req->sess); */
		req->sess = NULL;
	}

	/* Setup the SNMP session */
	if (!req->sess) {
		snmp_sess_init(&s);

		/* 
		 * snmp_session has a "remote_port" field, but it does not work.
		 * Instead, the peername should include a port number (IP:PORT)
		 * if (req->portnumber) s.remote_port = req->portnumber;
		 */
		s.peername = req->hostip[req->hostipidx];

		/* Set the SNMP version and authentication token(s) */
		s.version = req->version;
		switch (s.version) {
		  case SNMP_VERSION_1:
		  case SNMP_VERSION_2c:
			s.community = req->community;
			s.community_len = strlen((char *)req->community);
			break;

		  case SNMP_VERSION_3:
			/* set the SNMPv3 user name */
			s.securityName = strdup(req->username);
			s.securityNameLen = strlen(s.securityName);

			/* set the security level to authenticated, but not encrypted */
			s.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;

			/* set the authentication method */
			switch (req->authmethod) {
			  case SNMP_V3AUTH_MD5:
				s.securityAuthProto = usmHMACMD5AuthProtocol;
				s.securityAuthProtoLen = sizeof(usmHMACMD5AuthProtocol)/sizeof(oid);
				s.securityAuthKeyLen = USM_AUTH_KU_LEN;
				break;

			  case SNMP_V3AUTH_SHA1:
				s.securityAuthProto = usmHMACSHA1AuthProtocol;
				s.securityAuthProtoLen = sizeof(usmHMACSHA1AuthProtocol)/sizeof(oid);
				s.securityAuthKeyLen = USM_AUTH_KU_LEN;
				break;
			}

			/*
			 * set the authentication key to a hashed version of our
			 * passphrase (which must be at least 8 characters long).
			 */
			if (generate_Ku(s.securityAuthProto, s.securityAuthProtoLen,
					(u_char *)req->passphrase, strlen(req->passphrase),
					s.securityAuthKey, &s.securityAuthKeyLen) != SNMPERR_SUCCESS) {
				errprintf("Failed to generate Ku from authentication pass phrase for host %s\n",
					  req->hostname);
				snmp_perror("generate_Ku");
				return;
			}
			break;
		}

		/* Set timeouts and retries */
		if (timeout > 0) s.timeout = timeout;
		if (retries > 0) s.retries = retries;

		/* Setup the callback */
		s.callback = asynch_response;
		s.callback_magic = req;

		if (!(req->sess = snmp_open(&s))) {
			snmp_sess_perror("snmp_open", &s);
			return;
		}
	}

	switch (dataoperation) {
	  case GET_KEYS:
		snmpreq = snmp_pdu_create(SNMP_MSG_GETNEXT);
		pducount++;
		snmp_add_null_var(snmpreq, req->currentkey->indexmethod->rootoid, req->currentkey->indexmethod->rootoidlen);
		break;

	  case GET_DATA:
		/* Build the request PDU and send it */
		snmpreq = generate_datarequest(req);
		break;
	}

	if (!snmpreq) return;

	if (snmp_send(req->sess, snmpreq))
		active_requests++;
	else {
		errorcount++;
		snmp_sess_perror("snmp_send", req->sess);
		snmp_free_pdu(snmpreq);
	}
}
static int send_snmp_inform_or_trap(const GpErrorData * errorData, const char * subject, const char * severity)
{

	netsnmp_session session, *ss = NULL;
	netsnmp_pdu    *pdu, *response;
	int				status;
	char            csysuptime[20];
	static bool 	snmp_initialized = false;
	static char myhostname[255];	/* gethostname usually is limited to 65 chars out, but make this big to be safe */
	char	   *rawstring = NULL;
	List	   *elemlist = NIL;
	ListCell   *l = NULL;

	/*
	 * "inform" messages get a positive acknowledgement response from the SNMP manager.
	 * If it doesn't come, the message might be resent.
	 *
	 * "trap" messages are one-way, and we have no idea if the manager received it.
	 * But, it's faster and cheaper, and no need to retry.  So some people might prefer it.
	 */
	bool inform = strcmp(gp_snmp_use_inform_or_trap,"inform") == 0;


	if (gp_snmp_monitor_address == NULL || gp_snmp_monitor_address[0] == '\0')
	{
		static bool firsttime = 1;

		ereport(firsttime ? LOG : DEBUG1,(errmsg("SNMP inform/trap alerts are disabled"),errOmitLocation(true)));
		firsttime = false;

		return -1;
	}


	/*
	 * SNMP managers are required to handle messages up to at least 484 bytes long, but I believe most existing
	 * managers support messages up to one packet (ethernet frame) in size, 1472 bytes.
	 *
	 * But, should we take that chance?  Or play it safe and limit the message to 484 bytes?
	 */

	elog(DEBUG2,"send_snmp_inform_or_trap");

	if (!snmp_initialized)
	{
		snmp_enable_stderrlog();

		if (gp_snmp_debug_log != NULL && gp_snmp_debug_log[0] != '\0')
		{
			snmp_enable_filelog(gp_snmp_debug_log, 1);

			//debug_register_tokens("ALL");
			snmp_set_do_debugging(1);
		}

		/*
		 * Initialize the SNMP library.  This also reads the MIB database.
		 */
		/* Add GPDB-MIB to the list to be loaded */
		putenv("MIBS=+GPDB-MIB:SNMP-FRAMEWORK-MIB:SNMPv2-CONF:SNMPv2-TC:SNMPv2-TC");

		init_snmp("sendalert");

		snmp_initialized = true;

		{
			char portnum[16];
			myhostname[0] = '\0';

			if (gethostname(myhostname, sizeof(myhostname)) == 0)
			{
				strcat(myhostname,":");
				pg_ltoa(PostPortNumber,portnum);
				strcat(myhostname,portnum);
			}
		}
	}

	/*
	 * Trap/Inform messages always start with the system up time. (SysUpTime.0)
	 *
	 * This presumably would be the uptime of GPDB, not the machine it is running on, I think.
	 *
	 * Use Postmaster's "MyStartTime" as a way to get that.
	 */

	sprintf(csysuptime, "%ld", (long)(time(NULL) - MyStartTime));


	/*
	// ERRCODE_DISK_FULL could be reported vi rbmsMIB rdbmsTraps rdbmsOutOfSpace trap.
	// But it appears we never generate that error?

	// ERRCODE_ADMIN_SHUTDOWN means SysAdmin aborted somebody's request.  Not interesting?

	// ERRCODE_CRASH_SHUTDOWN sounds interesting, but I don't see that we ever generate it.

	// ERRCODE_CANNOT_CONNECT_NOW means we are starting up, shutting down, in recovery, or Too many users are logged on.

	// abnormal database system shutdown
	*/



	/*
	 * The gpdbAlertSeverity is a crude attempt to classify some of these messages based on severity,
	 * where OK means everything is running normal, Down means everything is shut down, degraded would be
	 * for times when some segments are down, but the system is up, The others are maybe useful in the future
	 *
	 *  gpdbSevUnknown(0),
	 *	gpdbSevOk(1),
	 *	gpdbSevWarning(2),
	 *	gpdbSevError(3),
	 *	gpdbSevFatal(4),
	 *	gpdbSevPanic(5),
	 *	gpdbSevSystemDegraded(6),
	 *	gpdbSevSystemDown(7)
	 */


	char detail[MAX_ALERT_STRING+1];
	snprintf(detail, MAX_ALERT_STRING, "%s", errorData->error_detail);
	detail[127] = '\0';

	char sqlstmt[MAX_ALERT_STRING+1];
	char * sqlstmtp = errorData->debug_query_string;
	if (sqlstmtp == NULL || sqlstmtp[0] == '\0')
		sqlstmtp = errorData->internal_query;
	if (sqlstmtp == NULL)
		sqlstmtp = "";


	snprintf(sqlstmt, MAX_ALERT_STRING, "%s", sqlstmtp);
	sqlstmt[MAX_ALERT_STRING] = '\0';


	/* Need a modifiable copy of To list */
	rawstring = pstrdup(gp_snmp_monitor_address);

	/* Parse string into list of identifiers */
	if (!SplitMailString(rawstring, ',', &elemlist))
	{
		/* syntax error in list */
		ereport(LOG,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("invalid list syntax for \"gp_snmp_monitor_address\"")));
		return -1;
	}


	/*
	 * This session is just a template, and doesn't need to be connected.
	 * It is used by snmp_add(), which copies this info, opens the new session, and assigns the transport.
	 */
	snmp_sess_init( &session );	/* Initialize session to default values */
	session.version = SNMP_VERSION_2c;
	session.timeout = SNMP_DEFAULT_TIMEOUT;
	session.retries = SNMP_DEFAULT_RETRIES;
	session.remote_port = 162; 							// I think this isn't used by net-snmp any more.

	/*if (strchr(session.peername,':')==NULL)
		strcat(session.peername,":162");*/
	session.community = (u_char *)gp_snmp_community;
	session.community_len = strlen((const char *)session.community);  // SNMP_DEFAULT_COMMUNITY_LEN means "public"
	session.callback_magic = NULL;

	foreach(l, elemlist)
	{
		char	   *cur_gp_snmp_monitor_address = (char *) lfirst(l);

		if (cur_gp_snmp_monitor_address == NULL || cur_gp_snmp_monitor_address[0] == '\0')
			continue;

		session.peername = cur_gp_snmp_monitor_address;
		/*
		 * If we try to "snmp_open( &session )", net-snmp will set up a connection to that
		 * endpoint on port 161, assuming we are the network monitor, and the other side is an agent.
		 *
		 * But we are pretending to be an agent, sending traps to the NM, so we don't need this.
		 */

		/*if (!snmp_open( &session ))   	// Don't open the session here!
		{
			const char     *str;
			int             xerr;
			xerr = snmp_errno;
			str = snmp_api_errstring(xerr);
			elog(LOG, "snmp_open: %s", str);
			return -1;
		}*/

		/*
		 * This call copies the info from "session" to "ss", assigns the transport, and opens the session.
		 * We must specify "snmptrap" so the transport will know we want port 162 by default.
		 */
		ss = snmp_add(&session,
					  netsnmp_transport_open_client("snmptrap", cur_gp_snmp_monitor_address),
					  NULL, NULL);
		if (ss == NULL) {
			/*
			 * diagnose netsnmp_transport_open_client and snmp_add errors with
			 * the input netsnmp_session pointer
			 */
			{
				char           *err;
				snmp_error(&session, NULL, NULL, &err);
				elog(LOG, "send_alert snmp_add of %s failed: %s", cur_gp_snmp_monitor_address, err);
				free(err);
			}
			return -1;
		}

		/*
		 * We need to create the pdu each time, as it gets freed when we send a trap.
		 */
		pdu = snmp_pdu_create(inform ? SNMP_MSG_INFORM : SNMP_MSG_TRAP2);
		if (!pdu)
		{
			const char     *str;
			int             xerr;
			xerr = snmp_errno;
			str = snmp_api_errstring(xerr);
			elog(LOG, "Failed to create notification PDU: %s", str);
			return -1;
		}

		/*
		 * Trap/Inform messages always start with the system up time. (SysUpTime.0)
		 * We use Postmaster's "MyStartTime" as a way to get that.
		 */

		snmp_add_var(pdu, objid_sysuptime,
							sizeof(objid_sysuptime) / sizeof(oid),
							't', (const char *)csysuptime);

	#if 0
		/*
		 * In the future, we might want to send RDBMS-MIB::rdbmsStateChange when the system becomes unavailable or
		 * partially unavailable.  This code, which is not currently used, shows how to build the pdu for
		 * that trap.
		 */
		/* {iso(1) identified-organization(3) dod(6) internet(1) mgmt(2) mib-2(1) rdbmsMIB(39) rdbmsTraps(2) rdbmsStateChange(1)} */
		snmp_add_var(pdu, objid_snmptrap,
							sizeof(objid_snmptrap) / sizeof(oid),
							'o', "1.3.6.1.2.1.39.2.1");  // rdbmsStateChange


		snmp_add_var(pdu, objid_rdbmsrelstate,
							sizeof(objid_rdbmsrelstate) / sizeof(oid),
							'i', "5");  // 4 = restricted, 5 = unavailable
	#endif

		/* {iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprises(1) gpdbMIB(31327) gpdbTraps(5) gpdbTrapsList(0) gpdbAlert(1)} */

		/*
		 * We could specify this trap oid by name, rather than numeric oid, but then if the GPDB-MIB wasn't
		 * found, we'd get an error.  Using the numeric oid means we can still work without the MIB loaded.
		 */
		snmp_add_var(pdu, objid_snmptrap,
							sizeof(objid_snmptrap) / sizeof(oid),
							'o', "1.3.6.1.4.1.31327.5.0.1");  // gpdbAlert


		snmp_add_var(pdu, objid_gpdbAlertMsg,
							sizeof(objid_gpdbAlertMsg) / sizeof(oid),
							's', subject);  // SnmpAdminString = UTF-8 text
		snmp_add_var(pdu, objid_gpdbAlertSeverity,
							sizeof(objid_gpdbAlertSeverity) / sizeof(oid),
							'i', (char *)severity);

		snmp_add_var(pdu, objid_gpdbAlertSqlstate,
							sizeof(objid_gpdbAlertSqlstate) / sizeof(oid),
							's', errorData->sql_state);

		snmp_add_var(pdu, objid_gpdbAlertDetail,
							sizeof(objid_gpdbAlertDetail) / sizeof(oid),
							's', detail); // SnmpAdminString = UTF-8 text

		snmp_add_var(pdu, objid_gpdbAlertSqlStmt,
							sizeof(objid_gpdbAlertSqlStmt) / sizeof(oid),
							's', sqlstmt); // SnmpAdminString = UTF-8 text

		snmp_add_var(pdu, objid_gpdbAlertSystemName,
							sizeof(objid_gpdbAlertSystemName) / sizeof(oid),
							's', myhostname); // SnmpAdminString = UTF-8 text



		elog(DEBUG2,"ready to send to %s",cur_gp_snmp_monitor_address);
		if (inform)
			status = snmp_synch_response(ss, pdu, &response);
		else
			status = snmp_send(ss, pdu) == 0;

		elog(DEBUG2,"send, status %d",status);
		if (status != STAT_SUCCESS)
		{
			/* Something went wrong */
			if (ss)
			{
				char           *err;
				snmp_error(ss, NULL, NULL, &err);
				elog(LOG, "sendalert failed to send %s: %s", inform ? "inform" : "trap", err);
				free(err);
			}
			else
			{
				elog(LOG, "sendalert failed to send %s: %s", inform ? "inform" : "trap", "Something went wrong");
			}
			if (!inform)
				snmp_free_pdu(pdu);
		}
		else if (inform)
			snmp_free_pdu(response);

		snmp_close(ss);
		ss = NULL;

	}
Exemple #25
0
/*
 * Print a description of the network interfaces.
 */
void
intpro(int interval)
{
	oid varname[MAX_OID_LEN], *instance, *ifentry;
	size_t varname_len;
	int ifnum, cfg_nnets;
	oid curifip [4];
	struct variable_list *var;
	struct snmp_pdu *request, *response;
	int status;
	int ifindex, oldindex = 0;
	struct _if_info {
	    int ifindex;
	    char name[128];
	    char ip[128], route[128];
	    char ioctets[20], ierrs[20], ooctets[20], oerrs[20], outqueue[20];
	    int operstatus;
	    u_long netmask;
	    struct in_addr ifip, ifroute;
	} *if_table, *cur_if;
	int max_name = 4, max_route = 7, max_ip = 7, max_ioctets = 7, max_ooctets = 7;
	int i;

	if (interval) {
		sidewaysintpr((unsigned)interval);
		return;
	}
	var = getvarbyname(Session, oid_cfg_nnets, sizeof(oid_cfg_nnets) / sizeof(oid));
	if (var && var->val.integer) {
	    cfg_nnets = *var->val.integer;
	    snmp_free_var(var);
	}
	else {
	    fprintf (stderr, "No response when requesting number of interfaces.\n");
	    return;
	}
	DEBUGMSGTL (("netstat:if", "cfg_nnets = %d\n", cfg_nnets));

	memset (curifip, 0, sizeof (curifip));
	if_table = (struct _if_info *) calloc (cfg_nnets, sizeof (*if_table));
	cur_if = if_table;

	for (ifnum = 1; ifnum <= cfg_nnets; ifnum++) {
		register char *cp;

		request = snmp_pdu_create (SNMP_MSG_GETNEXT);
		memmove (varname, oid_ipadentaddr, sizeof (oid_ipadentaddr));
		varname_len = sizeof (oid_ipadentaddr) / sizeof (oid);
		instance = varname + 9;
		memmove (varname + 10, curifip, sizeof (curifip));
		*instance = IPIFINDEX;
		snmp_add_null_var (request, varname, varname_len);
		*instance = IPADDR;
		snmp_add_null_var (request, varname, varname_len);
		*instance = IPNETMASK;
		snmp_add_null_var (request, varname, varname_len);

		status = snmp_synch_response (Session, request, &response);
		if (status != STAT_SUCCESS || response->errstat != SNMP_ERR_NOERROR) {
		    fprintf (stderr, "SNMP request failed for interface %d, variable %ld out of %d interfaces (IP)\n", ifnum, response->errindex, cfg_nnets);
		    cfg_nnets = ifnum;
		    break;
		}
		for (var = response->variables; var; var = var->next_variable) {
                  if (snmp_get_do_debugging()) {
		    print_variable (var->name, var->name_length, var);
                  }
		    switch (var->name [9]) {
		    case IPIFINDEX:
			ifindex = *var->val.integer;
			for (cur_if = if_table; cur_if->ifindex != ifindex && cur_if->ifindex != 0; cur_if++);
			cur_if->ifindex = ifindex;
			break;
		    case IPADDR:
			memmove (curifip, var->name+10, sizeof (curifip));
			memmove (&cur_if->ifip, var->val.string, sizeof (u_long));
			break;
		    case IPNETMASK:
			memmove (&cur_if->netmask, var->val.string, sizeof (u_long));
		    }
		}
		cur_if->ifroute.s_addr = cur_if->ifip.s_addr & cur_if->netmask;
		if (cur_if->ifroute.s_addr)
			strcpy(cur_if->route, netname (cur_if->ifroute, cur_if->netmask));
		else strcpy(cur_if->route, "none");
		if ((i = strlen(cur_if->route)) > max_route) max_route = i;
		if (cur_if->ifip.s_addr)
			strcpy(cur_if->ip, routename (cur_if->ifip));
		else strcpy(cur_if->ip, "none");
		if ((i = strlen(cur_if->ip)) > max_ip) max_ip = i;

		snmp_free_pdu (response);

		memmove (varname, oid_ifname, sizeof(oid_ifname));
		varname_len = sizeof(oid_ifname) / sizeof(oid);
		ifentry = varname + 9;
		instance = varname + 10;
		request = snmp_pdu_create (SNMP_MSG_GETNEXT);

		*instance = oldindex;
		*ifentry = IFINDEX;
		snmp_add_null_var (request, varname, varname_len);
		*ifentry = IFNAME;
		snmp_add_null_var (request, varname, varname_len);
		*ifentry = IFOPERSTATUS;
		snmp_add_null_var (request, varname, varname_len);
		*ifentry = INOCTETS;
		snmp_add_null_var (request, varname, varname_len);
		*ifentry = OUTOCTETS;
		snmp_add_null_var (request, varname, varname_len);

		while ((status = snmp_synch_response (Session, request, &response)) == STAT_SUCCESS) {
		    if (response->errstat != SNMP_ERR_NOSUCHNAME)
			break;
		    if ((request = snmp_fix_pdu(response, SNMP_MSG_GETNEXT)) == NULL)
			break;
		    snmp_free_pdu(response);
		}
		if (status != STAT_SUCCESS || response->errstat != SNMP_ERR_NOERROR) {
		    fprintf (stderr, "SNMP request failed for interface %d, variable %ld out of %d interfaces (IF)\n", ifnum, response->errindex, cfg_nnets);
		    cfg_nnets = ifnum;
		    break;
		}
		for (var = response->variables; var; var = var->next_variable) {
		    if (snmp_get_do_debugging()) {
			print_variable (var->name, var->name_length, var);
		    }
		    if (!var->val.integer) continue;
		    switch (var->name [9]) {
		    case IFINDEX:
			ifindex = *var->val.integer;
			for (cur_if = if_table; cur_if->ifindex != ifindex && cur_if->ifindex != 0; cur_if++);
			cur_if->ifindex = ifindex;
			break;
		    case INOCTETS:
			sprintf(cur_if->ioctets, "%lu",  *var->val.integer);
			i = strlen(cur_if->ioctets);
			if (i > max_ioctets) max_ioctets = i;
			break;
		    case OUTOCTETS:
			sprintf(cur_if->ooctets, "%lu",  *var->val.integer);
			i = strlen(cur_if->ooctets);
			if (i > max_ooctets) max_ooctets = i;
			break;
		    case IFNAME:
			oldindex = var->name[10];
			if (var->val_len >= sizeof(cur_if->name))
			    var->val_len = sizeof(cur_if->name) - 1;
			memmove (cur_if->name, var->val.string, var->val_len);
			cur_if->name [var->val_len] = 0;
			if ((i = strlen(cur_if->name)+1) > max_name) max_name = i;
			break;
		    case IFOPERSTATUS:
			cur_if->operstatus = *var->val.integer; break;
		    }
		}

		snmp_free_pdu (response);

		if (intrface != NULL && strcmp(cur_if->name, intrface) != 0) {
			cur_if->name [0] = 0;
			continue;
		}
		if (cur_if->operstatus != MIB_IFSTATUS_UP) {
			cp = strchr(cur_if->name, '\0');
			*cp++ = '*';
			*cp = '\0';
		}
	}

	printf("%*.*s %*.*s %*.*s %*.*s %*.*s ",
		-max_name, max_name, "Name",
		-max_route, max_route, "Network",
		-max_ip, max_ip, "Address",
		max_ioctets, max_ioctets, "Ioctets",
		max_ooctets, max_ooctets, "Ooctets");
	putchar('\n');
	for (ifnum = 0, cur_if = if_table; ifnum < cfg_nnets; ifnum++, cur_if++) {
		if (cur_if->name [0] == 0) continue;
		printf("%*.*s ", -max_name, max_name, cur_if->name);
		printf("%*.*s ", -max_route, max_route, cur_if->route);
		printf("%*.*s ", -max_ip, max_ip, cur_if->ip);
		printf("%*s %*s", max_ioctets, cur_if->ioctets,
		    max_ioctets, cur_if->ooctets);
		putchar('\n');
	}
	free(if_table);
}
Exemple #26
0
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() */
Exemple #27
0
static rsRetVal omsnmp_sendsnmp(instanceData *pData, uchar *psz)
{
	DEFiRet;

	netsnmp_pdu    *pdu = NULL;
	oid             enterpriseoid[MAX_OID_LEN];
	size_t          enterpriseoidlen = MAX_OID_LEN;
	oid				oidSyslogMessage[MAX_OID_LEN];
	size_t			oLen = MAX_OID_LEN;
	int             status;
	char            *trap = NULL;
	const char		*strErr = NULL;

	/* Init SNMP Session if necessary */
	if (pData->snmpsession == NULL) {
		CHKiRet(omsnmp_initSession(pData));
	}
	
	/* String should not be NULL */
	ASSERT(psz != NULL);
	dbgprintf( "omsnmp_sendsnmp: ENTER - Syslogmessage = '%s'\n", (char*)psz);

	/* If SNMP Version1 is configured !*/
	if(pData->snmpsession->version == SNMP_VERSION_1) {
		pdu = snmp_pdu_create(SNMP_MSG_TRAP);

		/* Set enterprise */
		if(!snmp_parse_oid(pData->szEnterpriseOID == NULL ? "1.3.6.1.4.1.3.1.1" : (char*)pData->szEnterpriseOID,
				   enterpriseoid, &enterpriseoidlen )) {
			strErr = snmp_api_errstring(snmp_errno);
			errmsg.LogError(0, RS_RET_DISABLE_ACTION, "omsnmp_sendsnmp: Parsing EnterpriseOID "
					"failed '%s' with error '%s' \n", pData->szSyslogMessageOID, strErr);
			ABORT_FINALIZE(RS_RET_DISABLE_ACTION);
		}
		pdu->enterprise = (oid *) MALLOC(enterpriseoidlen * sizeof(oid));
		memcpy(pdu->enterprise, enterpriseoid, enterpriseoidlen * sizeof(oid));
		pdu->enterprise_length = enterpriseoidlen;

		/* Set Traptype */
		pdu->trap_type = pData->iTrapType; 
		
		/* Set SpecificType */
		pdu->specific_type = pData->iSpecificType;

		/* Set Updtime */
		pdu->time = get_uptime();
	}
	/* If SNMP Version2c is configured !*/
	else if (pData->snmpsession->version == SNMP_VERSION_2c) 
	{
		long sysuptime;
		char csysuptime[20];
		
		/* Create PDU */
		pdu = snmp_pdu_create(SNMP_MSG_TRAP2);
		
		/* Set uptime */
		sysuptime = get_uptime();
		snprintf( csysuptime, sizeof(csysuptime) , "%ld", sysuptime);
		trap = csysuptime;
		snmp_add_var(pdu, objid_sysuptime, sizeof(objid_sysuptime) / sizeof(oid), 't', trap);

		/* Now set the SyslogMessage Trap OID */
		if ( snmp_add_var(pdu, objid_snmptrap, sizeof(objid_snmptrap) / sizeof(oid), 'o',
			pData->szSnmpTrapOID == NULL ?  "1.3.6.1.4.1.19406.1.2.1" : (char*) pData->szSnmpTrapOID
			) != 0) {
			strErr = snmp_api_errstring(snmp_errno);
			errmsg.LogError(0, RS_RET_DISABLE_ACTION, "omsnmp_sendsnmp: Adding trap OID failed '%s' with error '%s' \n", pData->szSnmpTrapOID, strErr);
			ABORT_FINALIZE(RS_RET_DISABLE_ACTION);
		}
	}

	/* SET TRAP PARAMETER for SyslogMessage! */
/*	dbgprintf( "omsnmp_sendsnmp: SyslogMessage '%s'\n", psz );*/

	/* First create new OID object */
	if (snmp_parse_oid(pData->szSyslogMessageOID == NULL ?
			    "1.3.6.1.4.1.19406.1.1.2.1" : (char*)pData->szSyslogMessageOID,
				oidSyslogMessage, &oLen)) {
		int iErrCode = snmp_add_var(pdu, oidSyslogMessage, oLen, 's', (char*) psz);
		if (iErrCode) {
			const char *str = snmp_api_errstring(iErrCode);
			errmsg.LogError(0, RS_RET_DISABLE_ACTION,  "omsnmp_sendsnmp: Invalid SyslogMessage OID, error code '%d' - '%s'\n", iErrCode, str );
			ABORT_FINALIZE(RS_RET_DISABLE_ACTION);
		}
	} else {
		strErr = snmp_api_errstring(snmp_errno);
		errmsg.LogError(0, RS_RET_DISABLE_ACTION, "omsnmp_sendsnmp: Parsing SyslogMessageOID failed '%s' with error '%s' \n", pData->szSyslogMessageOID, strErr);

		ABORT_FINALIZE(RS_RET_DISABLE_ACTION);
	}

	/* Send the TRAP */
	status = snmp_send(pData->snmpsession, pdu) == 0;
	if (status)
	{
		/* Debug Output! */
		int iErrorCode = pData->snmpsession->s_snmp_errno;
		errmsg.LogError(0, RS_RET_SUSPENDED,  "omsnmp_sendsnmp: snmp_send failed error '%d', Description='%s'\n", iErrorCode*(-1), api_errors[iErrorCode*(-1)]);

		/* Clear Session */
		omsnmp_exitSession(pData);

		ABORT_FINALIZE(RS_RET_SUSPENDED);
	}

finalize_it:
	if(iRet != RS_RET_OK) {
		if(pdu != NULL) {
			snmp_free_pdu(pdu);
		}
	}

	dbgprintf( "omsnmp_sendsnmp: LEAVE\n");
	RETiRet;
}
Exemple #28
0
unsigned long
Evaluate_Expression(struct expValueTable_data *vtable_data)
{

    struct header_complex_index *hcindex;
    struct expObjectTable_data *objstorage, *objfound;
    struct expValueTable_data *valstorage;
    valstorage = vtable_data;

    char           *expression;
    char           *result, *resultbak;
    char           *temp, *tempbak;
    char            intchar[10];
    int             i = 0, j, k, l;
    long            value;
    unsigned long   result_u_long;
    temp = malloc(100);
    result = malloc(100);
    tempbak = temp;
    memset(result, 0, 100);
    *result = '\0';
    resultbak = result;

    expression = vtable_data->expression_data->expExpression;

    while (*expression != '\0') {
        if (*expression == '$') {
            objfound = NULL;
            i++;
            for (j = 1; j < 100; j++) {
                if ((*(expression + j) == '+') ||
                    (*(expression + j) == '-') ||
                    (*(expression + j) == '*') ||
                    (*(expression + j) == '/') ||
                    (*(expression + j) == '(') ||
                    (*(expression + j) == ')') ||
                    *(expression + j) == '\0') {
                    break;
                }
            }
            strncpy(temp, expression + 1, j - 1);
            *(temp + j - 1) = '\0';
            l = atoi(temp);
            expression = expression + j;
            /*
             *   here use snmpget to get value
             */
            for (hcindex = expObjectTableStorage; hcindex != NULL;
                 hcindex = hcindex->next) {
                objstorage = (struct expObjectTable_data *) hcindex->data;
                if (!strcmp
                    (objstorage->expExpressionOwner,
                     valstorage->expExpressionOwner)
                    && (objstorage->expExpressionOwnerLen ==
                        valstorage->expExpressionOwnerLen)
                    && !strcmp(objstorage->expExpressionName,
                               valstorage->expExpressionName)
                    && (objstorage->expExpressionNameLen ==
                        valstorage->expExpressionNameLen)
                    && (l == objstorage->expObjectIndex)) {
                    objfound = objstorage;
                    break;
                }
            }


            if (!objfound) {
                /* have err */
                return 0;
            }
            struct snmp_session *ss;
            struct snmp_pdu *pdu;
            struct snmp_pdu *response;

            oid             anOID[MAX_OID_LEN];
            size_t          anOID_len;

            memcpy(anOID, objfound->expObjectID,
                   objfound->expObjectIDLen * sizeof(oid));
            anOID_len = objfound->expObjectIDLen;
            if (objfound->expObjectIDWildcard == EXPOBJCETIDWILDCARD_TRUE) {
                anOID_len =
                    anOID_len + valstorage->expValueInstanceLen - 2;
                memcpy(anOID + objfound->expObjectIDLen,
                       valstorage->expValueInstance + 2,
                       (valstorage->expValueInstanceLen -
                        2) * sizeof(oid));
            }
            struct variable_list *vars;
            int             status;

            /*
             * Initialize the SNMP library
             */

            /*
             * Initialize a "session" that defines who we're going to talk to
             */
            session.version = vtable_data->expression_data->pdu_version;

            /*
             * set the SNMPv1 community name used for authentication 
             */
            session.community =
                vtable_data->expression_data->pdu_community;
            session.community_len =
                vtable_data->expression_data->pdu_community_len;
            /*
             * Open the session
             */
            SOCK_STARTUP;
            ss = snmp_open(&session);   /* establish the session */

            if (!ss) {
                /* err */
                exit(2);
            }
            pdu = snmp_pdu_create(SNMP_MSG_GET);
            snmp_add_null_var(pdu, anOID, anOID_len);

            /*
             * Send the Request out.
             */
            status = snmp_synch_response(ss, pdu, &response);

            /*
             * Process the response.
             */
            if (status == STAT_SUCCESS
                && response->errstat == SNMP_ERR_NOERROR) {
                /*
                 * SUCCESS: Print the result variables
                 */

                vars = response->variables;
                value = *(vars->val.integer);
                sprintf(intchar, "%lu", value);
                for (k = 1; k <= strlen(intchar); k++) {
                    *result = intchar[k - 1];
                    result++;
                }

            } else {
                /*
                 * FAILURE: print what went wrong!
                 */

                if (status == STAT_SUCCESS)
                    fprintf(stderr, "Error in packet\nReason: %s\n",
                            snmp_errstring(response->errstat));
                else
                    snmp_sess_perror("snmpget", ss);

            }

            /*
             * Clean up:
             *  1) free the response.
             *  2) close the session.
             */
            if (response)
                snmp_free_pdu(response);
            snmp_close(ss);

            SOCK_CLEANUP;

        } else {
            *result = *expression;
            result++;
            expression++;
        }
    }
    result_u_long = get_result(resultbak);
    free(tempbak);
    free(resultbak);
    return result_u_long;
}
Exemple #29
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);
}
Exemple #30
0
/*
 * Print a summary of connections related to an Internet
 * protocol (currently only TCP).  For TCP, also give state of connection.
 */
void
protopr6(const char *name)
{
    struct tcpconn_entry *tcpconn = NULL, *tcplast = NULL, *tp, *newtp;
    struct udp_entry *udpconn = NULL, *udplast = NULL, *up, *newup;
    netsnmp_pdu    *request = NULL, *response = NULL;
    netsnmp_variable_list *vp;
    oid            *instance;
    int             first, status;

    response = NULL;
    if (strncmp(name, "tcp", 3) == 0) {
        request = snmp_pdu_create(SNMP_MSG_GETNEXT);
        snmp_add_null_var(request, oid_tcpconntable,
                          sizeof(oid_tcpconntable) / sizeof(oid));
        status = STAT_SUCCESS;
    } else
        status = STAT_TIMEOUT;
    while (status == STAT_SUCCESS) {
        if (response)
            snmp_free_pdu(response);
        response = NULL;
        status = snmp_synch_response(Session, request, &response);
        if (status != STAT_SUCCESS
            || response->errstat != SNMP_ERR_NOERROR) {
            snmp_perror("SNMP request failed");
            break;
        }
        vp = response->variables;
        if (!vp)
            break;
        if (vp->name_length != 46 ||
            memcmp(vp->name, oid_tcpconntable, sizeof(oid_tcpconntable))) {
            break;
        }

        request = snmp_pdu_create(SNMP_MSG_GETNEXT);
        snmp_add_null_var(request, vp->name, vp->name_length);

        instance = vp->name + 10;
        for (tp = tcpconn; tp != NULL; tp = tp->next) {
            if (!memcmp(instance, tp->instance, sizeof(tp->instance)))
                break;
        }
        if (tp == NULL) {
            tp = (struct tcpconn_entry *) calloc(1,
                                                 sizeof(struct
                                                        tcpconn_entry));
            if (tp == NULL)
                break;
            if (tcplast != NULL)
                tcplast->next = tp;
            tcplast = tp;
            if (tcpconn == NULL)
                tcpconn = tp;
            memmove(tp->instance, instance, sizeof(tp->instance));
        }

        if (vp->name[TCP_ENTRY] == TCPCONN_STATE) {
            tp->state = *vp->val.integer;
            tp->stateSet = 1;
        }

        if (vp->name[TCP_ENTRY] == TCPCONN_LOCADDR) {
            memmove(&tp->localAddress, vp->val.string,
                    sizeof(struct in6_addr));
            tp->locAddrSet = 1;
        }

        if (vp->name[TCP_ENTRY] == TCPCONN_LOCPORT) {
            if (validUShortAssign(&tp->localPort, *vp->val.integer,
                                  "TCPCONN_LOCPORT"))
                tp->locPortSet = 1;
        }

        if (vp->name[TCP_ENTRY] == TCPCONN_REMADDR) {
            memmove(&tp->remoteAddress, vp->val.string,
                    sizeof(struct in6_addr));
            tp->remAddrSet = 1;
        }

        if (vp->name[TCP_ENTRY] == TCPCONN_REMPORT) {
            if (validUShortAssign(&tp->remotePort, *vp->val.integer,
                                  "TCPCONN_REMPORT"))
                tp->remPortSet = 1;
        }
    }
    if (response)
        snmp_free_pdu(response);
    response = NULL;

    for (first = 1, tp = tcpconn, newtp = NULL; tp != NULL; tp = tp->next) {
        if (newtp)
            free(newtp);
        newtp = tp;
        if (!(tp->stateSet && tp->locAddrSet
              && tp->locPortSet && tp->remAddrSet && tp->remPortSet)) {
            printf("incomplete entry\n");
            continue;
        }
        if (!aflag && tp->state == MIB_TCPCONNSTATE_LISTEN)
            continue;
        if (first) {
            printf("Active Internet (%s) Connections", name);
            if (aflag)
                printf(" (including servers)");
            putchar('\n');
            printf("%-5.5s %-28.28s %-28.28s %s\n",
                   "Proto", "Local Address", "Foreign Address", "(state)");
            first = 0;
        }
        printf("%-5.5s ", name);
        inet6print(&tp->localAddress, tp->localPort, name);
        inet6print(&tp->remoteAddress, tp->remotePort, name);
        if (tp->state < 1 || tp->state > TCP_NSTATES)
            printf(" %d", tp->state);
        else
            printf(" %s", tcpstates[tp->state]);
        putchar('\n');
    }
    if (newtp)
        free(newtp);

    response = NULL;
    if (strncmp(name, "udp", 3) == 0) {
        request = snmp_pdu_create(SNMP_MSG_GETNEXT);
        snmp_add_null_var(request, oid_udptable,
                          sizeof(oid_udptable) / sizeof(oid));
        status = STAT_SUCCESS;
    } else
        status = STAT_TIMEOUT;
    while (status == STAT_SUCCESS) {
        if (response)
            snmp_free_pdu(response);
        response = NULL;
        status = snmp_synch_response(Session, request, &response);
        if (status != STAT_SUCCESS
            || response->errstat != SNMP_ERR_NOERROR) {
            fprintf(stderr, "SNMP request failed\n");
            break;
        }
        vp = response->variables;
        if (!vp)
            break;
        if (vp->name_length != 28 ||
            memcmp(vp->name, oid_udptable, sizeof(oid_udptable))) {
            break;
        }

        request = snmp_pdu_create(SNMP_MSG_GETNEXT);
        snmp_add_null_var(request, vp->name, vp->name_length);

        instance = vp->name + 10;
        for (up = udpconn; up != NULL; up = up->next) {
            if (!memcmp(instance, up->instance, sizeof(up->instance)))
                break;
        }
        if (up == NULL) {
            up = (struct udp_entry *) calloc(1, sizeof(struct udp_entry));
            if (up == NULL)
                break;
            if (udplast != NULL)
                udplast->next = up;
            udplast = up;
            if (udpconn == NULL)
                udpconn = up;
            memmove(up->instance, instance, sizeof(up->instance));
        }

        if (vp->name[UDP_ENTRY] == UDP_LOCADDR) {
            memmove(&up->localAddress, vp->val.string,
                    sizeof(struct in6_addr));
            up->locAddrSet = 1;
        }

        if (vp->name[UDP_ENTRY] == UDP_LOCPORT) {
            if (validUShortAssign(&up->localPort, *vp->val.integer,
                                  "UDP_LOCPORT"))
                up->locPortSet = 1;
        }
    }
    if (response)
        snmp_free_pdu(response);
    response = NULL;

    for (first = 1, up = udpconn, newup = NULL; up != NULL; up = up->next) {
        if (newup)
            free(newup);
        newup = up;
        if (!(up->locAddrSet && up->locPortSet)) {
            printf("incomplete entry\n");
            continue;
        }
        if (first) {
            printf("Active Internet (%s) Connections", name);
            putchar('\n');
            printf("%-5.5s %-28.28s\n", "Proto", "Local Address");
            first = 0;
        }
        printf("%-5.5s ", name);
        inet6print(&up->localAddress, up->localPort, name);
        putchar('\n');
    }
    if (newup)
        free(newup);

}