text: /*
   *Copyright(c)2004,Cisco URP imburses and Network Information Center in Beijing University of Posts and Telecommunications researches.
   *
   *All right reserved
   *
   *File Name:traceRouteCtlTable.c
   *File Description:Rows of traceRouteCtlTable MIB add delete ans read.
   *              Rows of traceRouteResultsTable MIB add and delete.
   *              Rows of traceRouteProbeHistoryTable MIB add and delete.
   *              Rows of traceRouteHopsTable MIB add and delete.
   *              The main function is also here.
   *
   *Current Version:1.0
   *Author:ChenJing
   *Date:2004.8.20
   */
  
  
  #include <net-snmp/net-snmp-config.h>
  #include <net-snmp/net-snmp-includes.h>
  #include <net-snmp/net-snmp-features.h>
  #include <net-snmp/agent/net-snmp-agent-includes.h>
  #include <pthread.h>
  #include <math.h>
  #include <stddef.h>
  
  #ifndef NETSNMP_NO_WRITE_SUPPORT
  netsnmp_feature_require(header_complex_find_entry);
  #endif /* NETSNMP_NO_WRITE_SUPPORT */
  
  #include "traceRouteCtlTable.h"
  #include "traceRouteResultsTable.h"
  #include "traceRouteProbeHistoryTable.h"
  #include "traceRouteHopsTable.h"
  #include "header_complex.h"
  
  oid             traceRouteCtlTable_variables_oid[] =
      { 1, 3, 6, 1, 2, 1, 81, 1, 2 };
  
  /* trap */
  oid             traceRoutePathChange[] = { 1, 3, 6, 1, 2, 1, 81, 0, 1 };
  oid             traceRouteTestFailed[] = { 1, 3, 6, 1, 2, 1, 81, 0, 2 };
  oid             traceRouteTestCompleted[] = { 1, 3, 6, 1, 2, 1, 81, 0, 3 };
  
  struct variable2 traceRouteCtlTable_variables[] = {
      /*
       * magic number        , variable type , ro/rw , callback fn  , L, oidsuffix 
       */
  
      {COLUMN_TRACEROUTECTLTARGETADDRESSTYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 3}},
      {COLUMN_TRACEROUTECTLTARGETADDRESS,   ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 4}},
      {COLUMN_TRACEROUTECTLBYPASSROUTETABLE,  ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 5}},
      {COLUMN_TRACEROUTECTLDATASIZE,     ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 6}},
      {COLUMN_TRACEROUTECTLTIMEOUT,      ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 7}},
      {COLUMN_TRACEROUTECTLPROBESPERHOP, ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 8}},
      {COLUMN_TRACEROUTECTLPORT,         ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 9}},
      {COLUMN_TRACEROUTECTLMAXTTL,       ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 10}},
      {COLUMN_TRACEROUTECTLDSFIELD,      ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 11}},
      {COLUMN_TRACEROUTECTLSOURCEADDRESSTYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 12}},
      {COLUMN_TRACEROUTECTLSOURCEADDRESS,   ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 13}},
      {COLUMN_TRACEROUTECTLIFINDEX,       ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 14}},
      {COLUMN_TRACEROUTECTLMISCOPTIONS, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 15}},
      {COLUMN_TRACEROUTECTLMAXFAILURES,  ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 16}},
      {COLUMN_TRACEROUTECTLDONTFRAGMENT,  ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 17}},
      {COLUMN_TRACEROUTECTLINITIALTTL,   ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 18}},
      {COLUMN_TRACEROUTECTLFREQUENCY,    ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 19}},
      {COLUMN_TRACEROUTECTLSTORAGETYPE,   ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 20}},
      {COLUMN_TRACEROUTECTLADMINSTATUS,   ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 21}},
      {COLUMN_TRACEROUTECTLDESCR,       ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 22}},
      {COLUMN_TRACEROUTECTLMAXROWS,      ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 23}},
      {COLUMN_TRACEROUTECTLTRAPGENERATION,  ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 24}},
      {COLUMN_TRACEROUTECTLCREATEHOPSENTRIES, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 25}},
      {COLUMN_TRACEROUTECTLTYPE,        ASN_OBJECT_ID, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 26}},
      {COLUMN_TRACEROUTECTLROWSTATUS,     ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
       var_traceRouteCtlTable, 2, {1, 27}}
  
  };
  
  /*
   * global storage of our data, saved in and configured by header_complex() 
   */
  
  struct header_complex_index *traceRouteCtlTableStorage = NULL;
  struct header_complex_index *traceRouteResultsTableStorage = NULL;
  struct header_complex_index *traceRouteProbeHistoryTableStorage = NULL;
  struct header_complex_index *traceRouteHopsTableStorage = NULL;
  
  static char *
  findsaddr(const struct sockaddr_in *to, struct sockaddr_in *from);
  int
  traceRouteResultsTable_add(struct traceRouteCtlTable_data *thedata);
  int
  traceRouteResultsTable_del(struct traceRouteCtlTable_data *thedata);
  
  void
  init_traceRouteCtlTable(void)
  {
      DEBUGMSGTL(("traceRouteCtlTable", "initializing...  "));
      /*
       * register ourselves with the agent to handle our mib tree 
       */
      REGISTER_MIB("traceRouteCtlTable", traceRouteCtlTable_variables,
                   variable2, traceRouteCtlTable_variables_oid);
  
      /*
       * register our config handler(s) to deal with registrations 
       */
      snmpd_register_config_handler("traceRouteCtlTable",
                                    parse_traceRouteCtlTable, NULL, NULL);
  
      /*
       * we need to be called back later to store our data 
       */
      snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
                             store_traceRouteCtlTable, NULL);
  
      DEBUGMSGTL(("traceRouteCtlTable", "done.\n"));
  }
  
  static void
  init_trResultsTable_ipv4(char *host,
                           struct traceRouteResultsTable_data *StorageTmp)
  {
      struct sockaddr whereto;        /* Who to try to reach */
      struct sockaddr_in *to = (struct sockaddr_in *) &whereto;
      struct hostinfo *hi;
  
      hi = gethostinfo(host);
      if (hi == NULL) {
          DEBUGMSGTL(("traceRouteCtlTable", "hi calloc %s\n",
                      strerror(errno)));
          exit(1);
      }
  
      setsin(to, hi->addrs[0]);
      if (inet_ntoa(to->sin_addr) == NULL) {
          StorageTmp->traceRouteResultsIpTgtAddrType = 0;
          StorageTmp->traceRouteResultsIpTgtAddr = strdup("");
          StorageTmp->traceRouteResultsIpTgtAddrLen = 0;
      } else {
          StorageTmp->traceRouteResultsIpTgtAddrType = 1;
          StorageTmp->traceRouteResultsIpTgtAddr =
              (char *) malloc(sizeof(char) *
                              (strlen(inet_ntoa(to->sin_addr)) + 1));
          if (StorageTmp->traceRouteResultsIpTgtAddr == NULL) {
              DEBUGMSGTL(("traceRouteCtlTable",
                          "traceRouteResultsIpTgtAddr malloc %s\n",
                          strerror(errno)));
              exit(1);
          }
  
          memcpy(StorageTmp->traceRouteResultsIpTgtAddr, inet_ntoa(to->sin_addr),
                 strlen(inet_ntoa(to->sin_addr)) + 1);
          StorageTmp->traceRouteResultsIpTgtAddr[strlen(inet_ntoa(to->sin_addr))]
              = '\0';
          StorageTmp->traceRouteResultsIpTgtAddrLen =
              strlen(inet_ntoa(to->sin_addr));
      }
      freehostinfo(hi);
  }
  
  static void
  init_trResultsTable_ipv6(char *host,
                           struct traceRouteResultsTable_data *StorageTmp)
  {
      struct sockaddr_in6 whereto;    /* Who to try to reach */
      struct sockaddr_in6 *to = (struct sockaddr_in6 *) &whereto;
      struct hostent *hp = NULL;
      /* struct hostenv hp; */
      char            pa[64];
  
      memset(pa, '\0', 64);
  
      to->sin6_family = AF_INET6;
      to->sin6_port = htons(33434);
  
      if (inet_pton(AF_INET6, host, &to->sin6_addr) > 0) {
          StorageTmp->traceRouteResultsIpTgtAddrType = 2;
          StorageTmp->traceRouteResultsIpTgtAddr =
              (char *) malloc(sizeof(char) * (strlen(host) + 1));
          if (StorageTmp->traceRouteResultsIpTgtAddr == NULL) {
              DEBUGMSGTL(("traceRouteCtlTable",
                          "traceRouteResultsIpTgtAddr malloc %s\n",
                          strerror(errno)));
              exit(1);
          }
          memset(StorageTmp->traceRouteResultsIpTgtAddr, '\0',
                 sizeof(char) * (strlen(host) + 1));
          memcpy(StorageTmp->traceRouteResultsIpTgtAddr, host, strlen(host) + 1);
          StorageTmp->traceRouteResultsIpTgtAddr[strlen(host)] = '\0';
          StorageTmp->traceRouteResultsIpTgtAddrLen = strlen(host);
      } else {
          hp = gethostbyname2(host, AF_INET6);
          if (hp != NULL) {
              const char     *hostname;
  
              memmove((caddr_t) & to->sin6_addr, hp->h_addr, 16);
              hostname = inet_ntop(AF_INET6, &to->sin6_addr, pa, 64);
              StorageTmp->traceRouteResultsIpTgtAddrType = 2;
              StorageTmp->traceRouteResultsIpTgtAddr =
                  (char *) malloc(sizeof(char) * (strlen(hostname) + 1));
              if (StorageTmp->traceRouteResultsIpTgtAddr == NULL) {
                  DEBUGMSGTL(("traceRouteCtlTable",
                              "traceRouteResultsIpTgtAddr malloc %s\n",
                              strerror(errno)));
                  exit(1);
              }
              memset(StorageTmp->traceRouteResultsIpTgtAddr, '\0',
                     sizeof(char) * (strlen(host) + 1));
              memcpy(StorageTmp->traceRouteResultsIpTgtAddr, hostname,
                     strlen(hostname) + 1);
              StorageTmp->traceRouteResultsIpTgtAddr[strlen(hostname)] = '\0';
              StorageTmp->traceRouteResultsIpTgtAddrLen = strlen(hostname);
          } else {
              DEBUGMSGTL(("traceRouteCtlTable",
                          "traceroute: unknown host %s\n", host));
  
              StorageTmp->traceRouteResultsIpTgtAddrType = 0;
              StorageTmp->traceRouteResultsIpTgtAddr = strdup("");
              StorageTmp->traceRouteResultsIpTgtAddrLen = 0;
          }
      }
  }
  
  void
  init_trResultsTable(struct traceRouteCtlTable_data *item)
  {
      struct traceRouteResultsTable_data *StorageTmp = NULL;
      netsnmp_variable_list *vars = NULL;
      char           *host = NULL;
  
      host =
          (char *) malloc(sizeof(char) *
                          (item->traceRouteCtlTargetAddressLen + 1));
  
      if (host == NULL) {
          DEBUGMSGTL(("traceRouteCtlTable", "host calloc %s\n",
                      strerror(errno)));
          exit(1);
      }
  
      memset(host, '\0',
  	   sizeof(char) * (item->traceRouteCtlTargetAddressLen + 1));
      strcpy(host, item->traceRouteCtlTargetAddress);
      host[item->traceRouteCtlTargetAddressLen] = '\0';
  
      StorageTmp = SNMP_MALLOC_STRUCT(traceRouteResultsTable_data);
      if (StorageTmp == NULL) {
          DEBUGMSGTL(("traceRouteCtlTable", "StorageTmp malloc %s\n",
                      strerror(errno)));
          exit(1);
      }
  
      StorageTmp->traceRouteCtlOwnerIndex =
          (char *) malloc(sizeof(char) *
                          (item->traceRouteCtlOwnerIndexLen + 1));
      if (StorageTmp->traceRouteCtlOwnerIndex == NULL) {
          DEBUGMSGTL(("traceRouteCtlTable",
                      "traceRouteCtlOwnerIndex malloc %s\n",
                      strerror(errno)));
          exit(1);
      }
  
      memcpy(StorageTmp->traceRouteCtlOwnerIndex,
             item->traceRouteCtlOwnerIndex,
             item->traceRouteCtlOwnerIndexLen + 1);
      StorageTmp->traceRouteCtlOwnerIndex[item->traceRouteCtlOwnerIndexLen] =
          '\0';
      StorageTmp->traceRouteCtlOwnerIndexLen =
          item->traceRouteCtlOwnerIndexLen;
  
      StorageTmp->traceRouteCtlTestName =
          (char *) malloc(sizeof(char) *
                          (item->traceRouteCtlTestNameLen + 1));
      if (StorageTmp->traceRouteCtlTestName == NULL) {
          DEBUGMSGTL(("traceRouteCtlTable",
                      "traceRouteCtlTestName malloc %s\n", strerror(errno)));
          exit(1);
      }
  
      memcpy(StorageTmp->traceRouteCtlTestName, item->traceRouteCtlTestName,
             item->traceRouteCtlTestNameLen + 1);
      StorageTmp->traceRouteCtlTestName[item->traceRouteCtlTestNameLen] =
          '\0';
      StorageTmp->traceRouteCtlTestNameLen = item->traceRouteCtlTestNameLen;
  
      StorageTmp->traceRouteResultsOperStatus = 1;
  
      switch (item->traceRouteCtlTargetAddressType) {
      case 1:
      case 16:
          init_trResultsTable_ipv4(host, StorageTmp);
          break;
      case 2:
          init_trResultsTable_ipv6(host, StorageTmp);
          break;
      }
  
      StorageTmp->traceRouteResultsCurHopCount = 0;
      StorageTmp->traceRouteResultsCurProbeCount = 0;
      StorageTmp->traceRouteResultsTestAttempts = 0;
      StorageTmp->traceRouteResultsTestSuccesses = 0;
  
      StorageTmp->traceRouteResultsLastGoodPathLen = 0;
  
      item->traceRouteResults = StorageTmp;
  
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /*  traceRouteCtlOwnerIndex  */
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen);     /*  traceRouteCtlTestName  */
      if ((header_complex_get(traceRouteResultsTableStorage, vars)) != NULL) {
          traceRouteResultsTable_del(item);
      }
      snmp_free_varbind(vars);
      vars = NULL;
      if (item->traceRouteResults != NULL) {
          if (traceRouteResultsTable_add(item) != SNMPERR_SUCCESS) {
              DEBUGMSGTL(("traceRouteResultsTable",
                          "init an entry error\n"));
          }
      }
      free(host);
  }
  
  
  
  int
  modify_trResultsOper(struct traceRouteCtlTable_data *thedata, long val)
  {
      netsnmp_variable_list *vars = NULL;
      struct traceRouteResultsTable_data *StorageTmp = NULL;
  
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen);   /* traceRouteCtlOwnerIndex */
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen);       /* traceRouteCtlTestName */
  
      if ((StorageTmp =
           header_complex_get(traceRouteResultsTableStorage,
                              vars)) == NULL) {
          snmp_free_varbind(vars);
          vars = NULL;
          return SNMP_ERR_NOSUCHNAME;
      } else {
          StorageTmp->traceRouteResultsOperStatus = val;
          DEBUGMSGTL(("traceRouteResultsOperStatus", "done.\n"));
          snmp_free_varbind(vars);
          vars = NULL;
          return SNMPERR_SUCCESS;
      }
  }
  
  
  struct traceRouteCtlTable_data *
  create_traceRouteCtlTable_data(void)
  {
      struct traceRouteCtlTable_data *StorageNew = NULL;
      StorageNew = SNMP_MALLOC_STRUCT(traceRouteCtlTable_data);
      if (StorageNew == NULL) {
          exit(1);
      }
      StorageNew->traceRouteCtlTargetAddressType = 1;
      StorageNew->traceRouteCtlTargetAddress = strdup("");
      StorageNew->traceRouteCtlTargetAddressLen = 0;
      StorageNew->traceRouteCtlByPassRouteTable = 2;
      StorageNew->traceRouteCtlDataSize = 0;
      StorageNew->traceRouteCtlTimeOut = 3;
      StorageNew->traceRouteCtlProbesPerHop = 3;
      StorageNew->traceRouteCtlPort = 33434;
      StorageNew->traceRouteCtlMaxTtl = 30;
      StorageNew->traceRouteCtlDSField = 0;
      StorageNew->traceRouteCtlSourceAddressType = 0;
      StorageNew->traceRouteCtlSourceAddress = strdup("");
      StorageNew->traceRouteCtlSourceAddressLen = 0;
      StorageNew->traceRouteCtlIfIndex = 0;
      StorageNew->traceRouteCtlMiscOptions = strdup("");
      StorageNew->traceRouteCtlMiscOptionsLen = 0;
      StorageNew->traceRouteCtlMaxFailures = 5;
      StorageNew->traceRouteCtlDontFragment = 2;
      StorageNew->traceRouteCtlInitialTtl = 1;
      StorageNew->traceRouteCtlFrequency = 0;
      StorageNew->traceRouteCtlStorageType = ST_NONVOLATILE;
      StorageNew->traceRouteCtlAdminStatus = 2;
      StorageNew->traceRouteCtlDescr = (char *) malloc(strlen("00") + 1);
      if (StorageNew->traceRouteCtlDescr == NULL) {
          exit(1);
      }
      memcpy(StorageNew->traceRouteCtlDescr, "00", strlen("00") + 1);
      StorageNew->traceRouteCtlDescr[strlen("00")] = '\0';
      StorageNew->traceRouteCtlDescrLen =
          strlen(StorageNew->traceRouteCtlDescr);
  
      StorageNew->traceRouteCtlMaxRows = 50;
      StorageNew->traceRouteCtlTrapGeneration = strdup("");
      StorageNew->traceRouteCtlTrapGenerationLen = 0;
      StorageNew->traceRouteCtlCreateHopsEntries = 2;
  
      StorageNew->traceRouteCtlType = calloc(1, sizeof(oid) * sizeof(2)); /* 0.0 */
      StorageNew->traceRouteCtlTypeLen = 2;
  
      StorageNew->traceRouteResults = NULL;
      StorageNew->traceRouteProbeHis = NULL;
      StorageNew->traceRouteHops = NULL;
  
      StorageNew->storageType = ST_NONVOLATILE;
      /* StorageNew->traceRouteProbeHistoryMaxIndex=0; */
      return StorageNew;
  }
  
  
  /*
   * traceRouteCtlTable_add(): adds a structure node to our data set 
   */
  int
  traceRouteCtlTable_add(struct traceRouteCtlTable_data *thedata)
  {
      netsnmp_variable_list *vars = NULL;
  
  
      DEBUGMSGTL(("traceRouteCtlTable", "adding data...  "));
      /*
       * add the index variables to the varbind list, which is 
       * used by header_complex to index the data 
       */
  
  
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen);   /* traceRouteCtlOwnerIndex */
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen);       /* traceRouteCtlOperationName */
  
      if (header_complex_add_data(&traceRouteCtlTableStorage, vars, thedata)
          == NULL) {
          vars = NULL;
          return SNMPERR_GENERR;
      } else {
  
          DEBUGMSGTL(("traceRouteCtlTable", "registered an entry\n"));
  
  
          DEBUGMSGTL(("traceRouteCtlTable", "done.\n"));
          vars = NULL;
          return SNMPERR_SUCCESS;
      }
  }
  
  int
  traceRouteResultsTable_add(struct traceRouteCtlTable_data *thedata)
  {
      netsnmp_variable_list *vars_list = NULL;
      struct traceRouteResultsTable_data *p = NULL;
      p = thedata->traceRouteResults;
      if (thedata->traceRouteResults != NULL) {
          snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) p->traceRouteCtlOwnerIndex, p->traceRouteCtlOwnerIndexLen);      /* traceRouteCtlOwnerIndex */
          snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) p->traceRouteCtlTestName, p->traceRouteCtlTestNameLen);  /* traceRouteCtlTestName */
          DEBUGMSGTL(("traceRouteResultsTable", "adding data...  "));
          /*
           * add the index variables to the varbind list, which is 
           * used by header_complex to index the data 
           */
  
          header_complex_add_data(&traceRouteResultsTableStorage, vars_list,
                                  p);
          DEBUGMSGTL(("traceRouteResultsTable", "out finished\n"));
          vars_list = NULL;
          DEBUGMSGTL(("traceRouteResultsTable", "done.\n"));
          return SNMPERR_SUCCESS;
      } else {
          vars_list = NULL;
          DEBUGMSGTL(("traceRouteResultsTable", "error.\n"));
          return SNMP_ERR_INCONSISTENTNAME;
      }
  }
  
  
  int
  traceRouteProbeHistoryTable_add(struct traceRouteProbeHistoryTable_data
                                  *thedata)
  {
      netsnmp_variable_list *vars_list = NULL;
      if (thedata != NULL) {
          snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen);  /* traceRouteCtlOwnerIndex */
          snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen);      /* traceRouteCtlTestName */
          snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &thedata->traceRouteProbeHistoryIndex, sizeof(thedata->traceRouteProbeHistoryIndex));     /* traceRouteProbeHistoryIndex */
          snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &thedata->traceRouteProbeHistoryHopIndex, sizeof(thedata->traceRouteProbeHistoryHopIndex));       /* traceRouteProbeHistoryHopIndex */
          snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &thedata->traceRouteProbeHistoryProbeIndex, sizeof(thedata->traceRouteProbeHistoryProbeIndex));   /* traceRouteProbeHistoryProbeIndex */
  
          DEBUGMSGTL(("traceRouteProbeHistoryTable", "adding data...  "));
          /*
           * add the index variables to the varbind list, which is 
           * used by header_complex to index the data 
           */
  
          if (header_complex_add_data
              (&traceRouteProbeHistoryTableStorage, vars_list,
               thedata) == NULL) {
              vars_list = NULL;
              return SNMP_ERR_INCONSISTENTNAME;
          } else {
              DEBUGMSGTL(("traceRouteProbeHistoryTable", "out finished\n"));
  
              vars_list = NULL;
  
              DEBUGMSGTL(("traceRouteProbeHistoryTable", "done.\n"));
              return SNMPERR_SUCCESS;
          }
      } else {
          return SNMP_ERR_INCONSISTENTNAME;
      }
  }
  
  int
  traceRouteProbeHistoryTable_addall(struct traceRouteCtlTable_data *thedata)
  {
      netsnmp_variable_list *vars_list = NULL;
      struct traceRouteProbeHistoryTable_data *p = NULL;
      p = thedata->traceRouteProbeHis;
      if (thedata->traceRouteProbeHis != NULL)
          do {
              snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) p->traceRouteCtlOwnerIndex, p->traceRouteCtlOwnerIndexLen);  /* traceRouteCtlOwnerIndex */
              snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) p->traceRouteCtlTestName, p->traceRouteCtlTestNameLen);      /* traceRouteCtlTestName */
              snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &p->traceRouteProbeHistoryIndex, sizeof(p->traceRouteProbeHistoryIndex));     /* traceRouteProbeHistoryIndex */
              snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &p->traceRouteProbeHistoryHopIndex, sizeof(p->traceRouteProbeHistoryHopIndex));       /* traceRouteProbeHistoryHopIndex */
              snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &p->traceRouteProbeHistoryProbeIndex, sizeof(p->traceRouteProbeHistoryProbeIndex));   /* traceRouteProbeHistoryProbeIndex */
  
              DEBUGMSGTL(("traceRouteProbeHistoryTable",
                          "adding data...  "));
              /*
               * add the index variables to the varbind list, which is 
               * used by header_complex to index the data 
               */
  
              if (header_complex_add_data
                  (&traceRouteProbeHistoryTableStorage, vars_list,
                   p) == NULL) {
                  vars_list = NULL;
                  return SNMP_ERR_INCONSISTENTNAME;
              } else {
  
                  struct header_complex_index *temp = NULL;
                  temp = traceRouteProbeHistoryTableStorage;
                  if (traceRouteProbeHistoryTableStorage != NULL)
                      do {
                          DEBUGMSGTL(("traceRouteProbeHistoryTable",
                                      "adding data,vars_oid="));
                          DEBUGMSGOID(("traceRouteProbeHistoryTable",
                                      temp->name, temp->namelen));
                          DEBUGMSGTL(("traceRouteProbeHistoryTable",
                                      "\n "));
                          temp = temp->next;
                      } while (temp != NULL);
  
                  DEBUGMSGTL(("traceRouteProbeHistoryTable",
                              "out finished\n"));
                  DEBUGMSGTL(("traceRouteProbeHistoryTable", "done.\n"));
                  vars_list = NULL;
                  return SNMPERR_SUCCESS;
              }
  
              p = p->next;
          } while (p != NULL);
      else {
          return SNMP_ERR_INCONSISTENTNAME;
      }
  
  }
  
  
  
  int
  traceRouteHopsTable_add(struct traceRouteHopsTable_data *thedata)
  {
      netsnmp_variable_list *vars_list = NULL;
  
      if (thedata != NULL) {
          snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen);  /* traceRouteCtlOwnerIndex */
          snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen);      /* traceRouteCtlTestName */
          snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &thedata->traceRouteHopsHopIndex, sizeof(thedata->traceRouteHopsHopIndex));       /* traceRouteHopsHopIndex */
  
          DEBUGMSGTL(("traceRouteHopsTable", "adding data...  "));
          /*
           * add the index variables to the varbind list, which is 
           * used by header_complex to index the data 
           */
  
          if (header_complex_add_data
              (&traceRouteHopsTableStorage, vars_list, thedata) == NULL) {
              vars_list = NULL;
              return SNMP_ERR_INCONSISTENTNAME;
          } else {
              DEBUGMSGTL(("traceRouteHopsTable", "out finished\n"));
              DEBUGMSGTL(("traceRouteHopsTable", "done.\n"));
              vars_list = NULL;
              return SNMPERR_SUCCESS;
          }
      }
      return SNMPERR_GENERR;
  }
  
  int
  traceRouteHopsTable_addall(struct traceRouteCtlTable_data *thedata)
  {
      netsnmp_variable_list *vars_list = NULL;
      struct traceRouteHopsTable_data *p = NULL;
      vars_list = NULL;
      p = thedata->traceRouteHops;
      if (thedata->traceRouteHops != NULL) {
          do {
              snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) p->traceRouteCtlOwnerIndex, p->traceRouteCtlOwnerIndexLen);  /* traceRouteCtlOwnerIndex */
              snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) p->traceRouteCtlTestName, p->traceRouteCtlTestNameLen);      /* traceRouteCtlTestName */
              snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &p->traceRouteHopsHopIndex, sizeof(p->traceRouteHopsHopIndex));       /* traceRouteHopsHopIndex */
  
              DEBUGMSGTL(("traceRouteHopsTable", "adding data...  "));
              /*
               * add the index variables to the varbind list, which is 
               * used by header_complex to index the data 
               */
  
              if (header_complex_add_data
                  (&traceRouteHopsTableStorage, vars_list, p) == NULL) {
                  vars_list = NULL;
                  return SNMP_ERR_INCONSISTENTNAME;
              } else {
  
                  struct header_complex_index *temp = NULL;
                  temp = traceRouteHopsTableStorage;
                  if (traceRouteHopsTableStorage != NULL)
                      do {
                          DEBUGMSGTL(("traceRouteProbeHistoryTable",
                                      "adding data,vars_oid="));
                          DEBUGMSGOID(("traceRouteProbeHistoryTable",
                                      temp->name, temp->namelen));
                          DEBUGMSGTL(("traceRouteProbeHistoryTable",
                                      "\n "));
                          temp = temp->next;
                      } while (temp != NULL);
                  DEBUGMSGTL(("traceRouteHopsTable", "out finished\n"));
  
                  vars_list = NULL;
              }
              p = p->next;
          } while (p != NULL);
          DEBUGMSGTL(("traceRouteHopsTable", "done.\n"));
          return SNMPERR_SUCCESS;
      } else {
          return SNMP_ERR_INCONSISTENTNAME;
      }
  
  }
  
  
  unsigned long
  traceRouteProbeHistoryTable_count(struct traceRouteCtlTable_data *thedata)
  {
      struct header_complex_index *hciptr2 = NULL;
      netsnmp_variable_list *vars = NULL;
      oid             newoid[MAX_OID_LEN];
      size_t          newoid_len;
      unsigned long   count = 0;
  
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen);   /* traceRouteCtlOwnerIndex */
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen);       /* traceRouteCtlTestName */
  
      header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars);
  
      vars = NULL;
      for (hciptr2 = traceRouteProbeHistoryTableStorage; hciptr2 != NULL;
           hciptr2 = hciptr2->next) {
          if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len)
              == 0) {
              count = count + 1;
          }
      }
      return count;
  }
  
  
  
  unsigned long
  traceRouteHopsTable_count(struct traceRouteCtlTable_data *thedata)
  {
      struct header_complex_index *hciptr2 = NULL;
      netsnmp_variable_list *vars = NULL;
      oid             newoid[MAX_OID_LEN];
      size_t          newoid_len;
      unsigned long   count = 0;
  
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen);   /* traceRouteCtlOwnerIndex */
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen);       /* traceRouteCtlOperationName */
  
      header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars);
  
      vars = NULL;
      for (hciptr2 = traceRouteHopsTableStorage; hciptr2 != NULL;
           hciptr2 = hciptr2->next) {
          if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len)
              == 0) {
              count = count + 1;
          }
      }
      return count;
  }
  
  
  
  void
  traceRouteProbeHistoryTable_delLast(struct traceRouteCtlTable_data
                                      *thedata)
  {
      struct header_complex_index *hciptr2 = NULL;
      struct header_complex_index *hcilast = NULL;
      struct traceRouteProbeHistoryTable_data *StorageTmp = NULL;
      netsnmp_variable_list *vars = NULL;
      oid             newoid[MAX_OID_LEN];
      size_t          newoid_len = 0;
      time_t          last_time = 2147483647;
      time_t          tp;
  
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen);   /* traceRouteCtlOwnerIndex */
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen);       /* traceRouteCtlOperationName */
  
      memset(newoid, '\0', sizeof(oid) * MAX_OID_LEN);
      header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars);
  
      for (hcilast = hciptr2 = traceRouteProbeHistoryTableStorage;
           hciptr2 != NULL; hciptr2 = hciptr2->next) {
          if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len)
              == 0) {
  
              StorageTmp =
                  header_complex_get_from_oid
                  (traceRouteProbeHistoryTableStorage, hciptr2->name,
                   hciptr2->namelen);
              tp = StorageTmp->traceRouteProbeHistoryTime_time;
  
              if (last_time > tp) {
                  last_time = tp;
                  hcilast = hciptr2;
              }
  
          }
      }
      header_complex_extract_entry(&traceRouteProbeHistoryTableStorage, hcilast);
      DEBUGMSGTL(("traceRouteProbeHistoryTable",
                  "delete the last one success!\n"));
      vars = NULL;
  }
  
  
  
  void
  traceRouteCtlTable_cleaner(struct header_complex_index *thestuff)
  {
      struct header_complex_index *hciptr, *nhciptr;
      struct traceRouteCtlTable_data *StorageDel;
  
      DEBUGMSGTL(("traceRouteCtlTable", "cleanerout  "));
      for (hciptr = thestuff; hciptr; hciptr = nhciptr) {
          nhciptr = hciptr->next;
          StorageDel =
              header_complex_extract_entry(&traceRouteCtlTableStorage,
                                           hciptr);
          if (StorageDel != NULL) {
              free(StorageDel->traceRouteCtlOwnerIndex);
              free(StorageDel->traceRouteCtlTestName);
              free(StorageDel->traceRouteCtlTargetAddress);
              free(StorageDel->traceRouteCtlSourceAddress);
              free(StorageDel->traceRouteCtlMiscOptions);
              free(StorageDel->traceRouteCtlDescr);
              free(StorageDel->traceRouteCtlTrapGeneration);
              free(StorageDel->traceRouteCtlType);
              free(StorageDel);
          }
          DEBUGMSGTL(("traceRouteCtlTable", "cleaner  "));
      }
  }
  
  
  /*
   * parse_mteObjectsTable():
   *   parses .conf file entries needed to configure the mib.
   */
  void
  parse_traceRouteCtlTable(const char *token, char *line)
  {
      size_t          tmpint;
      struct traceRouteCtlTable_data *StorageTmp =
          SNMP_MALLOC_STRUCT(traceRouteCtlTable_data);
  
      DEBUGMSGTL(("traceRouteCtlTable", "parsing config...  "));
  
  
      if (StorageTmp == NULL) {
          config_perror("malloc failure");
          return;
      }
  
  
      line =
          read_config_read_data(ASN_OCTET_STR, line,
                                &StorageTmp->traceRouteCtlOwnerIndex,
                                &StorageTmp->traceRouteCtlOwnerIndexLen);
      if (StorageTmp->traceRouteCtlOwnerIndex == NULL) {
          config_perror("invalid specification for traceRouteCtlOwnerIndex");
          free(StorageTmp);
          return;
      }
  
      line =
          read_config_read_data(ASN_OCTET_STR, line,
                                &StorageTmp->traceRouteCtlTestName,
                                &StorageTmp->traceRouteCtlTestNameLen);
      if (StorageTmp->traceRouteCtlTestName == NULL) {
          config_perror("invalid specification for traceRouteCtlTestName");
          free(StorageTmp);
          return;
      }
  
      line =
          read_config_read_data(ASN_INTEGER, line,
                                &StorageTmp->traceRouteCtlTargetAddressType,
                                &tmpint);
  
      line =
          read_config_read_data(ASN_OCTET_STR, line,
                                &StorageTmp->traceRouteCtlTargetAddress,
                                &StorageTmp->traceRouteCtlTargetAddressLen);
      if (StorageTmp->traceRouteCtlTargetAddress == NULL) {
          config_perror
              ("invalid specification for traceRouteCtlTargetAddress");
          free(StorageTmp);
          return;
      }
  
      line =
          read_config_read_data(ASN_INTEGER, line,
                                &StorageTmp->traceRouteCtlByPassRouteTable,
                                &tmpint);
      line =
          read_config_read_data(ASN_UNSIGNED, line,
                                &StorageTmp->traceRouteCtlDataSize, &tmpint);
  
      line =
          read_config_read_data(ASN_UNSIGNED, line,
                                &StorageTmp->traceRouteCtlTimeOut, &tmpint);
  
      line =
          read_config_read_data(ASN_UNSIGNED, line,
                                &StorageTmp->traceRouteCtlProbesPerHop,
                                &tmpint);
  
      line =
          read_config_read_data(ASN_UNSIGNED, line,
                                &StorageTmp->traceRouteCtlPort, &tmpint);
  
      line =
          read_config_read_data(ASN_UNSIGNED, line,
                                &StorageTmp->traceRouteCtlMaxTtl, &tmpint);
  
      line =
          read_config_read_data(ASN_UNSIGNED, line,
                                &StorageTmp->traceRouteCtlDSField, &tmpint);
  
      line =
          read_config_read_data(ASN_INTEGER, line,
                                &StorageTmp->traceRouteCtlSourceAddressType,
                                &tmpint);
  
      line =
          read_config_read_data(ASN_OCTET_STR, line,
                                &StorageTmp->traceRouteCtlSourceAddress,
                                &StorageTmp->traceRouteCtlSourceAddressLen);
      if (StorageTmp->traceRouteCtlSourceAddress == NULL) {
          config_perror
              ("invalid specification for traceRouteCtlSourceAddress");
          free(StorageTmp);
          return;
      }
  
      line =
          read_config_read_data(ASN_INTEGER, line,
                                &StorageTmp->traceRouteCtlIfIndex, &tmpint);
  
      line =
          read_config_read_data(ASN_OCTET_STR, line,
                                &StorageTmp->traceRouteCtlMiscOptions,
                                &StorageTmp->traceRouteCtlMiscOptionsLen);
      if (StorageTmp->traceRouteCtlMiscOptions == NULL) {
          config_perror
              ("invalid specification for traceRouteCtlMiscOptions");
          free(StorageTmp);
          return;
      }
  
      line =
          read_config_read_data(ASN_UNSIGNED, line,
                                &StorageTmp->traceRouteCtlMaxFailures,
                                &tmpint);
  
      line =
          read_config_read_data(ASN_INTEGER, line,
                                &StorageTmp->traceRouteCtlDontFragment,
                                &tmpint);
  
      line =
          read_config_read_data(ASN_UNSIGNED, line,
                                &StorageTmp->traceRouteCtlInitialTtl,
                                &tmpint);
  
      line =
          read_config_read_data(ASN_UNSIGNED, line,
                                &StorageTmp->traceRouteCtlFrequency,
                                &tmpint);
  
      line =
          read_config_read_data(ASN_INTEGER, line,
                                &StorageTmp->traceRouteCtlStorageType,
                                &tmpint);
  
      line =
          read_config_read_data(ASN_INTEGER, line,
                                &StorageTmp->traceRouteCtlAdminStatus,
                                &tmpint);
  
      line =
          read_config_read_data(ASN_OCTET_STR, line,
                                &StorageTmp->traceRouteCtlDescr,
                                &StorageTmp->traceRouteCtlDescrLen);
      if (StorageTmp->traceRouteCtlDescr == NULL) {
          config_perror("invalid specification for traceRouteCtlTrapDescr");
          free(StorageTmp);
          return;
      }
  
      line =
          read_config_read_data(ASN_UNSIGNED, line,
                                &StorageTmp->traceRouteCtlMaxRows, &tmpint);
  
      line =
          read_config_read_data(ASN_OCTET_STR, line,
                                &StorageTmp->traceRouteCtlTrapGeneration,
                                &StorageTmp->traceRouteCtlTrapGenerationLen);
      if (StorageTmp->traceRouteCtlTrapGeneration == NULL) {
          config_perror
              ("invalid specification for traceRouteCtlTrapGeneration");
          free(StorageTmp);
          return;
      }
  
      line =
          read_config_read_data(ASN_INTEGER, line,
                                &StorageTmp->traceRouteCtlCreateHopsEntries,
                                &tmpint);
  
      line =
          read_config_read_data(ASN_OBJECT_ID, line,
                                &StorageTmp->traceRouteCtlType,
                                &StorageTmp->traceRouteCtlTypeLen);
      if (StorageTmp->traceRouteCtlType == NULL) {
          config_perror("invalid specification for traceRouteCtlType");
          free(StorageTmp);
          return;
      }
  
      line =
          read_config_read_data(ASN_INTEGER, line,
                                &StorageTmp->traceRouteCtlRowStatus,
                                &tmpint);
  
      line =
          read_config_read_data(ASN_UNSIGNED, line,
                                &StorageTmp->traceRouteProbeHistoryMaxIndex,
                                &tmpint);
  
      StorageTmp->storageType = ST_NONVOLATILE;
      traceRouteCtlTable_add(StorageTmp);
      /*     traceRouteCtlTable_cleaner(traceRouteCtlTableStorage); */
  
      DEBUGMSGTL(("traceRouteCtlTable", "done.\n"));
  }
  
  
  
  /*
   * store_traceRouteCtlTable():
   *   stores .conf file entries needed to configure the mib.
   */
  int
  store_traceRouteCtlTable(int majorID, int minorID, void *serverarg,
                           void *clientarg)
  {
      char            line[SNMP_MAXBUF];
      char           *cptr = NULL;
      size_t          tmpint;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      struct header_complex_index *hcindex = NULL;
  
  
      DEBUGMSGTL(("traceRouteCtlTable", "storing data...  "));
  
  
      for (hcindex = traceRouteCtlTableStorage; hcindex != NULL;
           hcindex = hcindex->next) {
          StorageTmp = (struct traceRouteCtlTable_data *) hcindex->data;
  
          if (StorageTmp->storageType != ST_READONLY) {
              memset(line, 0, sizeof(line));
              strcat(line, "traceRouteCtlTable ");
              cptr = line + strlen(line);
  
              cptr =
                  read_config_store_data(ASN_OCTET_STR, cptr,
                                         &StorageTmp->
                                         traceRouteCtlOwnerIndex,
                                         &StorageTmp->
                                         traceRouteCtlOwnerIndexLen);
              cptr =
                  read_config_store_data(ASN_OCTET_STR, cptr,
                                         &StorageTmp->traceRouteCtlTestName,
                                         &StorageTmp->
                                         traceRouteCtlTestNameLen);
              cptr =
                  read_config_store_data(ASN_INTEGER, cptr,
                                         &StorageTmp->
                                         traceRouteCtlTargetAddressType,
                                         &tmpint);
              cptr =
                  read_config_store_data(ASN_OCTET_STR, cptr,
                                         &StorageTmp->
                                         traceRouteCtlTargetAddress,
                                         &StorageTmp->
                                         traceRouteCtlTargetAddressLen);
              cptr =
                  read_config_store_data(ASN_INTEGER, cptr,
                                         &StorageTmp->
                                         traceRouteCtlByPassRouteTable,
                                         &tmpint);
              cptr =
                  read_config_store_data(ASN_UNSIGNED, cptr,
                                         &StorageTmp->traceRouteCtlDataSize,
                                         &tmpint);
              cptr =
                  read_config_store_data(ASN_UNSIGNED, cptr,
                                         &StorageTmp->traceRouteCtlTimeOut,
                                         &tmpint);
              cptr =
                  read_config_store_data(ASN_UNSIGNED, cptr,
                                         &StorageTmp->
                                         traceRouteCtlProbesPerHop, &tmpint);
              cptr =
                  read_config_store_data(ASN_UNSIGNED, cptr,
                                         &StorageTmp->traceRouteCtlPort,
                                         &tmpint);
              cptr =
                  read_config_store_data(ASN_UNSIGNED, cptr,
                                         &StorageTmp->traceRouteCtlMaxTtl,
                                         &tmpint);
              cptr =
                  read_config_store_data(ASN_UNSIGNED, cptr,
                                         &StorageTmp->traceRouteCtlDSField,
                                         &tmpint);
  
              cptr =
                  read_config_store_data(ASN_INTEGER, cptr,
                                         &StorageTmp->
                                         traceRouteCtlSourceAddressType,
                                         &tmpint);
              cptr =
                  read_config_store_data(ASN_OCTET_STR, cptr,
                                         &StorageTmp->
                                         traceRouteCtlSourceAddress,
                                         &StorageTmp->
                                         traceRouteCtlSourceAddressLen);
              cptr =
                  read_config_store_data(ASN_INTEGER, cptr,
                                         &StorageTmp->traceRouteCtlIfIndex,
                                         &tmpint);
              cptr =
                  read_config_store_data(ASN_OCTET_STR, cptr,
                                         &StorageTmp->
                                         traceRouteCtlMiscOptions,
                                         &StorageTmp->
                                         traceRouteCtlMiscOptionsLen);
              cptr =
                  read_config_store_data(ASN_UNSIGNED, cptr,
                                         &StorageTmp->
                                         traceRouteCtlMaxFailures, &tmpint);
              cptr =
                  read_config_store_data(ASN_INTEGER, cptr,
                                         &StorageTmp->
                                         traceRouteCtlDontFragment, &tmpint);
              cptr =
                  read_config_store_data(ASN_UNSIGNED, cptr,
                                         &StorageTmp->
                                         traceRouteCtlInitialTtl, &tmpint);
              cptr =
                  read_config_store_data(ASN_UNSIGNED, cptr,
                                         &StorageTmp->traceRouteCtlFrequency,
                                         &tmpint);
  
              cptr =
                  read_config_store_data(ASN_INTEGER, cptr,
                                         &StorageTmp->
                                         traceRouteCtlStorageType, &tmpint);
              cptr =
                  read_config_store_data(ASN_INTEGER, cptr,
                                         &StorageTmp->
                                         traceRouteCtlAdminStatus, &tmpint);
              cptr =
                  read_config_store_data(ASN_OCTET_STR, cptr,
                                         &StorageTmp->traceRouteCtlDescr,
                                         &StorageTmp->traceRouteCtlDescrLen);
              cptr =
                  read_config_store_data(ASN_UNSIGNED, cptr,
                                         &StorageTmp->traceRouteCtlMaxRows,
                                         &tmpint);
              cptr =
                  read_config_store_data(ASN_OCTET_STR, cptr,
                                         &StorageTmp->
                                         traceRouteCtlTrapGeneration,
                                         &StorageTmp->
                                         traceRouteCtlTrapGenerationLen);
              cptr =
                  read_config_store_data(ASN_INTEGER, cptr,
                                         &StorageTmp->
                                         traceRouteCtlCreateHopsEntries,
                                         &tmpint);
              cptr =
                  read_config_store_data(ASN_OBJECT_ID, cptr,
                                         &StorageTmp->traceRouteCtlType,
                                         &StorageTmp->traceRouteCtlTypeLen);
              cptr =
                  read_config_store_data(ASN_INTEGER, cptr,
                                         &StorageTmp->traceRouteCtlRowStatus,
                                         &tmpint);
              cptr =
                  read_config_store_data(ASN_UNSIGNED, cptr,
                                         &StorageTmp->
                                         traceRouteProbeHistoryMaxIndex,
                                         &tmpint);
  
  
  
              snmpd_store_config(line);
          }
      }
      DEBUGMSGTL(("traceRouteCtlTable", "done.\n"));
      return SNMPERR_SUCCESS;
  }
  
  
  
  
  /*
   * var_traceRouteCtlTable():
   *   Handle this table separately from the scalar value case.
   *   The workings of this are basically the same as for var_mteObjectsTable above.
   */
  unsigned char  *
  var_traceRouteCtlTable(struct variable *vp,
                         oid * name,
                         size_t *length,
                         int exact,
                         size_t *var_len, WriteMethod ** write_method)
  {
  
      struct traceRouteCtlTable_data *StorageTmp = NULL;
  
      /*
       * this assumes you have registered all your data properly
       */
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, vp, name, length, exact,
                          var_len, write_method)) == NULL) {
          if (vp->magic == COLUMN_TRACEROUTECTLROWSTATUS)
              *write_method = write_traceRouteCtlRowStatus;
  
          return NULL;
      }
  
      /*
       * this is where we do the value assignments for the mib results.
       */
      switch (vp->magic) {
  
  
      case COLUMN_TRACEROUTECTLTARGETADDRESSTYPE:
          *write_method = write_traceRouteCtlTargetAddressType;
          *var_len = sizeof(StorageTmp->traceRouteCtlTargetAddressType);
  
          return (u_char *) & StorageTmp->traceRouteCtlTargetAddressType;
  
      case COLUMN_TRACEROUTECTLTARGETADDRESS:
          *write_method = write_traceRouteCtlTargetAddress;
          *var_len = (StorageTmp->traceRouteCtlTargetAddressLen);
  
          return (u_char *) StorageTmp->traceRouteCtlTargetAddress;
  
      case COLUMN_TRACEROUTECTLBYPASSROUTETABLE:
          *write_method = write_traceRouteCtlByPassRouteTable;
          *var_len = sizeof(StorageTmp->traceRouteCtlByPassRouteTable);
  
          return (u_char *) & StorageTmp->traceRouteCtlByPassRouteTable;
  
      case COLUMN_TRACEROUTECTLDATASIZE:
          *write_method = write_traceRouteCtlDataSize;
          *var_len = sizeof(StorageTmp->traceRouteCtlDataSize);
  
          return (u_char *) & StorageTmp->traceRouteCtlDataSize;
  
      case COLUMN_TRACEROUTECTLTIMEOUT:
          *write_method = write_traceRouteCtlTimeOut;
          *var_len = sizeof(StorageTmp->traceRouteCtlTimeOut);
  
          return (u_char *) & StorageTmp->traceRouteCtlTimeOut;
  
      case COLUMN_TRACEROUTECTLPROBESPERHOP:
          *write_method = write_traceRouteCtlProbesPerHop;
          *var_len = sizeof(StorageTmp->traceRouteCtlProbesPerHop);
  
          return (u_char *) & StorageTmp->traceRouteCtlProbesPerHop;
  
      case COLUMN_TRACEROUTECTLPORT:
          *write_method = write_traceRouteCtlPort;
          *var_len = sizeof(StorageTmp->traceRouteCtlPort);
  
          return (u_char *) & StorageTmp->traceRouteCtlPort;
  
      case COLUMN_TRACEROUTECTLMAXTTL:
          *write_method = write_traceRouteCtlMaxTtl;
          *var_len = sizeof(StorageTmp->traceRouteCtlMaxTtl);
  
          return (u_char *) & StorageTmp->traceRouteCtlMaxTtl;
  
      case COLUMN_TRACEROUTECTLDSFIELD:
          *write_method = write_traceRouteCtlDSField;
          *var_len = sizeof(StorageTmp->traceRouteCtlDSField);
  
          return (u_char *) & StorageTmp->traceRouteCtlDSField;
  
      case COLUMN_TRACEROUTECTLSOURCEADDRESSTYPE:
          *write_method = write_traceRouteCtlSourceAddressType;
          *var_len = sizeof(StorageTmp->traceRouteCtlSourceAddressType);
  
          return (u_char *) & StorageTmp->traceRouteCtlSourceAddressType;
  
      case COLUMN_TRACEROUTECTLSOURCEADDRESS:
          *write_method = write_traceRouteCtlSourceAddress;
          *var_len = (StorageTmp->traceRouteCtlSourceAddressLen);
  
          return (u_char *) StorageTmp->traceRouteCtlSourceAddress;
  
      case COLUMN_TRACEROUTECTLIFINDEX:
          *write_method = write_traceRouteCtlIfIndex;
          *var_len = sizeof(StorageTmp->traceRouteCtlIfIndex);
  
          return (u_char *) & StorageTmp->traceRouteCtlIfIndex;
  
      case COLUMN_TRACEROUTECTLMISCOPTIONS:
          *write_method = write_traceRouteCtlMiscOptions;
          *var_len = (StorageTmp->traceRouteCtlMiscOptionsLen);
  
          return (u_char *) StorageTmp->traceRouteCtlMiscOptions;
  
      case COLUMN_TRACEROUTECTLMAXFAILURES:
          *write_method = write_traceRouteCtlMaxFailures;
          *var_len = sizeof(StorageTmp->traceRouteCtlMaxFailures);
  
          return (u_char *) & StorageTmp->traceRouteCtlMaxFailures;
  
      case COLUMN_TRACEROUTECTLDONTFRAGMENT:
          *write_method = write_traceRouteCtlDontFragment;
          *var_len = sizeof(StorageTmp->traceRouteCtlDontFragment);
  
          return (u_char *) & StorageTmp->traceRouteCtlDontFragment;
  
      case COLUMN_TRACEROUTECTLINITIALTTL:
          *write_method = write_traceRouteCtlInitialTtl;
          *var_len = sizeof(StorageTmp->traceRouteCtlInitialTtl);
  
          return (u_char *) & StorageTmp->traceRouteCtlInitialTtl;
  
      case COLUMN_TRACEROUTECTLFREQUENCY:
          *write_method = write_traceRouteCtlFrequency;
          *var_len = sizeof(StorageTmp->traceRouteCtlFrequency);
  
          return (u_char *) & StorageTmp->traceRouteCtlFrequency;
  
      case COLUMN_TRACEROUTECTLSTORAGETYPE:
          *write_method = write_traceRouteCtlStorageType;
          *var_len = sizeof(StorageTmp->traceRouteCtlStorageType);
  
          return (u_char *) & StorageTmp->traceRouteCtlStorageType;
  
      case COLUMN_TRACEROUTECTLADMINSTATUS:
          *write_method = write_traceRouteCtlAdminStatus;
          *var_len = sizeof(StorageTmp->traceRouteCtlAdminStatus);
  
          return (u_char *) & StorageTmp->traceRouteCtlAdminStatus;
  
      case COLUMN_TRACEROUTECTLDESCR:
          *write_method = write_traceRouteCtlDescr;
          *var_len = (StorageTmp->traceRouteCtlDescrLen);
  
          return (u_char *) StorageTmp->traceRouteCtlDescr;
  
      case COLUMN_TRACEROUTECTLMAXROWS:
          *write_method = write_traceRouteCtlMaxRows;
          *var_len = sizeof(StorageTmp->traceRouteCtlMaxRows);
  
          return (u_char *) & StorageTmp->traceRouteCtlMaxRows;
  
      case COLUMN_TRACEROUTECTLTRAPGENERATION:
          *write_method = write_traceRouteCtlTrapGeneration;
          *var_len = (StorageTmp->traceRouteCtlTrapGenerationLen);
  
          return (u_char *) StorageTmp->traceRouteCtlTrapGeneration;
  
      case COLUMN_TRACEROUTECTLCREATEHOPSENTRIES:
          *write_method = write_traceRouteCtlCreateHopsEntries;
          *var_len = sizeof(StorageTmp->traceRouteCtlCreateHopsEntries);
  
          return (u_char *) & StorageTmp->traceRouteCtlCreateHopsEntries;
  
      case COLUMN_TRACEROUTECTLTYPE:
          *write_method = write_traceRouteCtlType;
          *var_len = (StorageTmp->traceRouteCtlTypeLen) * sizeof(oid);
  
          return (u_char *) StorageTmp->traceRouteCtlType;
  
      case COLUMN_TRACEROUTECTLROWSTATUS:
          *write_method = write_traceRouteCtlRowStatus;
          *var_len = sizeof(StorageTmp->traceRouteCtlRowStatus);
  
          return (u_char *) & StorageTmp->traceRouteCtlRowStatus;
  
      default:
          ERROR_MSG("");
      }
      return NULL;
  }
  
  
  
  int
  traceRouteResultsTable_del(struct traceRouteCtlTable_data *thedata)
  {
      struct header_complex_index *hciptr2, *nhciptr2;
      netsnmp_variable_list *vars = NULL;
      oid             newoid[MAX_OID_LEN];
      size_t          newoid_len = 0;
  
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen);   /* traceRouteCtlOwnerIndex */
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen);       /* traceRouteCtlTestName */
  
      memset(newoid, '\0', sizeof(oid) * MAX_OID_LEN);
      header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars);
  
      for (hciptr2 = traceRouteResultsTableStorage; hciptr2; hciptr2 = nhciptr2) {
          nhciptr2 = hciptr2->next;
          if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len)
              == 0) {
              header_complex_extract_entry(&traceRouteResultsTableStorage,
                                           hciptr2);
              DEBUGMSGTL(("traceRouteResultsTable", "delete  success!\n"));
  
          }
      }
      vars = NULL;
      return SNMPERR_SUCCESS;
  }
  
  
  
  
  int
  traceRouteProbeHistoryTable_del(struct traceRouteCtlTable_data *thedata)
  {
      struct header_complex_index *hciptr2, *nhciptr2;
      netsnmp_variable_list *vars = NULL;
      oid             newoid[MAX_OID_LEN];
      size_t          newoid_len = 0;
  
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen);   /* traceRouteCtlOwnerIndex */
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen);       /* traceRouteCtlOperationName */
  
      memset(newoid, '\0', sizeof(oid) * MAX_OID_LEN);
  
      header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars);
  
      for (hciptr2 = traceRouteProbeHistoryTableStorage; hciptr2;
           hciptr2 = nhciptr2) {
          nhciptr2 = hciptr2->next;
          if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len)
              == 0) {
              header_complex_extract_entry(&traceRouteProbeHistoryTableStorage,
                                           hciptr2);
              DEBUGMSGTL(("traceRouteProbeHistoryTable",
                          "delete  success!\n"));
  
          }
      }
      vars = NULL;
      return SNMPERR_SUCCESS;
  }
  
  
  int
  traceRouteHopsTable_del(struct traceRouteCtlTable_data *thedata)
  {
      struct header_complex_index *hciptr2, *nhciptr2;
      netsnmp_variable_list *vars = NULL;
      oid             newoid[MAX_OID_LEN];
      size_t          newoid_len = 0;
  
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen);   /* traceRouteCtlOwnerIndex */
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen);       /* traceRouteCtlTestName */
  
      memset(newoid, '\0', sizeof(oid) * MAX_OID_LEN);
  
      header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars);
  
      for (hciptr2 = traceRouteHopsTableStorage; hciptr2; hciptr2 = nhciptr2) {
          nhciptr2 = hciptr2->next;
          if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len)
              == 0) {
              header_complex_extract_entry(&traceRouteHopsTableStorage, hciptr2);
              DEBUGMSGTL(("traceRouteHopsTable", "delete  success!\n"));
          }
      }
      vars = NULL;
      return SNMPERR_SUCCESS;
  }
  
  /*
   * send trap 
   */
  
  void
  send_traceRoute_trap(struct traceRouteCtlTable_data *item,
                       oid * trap_oid, size_t trap_oid_len)
  {
      static oid      objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };     /* snmpTrapIOD.0 */
      struct traceRouteHopsTable_data *StorageHops = NULL;
      netsnmp_variable_list *var_list = NULL;
      netsnmp_variable_list *vars = NULL;
      netsnmp_variable_list *var_hops = NULL;
      oid             newoid[MAX_OID_LEN];
      size_t          newoid_len = 0;
  
      oid             indexoid[MAX_OID_LEN];
      size_t          indexoid_len = 0;
  
      struct header_complex_index *hciptr;
      oid             tempoid[MAX_OID_LEN];
      size_t          tempoid_len = 0;
  
      oid             traceRouteCtlTargetAddress[] =
          { 1, 3, 6, 1, 2, 1, 81, 1, 2, 1, 4 };
      oid             traceRouteHopsIpTgAddress[] =
          { 1, 3, 6, 1, 2, 1, 81, 1, 5, 1, 3 };
  
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */
      snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen);     /* traceRouteCtlTestName */
  
      /*
       * snmpTrap oid 
       */
      snmp_varlist_add_variable(&var_list, objid_snmptrap,
                                OID_LENGTH(objid_snmptrap),
                                ASN_OBJECT_ID, (u_char *) trap_oid,
                                trap_oid_len * sizeof(oid));
  
      /*
       * traceRouteCtlTargetAddress 
       */
      memset(newoid, '\0', MAX_OID_LEN * sizeof(oid));
      header_complex_generate_oid(newoid, &newoid_len,
                                  traceRouteCtlTargetAddress,
                                  sizeof(traceRouteCtlTargetAddress) /
                                  sizeof(oid), vars);
  
      snmp_varlist_add_variable(&var_list, newoid,
                                newoid_len,
                                ASN_OCTET_STR,
                                (u_char *) item->traceRouteCtlTargetAddress,
                                item->traceRouteCtlTargetAddressLen);
  
      for (hciptr = traceRouteHopsTableStorage; hciptr != NULL;
           hciptr = hciptr->next) {
  	memset(indexoid, '\0', MAX_OID_LEN * sizeof(oid));
          header_complex_generate_oid(indexoid, &indexoid_len, NULL, 0,
                                      vars);
          if (snmp_oid_compare
              (indexoid, indexoid_len, hciptr->name, indexoid_len) == 0) {
              StorageHops =
                  (struct traceRouteHopsTable_data *)
                  header_complex_get_from_oid(traceRouteHopsTableStorage,
                                              hciptr->name, hciptr->namelen);
              memset(tempoid, '\0', MAX_OID_LEN * sizeof(oid));
              header_complex_generate_oid(tempoid, &tempoid_len,
                                          traceRouteHopsIpTgAddress,
                                          sizeof(traceRouteHopsIpTgAddress) /
                                          sizeof(oid), vars);
              snmp_varlist_add_variable(&var_hops, NULL, 0, ASN_UNSIGNED, (char *) &StorageHops->traceRouteHopsHopIndex, sizeof(StorageHops->traceRouteHopsHopIndex));    /* traceRouteCtlTestName */
              memset(newoid, '\0', MAX_OID_LEN * sizeof(oid));
              header_complex_generate_oid(newoid, &newoid_len, tempoid,
                                          tempoid_len, var_hops);
              snmp_varlist_add_variable(&var_list, newoid, newoid_len,
                                        ASN_OCTET_STR,
                                        (u_char *) StorageHops->
                                        traceRouteHopsIpTgtAddress,
                                        StorageHops->
                                        traceRouteHopsIpTgtAddressLen);
  
              var_hops = NULL;
          }
      }
  
      /*
       * XXX: stuff based on event table 
       */
  
      DEBUGMSG(("pingTest:send_traceRoute_trap", "success!\n"));
  
      send_v2trap(var_list);
      snmp_free_varbind(vars);
      vars = NULL;
      snmp_free_varbind(var_list);
      var_list = NULL;
  }
  
  
  int
  write_traceRouteCtlTargetAddressType(int action,
                                       u_char * var_val,
                                       u_char var_val_type,
                                       size_t var_val_len,
                                       u_char * statP, oid * name,
                                       size_t name_len)
  {
      static size_t   tmpvar;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_INTEGER) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlTargetAddressType not ASN_INTEGER\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in objid for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlTargetAddressType;
          StorageTmp->traceRouteCtlTargetAddressType = *((long *) var_val);
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          StorageTmp->traceRouteCtlTargetAddressType = tmpvar;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  
  
  int
  write_traceRouteCtlTargetAddress(int action,
                                   u_char * var_val,
                                   u_char var_val_type,
                                   size_t var_val_len,
                                   u_char * statP, oid * name,
                                   size_t name_len)
  {
      static char    *tmpvar;
      static size_t   tmplen;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_OCTET_STR) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlTargetAddress not ASN_OCTET_STR\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in long_ret for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlTargetAddress;
          tmplen = StorageTmp->traceRouteCtlTargetAddressLen;
  
          StorageTmp->traceRouteCtlTargetAddress =
              (char *) malloc(var_val_len + 1);
          if (StorageTmp->traceRouteCtlTargetAddress == NULL) {
              exit(1);
          }
          memcpy(StorageTmp->traceRouteCtlTargetAddress, var_val,
                 var_val_len);
          StorageTmp->traceRouteCtlTargetAddress[var_val_len] = '\0';
          StorageTmp->traceRouteCtlTargetAddressLen = var_val_len;
  
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          SNMP_FREE(StorageTmp->traceRouteCtlTargetAddress);
          StorageTmp->traceRouteCtlTargetAddress = tmpvar;
          StorageTmp->traceRouteCtlTargetAddressLen = tmplen;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          SNMP_FREE(tmpvar);
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  int
  write_traceRouteCtlByPassRouteTable(int action,
                                      u_char * var_val,
                                      u_char var_val_type,
                                      size_t var_val_len,
                                      u_char * statP, oid * name,
                                      size_t name_len)
  {
      static size_t   tmpvar;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_INTEGER) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlTargetAddressType not ASN_INTEGER\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in objid for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlByPassRouteTable;
          StorageTmp->traceRouteCtlByPassRouteTable = *((long *) var_val);
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          StorageTmp->traceRouteCtlByPassRouteTable = tmpvar;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  
  }
  
  int
  write_traceRouteCtlDataSize(int action,
                              u_char * var_val,
                              u_char var_val_type,
                              size_t var_val_len,
                              u_char * statP, oid * name, size_t name_len)
  {
      static size_t   tmpvar;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_UNSIGNED) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlDataSize not ASN_UNSIGNED\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in objid for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlDataSize;
          if ((*((long *) var_val)) >= 0 && (*((long *) var_val)) <= 65507)
              StorageTmp->traceRouteCtlDataSize = *((long *) var_val);
          else
              StorageTmp->traceRouteCtlDataSize = 56;
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          StorageTmp->traceRouteCtlDataSize = tmpvar;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  
  
  
  int
  write_traceRouteCtlTimeOut(int action,
                             u_char * var_val,
                             u_char var_val_type,
                             size_t var_val_len,
                             u_char * statP, oid * name, size_t name_len)
  {
      static size_t   tmpvar;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_UNSIGNED) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlDataSize not ASN_UNSIGNED\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in objid for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlTimeOut;
  
          if ((*((long *) var_val)) >= 1 && (*((long *) var_val)) <= 60)
              StorageTmp->traceRouteCtlTimeOut = *((long *) var_val);
          else
              StorageTmp->traceRouteCtlTimeOut = 3;
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          StorageTmp->traceRouteCtlTimeOut = tmpvar;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  
  
  
  
  int
  write_traceRouteCtlProbesPerHop(int action,
                                  u_char * var_val,
                                  u_char var_val_type,
                                  size_t var_val_len,
                                  u_char * statP, oid * name,
                                  size_t name_len)
  {
      static size_t   tmpvar;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_UNSIGNED) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlDataSize not ASN_UNSIGNED\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in objid for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlProbesPerHop;
  
          if ((*((long *) var_val)) >= 1 && (*((long *) var_val)) <= 10)
              StorageTmp->traceRouteCtlProbesPerHop = *((long *) var_val);
          else
              StorageTmp->traceRouteCtlProbesPerHop = 3;
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          StorageTmp->traceRouteCtlProbesPerHop = tmpvar;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  
  
  int
  write_traceRouteCtlPort(int action,
                          u_char * var_val,
                          u_char var_val_type,
                          size_t var_val_len,
                          u_char * statP, oid * name, size_t name_len)
  {
      static size_t   tmpvar;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_UNSIGNED) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlTargetAddressType not ASN_UNSIGNED\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in objid for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlPort;
          StorageTmp->traceRouteCtlPort = *((long *) var_val);
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          StorageTmp->traceRouteCtlPort = tmpvar;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  
  
  
  int
  write_traceRouteCtlMaxTtl(int action,
                            u_char * var_val,
                            u_char var_val_type,
                            size_t var_val_len,
                            u_char * statP, oid * name, size_t name_len)
  {
      static size_t   tmpvar;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_UNSIGNED) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlDataSize not ASN_UNSIGNED\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in objid for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlMaxTtl;
          if ((*((long *) var_val)) >= 1 && (*((long *) var_val)) <= 255)
              StorageTmp->traceRouteCtlMaxTtl = *((long *) var_val);
          else
              StorageTmp->traceRouteCtlMaxTtl = 30;
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          StorageTmp->traceRouteCtlMaxTtl = tmpvar;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  
  int
  write_traceRouteCtlDSField(int action,
                             u_char * var_val,
                             u_char var_val_type,
                             size_t var_val_len,
                             u_char * statP, oid * name, size_t name_len)
  {
      static size_t   tmpvar;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_UNSIGNED) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlDataSize not ASN_UNSIGNED\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in objid for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlDSField;
          StorageTmp->traceRouteCtlDSField = *((long *) var_val);
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          StorageTmp->traceRouteCtlDSField = tmpvar;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  int
  write_traceRouteCtlSourceAddressType(int action,
                                       u_char * var_val,
                                       u_char var_val_type,
                                       size_t var_val_len,
                                       u_char * statP, oid * name,
                                       size_t name_len)
  {
      static size_t   tmpvar;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_INTEGER) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlMaxRows not ASN_INTEGER\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in objid for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlSourceAddressType;
          StorageTmp->traceRouteCtlSourceAddressType = *((long *) var_val);
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          StorageTmp->traceRouteCtlSourceAddressType = tmpvar;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  int
  write_traceRouteCtlSourceAddress(int action,
                                   u_char * var_val,
                                   u_char var_val_type,
                                   size_t var_val_len,
                                   u_char * statP, oid * name,
                                   size_t name_len)
  {
      static char    *tmpvar;
      static size_t   tmplen;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_OCTET_STR) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlTargetAddress not ASN_OCTET_STR\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in long_ret for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlSourceAddress;
          tmplen = StorageTmp->traceRouteCtlSourceAddressLen;
          StorageTmp->traceRouteCtlSourceAddress =
              (char *) malloc(var_val_len + 1);
          if (StorageTmp->traceRouteCtlSourceAddress == NULL) {
              exit(1);
          }
          memcpy(StorageTmp->traceRouteCtlSourceAddress, var_val,
                 var_val_len + 1);
          StorageTmp->traceRouteCtlSourceAddress[var_val_len] = '\0';
          StorageTmp->traceRouteCtlSourceAddressLen = var_val_len;
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          SNMP_FREE(StorageTmp->traceRouteCtlSourceAddress);
          StorageTmp->traceRouteCtlSourceAddress = tmpvar;
          StorageTmp->traceRouteCtlSourceAddressLen = tmplen;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          SNMP_FREE(tmpvar);
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  
  
  
  int
  write_traceRouteCtlIfIndex(int action,
                             u_char * var_val,
                             u_char var_val_type,
                             size_t var_val_len,
                             u_char * statP, oid * name, size_t name_len)
  {
      static size_t   tmpvar;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_INTEGER) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlMaxRows not ASN_INTEGER\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in objid for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlIfIndex;
          StorageTmp->traceRouteCtlIfIndex = *((long *) var_val);
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          StorageTmp->traceRouteCtlIfIndex = tmpvar;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  
  
  int
  write_traceRouteCtlMiscOptions(int action,
                                 u_char * var_val,
                                 u_char var_val_type,
                                 size_t var_val_len,
                                 u_char * statP, oid * name, size_t name_len)
  {
      static char    *tmpvar;
      static size_t   tmplen;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_OCTET_STR) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlTargetAddress not ASN_OCTET_STR\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in long_ret for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlMiscOptions;
          tmplen = StorageTmp->traceRouteCtlMiscOptionsLen;
          StorageTmp->traceRouteCtlMiscOptions =
              (char *) malloc(var_val_len + 1);
          if (StorageTmp->traceRouteCtlMiscOptions == NULL) {
              exit(1);
          }
          memcpy(StorageTmp->traceRouteCtlMiscOptions, var_val,
                 var_val_len + 1);
          StorageTmp->traceRouteCtlMiscOptions[var_val_len] = '\0';
          StorageTmp->traceRouteCtlMiscOptionsLen = var_val_len;
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          SNMP_FREE(StorageTmp->traceRouteCtlMiscOptions);
          StorageTmp->traceRouteCtlMiscOptions = tmpvar;
          StorageTmp->traceRouteCtlMiscOptionsLen = tmplen;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          SNMP_FREE(tmpvar);
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  int
  write_traceRouteCtlMaxFailures(int action,
                                 u_char * var_val,
                                 u_char var_val_type,
                                 size_t var_val_len,
                                 u_char * statP, oid * name, size_t name_len)
  {
      static size_t   tmpvar;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_UNSIGNED) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlTrapTestFailureFilter not ASN_UNSIGNED\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in objid for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlMaxFailures;
          if ((*((long *) var_val)) >= 0 && (*((long *) var_val)) <= 15)
              StorageTmp->traceRouteCtlMaxFailures = *((long *) var_val);
          else
              StorageTmp->traceRouteCtlMaxFailures = 1;
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          StorageTmp->traceRouteCtlMaxFailures = tmpvar;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  
  
  
  
  int
  write_traceRouteCtlDontFragment(int action,
                                  u_char * var_val,
                                  u_char var_val_type,
                                  size_t var_val_len,
                                  u_char * statP, oid * name,
                                  size_t name_len)
  {
      static size_t   tmpvar;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_INTEGER) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlMaxRows not ASN_INTEGER\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in objid for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlDontFragment;
          StorageTmp->traceRouteCtlDontFragment = *((long *) var_val);
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          StorageTmp->traceRouteCtlDontFragment = tmpvar;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  
  
  
  int
  write_traceRouteCtlInitialTtl(int action,
                                u_char * var_val,
                                u_char var_val_type,
                                size_t var_val_len,
                                u_char * statP, oid * name, size_t name_len)
  {
      static size_t   tmpvar;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_UNSIGNED) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlTrapTestFailureFilter not ASN_UNSIGNED\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in objid for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlInitialTtl;
          if ((*((long *) var_val)) >= 0 && (*((long *) var_val)) <= 255)
              StorageTmp->traceRouteCtlInitialTtl = *((long *) var_val);
          else
              StorageTmp->traceRouteCtlInitialTtl = 1;
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          StorageTmp->traceRouteCtlInitialTtl = tmpvar;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  
  int
  write_traceRouteCtlFrequency(int action,
                               u_char * var_val,
                               u_char var_val_type,
                               size_t var_val_len,
                               u_char * statP, oid * name, size_t name_len)
  {
      static size_t   tmpvar;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_UNSIGNED) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlSourceAddressType not ASN_UNSIGNED\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in objid for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlFrequency;
          StorageTmp->traceRouteCtlFrequency = *((long *) var_val);
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          StorageTmp->traceRouteCtlFrequency = tmpvar;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  
  
  
  int
  write_traceRouteCtlStorageType(int action,
                                 u_char * var_val,
                                 u_char var_val_type,
                                 size_t var_val_len,
                                 u_char * statP, oid * name, size_t name_len)
  {
      static size_t   tmpvar;
      int             set_value;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
  
      set_value = *((long *) var_val);
  
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_INTEGER) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlMaxRows not ASN_INTEGER\n");
              return SNMP_ERR_WRONGTYPE;
          }
  
          if ((StorageTmp->traceRouteCtlStorageType == 2
               || StorageTmp->traceRouteCtlStorageType == 3)
              && (set_value == 4 || set_value == 5)) {
              return SNMP_ERR_WRONGVALUE;
          }
          break;
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in objid for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlStorageType;
          StorageTmp->traceRouteCtlStorageType = *((long *) var_val);
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          StorageTmp->traceRouteCtlStorageType = tmpvar;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  
  
  int
  write_traceRouteCtlAdminStatus(int action,
                                 u_char * var_val,
                                 u_char var_val_type,
                                 size_t var_val_len,
                                 u_char * statP, oid * name, size_t name_len)
  {
      static size_t   tmpvar;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      netsnmp_variable_list *vars = NULL;
      struct traceRouteResultsTable_data *StorageNew = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_INTEGER) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlIfIndex not ASN_INTEGER\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in objid for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlAdminStatus;
          StorageTmp->traceRouteCtlAdminStatus = *((long *) var_val);
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          StorageTmp->traceRouteCtlAdminStatus = tmpvar;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
  
          snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) StorageTmp->traceRouteCtlOwnerIndex, StorageTmp->traceRouteCtlOwnerIndexLen); /*  traceRouteCtlOwnerIndex  */
          snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) StorageTmp->traceRouteCtlTestName, StorageTmp->traceRouteCtlTestNameLen);     /*  traceRouteCtlTestName  */
          StorageNew =
              header_complex_get(traceRouteResultsTableStorage, vars);
  
          if (StorageTmp->traceRouteCtlAdminStatus == 1
              && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
              if (StorageNew == NULL)
                  init_trResultsTable(StorageTmp);
              else {
                  StorageTmp->traceRouteResults->
                      traceRouteResultsOperStatus = 1;
                  modify_trResultsOper(StorageTmp, 1);
              }
              if (StorageTmp->traceRouteCtlFrequency != 0)
                  StorageTmp->timer_id =
                      snmp_alarm_register(StorageTmp->traceRouteCtlFrequency,
                                          SA_REPEAT, run_traceRoute,
                                          StorageTmp);
              else
                  StorageTmp->timer_id = snmp_alarm_register(1, 0, run_traceRoute,
                                                             StorageTmp);
  
          } else if (StorageTmp->traceRouteCtlAdminStatus == 2
                     && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
              snmp_alarm_unregister(StorageTmp->timer_id);
              if (StorageNew == NULL)
                  init_trResultsTable(StorageTmp);
              else {
                  StorageTmp->traceRouteResults->
                      traceRouteResultsOperStatus = 2;
                  modify_trResultsOper(StorageTmp, 2);
              }
          }
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  
  
  
  int
  write_traceRouteCtlDescr(int action,
                           u_char * var_val,
                           u_char var_val_type,
                           size_t var_val_len,
                           u_char * statP, oid * name, size_t name_len)
  {
      static char    *tmpvar;
      static size_t   tmplen;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_OCTET_STR) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlTargetAddress not ASN_OCTET_STR\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in long_ret for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlDescr;
          tmplen = StorageTmp->traceRouteCtlDescrLen;
  
          StorageTmp->traceRouteCtlDescr = (char *) malloc(var_val_len + 1);
          if (StorageTmp->traceRouteCtlDescr == NULL) {
              exit(1);
          }
          memcpy(StorageTmp->traceRouteCtlDescr, var_val, var_val_len + 1);
          StorageTmp->traceRouteCtlDescr[var_val_len] = '\0';
          StorageTmp->traceRouteCtlDescrLen = var_val_len;
  
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          SNMP_FREE(StorageTmp->traceRouteCtlDescr);
          StorageTmp->traceRouteCtlDescr = tmpvar;
          StorageTmp->traceRouteCtlDescrLen = tmplen;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          SNMP_FREE(tmpvar);
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  
  
  
  
  int
  write_traceRouteCtlMaxRows(int action,
                             u_char * var_val,
                             u_char var_val_type,
                             size_t var_val_len,
                             u_char * statP, oid * name, size_t name_len)
  {
      static size_t   tmpvar;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_UNSIGNED) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlDSField not ASN_UNSIGNED\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in objid for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlMaxRows;
          StorageTmp->traceRouteCtlMaxRows = *((long *) var_val);
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          StorageTmp->traceRouteCtlMaxRows = tmpvar;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  int
  write_traceRouteCtlTrapGeneration(int action,
                                    u_char * var_val,
                                    u_char var_val_type,
                                    size_t var_val_len,
                                    u_char * statP, oid * name,
                                    size_t name_len)
  {
      static char    *tmpvar;
      static size_t   tmplen;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_OCTET_STR) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlTargetAddress not ASN_OCTET_STR\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in long_ret for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlTrapGeneration;
          tmplen = StorageTmp->traceRouteCtlTrapGenerationLen;
          StorageTmp->traceRouteCtlTrapGeneration =
              (char *) malloc(var_val_len + 1);
          if (StorageTmp->traceRouteCtlTrapGeneration == NULL) {
              exit(1);
          }
  
          memcpy(StorageTmp->traceRouteCtlTrapGeneration, var_val,
                 var_val_len + 1);
          StorageTmp->traceRouteCtlTrapGeneration[var_val_len] = '\0';
          StorageTmp->traceRouteCtlTrapGenerationLen = var_val_len;
  
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          SNMP_FREE(StorageTmp->traceRouteCtlTrapGeneration);
          StorageTmp->traceRouteCtlTrapGeneration = tmpvar;
          StorageTmp->traceRouteCtlTrapGenerationLen = tmplen;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          SNMP_FREE(tmpvar);
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  int
  write_traceRouteCtlCreateHopsEntries(int action,
                                       u_char * var_val,
                                       u_char var_val_type,
                                       size_t var_val_len,
                                       u_char * statP, oid * name,
                                       size_t name_len)
  {
      static size_t   tmpvar;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_INTEGER) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlDSField not ASN_INTEGER\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in objid for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlCreateHopsEntries;
          StorageTmp->traceRouteCtlCreateHopsEntries = *((long *) var_val);
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          StorageTmp->traceRouteCtlCreateHopsEntries = tmpvar;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  int
  write_traceRouteCtlType(int action,
                          u_char * var_val,
                          u_char var_val_type,
                          size_t var_val_len,
                          u_char * statP, oid * name, size_t name_len)
  {
      static oid     *tmpvar;
      static size_t   tmplen;
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
  
      if ((StorageTmp =
           header_complex(traceRouteCtlTableStorage, NULL,
                          &name[sizeof(traceRouteCtlTable_variables_oid) /
                                sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                          NULL)) == NULL)
          return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      switch (action) {
      case RESERVE1:
          if (var_val_type != ASN_OBJECT_ID) {
              snmp_log(LOG_ERR,
                       "write to traceRouteCtlType not ASN_OBJECT_ID\n");
              return SNMP_ERR_WRONGTYPE;
          }
          break;
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          break;
  
  
      case FREE:
          /*
           * Release any resources that have been allocated 
           */
          break;
  
  
      case ACTION:
          /*
           * The variable has been stored in long_ret for
           * you to use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in the UNDO case 
           */
          tmpvar = StorageTmp->traceRouteCtlType;
          tmplen = StorageTmp->traceRouteCtlTypeLen;
  
          StorageTmp->traceRouteCtlType = (oid *) malloc(var_val_len);
          if (StorageTmp->traceRouteCtlType == NULL) {
              exit(1);
          }
          memcpy(StorageTmp->traceRouteCtlType, var_val, var_val_len);
          StorageTmp->traceRouteCtlTypeLen = var_val_len / sizeof(oid);
          break;
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          SNMP_FREE(StorageTmp->traceRouteCtlType);
          StorageTmp->traceRouteCtlType = tmpvar;
          StorageTmp->traceRouteCtlTypeLen = tmplen;
          break;
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          SNMP_FREE(tmpvar);
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  int
  write_traceRouteCtlRowStatus(int action,
                               u_char * var_val,
                               u_char var_val_type,
                               size_t var_val_len,
                               u_char * statP, oid * name, size_t name_len)
  {
      struct traceRouteCtlTable_data *StorageTmp = NULL;
      static struct traceRouteCtlTable_data *StorageNew = NULL;
      static struct traceRouteCtlTable_data *StorageDel = NULL;
      size_t          newlen =
          name_len -
          (OID_LENGTH(traceRouteCtlTable_variables_oid) + 3 - 1);
      static int      old_value;
      int             set_value;
      static netsnmp_variable_list *vars = NULL;
      struct header_complex_index *hciptr = NULL;
  
      StorageTmp =
          header_complex(traceRouteCtlTableStorage, NULL,
                         &name[sizeof(traceRouteCtlTable_variables_oid) /
                               sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL);
  
      if (var_val_type != ASN_INTEGER || var_val == NULL) {
          snmp_log(LOG_ERR,
                   "write to traceRouteCtlRowStatus not ASN_INTEGER\n");
          return SNMP_ERR_WRONGTYPE;
      }
      if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
          return SNMP_ERR_NOTWRITABLE;
      }
  
      set_value = *((long *) var_val);
  
  
      /*
       * check legal range, and notReady is reserved for us, not a user 
       */
      if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY)
          return SNMP_ERR_INCONSISTENTVALUE;
  
  
      switch (action) {
      case RESERVE1:
          /*
           * stage one: test validity 
           */
          if (StorageTmp == NULL) {
              /*
               * create the row now? 
               */
  
              /*
               * ditch illegal values now 
               */
              if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) {
  
                  return SNMP_ERR_INCONSISTENTVALUE;
              }
  
              /*
               * destroying a non-existent row is actually legal 
               */
              if (set_value == RS_DESTROY) {
  
                  return SNMP_ERR_NOERROR;
              }
  
  
              /*
               * illegal creation values 
               */
              if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) {
                  return SNMP_ERR_INCONSISTENTVALUE;
              }
          } else {
              /*
               * row exists.  Check for a valid state change 
               */
              if (set_value == RS_CREATEANDGO
                  || set_value == RS_CREATEANDWAIT) {
                  /*
                   * can't create a row that exists 
                   */
  
                  return SNMP_ERR_INCONSISTENTVALUE;
              }
  
              /*
               * XXX: interaction with row storage type needed 
               */
  
              if (StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE &&
                  set_value != RS_DESTROY) {
                  /*
                   * "Once made active an entry may not be modified except to 
                   * delete it."  XXX: doesn't this in fact apply to ALL
                   * columns of the table and not just this one?  
                   */
  
                  return SNMP_ERR_INCONSISTENTVALUE;
              }
              if (StorageTmp->storageType != ST_NONVOLATILE) {
  
                  return SNMP_ERR_NOTWRITABLE;
              }
          }
  
          break;
  
  
  
  
      case RESERVE2:
          /*
           * memory reseveration, final preparation... 
           */
          if (StorageTmp == NULL) {
  
              if (set_value == RS_DESTROY) {
                  return SNMP_ERR_NOERROR;
              }
              /*
               * creation 
               */
  
  
              snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0);  /* traceRouteCtlOwnerIndex */
              snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0);  /* traceRouteCtlTestName */
  
              if (header_complex_parse_oid
                  (&
                   (name
                    [OID_LENGTH(traceRouteCtlTable_variables_oid) +
                     2]), newlen, vars) != SNMPERR_SUCCESS) {
                  /*
                   * XXX: free, zero vars 
                   */
                  return SNMP_ERR_INCONSISTENTNAME;
              }
  
  
              StorageNew = create_traceRouteCtlTable_data();
              if (vars->val_len <= 32) {
                  StorageNew->traceRouteCtlOwnerIndex =
                      malloc(vars->val_len + 1);
                  memcpy(StorageNew->traceRouteCtlOwnerIndex,
                         vars->val.string, vars->val_len);
                  StorageNew->traceRouteCtlOwnerIndex[vars->val_len] = '\0';
                  StorageNew->traceRouteCtlOwnerIndexLen = vars->val_len;
              } else {
                  StorageNew->traceRouteCtlOwnerIndex = malloc(33);
                  memcpy(StorageNew->traceRouteCtlOwnerIndex,
                         vars->val.string, 32);
                  StorageNew->traceRouteCtlOwnerIndex[32] = '\0';
                  StorageNew->traceRouteCtlOwnerIndexLen = 32;
              }
  
              vars = vars->next_variable;
  
              if (vars->val_len <= 32) {
                  StorageNew->traceRouteCtlTestName =
                      malloc(vars->val_len + 1);
                  memcpy(StorageNew->traceRouteCtlTestName, vars->val.string,
                         vars->val_len);
                  StorageNew->traceRouteCtlTestName[vars->val_len] = '\0';
                  StorageNew->traceRouteCtlTestNameLen = vars->val_len;
              } else {
                  StorageNew->traceRouteCtlTestName = malloc(33);
                  memcpy(StorageNew->traceRouteCtlTestName, vars->val.string,
                         32);
                  StorageNew->traceRouteCtlTestName[32] = '\0';
                  StorageNew->traceRouteCtlTestNameLen = 32;
              }
              vars = vars->next_variable;
  
              /*
               * XXX: fill in default row values here into StorageNew 
               */
  
              StorageNew->traceRouteCtlRowStatus = set_value;
  
  
              /*
               * XXX: free, zero vars, no longer needed? 
               */
          }
          snmp_free_varbind(vars);
          vars = NULL;
          break;
  
      case FREE:
          /*
           * XXX: free, zero vars 
           */
          snmp_free_varbind(vars);
          vars = NULL;
          /*
           * Release any resources that have been allocated 
           */
          break;
  
      case ACTION:
          /*
           * The variable has been stored in set_value for you to
           * use, and you have just been asked to do something with
           * it.  Note that anything done here must be reversable in
           * the UNDO case 
           */
  
          if (StorageTmp == NULL) {
              if (set_value == RS_DESTROY) {
                  return SNMP_ERR_NOERROR;
              }
              /*
               * row creation, so add it 
               */
              if (StorageNew != NULL) {
  #if 1
                  DEBUGMSGTL(("traceRouteCtlTable",
                              "write_traceRouteCtlRowStatus entering new=%d...  \n",
                              action));
  #endif
                  traceRouteCtlTable_add(StorageNew);
              }
  
              /*
               * XXX: ack, and if it is NULL? 
               */
          } else if (set_value != RS_DESTROY) {
              /*
               * set the flag? 
               */
              old_value = StorageTmp->traceRouteCtlRowStatus;
              StorageTmp->traceRouteCtlRowStatus = *((long *) var_val);
          } else {
              /*
               * destroy...  extract it for now 
               */
  
              hciptr =
                  header_complex_find_entry(traceRouteCtlTableStorage,
                                            StorageTmp);
              StorageDel =
                  header_complex_extract_entry(&traceRouteCtlTableStorage,
                                               hciptr);
              snmp_alarm_unregister(StorageDel->timer_id);
  
              traceRouteResultsTable_del(StorageTmp);
              traceRouteProbeHistoryTable_del(StorageTmp);
              traceRouteHopsTable_del(StorageTmp);
          }
          break;
  
  
  
  
      case UNDO:
          /*
           * Back out any changes made in the ACTION case 
           */
          if (StorageTmp == NULL) {
              if (set_value == RS_DESTROY) {
                  return SNMP_ERR_NOERROR;
              }
              /*
               * row creation, so remove it again 
               */
              hciptr =
                  header_complex_find_entry(traceRouteCtlTableStorage,
                                            StorageTmp);
              StorageDel =
                  header_complex_extract_entry(&traceRouteCtlTableStorage,
                                               hciptr);
              /*
               * XXX: free it 
               */
          } else if (StorageDel != NULL) {
              /*
               * row deletion, so add it again 
               */
              traceRouteCtlTable_add(StorageDel);
              traceRouteResultsTable_add(StorageDel);
              traceRouteProbeHistoryTable_addall(StorageDel);
              traceRouteHopsTable_addall(StorageDel);
          } else {
              StorageTmp->traceRouteCtlRowStatus = old_value;
          }
          break;
  
  
  
  
      case COMMIT:
          /*
           * Things are working well, so it's now safe to make the change
           * permanently.  Make sure that anything done here can't fail! 
           */
          if (StorageTmp == NULL) {
              if (set_value == RS_DESTROY) {
                  return SNMP_ERR_NOERROR;
              }
          }
          if (StorageDel != NULL) {
              free(StorageDel->traceRouteCtlOwnerIndex);
              StorageDel->traceRouteCtlOwnerIndex = NULL;
              free(StorageDel->traceRouteCtlTestName);
              StorageDel->traceRouteCtlTestName = NULL;
              free(StorageDel->traceRouteCtlTargetAddress);
              StorageDel->traceRouteCtlTargetAddress = NULL;
              free(StorageDel->traceRouteCtlSourceAddress);
              StorageDel->traceRouteCtlSourceAddress = NULL;
              free(StorageDel->traceRouteCtlMiscOptions);
              StorageDel->traceRouteCtlMiscOptions = NULL;
              free(StorageDel->traceRouteCtlDescr);
              StorageDel->traceRouteCtlDescr = NULL;
              free(StorageDel->traceRouteCtlTrapGeneration);
              StorageDel->traceRouteCtlTrapGeneration = NULL;
              free(StorageDel->traceRouteCtlType);
              StorageDel->traceRouteCtlType = NULL;
              free(StorageDel);
              StorageDel = NULL;
  
              /*
               * XXX: free it, its dead 
               */
          } else {
              if (StorageTmp
                  && StorageTmp->traceRouteCtlRowStatus == RS_CREATEANDGO) {
                  StorageTmp->traceRouteCtlRowStatus = RS_ACTIVE;
              } else if (StorageTmp &&
                         StorageTmp->traceRouteCtlRowStatus ==
                         RS_CREATEANDWAIT) {
  
                  StorageTmp->traceRouteCtlRowStatus = RS_NOTINSERVICE;
              }
          }
          if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
  #if 1
              DEBUGMSGTL(("traceRouteCtlTable",
                          "write_traceRouteCtlRowStatus entering runbefore=%ld...  \n",
                          StorageTmp->traceRouteCtlTargetAddressType));
  
  #endif
              if (StorageTmp->traceRouteCtlAdminStatus == 1) {
                  init_trResultsTable(StorageTmp);
                  if (StorageTmp->traceRouteCtlFrequency != 0)
                      StorageTmp->timer_id =
                          snmp_alarm_register(StorageTmp->
                                              traceRouteCtlFrequency,
                                              SA_REPEAT, run_traceRoute,
                                              StorageTmp);
                  else
                      StorageTmp->timer_id =
                          snmp_alarm_register(1, 0, run_traceRoute, StorageTmp);
  
              }
  
          }
          snmp_store_needed(NULL);
          break;
      }
      return SNMP_ERR_NOERROR;
  }
  
  
  static void
  run_traceRoute_ipv4(struct traceRouteCtlTable_data *item)
  {
      u_short         port = item->traceRouteCtlPort;     /* start udp dest port # for probe packets */
      int             waittime = item->traceRouteCtlTimeOut;      /* time to wait for response (in seconds) */
      int             nprobes = item->traceRouteCtlProbesPerHop;
      char           *old_HopsAddress[255];
      int             count = 0;
      int             flag = 0;
  
      int    code, n, k;
      const    char  *cp;
      char *err;
      u_char *outp;
      u_int32_t *ap;
      struct sockaddr whereto;        /* Who to try to reach */
      struct sockaddr wherefrom;      /* Who we are */
  
      struct sockaddr_in *from = (struct sockaddr_in *) &wherefrom;
      struct sockaddr_in *to = (struct sockaddr_in *) &whereto;
      struct hostinfo *hi;
      int             on = 1;
      struct protoent *pe;
      int    ttl, probe, i;
      int    seq = 0;
      int             tos = 0, settos = 0;
      int    lsrr = 0;
      u_short off = 0;
      struct ifaddrlist *al;
      char            errbuf[132];
      int             minpacket = 0;  /* min ip packet size */
  
  
      struct ip      *outip = NULL;   /* last output (udp) packet */
      struct udphdr  *outudp;         /* last output (udp) packet */
      int             packlen = 0;    /* total length of packet */
      int             optlen = 0;     /* length of ip options */
      int             options = 0;    /* socket options */
      int             s = -1;         /* receive (icmp) socket file descriptor */
      int             sndsock = -1;   /* send (udp/icmp) socket file descriptor */
      int             fd[3] = { -1, -1, -1 };
  
      u_short         ident;
      /*
       * loose source route gateway list (including room for final destination) 
       */
      u_int32_t       gwlist[NGATEWAYS + 1];
      static const char devnull[] = "/dev/null";
      char           *device = NULL;
      char           *source = NULL;
      char           *hostname;
      u_int           pausemsecs = 0;
      u_char          packet[512];    /* last inbound (icmp) packet */
  
      int             pmtu = 0;       /* Path MTU Discovery (RFC1191) */
  
      struct outdata *outdata;        /* last output (udp) packet */
  
      minpacket = sizeof(*outip) + sizeof(*outdata) + optlen;
      minpacket += sizeof(*outudp);
      packlen = minpacket;    /* minimum sized packet */
  
      hostname = malloc(item->traceRouteCtlTargetAddressLen + 1);
      if (hostname == NULL)
          goto out;
      memcpy(hostname, item->traceRouteCtlTargetAddress,
             item->traceRouteCtlTargetAddressLen + 1);
      hostname[item->traceRouteCtlTargetAddressLen] = '\0';
  
      hi = gethostinfo(hostname);
      setsin(to, hi->addrs[0]);
      if (hi->n > 1)
          DEBUGMSGTL(("traceRouteCtlTable",
                      "Warning: %s has multiple addresses; using %s\n",
                      hostname, inet_ntoa(to->sin_addr)));
      free(hostname);
      hostname = strdup(hi->name);
      freehostinfo(hi);
  
  
      netsnmp_set_line_buffering(stdout);
  
      outip = (struct ip *) malloc(packlen);
      if (outip == NULL) {
          DEBUGMSGTL(("traceRouteCtlTable",
                      "malloc: %s\n", strerror(errno)));
          exit(1);
      }
      memset((char *) outip, 0, packlen);
  
      outip->ip_v = IPVERSION;
      if (settos)
          outip->ip_tos = tos;
  #ifdef BYTESWAP_IP_HDR
      outip->ip_len = htons(packlen);
      outip->ip_off = htons(off);
  #else
      outip->ip_len = packlen;
      outip->ip_off = off;
  #endif
      outp = (u_char *) (outip + 1);
  #ifdef HAVE_RAW_OPTIONS
      if (lsrr > 0) {
          u_char *optlist;
  
          optlist = outp;
          outp += optlen;
  
          /*
           * final hop 
           */
          gwlist[lsrr] = to->sin_addr.s_addr;
  
          outip->ip_dst.s_addr = gwlist[0];
  
          /*
           * force 4 byte alignment 
           */
          optlist[0] = IPOPT_NOP;
          /*
           * loose source route option 
           */
          optlist[1] = IPOPT_LSRR;
          i = lsrr * sizeof(gwlist[0]);
          optlist[2] = i + 3;
          /*
           * Pointer to LSRR addresses 
           */
          optlist[3] = IPOPT_MINOFF;
          memcpy(optlist + 4, gwlist + 1, i);
      } else
  #endif
          outip->ip_dst = to->sin_addr;
      outip->ip_hl = (outp - (u_char *) outip) >> 2;
      ident = (getpid() & 0xffff) | 0x8000;
  
      outip->ip_p = IPPROTO_UDP;
  
      outudp = (struct udphdr *) outp;
      outudp->source = htons(ident);
      outudp->len =
          htons((u_short) (packlen - (sizeof(*outip) + optlen)));
      outdata = (struct outdata *) (outudp + 1);
  
      cp = "icmp";
      if ((pe = getprotobyname(cp)) == NULL) {
          DEBUGMSGTL(("traceRouteCtlTable",
                      "unknown protocol %s\n", cp));
          exit(1);
      }
  
      /*
       * Insure the socket fds won't be 0, 1 or 2 
       */
      if ((fd[0] = open(devnull, O_RDONLY)) < 0 ||
          (fd[1] = open(devnull, O_RDONLY)) < 0 ||
          (fd[2] = open(devnull, O_RDONLY)) < 0) {
          DEBUGMSGTL(("traceRouteCtlTable",
                      "open \"%s\": %s\n", devnull, strerror(errno)));
          exit(1);
      }
      if ((s = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0) {
          DEBUGMSGTL(("traceRouteCtlTable",
                      "icmp socket: %s\n", strerror(errno)));
          exit(1);
      }
      if (options & SO_DEBUG)
          (void) setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *) &on,
                            sizeof(on));
      if (options & SO_DONTROUTE)
          (void) setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *) &on,
                            sizeof(on));
  #ifndef __hpux
      printf("raw\n");
      sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
  #else
      printf("udp\n");
      sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
  #endif
      if (sndsock < 0) {
          DEBUGMSGTL(("traceRouteCtlTable",
                      "raw socket: %s\n", strerror(errno)));
          exit(1);
      }
  #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
      if (lsrr > 0) {
          u_char          optlist[MAX_IPOPTLEN];
  
          cp = "ip";
          if ((pe = getprotobyname(cp)) == NULL) {
              DEBUGMSGTL(("traceRouteCtlTable",
                          "unknown protocol %s\n", cp));
              exit(1);
          }
          /*
           * final hop 
           */
          gwlist[lsrr] = to->sin_addr.s_addr;
          ++lsrr;
  
          /*
           * force 4 byte alignment 
           */
          optlist[0] = IPOPT_NOP;
          /*
           * loose source route option 
           */
          optlist[1] = IPOPT_LSRR;
          i = lsrr * sizeof(gwlist[0]);
          optlist[2] = i + 3;
          /*
           * Pointer to LSRR addresses 
           */
          optlist[3] = IPOPT_MINOFF;
          memcpy(optlist + 4, gwlist, i);
  
          if ((setsockopt(sndsock, pe->p_proto, IP_OPTIONS,
                          (char *) optlist,
                          i + sizeof(gwlist[0]))) < 0) {
              DEBUGMSGTL(("traceRouteCtlTable", "IP_OPTIONS: %s\n",
                          strerror(errno)));
              exit(1);
          }
      }
  #endif
  #ifdef SO_SNDBUF
      if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *) &packlen,
                     sizeof(packlen)) < 0) {
          DEBUGMSGTL(("traceRouteCtlTable",
                      "SO_SNDBUF: %s\n", strerror(errno)));
          exit(1);
      }
  #endif
  #ifdef IP_HDRINCL
      if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *) &on,
                     sizeof(on)) < 0) {
          DEBUGMSGTL(("traceRouteCtlTable",
                      "IP_HDRINCL: %s\n", strerror(errno)));
          exit(1);
      }
  #else
  #ifdef IP_TOS
      if (settos && setsockopt(sndsock, IPPROTO_IP, IP_TOS,
                               (char *) &tos, sizeof(tos)) < 0) {
          DEBUGMSGTL(("traceRouteCtlTable",
                      "setsockopt tos %d: %s\n", strerror(errno)));
          exit(1);
      }
  #endif
  #endif
      if (options & SO_DEBUG)
          (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *) &on,
                            sizeof(on));
      if (options & SO_DONTROUTE)
          (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
                            (char *) &on, sizeof(on));
      /*
       * Get the interface address list 
       */
      n = ifaddrlist(&al, errbuf);
      if (n < 0) {
          DEBUGMSGTL(("traceRouteCtlTable",
                      " ifaddrlist: %s\n", errbuf));
          exit(1);
      }
      if (n == 0) {
          DEBUGMSGTL(("traceRouteCtlTable",
                      " Can't find any network interfaces\n"));
  
          exit(1);
      }
  
      /*
       * Look for a specific device 
       */
      if (device != NULL) {
          for (i = n; i > 0; --i, ++al)
              if (strcmp(device, al->device) == 0)
                  break;
          if (i <= 0) {
              DEBUGMSGTL(("traceRouteCtlTable",
                          " Can't find interface %.32s\n", device));
  
              exit(1);
          }
      }
      /*
       * Determine our source address 
       */
      if (source == NULL) {
          /*
           * If a device was specified, use the interface address.
           * Otherwise, try to determine our source address.
           */
          if (device != NULL)
              setsin(from, al->addr);
          else if ((err = findsaddr(to, from)) != NULL) {
              DEBUGMSGTL(("traceRouteCtlTable",
                          " findsaddr: %s\n", err));
              free(err);
              exit(1);
          }
  
      } else {
          hi = gethostinfo(source);
          source = hi->name;
          hi->name = NULL;
          /*
           * If the device was specified make sure it
           * corresponds to the source address specified.
           * Otherwise, use the first address (and warn if
           * there are more than one).
           */
          if (device != NULL) {
              for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
                  if (*ap == al->addr)
                      break;
              if (i <= 0) {
                  DEBUGMSGTL(("traceRouteCtlTable",
                              " %s is not on interface %.32s\n",
                              source, device));
  
                  exit(1);
              }
              setsin(from, *ap);
          } else {
              setsin(from, hi->addrs[0]);
              if (hi->n > 1)
                  DEBUGMSGTL(("traceRouteCtlTable",
                              " Warning: %s has multiple addresses; using %s\n",
                              source, inet_ntoa(from->sin_addr)));
  
          }
          freehostinfo(hi);
      }
      /*
       * Revert to non-privileged user after opening sockets 
       */
      NETSNMP_IGNORE_RESULT(setgid(getgid()));
      NETSNMP_IGNORE_RESULT(setuid(getuid()));
  
      outip->ip_src = from->sin_addr;
  #ifndef IP_HDRINCL
      if (bind(sndsock, (struct sockaddr *) from, sizeof(*from)) < 0) {
          DEBUGMSGTL(("traceRouteCtlTable",
                      " bind: %s\n", strerror(errno)));
          exit(1);
      }
  #endif
      DEBUGMSGTL(("traceRouteCtlTable",
                  " to %s (%s)", hostname, inet_ntoa(to->sin_addr)));
  
      if (source)
          DEBUGMSGTL(("traceRouteCtlTable", " from %s", source));
  
      DEBUGMSGTL(("traceRouteCtlTable",
                  ", %lu hops max, %d byte packets\n",
                  item->traceRouteCtlMaxTtl, packlen));
      (void) fflush(stderr);
  
      struct traceRouteResultsTable_data *StorageResults = NULL;
      netsnmp_variable_list *vars_results = NULL;
  
      struct traceRouteHopsTable_data *temp = NULL;
      struct traceRouteHopsTable_data *current_temp = NULL;
      struct traceRouteHopsTable_data *current = NULL;
  
      unsigned long   index = 0;
  
      struct traceRouteProbeHistoryTable_data *temp_his = NULL;
      struct traceRouteProbeHistoryTable_data *current_temp_his = NULL;
  
      snmp_varlist_add_variable(&vars_results, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen);     /*  traceRouteCtlOwnerIndex  */
      snmp_varlist_add_variable(&vars_results, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen); /*  traceRouteCtlTestName  */
      if ((StorageResults =
           header_complex_get(traceRouteResultsTableStorage,
                              vars_results)) == NULL) {
          goto out;
      }
      snmp_free_varbind(vars_results);
      vars_results = NULL;
  
  
      for (ttl = item->traceRouteCtlInitialTtl;
           ttl <= item->traceRouteCtlMaxTtl; ++ttl) {
  
          u_int32_t       lastaddr = 0;
          int             gotlastaddr = 0;
          int             got_there = 0;
          int             unreachable = 0;
          int             sentfirst = 0;
          time_t          timep = 0;
  
          StorageResults->traceRouteResultsCurHopCount = ttl;
          if (item->traceRouteCtlCreateHopsEntries == 1) {
              if (ttl == item->traceRouteCtlInitialTtl) {
                  int             k = 0;
                  count = traceRouteHopsTable_count(item);
  
  
                  struct traceRouteHopsTable_data *StorageTmp = NULL;
                  struct header_complex_index *hciptr2, *nhciptr2;
                  netsnmp_variable_list *vars = NULL;
                  oid             newoid[MAX_OID_LEN];
                  size_t          newoid_len;
  
                  snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */
                  snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen);     /* traceRouteCtlTestName */
  
                  header_complex_generate_oid(newoid, &newoid_len, NULL,
                                              0, vars);
  
                  for (hciptr2 = traceRouteHopsTableStorage; hciptr2;
                       hciptr2 = nhciptr2) {
                      nhciptr2 = hciptr2->next;
                      if (snmp_oid_compare
                          (newoid, newoid_len, hciptr2->name,
                           newoid_len) == 0) {
                          StorageTmp =
                              header_complex_extract_entry
                              (&traceRouteHopsTableStorage, hciptr2);
  
                          old_HopsAddress[k] =
                              (char *) malloc(StorageTmp->
                                              traceRouteHopsIpTgtAddressLen
                                              + 1);
                          if (old_HopsAddress[k] == NULL) {
                              exit(1);
                          }
                          old_HopsAddress[k] = netsnmp_memdup(
                                                              StorageTmp->traceRouteHopsIpTgtAddress,
                                                              StorageTmp->
                                                              traceRouteHopsIpTgtAddressLen + 1);
                          old_HopsAddress[k][StorageTmp->
                                             traceRouteHopsIpTgtAddressLen]
                              = '\0';
  
                          k++;
                          StorageTmp = NULL;
                      }
                  }
                  traceRouteHopsTable_del(item);
                  index = 0;
              }
  
              temp = SNMP_MALLOC_STRUCT(traceRouteHopsTable_data);
              temp->traceRouteCtlOwnerIndex =
                  (char *) malloc(item->traceRouteCtlOwnerIndexLen + 1);
              memcpy(temp->traceRouteCtlOwnerIndex,
                     item->traceRouteCtlOwnerIndex,
                     item->traceRouteCtlOwnerIndexLen + 1);
              temp->traceRouteCtlOwnerIndex[item->
                                            traceRouteCtlOwnerIndexLen] =
                  '\0';
              temp->traceRouteCtlOwnerIndexLen =
                  item->traceRouteCtlOwnerIndexLen;
  
              temp->traceRouteCtlTestName =
                  (char *) malloc(item->traceRouteCtlTestNameLen + 1);
              memcpy(temp->traceRouteCtlTestName,
                     item->traceRouteCtlTestName,
                     item->traceRouteCtlTestNameLen + 1);
              temp->traceRouteCtlTestName[item->
                                          traceRouteCtlTestNameLen] =
                  '\0';
              temp->traceRouteCtlTestNameLen =
                  item->traceRouteCtlTestNameLen;
  
              /* add lock to protect */
              pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
              pthread_mutex_lock(&counter_mutex);
              temp->traceRouteHopsHopIndex = ++index;
              pthread_mutex_unlock(&counter_mutex);
              /* endsadsadsad */
  
  
              temp->traceRouteHopsIpTgtAddressType = 0;
              temp->traceRouteHopsIpTgtAddress = strdup("");
              temp->traceRouteHopsIpTgtAddressLen = 0;
              temp->traceRouteHopsMinRtt = 0;
              temp->traceRouteHopsMaxRtt = 0;
              temp->traceRouteHopsAverageRtt = 0;
              temp->traceRouteHopsRttSumOfSquares = 0;
              temp->traceRouteHopsSentProbes = 0;
              temp->traceRouteHopsProbeResponses = 0;
  
              temp->traceRouteHopsLastGoodProbeLen = 0;
              if (index == 1)
                  item->traceRouteHops = temp;
              else {
                  (current_temp)->next = temp;
              }
  
              current_temp = temp;
  
              if (index + 1 >= item->traceRouteCtlMaxTtl) {
                  current_temp->next = NULL;
              }
  
              if (item->traceRouteHops != NULL)
  
                  if (traceRouteHopsTable_add(current_temp) !=
                      SNMPERR_SUCCESS)
                      DEBUGMSGTL(("traceRouteHopsTable",
                                  "registered an entry error\n"));
  
          }
          unsigned long maxRtt = 0;
          unsigned long minRtt = 0;
          unsigned long averageRtt = 0;
          unsigned long sumRtt = 0;
          unsigned long responseProbe = 0;
          unsigned long sumOfSquare = 0;
          for (probe = 0; probe < nprobes; ++probe) {
              int    cc;
              struct timeval  t1, t2;
              struct timezone tz;
              struct ip *ip = NULL;
              unsigned long Rtt = 0;
  
              if (sentfirst && pausemsecs > 0)
                  usleep(pausemsecs * 1000);
              (void) gettimeofday(&t1, &tz);
              send_probe(to, ++seq, ttl, &t1, outip, outudp, packlen,
                         optlen, hostname, ident, sndsock, port,
                         outdata);
              ++sentfirst;
              while ((cc =
                      wait_for_reply(s, from, &t1, packet,
                                     waittime)) != 0) {
                  (void) gettimeofday(&t2, &tz);
                  timep = 0;
                  time(&timep);
                  i = packet_ok(packet, cc, from, seq, ident, pmtu,
                                port);
                  /*
                   * Skip short packet 
                   */
                  if (i == 0)
                      continue;
                  if (!gotlastaddr || from->sin_addr.s_addr != lastaddr) {
                      struct ip *ip;
                      int    hlen;
                      ip = (struct ip *) packet;
                      hlen = ip->ip_hl << 2;
                      cc -= hlen;
                      DEBUGMSGTL(("traceRouteCtlTable",
                                  " %s", inet_ntoa(from->sin_addr)));
  
  
                      lastaddr = from->sin_addr.s_addr;
                      ++gotlastaddr;
                  }
                  Rtt = deltaT(&t1, &t2);
                  responseProbe = responseProbe + 1;
                  if (probe == 0) {
                      minRtt = Rtt;
                      maxRtt = Rtt;
                      averageRtt = Rtt;
                      sumRtt = Rtt;
                      sumOfSquare = Rtt * Rtt;
                  } else {
                      if (Rtt < minRtt)
                          minRtt = Rtt;
                      if (Rtt > maxRtt)
                          maxRtt = Rtt;
                      sumRtt = (sumRtt) + Rtt;
                      averageRtt =
                          round((double) (sumRtt) /
                                (double) responseProbe);
                      sumOfSquare = sumOfSquare + Rtt * Rtt;
                  }
  
                  StorageResults->traceRouteResultsCurProbeCount =
                      probe + 1;
                  if (i == -2) {
  #ifndef ARCHAIC
                      ip = (struct ip *) packet;
                      if (ip->ip_ttl <= 1)
                          Printf(" !");
  #endif
                      ++got_there;
                      break;
                  }
                  /*
                   * time exceeded in transit 
                   */
                  if (i == -1)
                      break;
                  code = i - 1;
                  switch (code) {
  
                  case ICMP_UNREACH_PORT:
  #ifndef ARCHAIC
                      ip = (struct ip *) packet;
                      if (ip->ip_ttl <= 1)
                          Printf(" !");
  #endif
                      ++got_there;
                      break;
  
                  case ICMP_UNREACH_NET:
                      ++unreachable;
                      Printf(" !N");
                      break;
  
                  case ICMP_UNREACH_HOST:
                      ++unreachable;
                      Printf(" !H");
                      break;
  
                  case ICMP_UNREACH_PROTOCOL:
                      ++got_there;
                      Printf(" !P");
                      break;
  
                  case ICMP_UNREACH_NEEDFRAG:
                      ++unreachable;
                      Printf(" !F-%d", pmtu);
                      break;
  
                  case ICMP_UNREACH_SRCFAIL:
                      ++unreachable;
                      Printf(" !S");
                      break;
  
                  case ICMP_UNREACH_FILTER_PROHIB:
                      ++unreachable;
                      Printf(" !X");
                      break;
  
                  case ICMP_UNREACH_HOST_PRECEDENCE:
                      ++unreachable;
                      Printf(" !V");
                      break;
  
                  case ICMP_UNREACH_PRECEDENCE_CUTOFF:
                      ++unreachable;
                      Printf(" !C");
                      break;
  
                  default:
                      ++unreachable;
                      Printf(" !<%d>", code);
                      break;
                  }
                  break;
              }
              if (cc == 0) {
                  timep = 0;
                  time(&timep);
                  Printf(" *");
                  Rtt = (item->traceRouteCtlTimeOut) * 1000;
              }
              if (item->traceRouteCtlMaxRows != 0) {
  
                  temp_his =
                      SNMP_MALLOC_STRUCT
                      (traceRouteProbeHistoryTable_data);
                  temp_his->traceRouteCtlOwnerIndex =
                      (char *) malloc(item->traceRouteCtlOwnerIndexLen +
                                      1);
                  memcpy(temp_his->traceRouteCtlOwnerIndex,
                         item->traceRouteCtlOwnerIndex,
                         item->traceRouteCtlOwnerIndexLen + 1);
                  temp_his->traceRouteCtlOwnerIndex[item->
                                                    traceRouteCtlOwnerIndexLen]
                      = '\0';
                  temp_his->traceRouteCtlOwnerIndexLen =
                      item->traceRouteCtlOwnerIndexLen;
  
                  temp_his->traceRouteCtlTestName =
                      (char *) malloc(item->traceRouteCtlTestNameLen +
                                      1);
                  memcpy(temp_his->traceRouteCtlTestName,
                         item->traceRouteCtlTestName,
                         item->traceRouteCtlTestNameLen + 1);
                  temp_his->traceRouteCtlTestName[item->
                                                  traceRouteCtlTestNameLen]
                      = '\0';
                  temp_his->traceRouteCtlTestNameLen =
                      item->traceRouteCtlTestNameLen;
  
                  /* add lock to protect */
                  pthread_mutex_t counter_mutex =
                      PTHREAD_MUTEX_INITIALIZER;
                  pthread_mutex_lock(&counter_mutex);
                  if (item->traceRouteProbeHistoryMaxIndex >=
                      (unsigned long) (2147483647))
                      item->traceRouteProbeHistoryMaxIndex = 0;
                  temp_his->traceRouteProbeHistoryIndex =
                      ++(item->traceRouteProbeHistoryMaxIndex);
                  pthread_mutex_unlock(&counter_mutex);
                  /* endsadsadsad */
                  temp_his->traceRouteProbeHistoryHopIndex = ttl;
                  temp_his->traceRouteProbeHistoryProbeIndex = probe + 1;
  
                  temp_his->traceRouteProbeHistoryHAddrType = 1;
                  temp_his->traceRouteProbeHistoryHAddr =
                      (char *) malloc(strlen(inet_ntoa(from->sin_addr)) +
                                      1);
                  strcpy(temp_his->traceRouteProbeHistoryHAddr,
                         (inet_ntoa(from->sin_addr)));
                  temp_his->
                      traceRouteProbeHistoryHAddr[strlen
                                                  (inet_ntoa
                                                   (from->sin_addr))] =
                      '\0';
                  temp_his->traceRouteProbeHistoryHAddrLen =
                      strlen(inet_ntoa(from->sin_addr));
  
                  temp_his->traceRouteProbeHistoryResponse = Rtt;
                  temp_his->traceRouteProbeHistoryStatus = 1;
                  temp_his->traceRouteProbeHistoryLastRC = 0;
  
                  temp_his->traceRouteProbeHistoryTime_time = timep;
                  temp_his->traceRouteProbeHistoryTime =
                      netsnmp_memdup(date_n_time(&timep,
                                                 &temp_his->traceRouteProbeHistoryTimeLen),
                                     11);
                  if (probe == 0)
                      item->traceRouteProbeHis = temp_his;
                  else {
                      (current_temp_his)->next = temp_his;
                  }
  
                  current_temp_his = temp_his;
  
                  if (probe + 1 >= nprobes) {
                      current_temp_his->next = NULL;
  
                  }
  
                  if (item->traceRouteProbeHis != NULL) {
                      if (traceRouteProbeHistoryTable_count(item) <
                          item->traceRouteCtlMaxRows) {
                          if (traceRouteProbeHistoryTable_add
                              (current_temp_his) != SNMPERR_SUCCESS)
                              DEBUGMSGTL(("traceRouteProbeHistoryTable",
                                          "registered an entry error\n"));
                      } else {
                          traceRouteProbeHistoryTable_delLast(item);
                          if (traceRouteProbeHistoryTable_add
                              (current_temp_his) != SNMPERR_SUCCESS)
                              DEBUGMSGTL(("traceRouteProbeHistoryTable",
                                          "registered an entry error\n"));
  
                      }
                  }
  
              }
  
              if (item->traceRouteCtlCreateHopsEntries == 1) {
                  netsnmp_variable_list *vars_hops = NULL;
                  snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen);    /*  traceRouteCtlOwnerIndex  */
                  snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen);        /*  traceRouteCtlTestName  */
                  snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_UNSIGNED, (char *) &index, sizeof(index));       /*  traceRouteHopsIndex  */
                  if ((current =
                       header_complex_get(traceRouteHopsTableStorage,
                                          vars_hops)) == NULL) {
                      goto out;
                  }
                  snmp_free_varbind(vars_hops);
                  vars_hops = NULL;
  
                  current->traceRouteHopsIpTgtAddressType = 1;
                  current->traceRouteHopsIpTgtAddress =
                      (char *) malloc(strlen(inet_ntoa(from->sin_addr)) +
                                      1);
                  current->traceRouteHopsIpTgtAddress =
                      strdup(inet_ntoa(from->sin_addr));
                  current->
                      traceRouteHopsIpTgtAddress[strlen
                                                 (inet_ntoa
                                                  (from->sin_addr))] =
                      '\0';
                  current->traceRouteHopsIpTgtAddressLen =
                      strlen(inet_ntoa(from->sin_addr));
                  if (count != 0) {
                      if (strcmp
                          (old_HopsAddress[index - 1],
                           current->traceRouteHopsIpTgtAddress) != 0)
                          flag = 1;
                  }
  
                  current->traceRouteHopsIpTgtAddressLen =
                      strlen(inet_ntoa(from->sin_addr));
                  current->traceRouteHopsMinRtt = minRtt;
                  current->traceRouteHopsMaxRtt = maxRtt;
                  current->traceRouteHopsAverageRtt = averageRtt;
                  current->traceRouteHopsRttSumOfSquares = sumOfSquare;
                  current->traceRouteHopsSentProbes = probe + 1;
                  current->traceRouteHopsProbeResponses = responseProbe;
                  current->traceRouteHopsLastGoodProbe_time = timep;
                  current->traceRouteHopsLastGoodProbe =
                      netsnmp_memdup(date_n_time(&timep,
                                                 &current->traceRouteHopsLastGoodProbeLen),
                                     11);
              }
  
              (void) fflush(stdout);
          }
          putchar('\n');
  
  
          if (got_there
              || (unreachable > 0 && unreachable >= nprobes - 1)) {
  
              if (got_there != 0) {
                  StorageResults->traceRouteResultsTestAttempts =
                      StorageResults->traceRouteResultsTestAttempts + 1;
  
                  StorageResults->traceRouteResultsTestSuccesses =
                      StorageResults->traceRouteResultsTestSuccesses + 1;
  
                  StorageResults->traceRouteResultsLastGoodPath_time = timep;
                  StorageResults->traceRouteResultsLastGoodPath =
                      netsnmp_memdup(date_n_time(&timep,
                                                 &StorageResults->
                                                 traceRouteResultsLastGoodPathLen),
                                     11);
                  if ((item->
                       traceRouteCtlTrapGeneration[0] &
                       TRACEROUTETRAPGENERATION_TESTCOMPLETED) != 0) {
                      DEBUGMSGTL(("traceRouteProbeHistoryTable",
                                  "TEST completed!\n"));
                      send_traceRoute_trap(item, traceRouteTestCompleted,
                                           sizeof
                                           (traceRouteTestCompleted) /
                                           sizeof(oid));
                  }
              }
  
              else {
                  StorageResults->traceRouteResultsTestAttempts =
                      StorageResults->traceRouteResultsTestAttempts + 1;
                  if ((item->
                       traceRouteCtlTrapGeneration[0] &
                       TRACEROUTETRAPGENERATION_TESTFAILED) != 0) {
                      DEBUGMSGTL(("traceRouteProbeHistoryTable",
                                  "test Failed!\n"));
                      send_traceRoute_trap(item, traceRouteTestFailed,
                                           sizeof(traceRouteTestFailed) /
                                           sizeof(oid));
                  }
              }
              break;
  
          } else if (ttl == item->traceRouteCtlMaxTtl
                     && (probe + 1) == nprobes) {
              StorageResults->traceRouteResultsTestAttempts =
                  StorageResults->traceRouteResultsTestAttempts + 1;
  
              if ((item->
                   traceRouteCtlTrapGeneration[0] &
                   TRACEROUTETRAPGENERATION_TESTFAILED) != 0) {
                  DEBUGMSGTL(("traceRouteProbeHistoryTable",
                              "test Failed!\n"));
                  send_traceRoute_trap(item, traceRouteTestFailed,
                                       sizeof(traceRouteTestFailed) /
                                       sizeof(oid));
              }
          }
  
      }
  
      if (flag == 1) {
          DEBUGMSGTL(("traceRouteProbeHistoryTable", "path changed!\n"));
          send_traceRoute_trap(item, traceRoutePathChange,
                               sizeof(traceRoutePathChange) /
                               sizeof(oid));
      }
  
  out:
      for (k = 0; k < count; k++)
          free(old_HopsAddress[k]);
      for (k = 0; k < 3; k++)
          if (fd[k] >= 0)
              close(fd[k]);
      if (s >= 0)
          close(s);
      if (sndsock >= 0)
          close(sndsock);
      free(outip);
      free(hostname);
  }
  
  static void
  run_traceRoute_ipv6(struct traceRouteCtlTable_data *item)
  {
      int             nprobes = item->traceRouteCtlProbesPerHop;
      char           *old_HopsAddress[255];
      int             count = 0;
      int             flag = 0;
  
      int             icmp_sock = -1;  /* receive (icmp) socket file descriptor */
      int             sndsock = -1;    /* send (udp) socket file descriptor */
  
      struct sockaddr_in6 whereto;    /* Who to try to reach */
  
      struct sockaddr_in6 saddr;
      struct sockaddr_in6 firsthop;
      char           *source = NULL;
      char           *device = NULL;
      char           *hostname;
  
      pid_t           ident = 0;
      u_short         port = 32768 + 666;     /* start udp dest port # for probe packets */
      int             options = 0;    /* socket options */
      int             waittime = 5;   /* time to wait for response (in seconds) */
  
      char           *sendbuff = NULL;
      int             datalen = sizeof(struct pkt_format);
  
      u_char          packet[512];    /* last inbound (icmp) packet */
  
      char            pa[64];
      struct hostent *hp = NULL;
      struct sockaddr_in6 from, *to = NULL;
      int             i = 0, k, on = 0, probe = 0, seq = 0, tos = 0, ttl = 0;
      int             socket_errno = 0;
  
      icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
      socket_errno = errno;
  
      NETSNMP_IGNORE_RESULT(setuid(getuid()));
  
      on = 1;
      seq = tos = 0;
      to = (struct sockaddr_in6 *) &whereto;
  
      hostname = malloc(item->traceRouteCtlTargetAddressLen + 1);
      if (!hostname)
          goto out;
      memcpy(hostname, item->traceRouteCtlTargetAddress,
             item->traceRouteCtlTargetAddressLen + 1);
      hostname[item->traceRouteCtlTargetAddressLen] = '\0';
  
      setlinebuf(stdout);
  
      memset(&whereto, '\0', sizeof(struct sockaddr_in6));
  
      to->sin6_family = AF_INET6;
      to->sin6_port = htons(port);
  
      if (inet_pton(AF_INET6, hostname, &to->sin6_addr) <= 0) {
          hp = gethostbyname2(hostname, AF_INET6);
          if (hp != NULL) {
              memmove((caddr_t) & to->sin6_addr, hp->h_addr, 16);
              free(hostname);
              hostname = strdup((char *) hp->h_name);
          } else {
              fprintf(stderr, "traceroute: unknown host %s\n", hostname);
              free(hostname);
              hostname = NULL;
              goto out;
          }
      }
      firsthop = *to;
  
      datalen = item->traceRouteCtlDataSize;
      if (datalen < (int) sizeof(struct pkt_format)
          || datalen >= MAXPACKET) {
          Fprintf(stderr,
                  "traceroute: packet size must be %d <= s < %d.\n",
                  (int) sizeof(struct pkt_format), MAXPACKET);
          datalen = 16;
      }
  
      ident = getpid();
  
      sendbuff = malloc(datalen);
      if (sendbuff == NULL) {
          fprintf(stderr, "malloc failed\n");
          goto out;
      }
  
      if (icmp_sock < 0) {
          errno = socket_errno;
          perror("traceroute6: icmp socket");
          goto out;
      }
  
      if (options & SO_DEBUG)
          setsockopt(icmp_sock, SOL_SOCKET, SO_DEBUG,
                     (char *) &on, sizeof(on));
      if (options & SO_DONTROUTE)
          setsockopt(icmp_sock, SOL_SOCKET, SO_DONTROUTE,
                     (char *) &on, sizeof(on));
  
      if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
          perror("traceroute: UDP socket");
          goto out;
      }
  #ifdef SO_SNDBUF
      if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *) &datalen,
                     sizeof(datalen)) < 0) {
          perror("traceroute: SO_SNDBUF");
          goto out;
      }
  #endif                          /* SO_SNDBUF */
  
      if (options & SO_DEBUG)
          (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
                            (char *) &on, sizeof(on));
      if (options & SO_DONTROUTE)
          (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
                            (char *) &on, sizeof(on));
  
      if (source == NULL) {
          socklen_t       alen;
          int             probe_fd = socket(AF_INET6, SOCK_DGRAM, 0);
  
          if (probe_fd < 0) {
              perror("socket");
              close(probe_fd);
              goto out;
          }
          if (device) {
              if (setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device,
                             strlen(device) + 1) == -1)
                  perror("WARNING: interface is ignored");
          }
          firsthop.sin6_port = htons(1025);
          if (connect(probe_fd, (struct sockaddr *) &firsthop,
                      sizeof(firsthop)) == -1) {
              perror("connect");
              close(probe_fd);
              goto out;
          }
          alen = sizeof(saddr);
          if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1) {
              perror("getsockname");
              close(probe_fd);
              goto out;
          }
          saddr.sin6_port = 0;
          close(probe_fd);
      } else {
          memset(&saddr, '\0', sizeof(struct sockaddr_in6));
          saddr.sin6_family = AF_INET6;
          if (inet_pton(AF_INET6, source, &saddr.sin6_addr) < 0) {
              Printf("traceroute: unknown addr %s\n", source);
              goto out;
          }
      }
  
      if (bind(sndsock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
          perror("traceroute: bind sending socket");
          goto out;
      }
      if (bind(icmp_sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
          perror("traceroute: bind icmp6 socket");
          goto out;
      }
  
      Fprintf(stderr, "traceroute to %s (%s)", hostname,
              inet_ntop(AF_INET6, &to->sin6_addr, pa, 64));
  
      Fprintf(stderr, " from %s",
              inet_ntop(AF_INET6, &saddr.sin6_addr, pa, 64));
      Fprintf(stderr, ", %lu hops max, %d byte packets\n",
              item->traceRouteCtlMaxTtl, datalen);
      (void) fflush(stderr);
  
  
      struct traceRouteResultsTable_data *StorageResults = NULL;
      netsnmp_variable_list *vars_results = NULL;
  
      struct traceRouteHopsTable_data *temp = NULL;
      struct traceRouteHopsTable_data *current_temp = NULL;
      struct traceRouteHopsTable_data *current = NULL;
  
      unsigned long   index = 0;
  
      struct traceRouteProbeHistoryTable_data *temp_his = NULL;
      struct traceRouteProbeHistoryTable_data *current_temp_his = NULL;
  
      snmp_varlist_add_variable(&vars_results, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen);     /*  traceRouteCtlOwnerIndex  */
      snmp_varlist_add_variable(&vars_results, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen); /*  traceRouteCtlTestName  */
      if ((StorageResults =
           header_complex_get(traceRouteResultsTableStorage,
                              vars_results)) == NULL) {
          goto out;
      }
      snmp_free_varbind(vars_results);
      vars_results = NULL;
  
      for (ttl = item->traceRouteCtlInitialTtl;
           ttl <= item->traceRouteCtlMaxTtl; ++ttl) {
          struct in6_addr lastaddr = { {{0,}} };
          int             got_there = 0;
          int             unreachable = 0;
          time_t          timep = 0;
          Printf("%2d ", ttl);
  
  
          StorageResults->traceRouteResultsCurHopCount = ttl;
          if (item->traceRouteCtlCreateHopsEntries == 1) {
              if (ttl == item->traceRouteCtlInitialTtl) {
  
                  int             k = 0;
                  count = traceRouteHopsTable_count(item);
                  struct traceRouteHopsTable_data *StorageTmp;
                  struct header_complex_index *hciptr2, *nhciptr2;
                  netsnmp_variable_list *vars = NULL;
                  oid             newoid[MAX_OID_LEN];
                  size_t          newoid_len;
  
                  snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */
                  snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen);     /* traceRouteCtlTestName */
  
                  header_complex_generate_oid(newoid, &newoid_len, NULL,
                                              0, vars);
  
                  snmp_free_varbind(vars);
                  vars = NULL;
  
                  for (hciptr2 = traceRouteHopsTableStorage; hciptr2;
                       hciptr2 = nhciptr2) {
                      nhciptr2 = hciptr2->next;
                      if (snmp_oid_compare
                          (newoid, newoid_len, hciptr2->name,
                           newoid_len) == 0) {
                          StorageTmp =
                              header_complex_extract_entry
                              (&traceRouteHopsTableStorage, hciptr2);
  
                          old_HopsAddress[k] =
                              (char *) malloc(StorageTmp->
                                              traceRouteHopsIpTgtAddressLen
                                              + 1);
                          if (old_HopsAddress[k] == NULL) {
                              exit(1);
                          }
                          old_HopsAddress[k] = netsnmp_memdup(
                                                              StorageTmp->traceRouteHopsIpTgtAddress,
                                                              StorageTmp->
                                                              traceRouteHopsIpTgtAddressLen + 1);
                          old_HopsAddress[k][StorageTmp->
                                             traceRouteHopsIpTgtAddressLen]
                              = '\0';
  
                          k++;
                      }
                  }
                  traceRouteHopsTable_del(item);
                  index = 0;
              }
  
              temp = SNMP_MALLOC_STRUCT(traceRouteHopsTable_data);
              temp->traceRouteCtlOwnerIndex =
                  (char *) malloc(item->traceRouteCtlOwnerIndexLen + 1);
              memcpy(temp->traceRouteCtlOwnerIndex,
                     item->traceRouteCtlOwnerIndex,
                     item->traceRouteCtlOwnerIndexLen + 1);
              temp->traceRouteCtlOwnerIndex[item->
                                            traceRouteCtlOwnerIndexLen] =
                  '\0';
              temp->traceRouteCtlOwnerIndexLen =
                  item->traceRouteCtlOwnerIndexLen;
  
              temp->traceRouteCtlTestName =
                  (char *) malloc(item->traceRouteCtlTestNameLen + 1);
              memcpy(temp->traceRouteCtlTestName,
                     item->traceRouteCtlTestName,
                     item->traceRouteCtlTestNameLen + 1);
              temp->traceRouteCtlTestName[item->
                                          traceRouteCtlTestNameLen] =
                  '\0';
              temp->traceRouteCtlTestNameLen =
                  item->traceRouteCtlTestNameLen;
  
              /* add lock to protect */
              pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
              pthread_mutex_lock(&counter_mutex);
              temp->traceRouteHopsHopIndex = ++index;
              pthread_mutex_unlock(&counter_mutex);
              /* endsadsadsad */
  
  
              temp->traceRouteHopsIpTgtAddressType = 0;
              temp->traceRouteHopsIpTgtAddress = strdup("");
              temp->traceRouteHopsIpTgtAddressLen = 0;
              temp->traceRouteHopsMinRtt = 0;
              temp->traceRouteHopsMaxRtt = 0;
              temp->traceRouteHopsAverageRtt = 0;
              temp->traceRouteHopsRttSumOfSquares = 0;
              temp->traceRouteHopsSentProbes = 0;
              temp->traceRouteHopsProbeResponses = 0;
  
              temp->traceRouteHopsLastGoodProbeLen = 0;
              if (index == 1)
                  item->traceRouteHops = temp;
              else {
                  (current_temp)->next = temp;
              }
  
              current_temp = temp;
  
              if (index >= item->traceRouteCtlMaxTtl) {
                  current_temp->next = NULL;
              }
  
              if (item->traceRouteHops != NULL)
  
                  if (traceRouteHopsTable_add(current_temp) !=
                      SNMPERR_SUCCESS)
                      DEBUGMSGTL(("traceRouteHopsTable",
                                  "registered an entry error\n"));
  
          }
  
          unsigned long maxRtt = 0;
          unsigned long minRtt = 0;
          unsigned long averageRtt = 0;
          unsigned long sumRtt = 0;
          unsigned long responseProbe = 0;
          unsigned long sumOfSquare = 0;
          for (probe = 0; probe < nprobes; ++probe) {
              int             cc = 0, reset_timer = 0;
              struct timeval  t1, t2;
              struct timezone tz;
              unsigned long Rtt = 0;
  
              gettimeofday(&t1, &tz);
  
              send_probe_v6(++seq, ttl, sendbuff, ident, &tz, sndsock,
                            datalen, &whereto, hostname);
              reset_timer = 1;
  
              while ((cc =
                      wait_for_reply_v6(icmp_sock, &from, reset_timer,
                                        waittime, icmp_sock,
                                        packet)) != 0) {
                  gettimeofday(&t2, &tz);
                  timep = 0;
                  time(&timep);
                  if ((i =
                       packet_ok_v6(packet, cc, &from, seq, &t1,
                                    ident))) {
                      reset_timer = 1;
                      if (memcmp
                          (&from.sin6_addr, &lastaddr,
                           sizeof(struct in6_addr))) {
  
                          memcpy(&lastaddr,
                                 &from.sin6_addr,
                                 sizeof(struct in6_addr));
                      }
  
                      Rtt = deltaT(&t1, &t2);
                      responseProbe = responseProbe + 1;
                      if (probe == 0) {
                          minRtt = Rtt;
                          maxRtt = Rtt;
                          averageRtt = Rtt;
                          sumRtt = Rtt;
                          sumOfSquare = Rtt * Rtt;
                      } else {
                          if (Rtt < minRtt)
                              minRtt = Rtt;
                          if (Rtt > maxRtt)
                              maxRtt = Rtt;
                          sumRtt = (sumRtt) + Rtt;
                          averageRtt =
                              round((double) (sumRtt) /
                                    (double) responseProbe);
                          sumOfSquare = sumOfSquare + Rtt * Rtt;
                      }
  
                      StorageResults->traceRouteResultsCurProbeCount =
                          probe + 1;
  
  
                      switch (i - 1) {
                      case ICMP6_DST_UNREACH_NOPORT:
                          ++got_there;
                          break;
  
                      case ICMP6_DST_UNREACH_NOROUTE:
                          ++unreachable;
                          Printf(" !N");
                          break;
                      case ICMP6_DST_UNREACH_ADDR:
                          ++unreachable;
                          Printf(" !H");
                          break;
  
                      case ICMP6_DST_UNREACH_ADMIN:
                          ++unreachable;
                          Printf(" !S");
                          break;
                      }
                      break;
                  } else
                      reset_timer = 0;
              }
              if (cc == 0) {
                  timep = 0;
                  time(&timep);
                  Printf(" *");
                  Rtt = (item->traceRouteCtlTimeOut) * 1000;
              }
  
              if (item->traceRouteCtlMaxRows != 0) {
  
                  temp_his =
                      SNMP_MALLOC_STRUCT
                      (traceRouteProbeHistoryTable_data);
                  temp_his->traceRouteCtlOwnerIndex =
                      (char *) malloc(item->traceRouteCtlOwnerIndexLen +
                                      1);
                  memcpy(temp_his->traceRouteCtlOwnerIndex,
                         item->traceRouteCtlOwnerIndex,
                         item->traceRouteCtlOwnerIndexLen + 1);
                  temp_his->traceRouteCtlOwnerIndex[item->
                                                    traceRouteCtlOwnerIndexLen]
                      = '\0';
                  temp_his->traceRouteCtlOwnerIndexLen =
                      item->traceRouteCtlOwnerIndexLen;
  
                  temp_his->traceRouteCtlTestName =
                      (char *) malloc(item->traceRouteCtlTestNameLen +
                                      1);
                  memcpy(temp_his->traceRouteCtlTestName,
                         item->traceRouteCtlTestName,
                         item->traceRouteCtlTestNameLen + 1);
                  temp_his->traceRouteCtlTestName[item->
                                                  traceRouteCtlTestNameLen]
                      = '\0';
                  temp_his->traceRouteCtlTestNameLen =
                      item->traceRouteCtlTestNameLen;
  
                  /* add lock to protect */
                  pthread_mutex_t counter_mutex =
                      PTHREAD_MUTEX_INITIALIZER;
                  pthread_mutex_lock(&counter_mutex);
                  if (item->traceRouteProbeHistoryMaxIndex >=
                      (unsigned long) (2147483647))
                      item->traceRouteProbeHistoryMaxIndex = 0;
                  temp_his->traceRouteProbeHistoryIndex =
                      ++(item->traceRouteProbeHistoryMaxIndex);
                  pthread_mutex_unlock(&counter_mutex);
                  /* endsadsadsad */
                  temp_his->traceRouteProbeHistoryHopIndex = ttl;
                  temp_his->traceRouteProbeHistoryProbeIndex = probe + 1;
  
                  temp_his->traceRouteProbeHistoryHAddrType = 2;
                  temp_his->traceRouteProbeHistoryHAddr =
                      (char *)
                      malloc(strlen
                             (inet_ntop
                              (AF_INET6, &from.sin6_addr, pa, 64)) + 1);
                  temp_his->traceRouteProbeHistoryHAddr =
                      strdup(inet_ntop
                             (AF_INET6, &from.sin6_addr, pa, 64));
                  temp_his->
                      traceRouteProbeHistoryHAddr[strlen
                                                  (inet_ntop
                                                   (AF_INET6,
                                                    &from.sin6_addr, pa,
                                                    64))] = '\0';
                  temp_his->traceRouteProbeHistoryHAddrLen =
                      strlen(inet_ntop
                             (AF_INET6, &from.sin6_addr, pa, 64));
  
                  temp_his->traceRouteProbeHistoryResponse = Rtt;
                  temp_his->traceRouteProbeHistoryStatus = 1;
                  temp_his->traceRouteProbeHistoryLastRC = 0;
  
                  temp_his->traceRouteProbeHistoryTime_time = timep;
                  temp_his->traceRouteProbeHistoryTime = netsnmp_memdup(
                                                                        date_n_time(&timep,
                                                                                    &temp_his->traceRouteProbeHistoryTimeLen), 11);
  
                  if (probe == 0)
                      item->traceRouteProbeHis = temp_his;
                  else {
                      (current_temp_his)->next = temp_his;
                  }
  
                  current_temp_his = temp_his;
  
                  if (probe + 1 >= nprobes) {
                      current_temp_his->next = NULL;
                  }
  
                  if (item->traceRouteProbeHis != NULL) {
                      if (traceRouteProbeHistoryTable_count(item) <
                          item->traceRouteCtlMaxRows) {
                          if (traceRouteProbeHistoryTable_add
                              (current_temp_his) != SNMPERR_SUCCESS)
                              DEBUGMSGTL(("traceRouteProbeHistoryTable",
                                          "registered an entry error\n"));
                      } else {
                          traceRouteProbeHistoryTable_delLast(item);
                          if (traceRouteProbeHistoryTable_add
                              (current_temp_his) != SNMPERR_SUCCESS)
                              DEBUGMSGTL(("traceRouteProbeHistoryTable",
                                          "registered an entry error\n"));
  
                      }
                  }
  
              }
              if (item->traceRouteCtlCreateHopsEntries == 1) {
                  netsnmp_variable_list *vars_hops = NULL;
                  snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen);    /*  traceRouteCtlOwnerIndex  */
                  snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen);        /*  traceRouteCtlTestName  */
                  snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_UNSIGNED, (char *) &index, sizeof(index));       /*  traceRouteHopsIndex  */
                  if ((current =
                       header_complex_get(traceRouteHopsTableStorage,
                                          vars_hops)) == NULL)
                      goto out;
                  current->traceRouteHopsIpTgtAddressType = 2;
                  current->traceRouteHopsIpTgtAddress =
                      (char *)
                      malloc(strlen
                             (inet_ntop
                              (AF_INET6, &from.sin6_addr, pa, 64)) + 1);
                  current->traceRouteHopsIpTgtAddress =
                      strdup(inet_ntop
                             (AF_INET6, &from.sin6_addr, pa, 64));
                  current->
                      traceRouteHopsIpTgtAddress[strlen
                                                 (inet_ntop
                                                  (AF_INET6,
                                                   &from.sin6_addr, pa,
                                                   64))] = '\0';
  
                  if (count != 0) {
                      if (strcmp
                          (old_HopsAddress[index - 1],
                           current->traceRouteHopsIpTgtAddress) != 0)
                          flag = 1;
                  }
  
                  current->traceRouteHopsIpTgtAddressLen =
                      strlen(inet_ntop
                             (AF_INET6, &from.sin6_addr, pa, 64));
                  current->traceRouteHopsMinRtt = minRtt;
                  current->traceRouteHopsMaxRtt = maxRtt;
                  current->traceRouteHopsAverageRtt = averageRtt;
                  current->traceRouteHopsRttSumOfSquares = sumOfSquare;
                  current->traceRouteHopsSentProbes = probe + 1;
                  current->traceRouteHopsProbeResponses = responseProbe;
                  current->traceRouteHopsLastGoodProbe_time = timep;
                  current->traceRouteHopsLastGoodProbe = 
                      netsnmp_memdup(date_n_time(&timep,
                                                 &current->traceRouteHopsLastGoodProbeLen), 11);
  
                  snmp_free_varbind(vars_hops);
                  vars_hops = NULL;
              }
  
  
              (void) fflush(stdout);
          }
          putchar('\n');
  
  
          if (got_there || unreachable >= nprobes - 1) {
  
  
              if (got_there != 0) {
                  StorageResults->traceRouteResultsTestAttempts =
                      StorageResults->traceRouteResultsTestAttempts + 1;
  
                  StorageResults->traceRouteResultsTestSuccesses =
                      StorageResults->traceRouteResultsTestSuccesses + 1;
                  StorageResults->traceRouteResultsLastGoodPath_time = timep;
                  StorageResults->traceRouteResultsLastGoodPath =
                      netsnmp_memdup(date_n_time(&timep,
                                                 &StorageResults->
                                                 traceRouteResultsLastGoodPathLen),
                                     11);
                  if ((item->
                       traceRouteCtlTrapGeneration[0] &
                       TRACEROUTETRAPGENERATION_TESTCOMPLETED) != 0) {
                      printf("TEST completed!\n");
                      send_traceRoute_trap(item, traceRouteTestCompleted,
                                           sizeof
                                           (traceRouteTestCompleted) /
                                           sizeof(oid));
                  }
              }
  
              else {
                  StorageResults->traceRouteResultsTestAttempts =
                      StorageResults->traceRouteResultsTestAttempts + 1;
                  if ((item->
                       traceRouteCtlTrapGeneration[0] &
                       TRACEROUTETRAPGENERATION_TESTFAILED) != 0) {
                      printf("test Failed!\n");
                      send_traceRoute_trap(item, traceRouteTestFailed,
                                           sizeof(traceRouteTestFailed) /
                                           sizeof(oid));
                  }
              }
              break;
  
          } else if (ttl == item->traceRouteCtlMaxTtl
                     && (probe + 1) == nprobes) {
              StorageResults->traceRouteResultsTestAttempts =
                  StorageResults->traceRouteResultsTestAttempts + 1;
  
              if ((item->
                   traceRouteCtlTrapGeneration[0] &
                   TRACEROUTETRAPGENERATION_TESTFAILED) != 0) {
                  printf("test Failed!\n");
                  send_traceRoute_trap(item, traceRouteTestFailed,
                                       sizeof(traceRouteTestFailed) /
                                       sizeof(oid));
              }
          }
  
      }
  
      if (flag == 1) {
          printf("path changed!\n");
          send_traceRoute_trap(item, traceRoutePathChange,
                               sizeof(traceRoutePathChange) /
                               sizeof(oid));
      }
  
  out:
      for (k = 0; k < count; k++)
          free(old_HopsAddress[k]);
  
      free(sendbuff);
      if (sndsock >= 0)
          close(sndsock);
      if (icmp_sock >= 0)
          close(icmp_sock);
      free(hostname);
  }
  
  void
  run_traceRoute(unsigned int clientreg, void *clientarg)
  {
      struct traceRouteCtlTable_data *item = clientarg;
  
      if (item->traceRouteCtlInitialTtl > item->traceRouteCtlMaxTtl) {
          DEBUGMSGTL(("traceRouteCtlTable",
                      "first ttl (%lu) may not be greater than max ttl (%lu)\n",
                      item->traceRouteCtlInitialTtl,
                      item->traceRouteCtlMaxTtl));
          return;
      }
  
      switch (item->traceRouteCtlTargetAddressType) {
      case 1:
      case 16:
          run_traceRoute_ipv4(item);
          break;
      case 2:
          run_traceRoute_ipv6(item);
          break;
      }
  }
  
  int
  wait_for_reply(int sock, struct sockaddr_in *fromp,
                 const struct timeval *tp, u_char * packet,
                 int waittime)
  {
      fd_set          fds;
      struct timeval  now, wait;
      struct timezone tz;
      int    cc = 0;
      socklen_t       fromlen = sizeof(*fromp);
  
      FD_ZERO(&fds);
      FD_SET(sock, &fds);
      wait.tv_sec = tp->tv_sec + waittime;
      wait.tv_usec = tp->tv_usec;
      (void) gettimeofday(&now, &tz);
      tvsub(&wait, &now);
      if (select(sock + 1, &fds, NULL, NULL, &wait) > 0)
          cc = recvfrom(sock, (char *) packet, 512, 0,
                        (struct sockaddr *) fromp, &fromlen);
      return (cc);
  }
  
  
  int
  wait_for_reply_v6(int sock, struct sockaddr_in6 *from, int reset_timer,
                    int waittime, int icmp_sock, u_char * packet)
  {
      fd_set          fds;
      static struct timeval wait;
      int             cc = 0;
      socklen_t       fromlen = sizeof(*from);
  
      FD_ZERO(&fds);
      FD_SET(sock, &fds);
      if (reset_timer) {
          /*
           * traceroute could hang if someone else has a ping
           * running and our ICMP reply gets dropped but we don't
           * realize it because we keep waking up to handle those
           * other ICMP packets that keep coming in.  To fix this,
           * "reset_timer" will only be true if the last packet that
           * came in was for us or if this is the first time we're
           * waiting for a reply since sending out a probe.  Note
           * that this takes advantage of the select() feature on
           * Linux where the remaining timeout is written to the
           * struct timeval area.
           */
          wait.tv_sec = waittime;
          wait.tv_usec = 0;
      }
  
      if (select(sock + 1, &fds, (fd_set *) 0, (fd_set *) 0, &wait) > 0) {
          cc = recvfrom(icmp_sock, (char *) packet, 512, 0,
                        (struct sockaddr *) from, &fromlen);
      }
  
      return (cc);
  }
  
  /*
   * send_probe() uses the BSD-ish udpiphdr.
   * Define something that looks enough like it to work.
   */
  struct udpiphdr {
     struct iphdr ui_i;
     struct udphdr ui_u;
  };
  #define ui_src ui_i.saddr
  #define ui_dst ui_i.daddr
  #define ui_pr ui_i.protocol
  #define ui_len ui_i.tot_len
  
  void
  send_probe(struct sockaddr_in *whereto, int seq, int ttl,
             struct timeval *tp, struct ip *outip,
             struct udphdr *outudp, int packlen, int optlen,
             char *hostname, u_short ident, int sndsock, u_short port,
             struct outdata *outdata)
  {
      int    cc = 0;
      struct udpiphdr *ui = NULL, *oui = NULL;
      struct ip       tip;
  
      outip->ip_ttl = ttl;
  #ifndef __hpux
      outip->ip_id = htons(ident + seq);
  #endif
  
      /*
       * In most cases, the kernel will recalculate the ip checksum.
       * But we must do it anyway so that the udp checksum comes out
       * right.
       */
  
      outip->ip_sum =
          in_checksum((u_short *) outip, sizeof(*outip) + optlen);
      if (outip->ip_sum == 0)
          outip->ip_sum = 0xffff;
  
  
      /*
       * Payload 
       */
      outdata->seq = seq;
      outdata->ttl = ttl;
      outdata->tv = *tp;
  
  
      outudp->dest = htons(port + seq);
  
  
      /*
       * Checksum (we must save and restore ip header) 
       */
      tip = *outip;
      ui = (struct udpiphdr *) outip;
      oui = (struct udpiphdr *) &tip;
      /*
       * Easier to zero and put back things that are ok 
       */
      memset((char *) ui, 0, sizeof(ui->ui_i));
      ui->ui_src = oui->ui_src;
      ui->ui_dst = oui->ui_dst;
      ui->ui_pr = oui->ui_pr;
      ui->ui_len = outudp->len;
      outudp->check = 0;
      outudp->check = in_checksum((u_short *) ui, packlen);
      if (outudp->check == 0)
          outudp->check = 0xffff;
      *outip = tip;
  
  
      /*
       * XXX undocumented debugging hack 
       */
  
  
  #if !defined(IP_HDRINCL) && defined(IP_TTL)
      printf("ttl\n");
      if (setsockopt(sndsock, IPPROTO_IP, IP_TTL,
                     (char *) &ttl, sizeof(ttl)) < 0) {
          Fprintf(stderr, "%s: setsockopt ttl %d: %s\n",
                  "traceroute", ttl, strerror(errno));
          exit(1);
      }
  #endif
  
  #ifdef __hpux
  
      Printf("whereto=%s\n",
             inet_ntoa(((struct sockaddr_in *) whereto)->sin_addr));
      cc = sendto(sndsock, (char *) outudp,
                  packlen - (sizeof(*outip) + optlen), 0, whereto,
                  sizeof(*whereto));
      if (cc > 0)
          cc += sizeof(*outip) + optlen;
  #else
  
      cc = sendto(sndsock, (char *) outip,
                  packlen, 0, (void *)whereto, sizeof(*whereto));
  #endif
      if (cc < 0 || cc != packlen) {
          if (cc < 0)
              Fprintf(stderr, "%s: sendto: %s\n", "traceroute", strerror(errno));
          Printf("%s: wrote %s %d chars, ret=%d\n",
                 "traceroute", hostname, packlen, cc);
          (void) fflush(stdout);
      }
  }
  
  
  
  void
  send_probe_v6(int seq, int ttl, char *sendbuff, pid_t ident,
                struct timezone *tz, int sndsock, int datalen,
                struct sockaddr_in6 *whereto, char *hostname)
  {
      struct pkt_format *pkt = (struct pkt_format *) sendbuff;
      int             i = 0;
  
      pkt->ident = htonl(ident);
      pkt->seq = htonl(seq);
      gettimeofday(&pkt->tv, tz);
  
      i = setsockopt(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, &ttl,
                     sizeof(int));
      if (i < 0) {
          perror("setsockopt");
          exit(1);
      }
  
      do {
          i = sendto(sndsock, sendbuff, datalen, 0,
                     (struct sockaddr *) whereto,
                     sizeof(struct sockaddr_in6));
      } while (i < 0 && errno == ECONNREFUSED);
  
      if (i < 0 || i != datalen) {
          if (i < 0)
              perror("sendto");
          Printf("traceroute: wrote %s %d chars, ret=%d\n", hostname,
                 datalen, i);
          (void) fflush(stdout);
      }
  }
  
  
  unsigned long
  deltaT(struct timeval *t1p, struct timeval *t2p)
  {
      unsigned long dt;
  
      dt = (unsigned long) ((long) (t2p->tv_sec - t1p->tv_sec) * 1000 +
                            (long) (t2p->tv_usec - t1p->tv_usec) / 1000);
      return (dt);
  }
  
  
  int
  packet_ok(u_char * buf, int cc, struct sockaddr_in *from,
            int seq, u_short ident, int pmtu NETSNMP_ATTRIBUTE_UNUSED,
            u_short port)
  {
      struct icmp *icp = NULL;
      u_char type, code;
      int    hlen = 0;
  #ifndef ARCHAIC
      struct ip *ip = NULL;
  
      ip = (struct ip *) buf;
      hlen = ip->ip_hl << 2;
      if (cc < hlen + ICMP_MINLEN) {
  
          return (0);
      }
      cc -= hlen;
      icp = (struct icmp *) (buf + hlen);
  #else
      icp = (struct icmp *) buf;
  #endif
      type = icp->icmp_type;
      code = icp->icmp_code;
      /*
       * Path MTU Discovery (RFC1191) 
       */
  #if 0
      if (code != ICMP_UNREACH_NEEDFRAG)
          pmtu = 0;
      else {
  #ifdef HAVE_ICMP_NEXTMTU
          pmtu = ntohs(icp->icmp_nextmtu);
  #else
          pmtu = ntohs(((struct my_pmtu *) &icp->icmp_void)->ipm_nextmtu);
  #endif
      }
  #endif
      if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
          type == ICMP_UNREACH || type == ICMP_ECHOREPLY) {
          struct ip *hip;
          struct udphdr *up;
  
          if(cc < offsetof(struct icmp, icmp_ip) + sizeof(icp->icmp_ip)) {
              return (0);
          }
  
          hip = &icp->icmp_ip;
          hlen = hip->ip_hl << 2;
          up = (struct udphdr *) ((u_char *) hip + hlen);
          /*
           * XXX 8 is a magic number 
           */
          if (hlen + 12 <= cc &&
              hip->ip_p == IPPROTO_UDP &&
              up->source == htons(ident) && up->dest == htons(port + seq))
              return (type == ICMP_TIMXCEED ? -1 : code + 1);
      }
  
  
      return (0);
  }
  
  
  
  
  int
  packet_ok_v6(u_char * buf, int cc, struct sockaddr_in6 *from, int seq,
               struct timeval *tv, pid_t ident)
  {
      struct icmp6_hdr *icp = NULL;
      u_char          type, code;
  
      if(cc < sizeof(struct icmp6_hdr))
          return 0;
  
      icp = (struct icmp6_hdr *) buf;
  
      type = icp->icmp6_type;
      code = icp->icmp6_code;
  
      if ((type == ICMP6_TIME_EXCEEDED && code == ICMP6_TIME_EXCEED_TRANSIT) ||
          type == ICMP6_DST_UNREACH) {
          struct ip6_hdr  *hip = NULL;
          struct udphdr  *up = NULL;
          int             nexthdr = 0;
  
          hip = (struct ip6_hdr *) (icp + 1);
          up = (struct udphdr *) (hip + 1);
          nexthdr = hip->ip6_nxt;
  
          if (nexthdr == 44) {
              nexthdr = *(unsigned char *) up;
              up++;
          }
          if (nexthdr == IPPROTO_UDP) {
              struct pkt_format *pkt;
  
              pkt = (struct pkt_format *) (up + 1);
  
              if (ntohl(pkt->ident) == ident && ntohl(pkt->seq) == seq) {
                  *tv = pkt->tv;
                  return (type == ICMP6_TIME_EXCEEDED ? -1 : code + 1);
              }
          }
  
      }
  
      return (0);
  }
  
  
  /*
   * Checksum routine for Internet Protocol family headers (C Version)
   */
  
  u_short
  in_checksum(u_short * addr, int len)
  {
      int    nleft = len;
      u_short *w = addr;
      u_short answer;
      int    sum = 0;
  
      /*
       *  Our algorithm is simple, using a 32 bit accumulator (sum),
       *  we add sequential 16 bit words to it, and at the end, fold
       *  back all the carry bits from the top 16 bits into the lower
       *  16 bits.
       */
      while (nleft > 1) {
          sum += *w++;
          nleft -= 2;
      }
  
      /*
       * mop up an odd byte, if necessary 
       */
      if (nleft == 1)
          sum += *(u_char *) w;
  
      /*
       * add back carry outs from top 16 bits to low 16 bits
       */
      sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
      sum += (sum >> 16);         /* add carry */
      answer = ~sum;              /* truncate to 16 bits */
      return (answer);
  }
  
  /*
   * Subtract 2 timeval structs:  out = out - in.
   * Out is assumed to be >= in.
   */
  void
  tvsub(struct timeval *out, struct timeval *in)
  {
  
      if ((out->tv_usec -= in->tv_usec) < 0) {
          --out->tv_sec;
          out->tv_usec += 1000000;
      }
      out->tv_sec -= in->tv_sec;
  }
  
  
  struct hostinfo *
  gethostinfo(char *hostname)
  {
      int    n;
      struct hostent *hp = NULL;
      struct hostinfo *hi = NULL;
      char **p = NULL;
      u_int32_t addr, *ap = NULL;
  
      if (strlen(hostname) > 64) {
          Fprintf(stderr, "%s: hostname \"%.32s...\" is too long\n",
                  "traceroute", hostname);
          exit(1);
      }
      hi = calloc(1, sizeof(*hi));
      if (hi == NULL) {
          Fprintf(stderr, "%s: calloc %s\n", "traceroute", strerror(errno));
          exit(1);
      }
      addr = inet_addr(hostname);
      if ((int32_t) addr != -1) {
          hi->name = strdup(hostname);
          hi->n = 1;
          hi->addrs = calloc(1, sizeof(hi->addrs[0]));
          if (hi->addrs == NULL) {
              Fprintf(stderr, "%s: calloc %s\n", "traceroute", strerror(errno));
              exit(1);
          }
          hi->addrs[0] = addr;
          return (hi);
      }
  
      hp = netsnmp_gethostbyname(hostname);
      if (hp == NULL) {
          Fprintf(stderr, "%s: unknown host %s\n", "traceroute", hostname);
          printf("hp=NULL\n");
          exit(1);
      }
      if (hp->h_addrtype != AF_INET || hp->h_length != 4) {
          Fprintf(stderr, "%s: bad host %s\n", "traceroute", hostname);
          exit(1);
      }
      hi->name = strdup(hp->h_name);
      for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
          continue;
      hi->n = n;
      hi->addrs = calloc(n, sizeof(hi->addrs[0]));
      if (hi->addrs == NULL) {
          Fprintf(stderr, "%s: calloc %s\n", "traceroute", strerror(errno));
          exit(1);
      }
      for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
          memcpy(ap, *p, sizeof(*ap));
      return (hi);
  }
  
  void
  freehostinfo(struct hostinfo *hi)
  {
      if (hi->name != NULL) {
          free(hi->name);
          hi->name = NULL;
      }
      free((char *) hi->addrs);
      free((char *) hi);
  }
  
  void
  setsin(struct sockaddr_in *sin, u_int32_t addr)
  {
  
      memset(sin, 0, sizeof(*sin));
  #ifdef HAVE_SOCKADDR_SA_LEN
      sin->sin_len = sizeof(*sin);
  #endif
      sin->sin_family = AF_INET;
      sin->sin_addr.s_addr = addr;
  }
  
  
  /*
   * Return the source address for the given destination address
   */
  static char *
  findsaddr(const struct sockaddr_in *to,
            struct sockaddr_in *from)
  {
      int    i, n;
      FILE  *f;
      u_int32_t mask;
      u_int32_t       dest, tmask;
      struct ifaddrlist *al;
      char            buf[256], tdevice[256], device[256];
      char            *errbuf = NULL;
      static const char route[] = "/proc/net/route";
  
      if ((f = fopen(route, "r")) == NULL) {
          if (asprintf(&errbuf, "open %s: %s", route, strerror(errno)) < 0)
              snmp_log(LOG_ERR, "error buffer allocation failed\n");
          return errbuf;
      }
  
      /*
       * Find the appropriate interface 
       */
      n = 0;
      mask = 0;
      device[0] = '\0';
      while (fgets(buf, sizeof(buf), f) != NULL) {
          ++n;
          if (n == 1 && strncmp(buf, "Iface", 5) == 0)
              continue;
          if ((i = sscanf(buf, "%s %x %*s %*s %*s %*s %*s %x",
                          tdevice, &dest, &tmask)) != 3) {
              fclose(f);
              return strdup("junk in buffer");
          }
          if ((to->sin_addr.s_addr & tmask) == dest &&
              (tmask > mask || mask == 0)) {
              mask = tmask;
              strcpy(device, tdevice);
          }
      }
      fclose(f);
  
      if (device[0] == '\0')
          return strdup("Can't find interface");
  
      /*
       * Get the interface address list 
       */
      if ((n = ifaddrlist(&al, errbuf)) < 0)
          return (errbuf);
  
      if (n == 0)
          return strdup("Can't find any network interfaces");
  
      /*
       * Find our appropriate source address 
       */
      for (i = n; i > 0; --i, ++al)
          if (strcmp(device, al->device) == 0)
              break;
      if (i <= 0) {
          sprintf(errbuf, "Can't find interface \"%.32s\"", device);
          return (errbuf);
      }
  
      setsin(from, al->addr);
      return (NULL);
  }
  
  int
  ifaddrlist(struct ifaddrlist **ipaddrp, char *errbuf)
  {
      int    fd, nipaddr;
  #ifdef HAVE_SOCKADDR_SA_LEN
      int    n;
  #endif
      struct ifreq *ifrp, *ifend, *ifnext;
      struct sockaddr_in *sin;
      struct ifaddrlist *al;
      struct ifconf   ifc;
      struct ifreq    ibuf[(32 * 1024) / sizeof(struct ifreq)], ifr;
  #define MAX_IPADDR (sizeof(ibuf) / sizeof(ibuf[0]))
      static struct ifaddrlist ifaddrlist[MAX_IPADDR];
      char            device[sizeof(ifr.ifr_name) + 1];
  
      fd = socket(AF_INET, SOCK_DGRAM, 0);
      if (fd < 0) {
          (void) sprintf(errbuf, "socket: %s", strerror(errno));
          return (-1);
      }
      ifc.ifc_len = sizeof(ibuf);
      ifc.ifc_buf = (caddr_t) ibuf;
  
      if (ioctl(fd, SIOCGIFCONF, (char *) &ifc) < 0 ||
          ifc.ifc_len < sizeof(struct ifreq)) {
          if (errno == EINVAL)
              (void) sprintf(errbuf,
                             "SIOCGIFCONF: ifreq struct too small (%d bytes)",
                             (int)sizeof(ibuf));
          else
              (void) sprintf(errbuf, "SIOCGIFCONF: %s", strerror(errno));
          (void) close(fd);
          return (-1);
      }
      ifrp = ibuf;
      ifend = (struct ifreq *) ((char *) ibuf + ifc.ifc_len);
  
      al = ifaddrlist;
      nipaddr = 0;
      for (; ifrp < ifend; ifrp = ifnext) {
  #ifdef HAVE_SOCKADDR_SA_LEN
          n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
          if (n < sizeof(*ifrp))
              ifnext = ifrp + 1;
          else
              ifnext = (struct ifreq *) ((char *) ifrp + n);
          if (ifrp->ifr_addr.sa_family != AF_INET)
              continue;
  #else
          ifnext = ifrp + 1;
  #endif
          /*
           * Need a template to preserve address info that is
           * used below to locate the next entry.  (Otherwise,
           * SIOCGIFFLAGS stomps over it because the requests
           * are returned in a union.)
           */
          strlcpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name));
          if (ioctl(fd, SIOCGIFFLAGS, (char *) &ifr) < 0) {
              if (errno == ENXIO)
                  continue;
              (void) sprintf(errbuf, "SIOCGIFFLAGS: %.*s: %s",
                             (int) sizeof(ifr.ifr_name), ifr.ifr_name,
                             strerror(errno));
              (void) close(fd);
              return (-1);
          }
  
          /*
           * Must be up 
           */
          if ((ifr.ifr_flags & IFF_UP) == 0)
              continue;
  
          sprintf(device, "%.*s", (int) sizeof(ifr.ifr_name), ifr.ifr_name);
  #ifdef sun
          /*
           * Ignore sun virtual interfaces 
           */
          if (strchr(device, ':') != NULL)
              continue;
  #endif
          if (ioctl(fd, SIOCGIFADDR, (char *) &ifr) < 0) {
              (void) sprintf(errbuf, "SIOCGIFADDR: %s: %s",
                             device, strerror(errno));
              (void) close(fd);
              return (-1);
          }
  
          if (nipaddr >= MAX_IPADDR) {
              (void) sprintf(errbuf, "Too many interfaces (%d)", nipaddr);
              (void) close(fd);
              return (-1);
          }
          sin = (struct sockaddr_in *) &ifr.ifr_addr;
          al->addr = sin->sin_addr.s_addr;
          al->device = strdup(device);
          ++al;
          ++nipaddr;
      }
      (void) close(fd);
  
      *ipaddrp = ifaddrlist;
      return (nipaddr);
  }
  