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

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  *Copyright(c)2004,Cisco URP imburses and Network Information Center in Beijing University of Posts and Telecommunications researches.
  3.  *
  4.  *All right reserved
  5.  *
  6.  *File Name:pingCtlTable.c
  7.  *File Description:Rows of the pingCtlTable MIB add , delete and read.Rows of lookupResultsTable
  8.  *              MIB add and delete.Rows of pingProbeHistoryTable MIB add and delete. 
  9.  *              The main function is also here.
  10.  *
  11.  *Current Version:1.0
  12.  *Author:ChenJing
  13.  *Date:2004.8.20
  14.  */
  15. /*
  16.  * This should always be included first before anything else 
  17.  */
  18. #if HAVE_STDLIB_H
  19. #include <stdlib.h>
  20. #endif
  21. #if HAVE_STRING_H
  22. #include <string.h>
  23. #else
  24. #include <strings.h>
  25. #endif
  26. #ifdef HAVE_LIMITS_H
  27. #include <limits.h>
  28. #endif
  29. #include <netdb.h>
  30. #include <netinet/in.h>
  31. #include <sys/types.h>
  32. #include <sys/socket.h>
  33. #include <arpa/inet.h>
  34. #include <net-snmp/net-snmp-config.h>
  35. #include <net-snmp/net-snmp-includes.h>
  36. #include <net-snmp/agent/net-snmp-agent-includes.h>
  37. #include "pingCtlTable.h"
  38. #include "pingResultsTable.h"
  39. #include "pingProbeHistoryTable.h"
  40. #include "header_complex.h"
  41. /*
  42.  *pingCtlTable_variables_oid:
  43.  *                                                      
  44.  */
  45. oid             pingCtlTable_variables_oid[] =
  46.     { 1, 3, 6, 1, 2, 1, 80, 1, 2 };
  47. /* trap */
  48. oid             pingProbeFailed[] = { 1, 3, 6, 1, 2, 1, 80, 0, 1 };
  49. oid             pingTestFailed[] = { 1, 3, 6, 1, 2, 1, 80, 0, 2 };
  50. oid             pingTestCompleted[] = { 1, 3, 6, 1, 2, 1, 80, 0, 3 };
  51. struct variable2 pingCtlTable_variables[] = {
  52.     /*
  53.      * magic number        , variable type , ro/rw , callback fn  , L, oidsuffix 
  54.      */
  55.     {COLUMN_PINGCTLTARGETADDRESSTYPE, ASN_INTEGER, RWRITE, var_pingCtlTable, 2, {1, 3}},
  56.     {COLUMN_PINGCTLTARGETADDRESS,   ASN_OCTET_STR, RWRITE, var_pingCtlTable, 2, {1, 4}},
  57.     {COLUMN_PINGCTLDATASIZE,         ASN_UNSIGNED, RONLY, var_pingCtlTable, 2, {1, 5}},
  58.     {COLUMN_PINGCTLTIMEOUT,          ASN_UNSIGNED, RONLY, var_pingCtlTable, 2, {1, 6}},
  59.     {COLUMN_PINGCTLPROBECOUNT,       ASN_UNSIGNED, RONLY, var_pingCtlTable, 2, {1, 7}},
  60.     {COLUMN_PINGCTLADMINSTATUS,       ASN_INTEGER, RWRITE, var_pingCtlTable, 2, {1, 8}},
  61.     {COLUMN_PINGCTLDATAFILL,        ASN_OCTET_STR, RWRITE, var_pingCtlTable, 2, {1, 9}},
  62.     {COLUMN_PINGCTLFREQUENCY,        ASN_UNSIGNED, RWRITE, var_pingCtlTable, 2, {1, 10}},
  63.     {COLUMN_PINGCTLMAXROWS,          ASN_UNSIGNED, RWRITE, var_pingCtlTable, 2, {1, 11}},
  64.     {COLUMN_PINGCTLSTORAGETYPE,       ASN_INTEGER, RWRITE, var_pingCtlTable, 2, {1, 12}},
  65.     {COLUMN_PINGCTLTRAPGENERATION,  ASN_OCTET_STR, RWRITE, var_pingCtlTable, 2, {1, 13}},
  66.     {COLUMN_PINGCTLTRAPPROBEFAILUREFILTER, ASN_UNSIGNED, RWRITE, var_pingCtlTable, 2, {1, 14}},
  67.     {COLUMN_PINGCTLTRAPTESTFAILUREFILTER,  ASN_UNSIGNED, RWRITE, var_pingCtlTable, 2, {1, 15}},
  68.     {COLUMN_PINGCTLTYPE,            ASN_OBJECT_ID, RWRITE, var_pingCtlTable, 2, {1, 16}},
  69.     {COLUMN_PINGCTLDESCR,           ASN_OCTET_STR, RWRITE, var_pingCtlTable, 2, {1, 17}},
  70.     {COLUMN_PINGCTLSOURCEADDRESSTYPE, ASN_INTEGER, RWRITE, var_pingCtlTable, 2, {1, 18}},
  71.     {COLUMN_PINGCTLSOURCEADDRESS,   ASN_OCTET_STR, RWRITE, var_pingCtlTable, 2, {1, 19}},
  72.     {COLUMN_PINGCTLIFINDEX,           ASN_INTEGER, RWRITE, var_pingCtlTable, 2, {1, 20}},
  73.     {COLUMN_PINGCTLBYPASSROUTETABLE,  ASN_INTEGER, RWRITE, var_pingCtlTable, 2, {1, 21}},
  74.     {COLUMN_PINGCTLDSFIELD,          ASN_UNSIGNED, RWRITE, var_pingCtlTable, 2, {1, 22}},
  75.     {COLUMN_PINGCTLROWSTATUS,         ASN_INTEGER, RWRITE, var_pingCtlTable, 2, {1, 23}}
  76. };
  77. /*
  78.  * global storage of our data, saved in and configured by header_complex() 
  79.  */
  80. struct header_complex_index *pingCtlTableStorage = NULL;
  81. struct header_complex_index *pingResultsTableStorage = NULL;
  82. struct header_complex_index *pingProbeHistoryTableStorage = NULL;
  83. void
  84. init_pingCtlTable(void)
  85. {
  86.     DEBUGMSGTL(("pingCtlTable", "initializing...  "));
  87.     /*
  88.      * register ourselves with the agent to handle our mib tree 
  89.      */
  90.     REGISTER_MIB("pingCtlTable", pingCtlTable_variables, variable2,
  91.                  pingCtlTable_variables_oid);
  92.     /*
  93.      * register our config handler(s) to deal with registrations 
  94.      */
  95.     snmpd_register_config_handler("pingCtlTable", parse_pingCtlTable,
  96.                                   NULL, NULL);
  97.     /*
  98.      * we need to be called back later to store our data 
  99.      */
  100.     snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
  101.                            store_pingCtlTable, NULL);
  102.     DEBUGMSGTL(("pingCtlTable", "done.n"));
  103. }
  104. struct pingCtlTable_data *
  105. create_pingCtlTable_data(void)
  106. {
  107.     struct pingCtlTable_data *StorageNew = NULL;
  108.     StorageNew = SNMP_MALLOC_STRUCT(pingCtlTable_data);
  109.     if (StorageNew == NULL) {
  110.         exit(1);
  111.     }
  112.     StorageNew->pingCtlTargetAddressType = 1;
  113.     StorageNew->pingCtlTargetAddress = strdup("");
  114.     StorageNew->pingCtlTargetAddressLen = 0;
  115.     StorageNew->pingCtlDataSize = 0;
  116.     StorageNew->pingCtlTimeOut = 3;
  117.     StorageNew->pingCtlProbeCount = 1;
  118.     StorageNew->pingCtlAdminStatus = 2;
  119.     StorageNew->pingCtlDataFill = (char *) malloc(strlen("00") + 1);
  120.     if (StorageNew->pingCtlDataFill == NULL) {
  121.         exit(1);
  122.     }
  123.     memcpy(StorageNew->pingCtlDataFill, "00", strlen("00") + 1);
  124.     StorageNew->pingCtlDataFill[strlen("00")] = '';
  125.     StorageNew->pingCtlDataFillLen = strlen(StorageNew->pingCtlDataFill);
  126.     StorageNew->pingCtlFrequency = 0;
  127.     StorageNew->pingCtlMaxRows = 50;
  128.     StorageNew->pingCtlStorageType = 1;
  129.     StorageNew->pingCtlTrapGeneration = strdup("");
  130.     StorageNew->pingCtlTrapGenerationLen = 0;
  131.     StorageNew->pingCtlTrapGenerationLen = 0;
  132.     StorageNew->pingCtlTrapProbeFailureFilter = 1;
  133.     StorageNew->pingCtlTrapTestFailureFilter = 1;
  134.     StorageNew->pingCtlType = calloc(1, sizeof(oid) * sizeof(2));       /* 0.0 */
  135.     StorageNew->pingCtlTypeLen = 2;
  136.     StorageNew->pingCtlDescr = strdup("");
  137.     StorageNew->pingCtlDescrLen = 0;
  138.     StorageNew->pingCtlSourceAddressType = 1;
  139.     StorageNew->pingCtlSourceAddress = strdup("");
  140.     StorageNew->pingCtlSourceAddressLen = 0;
  141.     StorageNew->pingCtlIfIndex = 0;
  142.     StorageNew->pingCtlByPassRouteTable = 2;
  143.     StorageNew->pingCtlDSField = 0;
  144.     StorageNew->pingResults = NULL;
  145.     StorageNew->pingProbeHis = NULL;
  146.     StorageNew->storageType = ST_NONVOLATILE;
  147.     StorageNew->pingProbeHistoryMaxIndex = 0;
  148.     return StorageNew;
  149. }
  150. /*
  151.  * pingCtlTable_add(): adds a structure node to our data set 
  152.  */
  153. int
  154. pingCtlTable_add(struct pingCtlTable_data *thedata)
  155. {
  156.     netsnmp_variable_list *vars = NULL;
  157.     DEBUGMSGTL(("pingCtlTable", "adding data...  "));
  158.     /*
  159.      * add the index variables to the varbind list, which is 
  160.      * used by header_complex to index the data 
  161.      */
  162.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->pingCtlOwnerIndex, thedata->pingCtlOwnerIndexLen);       /* pingCtlOwnerIndex */
  163.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->pingCtlTestName, thedata->pingCtlTestNameLen);   /* pingCtlOperationName */
  164.     header_complex_add_data(&pingCtlTableStorage, vars, thedata);
  165.     DEBUGMSGTL(("pingCtlTable", "registered an entryn"));
  166.     vars = NULL;
  167.     DEBUGMSGTL(("pingCtlTable", "done.n"));
  168.     return SNMPERR_SUCCESS;
  169. }
  170. int
  171. pingResultsTable_add(struct pingCtlTable_data *thedata)
  172. {
  173.     netsnmp_variable_list *vars_list = NULL;
  174.     struct pingResultsTable_data *p = NULL;
  175.     p = thedata->pingResults;
  176.     if (thedata->pingResults != NULL) {
  177.         snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) p->pingCtlOwnerIndex, p->pingCtlOwnerIndexLen);  /* pingCtlOwnerIndex */
  178.         snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) p->pingCtlTestName, p->pingCtlTestNameLen);      /* pingCtlOperationName */
  179.         /*
  180.          * XXX: fill in default row values here into StorageNew 
  181.          * 
  182.          */
  183.         DEBUGMSGTL(("pingResultsTable", "adding data...  "));
  184.         /*
  185.          * add the index variables to the varbind list, which is 
  186.          * used by header_complex to index the data 
  187.          */
  188.         header_complex_add_data(&pingResultsTableStorage, vars_list, p);
  189.         DEBUGMSGTL(("pingResultsTable", "out finishedn"));
  190.     }
  191.     DEBUGMSGTL(("pingResultsTable", "done.n"));
  192.     vars_list = NULL;
  193.     return SNMPERR_SUCCESS;
  194. }
  195. int
  196. pingProbeHistoryTable_add(struct pingProbeHistoryTable_data *thedata)
  197. {
  198.     netsnmp_variable_list *vars_list;
  199.     vars_list = NULL;
  200.     if (thedata != NULL) {
  201.         snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) thedata->pingCtlOwnerIndex, thedata->pingCtlOwnerIndexLen);      /* pingCtlOwnerIndex */
  202.         snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) thedata->pingCtlTestName, thedata->pingCtlTestNameLen);  /* pingCtlTestName */
  203.         snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &thedata->pingProbeHistoryIndex, sizeof(thedata->pingProbeHistoryIndex)); /* pingProbeHistoryIndex */
  204.         /*
  205.          * XXX: fill in default row values here into StorageNew 
  206.          * 
  207.          */
  208.         DEBUGMSGTL(("pingProbeHistoryTable", "adding data...  "));
  209.         /*
  210.          * add the index variables to the varbind list, which is 
  211.          * used by header_complex to index the data 
  212.          */
  213.         header_complex_add_data(&pingProbeHistoryTableStorage, vars_list,
  214.                                 thedata);
  215.         DEBUGMSGTL(("pingProbeHistoryTable", "out finishedn"));
  216.     }
  217.     
  218.     vars_list = NULL;
  219.     DEBUGMSGTL(("pingProbeHistoryTable", "done.n"));
  220.     return SNMPERR_SUCCESS;
  221. }
  222. int
  223. pingProbeHistoryTable_addall(struct pingCtlTable_data *thedata)
  224. {
  225.     netsnmp_variable_list *vars_list = NULL;
  226.     struct pingProbeHistoryTable_data *p = NULL;
  227.     p = thedata->pingProbeHis;
  228.     if (thedata->pingProbeHis != NULL)
  229.         do {
  230.             snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) p->pingCtlOwnerIndex, p->pingCtlOwnerIndexLen);      /* pingCtlOwnerIndex */
  231.             snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) p->pingCtlTestName, p->pingCtlTestNameLen);  /* pingCtlTestName */
  232.             snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &p->pingProbeHistoryIndex, sizeof(p->pingProbeHistoryIndex)); /* pingProbeHistoryIndex */
  233.             /*
  234.              * XXX: fill in default row values here into StorageNew 
  235.              * 
  236.              */
  237.             DEBUGMSGTL(("pingProbeHistoryTable", "adding data...  "));
  238.             /*
  239.              * add the index variables to the varbind list, which is 
  240.              * used by header_complex to index the data 
  241.              */
  242.             header_complex_add_data(&pingProbeHistoryTableStorage,
  243.                                     vars_list, p);
  244.             DEBUGMSGTL(("pingProbeHistoryTable", "out finishedn"));
  245.             vars_list = NULL;
  246.             p = p->next;
  247.         } while (p != NULL);
  248.     DEBUGMSGTL(("pingProbeHistoryTable", "done.n"));
  249.     return SNMPERR_SUCCESS;
  250. }
  251. void
  252. pingCtlTable_cleaner(struct header_complex_index *thestuff)
  253. {
  254.     struct header_complex_index *hciptr = NULL;
  255.     struct pingCtlTable_data *StorageDel = NULL;
  256.     DEBUGMSGTL(("pingProbeHistoryTable", "cleanerout  "));
  257.     for (hciptr = thestuff; hciptr != NULL; hciptr = hciptr->next) {
  258.         StorageDel =
  259.             header_complex_extract_entry(&pingCtlTableStorage, hciptr);
  260.         DEBUGMSGTL(("pingProbeHistoryTable", "cleaner  "));
  261.     }
  262. }
  263. /*
  264.  * parse_mteObjectsTable():
  265.  *   parses .conf file entries needed to configure the mib.
  266.  */
  267. void
  268. parse_pingCtlTable(const char *token, char *line)
  269. {
  270.     size_t          tmpint;
  271.     struct pingCtlTable_data *StorageTmp =
  272.         SNMP_MALLOC_STRUCT(pingCtlTable_data);
  273.     DEBUGMSGTL(("pingCtlTable", "parsing config...  "));
  274.     if (StorageTmp == NULL) {
  275.         config_perror("malloc failure");
  276.         return;
  277.     }
  278.     line =
  279.         read_config_read_data(ASN_OCTET_STR, line,
  280.                               &StorageTmp->pingCtlOwnerIndex,
  281.                               &StorageTmp->pingCtlOwnerIndexLen);
  282.     if (StorageTmp->pingCtlOwnerIndex == NULL) {
  283.         config_perror("invalid specification for pingCtlOwnerIndex");
  284.         return;
  285.     }
  286.     line =
  287.         read_config_read_data(ASN_OCTET_STR, line,
  288.                               &StorageTmp->pingCtlTestName,
  289.                               &StorageTmp->pingCtlTestNameLen);
  290.     if (StorageTmp->pingCtlTestName == NULL) {
  291.         config_perror("invalid specification for pingCtlTestName");
  292.         return;
  293.     }
  294.     line =
  295.         read_config_read_data(ASN_INTEGER, line,
  296.                               &StorageTmp->pingCtlTargetAddressType,
  297.                               &tmpint);
  298.     line =
  299.         read_config_read_data(ASN_OCTET_STR, line,
  300.                               &StorageTmp->pingCtlTargetAddress,
  301.                               &StorageTmp->pingCtlTargetAddressLen);
  302.     if (StorageTmp->pingCtlTargetAddress == NULL) {
  303.         config_perror("invalid specification for pingCtlTargetAddress");
  304.         return;
  305.     }
  306.     line =
  307.         read_config_read_data(ASN_UNSIGNED, line,
  308.                               &StorageTmp->pingCtlDataSize, &tmpint);
  309.     line =
  310.         read_config_read_data(ASN_UNSIGNED, line,
  311.                               &StorageTmp->pingCtlTimeOut, &tmpint);
  312.     line =
  313.         read_config_read_data(ASN_UNSIGNED, line,
  314.                               &StorageTmp->pingCtlProbeCount, &tmpint);
  315.     line =
  316.         read_config_read_data(ASN_INTEGER, line,
  317.                               &StorageTmp->pingCtlAdminStatus, &tmpint);
  318.     line =
  319.         read_config_read_data(ASN_OCTET_STR, line,
  320.                               &StorageTmp->pingCtlDataFill,
  321.                               &StorageTmp->pingCtlDataFillLen);
  322.     if (StorageTmp->pingCtlDataFill == NULL) {
  323.         config_perror("invalid specification for pingCtlDataFill");
  324.         return;
  325.     }
  326.     line =
  327.         read_config_read_data(ASN_UNSIGNED, line,
  328.                               &StorageTmp->pingCtlFrequency, &tmpint);
  329.     line =
  330.         read_config_read_data(ASN_UNSIGNED, line,
  331.                               &StorageTmp->pingCtlMaxRows, &tmpint);
  332.     line =
  333.         read_config_read_data(ASN_INTEGER, line,
  334.                               &StorageTmp->pingCtlStorageType, &tmpint);
  335.     line =
  336.         read_config_read_data(ASN_OCTET_STR, line,
  337.                               &StorageTmp->pingCtlTrapGeneration,
  338.                               &StorageTmp->pingCtlTrapGenerationLen);
  339.     if (StorageTmp->pingCtlTrapGeneration == NULL) {
  340.         config_perror("invalid specification for pingCtlTrapGeneration");
  341.         return;
  342.     }
  343.     line =
  344.         read_config_read_data(ASN_UNSIGNED, line,
  345.                               &StorageTmp->pingCtlTrapProbeFailureFilter,
  346.                               &tmpint);
  347.     line =
  348.         read_config_read_data(ASN_UNSIGNED, line,
  349.                               &StorageTmp->pingCtlTrapTestFailureFilter,
  350.                               &tmpint);
  351.     line =
  352.         read_config_read_data(ASN_OBJECT_ID, line,
  353.                               &StorageTmp->pingCtlType,
  354.                               &StorageTmp->pingCtlTypeLen);
  355.     if (StorageTmp->pingCtlType == NULL) {
  356.         config_perror("invalid specification for pingCtlType");
  357.         return;
  358.     }
  359.     line =
  360.         read_config_read_data(ASN_OCTET_STR, line,
  361.                               &StorageTmp->pingCtlDescr,
  362.                               &StorageTmp->pingCtlDescrLen);
  363.     if (StorageTmp->pingCtlDescr == NULL) {
  364.         config_perror("invalid specification for pingCtlTrapDescr");
  365.         return;
  366.     }
  367.     line =
  368.         read_config_read_data(ASN_INTEGER, line,
  369.                               &StorageTmp->pingCtlSourceAddressType,
  370.                               &tmpint);
  371.     line =
  372.         read_config_read_data(ASN_OCTET_STR, line,
  373.                               &StorageTmp->pingCtlSourceAddress,
  374.                               &StorageTmp->pingCtlSourceAddressLen);
  375.     if (StorageTmp->pingCtlSourceAddress == NULL) {
  376.         config_perror("invalid specification for pingCtlSourceAddress");
  377.         return;
  378.     }
  379.     line =
  380.         read_config_read_data(ASN_INTEGER, line,
  381.                               &StorageTmp->pingCtlIfIndex, &tmpint);
  382.     line =
  383.         read_config_read_data(ASN_INTEGER, line,
  384.                               &StorageTmp->pingCtlByPassRouteTable,
  385.                               &tmpint);
  386.     line =
  387.         read_config_read_data(ASN_UNSIGNED, line,
  388.                               &StorageTmp->pingCtlDSField, &tmpint);
  389.     line =
  390.         read_config_read_data(ASN_INTEGER, line,
  391.                               &StorageTmp->pingCtlRowStatus, &tmpint);
  392.     line =
  393.         read_config_read_data(ASN_UNSIGNED, line,
  394.                               &StorageTmp->pingProbeHistoryMaxIndex,
  395.                               &tmpint);
  396.     StorageTmp->storageType = ST_NONVOLATILE;
  397.     pingCtlTable_add(StorageTmp);
  398.     /* pingCtlTable_cleaner(pingCtlTableStorage); */
  399.     DEBUGMSGTL(("pingCtlTable", "done.n"));
  400. }
  401. /*
  402.  * store_pingCtlTable():
  403.  *   stores .conf file entries needed to configure the mib.
  404.  */
  405. int
  406. store_pingCtlTable(int majorID, int minorID, void *serverarg,
  407.                    void *clientarg)
  408. {
  409.     char            line[SNMP_MAXBUF];
  410.     char           *cptr = NULL;
  411.     size_t          tmpint;
  412.     struct pingCtlTable_data *StorageTmp = NULL;
  413.     struct header_complex_index *hcindex = NULL;
  414.     DEBUGMSGTL(("pingCtlTable", "storing data...  "));
  415.     for (hcindex = pingCtlTableStorage; hcindex != NULL;
  416.          hcindex = hcindex->next) {
  417.         StorageTmp = (struct pingCtlTable_data *) hcindex->data;
  418.         if (StorageTmp->storageType != ST_READONLY) {
  419.             memset(line, 0, sizeof(line));
  420.             strcat(line, "pingCtlTable ");
  421.             cptr = line + strlen(line);
  422.             cptr =
  423.                 read_config_store_data(ASN_OCTET_STR, cptr,
  424.                                        &StorageTmp->pingCtlOwnerIndex,
  425.                                        &StorageTmp->pingCtlOwnerIndexLen);
  426.             cptr =
  427.                 read_config_store_data(ASN_OCTET_STR, cptr,
  428.                                        &StorageTmp->pingCtlTestName,
  429.                                        &StorageTmp->pingCtlTestNameLen);
  430.             cptr =
  431.                 read_config_store_data(ASN_INTEGER, cptr,
  432.                                        &StorageTmp->
  433.                                        pingCtlTargetAddressType, &tmpint);
  434.             cptr =
  435.                 read_config_store_data(ASN_OCTET_STR, cptr,
  436.                                        &StorageTmp->pingCtlTargetAddress,
  437.                                        &StorageTmp->
  438.                                        pingCtlTargetAddressLen);
  439.             cptr =
  440.                 read_config_store_data(ASN_UNSIGNED, cptr,
  441.                                        &StorageTmp->pingCtlDataSize,
  442.                                        &tmpint);
  443.             cptr =
  444.                 read_config_store_data(ASN_UNSIGNED, cptr,
  445.                                        &StorageTmp->pingCtlTimeOut,
  446.                                        &tmpint);
  447.             cptr =
  448.                 read_config_store_data(ASN_UNSIGNED, cptr,
  449.                                        &StorageTmp->pingCtlProbeCount,
  450.                                        &tmpint);
  451.             cptr =
  452.                 read_config_store_data(ASN_INTEGER, cptr,
  453.                                        &StorageTmp->pingCtlAdminStatus,
  454.                                        &tmpint);
  455.             cptr =
  456.                 read_config_store_data(ASN_OCTET_STR, cptr,
  457.                                        &StorageTmp->pingCtlDataFill,
  458.                                        &StorageTmp->pingCtlDataFillLen);
  459.             cptr =
  460.                 read_config_store_data(ASN_UNSIGNED, cptr,
  461.                                        &StorageTmp->pingCtlFrequency,
  462.                                        &tmpint);
  463.             cptr =
  464.                 read_config_store_data(ASN_UNSIGNED, cptr,
  465.                                        &StorageTmp->pingCtlMaxRows,
  466.                                        &tmpint);
  467.             cptr =
  468.                 read_config_store_data(ASN_INTEGER, cptr,
  469.                                        &StorageTmp->pingCtlStorageType,
  470.                                        &tmpint);
  471.             cptr =
  472.                 read_config_store_data(ASN_OCTET_STR, cptr,
  473.                                        &StorageTmp->pingCtlTrapGeneration,
  474.                                        &StorageTmp->
  475.                                        pingCtlTrapGenerationLen);
  476.             cptr =
  477.                 read_config_store_data(ASN_UNSIGNED, cptr,
  478.                                        &StorageTmp->
  479.                                        pingCtlTrapProbeFailureFilter,
  480.                                        &tmpint);
  481.             cptr =
  482.                 read_config_store_data(ASN_UNSIGNED, cptr,
  483.                                        &StorageTmp->
  484.                                        pingCtlTrapTestFailureFilter,
  485.                                        &tmpint);
  486.             cptr =
  487.                 read_config_store_data(ASN_OBJECT_ID, cptr,
  488.                                        &StorageTmp->pingCtlType,
  489.                                        &StorageTmp->pingCtlTypeLen);
  490.             cptr =
  491.                 read_config_store_data(ASN_OCTET_STR, cptr,
  492.                                        &StorageTmp->pingCtlDescr,
  493.                                        &StorageTmp->pingCtlDescrLen);
  494.             cptr =
  495.                 read_config_store_data(ASN_INTEGER, cptr,
  496.                                        &StorageTmp->
  497.                                        pingCtlSourceAddressType, &tmpint);
  498.             cptr =
  499.                 read_config_store_data(ASN_OCTET_STR, cptr,
  500.                                        &StorageTmp->pingCtlSourceAddress,
  501.                                        &StorageTmp->
  502.                                        pingCtlSourceAddressLen);
  503.             cptr =
  504.                 read_config_store_data(ASN_INTEGER, cptr,
  505.                                        &StorageTmp->pingCtlIfIndex,
  506.                                        &tmpint);
  507.             cptr =
  508.                 read_config_store_data(ASN_INTEGER, cptr,
  509.                                        &StorageTmp->
  510.                                        pingCtlByPassRouteTable, &tmpint);
  511.             cptr =
  512.                 read_config_store_data(ASN_UNSIGNED, cptr,
  513.                                        &StorageTmp->pingCtlDSField,
  514.                                        &tmpint);
  515.             if (StorageTmp->pingCtlRowStatus == RS_ACTIVE)
  516.                 StorageTmp->pingCtlRowStatus = RS_NOTINSERVICE;
  517.             cptr =
  518.                 read_config_store_data(ASN_INTEGER, cptr,
  519.                                        &StorageTmp->pingCtlRowStatus,
  520.                                        &tmpint);
  521.             cptr =
  522.                 read_config_store_data(ASN_UNSIGNED, cptr,
  523.                                        &StorageTmp->
  524.                                        pingProbeHistoryMaxIndex, &tmpint);
  525.             snmpd_store_config(line);
  526.         }
  527.     }
  528.     DEBUGMSGTL(("pingCtlTable", "done.n"));
  529.     return SNMPERR_SUCCESS;
  530. }
  531. /*
  532.  * var_pingCtlTable():
  533.  *   Handle this table separately from the scalar value case.
  534.  *   The workings of this are basically the same as for var_mteObjectsTable above.
  535.  */
  536. unsigned char  *
  537. var_pingCtlTable(struct variable *vp,
  538.                  oid * name,
  539.                  size_t *length,
  540.                  int exact, size_t *var_len, WriteMethod ** write_method)
  541. {
  542.     struct pingCtlTable_data *StorageTmp = NULL;
  543.     /*
  544.      * this assumes you have registered all your data properly
  545.      */
  546.     if ((StorageTmp =
  547.          header_complex(pingCtlTableStorage, vp, name, length, exact,
  548.                         var_len, write_method)) == NULL) {
  549.         if (vp->magic == COLUMN_PINGCTLROWSTATUS)
  550.             *write_method = write_pingCtlRowStatus;
  551.         return NULL;
  552.     }
  553.     /*
  554.      * this is where we do the value assignments for the mib results.
  555.      */
  556.     switch (vp->magic) {
  557.     case COLUMN_PINGCTLTARGETADDRESSTYPE:
  558.         *write_method = write_pingCtlTargetAddressType;
  559.         *var_len = sizeof(StorageTmp->pingCtlTargetAddressType);
  560.         return (u_char *) & StorageTmp->pingCtlTargetAddressType;
  561.     case COLUMN_PINGCTLTARGETADDRESS:
  562.         *write_method = write_pingCtlTargetAddress;
  563.         *var_len = (StorageTmp->pingCtlTargetAddressLen);
  564.         return (u_char *) StorageTmp->pingCtlTargetAddress;
  565.     case COLUMN_PINGCTLDATASIZE:
  566.         *write_method = write_pingCtlDataSize;
  567.         *var_len = sizeof(StorageTmp->pingCtlDataSize);
  568.         return (u_char *) & StorageTmp->pingCtlDataSize;
  569.     case COLUMN_PINGCTLTIMEOUT:
  570.         *write_method = write_pingCtlTimeOut;
  571.         *var_len = sizeof(StorageTmp->pingCtlTimeOut);
  572.         return (u_char *) & StorageTmp->pingCtlTimeOut;
  573.     case COLUMN_PINGCTLPROBECOUNT:
  574.         *write_method = write_pingCtlProbeCount;
  575.         *var_len = sizeof(StorageTmp->pingCtlProbeCount);
  576.         return (u_char *) & StorageTmp->pingCtlProbeCount;
  577.     case COLUMN_PINGCTLADMINSTATUS:
  578.         *write_method = write_pingCtlAdminStatus;
  579.         *var_len = sizeof(StorageTmp->pingCtlAdminStatus);
  580.         return (u_char *) & StorageTmp->pingCtlAdminStatus;
  581.     case COLUMN_PINGCTLDATAFILL:
  582.         *write_method = write_pingCtlDataFill;
  583.         *var_len = (StorageTmp->pingCtlDataFillLen);
  584.         return (u_char *) StorageTmp->pingCtlDataFill;
  585.     case COLUMN_PINGCTLFREQUENCY:
  586.         *write_method = write_pingCtlFrequency;
  587.         *var_len = sizeof(StorageTmp->pingCtlFrequency);
  588.         return (u_char *) & StorageTmp->pingCtlFrequency;
  589.     case COLUMN_PINGCTLMAXROWS:
  590.         *write_method = write_pingCtlMaxRows;
  591.         *var_len = sizeof(StorageTmp->pingCtlMaxRows);
  592.         return (u_char *) & StorageTmp->pingCtlMaxRows;
  593.     case COLUMN_PINGCTLSTORAGETYPE:
  594.         *write_method = write_pingCtlStorageType;
  595.         *var_len = sizeof(StorageTmp->pingCtlStorageType);
  596.         return (u_char *) & StorageTmp->pingCtlStorageType;
  597.     case COLUMN_PINGCTLTRAPGENERATION:
  598.         *write_method = write_pingCtlTrapGeneration;
  599.         *var_len = (StorageTmp->pingCtlTrapGenerationLen);
  600.         return (u_char *) StorageTmp->pingCtlTrapGeneration;
  601.     case COLUMN_PINGCTLTRAPPROBEFAILUREFILTER:
  602.         *write_method = write_pingCtlTrapProbeFailureFilter;
  603.         *var_len = sizeof(StorageTmp->pingCtlTrapProbeFailureFilter);
  604.         return (u_char *) & StorageTmp->pingCtlTrapProbeFailureFilter;
  605.     case COLUMN_PINGCTLTRAPTESTFAILUREFILTER:
  606.         *write_method = write_pingCtlTrapTestFailureFilter;
  607.         *var_len = sizeof(StorageTmp->pingCtlTrapTestFailureFilter);
  608.         return (u_char *) & StorageTmp->pingCtlTrapTestFailureFilter;
  609.     case COLUMN_PINGCTLTYPE:
  610.         *write_method = write_pingCtlType;
  611.         *var_len = (StorageTmp->pingCtlTypeLen) * sizeof(oid);
  612.         return (u_char *) StorageTmp->pingCtlType;
  613.     case COLUMN_PINGCTLDESCR:
  614.         *write_method = write_pingCtlDescr;
  615.         *var_len = (StorageTmp->pingCtlDescrLen);
  616.         return (u_char *) StorageTmp->pingCtlDescr;
  617.     case COLUMN_PINGCTLSOURCEADDRESSTYPE:
  618.         *write_method = write_pingCtlSourceAddressType;
  619.         *var_len = sizeof(StorageTmp->pingCtlSourceAddressType);
  620.         return (u_char *) & StorageTmp->pingCtlSourceAddressType;
  621.     case COLUMN_PINGCTLSOURCEADDRESS:
  622.         *write_method = write_pingCtlSourceAddress;
  623.         *var_len = (StorageTmp->pingCtlSourceAddressLen);
  624.         return (u_char *) StorageTmp->pingCtlSourceAddress;
  625.     case COLUMN_PINGCTLIFINDEX:
  626.         *write_method = write_pingCtlIfIndex;
  627.         *var_len = sizeof(StorageTmp->pingCtlIfIndex);
  628.         return (u_char *) & StorageTmp->pingCtlIfIndex;
  629.     case COLUMN_PINGCTLBYPASSROUTETABLE:
  630.         *write_method = write_pingCtlByPassRouteTable;
  631.         *var_len = sizeof(StorageTmp->pingCtlByPassRouteTable);
  632.         return (u_char *) & StorageTmp->pingCtlByPassRouteTable;
  633.     case COLUMN_PINGCTLDSFIELD:
  634.         *write_method = write_pingCtlDSField;
  635.         *var_len = sizeof(StorageTmp->pingCtlDSField);
  636.         return (u_char *) & StorageTmp->pingCtlDSField;
  637.     case COLUMN_PINGCTLROWSTATUS:
  638.         *write_method = write_pingCtlRowStatus;
  639.         *var_len = sizeof(StorageTmp->pingCtlRowStatus);
  640.         return (u_char *) & StorageTmp->pingCtlRowStatus;
  641.     default:
  642.         ERROR_MSG("");
  643.     }
  644.     return NULL;
  645. }
  646. unsigned long
  647. pingProbeHistoryTable_count(struct pingCtlTable_data *thedata)
  648. {
  649.     struct header_complex_index *hciptr2 = NULL;
  650.     netsnmp_variable_list *vars = NULL;
  651.     oid             newoid[MAX_OID_LEN];
  652.     size_t          newoid_len;
  653.     unsigned long   count = 0;
  654.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->pingCtlOwnerIndex, thedata->pingCtlOwnerIndexLen);       /* pingCtlOwnerIndex */
  655.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->pingCtlTestName, thedata->pingCtlTestNameLen);   /* pingCtlOperationName */
  656.     header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars);
  657.     for (hciptr2 = pingProbeHistoryTableStorage; hciptr2 != NULL;
  658.          hciptr2 = hciptr2->next) {
  659.         if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len)
  660.             == 0) {
  661.             count = count + 1;
  662.         }
  663.     }
  664.     return count;
  665. }
  666. int
  667. pingProbeHistoryTable_delLast(struct pingCtlTable_data *thedata)
  668. {
  669.     struct header_complex_index *hciptr2 = NULL;
  670.     struct header_complex_index *hcilast = NULL;
  671.     struct pingProbeHistoryTable_data *StorageDel = NULL;
  672.     struct pingProbeHistoryTable_data *StorageTmp = NULL;
  673.     netsnmp_variable_list *vars = NULL;
  674.     oid             newoid[MAX_OID_LEN];
  675.     size_t          newoid_len;
  676.     time_t          last_time = 2147483647;
  677.     struct tm      *tp;
  678.     tp = (struct tm *) malloc(sizeof(struct tm));
  679.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->pingCtlOwnerIndex, thedata->pingCtlOwnerIndexLen);       /* pingCtlOwnerIndex */
  680.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->pingCtlTestName, thedata->pingCtlTestNameLen);   /* pingCtlOperationName */
  681.     header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars);
  682.     for (hcilast = hciptr2 = pingProbeHistoryTableStorage; hciptr2 != NULL;
  683.          hciptr2 = hciptr2->next) {
  684.         if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len)
  685.             == 0) {
  686.             StorageTmp =
  687.                 header_complex_get_from_oid(pingProbeHistoryTableStorage,
  688.                                             hciptr2->name,
  689.                                             hciptr2->namelen);
  690.             strptime(StorageTmp->pingProbeHistoryTime, "%c", tp);
  691.             if (last_time > timegm(tp)) {
  692.                 last_time = timegm(tp);
  693.                 hcilast = hciptr2;
  694.             }
  695.         }
  696.     }
  697.     StorageDel =
  698.         header_complex_extract_entry(&pingProbeHistoryTableStorage,
  699.                                      hcilast);
  700.     DEBUGMSGTL(("pingProbeHistoryTable",
  701.                 "delete the last one success!n"));
  702.     SNMP_FREE(tp);
  703. }
  704. char           *
  705. sock_ntop_host(const struct sockaddr *sa, socklen_t salen)
  706. {
  707.     static char     str[128];   /* Unix domain is largest */
  708.     switch (sa->sa_family) {
  709.     case AF_INET:{
  710.             struct sockaddr_in *sin = (struct sockaddr_in *) sa;
  711.             if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) ==
  712.                 NULL)
  713.                 return (NULL);
  714.             return (str);
  715.         }
  716. #ifdef IPV6
  717.     case AF_INET6:{
  718.             struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
  719.             if (inet_ntop(AF_INET6, &sin6->sin6_addr, str, sizeof(str)) ==
  720.                 NULL)
  721.                 return (NULL);
  722.             return (str);
  723.         }
  724. #endif
  725. #ifdef AF_UNIX
  726.     case AF_UNIX:{
  727.             struct sockaddr_un *unp = (struct sockaddr_un *) sa;
  728.             /*
  729.              * OK to have no pathname bound to the socket: happens on
  730.              * every connect() unless client calls bind() first. 
  731.              */
  732.             if (unp->sun_path[0] == 0)
  733.                 strcpy(str, "(no pathname bound)");
  734.             else
  735.                 snprintf(str, sizeof(str), "%s", unp->sun_path);
  736.             return (str);
  737.         }
  738. #endif
  739. #ifdef HAVE_SOCKADDR_DL_STRUCT
  740.     case AF_LINK:{
  741.             struct sockaddr_dl *sdl = (struct sockaddr_dl *) sa;
  742.             if (sdl->sdl_nlen > 0)
  743.                 snprintf(str, sizeof(str), "%*s",
  744.                          sdl->sdl_nlen, &sdl->sdl_data[0]);
  745.             else
  746.                 snprintf(str, sizeof(str), "AF_LINK, index=%d",
  747.                          sdl->sdl_index);
  748.             return (str);
  749.         }
  750. #endif
  751.     default:
  752.         snprintf(str, sizeof(str),
  753.                  "sock_ntop_host: unknown AF_xxx: %d, len %d",
  754.                  sa->sa_family, salen);
  755.         return (str);
  756.     }
  757.     return (NULL);
  758. }
  759. char           *
  760. Sock_ntop_host(const struct sockaddr *sa, socklen_t salen)
  761. {
  762.     char           *ptr;
  763.     if ((ptr = sock_ntop_host(sa, salen)) == NULL)
  764.         printf("sock_ntop_host error"); /* inet_ntop() sets errno */
  765.     return (ptr);
  766. }
  767. unsigned short
  768. in_cksum(unsigned short *addr, int len)
  769. {
  770.     int             nleft = len;
  771.     int             sum = 0;
  772.     unsigned short *w = addr;
  773.     unsigned short  answer = 0;
  774.     /*
  775.      * Our algorithm is simple, using a 32 bit accumulator (sum), we add
  776.      * sequential 16 bit words to it, and at the end, fold back all the
  777.      * carry bits from the top 16 bits into the lower 16 bits.
  778.      */
  779.     while (nleft > 1) {
  780.         sum += *w++;
  781.         nleft -= 2;
  782.     }
  783.     /*
  784.      * 4mop up an odd byte, if necessary 
  785.      */
  786.     if (nleft == 1) {
  787.         *(unsigned char *) (&answer) = *(unsigned char *) w;
  788.         sum += answer;
  789.     }
  790.     /*
  791.      * 4add back carry outs from top 16 bits to low 16 bits 
  792.      */
  793.     sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
  794.     sum += (sum >> 16);         /* add carry */
  795.     answer = ~sum;              /* truncate to 16 bits */
  796.     return (answer);
  797. }
  798. struct addrinfo *
  799. host_serv(const char *host, const char *serv, int family, int socktype)
  800. {
  801.     int             n;
  802.     struct addrinfo hints, *res;
  803.     bzero(&hints, sizeof(struct addrinfo));
  804.     hints.ai_flags = AI_CANONNAME;      /* always return canonical name */
  805.     hints.ai_family = family;   /* AF_UNSPEC, AF_INET, AF_INET6, etc. */
  806.     hints.ai_socktype = socktype;       /* 0, SOCK_STREAM, SOCK_DGRAM, etc. */
  807.     if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)
  808.         return (NULL);
  809.     return (res);               /* return pointer to first on linked list */
  810. }
  811. /*
  812.  * end host_serv 
  813.  */
  814. /*
  815.  * There is no easy way to pass back the integer return code from
  816.  * getaddrinfo() in the function above, short of adding another argument
  817.  * that is a pointer, so the easiest way to provide the wrapper function
  818.  * is just to duplicate the simple function as we do here.
  819.  */
  820. struct addrinfo *
  821. Host_serv(const char *host, const char *serv, int family, int socktype)
  822. {
  823.     int             n;
  824.     struct addrinfo hints, *res;
  825.     bzero(&hints, sizeof(struct addrinfo));
  826.     hints.ai_flags = AI_CANONNAME;      /* always return canonical name */
  827.     hints.ai_family = family;   /* 0, AF_INET, AF_INET6, etc. */
  828.     hints.ai_socktype = socktype;       /* 0, SOCK_STREAM, SOCK_DGRAM, etc. */
  829.     if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)
  830.         printf("host_serv error for %s, %s: %s",
  831.                (host == NULL) ? "(no hostname)" : host,
  832.                (serv == NULL) ? "(no service name)" : serv,
  833.                gai_strerror(n));
  834.     return (res);               /* return pointer to first on linked list */
  835. }
  836. int
  837. readable_timeo(int fd, int sec)
  838. {
  839.     fd_set          rset;
  840.     struct timeval  tv;
  841.     FD_ZERO(&rset);
  842.     FD_SET(fd, &rset);
  843.     tv.tv_sec = sec;
  844.     tv.tv_usec = 0;
  845.     return (select(fd + 1, &rset, NULL, NULL, &tv));
  846. }
  847. /*
  848.  * send trap 
  849.  */
  850. int
  851. send_ping_trap(struct pingCtlTable_data *item,
  852.                oid * trap_oid, size_t trap_oid_len)
  853. {
  854.     static oid      objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };     /* snmpTrapIOD.0 */
  855.     struct pingResultsTable_data *StorageTmp = NULL;
  856.     netsnmp_variable_list *var_list = NULL, *vars = NULL;
  857.     oid             newoid[MAX_OID_LEN];
  858.     size_t          newoid_len;
  859.     oid             pingCtlTargetAddress[] =
  860.         { 1, 3, 6, 1, 2, 1, 80, 1, 2, 1, 4 };
  861.     oid             pingResultsMinRtt[] =
  862.         { 1, 3, 6, 1, 2, 1, 80, 1, 3, 1, 4 };
  863.     oid             pingResultsMaxRtt[] =
  864.         { 1, 3, 6, 1, 2, 1, 80, 1, 3, 1, 5 };
  865.     oid             pingResultsAverageRtt[] =
  866.         { 1, 3, 6, 1, 2, 1, 80, 1, 3, 1, 6 };
  867.     oid             pingResultsProbeResponses[] =
  868.         { 1, 3, 6, 1, 2, 1, 80, 1, 3, 1, 7 };
  869.     oid             pingResultsSendProbes[] =
  870.         { 1, 3, 6, 1, 2, 1, 80, 1, 3, 1, 8 };
  871.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->pingCtlOwnerIndex, item->pingCtlOwnerIndexLen);     /* pingCtlOwnerIndex */
  872.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->pingCtlTestName, item->pingCtlTestNameLen); /* pingCtlOperationName */
  873.     StorageTmp = SNMP_MALLOC_STRUCT(pingResultsTable_data);
  874.     if ((StorageTmp =
  875.          (struct pingResultsTable_data *)
  876.          header_complex_get(pingResultsTableStorage, vars)) == NULL)
  877.         return SNMP_ERR_NOSUCHNAME;
  878.     /*
  879.      * snmpTrap oid 
  880.      */
  881.     snmp_varlist_add_variable(&var_list, objid_snmptrap,
  882.                               sizeof(objid_snmptrap) / sizeof(oid),
  883.                               ASN_OBJECT_ID, (u_char *) trap_oid,
  884.                               trap_oid_len * sizeof(oid));
  885.     /*
  886.      * pingCtlTargetAddress 
  887.      */
  888.     bzero(newoid, MAX_OID_LEN * sizeof(oid));
  889.     header_complex_generate_oid(newoid, &newoid_len, pingCtlTargetAddress,
  890.                                 sizeof(pingCtlTargetAddress) / sizeof(oid),
  891.                                 vars);
  892.     snmp_varlist_add_variable(&var_list, newoid,
  893.                               newoid_len,
  894.                               ASN_OCTET_STR,
  895.                               (u_char *) item->pingCtlTargetAddress,
  896.                               item->pingCtlTargetAddressLen);
  897.     /*
  898.      * pingResultsMinRtt
  899.      */
  900.     bzero(newoid, newoid_len);
  901.     header_complex_generate_oid(newoid, &newoid_len, pingResultsMinRtt,
  902.                                 sizeof(pingResultsMinRtt) / sizeof(oid),
  903.                                 vars);
  904.     snmp_varlist_add_variable(&var_list, newoid,
  905.                               newoid_len,
  906.                               ASN_UNSIGNED,
  907.                               (u_char *) & (StorageTmp->pingResultsMinRtt),
  908.                               sizeof(StorageTmp->pingResultsMinRtt));
  909.     /*
  910.      * pingResultsMaxRtt 
  911.      */
  912.     bzero(newoid, newoid_len);
  913.     header_complex_generate_oid(newoid, &newoid_len, pingResultsMaxRtt,
  914.                                 sizeof(pingResultsMaxRtt) / sizeof(oid),
  915.                                 vars);
  916.     snmp_varlist_add_variable(&var_list, newoid,
  917.                               newoid_len,
  918.                               ASN_UNSIGNED,
  919.                               (u_char *) & (StorageTmp->pingResultsMaxRtt),
  920.                               sizeof(StorageTmp->pingResultsMaxRtt));
  921.     /*
  922.      * pingResultsAverageRtt 
  923.      */
  924.     bzero(newoid, newoid_len);
  925.     header_complex_generate_oid(newoid, &newoid_len, pingResultsAverageRtt,
  926.                                 sizeof(pingResultsAverageRtt) /
  927.                                 sizeof(oid), vars);
  928.     snmp_varlist_add_variable(&var_list, newoid,
  929.                               newoid_len,
  930.                               ASN_UNSIGNED,
  931.                               (u_char *) & (StorageTmp->
  932.                                             pingResultsAverageRtt),
  933.                               sizeof(StorageTmp->pingResultsAverageRtt));
  934.     /*
  935.      * pingResultsProbeResponses 
  936.      */
  937.     bzero(newoid, newoid_len);
  938.     header_complex_generate_oid(newoid, &newoid_len,
  939.                                 pingResultsProbeResponses,
  940.                                 sizeof(pingResultsProbeResponses) /
  941.                                 sizeof(oid), vars);
  942.     snmp_varlist_add_variable(&var_list, newoid,
  943.                               newoid_len,
  944.                               ASN_UNSIGNED,
  945.                               (u_char *) & (StorageTmp->
  946.                                             pingResultsProbeResponses),
  947.                               sizeof(StorageTmp->
  948.                                      pingResultsProbeResponses));
  949.     /*
  950.      * pingResultsSendProbes 
  951.      */
  952.     bzero(newoid, newoid_len);
  953.     header_complex_generate_oid(newoid, &newoid_len, pingResultsSendProbes,
  954.                                 sizeof(pingResultsSendProbes) /
  955.                                 sizeof(oid), vars);
  956.     snmp_varlist_add_variable(&var_list, newoid,
  957.                               newoid_len,
  958.                               ASN_UNSIGNED,
  959.                               (u_char *) & (StorageTmp->
  960.                                             pingResultsSendProbes),
  961.                               sizeof(StorageTmp->pingResultsSendProbes));
  962.     /*
  963.      * XXX: stuff based on event table 
  964.      */
  965.     DEBUGMSG(("pingTest:send_ping_trap", "success!n"));
  966.     send_v2trap(var_list);
  967.     snmp_free_varbind(vars);
  968.     vars = NULL;
  969.     snmp_free_varbind(var_list);
  970.     vars = NULL;
  971. }
  972. void
  973. readloop(struct pingCtlTable_data *item, struct addrinfo *ai, int datalen,
  974.          unsigned long *minrtt, unsigned long *maxrtt,
  975.          unsigned long *averagertt, pid_t pid)
  976. {
  977.     int             size;
  978.     char            recvbuf[BUFSIZE];
  979.     char            sendbuf[BUFSIZE];
  980.     int             nsent = 1;
  981.     socklen_t       len;
  982.     ssize_t         n;
  983.     struct timeval  tval;
  984.     /* static int                    loop_num; */
  985.     /* struct pingProbeHistoryTable_data * current=NULL; */
  986.     struct pingProbeHistoryTable_data current_var;
  987.     int             sockfd;
  988.     int             current_probe_temp;
  989.     int             success_probe = 0;
  990.     int             fail_probe = 0;
  991.     int             flag;
  992.     unsigned long  *sumrtt;
  993.     struct timeval  tv;
  994.     sumrtt = (unsigned long *) malloc(sizeof(unsigned long));
  995.     sockfd = socket(pr->sasend->sa_family, SOCK_RAW, pr->icmpproto);
  996.     setuid(getuid());           /* don't need special permissions any more */
  997.     size = 60 * 1024;           /* OK if setsockopt fails */
  998.     tv.tv_sec = 5;
  999.     tv.tv_usec = 0;
  1000.     setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
  1001.     for (current_probe_temp = 1;
  1002.          current_probe_temp <= item->pingCtlProbeCount;
  1003.          current_probe_temp++) {
  1004.         (*pr->fsend) (datalen, pid, nsent, sockfd, sendbuf);
  1005.         nsent++;
  1006.         len = pr->salen;
  1007.         if (readable_timeo(sockfd, item->pingCtlTimeOut) == 0) {
  1008.             /* printf("socket timeout!n"); */
  1009.             fail_probe = fail_probe + 1;
  1010.             flag = 1;
  1011.         } else {
  1012.             n = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, pr->sarecv,
  1013.                          &len);
  1014.             success_probe = success_probe + 1;
  1015.             flag = 0;
  1016.         }
  1017.         gettimeofday(&tval, NULL);
  1018.         time_t          timep;
  1019.         time(&timep);
  1020.         (*pr->fproc) (recvbuf, n, &tval, timep, item, ai, datalen, minrtt,
  1021.                       maxrtt, sumrtt, averagertt, current_probe_temp,
  1022.                       success_probe, fail_probe, flag, &current_var, pid);
  1023.         printf("receiver success!n");
  1024.         if (current_probe_temp >= item->pingCtlProbeCount) {
  1025.             SNMP_FREE(sumrtt);
  1026.             sumrtt = NULL;
  1027.             return;
  1028.         }
  1029.     }
  1030. }
  1031. unsigned long
  1032. round_double(double number)
  1033. {
  1034.     unsigned long   ret_num = 0;
  1035.     if (number - (unsigned long) number < 0.5)
  1036.         ret_num = (unsigned long) number;
  1037.     else
  1038.         ret_num = (unsigned long) number + 1;
  1039.     return ret_num;
  1040. }
  1041. int
  1042. proc_v4(char *ptr, ssize_t len, struct timeval *tvrecv, time_t timep,
  1043.         struct pingCtlTable_data *item, struct addrinfo *ai, int datalen,
  1044.         unsigned long *minrtt, unsigned long *maxrtt,
  1045.         unsigned long *sumrtt, unsigned long *averagertt,
  1046.         unsigned long current_probe, int success_probe, int fail_probe,
  1047.         int flag, struct pingProbeHistoryTable_data *current_temp,
  1048.         pid_t pid)
  1049. {
  1050.     int             hlen1 = 0, icmplen = 0;
  1051.     unsigned long   rtt = 0;
  1052.     struct ip      *ip = NULL;
  1053.     struct icmp    *icmp = NULL;
  1054.     struct timeval *tvsend = NULL;
  1055.     struct pingProbeHistoryTable_data *temp = NULL;
  1056.     static int      probeFailed = 0;
  1057.     static int      testFailed = 0;
  1058.     static int      series = 0;
  1059.     netsnmp_variable_list *vars = NULL;
  1060.     struct pingResultsTable_data *StorageNew = NULL;
  1061.     if (flag == 0) {
  1062.         series = 0;
  1063.         ip = (struct ip *) ptr; /* start of IP header */
  1064.         hlen1 = ip->ip_hl << 2; /* length of IP header */
  1065.         icmp = (struct icmp *) (ptr + hlen1);   /* start of ICMP header */
  1066.         if ((icmplen = len - hlen1) < 8)
  1067.             printf("icmplen (%d) < 8", icmplen);
  1068.         if (icmp->icmp_type == ICMP_ECHOREPLY) {
  1069.             if (icmp->icmp_id != pid)
  1070.                 return;         /* not a response to our ECHO_REQUEST */
  1071.             if (icmplen < 16)
  1072.                 printf("icmplen (%d) < 16", icmplen);
  1073.             tvsend = (struct timeval *) icmp->icmp_data;
  1074.             rtt =
  1075.                 round_double((1000000 * (tvrecv->tv_sec - tvsend->tv_sec) +
  1076.                               tvrecv->tv_usec - tvsend->tv_usec) / 1000);
  1077.             snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->pingCtlOwnerIndex, item->pingCtlOwnerIndexLen);     /* pingCtlOwnerIndex */
  1078.             snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->pingCtlTestName, item->pingCtlTestNameLen); /* pingCtlTestName */
  1079.             if ((StorageNew =
  1080.                  header_complex_get(pingResultsTableStorage,
  1081.                                     vars)) == NULL)
  1082.                 return SNMP_ERR_NOSUCHNAME;
  1083.             if (current_probe == 1) {
  1084.                 *averagertt = rtt;
  1085.                 *minrtt = rtt;
  1086.                 *maxrtt = rtt;
  1087.                 *sumrtt = rtt;
  1088.             } else {
  1089.                 printf("elsen");
  1090.                 if (rtt < *minrtt)
  1091.                     *minrtt = rtt;
  1092.                 if (rtt > *maxrtt)
  1093.                     *maxrtt = rtt;
  1094.                 *sumrtt = (*sumrtt) + rtt;
  1095.                 *averagertt =
  1096.                     round_double((*sumrtt) /
  1097.                                  (StorageNew->pingResultsProbeResponses +
  1098.                                   1));
  1099.             }
  1100.             StorageNew->pingResultsMinRtt = *minrtt;
  1101.             StorageNew->pingResultsMaxRtt = *maxrtt;
  1102.             StorageNew->pingResultsAverageRtt = *averagertt;
  1103.             StorageNew->pingResultsProbeResponses =
  1104.                 StorageNew->pingResultsProbeResponses + 1;
  1105.             StorageNew->pingResultsSendProbes =
  1106.                 StorageNew->pingResultsSendProbes + 1;
  1107.             StorageNew->pingResultsRttSumOfSquares =
  1108.                 StorageNew->pingResultsRttSumOfSquares + rtt * rtt;
  1109.             StorageNew->pingResultsLastGoodProbe =
  1110.                 (char *) malloc(strlen(asctime(gmtime(&timep))));
  1111.             StorageNew->pingResultsLastGoodProbe =
  1112.                 strdup(asctime(gmtime(&timep)));
  1113.             StorageNew->
  1114.                 pingResultsLastGoodProbe[strlen(asctime(gmtime(&timep))) -
  1115.                                          1] = '';
  1116.             StorageNew->pingResultsLastGoodProbeLen =
  1117.                 strlen(asctime(gmtime(&timep))) - 1;
  1118.             temp = SNMP_MALLOC_STRUCT(pingProbeHistoryTable_data);
  1119.             temp->pingCtlOwnerIndex =
  1120.                 (char *) malloc(item->pingCtlOwnerIndexLen + 1);
  1121.             memcpy(temp->pingCtlOwnerIndex, item->pingCtlOwnerIndex,
  1122.                    item->pingCtlOwnerIndexLen + 1);
  1123.             temp->pingCtlOwnerIndex[item->pingCtlOwnerIndexLen] = '';
  1124.             temp->pingCtlOwnerIndexLen = item->pingCtlOwnerIndexLen;
  1125.             temp->pingCtlTestName =
  1126.                 (char *) malloc(item->pingCtlTestNameLen + 1);
  1127.             memcpy(temp->pingCtlTestName, item->pingCtlTestName,
  1128.                    item->pingCtlTestNameLen + 1);
  1129.             temp->pingCtlTestName[item->pingCtlTestNameLen] = '';
  1130.             temp->pingCtlTestNameLen = item->pingCtlTestNameLen;
  1131.             /* add lock to protect */
  1132.             pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
  1133.             pthread_mutex_lock(&counter_mutex);
  1134.             if (item->pingProbeHistoryMaxIndex >=
  1135.                 (unsigned long) (2147483647))
  1136.                 item->pingProbeHistoryMaxIndex = 0;
  1137.             temp->pingProbeHistoryIndex =
  1138.                 ++(item->pingProbeHistoryMaxIndex);
  1139.             pthread_mutex_unlock(&counter_mutex);
  1140.             temp->pingProbeHistoryResponse = rtt;
  1141.             temp->pingProbeHistoryStatus = 1;
  1142.             temp->pingProbeHistoryLastRC = 0;
  1143.             temp->pingProbeHistoryTime =
  1144.                 (char *) malloc(strlen(asctime(gmtime(&timep))));
  1145.             temp->pingProbeHistoryTime = strdup(asctime(gmtime(&timep)));
  1146.             temp->pingProbeHistoryTime[strlen(asctime(gmtime(&timep))) -
  1147.                                        1] = '';
  1148.             temp->pingProbeHistoryTimeLen =
  1149.                 strlen(asctime(gmtime(&timep))) - 1;
  1150.             if (StorageNew->pingResultsSendProbes == 1)
  1151.                 item->pingProbeHis = temp;
  1152.             else {
  1153.                 (current_temp)->next = temp;
  1154.             }
  1155.             current_temp = temp;
  1156.             if (StorageNew->pingResultsSendProbes >=
  1157.                 item->pingCtlProbeCount) {
  1158.                 current_temp->next = NULL;
  1159.             }
  1160.             if (item->pingProbeHis != NULL)
  1161.                 if (pingProbeHistoryTable_count(item) <
  1162.                     item->pingCtlMaxRows) {
  1163.                     if (pingProbeHistoryTable_add(current_temp) !=
  1164.                         SNMPERR_SUCCESS)
  1165.                         DEBUGMSGTL(("pingProbeHistoryTable",
  1166.                                     "registered an entry errorn"));
  1167.                 } else {
  1168.                     pingProbeHistoryTable_delLast(item);
  1169.                     if (pingProbeHistoryTable_add(current_temp) !=
  1170.                         SNMPERR_SUCCESS)
  1171.                         DEBUGMSGTL(("pingProbeHistoryTable",
  1172.                                     "registered an entry errorn"));
  1173.                 }
  1174.         }
  1175.     }
  1176.     else if (flag == 1)
  1177.     {
  1178.         if (series == 0)
  1179.             probeFailed = 1;
  1180.         else
  1181.             probeFailed = probeFailed + 1;
  1182.         series = 1;
  1183.         testFailed = testFailed + 1;
  1184.         snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->pingCtlOwnerIndex, item->pingCtlOwnerIndexLen); /*  pingCtlOwnerIndex */
  1185.         snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->pingCtlTestName, item->pingCtlTestNameLen);     /* pingCtlTestName */
  1186.         if ((StorageNew =
  1187.              header_complex_get(pingResultsTableStorage, vars)) == NULL)
  1188.             return SNMP_ERR_NOSUCHNAME;
  1189.         if (current_probe == 1) {
  1190.             *averagertt = rtt;
  1191.             *minrtt = rtt;
  1192.             *maxrtt = rtt;
  1193.             *sumrtt = rtt;
  1194.         }
  1195.         StorageNew->pingResultsSendProbes =
  1196.             StorageNew->pingResultsSendProbes + 1;
  1197.         temp = SNMP_MALLOC_STRUCT(pingProbeHistoryTable_data);
  1198.         temp->pingCtlOwnerIndex =
  1199.             (char *) malloc(item->pingCtlOwnerIndexLen + 1);
  1200.         memcpy(temp->pingCtlOwnerIndex, item->pingCtlOwnerIndex,
  1201.                item->pingCtlOwnerIndexLen + 1);
  1202.         temp->pingCtlOwnerIndex[item->pingCtlOwnerIndexLen] = '';
  1203.         temp->pingCtlOwnerIndexLen = item->pingCtlOwnerIndexLen;
  1204.         temp->pingCtlTestName =
  1205.             (char *) malloc(item->pingCtlTestNameLen + 1);
  1206.         memcpy(temp->pingCtlTestName, item->pingCtlTestName,
  1207.                item->pingCtlTestNameLen + 1);
  1208.         temp->pingCtlTestName[item->pingCtlTestNameLen] = '';
  1209.         temp->pingCtlTestNameLen = item->pingCtlTestNameLen;
  1210.         /* add lock to protect */
  1211.         pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
  1212.         pthread_mutex_lock(&counter_mutex);
  1213.         temp->pingProbeHistoryIndex = ++(item->pingProbeHistoryMaxIndex);
  1214.         pthread_mutex_unlock(&counter_mutex);
  1215.         /* end */
  1216.         temp->pingProbeHistoryResponse = item->pingCtlTimeOut * 1000;
  1217.         temp->pingProbeHistoryStatus = 4;
  1218.         temp->pingProbeHistoryLastRC = 1;
  1219.         temp->pingProbeHistoryTime =
  1220.             (char *) malloc(strlen(asctime(gmtime(&timep))));
  1221.         temp->pingProbeHistoryTime = strdup(asctime(gmtime(&timep)));
  1222.         temp->pingProbeHistoryTime[strlen(asctime(gmtime(&timep))) - 1] =
  1223.             '';
  1224.         temp->pingProbeHistoryTimeLen =
  1225.             strlen(asctime(gmtime(&timep))) - 1;
  1226.         if (StorageNew->pingResultsSendProbes == 1)
  1227.             item->pingProbeHis = temp;
  1228.         else {
  1229.             (current_temp)->next = temp;
  1230.         }
  1231.         current_temp = temp;
  1232.         if (StorageNew->pingResultsSendProbes >= item->pingCtlProbeCount) {
  1233.             current_temp->next = NULL;
  1234.         }
  1235.         if (item->pingProbeHis != NULL)
  1236.             if (pingProbeHistoryTable_count(item) < item->pingCtlMaxRows) {
  1237.                 if (pingProbeHistoryTable_add(current_temp) !=
  1238.                     SNMPERR_SUCCESS)
  1239.                     DEBUGMSGTL(("pingProbeHistoryTable",
  1240.                                 "registered an entry errorn"));
  1241.             } else {
  1242.                 pingProbeHistoryTable_delLast(item);
  1243.                 if (pingProbeHistoryTable_add(current_temp) !=
  1244.                     SNMPERR_SUCCESS)
  1245.                     DEBUGMSGTL(("pingProbeHistoryTable",
  1246.                                 "registered an entry errorn"));
  1247.             }
  1248.         if ((item->
  1249.              pingCtlTrapGeneration[0] & PINGTRAPGENERATION_PROBEFAILED) !=
  1250.             0) {
  1251.             if (probeFailed >= item->pingCtlTrapProbeFailureFilter)
  1252.                 send_ping_trap(item, pingProbeFailed,
  1253.                                sizeof(pingProbeFailed) / sizeof(oid));
  1254.         }
  1255.     }
  1256.     if (current_probe == item->pingCtlProbeCount) {
  1257.         if ((item->
  1258.              pingCtlTrapGeneration[0] & PINGTRAPGENERATION_TESTCOMPLETED)
  1259.             != 0) {
  1260.             send_ping_trap(item, pingTestCompleted,
  1261.                            sizeof(pingTestCompleted) / sizeof(oid));
  1262.         } else
  1263.             if ((item->
  1264.                  pingCtlTrapGeneration[0] & PINGTRAPGENERATION_TESTFAILED)
  1265.                 != 0) {
  1266.             if (testFailed >= item->pingCtlTrapTestFailureFilter)
  1267.                 send_ping_trap(item, pingTestFailed,
  1268.                                sizeof(pingTestFailed) / sizeof(oid));
  1269.         }
  1270.         else if ((item->
  1271.                   pingCtlTrapGeneration[0] &
  1272.                   PINGTRAPGENERATION_PROBEFAILED) != 0) {;
  1273.         } else {
  1274.             ;
  1275.         }
  1276.         series = 0;
  1277.         probeFailed = 0;
  1278.         testFailed = 0;
  1279.     }
  1280.     return;
  1281. }
  1282. void
  1283. send_v4(int datalen, pid_t pid, int nsent, int sockfd, char *sendbuf)
  1284. {
  1285.     int             len;
  1286.     struct icmp    *icmp = NULL;
  1287.     struct timeval *temp = NULL;
  1288.     icmp = (struct icmp *) sendbuf;
  1289.     icmp->icmp_type = ICMP_ECHO;
  1290.     icmp->icmp_code = 0;
  1291.     icmp->icmp_id = pid;
  1292.     icmp->icmp_seq = nsent;
  1293.     gettimeofday((struct timeval *) icmp->icmp_data, NULL);
  1294.     temp = (struct timeval *) icmp->icmp_data;
  1295.     len = 8 + datalen;          /* checksum ICMP header and data */
  1296.     icmp->icmp_cksum = 0;
  1297.     icmp->icmp_cksum = in_cksum((u_short *) icmp, len);
  1298.     sendto(sockfd, sendbuf, len, 0, pr->sasend, pr->salen);
  1299. }
  1300. void
  1301. run_ping(unsigned int clientreg, void *clientarg)
  1302. /* run_ping(struct pingCtlTable_data *item) */
  1303. {
  1304.     struct pingCtlTable_data *item = clientarg;
  1305.     netsnmp_variable_list *vars = NULL;
  1306.     struct pingResultsTable_data *StorageNew = NULL;
  1307.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->pingCtlOwnerIndex, item->pingCtlOwnerIndexLen);     /* pingCtlOwnerIndex  */
  1308.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->pingCtlTestName, item->pingCtlTestNameLen); /* pingCtlTestName  */
  1309.     if ((StorageNew =
  1310.          header_complex_get(pingResultsTableStorage, vars)) == NULL)
  1311.         return;
  1312.     StorageNew->pingResultsSendProbes = 0;
  1313.     StorageNew->pingResultsProbeResponses = 0;
  1314.     if (item->pingCtlTargetAddressType == 1
  1315.         || item->pingCtlTargetAddressType == 16) {
  1316.         struct proto    proto_v4 =
  1317.             { proc_v4, send_v4, NULL, NULL, 0, IPPROTO_ICMP };
  1318.         char           *host = NULL;
  1319.         pid_t           pid;    /* our PID */
  1320.         int             datalen;
  1321.         unsigned long  *minrtt = NULL;
  1322.         unsigned long  *maxrtt = NULL;
  1323.         unsigned long  *averagertt = NULL;
  1324.         datalen = 56;           /* data that goes with ICMP echo request */
  1325.         unsigned int    n = 1;
  1326.         int             c;
  1327.         struct addrinfo *ai = NULL;
  1328.         minrtt = malloc(sizeof(unsigned long));
  1329.         maxrtt = malloc(sizeof(unsigned long));
  1330.         averagertt = malloc(sizeof(unsigned long));
  1331.         host = item->pingCtlTargetAddress;
  1332.         pid = getpid();
  1333.         ai = host_serv(host, NULL, 0, 0);
  1334.         printf("PING %s (%s): %d data bytesn", ai->ai_canonname,
  1335.                sock_ntop_host(ai->ai_addr, ai->ai_addrlen), datalen);
  1336.         /*
  1337.          * 4initialize according to protocol 
  1338.          */
  1339.         if (ai->ai_family == AF_INET) {
  1340.             pr = &proto_v4;
  1341. #ifdef IPV6
  1342.         } else if (ai->ai_family == AF_INET6) {
  1343.             pr = &proto_v6;
  1344.             if (IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *)
  1345.                                         ai->ai_addr)->sin6_addr)))
  1346.                 printf("cannot ping IPv4-mapped IPv6 address");
  1347. #endif
  1348.         } else
  1349.             printf("unknown address family %d", ai->ai_family);
  1350.         pr->sasend = ai->ai_addr;
  1351.         pr->sarecv = calloc(1, ai->ai_addrlen);
  1352.         pr->salen = ai->ai_addrlen;
  1353.         readloop(item, ai, datalen, minrtt, maxrtt, averagertt, pid);
  1354.         SNMP_FREE(minrtt);
  1355.         minrtt = NULL;
  1356.         SNMP_FREE(maxrtt);
  1357.         maxrtt = NULL;
  1358.         SNMP_FREE(averagertt);
  1359.         averagertt = NULL;
  1360.         free(ai);
  1361.         ai = NULL;
  1362.     }
  1363.     else if (item->pingCtlTargetAddressType == 2) {
  1364.         int             ch = 0, hold = 0, packlen = 0;
  1365.         u_char         *packet = NULL;
  1366.         char           *target = NULL;
  1367.         struct sockaddr_in6 firsthop;
  1368.         int             socket_errno = 0;
  1369.         struct icmp6_filter filter;
  1370.         int             err = 0, csum_offset = 0, sz_opt = 0;
  1371.         static int      icmp_sock = 0;
  1372.         int             uid = 0;
  1373.         struct sockaddr_in6 source;
  1374.         int             preload = 0;
  1375.         struct cmsghdr *srcrt = NULL;
  1376.         static unsigned char cmsgbuf[4096];
  1377.         static int      cmsglen = 0;
  1378.         struct sockaddr_in6 whereto;    /* who to ping */
  1379.         int             options = 0;
  1380.         char           *hostname = NULL;
  1381.         char           *device = NULL;
  1382.         int             interval = 1000;        /* interval between packets (msec) */
  1383.         int             pmtudisc = -1;
  1384.         int             datalen = DEFDATALEN;
  1385.         int             timing = 0;     /* flag to do timing */
  1386.         int             working_recverr = 0;
  1387.         __u32           flowlabel = 0;
  1388.         __u32           tclass = 0;
  1389.         int             ident = 0;      /* process id to identify our packets */
  1390.         u_char          outpack[MAX_PACKET];
  1391.         struct timeval  start_time;
  1392.         static int      screen_width = INT_MAX;
  1393.         int             deadline = 0;   /* time to die */
  1394.         int             timeout = 0;
  1395.         timeout = item->pingCtlTimeOut;
  1396.         memset(&source, 0, sizeof(source));
  1397.         icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
  1398.         socket_errno = errno;
  1399.         uid = getuid();
  1400.         setuid(uid);
  1401.         source.sin6_family = AF_INET6;
  1402.         memset(&firsthop, 0, sizeof(firsthop));
  1403.         firsthop.sin6_family = AF_INET6;
  1404.         preload = 1;
  1405.         target = item->pingCtlTargetAddress;
  1406.         memset(&whereto, 0, sizeof(struct sockaddr_in6));
  1407.         whereto.sin6_family = AF_INET6;
  1408.         whereto.sin6_port = htons(IPPROTO_ICMPV6);
  1409.         if (inet_pton(AF_INET6, target, &whereto.sin6_addr) <= 0) {
  1410.             struct hostent *hp = NULL;
  1411.             hp = gethostbyname2(target, AF_INET6);
  1412.             if (hp == NULL) {
  1413.                 fprintf(stderr, "unknown hostn");
  1414.                 return;
  1415.             }
  1416.             memcpy(&whereto.sin6_addr, hp->h_addr_list[0], 16);
  1417.         } else {
  1418.             options |= F_NUMERIC;
  1419.         }
  1420.         if (ipv6_addr_any(&firsthop.sin6_addr))
  1421.             memcpy(&firsthop.sin6_addr, &whereto.sin6_addr, 16);
  1422.         hostname = target;
  1423.         if (ipv6_addr_any(&source.sin6_addr)) {
  1424.             int             alen;
  1425.             int             probe_fd = socket(AF_INET6, SOCK_DGRAM, 0);
  1426.             if (probe_fd < 0) {
  1427.                 printf("error!n");
  1428.                 perror("socket");
  1429.                 return;
  1430.             }
  1431.             if (device) {
  1432.                 struct ifreq    ifr;
  1433.                 memset(&ifr, 0, sizeof(ifr));
  1434.                 strncpy(ifr.ifr_name, device, IFNAMSIZ - 1);
  1435.                 if (setsockopt
  1436.                     (probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device,
  1437.                      strlen(device) + 1) == -1) {
  1438. #ifdef HAVE_SIN6_SCOPEID
  1439.                     if ((firsthop.sin6_addr.
  1440.                          s6_addr16[0] & htons(0xffc0)) == htons(0xfe80)
  1441.                         || (firsthop.sin6_addr.
  1442.                             s6_addr16[0] & htons(0xffff)) ==
  1443.                         htons(0xff02)) {
  1444.                         if (ioctl(probe_fd, SIOCGIFINDEX, &ifr) < 0) {
  1445.                             fprintf(stderr, "ping: unknown iface %sn",
  1446.                                     device);
  1447.                             return;
  1448.                         }
  1449.                         firsthop.sin6_scope_id = ifr.ifr_ifindex;
  1450.                     }
  1451. #endif
  1452.                 }
  1453.             }
  1454.             firsthop.sin6_port = htons(1025);
  1455.             if (connect
  1456.                 (probe_fd, (struct sockaddr *) &firsthop,
  1457.                  sizeof(firsthop)) == -1) {
  1458.                 perror("connect");
  1459.                 return;
  1460.             }
  1461.             alen = sizeof(source);
  1462.             if (getsockname(probe_fd, (struct sockaddr *) &source, &alen)
  1463.                 == -1) {
  1464.                 perror("getsockname");
  1465.                 return;
  1466.             }
  1467.             source.sin6_port = 0;
  1468.             close(probe_fd);
  1469.         }
  1470.         if (icmp_sock < 0) {
  1471.             errno = socket_errno;
  1472.             perror("ping: icmp open socket");
  1473.             return;
  1474.         }
  1475.         if ((whereto.sin6_addr.s6_addr16[0] & htons(0xff00)) ==
  1476.             htons(0xff00)) {
  1477.             if (uid) {
  1478.                 if (interval < 1000) {
  1479.                     fprintf(stderr,
  1480.                             "ping: multicast ping with too short interval.n");
  1481.                     return;
  1482.                 }
  1483.                 if (pmtudisc >= 0 && pmtudisc != IPV6_PMTUDISC_DO) {
  1484.                     fprintf(stderr,
  1485.                             "ping: multicast ping does not fragment.n");
  1486.                     return;
  1487.                 }
  1488.             }
  1489.             if (pmtudisc < 0)
  1490.                 pmtudisc = IPV6_PMTUDISC_DO;
  1491.         }
  1492.         if (pmtudisc >= 0) {
  1493.             if (setsockopt
  1494.                 (icmp_sock, SOL_IPV6, IPV6_MTU_DISCOVER, &pmtudisc,
  1495.                  sizeof(pmtudisc)) == -1) {
  1496.                 perror("ping: IPV6_MTU_DISCOVER");
  1497.                 return;
  1498.             }
  1499.         }
  1500.         if (bind(icmp_sock, (struct sockaddr *) &source, sizeof(source)) ==
  1501.             -1) {
  1502.             perror("ping: bind icmp socket");
  1503.             return;
  1504.         }
  1505.         if (datalen >= sizeof(struct timeval))  /* can we time transfer */
  1506.             timing = 1;
  1507.         packlen = datalen + 8 + 4096 + 40 + 8;  /* 4096 for rthdr */
  1508.         if (!(packet = (u_char *) malloc((u_int) packlen))) {
  1509.             fprintf(stderr, "ping: out of memory.n");
  1510.             return;
  1511.         }
  1512.         working_recverr = 1;
  1513.         hold = 1;
  1514.         if (setsockopt
  1515.             (icmp_sock, SOL_IPV6, IPV6_RECVERR, (char *) &hold,
  1516.              sizeof(hold))) {
  1517.             fprintf(stderr,
  1518.                     "WARNING: your kernel is veeery old. No problems.n");
  1519.             working_recverr = 0;
  1520.         }
  1521.         /*
  1522.          * Estimate memory eaten by single packet. It is rough estimate.
  1523.          * * Actually, for small datalen's it depends on kernel side a lot. 
  1524.          */
  1525.         hold = datalen + 8;
  1526.         hold += ((hold + 511) / 512) * (40 + 16 + 64 + 160);
  1527.         sock_setbufs(icmp_sock, hold, preload);
  1528.         csum_offset = 2;
  1529.         sz_opt = sizeof(int);
  1530.         err =
  1531.             setsockopt(icmp_sock, SOL_RAW, IPV6_CHECKSUM, &csum_offset,
  1532.                        sz_opt);
  1533.         if (err < 0) {
  1534.             perror("setsockopt(RAW_CHECKSUM)");
  1535.             return;
  1536.         }
  1537.         /*
  1538.          *      select icmp echo reply as icmp type to receive
  1539.          */
  1540.         ICMPV6_FILTER_SETBLOCKALL(&filter);
  1541.         if (!working_recverr) {
  1542.             ICMPV6_FILTER_SETPASS(ICMPV6_DEST_UNREACH, &filter);
  1543.             ICMPV6_FILTER_SETPASS(ICMPV6_PKT_TOOBIG, &filter);
  1544.             ICMPV6_FILTER_SETPASS(ICMPV6_TIME_EXCEED, &filter);
  1545.             ICMPV6_FILTER_SETPASS(ICMPV6_PARAMPROB, &filter);
  1546.         }
  1547.         ICMPV6_FILTER_SETPASS(ICMPV6_ECHO_REPLY, &filter);
  1548.         err = setsockopt(icmp_sock, SOL_ICMPV6, ICMPV6_FILTER, &filter,
  1549.                          sizeof(struct icmp6_filter));
  1550.         if (err < 0) {
  1551.             perror("setsockopt(ICMPV6_FILTER)");
  1552.             return;
  1553.         }
  1554.         if (1) {
  1555.             int             on = 1;
  1556.             if (setsockopt(icmp_sock, IPPROTO_IPV6, IPV6_HOPLIMIT,
  1557.                            &on, sizeof(on)) == -1) {
  1558.                 perror("can't receive hop limit");
  1559.                 return;
  1560.             }
  1561.         }
  1562.         printf("PING %s(%s) ", hostname,
  1563.                pr_addr(&whereto.sin6_addr, options));
  1564.         if (flowlabel)
  1565.             printf(", flow 0x%05x, ", (unsigned) ntohl(flowlabel));
  1566.         if (device || (options & F_NUMERIC)) {
  1567.             printf("from %s %s: ",
  1568.                    pr_addr_n(&source.sin6_addr), device ? : "");
  1569.         }
  1570.         printf("%d data bytesn", datalen);
  1571.         setup(icmp_sock, options, uid, timeout, preload, interval, datalen,
  1572.               (char *) outpack, &ident, &start_time, &screen_width,
  1573.               &deadline);
  1574.         main_loop(item, icmp_sock, preload, packet, packlen, cmsglen,
  1575.                   (char *) cmsgbuf, &whereto, options, uid, hostname,
  1576.                   interval, datalen, timing, working_recverr,
  1577.                   (char *) outpack, &ident, &start_time, &screen_width,
  1578.                   &deadline);
  1579.     }
  1580.     return;
  1581. }
  1582. void
  1583. init_resultsTable(struct pingCtlTable_data *item)
  1584. {
  1585.     struct pingResultsTable_data *StorageTmp = NULL;
  1586.     struct pingResultsTable_data *StorageNew = NULL;
  1587.     struct addrinfo *ai = NULL;
  1588.     char           *host = NULL;
  1589.     netsnmp_variable_list *vars = NULL;
  1590.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->pingCtlOwnerIndex, item->pingCtlOwnerIndexLen);     /* pingCtlOwnerIndex  */
  1591.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->pingCtlTestName, item->pingCtlTestNameLen); /* pingCtlTestName  */
  1592.     if ((StorageNew =
  1593.          header_complex_get(pingResultsTableStorage, vars)) != NULL) {
  1594.         StorageNew->pingResultsSendProbes = 0;
  1595.         StorageNew->pingResultsProbeResponses = 0;
  1596.         return;
  1597.     }
  1598.     ai = malloc(sizeof(struct addrinfo));
  1599.     host = item->pingCtlTargetAddress;
  1600.     ai = host_serv(host, NULL, 0, 0);
  1601.     StorageTmp = SNMP_MALLOC_STRUCT(pingResultsTable_data);
  1602.     StorageTmp->pingCtlOwnerIndex =
  1603.         (char *) malloc(item->pingCtlOwnerIndexLen + 1);
  1604.     memcpy(StorageTmp->pingCtlOwnerIndex, item->pingCtlOwnerIndex,
  1605.            item->pingCtlOwnerIndexLen + 1);
  1606.     StorageTmp->pingCtlOwnerIndex[item->pingCtlOwnerIndexLen] = '';
  1607.     StorageTmp->pingCtlOwnerIndexLen = item->pingCtlOwnerIndexLen;
  1608.     StorageTmp->pingCtlTestName =
  1609.         (char *) malloc(item->pingCtlTestNameLen + 1);
  1610.     memcpy(StorageTmp->pingCtlTestName, item->pingCtlTestName,
  1611.            item->pingCtlTestNameLen + 1);
  1612.     StorageTmp->pingCtlTestName[item->pingCtlTestNameLen] = '';
  1613.     StorageTmp->pingCtlTestNameLen = item->pingCtlTestNameLen;
  1614.     StorageTmp->pingResultsOperStatus = 1;
  1615.     if (item->pingCtlTargetAddressType == 1
  1616.         || item->pingCtlTargetAddressType == 16) {
  1617.         if (ai == NULL) {
  1618.             StorageTmp->pingResultsIpTargetAddressType = 0;
  1619.             StorageTmp->pingResultsIpTargetAddress = strdup("");
  1620.             StorageTmp->pingResultsIpTargetAddressLen = 0;
  1621.         } else {
  1622.             StorageTmp->pingResultsIpTargetAddressType = 1;
  1623.             StorageTmp->pingResultsIpTargetAddress =
  1624.                 (char *)
  1625.                 malloc(strlen(sock_ntop_host(ai->ai_addr, ai->ai_addrlen))
  1626.                        + 1);
  1627.             StorageTmp->pingResultsIpTargetAddress =
  1628.                 strdup(sock_ntop_host(ai->ai_addr, ai->ai_addrlen));
  1629.             StorageTmp->
  1630.                 pingResultsIpTargetAddress[strlen
  1631.                                            (sock_ntop_host
  1632.                                             (ai->ai_addr,
  1633.                                              ai->ai_addrlen))] = '';
  1634.             StorageTmp->pingResultsIpTargetAddressLen =
  1635.                 strlen(sock_ntop_host(ai->ai_addr, ai->ai_addrlen));
  1636.         }
  1637.     }
  1638.     if (item->pingCtlTargetAddressType == 2) {
  1639.         struct sockaddr_in6 whereto;    /* Who to try to reach */
  1640.         register struct sockaddr_in6 *to =
  1641.             (struct sockaddr_in6 *) &whereto;
  1642.         struct hostent *hp = NULL;
  1643.         char            pa[64];
  1644.         to->sin6_family = AF_INET6;
  1645.         to->sin6_port = htons(33434);
  1646.         if (inet_pton(AF_INET6, host, &to->sin6_addr) > 0) {
  1647.             StorageTmp->pingResultsIpTargetAddressType = 2;
  1648.             StorageTmp->pingResultsIpTargetAddress =
  1649.                 (char *) malloc(strlen(host) + 1);
  1650.             StorageTmp->pingResultsIpTargetAddress = strdup(host);
  1651.             StorageTmp->pingResultsIpTargetAddress[strlen(host)] = '';
  1652.             StorageTmp->pingResultsIpTargetAddressLen = strlen(host);
  1653.         } else {
  1654.             hp = gethostbyname2(host, AF_INET6);
  1655.             if (hp != NULL) {
  1656.                 const char     *hostname = NULL;
  1657.                 memmove((caddr_t) & to->sin6_addr, hp->h_addr, 16);
  1658.                 hostname = inet_ntop(AF_INET6, &to->sin6_addr, pa, 64);
  1659.                 StorageTmp->pingResultsIpTargetAddressType = 2;
  1660.                 StorageTmp->pingResultsIpTargetAddress =
  1661.                     (char *) malloc(strlen(hostname) + 1);
  1662.                 StorageTmp->pingResultsIpTargetAddress = strdup(hostname);
  1663.                 StorageTmp->pingResultsIpTargetAddress[strlen(hostname)] =
  1664.                     '';
  1665.                 StorageTmp->pingResultsIpTargetAddressLen =
  1666.                     strlen(hostname);
  1667.             } else {
  1668.                 (void) fprintf(stderr,
  1669.                                "traceroute: unknown host %sn", host);
  1670.                 StorageTmp->pingResultsIpTargetAddressType = 0;
  1671.                 StorageTmp->pingResultsIpTargetAddress = strdup("");
  1672.                 StorageTmp->pingResultsIpTargetAddressLen = 0;
  1673.             }
  1674.         }
  1675.     }
  1676.     StorageTmp->pingResultsMinRtt = 0;
  1677.     StorageTmp->pingResultsMaxRtt = 0;
  1678.     StorageTmp->pingResultsAverageRtt = 0;
  1679.     StorageTmp->pingResultsProbeResponses = 0;
  1680.     StorageTmp->pingResultsSendProbes = 0;
  1681.     StorageTmp->pingResultsRttSumOfSquares = 0;
  1682.     StorageTmp->pingResultsLastGoodProbe = strdup("");
  1683.     StorageTmp->pingResultsLastGoodProbeLen = 0;
  1684.     item->pingResults = StorageTmp;
  1685.     if (item->pingProbeHistoryMaxIndex == 0) {
  1686.         if (item->pingResults != NULL) {
  1687.             if (pingResultsTable_add(item) != SNMPERR_SUCCESS) {
  1688.                 DEBUGMSGTL(("pingResultsTable", "init an entry errorn"));
  1689.             }
  1690.         }
  1691.     }
  1692.     SNMP_FREE(ai);
  1693.     ai = NULL;
  1694. }
  1695. int
  1696. modify_ResultsOper(struct pingCtlTable_data *thedata, long val)
  1697. {
  1698.     netsnmp_variable_list *vars = NULL;
  1699.     struct pingResultsTable_data *StorageTmp = NULL;
  1700.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->pingCtlOwnerIndex, thedata->pingCtlOwnerIndexLen);       /* pingCtlOwnerIndex */
  1701.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->pingCtlTestName, thedata->pingCtlTestNameLen);   /* pingCtlTestName */
  1702.     if ((StorageTmp =
  1703.          header_complex_get(pingResultsTableStorage, vars)) == NULL)
  1704.         return SNMP_ERR_NOSUCHNAME;
  1705.     StorageTmp->pingResultsOperStatus = val;
  1706.     DEBUGMSGTL(("pingResultsOperStatus", "done.n"));
  1707.     return SNMPERR_SUCCESS;
  1708. }
  1709. int
  1710. pingResultsTable_del(struct pingCtlTable_data *thedata)
  1711. {
  1712.     struct header_complex_index *hciptr2 = NULL;
  1713.     struct pingResultsTable_data *StorageDel = NULL;
  1714.     netsnmp_variable_list *vars = NULL;
  1715.     oid             newoid[MAX_OID_LEN];
  1716.     size_t          newoid_len;
  1717.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->pingCtlOwnerIndex, thedata->pingCtlOwnerIndexLen);       /* pingCtlOwnerIndex */
  1718.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->pingCtlTestName, thedata->pingCtlTestNameLen);   /* pingCtlOperationName */
  1719.     header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars);
  1720.     for (hciptr2 = pingResultsTableStorage; hciptr2 != NULL;
  1721.          hciptr2 = hciptr2->next) {
  1722.         if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len)
  1723.             == 0) {
  1724.             StorageDel =
  1725.                 header_complex_extract_entry(&pingResultsTableStorage,
  1726.                                              hciptr2);
  1727.             if (StorageDel != NULL) {
  1728.                 SNMP_FREE(StorageDel->pingCtlOwnerIndex);
  1729.                 SNMP_FREE(StorageDel->pingCtlTestName);
  1730.                 SNMP_FREE(StorageDel->pingResultsIpTargetAddress);
  1731.                 SNMP_FREE(StorageDel->pingResultsLastGoodProbe);
  1732.                 SNMP_FREE(StorageDel);
  1733.             }
  1734.             DEBUGMSGTL(("pingResultsTable", "delete  success!n"));
  1735.         }
  1736.     }
  1737.     return SNMPERR_SUCCESS;
  1738. }
  1739. int
  1740. pingProbeHistoryTable_del(struct pingCtlTable_data *thedata)
  1741. {
  1742.     struct header_complex_index *hciptr2 = NULL;
  1743.     struct pingProbeHistoryTable_data *StorageDel = NULL;
  1744.     netsnmp_variable_list *vars = NULL;
  1745.     oid             newoid[MAX_OID_LEN];
  1746.     size_t          newoid_len;
  1747.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->pingCtlOwnerIndex, thedata->pingCtlOwnerIndexLen);       /* pingCtlOwnerIndex */
  1748.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->pingCtlTestName, thedata->pingCtlTestNameLen);   /* pingCtlOperationName */
  1749.     header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars);
  1750.     for (hciptr2 = pingProbeHistoryTableStorage; hciptr2 != NULL;
  1751.          hciptr2 = hciptr2->next) {
  1752.         if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len)
  1753.             == 0) {
  1754.             StorageDel =
  1755.                 header_complex_extract_entry(&pingProbeHistoryTableStorage,
  1756.                                              hciptr2);
  1757.             if (StorageDel != NULL) {
  1758.                 SNMP_FREE(StorageDel->pingCtlOwnerIndex);
  1759.                 SNMP_FREE(StorageDel->pingCtlTestName);
  1760.                 SNMP_FREE(StorageDel->pingProbeHistoryTime);
  1761.                 SNMP_FREE(StorageDel);
  1762.             }
  1763.             DEBUGMSGTL(("pingProbeHistoryTable", "delete  success!n"));
  1764.         }
  1765.     }
  1766.     return SNMPERR_SUCCESS;
  1767. }
  1768. int
  1769. write_pingCtlTargetAddressType(int action,
  1770.                                u_char * var_val,
  1771.                                u_char var_val_type,
  1772.                                size_t var_val_len,
  1773.                                u_char * statP, oid * name, size_t name_len)
  1774. {
  1775.     static size_t   tmpvar;
  1776.     struct pingCtlTable_data *StorageTmp = NULL;
  1777.     static size_t   tmplen;
  1778.     size_t          newlen =
  1779.         name_len - (sizeof(pingCtlTable_variables_oid) / sizeof(oid) +
  1780.                     3 - 1);
  1781.     DEBUGMSGTL(("pingCtlTable",
  1782.                 "write_pingCtlTargetAddressType entering action=%d...  n",
  1783.                 action));
  1784.     if ((StorageTmp =
  1785.          header_complex(pingCtlTableStorage, NULL,
  1786.                         &name[sizeof(pingCtlTable_variables_oid) /
  1787.                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
  1788.                         NULL)) == NULL)
  1789.         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  1790.     if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
  1791.         return SNMP_ERR_NOTWRITABLE;
  1792.     }
  1793.     if (StorageTmp && StorageTmp->pingCtlRowStatus == RS_ACTIVE) {
  1794.         return SNMP_ERR_NOTWRITABLE;
  1795.     }
  1796.     switch (action) {
  1797.     case RESERVE1:
  1798.         if (var_val_type != ASN_INTEGER) {
  1799.             snmp_log(LOG_ERR,
  1800.                      "write to pingCtlTargetAddressType not ASN_INTEGERn");
  1801.             return SNMP_ERR_WRONGTYPE;
  1802.         }
  1803.         break;
  1804.     case RESERVE2:
  1805.         /*
  1806.          * memory reseveration, final preparation... 
  1807.          */
  1808.         break;
  1809.     case FREE:
  1810.         /*
  1811.          * Release any resources that have been allocated 
  1812.          */
  1813.         break;
  1814.     case ACTION:
  1815.         /*
  1816.          * The variable has been stored in objid for
  1817.          * you to use, and you have just been asked to do something with
  1818.          * it.  Note that anything done here must be reversable in the UNDO case 
  1819.          */
  1820.         tmpvar = StorageTmp->pingCtlTargetAddressType;
  1821.         StorageTmp->pingCtlTargetAddressType = *((long *) var_val);
  1822.         break;
  1823.     case UNDO:
  1824.         /*
  1825.          * Back out any changes made in the ACTION case 
  1826.          */
  1827.         StorageTmp->pingCtlTargetAddressType = tmpvar;
  1828.         break;
  1829.     case COMMIT:
  1830.         /*
  1831.          * Things are working well, so it's now safe to make the change
  1832.          * permanently.  Make sure that anything done here can't fail! 
  1833.          */
  1834.         break;
  1835.     }
  1836.     return SNMP_ERR_NOERROR;
  1837. }
  1838. int
  1839. write_pingCtlTargetAddress(int action,
  1840.                            u_char * var_val,
  1841.                            u_char var_val_type,
  1842.                            size_t var_val_len,
  1843.                            u_char * statP, oid * name, size_t name_len)
  1844. {
  1845.     static char    *tmpvar;
  1846.     static size_t   tmplen;
  1847.     struct pingCtlTable_data *StorageTmp = NULL;
  1848.     size_t          newlen =
  1849.         name_len - (sizeof(pingCtlTable_variables_oid) / sizeof(oid) +
  1850.                     3 - 1);
  1851.     if ((StorageTmp =
  1852.          header_complex(pingCtlTableStorage, NULL,
  1853.                         &name[sizeof(pingCtlTable_variables_oid) /
  1854.                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
  1855.                         NULL)) == NULL)
  1856.         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  1857.     if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
  1858.         return SNMP_ERR_NOTWRITABLE;
  1859.     }
  1860.     if (StorageTmp && StorageTmp->pingCtlRowStatus == RS_ACTIVE) {
  1861.         return SNMP_ERR_NOTWRITABLE;
  1862.     }
  1863.     switch (action) {
  1864.     case RESERVE1:
  1865.         if (var_val_type != ASN_OCTET_STR) {
  1866.             snmp_log(LOG_ERR,
  1867.                      "write to pingCtlTargetAddress not ASN_OCTET_STRn");
  1868.             return SNMP_ERR_WRONGTYPE;
  1869.         }
  1870.         break;
  1871.     case RESERVE2:
  1872.         /*
  1873.          * memory reseveration, final preparation... 
  1874.          */
  1875.         break;
  1876.     case FREE:
  1877.         /*
  1878.          * Release any resources that have been allocated 
  1879.          */
  1880.         break;
  1881.     case ACTION:
  1882.         /*
  1883.          * The variable has been stored in long_ret for
  1884.          * you to use, and you have just been asked to do something with
  1885.          * it.  Note that anything done here must be reversable in the UNDO case 
  1886.          */
  1887.         tmpvar = StorageTmp->pingCtlTargetAddress;
  1888.         tmplen = StorageTmp->pingCtlTargetAddressLen;
  1889.         StorageTmp->pingCtlTargetAddress =
  1890.             (char *) malloc(var_val_len + 1);
  1891.         if (StorageTmp->pingCtlTargetAddress == NULL) {
  1892.             exit(1);
  1893.         }
  1894.         memcpy(StorageTmp->pingCtlTargetAddress, var_val, var_val_len);
  1895.         StorageTmp->pingCtlTargetAddress[var_val_len] = '';
  1896.         StorageTmp->pingCtlTargetAddressLen = var_val_len;
  1897.         break;
  1898.     case UNDO:
  1899.         /*
  1900.          * Back out any changes made in the ACTION case 
  1901.          */
  1902.         SNMP_FREE(StorageTmp->pingCtlTargetAddress);
  1903.         StorageTmp->pingCtlTargetAddress = NULL;
  1904.         StorageTmp->pingCtlTargetAddress = tmpvar;
  1905.         StorageTmp->pingCtlTargetAddressLen = tmplen;
  1906.         break;
  1907.     case COMMIT:
  1908.         /*
  1909.          * Things are working well, so it's now safe to make the change
  1910.          * permanently.  Make sure that anything done here can't fail! 
  1911.          */
  1912.         SNMP_FREE(tmpvar);
  1913.         break;
  1914.     }
  1915.     return SNMP_ERR_NOERROR;
  1916. }
  1917. int
  1918. write_pingCtlDataSize(int action,
  1919.                       u_char * var_val,
  1920.                       u_char var_val_type,
  1921.                       size_t var_val_len,
  1922.                       u_char * statP, oid * name, size_t name_len)
  1923. {
  1924.     static size_t   tmpvar;
  1925.     struct pingCtlTable_data *StorageTmp = NULL;
  1926.     static size_t   tmplen;
  1927.     size_t          newlen =
  1928.         name_len - (sizeof(pingCtlTable_variables_oid) / sizeof(oid) +
  1929.                     3 - 1);
  1930.     DEBUGMSGTL(("pingCtlTable",
  1931.                 "pingCtlDataSize entering action=%d...  n", action));
  1932.     if ((StorageTmp =
  1933.          header_complex(pingCtlTableStorage, NULL,
  1934.                         &name[sizeof(pingCtlTable_variables_oid) /
  1935.                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
  1936.                         NULL)) == NULL)
  1937.         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  1938.     if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
  1939.         return SNMP_ERR_NOTWRITABLE;
  1940.     }
  1941.     if (StorageTmp && StorageTmp->pingCtlRowStatus == RS_ACTIVE) {
  1942.         return SNMP_ERR_NOTWRITABLE;
  1943.     }
  1944.     switch (action) {
  1945.     case RESERVE1:
  1946.         if (var_val_type != ASN_UNSIGNED) {
  1947.             snmp_log(LOG_ERR,
  1948.                      "write to pingCtlDataSize not ASN_UNSIGNEDn");
  1949.             return SNMP_ERR_WRONGTYPE;
  1950.         }
  1951.         break;
  1952.     case RESERVE2:
  1953.         /*
  1954.          * memory reseveration, final preparation... 
  1955.          */
  1956.         break;
  1957.     case FREE:
  1958.         /*
  1959.          * Release any resources that have been allocated 
  1960.          */
  1961.         break;
  1962.     case ACTION:
  1963.         /*
  1964.          * The variable has been stored in objid for
  1965.          * you to use, and you have just been asked to do something with
  1966.          * it.  Note that anything done here must be reversable in the UNDO case 
  1967.          */
  1968.         tmpvar = StorageTmp->pingCtlDataSize;
  1969.         if ((*((long *) var_val)) >= 0 && (*((long *) var_val)) <= 65507)
  1970.             StorageTmp->pingCtlDataSize = *((long *) var_val);
  1971.         else
  1972.             StorageTmp->pingCtlDataSize = 56;
  1973.         break;
  1974.     case UNDO:
  1975.         /*
  1976.          * Back out any changes made in the ACTION case 
  1977.          */
  1978.         StorageTmp->pingCtlDataSize = tmpvar;
  1979.         break;
  1980.     case COMMIT:
  1981.         /*
  1982.          * Things are working well, so it's now safe to make the change
  1983.          * permanently.  Make sure that anything done here can't fail! 
  1984.          */
  1985.         break;
  1986.     }
  1987.     return SNMP_ERR_NOERROR;
  1988. }
  1989. int
  1990. write_pingCtlTimeOut(int action,
  1991.                      u_char * var_val,
  1992.                      u_char var_val_type,
  1993.                      size_t var_val_len,
  1994.                      u_char * statP, oid * name, size_t name_len)
  1995. {
  1996.     static size_t   tmpvar;
  1997.     struct pingCtlTable_data *StorageTmp = NULL;
  1998.     static size_t   tmplen;
  1999.     size_t          newlen =
  2000.         name_len - (sizeof(pingCtlTable_variables_oid) / sizeof(oid) +
  2001.                     3 - 1);
  2002.     DEBUGMSGTL(("pingCtlTable",
  2003.                 "pingCtlTimeOut entering action=%d...  n", action));
  2004.     if ((StorageTmp =
  2005.          header_complex(pingCtlTableStorage, NULL,
  2006.                         &name[sizeof(pingCtlTable_variables_oid) /
  2007.                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
  2008.                         NULL)) == NULL)
  2009.         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  2010.     if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
  2011.         return SNMP_ERR_NOTWRITABLE;
  2012.     }
  2013.     if (StorageTmp && StorageTmp->pingCtlRowStatus == RS_ACTIVE) {
  2014.         return SNMP_ERR_NOTWRITABLE;
  2015.     }
  2016.     switch (action) {
  2017.     case RESERVE1:
  2018.         if (var_val_type != ASN_UNSIGNED) {
  2019.             snmp_log(LOG_ERR,
  2020.                      "write to pingCtlDataSize not ASN_UNSIGNEDn");
  2021.             return SNMP_ERR_WRONGTYPE;
  2022.         }
  2023.         break;
  2024.     case RESERVE2:
  2025.         /*
  2026.          * memory reseveration, final preparation... 
  2027.          */
  2028.         break;
  2029.     case FREE:
  2030.         /*
  2031.          * Release any resources that have been allocated 
  2032.          */
  2033.         break;
  2034.     case ACTION:
  2035.         /*
  2036.          * The variable has been stored in objid for
  2037.          * you to use, and you have just been asked to do something with
  2038.          * it.  Note that anything done here must be reversable in the UNDO case 
  2039.          */
  2040.         tmpvar = StorageTmp->pingCtlTimeOut;
  2041.         if ((*((long *) var_val)) >= 1 && (*((long *) var_val)) <= 60)
  2042.             StorageTmp->pingCtlTimeOut = *((long *) var_val);
  2043.         else
  2044.             StorageTmp->pingCtlTimeOut = 3;
  2045.         break;
  2046.     case UNDO:
  2047.         /*
  2048.          * Back out any changes made in the ACTION case 
  2049.          */
  2050.         StorageTmp->pingCtlTimeOut = tmpvar;
  2051.         break;
  2052.     case COMMIT:
  2053.         /*
  2054.          * Things are working well, so it's now safe to make the change
  2055.          * permanently.  Make sure that anything done here can't fail! 
  2056.          */
  2057.         break;
  2058.     }
  2059.     return SNMP_ERR_NOERROR;
  2060. }
  2061. int
  2062. write_pingCtlProbeCount(int action,
  2063.                         u_char * var_val,
  2064.                         u_char var_val_type,
  2065.                         size_t var_val_len,
  2066.                         u_char * statP, oid * name, size_t name_len)
  2067. {
  2068.     static size_t   tmpvar;
  2069.     struct pingCtlTable_data *StorageTmp = NULL;
  2070.     static size_t   tmplen;
  2071.     size_t          newlen =
  2072.         name_len - (sizeof(pingCtlTable_variables_oid) / sizeof(oid) +
  2073.                     3 - 1);
  2074.     DEBUGMSGTL(("pingCtlTable",
  2075.                 "pingCtlProbeCount entering action=%d...  n", action));
  2076.     if ((StorageTmp =
  2077.          header_complex(pingCtlTableStorage, NULL,
  2078.                         &name[sizeof(pingCtlTable_variables_oid) /
  2079.                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
  2080.                         NULL)) == NULL)
  2081.         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  2082.     if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
  2083.         return SNMP_ERR_NOTWRITABLE;
  2084.     }
  2085.     if (StorageTmp && StorageTmp->pingCtlRowStatus == RS_ACTIVE) {
  2086.         return SNMP_ERR_NOTWRITABLE;
  2087.     }
  2088.     switch (action) {
  2089.     case RESERVE1:
  2090.         if (var_val_type != ASN_UNSIGNED) {
  2091.             snmp_log(LOG_ERR,
  2092.                      "write to pingCtlDataSize not ASN_UNSIGNEDn");
  2093.             return SNMP_ERR_WRONGTYPE;
  2094.         }
  2095.         break;
  2096.     case RESERVE2:
  2097.         /*
  2098.          * memory reseveration, final preparation... 
  2099.          */
  2100.         break;
  2101.     case FREE:
  2102.         /*
  2103.          * Release any resources that have been allocated 
  2104.          */
  2105.         break;
  2106.     case ACTION:
  2107.         /*
  2108.          * The variable has been stored in objid for
  2109.          * you to use, and you have just been asked to do something with
  2110.          * it.  Note that anything done here must be reversable in the UNDO case 
  2111.          */
  2112.         tmpvar = StorageTmp->pingCtlProbeCount;
  2113.         if ((*((long *) var_val)) >= 1 && (*((long *) var_val)) <= 15)
  2114.             StorageTmp->pingCtlProbeCount = *((long *) var_val);
  2115.         else
  2116.             StorageTmp->pingCtlProbeCount = 15;
  2117.         break;
  2118.     case UNDO:
  2119.         /*
  2120.          * Back out any changes made in the ACTION case 
  2121.          */
  2122.         StorageTmp->pingCtlProbeCount = tmpvar;
  2123.         break;
  2124.     case COMMIT:
  2125.         /*
  2126.          * Things are working well, so it's now safe to make the change
  2127.          * permanently.  Make sure that anything done here can't fail! 
  2128.          */
  2129.         break;
  2130.     }
  2131.     return SNMP_ERR_NOERROR;
  2132. }
  2133. int
  2134. write_pingCtlAdminStatus(int action,
  2135.                          u_char * var_val,
  2136.                          u_char var_val_type,
  2137.                          size_t var_val_len,
  2138.                          u_char * statP, oid * name, size_t name_len)
  2139. {
  2140.     static size_t   tmpvar;
  2141.     struct pingCtlTable_data *StorageTmp = NULL;
  2142.     static size_t   tmplen;
  2143.     size_t          newlen =
  2144.         name_len - (sizeof(pingCtlTable_variables_oid) / sizeof(oid) +
  2145.                     3 - 1);
  2146.     DEBUGMSGTL(("pingCtlTable",
  2147.                 "pingCtlAdminStatus entering action=%d...  n", action));
  2148.     if ((StorageTmp =
  2149.          header_complex(pingCtlTableStorage, NULL,
  2150.                         &name[sizeof(pingCtlTable_variables_oid) /
  2151.                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
  2152.                         NULL)) == NULL)
  2153.         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  2154.     if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
  2155.         return SNMP_ERR_NOTWRITABLE;
  2156.     }
  2157.     switch (action) {
  2158.     case RESERVE1:
  2159.         if (var_val_type != ASN_INTEGER) {
  2160.             snmp_log(LOG_ERR,
  2161.                      "write to pingCtlTargetAddressType not ASN_INTEGERn");
  2162.             return SNMP_ERR_WRONGTYPE;
  2163.         }
  2164.         break;
  2165.     case RESERVE2:
  2166.         /*
  2167.          * memory reseveration, final preparation... 
  2168.          */
  2169.         break;
  2170.     case FREE:
  2171.         /*
  2172.          * Release any resources that have been allocated 
  2173.          */
  2174.         break;
  2175.     case ACTION:
  2176.         /*
  2177.          * The variable has been stored in objid for
  2178.          * you to use, and you have just been asked to do something with
  2179.          * it.  Note that anything done here must be reversable in the UNDO case 
  2180.          */
  2181.         tmpvar = StorageTmp->pingCtlAdminStatus;
  2182.         StorageTmp->pingCtlAdminStatus = *((long *) var_val);
  2183.         break;
  2184.     case UNDO:
  2185.         /*
  2186.          * Back out any changes made in the ACTION case 
  2187.          */
  2188.         StorageTmp->pingCtlAdminStatus = tmpvar;
  2189.         break;
  2190.     case COMMIT:
  2191.         /*
  2192.          * Things are working well, so it's now safe to make the change
  2193.          * permanently.  Make sure that anything done here can't fail! 
  2194.          */
  2195.         if (StorageTmp->pingCtlAdminStatus == 1
  2196.             && StorageTmp->pingCtlRowStatus == RS_ACTIVE) {
  2197.             StorageTmp->pingResults->pingResultsOperStatus = 1;
  2198.             modify_ResultsOper(StorageTmp, 1);
  2199.             if (StorageTmp->pingCtlFrequency != 0)
  2200.                 StorageTmp->timer_id =
  2201.                     snmp_alarm_register(StorageTmp->pingCtlFrequency,
  2202.                                         SA_REPEAT, run_ping, StorageTmp);
  2203.             else
  2204.                 StorageTmp->timer_id = snmp_alarm_register(1, (int) NULL,
  2205.                                                            run_ping,
  2206.                                                            StorageTmp);
  2207.         } else if (StorageTmp->pingCtlAdminStatus == 2
  2208.                    && StorageTmp->pingCtlRowStatus == RS_ACTIVE) {
  2209.             snmp_alarm_unregister(StorageTmp->timer_id);
  2210.             StorageTmp->pingResults->pingResultsOperStatus = 2;
  2211.             modify_ResultsOper(StorageTmp, 2);
  2212.         }
  2213.         break;
  2214.     }
  2215.     return SNMP_ERR_NOERROR;
  2216. }
  2217. int
  2218. write_pingCtlDataFill(int action,
  2219.                       u_char * var_val,
  2220.                       u_char var_val_type,
  2221.                       size_t var_val_len,
  2222.                       u_char * statP, oid * name, size_t name_len)
  2223. {
  2224.     static char    *tmpvar;
  2225.     static size_t   tmplen;
  2226.     struct pingCtlTable_data *StorageTmp = NULL;
  2227.     size_t          newlen =
  2228.         name_len - (sizeof(pingCtlTable_variables_oid) / sizeof(oid) +
  2229.                     3 - 1);
  2230.     if ((StorageTmp =
  2231.          header_complex(pingCtlTableStorage, NULL,
  2232.                         &name[sizeof(pingCtlTable_variables_oid) /
  2233.                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
  2234.                         NULL)) == NULL)
  2235.         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  2236.     if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
  2237.         return SNMP_ERR_NOTWRITABLE;
  2238.     }
  2239.     if (StorageTmp && StorageTmp->pingCtlRowStatus == RS_ACTIVE) {
  2240.         return SNMP_ERR_NOTWRITABLE;
  2241.     }
  2242.     switch (action) {
  2243.     case RESERVE1:
  2244.         if (var_val_type != ASN_OCTET_STR) {
  2245.             snmp_log(LOG_ERR,
  2246.                      "write to pingCtlTargetAddress not ASN_OCTET_STRn");
  2247.             return SNMP_ERR_WRONGTYPE;
  2248.         }
  2249.         break;
  2250.     case RESERVE2:
  2251.         /*
  2252.          * memory reseveration, final preparation... 
  2253.          */
  2254.         break;
  2255.     case FREE:
  2256.         /*
  2257.          * Release any resources that have been allocated 
  2258.          */
  2259.         break;
  2260.     case ACTION:
  2261.         /*
  2262.          * The variable has been stored in long_ret for
  2263.          * you to use, and you have just been asked to do something with
  2264.          * it.  Note that anything done here must be reversable in the UNDO case 
  2265.          */
  2266.         tmpvar = StorageTmp->pingCtlDataFill;
  2267.         tmplen = StorageTmp->pingCtlDataFillLen;
  2268.         StorageTmp->pingCtlDataFill = (char *) malloc(var_val_len + 1);
  2269.         if (StorageTmp->pingCtlDataFill == NULL) {
  2270.             exit(1);
  2271.         }
  2272.         memcpy(StorageTmp->pingCtlDataFill, var_val, var_val_len);
  2273.         StorageTmp->pingCtlDataFill[var_val_len] = '';
  2274.         StorageTmp->pingCtlDataFillLen = var_val_len;
  2275.         break;
  2276.     case UNDO:
  2277.         /*
  2278.          * Back out any changes made in the ACTION case 
  2279.          */
  2280.         SNMP_FREE(StorageTmp->pingCtlDataFill);
  2281.         StorageTmp->pingCtlDataFill = NULL;
  2282.         StorageTmp->pingCtlDataFill = tmpvar;
  2283.         StorageTmp->pingCtlDataFillLen = tmplen;
  2284.         break;
  2285.     case COMMIT:
  2286.         /*
  2287.          * Things are working well, so it's now safe to make the change
  2288.          * permanently.  Make sure that anything done here can't fail! 
  2289.          */
  2290.         SNMP_FREE(tmpvar);
  2291.         break;
  2292.     }
  2293.     return SNMP_ERR_NOERROR;
  2294. }
  2295. int
  2296. write_pingCtlFrequency(int action,
  2297.                        u_char * var_val,
  2298.                        u_char var_val_type,
  2299.                        size_t var_val_len,
  2300.                        u_char * statP, oid * name, size_t name_len)
  2301. {
  2302.     static size_t   tmpvar;
  2303.     struct pingCtlTable_data *StorageTmp = NULL;
  2304.     static size_t   tmplen;
  2305.     size_t          newlen =
  2306.         name_len - (sizeof(pingCtlTable_variables_oid) / sizeof(oid) +
  2307.                     3 - 1);
  2308.     DEBUGMSGTL(("pingCtlTable",
  2309.                 "pingCtlFrequency entering action=%d...  n", action));
  2310.     if ((StorageTmp =
  2311.          header_complex(pingCtlTableStorage, NULL,
  2312.                         &name[sizeof(pingCtlTable_variables_oid) /
  2313.                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
  2314.                         NULL)) == NULL)
  2315.         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  2316.     if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
  2317.         return SNMP_ERR_NOTWRITABLE;
  2318.     }
  2319.     if (StorageTmp && StorageTmp->pingCtlRowStatus == RS_ACTIVE) {
  2320.         return SNMP_ERR_NOTWRITABLE;
  2321.     }
  2322.     switch (action) {
  2323.     case RESERVE1:
  2324.         if (var_val_type != ASN_UNSIGNED) {
  2325.             snmp_log(LOG_ERR,
  2326.                      "write to pingCtlDataSize not ASN_UNSIGNEDn");
  2327.             return SNMP_ERR_WRONGTYPE;
  2328.         }
  2329.         break;
  2330.     case RESERVE2:
  2331.         /*
  2332.          * memory reseveration, final preparation... 
  2333.          */
  2334.         break;
  2335.     case FREE:
  2336.         /*
  2337.          * Release any resources that have been allocated 
  2338.          */
  2339.         break;
  2340.     case ACTION:
  2341.         /*
  2342.          * The variable has been stored in objid for
  2343.          * you to use, and you have just been asked to do something with
  2344.          * it.  Note that anything done here must be reversable in the UNDO case 
  2345.          */
  2346.         tmpvar = StorageTmp->pingCtlFrequency;
  2347.         StorageTmp->pingCtlFrequency = *((long *) var_val);
  2348.         break;
  2349.     case UNDO:
  2350.         /*
  2351.          * Back out any changes made in the ACTION case 
  2352.          */
  2353.         StorageTmp->pingCtlFrequency = tmpvar;
  2354.         break;
  2355.     case COMMIT:
  2356.         /*
  2357.          * Things are working well, so it's now safe to make the change
  2358.          * permanently.  Make sure that anything done here can't fail! 
  2359.          */
  2360.         break;
  2361.     }
  2362.     return SNMP_ERR_NOERROR;
  2363. }