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

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  * This file was generated by mib2c and is intended for use as
  3.  * a mib module for the ucd-snmp snmpd agent. 
  4.  */
  5. /*
  6.  * This should always be included first before anything else 
  7.  */
  8. #include <net-snmp/net-snmp-config.h>
  9. #include <sys/types.h>
  10. #if HAVE_WINSOCK_H
  11. #include <winsock.h>
  12. #endif
  13. #if HAVE_STDLIB_H
  14. #include <stdlib.h>
  15. #endif
  16. #if HAVE_STRING_H
  17. #include <string.h>
  18. #else
  19. #include <strings.h>
  20. #endif
  21. /*
  22.  * minimal include directives 
  23.  */
  24. #include <net-snmp/net-snmp-includes.h>
  25. #include <net-snmp/agent/net-snmp-agent-includes.h>
  26. #include "header_complex.h"
  27. #include "snmpNotifyTable.h"
  28. #include "target/snmpTargetParamsEntry.h"
  29. #include "target/snmpTargetAddrEntry.h"
  30. #include "target/target.h"
  31. #include <net-snmp/agent/agent_callbacks.h>
  32. #include <net-snmp/agent/agent_trap.h>
  33. SNMPCallback    store_snmpNotifyTable;
  34. /*
  35.  * snmpNotifyTable_variables_oid:
  36.  *   this is the top level oid that we want to register under.  This
  37.  *   is essentially a prefix, with the suffix appearing in the
  38.  *   variable below.
  39.  */
  40. oid             snmpNotifyTable_variables_oid[] =
  41.     { 1, 3, 6, 1, 6, 3, 13, 1, 1 };
  42. /*
  43.  * variable2 snmpNotifyTable_variables:
  44.  *   this variable defines function callbacks and type return information 
  45.  *   for the snmpNotifyTable mib section 
  46.  */
  47. struct variable2 snmpNotifyTable_variables[] = {
  48.     /*
  49.      * magic number        , variable type , ro/rw , callback fn  , L, oidsuffix 
  50.      */
  51. #define   SNMPNOTIFYTAG         4
  52.     {SNMPNOTIFYTAG, ASN_OCTET_STR, RWRITE, var_snmpNotifyTable, 2, {1, 2}},
  53. #define   SNMPNOTIFYTYPE        5
  54.     {SNMPNOTIFYTYPE, ASN_INTEGER, RWRITE, var_snmpNotifyTable, 2, {1, 3}},
  55. #define   SNMPNOTIFYSTORAGETYPE  6
  56.     {SNMPNOTIFYSTORAGETYPE, ASN_INTEGER, RWRITE, var_snmpNotifyTable, 2,
  57.      {1, 4}},
  58. #define   SNMPNOTIFYROWSTATUS   7
  59.     {SNMPNOTIFYROWSTATUS, ASN_INTEGER, RWRITE, var_snmpNotifyTable, 2,
  60.      {1, 5}},
  61. };
  62. /*
  63.  * (L = length of the oidsuffix) 
  64.  */
  65. /*
  66.  * global storage of our data, saved in and configured by header_complex() 
  67.  */
  68. static struct header_complex_index *snmpNotifyTableStorage = NULL;
  69. int
  70. send_notifications(int major, int minor, void *serverarg, void *clientarg)
  71. {
  72.     struct header_complex_index *hptr;
  73.     struct snmpNotifyTable_data *nptr;
  74.     netsnmp_session *sess, *sptr;
  75.     netsnmp_pdu    *template_pdu = (netsnmp_pdu *) serverarg;
  76.     DEBUGMSGTL(("send_notifications", "starting: pdu=%x, vars=%xn",
  77.                 template_pdu, template_pdu->variables));
  78.     for (hptr = snmpNotifyTableStorage; hptr; hptr = hptr->next) {
  79.         nptr = (struct snmpNotifyTable_data *) hptr->data;
  80.         if (nptr->snmpNotifyRowStatus != RS_ACTIVE)
  81.             continue;
  82.         if (!nptr->snmpNotifyTag)
  83.             continue;
  84.         sess = get_target_sessions(nptr->snmpNotifyTag, NULL, NULL);
  85.         /*
  86.          * XXX: filter appropriately 
  87.          */
  88.         for (sptr = sess; sptr; sptr = sptr->next) {
  89. #ifndef DISABLE_SNMPV1
  90.             if (sptr->version == SNMP_VERSION_1 &&
  91.                 minor == SNMPD_CALLBACK_SEND_TRAP1) {
  92.                 send_trap_to_sess(sptr, template_pdu);
  93.             } else
  94. #endif
  95.             if ((sptr->version == SNMP_VERSION_3
  96. #ifndef DISABLE_SNMPV2C
  97.                  || sptr->version == SNMP_VERSION_2c
  98. #endif
  99.                 ) && minor == SNMPD_CALLBACK_SEND_TRAP2) {
  100.                 if (nptr->snmpNotifyType == SNMPNOTIFYTYPE_INFORM) {
  101.                     template_pdu->command = SNMP_MSG_INFORM;
  102.                 } else {
  103.                     template_pdu->command = SNMP_MSG_TRAP2;
  104.                 }
  105.                 send_trap_to_sess(sptr, template_pdu);
  106.             }
  107.         }
  108.     }
  109.     return 0;
  110. }
  111. #define MAX_ENTRIES 1024
  112. int
  113. notifyTable_register_notifications(int major, int minor,
  114.                                    void *serverarg, void *clientarg)
  115. {
  116.     struct targetAddrTable_struct *ptr;
  117.     struct targetParamTable_struct *pptr;
  118.     struct snmpNotifyTable_data *nptr;
  119.     int             confirm, i;
  120.     char            buf[SNMP_MAXBUF_SMALL];
  121.     netsnmp_transport *t = NULL;
  122.     struct agent_add_trap_args *args =
  123.         (struct agent_add_trap_args *) serverarg;
  124.     netsnmp_session *ss;
  125.     if (!args || !(args->ss)) {
  126.         return (0);
  127.     }
  128.     confirm = args->confirm;
  129.     ss = args->ss;
  130.     /*
  131.      * XXX: START move target creation to target code 
  132.      */
  133.     for (i = 0; i < MAX_ENTRIES; i++) {
  134.         sprintf(buf, "internal%d", i);
  135.         if (get_addrForName(buf) == NULL && get_paramEntry(buf) == NULL)
  136.             break;
  137.     }
  138.     if (i == MAX_ENTRIES) {
  139.         snmp_log(LOG_ERR,
  140.                  "Can't register new trap destination: max limit reached: %d",
  141.                  MAX_ENTRIES);
  142.         snmp_sess_close(ss);
  143.         return (0);
  144.     }
  145.     /*
  146.      * address 
  147.      */
  148.     ptr = snmpTargetAddrTable_create();
  149.     ptr->name = strdup(buf);
  150.     t = snmp_sess_transport(snmp_sess_pointer(ss));
  151.     memcpy(ptr->tDomain, t->domain, t->domain_length * sizeof(oid));
  152.     ptr->tDomainLen = t->domain_length;
  153.     ptr->tAddressLen = t->remote_length;
  154.     ptr->tAddress = t->remote;
  155.     ptr->timeout = ss->timeout / 1000;
  156.     ptr->retryCount = ss->retries;
  157.     SNMP_FREE(ptr->tagList);
  158.     ptr->tagList = strdup(ptr->name);
  159.     ptr->params = strdup(ptr->name);
  160.     ptr->storageType = ST_READONLY;
  161.     ptr->rowStatus = RS_ACTIVE;
  162.     ptr->sess = ss;
  163.     DEBUGMSGTL(("trapsess", "adding to trap tablen"));
  164.     snmpTargetAddrTable_add(ptr);
  165.     /*
  166.      * param 
  167.      */
  168.     pptr = snmpTargetParamTable_create();
  169.     pptr->paramName = strdup(buf);
  170.     pptr->mpModel = ss->version;
  171.     if (ss->version == SNMP_VERSION_3) {
  172.         pptr->secModel = ss->securityModel;
  173.         pptr->secLevel = ss->securityLevel;
  174.         pptr->secName = (char *) malloc(ss->securityNameLen + 1);
  175.         memcpy((void *) pptr->secName, (void *) ss->securityName,
  176.                ss->securityNameLen);
  177.         pptr->secName[ss->securityNameLen] = 0;
  178.     }
  179. #if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C)
  180.        else {
  181.         pptr->secModel = ss->version == SNMP_VERSION_1 ?
  182.             SNMP_SEC_MODEL_SNMPv1 : SNMP_SEC_MODEL_SNMPv2c;
  183.         pptr->secLevel = SNMP_SEC_LEVEL_NOAUTH;
  184.         pptr->secName = NULL;
  185.         if (ss->community && (ss->community_len > 0)) {
  186.             pptr->secName = (char *) malloc(ss->community_len + 1);
  187.             memcpy((void *) pptr->secName, (void *) ss->community,
  188.                    ss->community_len);
  189.             pptr->secName[ss->community_len] = 0;
  190.         }
  191.     }
  192. #endif
  193.     pptr->storageType = ST_READONLY;
  194.     pptr->rowStatus = RS_ACTIVE;
  195.     snmpTargetParamTable_add(pptr);
  196.     /*
  197.      * XXX: END move target creation to target code 
  198.      */
  199.     /*
  200.      * notify table 
  201.      */
  202.     nptr = SNMP_MALLOC_STRUCT(snmpNotifyTable_data);
  203.     nptr->snmpNotifyName = strdup(buf);
  204.     nptr->snmpNotifyNameLen = strlen(buf);
  205.     nptr->snmpNotifyTag = strdup(buf);
  206.     nptr->snmpNotifyTagLen = strlen(buf);
  207.     nptr->snmpNotifyType = confirm ?
  208.         SNMPNOTIFYTYPE_INFORM : SNMPNOTIFYTYPE_TRAP;
  209.     nptr->snmpNotifyStorageType = ST_READONLY;
  210.     nptr->snmpNotifyRowStatus = RS_ACTIVE;
  211.     snmpNotifyTable_add(nptr);
  212.     return 0;
  213. }
  214. /*
  215.  * XXX: this really needs to be done for the target mib entries too.
  216.  * But we can only trust that we've added stuff here and we don't want
  217.  * to destroy other valid entries in the target tables, so...  Don't
  218.  * do too many kill -HUPs to your agent as re reading the config file
  219.  * will be a slow memory leak in the target mib. 
  220.  */
  221. int
  222. notifyTable_unregister_notifications(int major, int minor,
  223.                                      void *serverarg, void *clientarg)
  224. {
  225.     struct header_complex_index *hptr, *nhptr;
  226.     struct snmpNotifyTable_data *nptr;
  227.     for (hptr = snmpNotifyTableStorage; hptr; hptr = nhptr) {
  228.         nptr = (struct snmpNotifyTable_data *) hptr->data;
  229.         nhptr = hptr->next;
  230.         if (nptr->snmpNotifyStorageType == ST_READONLY) {
  231.             header_complex_extract_entry(&snmpNotifyTableStorage, hptr);
  232.             SNMP_FREE(nptr->snmpNotifyName);
  233.             SNMP_FREE(nptr->snmpNotifyTag);
  234.             SNMP_FREE(nptr);
  235.         }
  236.     }
  237.     return (0);
  238. }
  239. /*
  240.  * init_snmpNotifyTable():
  241.  *   Initialization routine.  This is called when the agent starts up.
  242.  *   At a minimum, registration of your variables should take place here.
  243.  */
  244. void
  245. init_snmpNotifyTable(void)
  246. {
  247.     DEBUGMSGTL(("snmpNotifyTable", "initializing...  "));
  248.     /*
  249.      * register ourselves with the agent to handle our mib tree 
  250.      */
  251.     REGISTER_MIB("snmpNotifyTable", snmpNotifyTable_variables, variable2,
  252.                  snmpNotifyTable_variables_oid);
  253.     /*
  254.      * register our config handler(s) to deal with registrations 
  255.      */
  256.     snmpd_register_config_handler("snmpNotifyTable", parse_snmpNotifyTable,
  257.                                   NULL, NULL);
  258.     /*
  259.      * we need to be called back later to store our data 
  260.      */
  261.     snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
  262.                            store_snmpNotifyTable, NULL);
  263.     snmp_register_callback(SNMP_CALLBACK_APPLICATION,
  264.                            SNMPD_CALLBACK_SEND_TRAP1, send_notifications,
  265.                            NULL);
  266.     snmp_register_callback(SNMP_CALLBACK_APPLICATION,
  267.                            SNMPD_CALLBACK_SEND_TRAP2, send_notifications,
  268.                            NULL);
  269.     snmp_register_callback(SNMP_CALLBACK_APPLICATION,
  270.                            SNMPD_CALLBACK_REGISTER_NOTIFICATIONS,
  271.                            notifyTable_register_notifications, NULL);
  272.     snmp_register_callback(SNMP_CALLBACK_APPLICATION,
  273.                            SNMPD_CALLBACK_PRE_UPDATE_CONFIG,
  274.                            notifyTable_unregister_notifications, NULL);
  275.     /*
  276.      * place any other initialization junk you need here 
  277.      */
  278.     DEBUGMSGTL(("snmpNotifyTable", "done.n"));
  279. }
  280. /*
  281.  * snmpNotifyTable_add(): adds a structure node to our data set 
  282.  */
  283. int
  284. snmpNotifyTable_add(struct snmpNotifyTable_data *thedata)
  285. {
  286.     netsnmp_variable_list *vars = NULL;
  287.     DEBUGMSGTL(("snmpNotifyTable", "adding data...  "));
  288.     /*
  289.      * add the index variables to the varbind list, which is 
  290.      * used by header_complex to index the data 
  291.      */
  292.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OCTET_STR, (u_char *) thedata->snmpNotifyName, thedata->snmpNotifyNameLen);      /* snmpNotifyName */
  293.     header_complex_add_data(&snmpNotifyTableStorage, vars, thedata);
  294.     DEBUGMSGTL(("snmpNotifyTable", "registered an entryn"));
  295.     DEBUGMSGTL(("snmpNotifyTable", "done.n"));
  296.     return SNMPERR_SUCCESS;
  297. }
  298. /*
  299.  * parse_snmpNotifyTable():
  300.  *   parses .conf file entries needed to configure the mib.
  301.  */
  302. void
  303. parse_snmpNotifyTable(const char *token, char *line)
  304. {
  305.     size_t          tmpint;
  306.     struct snmpNotifyTable_data *StorageTmp =
  307.         SNMP_MALLOC_STRUCT(snmpNotifyTable_data);
  308.     DEBUGMSGTL(("snmpNotifyTable", "parsing config...  "));
  309.     if (StorageTmp == NULL) {
  310.         config_perror("malloc failure");
  311.         return;
  312.     }
  313.     line =
  314.         read_config_read_data(ASN_OCTET_STR, line,
  315.                               &StorageTmp->snmpNotifyName,
  316.                               &StorageTmp->snmpNotifyNameLen);
  317.     if (StorageTmp->snmpNotifyName == NULL) {
  318.         config_perror("invalid specification for snmpNotifyName");
  319.         return;
  320.     }
  321.     line =
  322.         read_config_read_data(ASN_OCTET_STR, line,
  323.                               &StorageTmp->snmpNotifyTag,
  324.                               &StorageTmp->snmpNotifyTagLen);
  325.     if (StorageTmp->snmpNotifyTag == NULL) {
  326.         config_perror("invalid specification for snmpNotifyTag");
  327.         return;
  328.     }
  329.     line =
  330.         read_config_read_data(ASN_INTEGER, line,
  331.                               &StorageTmp->snmpNotifyType, &tmpint);
  332.     line =
  333.         read_config_read_data(ASN_INTEGER, line,
  334.                               &StorageTmp->snmpNotifyStorageType, &tmpint);
  335.     line =
  336.         read_config_read_data(ASN_INTEGER, line,
  337.                               &StorageTmp->snmpNotifyRowStatus, &tmpint);
  338.     snmpNotifyTable_add(StorageTmp);
  339.     DEBUGMSGTL(("snmpNotifyTable", "done.n"));
  340. }
  341. /*
  342.  * store_snmpNotifyTable():
  343.  *   stores .conf file entries needed to configure the mib.
  344.  */
  345. int
  346. store_snmpNotifyTable(int majorID, int minorID, void *serverarg,
  347.                       void *clientarg)
  348. {
  349.     char            line[SNMP_MAXBUF];
  350.     char           *cptr;
  351.     size_t          tmpint;
  352.     struct snmpNotifyTable_data *StorageTmp;
  353.     struct header_complex_index *hcindex;
  354.     DEBUGMSGTL(("snmpNotifyTable", "storing data...  "));
  355.     for (hcindex = snmpNotifyTableStorage; hcindex != NULL;
  356.          hcindex = hcindex->next) {
  357.         StorageTmp = (struct snmpNotifyTable_data *) hcindex->data;
  358.         /*
  359.          * store permanent and nonvolatile rows.
  360.          * XXX should there be a qualification on RowStatus??
  361.          */
  362.         if ((StorageTmp->snmpNotifyStorageType == ST_NONVOLATILE) ||
  363.             (StorageTmp->snmpNotifyStorageType == ST_PERMANENT) ){
  364.             memset(line, 0, sizeof(line));
  365.             strcat(line, "snmpNotifyTable ");
  366.             cptr = line + strlen(line);
  367.             cptr =
  368.                 read_config_store_data(ASN_OCTET_STR, cptr,
  369.                                        &StorageTmp->snmpNotifyName,
  370.                                        &StorageTmp->snmpNotifyNameLen);
  371.             cptr =
  372.                 read_config_store_data(ASN_OCTET_STR, cptr,
  373.                                        &StorageTmp->snmpNotifyTag,
  374.                                        &StorageTmp->snmpNotifyTagLen);
  375.             cptr =
  376.                 read_config_store_data(ASN_INTEGER, cptr,
  377.                                        &StorageTmp->snmpNotifyType,
  378.                                        &tmpint);
  379.             cptr =
  380.                 read_config_store_data(ASN_INTEGER, cptr,
  381.                                        &StorageTmp->snmpNotifyStorageType,
  382.                                        &tmpint);
  383.             cptr =
  384.                 read_config_store_data(ASN_INTEGER, cptr,
  385.                                        &StorageTmp->snmpNotifyRowStatus,
  386.                                        &tmpint);
  387.             snmpd_store_config(line);
  388.         }
  389.     }
  390.     DEBUGMSGTL(("snmpNotifyTable", "done.n"));
  391.     return 0;
  392. }
  393. /*
  394.  * var_snmpNotifyTable():
  395.  *   Handle this table separately from the scalar value case.
  396.  *   The workings of this are basically the same as for var_snmpNotifyTable above.
  397.  */
  398. unsigned char  *
  399. var_snmpNotifyTable(struct variable *vp,
  400.                     oid * name,
  401.                     size_t * length,
  402.                     int exact,
  403.                     size_t * var_len, WriteMethod ** write_method)
  404. {
  405.     struct snmpNotifyTable_data *StorageTmp = NULL;
  406.     int             found = 1;
  407.     DEBUGMSGTL(("snmpNotifyTable",
  408.                 "var_snmpNotifyTable: Entering...  n"));
  409.     /*
  410.      * this assumes you have registered all your data properly
  411.      */
  412.     if ((StorageTmp = (struct snmpNotifyTable_data *)
  413.          header_complex((struct header_complex_index *)
  414.                         snmpNotifyTableStorage, vp, name, length, exact,
  415.                         var_len, write_method)) == NULL) {
  416.         found = 0;
  417.     }
  418.     switch (vp->magic) {
  419.     case SNMPNOTIFYTAG:
  420.         *write_method = write_snmpNotifyTag;
  421.         break;
  422.     case SNMPNOTIFYTYPE:
  423.         *write_method = write_snmpNotifyType;
  424.         break;
  425.     case SNMPNOTIFYSTORAGETYPE:
  426.         *write_method = write_snmpNotifyStorageType;
  427.         break;
  428.     case SNMPNOTIFYROWSTATUS:
  429.         *write_method = write_snmpNotifyRowStatus;
  430.         break;
  431.     default:
  432.         *write_method = NULL;
  433.     }
  434.     if (!found) {
  435.         return NULL;
  436.     }
  437.     switch (vp->magic) {
  438.     case SNMPNOTIFYTAG:
  439.         *var_len = StorageTmp->snmpNotifyTagLen;
  440.         return (u_char *) StorageTmp->snmpNotifyTag;
  441.     case SNMPNOTIFYTYPE:
  442.         *var_len = sizeof(StorageTmp->snmpNotifyType);
  443.         return (u_char *) & StorageTmp->snmpNotifyType;
  444.     case SNMPNOTIFYSTORAGETYPE:
  445.         *var_len = sizeof(StorageTmp->snmpNotifyStorageType);
  446.         return (u_char *) & StorageTmp->snmpNotifyStorageType;
  447.     case SNMPNOTIFYROWSTATUS:
  448.         *var_len = sizeof(StorageTmp->snmpNotifyRowStatus);
  449.         return (u_char *) & StorageTmp->snmpNotifyRowStatus;
  450.     default:
  451.         ERROR_MSG("");
  452.     }
  453.     return NULL;
  454. }
  455. static int
  456. is_delim(const char c)
  457. {
  458.     return (c == 0x020 || c == 0x09 || c == 0x0d || c == 0x0b);
  459. }
  460. int
  461. snmpTagValid(const char *tag, const size_t tagLen)
  462. {
  463.     size_t          i = 0;
  464.     for (i = 0; i < tagLen; i++) {
  465.         if (is_delim(tag[i])) {
  466.             /*
  467.              * Delimeters aren't allowed.  
  468.              */
  469.             return 0;
  470.         }
  471.     }
  472.     return 1;
  473. }
  474. static struct snmpNotifyTable_data *StorageNew;
  475. int
  476. write_snmpNotifyTag(int action,
  477.                     u_char * var_val,
  478.                     u_char var_val_type,
  479.                     size_t var_val_len,
  480.                     u_char * statP, oid * name, size_t name_len)
  481. {
  482.     static char    *tmpvar;
  483.     struct snmpNotifyTable_data *StorageTmp = NULL;
  484.     static size_t   tmplen;
  485.     size_t          newlen =
  486.         name_len - (sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) +
  487.                     3 - 1);
  488.     DEBUGMSGTL(("snmpNotifyTable",
  489.                 "write_snmpNotifyTag entering action=%d...  n", action));
  490.     if (action != RESERVE1 &&
  491.         (StorageTmp = (struct snmpNotifyTable_data *)
  492.          header_complex((struct header_complex_index *)
  493.                         snmpNotifyTableStorage, NULL,
  494.                         &name[sizeof(snmpNotifyTable_variables_oid) /
  495.                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
  496.                         NULL)) == NULL) {
  497.         if ((StorageTmp = StorageNew) == NULL)
  498.             return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */
  499.     }
  500.     switch (action) {
  501.     case RESERVE1:
  502.         if (var_val_type != ASN_OCTET_STR) {
  503.             return SNMP_ERR_WRONGTYPE;
  504.         }
  505.         if (var_val_len < 0 || var_val_len > 255) {
  506.             return SNMP_ERR_WRONGLENGTH;
  507.         }
  508.         if (!snmpTagValid(var_val, var_val_len)) {
  509.             return SNMP_ERR_WRONGVALUE;
  510.         }
  511.         break;
  512.     case RESERVE2:
  513.         /*
  514.          * memory reseveration, final preparation... 
  515.          */
  516.         tmpvar = StorageTmp->snmpNotifyTag;
  517.         tmplen = StorageTmp->snmpNotifyTagLen;
  518.         StorageTmp->snmpNotifyTag = calloc(1, var_val_len + 1);
  519.         if (NULL == StorageTmp->snmpNotifyTag)
  520.             return SNMP_ERR_RESOURCEUNAVAILABLE;
  521.         break;
  522.     case FREE:
  523.         /*
  524.          * Release any resources that have been allocated 
  525.          */
  526.         break;
  527.     case ACTION:
  528.         memcpy(StorageTmp->snmpNotifyTag, var_val, var_val_len);
  529.         StorageTmp->snmpNotifyTagLen = var_val_len;
  530.         break;
  531.     case UNDO:
  532.         /*
  533.          * Back out any changes made in the ACTION case 
  534.          */
  535.         SNMP_FREE(StorageTmp->snmpNotifyTag);
  536.         StorageTmp->snmpNotifyTag = tmpvar;
  537.         StorageTmp->snmpNotifyTagLen = tmplen;
  538.         tmpvar = NULL;
  539.         break;
  540.     case COMMIT:
  541.         /*
  542.          * Things are working well, so it's now safe to make the change
  543.          * permanently.  Make sure that anything done here can't fail! 
  544.          */
  545.         SNMP_FREE(tmpvar);
  546.         break;
  547.     }
  548.     return SNMP_ERR_NOERROR;
  549. }
  550. int
  551. write_snmpNotifyType(int action,
  552.                      u_char * var_val,
  553.                      u_char var_val_type,
  554.                      size_t var_val_len,
  555.                      u_char * statP, oid * name, size_t name_len)
  556. {
  557.     static int      tmpvar;
  558.     struct snmpNotifyTable_data *StorageTmp = NULL;
  559.     long            value = *((long *) var_val);
  560.     size_t          newlen =
  561.         name_len - (sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) +
  562.                     3 - 1);
  563.     DEBUGMSGTL(("snmpNotifyTable",
  564.                 "write_snmpNotifyType entering action=%d...  n", action));
  565.     if (action != RESERVE1 &&
  566.         (StorageTmp = (struct snmpNotifyTable_data *)
  567.          header_complex((struct header_complex_index *)
  568.                         snmpNotifyTableStorage, NULL,
  569.                         &name[sizeof(snmpNotifyTable_variables_oid) /
  570.                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
  571.                         NULL)) == NULL) {
  572.         if ((StorageTmp = StorageNew) == NULL)
  573.             return SNMP_ERR_NOSUCHNAME;
  574.     }
  575.     switch (action) {
  576.     case RESERVE1:
  577.         if (var_val_type != ASN_INTEGER) {
  578.             return SNMP_ERR_WRONGTYPE;
  579.         }
  580.         if (var_val_len != sizeof(long)) {
  581.             return SNMP_ERR_WRONGLENGTH;
  582.         }
  583.         if (value < 1 || value > 2) {
  584.             return SNMP_ERR_WRONGVALUE;
  585.         }
  586.         break;
  587.     case ACTION:
  588.         tmpvar = StorageTmp->snmpNotifyType;
  589.         StorageTmp->snmpNotifyType = value;
  590.         break;
  591.     case UNDO:
  592.         /*
  593.          * Back out any changes made in the ACTION case 
  594.          */
  595.         StorageTmp->snmpNotifyType = tmpvar;
  596.         break;
  597.     }
  598.     return SNMP_ERR_NOERROR;
  599. }
  600. int
  601. write_snmpNotifyStorageType(int action,
  602.                             u_char * var_val,
  603.                             u_char var_val_type,
  604.                             size_t var_val_len,
  605.                             u_char * statP, oid * name, size_t name_len)
  606. {
  607.     static int      tmpvar;
  608.     long            value = *((long *) var_val);
  609.     struct snmpNotifyTable_data *StorageTmp = NULL;
  610.     size_t          newlen =
  611.         name_len - (sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) +
  612.                     3 - 1);
  613.     DEBUGMSGTL(("snmpNotifyTable",
  614.                 "write_snmpNotifyStorageType entering action=%d...  n",
  615.                 action));
  616.     if (action != RESERVE1 &&
  617.         (StorageTmp = (struct snmpNotifyTable_data *)
  618.          header_complex((struct header_complex_index *)
  619.                         snmpNotifyTableStorage, NULL,
  620.                         &name[sizeof(snmpNotifyTable_variables_oid) /
  621.                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
  622.                         NULL)) == NULL) {
  623.         if ((StorageTmp = StorageNew) == NULL)
  624.             return SNMP_ERR_NOSUCHNAME;
  625.     }
  626.     switch (action) {
  627.     case RESERVE1:
  628.         if (var_val_type != ASN_INTEGER) {
  629.             return SNMP_ERR_WRONGTYPE;
  630.         }
  631.         if (var_val_len != sizeof(long)) {
  632.             return SNMP_ERR_WRONGLENGTH;
  633.         }
  634.         if (value != SNMP_STORAGE_OTHER && value != SNMP_STORAGE_VOLATILE
  635.             && value != SNMP_STORAGE_NONVOLATILE) {
  636.             return SNMP_ERR_WRONGVALUE;
  637.         }
  638.         break;
  639.     case ACTION:
  640.         tmpvar = StorageTmp->snmpNotifyStorageType;
  641.         StorageTmp->snmpNotifyStorageType = value;
  642.         break;
  643.     case UNDO:
  644.         StorageTmp->snmpNotifyStorageType = tmpvar;
  645.         break;
  646.     }
  647.     return SNMP_ERR_NOERROR;
  648. }
  649. int
  650. write_snmpNotifyRowStatus(int action,
  651.                           u_char * var_val,
  652.                           u_char var_val_type,
  653.                           size_t var_val_len,
  654.                           u_char * statP, oid * name, size_t name_len)
  655. {
  656.     struct snmpNotifyTable_data *StorageTmp = NULL;
  657.     static struct snmpNotifyTable_data *StorageDel;
  658.     size_t          newlen =
  659.         name_len - (sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) +
  660.                     3 - 1);
  661.     static int      old_value;
  662.     int             set_value = *((long *) var_val);
  663.     static netsnmp_variable_list *vars, *vp;
  664.     struct header_complex_index *hciptr;
  665.     DEBUGMSGTL(("snmpNotifyTable",
  666.                 "write_snmpNotifyRowStatus entering action=%d...  n",
  667.                 action));
  668.     StorageTmp = (struct snmpNotifyTable_data *)
  669.         header_complex((struct header_complex_index *)
  670.                        snmpNotifyTableStorage, NULL,
  671.                        &name[sizeof(snmpNotifyTable_variables_oid) /
  672.                              sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL);
  673.     switch (action) {
  674.     case RESERVE1:
  675.         if (var_val_type != ASN_INTEGER || var_val == NULL) {
  676.             return SNMP_ERR_WRONGTYPE;
  677.         }
  678.         if (var_val_len != sizeof(long)) {
  679.             return SNMP_ERR_WRONGLENGTH;
  680.         }
  681.         if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY) {
  682.             return SNMP_ERR_WRONGVALUE;
  683.         }
  684.         if (StorageTmp == NULL) {
  685.             /*
  686.              * create the row now? 
  687.              */
  688.             /*
  689.              * ditch illegal values now 
  690.              */
  691.             if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) {
  692.                 return SNMP_ERR_INCONSISTENTVALUE;
  693.             }
  694.         } else {
  695.             /*
  696.              * row exists.  Check for a valid state change 
  697.              */
  698.             if (set_value == RS_CREATEANDGO
  699.                 || set_value == RS_CREATEANDWAIT) {
  700.                 /*
  701.                  * can't create a row that exists 
  702.                  */
  703.                 return SNMP_ERR_INCONSISTENTVALUE;
  704.             }
  705.             /*
  706.              * XXX: interaction with row storage type needed 
  707.              */
  708.         }
  709.         /*
  710.          * memory reseveration, final preparation... 
  711.          */
  712.         if (StorageTmp == NULL &&
  713.             (set_value == RS_CREATEANDGO
  714.              || set_value == RS_CREATEANDWAIT)) {
  715.             /*
  716.              * creation 
  717.              */
  718.             vars = NULL;
  719.             snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OCTET_STR, NULL, 0);     /* snmpNotifyName */
  720.             if (header_complex_parse_oid
  721.                 (&
  722.                  (name
  723.                   [sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) +
  724.                    2]), newlen, vars) != SNMPERR_SUCCESS) {
  725.                 /*
  726.                  * XXX: free, zero vars 
  727.                  */
  728.                 snmp_free_var(vars);
  729.                 return SNMP_ERR_INCONSISTENTNAME;
  730.             }
  731.             vp = vars;
  732.             StorageNew = SNMP_MALLOC_STRUCT(snmpNotifyTable_data);
  733.             if (StorageNew == NULL) {
  734.                 return SNMP_ERR_RESOURCEUNAVAILABLE;
  735.             }
  736.             StorageNew->snmpNotifyName = calloc( 1, vp->val_len + 1 );
  737.             if (StorageNew->snmpNotifyName == NULL) {
  738.                 return SNMP_ERR_RESOURCEUNAVAILABLE;
  739.             }
  740.             memcpy(StorageNew->snmpNotifyName, vp->val.string, vp->val_len);
  741.             StorageNew->snmpNotifyNameLen = vp->val_len;
  742.             vp = vp->next_variable;
  743.             /*
  744.              * default values 
  745.              */
  746.             StorageNew->snmpNotifyStorageType = ST_NONVOLATILE;
  747.             StorageNew->snmpNotifyType = SNMPNOTIFYTYPE_TRAP;
  748.             StorageNew->snmpNotifyTagLen = 0;
  749.             StorageNew->snmpNotifyTag = (char *) calloc(sizeof(char), 1);
  750.             if (StorageNew->snmpNotifyTag == NULL) {
  751.                 return SNMP_ERR_RESOURCEUNAVAILABLE;
  752.             }
  753.             StorageNew->snmpNotifyRowStatus = set_value;
  754.             snmp_free_var(vars);
  755.         }
  756.         break;
  757.     case RESERVE2:
  758.         break;
  759.     case FREE:
  760.         if (StorageNew != NULL) {
  761.             SNMP_FREE(StorageNew->snmpNotifyTag);
  762.             SNMP_FREE(StorageNew->snmpNotifyName);
  763.             free(StorageNew);
  764.             StorageNew = NULL;
  765.         }
  766.         break;
  767.     case ACTION:
  768.         if (StorageTmp == NULL && (set_value == RS_CREATEANDGO ||
  769.                                    set_value == RS_CREATEANDWAIT)) {
  770.             /*
  771.              * row creation, so add it 
  772.              */
  773.             if (StorageNew != NULL) {
  774.                 snmpNotifyTable_add(StorageNew);
  775.             }
  776.         } else if (set_value != RS_DESTROY) {
  777.             /*
  778.              * set the flag? 
  779.              */
  780.             old_value = StorageTmp->snmpNotifyRowStatus;
  781.             StorageTmp->snmpNotifyRowStatus = *((long *) var_val);
  782.         } else {
  783.             /*
  784.              * destroy...  extract it for now 
  785.              */
  786.             if (StorageTmp) {
  787.                 hciptr = header_complex_find_entry(snmpNotifyTableStorage,
  788.                                                    StorageTmp);
  789.                 StorageDel = (struct snmpNotifyTable_data *)
  790.                     header_complex_extract_entry((struct
  791.                                                   header_complex_index **)
  792.                                                  &snmpNotifyTableStorage,
  793.                                                  hciptr);
  794.             }
  795.         }
  796.         break;
  797.     case UNDO:
  798.         /*
  799.          * Back out any changes made in the ACTION case 
  800.          */
  801.         if (StorageTmp == NULL && (set_value == RS_CREATEANDGO ||
  802.                                    set_value == RS_CREATEANDWAIT)) {
  803.             /*
  804.              * row creation, so remove it again 
  805.              */
  806.             hciptr = header_complex_find_entry(snmpNotifyTableStorage,
  807.                                                StorageNew);
  808.             StorageDel = (struct snmpNotifyTable_data *)
  809.                 header_complex_extract_entry((struct header_complex_index
  810.                                               **) &snmpNotifyTableStorage,
  811.                                              hciptr);
  812.             /*
  813.              * XXX: free it 
  814.              */
  815.         } else if (StorageDel != NULL) {
  816.             /*
  817.              * row deletion, so add it again 
  818.              */
  819.             snmpNotifyTable_add(StorageDel);
  820.         } else if (set_value != RS_DESTROY) {
  821.             StorageTmp->snmpNotifyRowStatus = old_value;
  822.         }
  823.         break;
  824.     case COMMIT:
  825.         if (StorageDel != NULL) {
  826.             SNMP_FREE(StorageDel->snmpNotifyTag);
  827.             SNMP_FREE(StorageDel->snmpNotifyName);
  828.             free(StorageDel);
  829.             StorageDel = NULL;
  830.         }
  831.         if (StorageTmp
  832.             && StorageTmp->snmpNotifyRowStatus == RS_CREATEANDGO) {
  833.             StorageTmp->snmpNotifyRowStatus = RS_ACTIVE;
  834.             StorageNew = NULL;
  835.         } else if (StorageTmp &&
  836.                    StorageTmp->snmpNotifyRowStatus == RS_CREATEANDWAIT) {
  837.             StorageTmp->snmpNotifyRowStatus = RS_NOTINSERVICE;
  838.             StorageNew = NULL;
  839.         }
  840.         break;
  841.     }
  842.     return SNMP_ERR_NOERROR;
  843. }