754 lines
23 KiB
C
754 lines
23 KiB
C
/*
|
|
* snmpdelta.c - Monitor deltas of integer valued SNMP variables
|
|
*
|
|
*/
|
|
/**********************************************************************
|
|
*
|
|
* Copyright 1996 by Carnegie Mellon University
|
|
*
|
|
* All Rights Reserved
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software and its
|
|
* documentation for any purpose and without fee is hereby granted,
|
|
* provided that the above copyright notice appear in all copies and that
|
|
* both that copyright notice and this permission notice appear in
|
|
* supporting documentation, and that the name of CMU not be
|
|
* used in advertising or publicity pertaining to distribution of the
|
|
* software without specific, written prior permission.
|
|
*
|
|
* CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
|
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
|
* CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
|
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
* SOFTWARE.
|
|
*
|
|
**********************************************************************/
|
|
|
|
#include <net-snmp/net-snmp-config.h>
|
|
|
|
#if HAVE_STDLIB_H
|
|
#include <stdlib.h>
|
|
#endif
|
|
#if HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
#if HAVE_STRING_H
|
|
#include <string.h>
|
|
#else
|
|
#include <strings.h>
|
|
#endif
|
|
#include <sys/types.h>
|
|
#if HAVE_NETINET_IN_H
|
|
#include <netinet/in.h>
|
|
#endif
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
#if TIME_WITH_SYS_TIME
|
|
# include <sys/time.h>
|
|
# include <time.h>
|
|
#else
|
|
# if HAVE_SYS_TIME_H
|
|
# include <sys/time.h>
|
|
# else
|
|
# include <time.h>
|
|
# endif
|
|
#endif
|
|
#if HAVE_SYS_SELECT_H
|
|
#include <sys/select.h>
|
|
#endif
|
|
#if HAVE_NETDB_H
|
|
#include <netdb.h>
|
|
#endif
|
|
#if HAVE_ARPA_INET_H
|
|
#include <arpa/inet.h>
|
|
#endif
|
|
|
|
#include <net-snmp/net-snmp-includes.h>
|
|
|
|
#define MAX_ARGS 256
|
|
#define NETSNMP_DS_APP_DONT_FIX_PDUS 0
|
|
|
|
const char *SumFile = "Sum";
|
|
|
|
/*
|
|
* Information about the handled variables
|
|
*/
|
|
struct varInfo {
|
|
char *name;
|
|
oid *info_oid;
|
|
int type;
|
|
size_t oidlen;
|
|
char descriptor[64];
|
|
u_int value;
|
|
struct counter64 c64value;
|
|
float max;
|
|
time_t time;
|
|
int peak_count;
|
|
float peak;
|
|
float peak_average;
|
|
int spoiled;
|
|
};
|
|
|
|
struct varInfo varinfo[MAX_ARGS];
|
|
int current_name = 0;
|
|
int period = 1;
|
|
int deltat = 0, timestamp = 0, fileout = 0, dosum =
|
|
0, printmax = 0;
|
|
int keepSeconds = 0, peaks = 0;
|
|
int tableForm = 0;
|
|
int varbindsPerPacket = 60;
|
|
|
|
static void processFileArgs(char *fileName);
|
|
|
|
void
|
|
usage(void)
|
|
{
|
|
fprintf(stderr,
|
|
"Usage: snmpdelta [-Cf] [-CF commandFile] [-Cl] [-CL SumFileName]\n\t[-Cs] [-Ck] [-Ct] [-CS] [-Cv vars/pkt] [-Cp period]\n\t[-CP peaks] ");
|
|
snmp_parse_args_usage(stderr);
|
|
fprintf(stderr, " oid [oid ...]\n");
|
|
snmp_parse_args_descriptions(stderr);
|
|
fprintf(stderr, "snmpdelta specific options\n");
|
|
fprintf(stderr, " -Cf\t\tDon't fix errors and retry the request.\n");
|
|
fprintf(stderr, " -Cl\t\twrite configuration to file\n");
|
|
fprintf(stderr, " -CF config\tload configuration from file\n");
|
|
fprintf(stderr, " -Cp period\tspecifies the poll period\n");
|
|
fprintf(stderr, " -CP peaks\treporting period in poll periods\n");
|
|
fprintf(stderr, " -Cv vars/pkt\tnumber of variables per packet\n");
|
|
fprintf(stderr, " -Ck\t\tkeep seconds in output time\n");
|
|
fprintf(stderr, " -Cm\t\tshow max values\n");
|
|
fprintf(stderr, " -CS\t\tlog to a sum file\n");
|
|
fprintf(stderr, " -Cs\t\tshow timestamps\n");
|
|
fprintf(stderr, " -Ct\t\tget timing from agent\n");
|
|
fprintf(stderr, " -CT\t\tprint output in tabular form\n");
|
|
fprintf(stderr, " -CL sumfile\tspecifies the sum file name\n");
|
|
}
|
|
|
|
static void
|
|
optProc(int argc, char *const *argv, int opt)
|
|
{
|
|
switch (opt) {
|
|
case 'C':
|
|
while (*optarg) {
|
|
switch ((opt = *optarg++)) {
|
|
case 'f':
|
|
netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
|
|
NETSNMP_DS_APP_DONT_FIX_PDUS);
|
|
break;
|
|
case 'p':
|
|
period = atoi(argv[optind++]);
|
|
break;
|
|
case 'P':
|
|
peaks = atoi(argv[optind++]);
|
|
break;
|
|
case 'v':
|
|
varbindsPerPacket = atoi(argv[optind++]);
|
|
break;
|
|
case 't':
|
|
deltat = 1;
|
|
break;
|
|
case 's':
|
|
timestamp = 1;
|
|
break;
|
|
case 'S':
|
|
dosum = 1;
|
|
break;
|
|
case 'm':
|
|
printmax = 1;
|
|
break;
|
|
case 'F':
|
|
processFileArgs(argv[optind++]);
|
|
break;
|
|
case 'l':
|
|
fileout = 1;
|
|
break;
|
|
case 'L':
|
|
SumFile = argv[optind++];
|
|
break;
|
|
case 'k':
|
|
keepSeconds = 1;
|
|
break;
|
|
case 'T':
|
|
tableForm = 1;
|
|
break;
|
|
default:
|
|
fprintf(stderr, "Bad -C options: %c\n", opt);
|
|
exit(1);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
int
|
|
wait_for_peak_start(int period, int peak)
|
|
{
|
|
struct timeval m_time, *tv = &m_time;
|
|
struct tm tm;
|
|
time_t SecondsAtNextHour;
|
|
int target = 0;
|
|
int seconds;
|
|
|
|
seconds = period * peak;
|
|
|
|
/*
|
|
* Find the current time
|
|
*/
|
|
gettimeofday(tv, (struct timezone *) 0);
|
|
|
|
/*
|
|
* Create a tm struct from it
|
|
*/
|
|
memcpy(&tm, localtime((time_t *) & tv->tv_sec), sizeof(tm));
|
|
|
|
/*
|
|
* Calculate the next hour
|
|
*/
|
|
tm.tm_sec = 0;
|
|
tm.tm_min = 0;
|
|
tm.tm_hour++;
|
|
SecondsAtNextHour = mktime(&tm);
|
|
|
|
/*
|
|
* Now figure out the amount of time to sleep
|
|
*/
|
|
target = (int)(SecondsAtNextHour - tv->tv_sec) % seconds;
|
|
|
|
return target;
|
|
}
|
|
|
|
void
|
|
print_log(char *file, char *message)
|
|
{
|
|
FILE *fp;
|
|
|
|
fp = fopen(file, "a");
|
|
if (fp == NULL) {
|
|
fprintf(stderr, "Couldn't open %s\n", file);
|
|
return;
|
|
}
|
|
fprintf(fp, "%s\n", message);
|
|
fclose(fp);
|
|
}
|
|
|
|
void
|
|
sprint_descriptor(char *buffer, struct varInfo *vip)
|
|
{
|
|
char *buf = NULL, *cp = NULL;
|
|
size_t buf_len = 0, out_len = 0;
|
|
|
|
if (!sprint_realloc_objid((u_char **)&buf, &buf_len, &out_len, 1,
|
|
vip->info_oid, vip->oidlen)) {
|
|
if (buf != NULL) {
|
|
free(buf);
|
|
}
|
|
return;
|
|
}
|
|
|
|
for (cp = buf; *cp; cp++);
|
|
while (cp >= buf) {
|
|
if (isalpha((unsigned char)(*cp)))
|
|
break;
|
|
cp--;
|
|
}
|
|
while (cp >= buf) {
|
|
if (*cp == '.')
|
|
break;
|
|
cp--;
|
|
}
|
|
cp++;
|
|
if (cp < buf)
|
|
cp = buf;
|
|
strcpy(buffer, cp);
|
|
|
|
if (buf != NULL) {
|
|
free(buf);
|
|
}
|
|
}
|
|
|
|
void
|
|
processFileArgs(char *fileName)
|
|
{
|
|
FILE *fp;
|
|
char buf[260] = { 0 }, *cp;
|
|
int blank, linenumber = 0;
|
|
|
|
fp = fopen(fileName, "r");
|
|
if (fp == NULL)
|
|
return;
|
|
while (fgets(buf, sizeof(buf), fp)) {
|
|
linenumber++;
|
|
if (strlen(buf) > (sizeof(buf) - 2)) {
|
|
fprintf(stderr, "Line too long on line %d of %s\n",
|
|
linenumber, fileName);
|
|
exit(1);
|
|
}
|
|
if (buf[0] == '#')
|
|
continue;
|
|
blank = TRUE;
|
|
for (cp = buf; *cp; cp++)
|
|
if (!isspace((unsigned char)(*cp))) {
|
|
blank = FALSE;
|
|
break;
|
|
}
|
|
if (blank)
|
|
continue;
|
|
buf[strlen(buf) - 1] = 0;
|
|
if (current_name >= MAX_ARGS) {
|
|
fprintf(stderr, "Too many variables read at line %d of %s (max %d)\n",
|
|
linenumber, fileName, MAX_ARGS);
|
|
exit(1);
|
|
}
|
|
varinfo[current_name++].name = strdup(buf);
|
|
}
|
|
fclose(fp);
|
|
return;
|
|
}
|
|
|
|
void
|
|
wait_for_period(int period)
|
|
{
|
|
#ifdef WIN32
|
|
Sleep(period * 1000);
|
|
#else /* WIN32 */
|
|
struct timeval m_time, *tv = &m_time;
|
|
struct tm tm;
|
|
int count;
|
|
static int target = 0;
|
|
time_t nexthour;
|
|
|
|
gettimeofday(tv, (struct timezone *) 0);
|
|
|
|
if (target) {
|
|
target += period;
|
|
} else {
|
|
memcpy(&tm, localtime((time_t *) & tv->tv_sec), sizeof(tm));
|
|
tm.tm_sec = 0;
|
|
tm.tm_min = 0;
|
|
tm.tm_hour++;
|
|
nexthour = mktime(&tm);
|
|
|
|
target = (nexthour - tv->tv_sec) % period;
|
|
if (target == 0)
|
|
target = period;
|
|
target += tv->tv_sec;
|
|
}
|
|
|
|
tv->tv_sec = target - tv->tv_sec;
|
|
if (tv->tv_usec != 0) {
|
|
tv->tv_sec--;
|
|
tv->tv_usec = 1000000 - tv->tv_usec;
|
|
}
|
|
if (tv->tv_sec < 0) {
|
|
/*
|
|
* ran out of time, schedule immediately
|
|
*/
|
|
tv->tv_sec = 0;
|
|
tv->tv_usec = 0;
|
|
}
|
|
count = 1;
|
|
while (count != 0) {
|
|
count = select(0, NULL, NULL, NULL, tv);
|
|
switch (count) {
|
|
case 0:
|
|
break;
|
|
case -1:
|
|
/*
|
|
* FALLTHRU
|
|
*/
|
|
default:
|
|
snmp_log_perror("select");
|
|
break;
|
|
}
|
|
}
|
|
#endif /* WIN32 */
|
|
}
|
|
|
|
oid sysUpTimeOid[9] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
|
|
size_t sysUpTimeLen = 9;
|
|
|
|
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);
|
|
}
|