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

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:lookupCtlTable.c
  7.  *File Description:Rows of the lookupCtlTable MIB add , delete and read.Rows of lookupResultsTable
  8.  *              MIB add and delete.
  9.  
  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 "lookupCtlTable.h"
  38. #include "lookupResultsTable.h"
  39. #include "header_complex.h"
  40. /*
  41.  *For discontinuity checking.
  42.  */
  43. oid             lookupCtlTable_variables_oid[] =
  44.     { 1, 3, 6, 1, 2, 1, 82, 1, 3 };
  45. struct variable2 lookupCtlTable_variables[] = {
  46.     /*
  47.      * magic number        , variable type , ro/rw , callback fn  , L, oidsuffix 
  48.      */
  49.     {COLUMN_LOOKUPCTLTARGETADDRESSTYPE, ASN_INTEGER, RWRITE, var_lookupCtlTable, 2, {1, 3}},
  50.     {COLUMN_LOOKUPCTLTARGETADDRESS,   ASN_OCTET_STR, RWRITE, var_lookupCtlTable, 2, {1, 4}},
  51.     {COLUMN_LOOKUPCTLOPERSTATUS, ASN_INTEGER, RONLY, var_lookupCtlTable, 2, {1, 5}},
  52.     {COLUMN_LOOKUPCTLTIME,      ASN_UNSIGNED, RONLY, var_lookupCtlTable, 2, {1, 6}},
  53.     {COLUMN_LOOKUPCTLRC,         ASN_INTEGER, RONLY, var_lookupCtlTable, 2, {1, 7}},
  54.     {COLUMN_LOOKUPCTLROWSTATUS, ASN_INTEGER, RWRITE, var_lookupCtlTable, 2, {1, 8}}
  55. };
  56. /*
  57.  * global storage of our data, saved in and configured by header_complex() 
  58.  */
  59. struct header_complex_index *lookupCtlTableStorage = NULL;
  60. struct header_complex_index *lookupResultsTableStorage = NULL;
  61. void
  62. init_lookupCtlTable(void)
  63. {
  64.     DEBUGMSGTL(("lookupCtlTable", "initializing...  "));
  65.     /*
  66.      * register ourselves with the agent to handle our mib tree 
  67.      */
  68.     REGISTER_MIB("lookupCtlTable", lookupCtlTable_variables, variable2,
  69.                  lookupCtlTable_variables_oid);
  70.     /*
  71.      * register our config handler(s) to deal with registrations 
  72.      */
  73.     snmpd_register_config_handler("lookupCtlTable", parse_lookupCtlTable,
  74.                                   NULL, NULL);
  75.     /*
  76.      * we need to be called back later to store our data 
  77.      */
  78.     snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
  79.                            store_lookupCtlTable, NULL);
  80.     DEBUGMSGTL(("lookupCtlTable", "done.n"));
  81. }
  82. struct lookupTable_data *
  83. create_lookupTable_data(void)
  84. {
  85.     struct lookupTable_data *StorageNew = NULL;
  86.     StorageNew = SNMP_MALLOC_STRUCT(lookupTable_data);
  87.     if (StorageNew == NULL) {
  88.         exit(1);
  89.     }
  90.     StorageNew->lookupCtlTargetAddress = strdup("");
  91.     StorageNew->lookupCtlTargetAddressLen = 0;
  92.     StorageNew->lookupCtlOperStatus = 2l;
  93.     StorageNew->lookupCtlTime = 0;
  94.     StorageNew->storagetype = ST_NONVOLATILE;
  95.     return StorageNew;
  96. }
  97. /*
  98.  * lookupCtlTable_add(): adds a structure node to our data set 
  99.  */
  100. int
  101. lookupCtlTable_add(struct lookupTable_data *thedata)
  102. {
  103.     netsnmp_variable_list *vars = NULL;
  104.     DEBUGMSGTL(("lookupCtlTable", "adding data...  "));
  105.     /*
  106.      * add the index variables to the varbind list, which is 
  107.      * used by header_complex to index the data 
  108.      */
  109.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->lookupCtlOwnerIndex, thedata->lookupCtlOwnerIndexLen);   /* lookupCtlOwnerIndex */
  110.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->lookupCtlOperationName, thedata->lookupCtlOperationNameLen);     /* lookupCtlOperationName */
  111.     if (header_complex_add_data(&lookupCtlTableStorage, vars, thedata) ==
  112.         NULL) {
  113.         return SNMPERR_GENERR;
  114.     }
  115.     DEBUGMSGTL(("lookupCtlTable", "registered an entryn"));
  116.     vars = NULL;
  117.     DEBUGMSGTL(("lookupCtlTable", "done.n"));
  118.     return SNMPERR_SUCCESS;
  119. }
  120. int
  121. lookupResultsTable_add(struct lookupTable_data *thedata)
  122. {
  123.     netsnmp_variable_list *vars_list = NULL;
  124.     struct lookupResultsTable_data *p = NULL;
  125.     p = thedata->ResultsTable;
  126.     if (thedata->ResultsTable != NULL)
  127.         do {
  128.             snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) p->lookupCtlOwnerIndex, p->lookupCtlOwnerIndexLen);  /* lookupCtlOwnerIndex */
  129.             snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) p->lookupCtlOperationName, p->lookupCtlOperationNameLen);    /* lookupCtlOperationName */
  130.             snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &p->lookupResultsIndex, sizeof(p->lookupResultsIndex));       /* lookupResultsIndex */
  131.             DEBUGMSGTL(("lookupResultsTable", "adding data...  "));
  132.             /*
  133.              * add the index variables to the varbind list, which is 
  134.              * used by header_complex to index the data 
  135.              */
  136.             if (header_complex_add_data
  137.                 (&lookupResultsTableStorage, vars_list, p) == NULL) {
  138.                 return SNMPERR_GENERR;
  139.             }
  140.             DEBUGMSGTL(("lookupResultsTable", "out finishedn"));
  141.             vars_list = NULL;
  142.             p = p->next;
  143.         } while (p != NULL);
  144.     DEBUGMSGTL(("lookupResultsTable", "done.n"));
  145. }
  146. void
  147. lookupCtlTable_cleaner(struct header_complex_index *thestuff)
  148. {
  149.     struct header_complex_index *hciptr = NULL;
  150.     struct lookupTable_data *StorageDel = NULL;
  151.     DEBUGMSGTL(("lookupCtlTable", "cleanerout  "));
  152.     for (hciptr = thestuff; hciptr != NULL; hciptr = hciptr->next) {
  153.         StorageDel =
  154.             header_complex_extract_entry(&lookupCtlTableStorage, hciptr);
  155.         if (StorageDel != NULL) {
  156.             free(StorageDel->lookupCtlOwnerIndex);
  157.             StorageDel->lookupCtlOwnerIndex = NULL;
  158.             free(StorageDel->lookupCtlOperationName);
  159.             StorageDel->lookupCtlOperationName = NULL;
  160.             free(StorageDel->lookupCtlTargetAddress);
  161.             StorageDel->lookupCtlTargetAddress = NULL;
  162.             free(StorageDel);
  163.             StorageDel = NULL;
  164.         }
  165.         DEBUGMSGTL(("lookupCtlTable", "cleaner  "));
  166.     }
  167. }
  168. /*
  169.  * parse_lookupCtlTable():
  170.  *   parses .conf file entries needed to configure the mib.
  171.  */
  172. void
  173. parse_lookupCtlTable(const char *token, char *line)
  174. {
  175.     size_t          tmpint;
  176.     struct lookupTable_data *StorageTmp =
  177.         SNMP_MALLOC_STRUCT(lookupTable_data);
  178.     DEBUGMSGTL(("lookupCtlTable", "parsing config...  "));
  179.     if (StorageTmp == NULL) {
  180.         config_perror("malloc failure");
  181.         return;
  182.     }
  183.     line =
  184.         read_config_read_data(ASN_OCTET_STR, line,
  185.                               &StorageTmp->lookupCtlOwnerIndex,
  186.                               &StorageTmp->lookupCtlOwnerIndexLen);
  187.     if (StorageTmp->lookupCtlOwnerIndex == NULL) {
  188.         config_perror("invalid specification for lookupCtlOwnerIndex");
  189.         return;
  190.     }
  191.     line =
  192.         read_config_read_data(ASN_OCTET_STR, line,
  193.                               &StorageTmp->lookupCtlOperationName,
  194.                               &StorageTmp->lookupCtlOperationNameLen);
  195.     if (StorageTmp->lookupCtlOperationName == NULL) {
  196.         config_perror("invalid specification for lookupCtlOperationName");
  197.         return;
  198.     }
  199.     line =
  200.         read_config_read_data(ASN_INTEGER, line,
  201.                               &StorageTmp->lookupCtlTargetAddressType,
  202.                               &tmpint);
  203.     line =
  204.         read_config_read_data(ASN_OCTET_STR, line,
  205.                               &StorageTmp->lookupCtlTargetAddress,
  206.                               &StorageTmp->lookupCtlTargetAddressLen);
  207.     if (StorageTmp->lookupCtlTargetAddress == NULL) {
  208.         config_perror("invalid specification for lookupCtlTargetAddress");
  209.         return;
  210.     }
  211.     line =
  212.         read_config_read_data(ASN_INTEGER, line,
  213.                               &StorageTmp->lookupCtlOperStatus, &tmpint);
  214.     line =
  215.         read_config_read_data(ASN_UNSIGNED, line,
  216.                               &StorageTmp->lookupCtlTime, &tmpint);
  217.     line =
  218.         read_config_read_data(ASN_INTEGER, line,
  219.                               &StorageTmp->lookupCtlRc, &tmpint);
  220.     line =
  221.         read_config_read_data(ASN_INTEGER, line,
  222.                               &StorageTmp->lookupCtlRowStatus, &tmpint);
  223.     StorageTmp->storagetype = ST_NONVOLATILE;
  224.     lookupCtlTable_add(StorageTmp);
  225.     /* lookupCtlTable_cleaner(lookupCtlTableStorage); */
  226.     DEBUGMSGTL(("lookupCtlTable", "done.n"));
  227. }
  228. /*
  229.  * store_lookupCtlTable():
  230.  *   stores .conf file entries needed to configure the mib.
  231.  */
  232. int
  233. store_lookupCtlTable(int majorID, int minorID, void *serverarg,
  234.                      void *clientarg)
  235. {
  236.     char            line[SNMP_MAXBUF];
  237.     char           *cptr;
  238.     size_t          tmpint;
  239.     struct lookupTable_data *StorageTmp;
  240.     struct header_complex_index *hcindex;
  241.     DEBUGMSGTL(("lookupCtlTable", "storing data...  "));
  242.     for (hcindex = lookupCtlTableStorage; hcindex != NULL;
  243.          hcindex = hcindex->next) {
  244.         StorageTmp = (struct lookupTable_data *) hcindex->data;
  245.         if (StorageTmp->storagetype != ST_READONLY) {
  246.             memset(line, 0, sizeof(line));
  247.             strcat(line, "lookupCtlTable ");
  248.             cptr = line + strlen(line);
  249.             cptr =
  250.                 read_config_store_data(ASN_OCTET_STR, cptr,
  251.                                        &StorageTmp->lookupCtlOwnerIndex,
  252.                                        &StorageTmp->
  253.                                        lookupCtlOwnerIndexLen);
  254.             cptr =
  255.                 read_config_store_data(ASN_OCTET_STR, cptr,
  256.                                        &StorageTmp->lookupCtlOperationName,
  257.                                        &StorageTmp->
  258.                                        lookupCtlOperationNameLen);
  259.             cptr =
  260.                 read_config_store_data(ASN_INTEGER, cptr,
  261.                                        &StorageTmp->
  262.                                        lookupCtlTargetAddressType,
  263.                                        &tmpint);
  264.             cptr =
  265.                 read_config_store_data(ASN_OCTET_STR, cptr,
  266.                                        &StorageTmp->lookupCtlTargetAddress,
  267.                                        &StorageTmp->
  268.                                        lookupCtlTargetAddressLen);
  269.             cptr =
  270.                 read_config_store_data(ASN_INTEGER, cptr,
  271.                                        &StorageTmp->lookupCtlOperStatus,
  272.                                        &tmpint);
  273.             cptr =
  274.                 read_config_store_data(ASN_UNSIGNED, cptr,
  275.                                        &StorageTmp->lookupCtlTime,
  276.                                        &tmpint);
  277.             cptr =
  278.                 read_config_store_data(ASN_INTEGER, cptr,
  279.                                        &StorageTmp->lookupCtlRc, &tmpint);
  280.             cptr =
  281.                 read_config_store_data(ASN_INTEGER, cptr,
  282.                                        &StorageTmp->lookupCtlRowStatus,
  283.                                        &tmpint);
  284.             snmpd_store_config(line);
  285.         }
  286.     }
  287.     DEBUGMSGTL(("lookupCtlTable", "done.n"));
  288.     return SNMPERR_SUCCESS;
  289. }
  290. /*
  291.  * var_lookupCtlTable():
  292.  *   Handle this table separately from the scalar value case.
  293.  *   The workings of this are basically the same as for var_mteObjectsTable above.
  294.  */
  295. unsigned char  *
  296. var_lookupCtlTable(struct variable *vp,
  297.                    oid * name,
  298.                    size_t *length,
  299.                    int exact, size_t *var_len, WriteMethod ** write_method)
  300. {
  301.     struct lookupTable_data *StorageTmp = NULL;
  302.     /*
  303.      * this assumes you have registered all your data properly
  304.      */
  305.     if ((StorageTmp =
  306.          header_complex(lookupCtlTableStorage, vp, name, length, exact,
  307.                         var_len, write_method)) == NULL) {
  308.         if (vp->magic == COLUMN_LOOKUPCTLROWSTATUS)
  309.             *write_method = write_lookupCtlRowStatus;
  310.         return NULL;
  311.     }
  312.     /*
  313.      * this is where we do the value assignments for the mib results.
  314.      */
  315.     switch (vp->magic) {
  316.     case COLUMN_LOOKUPCTLTARGETADDRESSTYPE:
  317.         *write_method = write_lookupCtlTargetAddressType;
  318.         *var_len = sizeof(StorageTmp->lookupCtlTargetAddressType);
  319.         return (u_char *) & StorageTmp->lookupCtlTargetAddressType;
  320.     case COLUMN_LOOKUPCTLTARGETADDRESS:
  321.         *write_method = write_lookupCtlTargetAddress;
  322.         *var_len = (StorageTmp->lookupCtlTargetAddressLen);
  323.         return (u_char *) StorageTmp->lookupCtlTargetAddress;
  324.     case COLUMN_LOOKUPCTLOPERSTATUS:
  325.         *var_len = sizeof(StorageTmp->lookupCtlOperStatus);
  326.         return (u_char *) & StorageTmp->lookupCtlOperStatus;
  327.     case COLUMN_LOOKUPCTLTIME:
  328.         *var_len = sizeof(StorageTmp->lookupCtlTime);
  329.         return (u_char *) & StorageTmp->lookupCtlTime;
  330.     case COLUMN_LOOKUPCTLRC:
  331.         *var_len = sizeof(StorageTmp->lookupCtlRc);
  332.         return (u_char *) & StorageTmp->lookupCtlRc;
  333.     case COLUMN_LOOKUPCTLROWSTATUS:
  334.         *write_method = write_lookupCtlRowStatus;
  335.         *var_len = sizeof(StorageTmp->lookupCtlRowStatus);
  336.         return (u_char *) & StorageTmp->lookupCtlRowStatus;
  337.     default:
  338.         ERROR_MSG("");
  339.     }
  340.     return NULL;
  341. }
  342. void
  343. run_lookup(struct lookupTable_data *item)
  344. {
  345.     long            addressType;
  346.     char           *address = NULL;
  347.     size_t          addresslen;
  348.     struct lookupResultsTable_data *head = NULL;
  349.     struct lookupResultsTable_data *current = NULL;
  350.     struct lookupResultsTable_data *temp = NULL;
  351.     int             i = 0, n = 1, t = 0;
  352.     /* for ipv4,ipv6 */
  353.     unsigned int    addr_in, addr_in6;
  354.     struct hostent *lookup = NULL;
  355.     struct sockaddr_in *addr = NULL;
  356.     struct timeval  tpstart, tpend;
  357.     unsigned long   timeuse, timeuse4, timeuse6;
  358.     /* for dns */
  359.     struct in_addr  a;
  360.     struct in6_addr a6;
  361.     char           *strptr = NULL;
  362.     struct addrinfo hints, *res = NULL, *tempinfo = NULL;
  363.     struct sockaddr_in6 myaddress6;
  364.     char            buf[BUFSIZ];
  365.     if (item == NULL)
  366.         return;
  367.     addressType = (long) item->lookupCtlTargetAddressType;
  368.     addresslen = (size_t) item->lookupCtlTargetAddressLen;
  369.     address = (char *) malloc(addresslen + 1);
  370.     memcpy(address, item->lookupCtlTargetAddress, addresslen + 1);
  371.     address[addresslen] = '';
  372.     if (addressType == 1) {
  373.         addr_in = inet_addr(address);
  374.         if (addr_in == 0xffffffff
  375.             && strcmp(address, "255.255.255.255") != 0) {
  376.             DEBUGMSGTL(("lookupResultsTable", "Invalid argument: %sn",
  377.                         address));
  378.             return;
  379.         }
  380.         gettimeofday(&tpstart, NULL);
  381.         lookup = gethostbyaddr((char *) &addr_in, 4, AF_INET);
  382.         gettimeofday(&tpend, NULL);
  383.         timeuse = 1000000 * (tpend.tv_sec - tpstart.tv_sec) +
  384.             tpend.tv_usec - tpstart.tv_usec;
  385.         timeuse /= 1000;
  386.         modify_lookupCtlTime(item, timeuse);
  387.         modify_lookupCtlOperStatus(item, 3l);
  388.         if (lookup == NULL) {
  389.             DEBUGMSGTL(("lookupCtlTable",
  390.                         "Can't get a network host entry for ipv4 address: %sn",
  391.                         address));
  392.             modify_lookupCtlRc(item, 1l);
  393.             return;
  394.         } else {
  395.             modify_lookupCtlRc(item, 0l);
  396.             if (lookup->h_name != NULL) {
  397.                 current = temp =
  398.                     SNMP_MALLOC_STRUCT(lookupResultsTable_data);
  399.                 if (temp == NULL) {
  400.                     exit(1);
  401.                 }
  402.                 temp->lookupResultsIndex = n;
  403.                 temp->lookupCtlOwnerIndex =
  404.                     (char *) malloc(item->lookupCtlOwnerIndexLen + 1);
  405.                 if (temp->lookupCtlOwnerIndex == NULL) {
  406.                     exit(1);
  407.                 }
  408.                 memcpy(temp->lookupCtlOwnerIndex,
  409.                        item->lookupCtlOwnerIndex,
  410.                        item->lookupCtlOwnerIndexLen + 1);
  411.                 temp->lookupCtlOwnerIndex[item->lookupCtlOwnerIndexLen] =
  412.                     '';
  413.                 temp->lookupCtlOwnerIndexLen =
  414.                     item->lookupCtlOwnerIndexLen;
  415.                 temp->lookupCtlOperationName =
  416.                     (char *) malloc(item->lookupCtlOperationNameLen + 1);
  417.                 if (temp->lookupCtlOperationName == NULL) {
  418.                     exit(1);
  419.                 }
  420.                 memcpy(temp->lookupCtlOperationName,
  421.                        item->lookupCtlOperationName,
  422.                        item->lookupCtlOperationNameLen + 1);
  423.                 temp->lookupCtlOperationName[item->
  424.                                              lookupCtlOperationNameLen] =
  425.                     '';
  426.                 temp->lookupCtlOperationNameLen =
  427.                     item->lookupCtlOperationNameLen;
  428.                 temp->lookupResultsAddressType = 16;
  429.                 temp->lookupResultsAddress =
  430.                     (char *) malloc(strlen(lookup->h_name) + 1);
  431.                 memcpy(temp->lookupResultsAddress, lookup->h_name,
  432.                        strlen(lookup->h_name) + 1);
  433.                 temp->lookupResultsAddress[strlen(lookup->h_name)] = '';
  434.                 temp->lookupResultsAddressLen = strlen(lookup->h_name);
  435.                 item->ResultsTable = temp;
  436.                 n = n + 1;
  437.             }
  438.             i = 0;
  439.             while (lookup->h_aliases[i]) {
  440.                 temp = SNMP_MALLOC_STRUCT(lookupResultsTable_data);
  441.                 if (temp == NULL) {
  442.                     exit(1);
  443.                 }
  444.                 temp->lookupCtlOwnerIndex =
  445.                     (char *) malloc(item->lookupCtlOwnerIndexLen + 1);
  446.                 if (temp->lookupCtlOwnerIndex == NULL) {
  447.                     exit(1);
  448.                 }
  449.                 memcpy(temp->lookupCtlOwnerIndex,
  450.                        item->lookupCtlOwnerIndex,
  451.                        item->lookupCtlOwnerIndexLen + 1);
  452.                 temp->lookupCtlOwnerIndex[item->lookupCtlOwnerIndexLen] =
  453.                     '';
  454.                 temp->lookupCtlOwnerIndexLen =
  455.                     item->lookupCtlOwnerIndexLen;
  456.                 temp->lookupCtlOperationName =
  457.                     (char *) malloc(item->lookupCtlOperationNameLen + 1);
  458.                 if (temp->lookupCtlOperationName == NULL) {
  459.                     exit(1);
  460.                 }
  461.                 memcpy(temp->lookupCtlOperationName,
  462.                        item->lookupCtlOperationName,
  463.                        item->lookupCtlOperationNameLen + 1);
  464.                 temp->lookupCtlOperationName[item->
  465.                                              lookupCtlOperationNameLen] =
  466.                     '';
  467.                 temp->lookupCtlOperationNameLen =
  468.                     item->lookupCtlOperationNameLen;
  469.                 temp->lookupResultsIndex = n;
  470.                 temp->lookupResultsAddressType = 16;
  471.                 temp->lookupResultsAddress =
  472.                     (char *) malloc(strlen(lookup->h_aliases[i]) + 1);
  473.                 memcpy(temp->lookupResultsAddress, lookup->h_aliases[i],
  474.                        strlen(lookup->h_aliases[i]) + 1);
  475.                 temp->lookupResultsAddress[strlen(lookup->h_aliases[i])] =
  476.                     '';
  477.                 temp->lookupResultsAddressLen =
  478.                     strlen(lookup->h_aliases[i]);
  479.                 current->next = temp;
  480.                 current = temp;
  481.                 i = i + 1;
  482.                 n = n + 1;
  483.             }
  484.             current->next = NULL;
  485.         }
  486.         if (item->ResultsTable != NULL)
  487.             if (lookupResultsTable_add(item) != SNMPERR_SUCCESS)
  488.                 DEBUGMSGTL(("lookupResultsTable",
  489.                             "registered an entry errorn"));
  490.         SNMP_FREE(address);
  491.         address = NULL;
  492.         return;
  493.     }
  494.     else if (addressType == 16) {
  495.         gettimeofday(&tpstart, NULL);
  496.         lookup = gethostbyname(address);
  497.         gettimeofday(&tpend, NULL);
  498.         timeuse4 = 1000000 * (tpend.tv_sec - tpstart.tv_sec) +
  499.             tpend.tv_usec - tpstart.tv_usec;
  500.         timeuse4 /= 1000;
  501.         if (lookup == NULL) {
  502.             DEBUGMSGTL(("lookupCtlTable",
  503.                         "Can't get a network host entry for %sn",
  504.                         address));
  505.         } else {
  506.             while (*lookup->h_addr_list) {
  507.                 bcopy(*lookup->h_addr_list++, (char *) &a, sizeof(a));
  508.                 temp = SNMP_MALLOC_STRUCT(lookupResultsTable_data);
  509.                 if (temp == NULL) {
  510.                     exit(1);
  511.                 }
  512.                 temp->lookupResultsIndex = n;
  513.                 temp->lookupCtlOwnerIndex =
  514.                     (char *) malloc(item->lookupCtlOwnerIndexLen + 1);
  515.                 if (temp->lookupCtlOwnerIndex == NULL) {
  516.                     exit(1);
  517.                 }
  518.                 memcpy(temp->lookupCtlOwnerIndex,
  519.                        item->lookupCtlOwnerIndex,
  520.                        item->lookupCtlOwnerIndexLen + 1);
  521.                 temp->lookupCtlOwnerIndex[item->lookupCtlOwnerIndexLen] =
  522.                     '';
  523.                 temp->lookupCtlOwnerIndexLen =
  524.                     item->lookupCtlOwnerIndexLen;
  525.                 temp->lookupCtlOperationName =
  526.                     (char *) malloc(item->lookupCtlOperationNameLen + 1);
  527.                 if (temp->lookupCtlOperationName == NULL) {
  528.                     exit(1);
  529.                 }
  530.                 memcpy(temp->lookupCtlOperationName,
  531.                        item->lookupCtlOperationName,
  532.                        item->lookupCtlOperationNameLen + 1);
  533.                 temp->lookupCtlOperationName[item->
  534.                                              lookupCtlOperationNameLen] =
  535.                     '';
  536.                 temp->lookupCtlOperationNameLen =
  537.                     item->lookupCtlOperationNameLen;
  538.                 temp->lookupResultsAddressType = 1;
  539.                 temp->lookupResultsAddress =
  540.                     (char *) malloc(strlen(inet_ntoa(a)) + 1);
  541.                 if (temp->lookupResultsAddress == NULL) {
  542.                     exit(1);
  543.                 }
  544.                 memcpy(temp->lookupResultsAddress, inet_ntoa(a),
  545.                        strlen(inet_ntoa(a)) + 1);
  546.                 temp->lookupResultsAddress[strlen(inet_ntoa(a))] = '';
  547.                 temp->lookupResultsAddressLen = strlen(inet_ntoa(a));
  548.                 if (n == 1)
  549.                     item->ResultsTable = temp;
  550.                 else
  551.                     current->next = temp;
  552.                 current = temp;
  553.                 n = n + 1;
  554.             }
  555.             current->next = NULL;
  556.             t = n;
  557.         }
  558.         struct hostent *hp;
  559.         char            pa[64];
  560.         char           *hostname = NULL;
  561.         gettimeofday(&tpstart, NULL);
  562.         hp = gethostbyname2(address, AF_INET6);
  563.         gettimeofday(&tpend, NULL);
  564.         timeuse6 = 1000000 * (tpend.tv_sec - tpstart.tv_sec) +
  565.             tpend.tv_usec - tpstart.tv_usec;
  566.         timeuse6 /= 1000;
  567.         if (hp == NULL) {
  568.             DEBUGMSGTL(("lookupCtlTable",
  569.                         "Can't get a ipv6 network host entry for %sn",
  570.                         address));
  571.         } else {
  572.             while (*hp->h_addr_list) {
  573.                 memmove((caddr_t) & a6, *hp->h_addr_list++, 16);
  574.                 hostname = (char *) hp->h_name;
  575.                 temp = SNMP_MALLOC_STRUCT(lookupResultsTable_data);
  576.                 if (temp == NULL) {
  577.                     exit(1);
  578.                 }
  579.                 temp->lookupResultsIndex = n;
  580.                 temp->lookupCtlOwnerIndex =
  581.                     (char *) malloc(item->lookupCtlOwnerIndexLen + 1);
  582.                 if (temp->lookupCtlOwnerIndex == NULL) {
  583.                     exit(1);
  584.                 }
  585.                 memcpy(temp->lookupCtlOwnerIndex,
  586.                        item->lookupCtlOwnerIndex,
  587.                        item->lookupCtlOwnerIndexLen + 1);
  588.                 temp->lookupCtlOwnerIndex[item->lookupCtlOwnerIndexLen] =
  589.                     '';
  590.                 temp->lookupCtlOwnerIndexLen =
  591.                     item->lookupCtlOwnerIndexLen;
  592.                 temp->lookupCtlOperationName =
  593.                     (char *) malloc(item->lookupCtlOperationNameLen + 1);
  594.                 if (temp->lookupCtlOperationName == NULL) {
  595.                     exit(1);
  596.                 }
  597.                 memcpy(temp->lookupCtlOperationName,
  598.                        item->lookupCtlOperationName,
  599.                        item->lookupCtlOperationNameLen + 1);
  600.                 temp->lookupCtlOperationName[item->
  601.                                              lookupCtlOperationNameLen] =
  602.                     '';
  603.                 temp->lookupCtlOperationNameLen =
  604.                     item->lookupCtlOperationNameLen;
  605.                 temp->lookupResultsAddressType = 2;
  606.                 temp->lookupResultsAddress =
  607.                     (char *)
  608.                     malloc(strlen(inet_ntop(AF_INET6, &a6, pa, 64)) + 1);
  609.                 memcpy(temp->lookupResultsAddress,
  610.                        inet_ntop(AF_INET6, &a6, pa, 64),
  611.                        strlen(inet_ntop(AF_INET6, &a6, pa, 64)) + 1);
  612.                 temp->
  613.                     lookupResultsAddress[strlen
  614.                                          (inet_ntop
  615.                                           (AF_INET6, &a6, pa, 64))] = '';
  616.                 temp->lookupResultsAddressLen =
  617.                     strlen(inet_ntop(AF_INET6, &a6, pa, 64));
  618.                 if (n == 1)
  619.                     item->ResultsTable = temp;
  620.                 else
  621.                     current->next = temp;
  622.                 current = temp;
  623.                 n = n + 1;
  624.             }
  625.             current->next = NULL;
  626.         }
  627.         timeuse = timeuse4 + timeuse6;
  628.         modify_lookupCtlTime(item, timeuse);
  629.         modify_lookupCtlOperStatus(item, 3l);
  630.         if (item->ResultsTable != NULL) {
  631.             modify_lookupCtlRc(item, 0l);
  632.             if (lookupResultsTable_add(item) != SNMPERR_SUCCESS)
  633.                 DEBUGMSGTL(("lookupResultsTable",
  634.                             "registered an entry errorn"));
  635.         } else {
  636.             modify_lookupCtlRc(item, 1l);
  637.         }
  638.         SNMP_FREE(address);
  639.         address = NULL;
  640.         return;
  641.     }
  642.     else if (addressType == 2) {
  643.         if (inet_pton(AF_INET6, address, &addr_in6) == 1)
  644.             DEBUGMSGTL(("lookupCtlTable", "success! n"));
  645.         else
  646.             DEBUGMSGTL(("lookupCtlTable", "error! n"));
  647.         gettimeofday(&tpstart, NULL);
  648.         lookup = gethostbyaddr((char *) &addr_in6, 16, AF_INET6);
  649.         gettimeofday(&tpend, NULL);
  650.         timeuse = 1000000 * (tpend.tv_sec - tpstart.tv_sec) +
  651.             tpend.tv_usec - tpstart.tv_usec;
  652.         timeuse /= 1000;
  653.         modify_lookupCtlTime(item, timeuse);
  654.         modify_lookupCtlOperStatus(item, 3l);
  655.         if (lookup == NULL) {
  656.             DEBUGMSGTL(("lookupCtlTable",
  657.                         "Can't get a network host entry for %sn",
  658.                         address));
  659.             modify_lookupCtlRc(item, 1l);
  660.             return;
  661.         } else {
  662.             modify_lookupCtlRc(item, 0l);
  663.             if (lookup->h_name != NULL) {
  664.                 current = temp =
  665.                     SNMP_MALLOC_STRUCT(lookupResultsTable_data);
  666.                 if (temp == NULL) {
  667.                     exit(1);
  668.                 }
  669.                 temp->lookupResultsIndex = n;
  670.                 temp->lookupCtlOwnerIndex =
  671.                     (char *) malloc(item->lookupCtlOwnerIndexLen + 1);
  672.                 if (temp->lookupCtlOwnerIndex == NULL) {
  673.                     exit(1);
  674.                 }
  675.                 memcpy(temp->lookupCtlOwnerIndex,
  676.                        item->lookupCtlOwnerIndex,
  677.                        item->lookupCtlOwnerIndexLen + 1);
  678.                 temp->lookupCtlOwnerIndex[item->lookupCtlOwnerIndexLen] =
  679.                     '';
  680.                 temp->lookupCtlOwnerIndexLen =
  681.                     item->lookupCtlOwnerIndexLen;
  682.                 temp->lookupCtlOperationName =
  683.                     (char *) malloc(item->lookupCtlOperationNameLen + 1);
  684.                 if (temp->lookupCtlOperationName == NULL) {
  685.                     exit(1);
  686.                 }
  687.                 memcpy(temp->lookupCtlOperationName,
  688.                        item->lookupCtlOperationName,
  689.                        item->lookupCtlOperationNameLen + 1);
  690.                 temp->lookupCtlOperationName[item->
  691.                                              lookupCtlOperationNameLen] =
  692.                     '';
  693.                 temp->lookupCtlOperationNameLen =
  694.                     item->lookupCtlOperationNameLen;
  695.                 temp->lookupResultsAddressType = 16;
  696.                 temp->lookupResultsAddress =
  697.                     (char *) malloc(strlen(lookup->h_name) + 1);
  698.                 memcpy(temp->lookupResultsAddress, lookup->h_name,
  699.                        strlen(lookup->h_name) + 1);
  700.                 temp->lookupResultsAddress[strlen(lookup->h_name)] = '';
  701.                 temp->lookupResultsAddressLen = strlen(lookup->h_name);
  702.                 item->ResultsTable = temp;
  703.                 n = n + 1;
  704.             }
  705.             i = 0;
  706.             while (lookup->h_aliases[i]) {
  707.                 temp = SNMP_MALLOC_STRUCT(lookupResultsTable_data);
  708.                 if (temp == NULL) {
  709.                     exit(1);
  710.                 }
  711.                 temp->lookupCtlOwnerIndex =
  712.                     (char *) malloc(item->lookupCtlOwnerIndexLen + 1);
  713.                 if (temp->lookupCtlOwnerIndex == NULL) {
  714.                     exit(1);
  715.                 }
  716.                 memcpy(temp->lookupCtlOwnerIndex,
  717.                        item->lookupCtlOwnerIndex,
  718.                        item->lookupCtlOwnerIndexLen + 1);
  719.                 temp->lookupCtlOwnerIndex[item->lookupCtlOwnerIndexLen] =
  720.                     '';
  721.                 temp->lookupCtlOwnerIndexLen =
  722.                     item->lookupCtlOwnerIndexLen;
  723.                 temp->lookupCtlOperationName =
  724.                     (char *) malloc(item->lookupCtlOperationNameLen + 1);
  725.                 if (temp->lookupCtlOperationName == NULL) {
  726.                     exit(1);
  727.                 }
  728.                 memcpy(temp->lookupCtlOperationName,
  729.                        item->lookupCtlOperationName,
  730.                        item->lookupCtlOperationNameLen + 1);
  731.                 temp->lookupCtlOperationName[item->
  732.                                              lookupCtlOperationNameLen] =
  733.                     '';
  734.                 temp->lookupCtlOperationNameLen =
  735.                     item->lookupCtlOperationNameLen;
  736.                 temp->lookupResultsIndex = n;
  737.                 temp->lookupResultsAddressType = 16;
  738.                 temp->lookupResultsAddress =
  739.                     (char *) malloc(strlen(lookup->h_aliases[i]) + 1);
  740.                 if (temp->lookupResultsAddress == NULL) {
  741.                     exit(1);
  742.                 }
  743.                 memcpy(temp->lookupResultsAddress, lookup->h_aliases[i],
  744.                        strlen(lookup->h_aliases[i]) + 1);
  745.                 temp->lookupResultsAddress[strlen(lookup->h_aliases[i])] =
  746.                     '';
  747.                 temp->lookupResultsAddressLen =
  748.                     strlen(lookup->h_aliases[i]);
  749.                 current->next = temp;
  750.                 current = temp;
  751.                 i = i + 1;
  752.                 n = n + 1;
  753.             }
  754.             if (item->ResultsTable != NULL)
  755.                 current->next = NULL;
  756.             else
  757.                 current = NULL;
  758.         }
  759.         if (item->ResultsTable != NULL)
  760.             if (lookupResultsTable_add(item) != SNMPERR_SUCCESS)
  761.                 DEBUGMSGTL(("lookupResultsTable",
  762.                             "registered an entry errorn"));
  763.         SNMP_FREE(address);
  764.         address = NULL;
  765.         return;
  766.     } else {
  767.         SNMP_FREE(address);
  768.         address = NULL;
  769.         return;
  770.     }
  771. }
  772. int
  773. modify_lookupCtlOperStatus(struct lookupTable_data *thedata, long val)
  774. {
  775.     netsnmp_variable_list *vars = NULL;
  776.     struct lookupTable_data *StorageTmp = NULL;
  777.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->lookupCtlOwnerIndex, thedata->lookupCtlOwnerIndexLen);   /* lookupCtlOwnerIndex */
  778.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->lookupCtlOperationName, thedata->lookupCtlOperationNameLen);     /* lookupCtlOperationName */
  779.     if ((StorageTmp =
  780.          header_complex_get(lookupCtlTableStorage, vars)) == NULL) {
  781.         snmp_free_varbind(vars);
  782.         vars = NULL;
  783.         return SNMP_ERR_NOSUCHNAME;
  784.     }
  785.     StorageTmp->lookupCtlOperStatus = val;
  786.     snmp_free_varbind(vars);
  787.     vars = NULL;
  788.     DEBUGMSGTL(("lookupOperStatus", "done.n"));
  789.     return SNMPERR_SUCCESS;
  790. }
  791. int
  792. modify_lookupCtlTime(struct lookupTable_data *thedata, unsigned long val)
  793. {
  794.     netsnmp_variable_list *vars = NULL;
  795.     struct lookupTable_data *StorageTmp = NULL;
  796.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->lookupCtlOwnerIndex, thedata->lookupCtlOwnerIndexLen);   /* lookupCtlOwnerIndex */
  797.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->lookupCtlOperationName, thedata->lookupCtlOperationNameLen);     /* lookupCtlOperationName */
  798.     if ((StorageTmp =
  799.          header_complex_get(lookupCtlTableStorage, vars)) == NULL) {
  800.         snmp_free_varbind(vars);
  801.         vars = NULL;
  802.         return SNMP_ERR_NOSUCHNAME;
  803.     }
  804.     StorageTmp->lookupCtlTime = val;
  805.     snmp_free_varbind(vars);
  806.     vars = NULL;
  807.     DEBUGMSGTL(("lookupCtlTime", "done.n"));
  808.     return SNMPERR_SUCCESS;
  809. }
  810. int
  811. modify_lookupCtlRc(struct lookupTable_data *thedata, long val)
  812. {
  813.     netsnmp_variable_list *vars = NULL;
  814.     struct lookupTable_data *StorageTmp = NULL;
  815.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->lookupCtlOwnerIndex, thedata->lookupCtlOwnerIndexLen);   /* lookupCtlOwnerIndex */
  816.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->lookupCtlOperationName, thedata->lookupCtlOperationNameLen);     /* lookupCtlOperationName */
  817.     if ((StorageTmp =
  818.          header_complex_get(lookupCtlTableStorage, vars)) == NULL) {
  819.         snmp_free_varbind(vars);
  820.         vars = NULL;
  821.         return SNMP_ERR_NOSUCHNAME;
  822.     }
  823.     StorageTmp->lookupCtlRc = val;
  824.     snmp_free_varbind(vars);
  825.     vars = NULL;
  826.     DEBUGMSGTL(("lookupOperStatus", "done.n"));
  827.     return SNMPERR_SUCCESS;
  828. }
  829. int
  830. lookupResultsTable_del(struct lookupTable_data *thedata)
  831. {
  832.     struct header_complex_index *hciptr2 = NULL;
  833.     struct lookupResultsTable_data *StorageDel = NULL;
  834.     netsnmp_variable_list *vars = NULL;
  835.     oid             newoid[MAX_OID_LEN];
  836.     size_t          newoid_len;
  837.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->lookupCtlOwnerIndex, thedata->lookupCtlOwnerIndexLen);   /* lookupCtlOwnerIndex */
  838.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->lookupCtlOperationName, thedata->lookupCtlOperationNameLen);     /* lookupCtlOperationName */
  839.     bzero(newoid, MAX_OID_LEN * sizeof(oid));
  840.     header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars);
  841.     snmp_free_varbind(vars);
  842.     vars = NULL;
  843.     for (hciptr2 = lookupResultsTableStorage; hciptr2 != NULL;
  844.          hciptr2 = hciptr2->next) {
  845.         if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len)
  846.             == 0) {
  847.             StorageDel =
  848.                 header_complex_extract_entry(&lookupResultsTableStorage,
  849.                                              hciptr2);
  850.             if (StorageDel != NULL) {
  851.                 SNMP_FREE(StorageDel->lookupCtlOwnerIndex);
  852.                 SNMP_FREE(StorageDel->lookupCtlOperationName);
  853.                 SNMP_FREE(StorageDel->lookupResultsAddress);
  854.                 SNMP_FREE(StorageDel);
  855.             }
  856.             DEBUGMSGTL(("lookupResultsTable", "delete  success!n"));
  857.         }
  858.     }
  859.     return SNMPERR_SUCCESS;
  860. }
  861. int
  862. write_lookupCtlTargetAddressType(int action,
  863.                                  u_char * var_val,
  864.                                  u_char var_val_type,
  865.                                  size_t var_val_len,
  866.                                  u_char * statP, oid * name,
  867.                                  size_t name_len)
  868. {
  869.     static size_t   tmpvar;
  870.     struct lookupTable_data *StorageTmp = NULL;
  871.     static size_t   tmplen;
  872.     size_t          newlen =
  873.         name_len - (sizeof(lookupCtlTable_variables_oid) / sizeof(oid) +
  874.                     3 - 1);
  875.     if ((StorageTmp =
  876.          header_complex(lookupCtlTableStorage, NULL,
  877.                         &name[sizeof(lookupCtlTable_variables_oid) /
  878.                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
  879.                         NULL)) == NULL)
  880.         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  881.     if (StorageTmp && StorageTmp->storagetype == ST_READONLY) {
  882.         return SNMP_ERR_NOTWRITABLE;
  883.     }
  884.     if (StorageTmp && StorageTmp->lookupCtlRowStatus == RS_ACTIVE) {
  885.         return SNMP_ERR_NOTWRITABLE;
  886.     }
  887.     switch (action) {
  888.     case RESERVE1:
  889.         if (var_val_type != ASN_INTEGER) {
  890.             snmp_log(LOG_ERR,
  891.                      "write to lookupCtlTargetAddressType not ASN_INTEGERn");
  892.             return SNMP_ERR_WRONGTYPE;
  893.         }
  894.         break;
  895.     case RESERVE2:
  896.         /*
  897.          * memory reseveration, final preparation... 
  898.          */
  899.         break;
  900.     case FREE:
  901.         /*
  902.          * Release any resources that have been allocated 
  903.          */
  904.         break;
  905.     case ACTION:
  906.         /*
  907.          * The variable has been stored in objid for
  908.          * you to use, and you have just been asked to do something with
  909.          * it.  Note that anything done here must be reversable in the UNDO case 
  910.          */
  911.         tmpvar = StorageTmp->lookupCtlTargetAddressType;
  912.         StorageTmp->lookupCtlTargetAddressType = *((long *) var_val);
  913.         break;
  914.     case UNDO:
  915.         /*
  916.          * Back out any changes made in the ACTION case 
  917.          */
  918.         StorageTmp->lookupCtlTargetAddressType = tmpvar;
  919.         break;
  920.     case COMMIT:
  921.         /*
  922.          * Things are working well, so it's now safe to make the change
  923.          * permanently.  Make sure that anything done here can't fail! 
  924.          */
  925.         break;
  926.     }
  927.     return SNMP_ERR_NOERROR;
  928. }
  929. int
  930. write_lookupCtlTargetAddress(int action,
  931.                              u_char * var_val,
  932.                              u_char var_val_type,
  933.                              size_t var_val_len,
  934.                              u_char * statP, oid * name, size_t name_len)
  935. {
  936.     static char    *tmpvar = NULL;
  937.     static size_t   tmplen;
  938.     struct lookupTable_data *StorageTmp = NULL;
  939.     size_t          newlen =
  940.         name_len - (sizeof(lookupCtlTable_variables_oid) / sizeof(oid) +
  941.                     3 - 1);
  942.     if ((StorageTmp =
  943.          header_complex(lookupCtlTableStorage, NULL,
  944.                         &name[sizeof(lookupCtlTable_variables_oid) /
  945.                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
  946.                         NULL)) == NULL)
  947.         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  948.     if (StorageTmp && StorageTmp->storagetype == ST_READONLY) {
  949.         return SNMP_ERR_NOTWRITABLE;
  950.     }
  951.     if (StorageTmp && StorageTmp->lookupCtlRowStatus == RS_ACTIVE) {
  952.         return SNMP_ERR_NOTWRITABLE;
  953.     }
  954.     switch (action) {
  955.     case RESERVE1:
  956.         if (var_val_type != ASN_OCTET_STR) {
  957.             snmp_log(LOG_ERR,
  958.                      "write to lookupCtlTargetAddress not ASN_OCTET_STRn");
  959.             return SNMP_ERR_WRONGTYPE;
  960.         }
  961.         break;
  962.     case RESERVE2:
  963.         /*
  964.          * memory reseveration, final preparation... 
  965.          */
  966.         break;
  967.     case FREE:
  968.         /*
  969.          * Release any resources that have been allocated 
  970.          */
  971.         break;
  972.     case ACTION:
  973.         /*
  974.          * The variable has been stored in long_ret for
  975.          * you to use, and you have just been asked to do something with
  976.          * it.  Note that anything done here must be reversable in the UNDO case 
  977.          */
  978.         tmpvar = StorageTmp->lookupCtlTargetAddress;
  979.         tmplen = StorageTmp->lookupCtlTargetAddressLen;
  980.         if ((StorageTmp->lookupCtlTargetAddress =
  981.              (char *) malloc(var_val_len + 1)) == NULL) {
  982.             exit(1);
  983.         }
  984.         memcpy(StorageTmp->lookupCtlTargetAddress, var_val, var_val_len);
  985.         StorageTmp->lookupCtlTargetAddress[var_val_len] = '';
  986.         StorageTmp->lookupCtlTargetAddressLen = var_val_len;
  987.         break;
  988.     case UNDO:
  989.         /*
  990.          * Back out any changes made in the ACTION case 
  991.          */
  992.         free(StorageTmp->lookupCtlTargetAddress);
  993.         StorageTmp->lookupCtlTargetAddress = NULL;
  994.         StorageTmp->lookupCtlTargetAddress = tmpvar;
  995.         StorageTmp->lookupCtlTargetAddressLen = tmplen;
  996.         break;
  997.     case COMMIT:
  998.         /*
  999.          * Things are working well, so it's now safe to make the change
  1000.          * permanently.  Make sure that anything done here can't fail! 
  1001.          */
  1002.         free(tmpvar);
  1003.         tmpvar = NULL;
  1004.         break;
  1005.     }
  1006.     return SNMP_ERR_NOERROR;
  1007. }
  1008. int
  1009. write_lookupCtlRowStatus(int action,
  1010.                          u_char * var_val,
  1011.                          u_char var_val_type,
  1012.                          size_t var_val_len,
  1013.                          u_char * statP, oid * name, size_t name_len)
  1014. {
  1015.     struct lookupTable_data *StorageTmp = NULL;
  1016.     static struct lookupTable_data *StorageNew, *StorageDel = NULL;
  1017.     size_t          newlen =
  1018.         name_len - (sizeof(lookupCtlTable_variables_oid) / sizeof(oid) +
  1019.                     3 - 1);
  1020.     static int      old_value;
  1021.     int             set_value;
  1022.     static netsnmp_variable_list *vars, *vp;
  1023.     struct header_complex_index *hciptr = NULL;
  1024.     StorageTmp =
  1025.         header_complex(lookupCtlTableStorage, NULL,
  1026.                        &name[sizeof(lookupCtlTable_variables_oid) /
  1027.                              sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL);
  1028.     if (var_val_type != ASN_INTEGER || var_val == NULL) {
  1029.         snmp_log(LOG_ERR, "write to lookupCtlRowStatus not ASN_INTEGERn");
  1030.         return SNMP_ERR_WRONGTYPE;
  1031.     }
  1032.     if (StorageTmp && StorageTmp->storagetype == ST_READONLY) {
  1033.         return SNMP_ERR_NOTWRITABLE;
  1034.     }
  1035.     set_value = *((long *) var_val);
  1036.     /*
  1037.      * check legal range, and notReady is reserved for us, not a user 
  1038.      */
  1039.     if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY)
  1040.         return SNMP_ERR_INCONSISTENTVALUE;
  1041.     switch (action) {
  1042.     case RESERVE1:
  1043.         /*
  1044.          * stage one: test validity 
  1045.          */
  1046.         if (StorageTmp == NULL) {
  1047.             /*
  1048.              * create the row now? 
  1049.              */
  1050.             /*
  1051.              * ditch illegal values now 
  1052.              */
  1053.             if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) {
  1054.                 return SNMP_ERR_INCONSISTENTVALUE;
  1055.             }
  1056.             /*
  1057.              * destroying a non-existent row is actually legal 
  1058.              */
  1059.             if (set_value == RS_DESTROY) {
  1060.                 return SNMP_ERR_NOERROR;
  1061.             }
  1062.             /*
  1063.              * illegal creation values 
  1064.              */
  1065.             if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) {
  1066.                 return SNMP_ERR_INCONSISTENTVALUE;
  1067.             }
  1068.         } else {
  1069.             /*
  1070.              * row exists.  Check for a valid state change 
  1071.              */
  1072.             if (set_value == RS_CREATEANDGO
  1073.                 || set_value == RS_CREATEANDWAIT) {
  1074.                 /*
  1075.                  * can't create a row that exists 
  1076.                  */
  1077.                 return SNMP_ERR_INCONSISTENTVALUE;
  1078.             }
  1079.             /*
  1080.              * XXX: interaction with row storage type needed 
  1081.              */
  1082.             if (StorageTmp->lookupCtlRowStatus == RS_ACTIVE &&
  1083.                 set_value != RS_DESTROY) {
  1084.                 /*
  1085.                  * "Once made active an entry may not be modified except to 
  1086.                  * delete it."  XXX: doesn't this in fact apply to ALL
  1087.                  * columns of the table and not just this one?  
  1088.                  */
  1089.                 return SNMP_ERR_INCONSISTENTVALUE;
  1090.             }
  1091.             if (StorageTmp->storagetype != ST_NONVOLATILE)
  1092.                 return SNMP_ERR_NOTWRITABLE;
  1093.         }
  1094.         break;
  1095.     case RESERVE2:
  1096.         /*
  1097.          * memory reseveration, final preparation... 
  1098.          */
  1099.         if (StorageTmp == NULL) {
  1100.             /*
  1101.              * creation 
  1102.              */
  1103.             if (set_value == RS_DESTROY) {
  1104.                 return SNMP_ERR_NOERROR;
  1105.             }
  1106.             vars = NULL;
  1107.             /*
  1108.              * 将name为空的三个索引字段加到var变量列表的末尾 
  1109.              */
  1110.             snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0);  /* lookupCtlOwnerIndex */
  1111.             snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0);  /* lookupCtlOperationName */
  1112.             if (header_complex_parse_oid
  1113.                 (&
  1114.                  (name
  1115.                   [sizeof(lookupCtlTable_variables_oid) / sizeof(oid) +
  1116.                    2]), newlen, vars) != SNMPERR_SUCCESS) {
  1117.                 /*
  1118.                  * XXX: free, zero vars 
  1119.                  */
  1120.                 snmp_free_varbind(vars);
  1121.                 vars = NULL;
  1122.                 return SNMP_ERR_INCONSISTENTNAME;
  1123.             }
  1124.             vp = vars;
  1125.             StorageNew = create_lookupTable_data();
  1126.             StorageNew->lookupCtlOwnerIndex = malloc(vp->val_len + 1);
  1127.             memcpy(StorageNew->lookupCtlOwnerIndex, vp->val.string,
  1128.                    vp->val_len);
  1129.             StorageNew->lookupCtlOwnerIndex[vp->val_len] = '';
  1130.             StorageNew->lookupCtlOwnerIndexLen = vp->val_len;
  1131.             vp = vp->next_variable;
  1132.             StorageNew->lookupCtlOperationName = malloc(vp->val_len + 1);
  1133.             memcpy(StorageNew->lookupCtlOperationName, vp->val.string,
  1134.                    vp->val_len);
  1135.             StorageNew->lookupCtlOperationName[vp->val_len] = '';
  1136.             StorageNew->lookupCtlOperationNameLen = vp->val_len;
  1137.             vp = vp->next_variable;
  1138.             /*
  1139.              * XXX: fill in default row values here into StorageNew 
  1140.              */
  1141.             StorageNew->lookupCtlTargetAddressType = 1; /* ipv4 */
  1142.             StorageNew->lookupCtlRowStatus = set_value;
  1143.             snmp_free_varbind(vars);
  1144.             vars = NULL;
  1145.             /*
  1146.              * XXX: free, zero vars, no longer needed? 
  1147.              */
  1148.         }
  1149.         break;
  1150.     case FREE:
  1151.         /*
  1152.          * XXX: free, zero vars 
  1153.          */
  1154.         /*
  1155.          * Release any resources that have been allocated 
  1156.          */
  1157.         break;
  1158.     case ACTION:
  1159.         /*
  1160.          * The variable has been stored in set_value for you to
  1161.          * use, and you have just been asked to do something with
  1162.          * it.  Note that anything done here must be reversable in
  1163.          * the UNDO case 
  1164.          */
  1165.         if (StorageTmp == NULL) {
  1166.             /*
  1167.              * row creation, so add it 
  1168.              */
  1169.             if (set_value == RS_DESTROY) {
  1170.                 return SNMP_ERR_NOERROR;
  1171.             }
  1172.             if (StorageNew != NULL)
  1173. #if 1
  1174.                 DEBUGMSGTL(("lookupCtlTable",
  1175.                             "write_lookupCtlRowStatus entering new=%d...  n",
  1176.                             action));
  1177. #endif
  1178.             lookupCtlTable_add(StorageNew);
  1179.             /*
  1180.              * XXX: ack, and if it is NULL? 
  1181.              */
  1182.         } else if (set_value != RS_DESTROY) {
  1183.             /*
  1184.              * set the flag? 
  1185.              */
  1186.             old_value = StorageTmp->lookupCtlRowStatus;
  1187.             StorageTmp->lookupCtlRowStatus = *((long *) var_val);
  1188.         } else {
  1189.             /*
  1190.              * destroy...  extract it for now 
  1191.              */
  1192.             DEBUGMSGTL(("lookupCtlTable",
  1193.                         "write_lookupCtlTable_delete 1 n"));
  1194.             hciptr =
  1195.                 header_complex_find_entry(lookupCtlTableStorage,
  1196.                                           StorageTmp);
  1197.             StorageDel =
  1198.                 header_complex_extract_entry(&lookupCtlTableStorage,
  1199.                                              hciptr);
  1200.             lookupResultsTable_del(StorageTmp);
  1201.             DEBUGMSGTL(("lookupCtlTable",
  1202.                         "write_lookupCtlTable_delete  n"));
  1203.         }
  1204.         break;
  1205.     case UNDO:
  1206.         /*
  1207.          * Back out any changes made in the ACTION case 
  1208.          */
  1209.         if (StorageTmp == NULL) {
  1210.             /*
  1211.              * row creation, so remove it again 
  1212.              */
  1213.             hciptr =
  1214.                 header_complex_find_entry(lookupCtlTableStorage,
  1215.                                           StorageTmp);
  1216.             StorageDel =
  1217.                 header_complex_extract_entry(&lookupCtlTableStorage,
  1218.                                              hciptr);
  1219.             lookupResultsTable_del(StorageTmp);
  1220.             /*
  1221.              * XXX: free it 
  1222.              */
  1223.         } else if (StorageDel != NULL) {
  1224.             /*
  1225.              * row deletion, so add it again 
  1226.              */
  1227.             lookupCtlTable_add(StorageDel);
  1228.             lookupResultsTable_add(StorageDel);
  1229.         } else {
  1230.             StorageTmp->lookupCtlRowStatus = old_value;
  1231.         }
  1232.         break;
  1233.     case COMMIT:
  1234.         /*
  1235.          * Things are working well, so it's now safe to make the change
  1236.          * permanently.  Make sure that anything done here can't fail! 
  1237.          */
  1238.         if (StorageTmp == NULL) {
  1239.             if (set_value == RS_DESTROY) {
  1240.                 return SNMP_ERR_NOERROR;
  1241.             }
  1242.         }
  1243.         if (StorageDel != NULL) {
  1244.             SNMP_FREE(StorageDel->lookupCtlOwnerIndex);
  1245.             StorageDel->lookupCtlOwnerIndex = NULL;
  1246.             SNMP_FREE(StorageDel->lookupCtlOperationName);
  1247.             StorageDel->lookupCtlOperationName = NULL;
  1248.             SNMP_FREE(StorageDel->lookupCtlTargetAddress);
  1249.             StorageDel->lookupCtlTargetAddress = NULL;
  1250.             SNMP_FREE(StorageDel);
  1251.             StorageDel = NULL;
  1252.             StorageDel = 0;
  1253.             /*
  1254.              * XXX: free it, its dead 
  1255.              */
  1256.         } else {
  1257.             if (StorageTmp
  1258.                 && StorageTmp->lookupCtlRowStatus == RS_CREATEANDGO) {
  1259.                 StorageTmp->lookupCtlRowStatus = RS_ACTIVE;
  1260.             } else if (StorageTmp &&
  1261.                        StorageTmp->lookupCtlRowStatus ==
  1262.                        RS_CREATEANDWAIT) {
  1263.                 StorageTmp->lookupCtlRowStatus = RS_NOTINSERVICE;
  1264.             }
  1265.         }
  1266.         if (StorageTmp && StorageTmp->lookupCtlRowStatus == RS_ACTIVE) {
  1267. #if 1
  1268.             DEBUGMSGTL(("lookupCtlTable",
  1269.                         "write_lookupCtlRowStatus entering runbefore=%ld...  n",
  1270.                         StorageTmp->lookupCtlTargetAddressType));
  1271. #endif
  1272.             modify_lookupCtlOperStatus(StorageTmp, 2l);
  1273.             run_lookup((struct lookupTable_data *) StorageTmp);
  1274.         }
  1275.         break;
  1276.     }
  1277.     return SNMP_ERR_NOERROR;
  1278. }