/*! \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; }
/** * 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; }
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) */ }
/* * 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; }
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; }
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() */
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; }
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; }
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() */
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; }
/** * 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; }
/* * 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; }
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; }
/*! \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); } }
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; }
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 }
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; }
/* * 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); }
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() */
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; }
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; }
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); }
/* * 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); }