snmpdelta.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:23k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  * snmpdelta.c - Monitor deltas of integer valued SNMP variables
  3.  *
  4.  */
  5. /**********************************************************************
  6.  *
  7.  *           Copyright 1996 by Carnegie Mellon University
  8.  * 
  9.  *                       All Rights Reserved
  10.  * 
  11.  * Permission to use, copy, modify, and distribute this software and its
  12.  * documentation for any purpose and without fee is hereby granted,
  13.  * provided that the above copyright notice appear in all copies and that
  14.  * both that copyright notice and this permission notice appear in
  15.  * supporting documentation, and that the name of CMU not be
  16.  * used in advertising or publicity pertaining to distribution of the
  17.  * software without specific, written prior permission.
  18.  * 
  19.  * CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  20.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  21.  * CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  22.  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  23.  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  24.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  25.  * SOFTWARE.
  26.  * 
  27.  **********************************************************************/
  28. #include <net-snmp/net-snmp-config.h>
  29. #if HAVE_STDLIB_H
  30. #include <stdlib.h>
  31. #endif
  32. #if HAVE_UNISTD_H
  33. #include <unistd.h>
  34. #endif
  35. #if HAVE_STRING_H
  36. #include <string.h>
  37. #else
  38. #include <strings.h>
  39. #endif
  40. #include <sys/types.h>
  41. #if HAVE_NETINET_IN_H
  42. #include <netinet/in.h>
  43. #endif
  44. #include <stdio.h>
  45. #include <ctype.h>
  46. #if TIME_WITH_SYS_TIME
  47. # ifdef WIN32
  48. #  include <sys/timeb.h>
  49. # else
  50. #  include <sys/time.h>
  51. # endif
  52. # include <time.h>
  53. #else
  54. # if HAVE_SYS_TIME_H
  55. #  include <sys/time.h>
  56. # else
  57. #  include <time.h>
  58. # endif
  59. #endif
  60. #if HAVE_SYS_SELECT_H
  61. #include <sys/select.h>
  62. #endif
  63. #if HAVE_WINSOCK_H
  64. #include <winsock.h>
  65. #endif
  66. #if HAVE_NETDB_H
  67. #include <netdb.h>
  68. #endif
  69. #if HAVE_ARPA_INET_H
  70. #include <arpa/inet.h>
  71. #endif
  72. #include <net-snmp/net-snmp-includes.h>
  73. #define MAX_ARGS 256
  74. #define NETSNMP_DS_APP_DONT_FIX_PDUS 0
  75. const char     *SumFile = "Sum";
  76. /*
  77.  * Information about the handled variables 
  78.  */
  79. struct varInfo {
  80.     char           *name;
  81.     oid            *info_oid;
  82.     int             type;
  83.     size_t          oidlen;
  84.     char            descriptor[64];
  85.     u_int           value;
  86.     struct counter64 c64value;
  87.     float           max;
  88.     time_t          time;
  89.     int             peak_count;
  90.     float           peak;
  91.     float           peak_average;
  92.     int             spoiled;
  93. };
  94. struct varInfo  varinfo[MAX_ARGS];
  95. int             current_name = 0;
  96. int             period = 1;
  97. int             deltat = 0, timestamp = 0, fileout = 0, dosum =
  98.     0, printmax = 0;
  99. int             keepSeconds = 0, peaks = 0;
  100. int             tableForm = 0;
  101. int             varbindsPerPacket = 60;
  102. void            processFileArgs(char *fileName);
  103. void
  104. usage(void)
  105. {
  106.     fprintf(stderr,
  107.             "Usage: snmpdelta [-Cf] [-CF commandFile] [-Cl] [-CL SumFileName]nt[-Cs] [-Ck] [-Ct] [-CS] [-Cv vars/pkt] [-Cp period]nt[-CP peaks] ");
  108.     snmp_parse_args_usage(stderr);
  109.     fprintf(stderr, " oid [oid ...]n");
  110.     snmp_parse_args_descriptions(stderr);
  111.     fprintf(stderr, "snmpdelta specific optionsn");
  112.     fprintf(stderr, "  -CfttDon't fix errors and retry the request.n");
  113.     fprintf(stderr, "  -Clttwrite configuration to filen");
  114.     fprintf(stderr, "  -CF configtload configuration from filen");
  115.     fprintf(stderr, "  -Cp periodtspecifies the poll periodn");
  116.     fprintf(stderr, "  -CP peakstreporting period in poll periodsn");
  117.     fprintf(stderr, "  -Cv vars/pkttnumber of variables per packetn");
  118.     fprintf(stderr, "  -Ckttkeep seconds in output timen");
  119.     fprintf(stderr, "  -Cmttshow max valuesn");
  120.     fprintf(stderr, "  -CSttlog to a sum filen");
  121.     fprintf(stderr, "  -Csttshow timestampsn");
  122.     fprintf(stderr, "  -Ctttget timing from agentn");
  123.     fprintf(stderr, "  -CTttprint output in tabular formn");
  124.     fprintf(stderr, "  -CL sumfiletspecifies the sum file namen");
  125. }
  126. static void
  127. optProc(int argc, char *const *argv, int opt)
  128. {
  129.     switch (opt) {
  130.     case 'C':
  131.         while (*optarg) {
  132.             switch ((opt = *optarg++)) {
  133.             case 'f':
  134.                 netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
  135.   NETSNMP_DS_APP_DONT_FIX_PDUS);
  136.                 break;
  137.             case 'p':
  138.                 period = atoi(argv[optind++]);
  139.                 break;
  140.             case 'P':
  141.                 peaks = atoi(argv[optind++]);
  142.                 break;
  143.             case 'v':
  144.                 varbindsPerPacket = atoi(argv[optind++]);
  145.                 break;
  146.             case 't':
  147.                 deltat = 1;
  148.                 break;
  149.             case 's':
  150.                 timestamp = 1;
  151.                 break;
  152.             case 'S':
  153.                 dosum = 1;
  154.                 break;
  155.             case 'm':
  156.                 printmax = 1;
  157.                 break;
  158.             case 'F':
  159.                 processFileArgs(argv[optind++]);
  160.                 break;
  161.             case 'l':
  162.                 fileout = 1;
  163.                 break;
  164.             case 'L':
  165.                 SumFile = argv[optind++];
  166.                 break;
  167.             case 'k':
  168.                 keepSeconds = 1;
  169.                 break;
  170.             case 'T':
  171.                 tableForm = 1;
  172.                 break;
  173.             default:
  174.                 fprintf(stderr, "Bad -C options: %cn", opt);
  175.                 exit(1);
  176.             }
  177.         }
  178.         break;
  179.     }
  180. }
  181. int
  182. wait_for_peak_start(int period, int peak)
  183. {
  184.     struct timeval  m_time, *tv = &m_time;
  185.     struct tm       tm;
  186.     time_t          SecondsAtNextHour;
  187.     int             target = 0;
  188.     int             seconds;
  189.     seconds = period * peak;
  190.     /*
  191.      * Find the current time 
  192.      */
  193.     gettimeofday(tv, (struct timezone *) 0);
  194.     /*
  195.      * Create a tm struct from it 
  196.      */
  197.     memcpy(&tm, localtime((time_t *) & tv->tv_sec), sizeof(tm));
  198.     /*
  199.      * Calculate the next hour 
  200.      */
  201.     tm.tm_sec = 0;
  202.     tm.tm_min = 0;
  203.     tm.tm_hour++;
  204.     SecondsAtNextHour = mktime(&tm);
  205.     /*
  206.      * Now figure out the amount of time to sleep 
  207.      */
  208.     target = (SecondsAtNextHour - tv->tv_sec) % seconds;
  209.     return target;
  210. }
  211. void
  212. print_log(char *file, char *message)
  213. {
  214.     FILE           *fp;
  215.     fp = fopen(file, "a");
  216.     if (fp == NULL) {
  217.         fprintf(stderr, "Couldn't open %sn", file);
  218.         return;
  219.     }
  220.     fprintf(fp, "%sn", message);
  221.     fclose(fp);
  222. }
  223. void
  224. sprint_descriptor(char *buffer, struct varInfo *vip)
  225. {
  226.     u_char         *buf = NULL, *cp = NULL;
  227.     size_t          buf_len = 0, out_len = 0;
  228.     if (!sprint_realloc_objid(&buf, &buf_len, &out_len, 1,
  229.                               vip->info_oid, vip->oidlen)) {
  230.         if (buf != NULL) {
  231.             free(buf);
  232.         }
  233.         return;
  234.     }
  235.     for (cp = buf; *cp; cp++);
  236.     while (cp >= buf) {
  237.         if (isalpha(*cp))
  238.             break;
  239.         cp--;
  240.     }
  241.     while (cp >= buf) {
  242.         if (*cp == '.')
  243.             break;
  244.         cp--;
  245.     }
  246.     cp++;
  247.     if (cp < buf)
  248.         cp = buf;
  249.     strcpy(buffer, cp);
  250.     if (buf != NULL) {
  251.         free(buf);
  252.     }
  253. }
  254. void
  255. processFileArgs(char *fileName)
  256. {
  257.     FILE           *fp;
  258.     char            buf[260] = { 0 }, *cp;
  259.     int             blank, linenumber = 0;
  260.     fp = fopen(fileName, "r");
  261.     if (fp == NULL)
  262.         return;
  263.     while (fgets(buf, sizeof(buf), fp)) {
  264.         linenumber++;
  265.         if (strlen(buf) > (sizeof(buf) - 2)) {
  266.             fprintf(stderr, "Line too long on line %d of %sn",
  267.                     linenumber, fileName);
  268.             exit(1);
  269.         }
  270.         if (buf[0] == '#')
  271.             continue;
  272.         blank = TRUE;
  273.         for (cp = buf; *cp; cp++)
  274.             if (!isspace(*cp)) {
  275.                 blank = FALSE;
  276.                 break;
  277.             }
  278.         if (blank)
  279.             continue;
  280.         buf[strlen(buf) - 1] = 0;
  281. if (current_name >= MAX_ARGS) {
  282.     fprintf(stderr, "Too many variables read at line %d of %s (max %d)n",
  283.      linenumber, fileName, MAX_ARGS);
  284.     exit(1);
  285. }
  286.         varinfo[current_name++].name = strdup(buf);
  287.     }
  288.     fclose(fp);
  289.     return;
  290. }
  291. void
  292. wait_for_period(int period)
  293. {
  294. #ifdef WIN32
  295.     Sleep(period * 1000);
  296. #else                   /* WIN32 */
  297.     struct timeval  m_time, *tv = &m_time;
  298.     struct tm       tm;
  299.     int             count;
  300.     static int      target = 0;
  301.     time_t          nexthour;
  302.     gettimeofday(tv, (struct timezone *) 0);
  303.     if (target) {
  304.         target += period;
  305.     } else {
  306.         memcpy(&tm, localtime((time_t *) & tv->tv_sec), sizeof(tm));
  307.         tm.tm_sec = 0;
  308.         tm.tm_min = 0;
  309.         tm.tm_hour++;
  310.         nexthour = mktime(&tm);
  311.         target = (nexthour - tv->tv_sec) % period;
  312.         if (target == 0)
  313.             target = period;
  314.         target += tv->tv_sec;
  315.     }
  316.     tv->tv_sec = target - tv->tv_sec;
  317.     if (tv->tv_usec != 0) {
  318.         tv->tv_sec--;
  319.         tv->tv_usec = 1000000 - tv->tv_usec;
  320.     }
  321.     if (tv->tv_sec < 0) {
  322.         /*
  323.          * ran out of time, schedule immediately 
  324.          */
  325.         tv->tv_sec = 0;
  326.         tv->tv_usec = 0;
  327.     }
  328.     count = 1;
  329.     while (count != 0) {
  330.         count = select(0, 0, 0, 0, tv);
  331.         switch (count) {
  332.         case 0:
  333.             break;
  334.         case -1:
  335.             /*
  336.              * FALLTHRU 
  337.              */
  338.         default:
  339.             snmp_log_perror("select");
  340.             break;
  341.         }
  342.     }
  343. #endif                   /* WIN32 */
  344. }
  345. oid             sysUpTimeOid[9] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
  346. size_t          sysUpTimeLen = 9;
  347. int
  348. main(int argc, char *argv[])
  349. {
  350.     netsnmp_session session, *ss;
  351.     netsnmp_pdu    *pdu, *response;
  352.     netsnmp_variable_list *vars;
  353.     int             arg;
  354.     char           *gateway;
  355.     int             count;
  356.     struct varInfo *vip;
  357.     u_int           value = 0;
  358.     struct counter64 c64value;
  359.     float           printvalue;
  360.     time_t          last_time = 0;
  361.     time_t          this_time;
  362.     time_t          delta_time;
  363.     int             sum;        /* what the heck is this for, its never used? */
  364.     char            filename[128] = { 0 };
  365.     struct timeval  tv;
  366.     struct tm       tm;
  367.     char            timestring[64] = { 0 }, valueStr[64] = {
  368.     0}, maxStr[64] = {
  369.     0};
  370.     char            outstr[256] = { 0 }, peakStr[64] = {
  371.     0};
  372.     int             status;
  373.     int             begin, end, last_end;
  374.     int             print = 1;
  375.     int             exit_code = 0;
  376.     switch (arg = snmp_parse_args(argc, argv, &session, "C:", &optProc)) {
  377.     case -2:
  378.         exit(0);
  379.     case -1:
  380.         usage();
  381.         exit(1);
  382.     default:
  383.         break;
  384.     }
  385.     gateway = session.peername;
  386.     for (; optind < argc; optind++) {
  387. if (current_name >= MAX_ARGS) {
  388.     fprintf(stderr, "%s: Too many variables specified (max %d)n",
  389.      argv[optind], MAX_ARGS);
  390.     exit(1);
  391. }
  392.         varinfo[current_name++].name = argv[optind];
  393.     }
  394.     if (current_name == 0) {
  395.         usage();
  396.         exit(1);
  397.     }
  398.     if (dosum) {
  399. if (current_name >= MAX_ARGS) {
  400.     fprintf(stderr, "Too many variables specified (max %d)n",
  401.      MAX_ARGS);
  402.     exit(1);
  403. }
  404.         varinfo[current_name++].name = 0;
  405.     }
  406.     SOCK_STARTUP;
  407.     /*
  408.      * open an SNMP session 
  409.      */
  410.     ss = snmp_open(&session);
  411.     if (ss == NULL) {
  412.         /*
  413.          * diagnose snmp_open errors with the input netsnmp_session pointer 
  414.          */
  415.         snmp_sess_perror("snmpdelta", &session);
  416.         SOCK_CLEANUP;
  417.         exit(1);
  418.     }
  419.     if (tableForm && timestamp) {
  420.         printf("%s", gateway);
  421.     }
  422.     for (count = 0; count < current_name; count++) {
  423.         vip = varinfo + count;
  424.         if (vip->name) {
  425.             vip->oidlen = MAX_OID_LEN;
  426.             vip->info_oid = (oid *) malloc(sizeof(oid) * vip->oidlen);
  427.             if (snmp_parse_oid(vip->name, vip->info_oid, &vip->oidlen) ==
  428.                 NULL) {
  429.                 snmp_perror(vip->name);
  430.                 SOCK_CLEANUP;
  431.                 exit(1);
  432.             }
  433.             sprint_descriptor(vip->descriptor, vip);
  434.             if (tableForm)
  435.                 printf("t%s", vip->descriptor);
  436.         } else {
  437.             vip->oidlen = 0;
  438.             strcpy(vip->descriptor, SumFile);
  439.         }
  440.         vip->value = 0;
  441.         zeroU64(&vip->c64value);
  442.         vip->time = 0;
  443.         vip->max = 0;
  444.         if (peaks) {
  445.             vip->peak_count = -1;
  446.             vip->peak = 0;
  447.             vip->peak_average = 0;
  448.         }
  449.     }
  450.     wait_for_period(period);
  451.     end = current_name;
  452.     sum = 0;
  453.     while (1) {
  454.         pdu = snmp_pdu_create(SNMP_MSG_GET);
  455.         if (deltat)
  456.             snmp_add_null_var(pdu, sysUpTimeOid, sysUpTimeLen);
  457.         if (end == current_name)
  458.             count = 0;
  459.         else
  460.             count = end;
  461.         begin = count;
  462.         for (; count < current_name
  463.              && count < begin + varbindsPerPacket - deltat; count++) {
  464.             if (varinfo[count].oidlen)
  465.                 snmp_add_null_var(pdu, varinfo[count].info_oid,
  466.                                   varinfo[count].oidlen);
  467.         }
  468.         last_end = end;
  469.         end = count;
  470.       retry:
  471.         status = snmp_synch_response(ss, pdu, &response);
  472.         if (status == STAT_SUCCESS) {
  473.             if (response->errstat == SNMP_ERR_NOERROR) {
  474.                 if (timestamp) {
  475.                     gettimeofday(&tv, (struct timezone *) 0);
  476.                     memcpy(&tm, localtime((time_t *) & tv.tv_sec),
  477.                            sizeof(tm));
  478.                     if (((period % 60)
  479.                          && (!peaks || ((period * peaks) % 60)))
  480.                         || keepSeconds)
  481.                         sprintf(timestring, " [%02d:%02d:%02d %d/%d]",
  482.                                 tm.tm_hour, tm.tm_min, tm.tm_sec,
  483.                                 tm.tm_mon + 1, tm.tm_mday);
  484.                     else
  485.                         sprintf(timestring, " [%02d:%02d %d/%d]",
  486.                                 tm.tm_hour, tm.tm_min,
  487.                                 tm.tm_mon + 1, tm.tm_mday);
  488.                 }
  489.                 vars = response->variables;
  490.                 if (deltat) {
  491.                     if (!vars || !vars->val.integer) {
  492.                         fprintf(stderr, "Missing variable in replyn");
  493.                         continue;
  494.                     } else {
  495.                         this_time = *(vars->val.integer);
  496.                     }
  497.                     vars = vars->next_variable;
  498.                 } else {
  499.                     this_time = 1;
  500.                 }
  501.                 for (count = begin; count < end; count++) {
  502.                     vip = varinfo + count;
  503.                     if (vip->oidlen) {
  504.                         if (!vars || !vars->val.integer) {
  505.                             fprintf(stderr, "Missing variable in replyn");
  506.                             break;
  507.                         }
  508.                         vip->type = vars->type;
  509.                         if (vars->type == ASN_COUNTER64) {
  510.                             u64Subtract(vars->val.counter64,
  511.                                         &vip->c64value, &c64value);
  512.                             memcpy(&vip->c64value, vars->val.counter64,
  513.                                    sizeof(struct counter64));
  514.                         } else {
  515.                             value = *(vars->val.integer) - vip->value;
  516.                             vip->value = *(vars->val.integer);
  517.                         }
  518.                         vars = vars->next_variable;
  519.                     } else {
  520.                         value = sum;
  521.                         sum = 0;
  522.                     }
  523.                     delta_time = this_time - vip->time;
  524.                     if (delta_time <= 0)
  525.                         delta_time = 100;
  526.                     last_time = vip->time;
  527.                     vip->time = this_time;
  528.                     if (last_time == 0)
  529.                         continue;
  530.                     if (vip->oidlen && vip->type != ASN_COUNTER64) {
  531.                         sum += value;
  532.                     }
  533.                     if (tableForm) {
  534.                         if (count == begin) {
  535.                             sprintf(outstr, "%s", timestring + 1);
  536.                         } else {
  537.                             outstr[0] = '';
  538.                         }
  539.                     } else {
  540.                         sprintf(outstr, "%s %s", timestring,
  541.                                 vip->descriptor);
  542.                     }
  543.                     if (deltat || tableForm) {
  544.                         if (vip->type == ASN_COUNTER64) {
  545.                             fprintf(stderr,
  546.                                     "time delta and table form not supported for counter64sn");
  547.                             exit(1);
  548.                         } else {
  549.                             printvalue =
  550.                                 ((float) value * 100) / delta_time;
  551.                             if (tableForm)
  552.                                 sprintf(valueStr, "t%.2f", printvalue);
  553.                             else
  554.                                 sprintf(valueStr, " /sec: %.2f",
  555.                                         printvalue);
  556.                         }
  557.                     } else {
  558.                         printvalue = (float) value;
  559.                         sprintf(valueStr, " /%d sec: ", period);
  560.                         if (vip->type == ASN_COUNTER64)
  561.                             printU64(valueStr + strlen(valueStr),
  562.                                      &c64value);
  563.                         else
  564.                             sprintf(valueStr + strlen(valueStr), "%u",
  565.                                     value);
  566.                     }
  567.                     if (!peaks) {
  568.                         strcat(outstr, valueStr);
  569.                     } else {
  570.                         print = 0;
  571.                         if (vip->peak_count == -1) {
  572.                             if (wait_for_peak_start(period, peaks) == 0)
  573.                                 vip->peak_count = 0;
  574.                         } else {
  575.                             vip->peak_average += printvalue;
  576.                             if (vip->peak < printvalue)
  577.                                 vip->peak = printvalue;
  578.                             if (++vip->peak_count == peaks) {
  579.                                 if (deltat)
  580.                                     sprintf(peakStr,
  581.                                             " /sec: %.2f (%d sec Peak: %.2f)",
  582.                                             vip->peak_average /
  583.                                             vip->peak_count, period,
  584.                                             vip->peak);
  585.                                 else
  586.                                     sprintf(peakStr,
  587.                                             " /%d sec: %.0f (%d sec Peak: %.0f)",
  588.                                             period,
  589.                                             vip->peak_average /
  590.                                             vip->peak_count, period,
  591.                                             vip->peak);
  592.                                 vip->peak_average = 0;
  593.                                 vip->peak = 0;
  594.                                 vip->peak_count = 0;
  595.                                 print = 1;
  596.                                 strcat(outstr, peakStr);
  597.                             }
  598.                         }
  599.                     }
  600.                     if (printmax) {
  601.                         if (printvalue > vip->max) {
  602.                             vip->max = printvalue;
  603.                         }
  604.                         if (deltat)
  605.                             sprintf(maxStr, " (Max: %.2f)", vip->max);
  606.                         else
  607.                             sprintf(maxStr, " (Max: %.0f)", vip->max);
  608.                         strcat(outstr, maxStr);
  609.                     }
  610.                     if (print) {
  611.                         if (fileout) {
  612.                             sprintf(filename, "%s-%s", gateway,
  613.                                     vip->descriptor);
  614.                             print_log(filename, outstr + 1);
  615.                         } else {
  616.                             if (tableForm)
  617.                                 printf("%s", outstr);
  618.                             else
  619.                                 printf("%sn", outstr + 1);
  620.                             fflush(stdout);
  621.                         }
  622.                     }
  623.                 }
  624.                 if (end == last_end && tableForm)
  625.                     printf("n");
  626.             } else {
  627.                 if (response->errstat == SNMP_ERR_TOOBIG) {
  628.                     if (response->errindex <= varbindsPerPacket
  629.                         && response->errindex > 0) {
  630.                         varbindsPerPacket = response->errindex - 1;
  631.                     } else {
  632.                         if (varbindsPerPacket > 30)
  633.                             varbindsPerPacket -= 5;
  634.                         else
  635.                             varbindsPerPacket--;
  636.                     }
  637.                     if (varbindsPerPacket <= 0) {
  638.                         exit_code = 5;
  639.                         break;
  640.                     }
  641.                     end = last_end;
  642.                     continue;
  643.                 } else if (response->errindex != 0) {
  644.                     fprintf(stderr, "Failed object: ");
  645.                     for (count = 1, vars = response->variables;
  646.                          vars && count != response->errindex;
  647.                          vars = vars->next_variable, count++);
  648.                     if (vars)
  649.                         fprint_objid(stderr, vars->name,
  650.                                      vars->name_length);
  651.                     fprintf(stderr, "n");
  652.                     /*
  653.                      * Don't exit when OIDs from file are not found on agent
  654.                      * exit_code = 1;
  655.                      * break;
  656.                      */
  657.                 } else {
  658.                     fprintf(stderr, "Error in packet: %sn",
  659.                             snmp_errstring(response->errstat));
  660.                     exit_code = 1;
  661.                     break;
  662.                 }
  663.                 /*
  664.                  * retry if the errored variable was successfully removed 
  665.                  */
  666.                 if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
  667.     NETSNMP_DS_APP_DONT_FIX_PDUS)) {
  668.                     pdu = snmp_fix_pdu(response, SNMP_MSG_GET);
  669.                     snmp_free_pdu(response);
  670.                     response = NULL;
  671.                     if (pdu != NULL)
  672.                         goto retry;
  673.                 }
  674.             }
  675.         } else if (status == STAT_TIMEOUT) {
  676.             fprintf(stderr, "Timeout: No Response from %sn", gateway);
  677.             response = 0;
  678.             exit_code = 1;
  679.             break;
  680.         } else {                /* status == STAT_ERROR */
  681.             snmp_sess_perror("snmpdelta", ss);
  682.             response = 0;
  683.             exit_code = 1;
  684.             break;
  685.         }
  686.         if (response)
  687.             snmp_free_pdu(response);
  688.         if (end == current_name) {
  689.             wait_for_period(period);
  690.         }
  691.     }
  692.     snmp_close(ss);
  693.     SOCK_CLEANUP;
  694.     return (exit_code);
  695. }