|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* snmpdelta.c - Monitor deltas of integer valued SNMP variables
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
/**********************************************************************
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* Copyright 1996 by Carnegie Mellon University
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* All Rights Reserved
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* Permission to use, copy, modify, and distribute this software and its
|
|
Packit |
fcad23 |
* documentation for any purpose and without fee is hereby granted,
|
|
Packit |
fcad23 |
* provided that the above copyright notice appear in all copies and that
|
|
Packit |
fcad23 |
* both that copyright notice and this permission notice appear in
|
|
Packit |
fcad23 |
* supporting documentation, and that the name of CMU not be
|
|
Packit |
fcad23 |
* used in advertising or publicity pertaining to distribution of the
|
|
Packit |
fcad23 |
* software without specific, written prior permission.
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
|
Packit |
fcad23 |
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
|
Packit |
fcad23 |
* CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
|
Packit |
fcad23 |
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
Packit |
fcad23 |
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
Packit |
fcad23 |
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
Packit |
fcad23 |
* SOFTWARE.
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
**********************************************************************/
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#include <net-snmp/net-snmp-config.h>
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#if HAVE_STDLIB_H
|
|
Packit |
fcad23 |
#include <stdlib.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_UNISTD_H
|
|
Packit |
fcad23 |
#include <unistd.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_STRING_H
|
|
Packit |
fcad23 |
#include <string.h>
|
|
Packit |
fcad23 |
#else
|
|
Packit |
fcad23 |
#include <strings.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#include <sys/types.h>
|
|
Packit |
fcad23 |
#if HAVE_NETINET_IN_H
|
|
Packit |
fcad23 |
#include <netinet/in.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#include <stdio.h>
|
|
Packit |
fcad23 |
#include <ctype.h>
|
|
Packit |
fcad23 |
#if TIME_WITH_SYS_TIME
|
|
Packit |
fcad23 |
# include <sys/time.h>
|
|
Packit |
fcad23 |
# include <time.h>
|
|
Packit |
fcad23 |
#else
|
|
Packit |
fcad23 |
# if HAVE_SYS_TIME_H
|
|
Packit |
fcad23 |
# include <sys/time.h>
|
|
Packit |
fcad23 |
# else
|
|
Packit |
fcad23 |
# include <time.h>
|
|
Packit |
fcad23 |
# endif
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_SYS_SELECT_H
|
|
Packit |
fcad23 |
#include <sys/select.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_NETDB_H
|
|
Packit |
fcad23 |
#include <netdb.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_ARPA_INET_H
|
|
Packit |
fcad23 |
#include <arpa/inet.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#include <net-snmp/net-snmp-includes.h>
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#define MAX_ARGS 256
|
|
Packit |
fcad23 |
#define NETSNMP_DS_APP_DONT_FIX_PDUS 0
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
const char *SumFile = "Sum";
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Information about the handled variables
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
struct varInfo {
|
|
Packit |
fcad23 |
char *name;
|
|
Packit |
fcad23 |
oid *info_oid;
|
|
Packit |
fcad23 |
int type;
|
|
Packit |
fcad23 |
size_t oidlen;
|
|
Packit |
fcad23 |
char descriptor[64];
|
|
Packit |
fcad23 |
u_int value;
|
|
Packit |
fcad23 |
struct counter64 c64value;
|
|
Packit |
fcad23 |
float max;
|
|
Packit |
fcad23 |
time_t time;
|
|
Packit |
fcad23 |
int peak_count;
|
|
Packit |
fcad23 |
float peak;
|
|
Packit |
fcad23 |
float peak_average;
|
|
Packit |
fcad23 |
int spoiled;
|
|
Packit |
fcad23 |
};
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
struct varInfo varinfo[MAX_ARGS];
|
|
Packit |
fcad23 |
int current_name = 0;
|
|
Packit |
fcad23 |
int period = 1;
|
|
Packit |
fcad23 |
int deltat = 0, timestamp = 0, fileout = 0, dosum =
|
|
Packit |
fcad23 |
0, printmax = 0;
|
|
Packit |
fcad23 |
int keepSeconds = 0, peaks = 0;
|
|
Packit |
fcad23 |
int tableForm = 0;
|
|
Packit |
fcad23 |
int varbindsPerPacket = 60;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static void processFileArgs(char *fileName);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
usage(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
fprintf(stderr,
|
|
Packit |
fcad23 |
"Usage: snmpdelta [-Cf] [-CF commandFile] [-Cl] [-CL SumFileName]\n\t[-Cs] [-Ck] [-Ct] [-CS] [-Cv vars/pkt] [-Cp period]\n\t[-CP peaks] ");
|
|
Packit |
fcad23 |
snmp_parse_args_usage(stderr);
|
|
Packit |
fcad23 |
fprintf(stderr, " oid [oid ...]\n");
|
|
Packit |
fcad23 |
snmp_parse_args_descriptions(stderr);
|
|
Packit |
fcad23 |
fprintf(stderr, "snmpdelta specific options\n");
|
|
Packit |
fcad23 |
fprintf(stderr, " -Cf\t\tDon't fix errors and retry the request.\n");
|
|
Packit |
fcad23 |
fprintf(stderr, " -Cl\t\twrite configuration to file\n");
|
|
Packit |
fcad23 |
fprintf(stderr, " -CF config\tload configuration from file\n");
|
|
Packit |
fcad23 |
fprintf(stderr, " -Cp period\tspecifies the poll period\n");
|
|
Packit |
fcad23 |
fprintf(stderr, " -CP peaks\treporting period in poll periods\n");
|
|
Packit |
fcad23 |
fprintf(stderr, " -Cv vars/pkt\tnumber of variables per packet\n");
|
|
Packit |
fcad23 |
fprintf(stderr, " -Ck\t\tkeep seconds in output time\n");
|
|
Packit |
fcad23 |
fprintf(stderr, " -Cm\t\tshow max values\n");
|
|
Packit |
fcad23 |
fprintf(stderr, " -CS\t\tlog to a sum file\n");
|
|
Packit |
fcad23 |
fprintf(stderr, " -Cs\t\tshow timestamps\n");
|
|
Packit |
fcad23 |
fprintf(stderr, " -Ct\t\tget timing from agent\n");
|
|
Packit |
fcad23 |
fprintf(stderr, " -CT\t\tprint output in tabular form\n");
|
|
Packit |
fcad23 |
fprintf(stderr, " -CL sumfile\tspecifies the sum file name\n");
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static void
|
|
Packit |
fcad23 |
optProc(int argc, char *const *argv, int opt)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
switch (opt) {
|
|
Packit |
fcad23 |
case 'C':
|
|
Packit |
fcad23 |
while (*optarg) {
|
|
Packit |
fcad23 |
switch ((opt = *optarg++)) {
|
|
Packit |
fcad23 |
case 'f':
|
|
Packit |
fcad23 |
netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
|
|
Packit |
fcad23 |
NETSNMP_DS_APP_DONT_FIX_PDUS);
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case 'p':
|
|
Packit |
fcad23 |
period = atoi(argv[optind++]);
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case 'P':
|
|
Packit |
fcad23 |
peaks = atoi(argv[optind++]);
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case 'v':
|
|
Packit |
fcad23 |
varbindsPerPacket = atoi(argv[optind++]);
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case 't':
|
|
Packit |
fcad23 |
deltat = 1;
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case 's':
|
|
Packit |
fcad23 |
timestamp = 1;
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case 'S':
|
|
Packit |
fcad23 |
dosum = 1;
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case 'm':
|
|
Packit |
fcad23 |
printmax = 1;
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case 'F':
|
|
Packit |
fcad23 |
processFileArgs(argv[optind++]);
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case 'l':
|
|
Packit |
fcad23 |
fileout = 1;
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case 'L':
|
|
Packit |
fcad23 |
SumFile = argv[optind++];
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case 'k':
|
|
Packit |
fcad23 |
keepSeconds = 1;
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case 'T':
|
|
Packit |
fcad23 |
tableForm = 1;
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
default:
|
|
Packit |
fcad23 |
fprintf(stderr, "Bad -C options: %c\n", opt);
|
|
Packit |
fcad23 |
exit(1);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
wait_for_peak_start(int period, int peak)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
struct timeval m_time, *tv = &m_time;
|
|
Packit |
fcad23 |
struct tm tm;
|
|
Packit |
fcad23 |
time_t SecondsAtNextHour;
|
|
Packit |
fcad23 |
int target = 0;
|
|
Packit |
fcad23 |
int seconds;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
seconds = period * peak;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Find the current time
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
gettimeofday(tv, (struct timezone *) 0);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Create a tm struct from it
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
memcpy(&tm, localtime((time_t *) & tv->tv_sec), sizeof(tm));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Calculate the next hour
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
tm.tm_sec = 0;
|
|
Packit |
fcad23 |
tm.tm_min = 0;
|
|
Packit |
fcad23 |
tm.tm_hour++;
|
|
Packit |
fcad23 |
SecondsAtNextHour = mktime(&tm;;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Now figure out the amount of time to sleep
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
target = (int)(SecondsAtNextHour - tv->tv_sec) % seconds;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return target;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
print_log(char *file, char *message)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
FILE *fp;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
fp = fopen(file, "a");
|
|
Packit |
fcad23 |
if (fp == NULL) {
|
|
Packit |
fcad23 |
fprintf(stderr, "Couldn't open %s\n", file);
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
fprintf(fp, "%s\n", message);
|
|
Packit |
fcad23 |
fclose(fp);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
sprint_descriptor(char *buffer, struct varInfo *vip)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
char *buf = NULL, *cp = NULL;
|
|
Packit |
fcad23 |
size_t buf_len = 0, out_len = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (!sprint_realloc_objid((u_char **)&buf, &buf_len, &out_len, 1,
|
|
Packit |
fcad23 |
vip->info_oid, vip->oidlen)) {
|
|
Packit |
fcad23 |
if (buf != NULL) {
|
|
Packit |
fcad23 |
free(buf);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
for (cp = buf; *cp; cp++);
|
|
Packit |
fcad23 |
while (cp >= buf) {
|
|
Packit |
fcad23 |
if (isalpha((unsigned char)(*cp)))
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
cp--;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
while (cp >= buf) {
|
|
Packit |
fcad23 |
if (*cp == '.')
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
cp--;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
cp++;
|
|
Packit |
fcad23 |
if (cp < buf)
|
|
Packit |
fcad23 |
cp = buf;
|
|
Packit |
fcad23 |
strcpy(buffer, cp);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (buf != NULL) {
|
|
Packit |
fcad23 |
free(buf);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
processFileArgs(char *fileName)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
FILE *fp;
|
|
Packit |
fcad23 |
char buf[260] = { 0 }, *cp;
|
|
Packit |
fcad23 |
int blank, linenumber = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
fp = fopen(fileName, "r");
|
|
Packit |
fcad23 |
if (fp == NULL)
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
while (fgets(buf, sizeof(buf), fp)) {
|
|
Packit |
fcad23 |
linenumber++;
|
|
Packit |
fcad23 |
if (strlen(buf) > (sizeof(buf) - 2)) {
|
|
Packit |
fcad23 |
fprintf(stderr, "Line too long on line %d of %s\n",
|
|
Packit |
fcad23 |
linenumber, fileName);
|
|
Packit |
fcad23 |
exit(1);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if (buf[0] == '#')
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
blank = TRUE;
|
|
Packit |
fcad23 |
for (cp = buf; *cp; cp++)
|
|
Packit |
fcad23 |
if (!isspace((unsigned char)(*cp))) {
|
|
Packit |
fcad23 |
blank = FALSE;
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if (blank)
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
buf[strlen(buf) - 1] = 0;
|
|
Packit |
fcad23 |
if (current_name >= MAX_ARGS) {
|
|
Packit |
fcad23 |
fprintf(stderr, "Too many variables read at line %d of %s (max %d)\n",
|
|
Packit |
fcad23 |
linenumber, fileName, MAX_ARGS);
|
|
Packit |
fcad23 |
exit(1);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
varinfo[current_name++].name = strdup(buf);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
fclose(fp);
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
wait_for_period(int period)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
#ifdef WIN32
|
|
Packit |
fcad23 |
Sleep(period * 1000);
|
|
Packit |
fcad23 |
#else /* WIN32 */
|
|
Packit |
fcad23 |
struct timeval m_time, *tv = &m_time;
|
|
Packit |
fcad23 |
struct tm tm;
|
|
Packit |
fcad23 |
int count;
|
|
Packit |
fcad23 |
static int target = 0;
|
|
Packit |
fcad23 |
time_t nexthour;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
gettimeofday(tv, (struct timezone *) 0);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (target) {
|
|
Packit |
fcad23 |
target += period;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
memcpy(&tm, localtime((time_t *) & tv->tv_sec), sizeof(tm));
|
|
Packit |
fcad23 |
tm.tm_sec = 0;
|
|
Packit |
fcad23 |
tm.tm_min = 0;
|
|
Packit |
fcad23 |
tm.tm_hour++;
|
|
Packit |
fcad23 |
nexthour = mktime(&tm;;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
target = (nexthour - tv->tv_sec) % period;
|
|
Packit |
fcad23 |
if (target == 0)
|
|
Packit |
fcad23 |
target = period;
|
|
Packit |
fcad23 |
target += tv->tv_sec;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
tv->tv_sec = target - tv->tv_sec;
|
|
Packit |
fcad23 |
if (tv->tv_usec != 0) {
|
|
Packit |
fcad23 |
tv->tv_sec--;
|
|
Packit |
fcad23 |
tv->tv_usec = 1000000 - tv->tv_usec;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if (tv->tv_sec < 0) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* ran out of time, schedule immediately
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
tv->tv_sec = 0;
|
|
Packit |
fcad23 |
tv->tv_usec = 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
count = 1;
|
|
Packit |
fcad23 |
while (count != 0) {
|
|
Packit |
fcad23 |
count = select(0, NULL, NULL, NULL, tv);
|
|
Packit |
fcad23 |
switch (count) {
|
|
Packit |
fcad23 |
case 0:
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case -1:
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* FALLTHRU
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
default:
|
|
Packit |
fcad23 |
snmp_log_perror("select");
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif /* WIN32 */
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
oid sysUpTimeOid[9] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
|
|
Packit |
fcad23 |
size_t sysUpTimeLen = 9;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
main(int argc, char *argv[])
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_session session, *ss;
|
|
Packit |
fcad23 |
netsnmp_pdu *pdu, *response;
|
|
Packit |
fcad23 |
netsnmp_variable_list *vars;
|
|
Packit |
fcad23 |
int arg;
|
|
Packit |
fcad23 |
char *gateway;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
int count;
|
|
Packit |
fcad23 |
struct varInfo *vip;
|
|
Packit |
fcad23 |
u_int value = 0;
|
|
Packit |
fcad23 |
struct counter64 c64value;
|
|
Packit |
fcad23 |
float printvalue;
|
|
Packit |
fcad23 |
time_t last_time = 0;
|
|
Packit |
fcad23 |
time_t this_time;
|
|
Packit |
fcad23 |
time_t delta_time;
|
|
Packit |
fcad23 |
int sum; /* what the heck is this for, its never used? */
|
|
Packit |
fcad23 |
char filename[128] = { 0 };
|
|
Packit |
fcad23 |
struct timeval tv;
|
|
Packit |
fcad23 |
struct tm tm;
|
|
Packit |
fcad23 |
char timestring[64] = { 0 }, valueStr[64] = {
|
|
Packit |
fcad23 |
0}, maxStr[64] = {
|
|
Packit |
fcad23 |
0};
|
|
Packit |
fcad23 |
char outstr[256] = { 0 }, peakStr[64] = {
|
|
Packit |
fcad23 |
0};
|
|
Packit |
fcad23 |
int status;
|
|
Packit |
fcad23 |
int begin, end, last_end;
|
|
Packit |
fcad23 |
int print = 1;
|
|
Packit |
fcad23 |
int exit_code = 1;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
SOCK_STARTUP;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
switch (arg = snmp_parse_args(argc, argv, &session, "C:", &optProc)) {
|
|
Packit |
fcad23 |
case NETSNMP_PARSE_ARGS_ERROR:
|
|
Packit |
fcad23 |
goto out;
|
|
Packit |
fcad23 |
case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
|
|
Packit |
fcad23 |
exit_code = 0;
|
|
Packit |
fcad23 |
goto out;
|
|
Packit |
fcad23 |
case NETSNMP_PARSE_ARGS_ERROR_USAGE:
|
|
Packit |
fcad23 |
usage();
|
|
Packit |
fcad23 |
goto out;
|
|
Packit |
fcad23 |
default:
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
gateway = session.peername;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
for (; optind < argc; optind++) {
|
|
Packit |
fcad23 |
if (current_name >= MAX_ARGS) {
|
|
Packit |
fcad23 |
fprintf(stderr, "%s: Too many variables specified (max %d)\n",
|
|
Packit |
fcad23 |
argv[optind], MAX_ARGS);
|
|
Packit |
fcad23 |
goto out;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
varinfo[current_name++].name = argv[optind];
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (current_name == 0) {
|
|
Packit |
fcad23 |
usage();
|
|
Packit |
fcad23 |
goto out;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (dosum) {
|
|
Packit |
fcad23 |
if (current_name >= MAX_ARGS) {
|
|
Packit |
fcad23 |
fprintf(stderr, "Too many variables specified (max %d)\n",
|
|
Packit |
fcad23 |
MAX_ARGS);
|
|
Packit |
fcad23 |
goto out;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
varinfo[current_name++].name = NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* open an SNMP session
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
ss = snmp_open(&session);
|
|
Packit |
fcad23 |
if (ss == NULL) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* diagnose snmp_open errors with the input netsnmp_session pointer
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
snmp_sess_perror("snmpdelta", &session);
|
|
Packit |
fcad23 |
goto out;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (tableForm && timestamp) {
|
|
Packit |
fcad23 |
printf("%s", gateway);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
for (count = 0; count < current_name; count++) {
|
|
Packit |
fcad23 |
vip = varinfo + count;
|
|
Packit |
fcad23 |
if (vip->name) {
|
|
Packit |
fcad23 |
vip->oidlen = MAX_OID_LEN;
|
|
Packit |
fcad23 |
vip->info_oid = (oid *) malloc(sizeof(oid) * vip->oidlen);
|
|
Packit |
fcad23 |
if (snmp_parse_oid(vip->name, vip->info_oid, &vip->oidlen) ==
|
|
Packit |
fcad23 |
NULL) {
|
|
Packit |
fcad23 |
snmp_perror(vip->name);
|
|
Packit |
fcad23 |
goto close_session;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
sprint_descriptor(vip->descriptor, vip);
|
|
Packit |
fcad23 |
if (tableForm)
|
|
Packit |
fcad23 |
printf("\t%s", vip->descriptor);
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
vip->oidlen = 0;
|
|
Packit |
fcad23 |
strlcpy(vip->descriptor, SumFile, sizeof(vip->descriptor));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
vip->value = 0;
|
|
Packit |
fcad23 |
zeroU64(&vip->c64value);
|
|
Packit |
fcad23 |
vip->time = 0;
|
|
Packit |
fcad23 |
vip->max = 0;
|
|
Packit |
fcad23 |
if (peaks) {
|
|
Packit |
fcad23 |
vip->peak_count = -1;
|
|
Packit |
fcad23 |
vip->peak = 0;
|
|
Packit |
fcad23 |
vip->peak_average = 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
wait_for_period(period);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
end = current_name;
|
|
Packit |
fcad23 |
sum = 0;
|
|
Packit |
fcad23 |
while (1) {
|
|
Packit |
fcad23 |
pdu = snmp_pdu_create(SNMP_MSG_GET);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (deltat)
|
|
Packit |
fcad23 |
snmp_add_null_var(pdu, sysUpTimeOid, sysUpTimeLen);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (end == current_name)
|
|
Packit |
fcad23 |
count = 0;
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
count = end;
|
|
Packit |
fcad23 |
begin = count;
|
|
Packit |
fcad23 |
for (; count < current_name
|
|
Packit |
fcad23 |
&& count < begin + varbindsPerPacket - deltat; count++) {
|
|
Packit |
fcad23 |
if (varinfo[count].oidlen)
|
|
Packit |
fcad23 |
snmp_add_null_var(pdu, varinfo[count].info_oid,
|
|
Packit |
fcad23 |
varinfo[count].oidlen);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
last_end = end;
|
|
Packit |
fcad23 |
end = count;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
retry:
|
|
Packit |
fcad23 |
status = snmp_synch_response(ss, pdu, &response);
|
|
Packit |
fcad23 |
if (status == STAT_SUCCESS) {
|
|
Packit |
fcad23 |
if (response->errstat == SNMP_ERR_NOERROR) {
|
|
Packit |
fcad23 |
if (timestamp) {
|
|
Packit |
fcad23 |
gettimeofday(&tv, (struct timezone *) 0);
|
|
Packit |
fcad23 |
memcpy(&tm, localtime((time_t *) & tv.tv_sec),
|
|
Packit |
fcad23 |
sizeof(tm));
|
|
Packit |
fcad23 |
if (((period % 60)
|
|
Packit |
fcad23 |
&& (!peaks || ((period * peaks) % 60)))
|
|
Packit |
fcad23 |
|| keepSeconds)
|
|
Packit |
fcad23 |
sprintf(timestring, " [%02d:%02d:%02d %d/%d]",
|
|
Packit |
fcad23 |
tm.tm_hour, tm.tm_min, tm.tm_sec,
|
|
Packit |
fcad23 |
tm.tm_mon + 1, tm.tm_mday);
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
sprintf(timestring, " [%02d:%02d %d/%d]",
|
|
Packit |
fcad23 |
tm.tm_hour, tm.tm_min,
|
|
Packit |
fcad23 |
tm.tm_mon + 1, tm.tm_mday);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
vars = response->variables;
|
|
Packit |
fcad23 |
if (deltat) {
|
|
Packit |
fcad23 |
if (!vars || !vars->val.integer) {
|
|
Packit |
fcad23 |
fprintf(stderr, "Missing variable in reply\n");
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
this_time = *(vars->val.integer);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
vars = vars->next_variable;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
this_time = 1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
for (count = begin; count < end; count++) {
|
|
Packit |
fcad23 |
vip = varinfo + count;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (vip->oidlen) {
|
|
Packit |
fcad23 |
if (!vars || !vars->val.integer) {
|
|
Packit |
fcad23 |
fprintf(stderr, "Missing variable in reply\n");
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
vip->type = vars->type;
|
|
Packit |
fcad23 |
if (vars->type == ASN_COUNTER64) {
|
|
Packit |
fcad23 |
u64Subtract(vars->val.counter64,
|
|
Packit |
fcad23 |
&vip->c64value, &c64value);
|
|
Packit |
fcad23 |
memcpy(&vip->c64value, vars->val.counter64,
|
|
Packit |
fcad23 |
sizeof(struct counter64));
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
value = *(vars->val.integer) - vip->value;
|
|
Packit |
fcad23 |
vip->value = *(vars->val.integer);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
vars = vars->next_variable;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
value = sum;
|
|
Packit |
fcad23 |
sum = 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
delta_time = this_time - vip->time;
|
|
Packit |
fcad23 |
if (delta_time <= 0)
|
|
Packit |
fcad23 |
delta_time = 100;
|
|
Packit |
fcad23 |
last_time = vip->time;
|
|
Packit |
fcad23 |
vip->time = this_time;
|
|
Packit |
fcad23 |
if (last_time == 0)
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (vip->oidlen && vip->type != ASN_COUNTER64) {
|
|
Packit |
fcad23 |
sum += value;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (tableForm) {
|
|
Packit |
fcad23 |
if (count == begin) {
|
|
Packit |
fcad23 |
sprintf(outstr, "%s", timestring + 1);
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
outstr[0] = '\0';
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
sprintf(outstr, "%s %s", timestring,
|
|
Packit |
fcad23 |
vip->descriptor);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (deltat || tableForm) {
|
|
Packit |
fcad23 |
if (vip->type == ASN_COUNTER64) {
|
|
Packit |
fcad23 |
fprintf(stderr,
|
|
Packit |
fcad23 |
"time delta and table form not supported for counter64s\n");
|
|
Packit |
fcad23 |
goto close_session;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
printvalue =
|
|
Packit |
fcad23 |
((float) value * 100) / delta_time;
|
|
Packit |
fcad23 |
if (tableForm)
|
|
Packit |
fcad23 |
sprintf(valueStr, "\t%.2f", printvalue);
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
sprintf(valueStr, " /sec: %.2f",
|
|
Packit |
fcad23 |
printvalue);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
printvalue = (float) value;
|
|
Packit |
fcad23 |
sprintf(valueStr, " /%d sec: ", period);
|
|
Packit |
fcad23 |
if (vip->type == ASN_COUNTER64)
|
|
Packit |
fcad23 |
printU64(valueStr + strlen(valueStr),
|
|
Packit |
fcad23 |
&c64value);
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
sprintf(valueStr + strlen(valueStr), "%u",
|
|
Packit |
fcad23 |
value);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (!peaks) {
|
|
Packit |
fcad23 |
strcat(outstr, valueStr);
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
print = 0;
|
|
Packit |
fcad23 |
if (vip->peak_count == -1) {
|
|
Packit |
fcad23 |
if (wait_for_peak_start(period, peaks) == 0)
|
|
Packit |
fcad23 |
vip->peak_count = 0;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
vip->peak_average += printvalue;
|
|
Packit |
fcad23 |
if (vip->peak < printvalue)
|
|
Packit |
fcad23 |
vip->peak = printvalue;
|
|
Packit |
fcad23 |
if (++vip->peak_count == peaks) {
|
|
Packit |
fcad23 |
if (deltat)
|
|
Packit |
fcad23 |
sprintf(peakStr,
|
|
Packit |
fcad23 |
" /sec: %.2f (%d sec Peak: %.2f)",
|
|
Packit |
fcad23 |
vip->peak_average /
|
|
Packit |
fcad23 |
vip->peak_count, period,
|
|
Packit |
fcad23 |
vip->peak);
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
sprintf(peakStr,
|
|
Packit |
fcad23 |
" /%d sec: %.0f (%d sec Peak: %.0f)",
|
|
Packit |
fcad23 |
period,
|
|
Packit |
fcad23 |
vip->peak_average /
|
|
Packit |
fcad23 |
vip->peak_count, period,
|
|
Packit |
fcad23 |
vip->peak);
|
|
Packit |
fcad23 |
vip->peak_average = 0;
|
|
Packit |
fcad23 |
vip->peak = 0;
|
|
Packit |
fcad23 |
vip->peak_count = 0;
|
|
Packit |
fcad23 |
print = 1;
|
|
Packit |
fcad23 |
strcat(outstr, peakStr);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (printmax) {
|
|
Packit |
fcad23 |
if (printvalue > vip->max) {
|
|
Packit |
fcad23 |
vip->max = printvalue;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if (deltat)
|
|
Packit |
fcad23 |
sprintf(maxStr, " (Max: %.2f)", vip->max);
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
sprintf(maxStr, " (Max: %.0f)", vip->max);
|
|
Packit |
fcad23 |
strcat(outstr, maxStr);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (print) {
|
|
Packit |
fcad23 |
if (fileout) {
|
|
Packit |
fcad23 |
sprintf(filename, "%s-%s", gateway,
|
|
Packit |
fcad23 |
vip->descriptor);
|
|
Packit |
fcad23 |
print_log(filename, outstr + 1);
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
if (tableForm)
|
|
Packit |
fcad23 |
printf("%s", outstr);
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
printf("%s\n", outstr + 1);
|
|
Packit |
fcad23 |
fflush(stdout);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if (end == last_end && tableForm)
|
|
Packit |
fcad23 |
printf("\n");
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
if (response->errstat == SNMP_ERR_TOOBIG) {
|
|
Packit |
fcad23 |
if (response->errindex <= varbindsPerPacket
|
|
Packit |
fcad23 |
&& response->errindex > 0) {
|
|
Packit |
fcad23 |
varbindsPerPacket = response->errindex - 1;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
if (varbindsPerPacket > 30)
|
|
Packit |
fcad23 |
varbindsPerPacket -= 5;
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
varbindsPerPacket--;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if (varbindsPerPacket <= 0) {
|
|
Packit |
fcad23 |
exit_code = 5;
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
end = last_end;
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
} else if (response->errindex != 0) {
|
|
Packit |
fcad23 |
fprintf(stderr, "Failed object: ");
|
|
Packit |
fcad23 |
for (count = 1, vars = response->variables;
|
|
Packit |
fcad23 |
vars && count != response->errindex;
|
|
Packit |
fcad23 |
vars = vars->next_variable, count++);
|
|
Packit |
fcad23 |
if (vars)
|
|
Packit |
fcad23 |
fprint_objid(stderr, vars->name,
|
|
Packit |
fcad23 |
vars->name_length);
|
|
Packit |
fcad23 |
fprintf(stderr, "\n");
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Don't exit when OIDs from file are not found on agent
|
|
Packit |
fcad23 |
* exit_code = 1;
|
|
Packit |
fcad23 |
* break;
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
fprintf(stderr, "Error in packet: %s\n",
|
|
Packit |
fcad23 |
snmp_errstring(response->errstat));
|
|
Packit |
fcad23 |
exit_code = 1;
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* retry if the errored variable was successfully removed
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
|
|
Packit |
fcad23 |
NETSNMP_DS_APP_DONT_FIX_PDUS)) {
|
|
Packit |
fcad23 |
pdu = snmp_fix_pdu(response, SNMP_MSG_GET);
|
|
Packit |
fcad23 |
snmp_free_pdu(response);
|
|
Packit |
fcad23 |
response = NULL;
|
|
Packit |
fcad23 |
if (pdu != NULL)
|
|
Packit |
fcad23 |
goto retry;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
} else if (status == STAT_TIMEOUT) {
|
|
Packit |
fcad23 |
fprintf(stderr, "Timeout: No Response from %s\n", gateway);
|
|
Packit |
fcad23 |
response = NULL;
|
|
Packit |
fcad23 |
exit_code = 1;
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
} else { /* status == STAT_ERROR */
|
|
Packit |
fcad23 |
snmp_sess_perror("snmpdelta", ss);
|
|
Packit |
fcad23 |
response = NULL;
|
|
Packit |
fcad23 |
exit_code = 1;
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (response)
|
|
Packit |
fcad23 |
snmp_free_pdu(response);
|
|
Packit |
fcad23 |
if (end == current_name) {
|
|
Packit |
fcad23 |
wait_for_period(period);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
exit_code = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
close_session:
|
|
Packit |
fcad23 |
snmp_close(ss);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
out:
|
|
Packit |
fcad23 |
SOCK_CLEANUP;
|
|
Packit |
fcad23 |
return (exit_code);
|
|
Packit |
fcad23 |
}
|