/* * Calculates the entries, which are not provided by OS, but can be * computed from the others. */ static void _calculate_entries(netsnmp_systemstats_entry * entry) { /* * HCInForwDatagrams = HCInNoRoutes + HCOutForwDatagrams */ if (!entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCINFORWDATAGRAMS] && entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTFORWDATAGRAMS] && entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCINNOROUTES]) { entry->stats.HCInForwDatagrams = entry->stats.HCInNoRoutes; u64Incr(&entry->stats.HCInForwDatagrams, &entry->stats.HCOutForwDatagrams); entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCINFORWDATAGRAMS] = 1; } /* * HCOutFragReqds = HCOutFragOKs + HCOutFragFails */ if (!entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTFRAGREQDS] && entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTFRAGOKS] && entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTFRAGFAILS]) { entry->stats.HCOutFragReqds = entry->stats.HCOutFragOKs; u64Incr(&entry->stats.HCOutFragReqds, &entry->stats.HCOutFragFails); entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTFRAGREQDS] = 1; } /* * HCOutTransmits = HCOutRequests + HCOutForwDatagrams + HCOutFragCreates * - HCOutFragReqds - HCOutNoRoutes - HCOutDiscards */ if (!entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTTRANSMITS] && entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTREQUESTS] && entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTFORWDATAGRAMS] && entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTFRAGREQDS] && entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTNOROUTES] && entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTFRAGCREATES] && entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTDISCARDS]) { U64 tmp, tmp2, tmp3; tmp = entry->stats.HCOutRequests; u64Incr(&tmp, &entry->stats.HCOutForwDatagrams); u64Incr(&tmp, &entry->stats.HCOutFragCreates); u64Subtract(&tmp, &entry->stats.HCOutFragReqds, &tmp2); u64Subtract(&tmp2, &entry->stats.HCOutNoRoutes, &tmp3); u64Subtract(&tmp3, &entry->stats.HCOutDiscards, &entry->stats.HCOutTransmits); entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTTRANSMITS] = 1; } }
/** * Calculate stats * * @retval 0 : success * @retval -1 : error */ int netsnmp_access_interface_entry_calculate_stats(netsnmp_interface_entry *entry) { DEBUGMSGTL(("access:interface", "calculate_stats\n")); if (entry->ns_flags & NETSNMP_INTERFACE_FLAGS_CALCULATE_UCAST) { u64Subtract(&entry->stats.iall, &entry->stats.imcast, &entry->stats.iucast); } return 0; }
int main(int argc, char *argv[]) { netsnmp_session session, *ss; netsnmp_pdu *pdu, *response; netsnmp_variable_list *vars; int arg; char *gateway; int count; struct varInfo *vip; u_int value = 0; struct counter64 c64value; float printvalue; time_t last_time = 0; time_t this_time; time_t delta_time; int sum; /* what the heck is this for, its never used? */ char filename[128] = { 0 }; struct timeval tv; struct tm tm; char timestring[64] = { 0 }, valueStr[64] = { 0}, maxStr[64] = { 0}; char outstr[256] = { 0 }, peakStr[64] = { 0}; int status; int begin, end, last_end; int print = 1; int exit_code = 1; SOCK_STARTUP; switch (arg = snmp_parse_args(argc, argv, &session, "C:", &optProc)) { case NETSNMP_PARSE_ARGS_ERROR: goto out; case NETSNMP_PARSE_ARGS_SUCCESS_EXIT: exit_code = 0; goto out; case NETSNMP_PARSE_ARGS_ERROR_USAGE: usage(); goto out; default: break; } gateway = session.peername; for (; optind < argc; optind++) { if (current_name >= MAX_ARGS) { fprintf(stderr, "%s: Too many variables specified (max %d)\n", argv[optind], MAX_ARGS); goto out; } varinfo[current_name++].name = argv[optind]; } if (current_name == 0) { usage(); goto out; } if (dosum) { if (current_name >= MAX_ARGS) { fprintf(stderr, "Too many variables specified (max %d)\n", MAX_ARGS); goto out; } varinfo[current_name++].name = NULL; } /* * open an SNMP session */ ss = snmp_open(&session); if (ss == NULL) { /* * diagnose snmp_open errors with the input netsnmp_session pointer */ snmp_sess_perror("snmpdelta", &session); goto out; } if (tableForm && timestamp) { printf("%s", gateway); } for (count = 0; count < current_name; count++) { vip = varinfo + count; if (vip->name) { vip->oidlen = MAX_OID_LEN; vip->info_oid = (oid *) malloc(sizeof(oid) * vip->oidlen); if (snmp_parse_oid(vip->name, vip->info_oid, &vip->oidlen) == NULL) { snmp_perror(vip->name); goto close_session; } sprint_descriptor(vip->descriptor, vip); if (tableForm) printf("\t%s", vip->descriptor); } else { vip->oidlen = 0; strlcpy(vip->descriptor, SumFile, sizeof(vip->descriptor)); } vip->value = 0; zeroU64(&vip->c64value); vip->time = 0; vip->max = 0; if (peaks) { vip->peak_count = -1; vip->peak = 0; vip->peak_average = 0; } } wait_for_period(period); end = current_name; sum = 0; while (1) { pdu = snmp_pdu_create(SNMP_MSG_GET); if (deltat) snmp_add_null_var(pdu, sysUpTimeOid, sysUpTimeLen); if (end == current_name) count = 0; else count = end; begin = count; for (; count < current_name && count < begin + varbindsPerPacket - deltat; count++) { if (varinfo[count].oidlen) snmp_add_null_var(pdu, varinfo[count].info_oid, varinfo[count].oidlen); } last_end = end; end = count; retry: status = snmp_synch_response(ss, pdu, &response); if (status == STAT_SUCCESS) { if (response->errstat == SNMP_ERR_NOERROR) { if (timestamp) { gettimeofday(&tv, (struct timezone *) 0); memcpy(&tm, localtime((time_t *) & tv.tv_sec), sizeof(tm)); if (((period % 60) && (!peaks || ((period * peaks) % 60))) || keepSeconds) sprintf(timestring, " [%02d:%02d:%02d %d/%d]", tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_mon + 1, tm.tm_mday); else sprintf(timestring, " [%02d:%02d %d/%d]", tm.tm_hour, tm.tm_min, tm.tm_mon + 1, tm.tm_mday); } vars = response->variables; if (deltat) { if (!vars || !vars->val.integer) { fprintf(stderr, "Missing variable in reply\n"); continue; } else { this_time = *(vars->val.integer); } vars = vars->next_variable; } else { this_time = 1; } for (count = begin; count < end; count++) { vip = varinfo + count; if (vip->oidlen) { if (!vars || !vars->val.integer) { fprintf(stderr, "Missing variable in reply\n"); break; } vip->type = vars->type; if (vars->type == ASN_COUNTER64) { u64Subtract(vars->val.counter64, &vip->c64value, &c64value); memcpy(&vip->c64value, vars->val.counter64, sizeof(struct counter64)); } else { value = *(vars->val.integer) - vip->value; vip->value = *(vars->val.integer); } vars = vars->next_variable; } else { value = sum; sum = 0; } delta_time = this_time - vip->time; if (delta_time <= 0) delta_time = 100; last_time = vip->time; vip->time = this_time; if (last_time == 0) continue; if (vip->oidlen && vip->type != ASN_COUNTER64) { sum += value; } if (tableForm) { if (count == begin) { sprintf(outstr, "%s", timestring + 1); } else { outstr[0] = '\0'; } } else { sprintf(outstr, "%s %s", timestring, vip->descriptor); } if (deltat || tableForm) { if (vip->type == ASN_COUNTER64) { fprintf(stderr, "time delta and table form not supported for counter64s\n"); goto close_session; } else { printvalue = ((float) value * 100) / delta_time; if (tableForm) sprintf(valueStr, "\t%.2f", printvalue); else sprintf(valueStr, " /sec: %.2f", printvalue); } } else { printvalue = (float) value; sprintf(valueStr, " /%d sec: ", period); if (vip->type == ASN_COUNTER64) printU64(valueStr + strlen(valueStr), &c64value); else sprintf(valueStr + strlen(valueStr), "%u", value); } if (!peaks) { strcat(outstr, valueStr); } else { print = 0; if (vip->peak_count == -1) { if (wait_for_peak_start(period, peaks) == 0) vip->peak_count = 0; } else { vip->peak_average += printvalue; if (vip->peak < printvalue) vip->peak = printvalue; if (++vip->peak_count == peaks) { if (deltat) sprintf(peakStr, " /sec: %.2f (%d sec Peak: %.2f)", vip->peak_average / vip->peak_count, period, vip->peak); else sprintf(peakStr, " /%d sec: %.0f (%d sec Peak: %.0f)", period, vip->peak_average / vip->peak_count, period, vip->peak); vip->peak_average = 0; vip->peak = 0; vip->peak_count = 0; print = 1; strcat(outstr, peakStr); } } } if (printmax) { if (printvalue > vip->max) { vip->max = printvalue; } if (deltat) sprintf(maxStr, " (Max: %.2f)", vip->max); else sprintf(maxStr, " (Max: %.0f)", vip->max); strcat(outstr, maxStr); } if (print) { if (fileout) { sprintf(filename, "%s-%s", gateway, vip->descriptor); print_log(filename, outstr + 1); } else { if (tableForm) printf("%s", outstr); else printf("%s\n", outstr + 1); fflush(stdout); } } } if (end == last_end && tableForm) printf("\n"); } else { if (response->errstat == SNMP_ERR_TOOBIG) { if (response->errindex <= varbindsPerPacket && response->errindex > 0) { varbindsPerPacket = response->errindex - 1; } else { if (varbindsPerPacket > 30) varbindsPerPacket -= 5; else varbindsPerPacket--; } if (varbindsPerPacket <= 0) { exit_code = 5; break; } end = last_end; continue; } else if (response->errindex != 0) { fprintf(stderr, "Failed object: "); for (count = 1, vars = response->variables; vars && count != response->errindex; vars = vars->next_variable, count++); if (vars) fprint_objid(stderr, vars->name, vars->name_length); fprintf(stderr, "\n"); /* * Don't exit when OIDs from file are not found on agent * exit_code = 1; * break; */ } else { fprintf(stderr, "Error in packet: %s\n", snmp_errstring(response->errstat)); exit_code = 1; break; } /* * retry if the errored variable was successfully removed */ if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_APP_DONT_FIX_PDUS)) { pdu = snmp_fix_pdu(response, SNMP_MSG_GET); snmp_free_pdu(response); response = NULL; if (pdu != NULL) goto retry; } } } else if (status == STAT_TIMEOUT) { fprintf(stderr, "Timeout: No Response from %s\n", gateway); response = NULL; exit_code = 1; break; } else { /* status == STAT_ERROR */ snmp_sess_perror("snmpdelta", ss); response = NULL; exit_code = 1; break; } if (response) snmp_free_pdu(response); if (end == current_name) { wait_for_period(period); } } exit_code = 0; close_session: snmp_close(ss); out: SOCK_CLEANUP; return (exit_code); }