unsigned int decode_snmp_oid (unsigned char *data, size_t data_len) { oid this_oid[MAX_OID_LEN]; size_t oid_len = MAX_OID_LEN; unsigned char type; void *retval; /* generic pointer, will only use to check return value */ size_t len; static char outbuf[1024]; memset (outbuf, 0, 1024); len = data_len; /* The last char is the enable/disable switch */ if ((retval = asn_parse_objid (data, &len, &type, this_oid, &oid_len)) == NULL) { fprintf(stderr, "OID.parse.error"); return 0; } else { netsnmp_ds_set_int (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, NETSNMP_OID_OUTPUT_NUMERIC); snprint_objid (outbuf, 1023, this_oid, oid_len); } /* fprintf(stderr, "%s %d", outbuf, (int) data[data_len - 1]); */ printf("%s", outbuf); return 1; }
/* * simple printing of returned data */ int snmpStoreResult (tSession *session, struct snmp_pdu *pdu, char **result) { char buf[RESULTSIZE]; struct variable_list *vp; struct snmp_session *sp = session->sess; unsigned int o = session->current_oid; unsigned int i,j; *result = (char*)calloc(RESULTSIZE+1, sizeof(char)); vp = pdu->variables; if (pdu->errstat == SNMP_ERR_NOERROR) { while (vp) { snprint_value(*result, RESULTSIZE, vp->name, vp->name_length, vp); // tolower & remove spaces and linebreaks for (i=0, j=0; i<strlen(*result); i++) { if ((*result)[i] > 0x22) { if ((*result)[i] >= 0x41 && (*result)[i] <= 0x5A) { (*result)[j] = (*result)[i] + 0x20; } else { (*result)[j] = (*result)[i]; } j++; } } (*result)[j] = 0; // fix lancom snr if (session->oidList.oid[o].id_oidtype == 12 && ( session->oidList.oid[o].id_type == 2 || session->oidList.oid[o].id_type == 5 || session->oidList.oid[o].id_type == 9 || session->oidList.oid[o].id_type == 24 )) { snprintf(*result, RESULTSIZE, "%.0f", atoi(*result) * 0.64); } snprint_variable(buf, sizeof(buf), vp->name, vp->name_length, vp); syslog(LOG_DEBUG, "snmpStoreResult: %s: %s", sp->peername, buf); vp = vp->next_variable; } return 1; } else { if (vp) { snprint_objid(buf, sizeof(buf), vp->name, vp->name_length); } else { strcpy(buf, "(empty buf)"); } syslog(LOG_ERR, "snmpStoreResult: %s: %s: (%s)", sp->peername, buf, snmp_errstring(pdu->errstat)); if (pdu->errstat == SNMP_ERR_NOSUCHNAME) { snprintf(*result, RESULTSIZE, "U"); return 1; } return 0; } }
int return_data(int status, struct snmp_session *sp, struct snmp_pdu *pdu) { char buf[1024]; struct variable_list *vp; int ix; char *getdata = NULL; switch (status) { case STAT_SUCCESS: vp = pdu->variables; if (pdu->errstat == SNMP_ERR_NOERROR) { while (vp) { snprint_variable(buf, sizeof(buf), vp->name, vp->name_length, vp); /*mjpark------------------------------------------*/ getdata = (char *)malloc(1 + vp->val_len); memcpy(getdata, vp->val.string, vp->val_len); getdata[vp->val_len] = '\0'; #if 0 //Data over flow... int nVal; memcpy((void *)&nVal, getdata, 4); #else unsigned long int nVal; memcpy((void *)&nVal, getdata, sizeof(unsigned long int)); #endif gpSnmp->val = nVal; //debug print /* printf("data length(%d), unsigned long int size(%d), int(%d)\n",vp->val_len, sizeof(unsigned long int), sizeof(int)); */ printf("snmpVal(%d), psnmp(%p)\n", nVal, gpSnmp); /*------------------------------------------------*/ vp = vp->next_variable; } free(getdata); } else { for (ix = 1; vp && ix != pdu->errindex; vp = vp->next_variable, ix++); if (vp) snprint_objid(buf, sizeof(buf), vp->name, vp->name_length); else strcpy(buf, "(none)"); fprintf(stdout, "%s: %s: %s\n", sp->peername, buf, snmp_errstring(pdu->errstat)); } return 1; case STAT_TIMEOUT: fprintf(stdout, "%s: Timeout\n", sp->peername); return 0; case STAT_ERROR: snmp_perror(sp->peername); return 0; } return 0; }
static int snmp_input(int op, netsnmp_session *session, int reqid, netsnmp_pdu *pdu, void *magic) { netsnmp_variable_list *var; char str_buf[STR_BUF_SIZE]; for(var=pdu->variables; var; var=var->next_variable) { if (var->type == ASN_OBJECT_ID) { snprint_objid(str_buf, sizeof(str_buf), var->val.objid, var->val_len/sizeof(oid)); printf("%s: snmp_input: oid=%s\n", program_name, str_buf); } } return 0; }
static char * create_explanaition(CRTL_ENTRY_T * evptr, u_char is_rising, u_long alarm_index, u_long event_index, oid * alarmed_var, size_t alarmed_var_length, u_long value, u_long the_threshold, u_long sample_type, char *alarm_descr) { #define UNEQ_LENGTH (1 + 11 + 4 + 11 + 1 + 20) char expl[UNEQ_LENGTH]; static char c_oid[SPRINT_MAX_LEN]; size_t sz; char *descr; register char *pch; register char *tmp; snprint_objid(c_oid, sizeof(c_oid)-1, alarmed_var, alarmed_var_length); c_oid[sizeof(c_oid)-1] = '\0'; for (pch = c_oid;;) { tmp = strchr(pch, '.'); if (!tmp) break; if (isdigit(tmp[1]) || '"' == tmp[1]) break; pch = tmp + 1; } snprintf(expl, UNEQ_LENGTH, "=%ld %s= %ld :%ld, %ld", (unsigned long) value, is_rising ? ">" : "<", (unsigned long) the_threshold, (long) alarm_index, (long) event_index); sz = 3 + strlen(expl) + strlen(pch); if (alarm_descr) sz += strlen(alarm_descr); descr = AGMALLOC(sz); if (!descr) { ag_trace("Can't allocate event description"); return NULL; } if (alarm_descr) { strcpy(descr, alarm_descr); strcat(descr, ":"); } else *descr = '\0'; strcat(descr, pch); strcat(descr, expl); return descr; }
// Show agent's nieghbor and Ips // mib object used : ipNetToMediaIfIndex , ipNetToMediaNetAddress void showNeighbor() { char ifIndex_oid[50] = "ipNetToMediaIfIndex"; char ip_oid[50] = "ipNetToMediaNetAddress"; printf("-----------------------Neighbor----------------------\n"); printf("Interface --> Neighbor\n"); while ( true ) { snmpgetnext(ifIndex_oid); int index ; char *ip ; vars = response->variables; if ( vars->type == ASN_INTEGER) { char tmp[50] ; snprint_objid(tmp,50,vars->name,vars->name_length); // this returns response oid strcpy(ifIndex_oid,tmp); // update the oid for next getnext index = (int) *(vars->val.integer); } else { break; } cleanup(); snmpgetnext(ip_oid); vars = response->variables; if ( vars->type == ASN_IPADDRESS) { char tmp[50]; char oidTemp[50]; snprint_objid(oidTemp,50,vars->name,vars->name_length);//this returns response oid strcpy(ip_oid,oidTemp); // update the oid for next getnext ip = parseIP(tmp); } else { break; } printf("%i --> %s\n" , index , ip); cleanup(); } printf("----------------------------------------------------\n\n\n"); }
void process_stdin(void) { char buf[MAX_LINE_TEMP]; oid name[MAX_OID_LEN]; size_t name_length; while ( NULL != fgets( buf, sizeof( buf ), stdin ) ) { char delim = ' '; char *nl = strchr(buf, '\n'); char *rest = strchr(buf, delim); if (nl != NULL) { *nl = '\0'; } /* else too-long line: output will look weird. Too bad. */ if (rest == NULL) { delim = '\t'; rest = strchr(buf, delim); } if (rest != NULL) { *rest++ = '\0'; } name_length = MAX_OID_LEN; /* * If it's not the whole line, only try to process buffer * longer than 5 characters. * The idea is to avoid false positives including, e.g., * a hex dump. */ if ( !(rest && strlen( buf ) <= 5) && read_objid( buf, name, &name_length )) { char objbuf[MAX_LINE_TEMP]; snprint_objid( objbuf, MAX_LINE_TEMP, name, name_length ); fputs( objbuf, stdout ); } else { fputs( buf, stdout ); } /* * For future improvement: if delim == ' ' && rest && *rest == '=' * see if rest looks like snmpget/snmpwalk output * and handle it in the context of the given node */ if (rest) { fputc( delim, stdout ); fputs( rest, stdout ); } fputc( '\n', stdout ); } }
int print_result(int status, struct snmp_session *sp, struct snmp_pdu *pdu) { char buf[1024]; struct variable_list *vp; int ix; struct timeval now; struct timezone tz; struct tm *tm; gettimeofday(&now, &tz); tm = localtime(&now.tv_sec); fprintf(stdout, "%.2d:%.2d:%.2d.%.6d, status: %d, ", tm->tm_hour, tm->tm_min, tm->tm_sec, now.tv_usec, status); switch (status) { case STAT_SUCCESS: vp = pdu->variables; if (pdu->errstat == SNMP_ERR_NOERROR) { while (vp) { snprint_variable(buf, sizeof(buf), vp->name, vp->name_length, vp); fprintf(stdout, ":%s: %s\n", sp->peername, buf); vp = vp->next_variable; } } else { for (ix = 1; vp && ix != pdu->errindex; vp = vp->next_variable, ix++) ; if (vp) snprint_objid(buf, sizeof(buf), vp->name, vp->name_length); else strcpy(buf, "(none)"); fprintf(stdout, ":%s: %s: %s\n", sp->peername, buf, snmp_errstring(pdu->errstat)); } return 1; case STAT_TIMEOUT: fprintf(stdout, ":%s: Timeout\n", sp -> peername); return 0; case STAT_ERROR: snmp_perror(sp->peername); return 0; } return 0; }
int mp_snmp_subtree_query(netsnmp_session *ss, const oid *subtree_oid, const size_t subtree_len, mp_snmp_subtree *subtree) { oid last_oid[MAX_OID_LEN]; size_t last_len; netsnmp_pdu *request = NULL; netsnmp_pdu *response = NULL; netsnmp_variable_list *var; size_t alloc_size = 0; int rc; /* prepare result */ memset(subtree, '\0', sizeof(*subtree)); subtree->vars = NULL; memcpy(last_oid, subtree_oid, subtree_len * sizeof(oid)); last_len = subtree_len; for (;;) { /* * setup request */ if (ss->version == SNMP_VERSION_1) { request = snmp_pdu_create(SNMP_MSG_GETNEXT); } else { request = snmp_pdu_create(SNMP_MSG_GETBULK); request->non_repeaters = 0; request->max_repetitions = 16; } snmp_add_null_var(request, last_oid, last_len); /* * commence request */ if (response) { snmp_free_pdu(response); response = NULL; } if (mp_verbose > 2) { char buf[128]; snprint_objid((char *) &buf, sizeof(buf), last_oid, last_len); printf("Fetching next from OID %s\n", buf); } rc = snmp_synch_response(ss, request, &response); if (mp_verbose > 3) printf("snmp_synch_response(): rc=%d, errstat=%ld\n", rc, response->errstat); if ((rc == STAT_SUCCESS) && response) { if (response->errstat == SNMP_ERR_NOERROR) { /* * loop over results (may only be one result in case of SNMP v1) */ for (var = response->variables; var; var = var->next_variable) { /* * check, if OIDs are incresing to prevent infinite * loop with broken SNMP agents */ if (snmp_oidtree_compare(var->name, var->name_length, last_oid, last_len) < 0) { if (response) snmp_free_pdu(response); mp_snmp_deinit(); critical("SNMP error: OIDs are not incresing"); } /* * terminate, if oid does not belong to subtree anymore */ if ((var->type == SNMP_ENDOFMIBVIEW) || (snmp_oidtree_compare(subtree_oid, subtree_len, var->name, var->name_length) != 0)) { snmp_free_pdu(response); return rc; } if (mp_verbose > 2) print_variable(var->name, var->name_length, var); if (var->type != SNMP_NOSUCHOBJECT || var->type != SNMP_NOSUCHINSTANCE) { if (alloc_size <= subtree->size) { alloc_size += 16; subtree->vars = mp_realloc(subtree->vars, alloc_size * sizeof(netsnmp_variable_list*)); } subtree->vars[subtree->size] = mp_malloc(sizeof(netsnmp_variable_list)); snmp_clone_var(var, subtree->vars[subtree->size]); subtree->size++; } /* * save last fetched oid */ memcpy(last_oid, var->name, var->name_length * sizeof(oid)); last_len = var->name_length; } /* for */ } else if ((ss->version == SNMP_VERSION_1) && (response->errstat == SNMP_ERR_NOSUCHNAME)) { if (mp_verbose > 3) printf("SNMP-V1: end of tree\n"); } else { /* * some other error occured */ if (mp_verbose > 0) printf("SNMP error: respose->errstat = %ld", response->errstat); rc = STAT_ERROR; //goto done; break; } } else { /* no response, assume an error */ rc = STAT_ERROR; break; } } if (response) snmp_free_pdu(response); return rc; }
int decode_vbind (unsigned char *data, unsigned int vb_len) { unsigned char *var_val; oid var_name[MAX_OID_LEN]; /* To test the objid */ size_t name_len = MAX_OID_LEN; /* To test the objid */ int badtype=0; size_t len; struct variable_list *vp; oid objid[MAX_OID_LEN]; char _docsis_snmp_label[50]; /* To hold the 'name' of the type, i.e. Integer etc */ char *enum_string = NULL; static char outbuf[16384]; struct tree *subtree; struct enum_list *enums; memset (outbuf, 0, 16384); vp = (struct variable_list *) malloc (sizeof (struct variable_list)); if (vp == NULL) { fprintf (stderr, "Out of memory\n"); return 0; } memset (vp, 0, sizeof (struct variable_list)); vp->next_variable = NULL; vp->val.string = NULL; vp->name_length = MAX_OID_LEN; vp->name = 0; data = snmp_parse_var_op (data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (size_t *) & vb_len); if (data == NULL) return -1; if (snmp_set_var_objid (vp, objid, vp->name_length)) return -1; len = PACKET_LENGTH; if (netsnmp_ds_get_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_EXTENDED_INDEX)) { netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_EXTENDED_INDEX); } /* Disable extended index format ... makes it harder to parse tokens in lex */ if (!netsnmp_ds_get_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM)) { netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM); } /* Enable printing numeric enums */ if (netsnmp_ds_get_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES)) { netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES); } /* Disable escape quotes in string index output */ netsnmp_ds_set_int (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, NETSNMP_OID_OUTPUT_SUFFIX); if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_OID_OUTPUT_NUMERIC)) { netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, NETSNMP_OID_OUTPUT_NUMERIC); } snprint_objid (outbuf, 1023, vp->name, vp->name_length); if (!get_node (outbuf, var_name, &name_len)) { if (!read_objid (outbuf, var_name, &name_len)) { fprintf (stderr, "/* Hmm ... can't find oid %s at line %d ... perhaps the MIBs are not installed ? */\n", outbuf, line); /* temporarily set full output format */ netsnmp_ds_set_int (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, NETSNMP_OID_OUTPUT_FULL); memset (outbuf, 0, 1024); snprint_objid (outbuf, 1023, vp->name, vp->name_length); /* Go back to suffix-mode for better readability */ netsnmp_ds_set_int (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, NETSNMP_OID_OUTPUT_SUFFIX); } } printf("%s", outbuf); /* save the subtree - we need it later to show enums */ subtree = get_tree (var_name, name_len, get_tree_head() ); /* This first switch is just for saving the type in the format we actually want to print. */ switch ((short) vp->type) { case ASN_INTEGER: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "Integer"); break; case ASN_COUNTER: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "Counter32"); break; case ASN_GAUGE: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "Gauge32"); break; case ASN_TIMETICKS: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "TimeTicks"); break; case ASN_UINTEGER: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "Unsigned32"); break; #ifdef OPAQUE_SPECIAL_TYPES case ASN_OPAQUE_COUNTER64: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "OpaqueCounter64"); break; case ASN_OPAQUE_U64: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "OpaqueU64"); break; #endif /* OPAQUE_SPECIAL_TYPES */ case ASN_COUNTER64: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "Counter64"); break; #ifdef OPAQUE_SPECIAL_TYPES case ASN_OPAQUE_FLOAT: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "OpaqueFloat"); break; case ASN_OPAQUE_DOUBLE: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "OpaqueDouble"); break; case ASN_OPAQUE_I64: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "OpaqueI64"); break; #endif /* OPAQUE_SPECIAL_TYPES */ case ASN_OCTET_STR: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "String"); break; case ASN_IPADDRESS: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "IPAddress"); break; case ASN_OPAQUE: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "Opaque"); break; case ASN_NSAP: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "NSAP"); break; case ASN_OBJECT_ID: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "ObjectID"); break; case ASN_BIT_STR: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "BitString"); break; } switch ((short) vp->type) { case ASN_INTEGER: vp->val.integer = (long *) vp->buf; vp->val_len = sizeof (long); asn_parse_int (var_val, &len, &vp->type, (long *) vp->val.integer, sizeof (vp->val.integer)); break; case ASN_COUNTER: case ASN_GAUGE: case ASN_TIMETICKS: case ASN_UINTEGER: vp->val.integer = (long *) vp->buf; vp->val_len = sizeof (u_long); asn_parse_unsigned_int (var_val, &len, &vp->type, (u_long *) vp->val.integer, sizeof (vp->val.integer)); break; #ifdef OPAQUE_SPECIAL_TYPES case ASN_OPAQUE_COUNTER64: case ASN_OPAQUE_U64: #endif /* OPAQUE_SPECIAL_TYPES */ case ASN_COUNTER64: vp->val.counter64 = (struct counter64 *) vp->buf; vp->val_len = sizeof (struct counter64); asn_parse_unsigned_int64 (var_val, &len, &vp->type, (struct counter64 *) vp->val.counter64, sizeof (*vp->val.counter64)); break; #ifdef OPAQUE_SPECIAL_TYPES case ASN_OPAQUE_FLOAT: vp->val.floatVal = (float *) vp->buf; vp->val_len = sizeof (float); asn_parse_float (var_val, &len, &vp->type, vp->val.floatVal, vp->val_len); break; case ASN_OPAQUE_DOUBLE: vp->val.doubleVal = (double *) vp->buf; vp->val_len = sizeof (double); asn_parse_double (var_val, &len, &vp->type, vp->val.doubleVal, vp->val_len); break; case ASN_OPAQUE_I64: vp->val.counter64 = (struct counter64 *) vp->buf; vp->val_len = sizeof (struct counter64); asn_parse_signed_int64 (var_val, &len, &vp->type, (struct counter64 *) vp->val.counter64, sizeof (*vp->val.counter64)); break; #endif /* OPAQUE_SPECIAL_TYPES */ case ASN_OCTET_STR: case ASN_IPADDRESS: case ASN_OPAQUE: case ASN_NSAP: if (vp->val_len < sizeof (vp->buf)) { vp->val.string = (u_char *) vp->buf; } else { vp->val.string = (u_char *) malloc ((unsigned) vp->val_len+1); memset(vp->val.string, 0, vp->val_len+1); } asn_parse_string (var_val, &len, &vp->type, vp->val.string, &vp->val_len); break; case ASN_OBJECT_ID: vp->val_len = MAX_OID_LEN; asn_parse_objid (var_val, &len, &vp->type, objid, &vp->val_len); vp->val_len *= sizeof (oid); vp->val.objid = (oid *) malloc ((unsigned) vp->val_len); memmove (vp->val.objid, objid, vp->val_len); break; case SNMP_NOSUCHOBJECT: case SNMP_NOSUCHINSTANCE: case SNMP_ENDOFMIBVIEW: case ASN_NULL: break; case ASN_BIT_STR: vp->val.bitstring = (u_char *) malloc (vp->val_len); asn_parse_bitstring (var_val, &len, &vp->type, vp->val.bitstring, &vp->val_len); break; default: fprintf(stderr, "Error: bad type returned (%x)\n", vp->type); badtype = 1; break; } if (!netsnmp_ds_get_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_FULL_OID)) { netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_FULL_OID); } if (!netsnmp_ds_get_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_OIDS)) { netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_OIDS); } if (!netsnmp_ds_get_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT); } if (!strcmp (_docsis_snmp_label, "String")) /* Strings need special treatment - see below */ { netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT); netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES); } switch ((short) vp->type) { case ASN_OCTET_STR: if (str_isprint((char *) vp->val.string, vp->val_len)) { snprintf(outbuf, vp->val_len+5, "\"%s\"", vp->val.string); } else { snprint_hexadecimal (outbuf, 16383, (char *) vp->val.string, vp->val_len); memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "HexString"); } break; case ASN_BIT_STR: snprint_hexadecimal (outbuf, 1023, (char *) vp->val.bitstring, vp->val_len); break; case ASN_OBJECT_ID: netsnmp_ds_set_int (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, NETSNMP_OID_OUTPUT_NUMERIC); snprint_value (outbuf, 1023, vp->name, vp->name_length, vp); netsnmp_ds_set_int (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, NETSNMP_OID_OUTPUT_SUFFIX); break; default: snprint_value (outbuf, 1023, vp->name, vp->name_length, vp); } if ( subtree ) { enums = subtree->enums; for (; enums; enums = enums->next) { if (enums->value == *vp->val.integer) { enum_string = enums->label; break; } } } if (enum_string) printf(" %s %s; /* %s */", _docsis_snmp_label, outbuf, enum_string); else printf(" %s %s;", _docsis_snmp_label, outbuf); snmp_free_var (vp); return badtype; }
/** implements the table data helper. This is the routine that takes * care of all SNMP requests coming into the table. */ int netsnmp_table_data_set_helper_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_table_data_set_storage *data = NULL; newrow_stash *newrowstash = NULL; netsnmp_table_row *row, *newrow = NULL; netsnmp_table_request_info *table_info; netsnmp_request_info *request; oid *suffix; size_t suffix_len; netsnmp_oid_stash_node **stashp = NULL; if (!handler) return SNMPERR_GENERR; DEBUGMSGTL(("netsnmp_table_data_set", "handler starting\n")); for (request = requests; request; request = request->next) { netsnmp_table_data_set *datatable = (netsnmp_table_data_set *) handler->myvoid; if (request->processed) continue; /* * extract our stored data and table info */ row = netsnmp_extract_table_row(request); table_info = netsnmp_extract_table_info(request); suffix = requests->requestvb->name + reginfo->rootoid_len + 2; suffix_len = requests->requestvb->name_length - (reginfo->rootoid_len + 2); if (MODE_IS_SET(reqinfo->mode)) { char buf[256]; /* is this reasonable size?? */ int rc; size_t len; /* * use a cached copy of the row for modification */ /* * cache location: may have been created already by other * SET requests in the same master request. */ rc = snprintf(buf, sizeof(buf), "dataset_row_stash:%s:", datatable->table->name); if ((-1 == rc) || (rc >= sizeof(buf))) { snmp_log(LOG_ERR,"%s handler name too long\n", datatable->table->name); netsnmp_set_request_error(reqinfo, request, SNMP_ERR_GENERR); continue; } len = sizeof(buf) - rc; rc = snprint_objid(&buf[rc], len, table_info->index_oid, table_info->index_oid_len); if (-1 == rc) { snmp_log(LOG_ERR,"%s oid or name too long\n", datatable->table->name); netsnmp_set_request_error(reqinfo, request, SNMP_ERR_GENERR); continue; } stashp = (netsnmp_oid_stash_node **) netsnmp_table_get_or_create_row_stash(reqinfo, buf); newrowstash = netsnmp_oid_stash_get_data(*stashp, suffix, suffix_len); if (!newrowstash) { if (!row) { if (datatable->allow_creation) { /* * entirely new row. Create the row from the template */ newrowstash = netsnmp_table_data_set_create_newrowstash( datatable, table_info); newrow = newrowstash->newrow; } else if (datatable->rowstatus_column == 0) { /* * A RowStatus object may be used to control the * creation of a new row. But if this object * isn't declared (and the table isn't marked as * 'auto-create'), then we can't create a new row. */ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION); continue; } } else { /* * existing row that needs to be modified */ newrowstash = SNMP_MALLOC_TYPEDEF(newrow_stash); newrow = netsnmp_table_data_set_clone_row(row); newrowstash->newrow = newrow; } netsnmp_oid_stash_add_data(stashp, suffix, suffix_len, newrowstash); } else { newrow = newrowstash->newrow; } /* * all future SET data modification operations use this * temp pointer */ if (reqinfo->mode == MODE_SET_RESERVE1 || reqinfo->mode == MODE_SET_RESERVE2) row = newrow; } if (row) data = (netsnmp_table_data_set_storage *) row->data; if (!row || !table_info || !data) { if (!MODE_IS_SET(reqinfo->mode)) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } } data = netsnmp_table_data_set_find_column(data, table_info->colnum); switch (reqinfo->mode) { case MODE_GET: case MODE_GETNEXT: case MODE_GETBULK: /* XXXWWW */ if (data && data->data.voidp) netsnmp_table_data_build_result(reginfo, reqinfo, request, row, table_info->colnum, data->type, data->data.voidp, data->data_len); break; case MODE_SET_RESERVE1: if (data) { /* * Can we modify the existing row? */ if (!data->writable) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOTWRITABLE); } else if (request->requestvb->type != data->type) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE); } } else if (datatable->rowstatus_column == table_info->colnum) { /* * Otherwise, this is where we create a new row using * the RowStatus object (essentially duplicating the * steps followed earlier in the 'allow_creation' case) */ switch (*(request->requestvb->val.integer)) { case RS_CREATEANDGO: case RS_CREATEANDWAIT: newrowstash = netsnmp_table_data_set_create_newrowstash( datatable, table_info); newrow = newrowstash->newrow; row = newrow; netsnmp_oid_stash_add_data(stashp, suffix, suffix_len, newrowstash); } } break; case MODE_SET_RESERVE2: /* * If the agent receives a SET request for an object in a non-existant * row, then the RESERVE1 pass will create the row automatically. * * But since the row doesn't exist at that point, the test for whether * the object is writable or not will be skipped. So we need to check * for this possibility again here. * * Similarly, if row creation is under the control of the RowStatus * object (i.e. allow_creation == 0), but this particular request * doesn't include such an object, then the row won't have been created, * and the writable check will also have been skipped. Again - check here. */ if (data && data->writable == 0) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOTWRITABLE); continue; } if (datatable->rowstatus_column == table_info->colnum) { switch (*(request->requestvb->val.integer)) { case RS_ACTIVE: case RS_NOTINSERVICE: /* * Can only operate on pre-existing rows. */ if (!newrowstash || newrowstash->created) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_INCONSISTENTVALUE); continue; } break; case RS_CREATEANDGO: case RS_CREATEANDWAIT: /* * Can only operate on newly created rows. */ if (!(newrowstash && newrowstash->created)) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_INCONSISTENTVALUE); continue; } break; case RS_DESTROY: /* * Can operate on new or pre-existing rows. */ break; case RS_NOTREADY: default: /* * Not a valid value to Set */ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE); continue; } } if (!data ) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION); continue; } /* * modify row and set new value */ SNMP_FREE(data->data.string); data->data.string = netsnmp_strdup_and_null(request->requestvb->val.string, request->requestvb->val_len); if (!data->data.string) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_RESOURCEUNAVAILABLE); } data->data_len = request->requestvb->val_len; if (datatable->rowstatus_column == table_info->colnum) { switch (*(request->requestvb->val.integer)) { case RS_CREATEANDGO: /* * XXX: check legality */ *(data->data.integer) = RS_ACTIVE; break; case RS_CREATEANDWAIT: /* * XXX: check legality */ *(data->data.integer) = RS_NOTINSERVICE; break; case RS_DESTROY: newrowstash->deleted = 1; break; } } break; case MODE_SET_ACTION: /* * Install the new row into the stored table. * Do this only *once* per row .... */ if (newrowstash->state != STATE_ACTION) { newrowstash->state = STATE_ACTION; if (newrowstash->created) { netsnmp_table_dataset_add_row(datatable, newrow); } else { netsnmp_table_dataset_replace_row(datatable, row, newrow); } } /* * ... but every (relevant) varbind in the request will * need to know about this new row, so update the * per-request row information regardless */ if (newrowstash->created) { netsnmp_request_add_list_data(request, netsnmp_create_data_list(TABLE_DATA_NAME, newrow, NULL)); } break; case MODE_SET_UNDO: /* * extract the new row, replace with the old or delete */ if (newrowstash->state != STATE_UNDO) { newrowstash->state = STATE_UNDO; if (newrowstash->created) { netsnmp_table_dataset_remove_and_delete_row(datatable, newrow); } else { netsnmp_table_dataset_replace_row(datatable, newrow, row); netsnmp_table_dataset_delete_row(newrow); } } break; case MODE_SET_COMMIT: if (newrowstash->state != STATE_COMMIT) { newrowstash->state = STATE_COMMIT; if (!newrowstash->created) { netsnmp_table_dataset_delete_row(row); } if (newrowstash->deleted) { netsnmp_table_dataset_remove_and_delete_row(datatable, newrow); } } break; case MODE_SET_FREE: if (newrowstash && newrowstash->state != STATE_FREE) { newrowstash->state = STATE_FREE; netsnmp_table_dataset_delete_row(newrow); } break; } } /* next handler called automatically - 'AUTO_NEXT' */ return SNMP_ERR_NOERROR; }
int return_data(int status, struct snmp_session *sp, struct snmp_pdu *pdu) /* simple printing of returned data */ { char buf[1024]; struct variable_list *vp; int ix; char *getdata = NULL; unsigned long int nVal; /* unsigned char sVal; */ /* int ipVal; */ switch (status) { case STAT_SUCCESS: vp = pdu->variables; if (pdu->errstat == SNMP_ERR_NOERROR) { while (vp) { snprint_variable(buf, sizeof(buf), vp->name, vp->name_length, vp); /*mjpark------------------------------------------*/ getdata = (char *)malloc(1 + vp->val_len); memcpy(getdata, vp->val.string, vp->val_len); getdata[vp->val_len] = '\0'; switch(vp->type) { case ASN_OCTET_STR: /* { */ /* memcpy((void *)&sVal, getdata, sizeof(unsigned char)); */ /* gpSnmpstr->val = sVal; */ /* break; */ /* } */ case ASN_GAUGE: case ASN_COUNTER: case ASN_TIMETICKS: case ASN_INTEGER: { memcpy((void *)&nVal, getdata, sizeof(unsigned long int)); gpSnmp->val = nVal; break; } case ASN_IPADDRESS: { /* struct in_addr st_addr; */ /* memcpy((void *)&ipVal, getdata, 4); */ /* st_addr.s_addr = ipVal; */ /* gpSnmpstr->val = inet_ntoa(st_addr); */ break; } } //debug print //printf("data length(%d), unsigned long int size(%d), int(%d)\n",vp->val_len, sizeof(unsigned long int), sizeof(int)); /* printf("snmpVal(%d), psnmp(%p)\n", nVal, gpSnmp); */ /*------------------------------------------------*/ vp = vp->next_variable; } free(getdata); } else { for (ix = 1; vp && ix != pdu->errindex; vp = vp->next_variable, ix++); if (vp) snprint_objid(buf, sizeof(buf), vp->name, vp->name_length); else strcpy(buf, "(none)"); fprintf(stdout, "%s: %s: %s\n", sp->peername, buf, snmp_errstring(pdu->errstat)); } return 1; case STAT_TIMEOUT: fprintf(stdout, "%s: Timeout\n", sp->peername); return 0; case STAT_ERROR: snmp_perror(sp->peername); return 0; } return 0; }
/* TODO: Check if negative values wrap around. Problem: negative temperatures. */ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type, double scale, double shift, const char *host_name, const char *data_name) { value_t ret; uint64_t tmp_unsigned = 0; int64_t tmp_signed = 0; _Bool defined = 1; /* Set to true when the original SNMP type appears to have been signed. */ _Bool prefer_signed = 0; if ((vl->type == ASN_INTEGER) || (vl->type == ASN_UINTEGER) || (vl->type == ASN_COUNTER) #ifdef ASN_TIMETICKS || (vl->type == ASN_TIMETICKS) #endif || (vl->type == ASN_GAUGE)) { tmp_unsigned = (uint32_t) *vl->val.integer; tmp_signed = (int32_t) *vl->val.integer; if (vl->type == ASN_INTEGER) prefer_signed = 1; DEBUG ("snmp plugin: Parsed int32 value is %"PRIu64".", tmp_unsigned); } else if (vl->type == ASN_COUNTER64) { tmp_unsigned = (uint32_t) vl->val.counter64->high; tmp_unsigned = tmp_unsigned << 32; tmp_unsigned += (uint32_t) vl->val.counter64->low; tmp_signed = (int64_t) tmp_unsigned; DEBUG ("snmp plugin: Parsed int64 value is %"PRIu64".", tmp_unsigned); } else if (vl->type == ASN_OCTET_STR) { /* We'll handle this later.. */ } else { char oid_buffer[1024]; memset (oid_buffer, 0, sizeof (oid_buffer)); snprint_objid (oid_buffer, sizeof (oid_buffer) - 1, vl->name, vl->name_length); #ifdef ASN_NULL if (vl->type == ASN_NULL) INFO ("snmp plugin: OID \"%s\" is undefined (type ASN_NULL)", oid_buffer); else #endif WARNING ("snmp plugin: I don't know the ASN type #%i " "(OID: \"%s\", data block \"%s\", host block \"%s\")", (int) vl->type, oid_buffer, (data_name != NULL) ? data_name : "UNKNOWN", (host_name != NULL) ? host_name : "UNKNOWN"); defined = 0; } if (vl->type == ASN_OCTET_STR) { int status = -1; if (vl->val.string != NULL) { char string[64]; size_t string_length; string_length = sizeof (string) - 1; if (vl->val_len < string_length) string_length = vl->val_len; /* The strings we get from the Net-SNMP library may not be null * terminated. That is why we're using `memcpy' here and not `strcpy'. * `string_length' is set to `vl->val_len' which holds the length of the * string. -octo */ memcpy (string, vl->val.string, string_length); string[string_length] = 0; status = parse_value (string, &ret, type); if (status != 0) { ERROR ("snmp plugin: host %s: csnmp_value_list_to_value: Parsing string as %s failed: %s", (host_name != NULL) ? host_name : "UNKNOWN", DS_TYPE_TO_STRING (type), string); } } if (status != 0) { switch (type) { case DS_TYPE_COUNTER: case DS_TYPE_DERIVE: case DS_TYPE_ABSOLUTE: memset (&ret, 0, sizeof (ret)); break; case DS_TYPE_GAUGE: ret.gauge = NAN; break; default: ERROR ("snmp plugin: csnmp_value_list_to_value: Unknown " "data source type: %i.", type); ret.gauge = NAN; } } } /* if (vl->type == ASN_OCTET_STR) */ else if (type == DS_TYPE_COUNTER) { ret.counter = tmp_unsigned; } else if (type == DS_TYPE_GAUGE) { if (!defined) ret.gauge = NAN; else if (prefer_signed) ret.gauge = (scale * tmp_signed) + shift; else ret.gauge = (scale * tmp_unsigned) + shift; } else if (type == DS_TYPE_DERIVE) { if (prefer_signed) ret.derive = (derive_t) tmp_signed; else ret.derive = (derive_t) tmp_unsigned; } else if (type == DS_TYPE_ABSOLUTE) { ret.absolute = (absolute_t) tmp_unsigned; } else { ERROR ("snmp plugin: csnmp_value_list_to_value: Unknown data source " "type: %i.", type); ret.gauge = NAN; } return (ret); } /* value_t csnmp_value_list_to_value */
/****************************************************************************** * * * Function: snmp_get_index * * * * Purpose: find index of OID with given value * * * * Parameters: DB_ITEM *item - configuration of zabbix item * * char *OID - OID of table with values of interest * * char *value - value to look for * * int *idx - result to be placed here * * * * Return value: NOTSUPPORTED - OID does not exist, any other critical error * * NETWORK_ERROR - recoverable network error * * SUCCEED - success, variable 'idx' contains index having * * value 'value' * * * * Author: * * * * Comments: * * * ******************************************************************************/ static int snmp_get_index(struct snmp_session *ss, DC_ITEM *item, const char *OID, const char *value, int *idx, char *err, int bulk) { const char *__function_name = "snmp_get_index"; oid anOID[MAX_OID_LEN], rootOID[MAX_OID_LEN]; size_t anOID_len = MAX_OID_LEN, rootOID_len = MAX_OID_LEN; char strval[MAX_STRING_LEN], *strval_dyn, snmp_oid[MAX_STRING_LEN], *error; int status, running, ret = NOTSUPPORTED; struct snmp_pdu *pdu, *response; struct variable_list *vars; zabbix_log(LOG_LEVEL_DEBUG, "In %s() oid:'%s' value:'%s' bulk:%d", __function_name, OID, value, bulk); *idx = 0; *err = '\0'; /* create OID from string */ snmp_parse_oid(OID, rootOID, &rootOID_len); /* copy rootOID to anOID */ memcpy(anOID, rootOID, rootOID_len * sizeof(oid)); anOID_len = rootOID_len; running = 1; while (1 == running) { pdu = snmp_pdu_create(bulk ? SNMP_MSG_GETNEXT : SNMP_MSG_GET); /* create empty PDU */ snmp_add_null_var(pdu, anOID, anOID_len); /* add OID as variable to PDU */ /* communicate with agent */ status = snmp_synch_response(ss, pdu, &response); zabbix_log(LOG_LEVEL_DEBUG, "%s() snmp_synch_response():%d", __function_name, status); /* process response */ if (STAT_SUCCESS == status && SNMP_ERR_NOERROR == response->errstat) { for (vars = response->variables; vars && running; vars = vars->next_variable) { /* verify if we are in the same subtree */ if (vars->name_length < rootOID_len || 0 != memcmp(rootOID, vars->name, rootOID_len * sizeof(oid))) { /* not part of this subtree */ zbx_snprintf(err, MAX_STRING_LEN, "NOT FOUND: %s[%s]", OID, value); ret = NOTSUPPORTED; running = 0; } else { /* verify if OIDs are increasing */ if (SNMP_ENDOFMIBVIEW != vars->type && SNMP_NOSUCHOBJECT != vars->type && SNMP_NOSUCHINSTANCE != vars->type) { /* not an exception value */ if (0 <= snmp_oid_compare(anOID, anOID_len, vars->name, vars->name_length)) { zbx_snprintf(err, MAX_STRING_LEN, "OID not increasing."); ret = NOTSUPPORTED; running = 0; } if (ASN_OCTET_STR == vars->type) { if (NULL == (strval_dyn = snmp_get_octet_string(vars))) { zbx_strlcpy(err, "out of memory", MAX_STRING_LEN); ret = NOTSUPPORTED; running = 0; } else { strscpy(strval, strval_dyn); zbx_free(strval_dyn); } } #ifdef OPAQUE_SPECIAL_TYPES else if (ASN_UINTEGER == vars->type || ASN_COUNTER == vars->type || ASN_TIMETICKS == vars->type || ASN_GAUGE == vars->type || ASN_UNSIGNED64 == vars->type) #else else if (ASN_UINTEGER == vars->type || ASN_COUNTER == vars->type || ASN_TIMETICKS == vars->type || ASN_GAUGE == vars->type) #endif { zbx_snprintf(strval, sizeof(strval), "%u", *vars->val.integer); } else if (ASN_COUNTER64 == vars->type) { zbx_snprintf(strval, sizeof(strval), ZBX_FS_UI64, (((zbx_uint64_t)vars->val.counter64->high) << 32) + (zbx_uint64_t)vars->val.counter64->low); } #ifdef OPAQUE_SPECIAL_TYPES else if (ASN_INTEGER == vars->type || ASN_INTEGER64 == vars->type) #else else if (ASN_INTEGER == vars->type) #endif { zbx_snprintf(strval, sizeof(strval), "%d", *vars->val.integer); } else if (ASN_IPADDRESS == vars->type) { zbx_snprintf(strval, sizeof(strval), "%d.%d.%d.%d", vars->val.string[0], vars->val.string[1], vars->val.string[2], vars->val.string[3]); } else { error = zbx_get_snmp_type_error(vars->type); memset(snmp_oid, '\0', sizeof(snmp_oid)); snprint_objid(snmp_oid, sizeof(snmp_oid) - 1, vars->name, vars->name_length); zabbix_log(LOG_LEVEL_DEBUG, "OID \"%s\": %s", snmp_oid, error); zbx_free(error); } if (0 == strcmp(value, strval)) { *idx = vars->name[vars->name_length - 1]; zabbix_log(LOG_LEVEL_DEBUG, "index found: %d", *idx); ret = SUCCEED; running = 0; } /* go to next variable */ memmove((char *)anOID, (char *)vars->name, vars->name_length * sizeof(oid)); anOID_len = vars->name_length; } else { /* an exception value, so stop */ zabbix_log(LOG_LEVEL_DEBUG, "exception value found"); ret = NOTSUPPORTED; running = 0; } } } } else {
/////////////////////////////////////////////////////////////// /// Given a host loads all the oid mappings for that host /// Uses snmp bulk get to minimize the time required for each /// mapping. int Host_Info::load_oid_table(){ unsigned int thread_id; struct snmp_session session; map<string,OID_Value_Table>::iterator iter; int fvalue=0; //// //netsnmp_session session, *ss; int numprinted = 0; int reps = 15, non_reps = 0; netsnmp_pdu *pdu, *response=NULL; 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; struct snmp_pdu *req, *resp; void *sp; char snmp_err_str[SNMP_ERR_STR_SIZE]; char buf[512]; char *placeholder; char buf2[512]; /// string temp_string1,temp_string2; int i; //////////// thread_id=(unsigned int)((uint64_t) pthread_self()); simple_snmp_sess_init(&session); session.retries=4; session.version = SNMP_VERSION_2c; //ARE THE NEXT TWO LINES VALID???! session.peername = (char *) ip_address.c_str(); session.community = (u_char *) community.c_str(); session.community_len = strlen(community.c_str()); for (iter = oid_table.begin(); iter != oid_table.end(); iter++){ /// assert(0==iter->first.compare(iter->second.oid)); print_log(LOG_INFO,"Doing host=%s for oid %s\n",ip_address.c_str(),iter->first.c_str()); rootlen = MAX_OID_LEN; //rootlen = strlen(iter->first.c_str()); if (!read_objid(iter->first.c_str(), root, &rootlen)) { //if (!Read_objid_ts(iter->first.c_str(), root, &rootlen)) { //snmp_perror(argv[arg]); //exit(1); print_log(LOG_ERR,"Cannot parse the oid='%s' rootlen=%d host=%s\n",iter->first.c_str(),rootlen,ip_address.c_str()); snmp_perror("read_objid"); return -1; } if(!(sp = snmp_sess_open(&session))){ snmp_perror("snmp_open"); print_log(LOG_WARNING,"[Thread %u] SNMP table builder, failed to open session to %s\n",thread_id,ip_address.c_str()); return -1; } running=1; //why memmove and not memcpy? ask the netsmpbulk writers memmove(name, root, rootlen * sizeof(oid)); name_length = rootlen; //should be a while while(running==1){ /* * 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(sp, pdu, &response); status = snmp_sess_synch_response(sp,pdu,&response); switch (status){ case STAT_SUCCESS: if (response->errstat == SNMP_ERR_NOERROR) { //Yay success! ////////////// 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_log(LOG_DEBUG,"num_printed=%d\n",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; } */ snmp_err_str[0]=0; snprint_objid(snmp_err_str,SNMP_ERR_STR_SIZE-1,vars->name,vars->name_length); snprint_value(buf, sizeof(buf)-5, vars->name, vars->name_length, vars); //print_log(LOG_DEBUG,"[Thread %u] '%s'='%s'\n",thread_id,snmp_err_str,buf); temp_string1=snmp_err_str; size_t found; found=temp_string1.find_last_of("."); temp_string2=temp_string1.substr(found+1); string search_string; found=iter->first.find_last_not_of(".0123456789"); if(found==iter->first.npos){ //not found the search string is the whole thing! search_string=iter->first; } else{ search_string=iter->first.substr(found); } search_string=iter->first.substr((iter->first.length()*2)/3); string suffix_str; //iterate over the data. found=temp_string1.find(iter->first); found=temp_string1.find(search_string); print_log(LOG_DEBUG,"[Thread %u] [host %s] found=%u first=%s temp_string1=%s search_str=%s\n" , thread_id,ip_address.c_str(), found,iter->first.c_str(),temp_string1.c_str(),search_string.c_str()); if(temp_string1.npos!=found){ //print_log(LOG_INFO,"[Thread %u] [host %s] found!\n",thread_id,ip_address.c_str()); //suffix_str=temp_string1.substr(found+iter->first.length()+1); suffix_str=temp_string1.substr(found+search_string.length()+1); //print_log(LOG_INFO,"[Thread %u] found=%u first=%s temp_string1=%s\n" , thread_id,found,iter->first.c_str(),temp_string1.c_str()); print_log(LOG_DEBUG,"[Thread %u] [host %s] found =%s!\n",thread_id,ip_address.c_str(),suffix_str.c_str()); } else{ print_log(LOG_DEBUG,"[Thread %u] [host %s] NOT found!\n",thread_id,ip_address.c_str()); found=temp_string1.find_last_of("."); suffix_str=temp_string1.substr(found+1); } //print_log(LOG_DEBUG,"[Thread %u] index='%s'\n",thread_id,temp_string2.c_str()); uint64_t local_index; local_index=atoll(temp_string2.c_str()); //printf("Raw Value = %s\n",buf); temp_string2=extract_value_from_raw(buf); //print_log(LOG_DEBUG,"[Thread %u] index=%lu value='%s' \n",thread_id,local_index,buf2); //iter->second.indexof[temp_string2]=local_index; //iter->second.valueof[local_index]=temp_string2; iter->second.suffix_of[temp_string2]=suffix_str; iter->second.value_of[suffix_str]=temp_string2; print_log(LOG_DEBUG,"[Thread %u] [host %s] suffix_of[%s]='%s' \n",thread_id,ip_address.c_str(),temp_string2.c_str(),suffix_str.c_str()); /* * 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, report and exit loop running=0; snprintf(snmp_err_str,SNMP_ERR_STR_SIZE-1,"[Thread %u] Hostname: %-15s snmp_sync_response",thread_id, ip_address.c_str()); snmp_perror(snmp_err_str); } break; case STAT_TIMEOUT: print_log(LOG_NOTICE,"[Thread %u] SNMP timeout(building table), host=%15s \n",thread_id, ip_address.c_str() ); running=0; break; default: //other error! print_log(LOG_ERR,"SNMP MISC error\n"); running=0; break; } if (response){ snmp_free_pdu(response); response=NULL; } if(0==iter->second.suffix_of.size()){ print_log(LOG_WARNING,"[Thread %u][host %s] no data inserted for %s\n",thread_id,ip_address.c_str(),iter->first.c_str()); //fvalue=-1; } //print_log(LOG_DEBUG,"[Thread %u] inserted %d values\n" ,thread_id,iter->second.indexof.size()); }//end while if (response){ snmp_free_pdu(response); response=NULL; } //is this the best place to clse it? snmp_sess_close(sp); }//end for return fvalue; }
/* * response handler */ int snmpAsyncResponse(int operation, struct snmp_session *sp, int reqid, struct snmp_pdu *pdu, void *magic) { char buf[RESULTSIZE]; tSession *host = (tSession *)magic; struct snmp_pdu *req; tOid *oid; oid = &host->oidList.oid[host->current_oid]; if (operation == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) { if (oid->doWalk) { if (pdu->variables->name_length >= oid->OidLen && memcmp(pdu->variables->name, oid->Oid, oid->OidLen * sizeof(oid))==0 && pdu->variables->type != SNMP_ENDOFMIBVIEW && pdu->variables->type != SNMP_NOSUCHOBJECT && pdu->variables->type != SNMP_NOSUCHINSTANCE) { snprint_objid(buf, RESULTSIZE, pdu->variables->name, pdu->variables->name_length); if (strcmp(buf, oid->currentName) == 0) { syslog(LOG_ERR, "snmpAsyncResponse: %s: oid %s not increasing", sp->peername, buf); snmpActiveHosts--; return 1; } strcpy(oid->currentName, buf); oid->resultWalkCount++; oid->resultWalk = (char**) realloc(oid->resultWalk, oid->resultWalkCount * sizeof(char*)); if (snmpStoreResult(host, pdu, &oid->resultWalk[oid->resultWalkCount-1])) { req = snmp_pdu_create(SNMP_MSG_GETNEXT); snprint_objid(buf, RESULTSIZE, pdu->variables->name, pdu->variables->name_length); snmp_add_null_var(req, pdu->variables->name, pdu->variables->name_length); if (snmp_send(host->sess, req)) return 1; else { syslog(LOG_ERR, "snmpAsyncResponse: snmp_send failed for: %s", sp->peername); snmp_free_pdu(req); } } else { oid->resultWalkCount--; oid->resultWalk = (char**) realloc(oid->resultWalk, oid->resultWalkCount * sizeof(char*)); storeEmptyResult(host); } } } else { if (!snmpStoreResult(host, pdu, &oid->result)) { storeEmptyResult(host); } } if (host->current_oid < host->oidList.count-1) { host->current_oid++; req = snmp_pdu_create(host->oidList.oid[host->current_oid].doWalk ? SNMP_MSG_GETNEXT : SNMP_MSG_GET); snmp_add_null_var(req, host->oidList.oid[host->current_oid].Oid, host->oidList.oid[host->current_oid].OidLen); if (snmp_send(host->sess, req)) return 1; else { syslog(LOG_ERR, "snmpAsyncResponse: snmp_send failed for: %s", sp->peername); snmp_free_pdu(req); } } } else { syslog(LOG_DEBUG, "snmpAsyncResponse: %s: Timeout", sp->peername); storeEmptyResult(host); } /* something went wrong (or end of variables) * this host not active any more */ snmpActiveHosts--; return 1; }