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

SNMP编程

开发平台:

Unix_Linux

  1. #include <net-snmp/net-snmp-config.h>
  2. #include <net-snmp/net-snmp-includes.h>
  3. #include <net-snmp/agent/net-snmp-agent-includes.h>
  4. #include <net-snmp/agent/scalar.h>
  5. #ifdef HAVE_STRING_H
  6. #include <string.h>
  7. #else
  8. #include <strings.h>
  9. #endif
  10. #include <net-snmp/library/snmp_logging.h>
  11. #include "agent/nsLogging.h"
  12. #include "util_funcs.h"
  13. /*
  14.  * OID and columns for the logging table.
  15.  */
  16. #define  NSLOGGING_TYPE 3
  17. #define  NSLOGGING_MAXLEVEL 4
  18. #define  NSLOGGING_STATUS 5
  19. oid nsLoggingTable_oid[]      = { 1, 3, 6, 1, 4, 1, 8072, 1, 7, 2, 1};
  20. void
  21. init_nsLogging(void)
  22. {
  23.     netsnmp_table_registration_info *table_info;
  24.     netsnmp_iterator_info           *iinfo;
  25.     /*
  26.      * Register the table.
  27.      * We need to define the column structure and indexing....
  28.      */
  29.     table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
  30.     if (!table_info) {
  31.         return;
  32.     }
  33.     netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER,
  34.                                                  ASN_PRIV_IMPLIED_OCTET_STR, 0);
  35.     table_info->min_column = NSLOGGING_TYPE;
  36.     table_info->max_column = NSLOGGING_STATUS;
  37.     /*
  38.      * .... and the iteration information ....
  39.      */
  40.     iinfo      = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
  41.     if (!iinfo) {
  42.         return;
  43.     }
  44.     iinfo->get_first_data_point = get_first_logging_entry;
  45.     iinfo->get_next_data_point  = get_next_logging_entry;
  46.     iinfo->table_reginfo        = table_info;
  47.     /*
  48.      * .... and register the table with the agent.
  49.      */
  50.     netsnmp_register_table_iterator(
  51.         netsnmp_create_handler_registration(
  52.             "tzLoggingTable", handle_nsLoggingTable,
  53.             nsLoggingTable_oid, OID_LENGTH(nsLoggingTable_oid),
  54.             HANDLER_CAN_RWRITE),
  55.         iinfo);
  56. }
  57. /*
  58.  * nsLoggingTable handling
  59.  */
  60. netsnmp_variable_list *
  61. get_first_logging_entry(void **loop_context, void **data_context,
  62.                       netsnmp_variable_list *index,
  63.                       netsnmp_iterator_info *data)
  64. {
  65.     long temp;
  66.     netsnmp_log_handler  *logh_head = get_logh_head();
  67.     if ( !logh_head )
  68.         return NULL;
  69.     temp = logh_head->priority;
  70.     snmp_set_var_value(index, (u_char*)&temp,
  71.                  sizeof(temp));
  72.     if ( logh_head->token )
  73.         snmp_set_var_value(index->next_variable, (const u_char*)logh_head->token,
  74.                                    strlen(logh_head->token));
  75.     else
  76.         snmp_set_var_value(index->next_variable, NULL, 0);
  77.     *loop_context = (void*)logh_head;
  78.     *data_context = (void*)logh_head;
  79.     return index;
  80. }
  81. netsnmp_variable_list *
  82. get_next_logging_entry(void **loop_context, void **data_context,
  83.                       netsnmp_variable_list *index,
  84.                       netsnmp_iterator_info *data)
  85. {
  86.     long temp;
  87.     netsnmp_log_handler *logh = (netsnmp_log_handler *)*loop_context;
  88.     logh = logh->next;
  89.     if ( !logh )
  90.         return NULL;
  91.     temp = logh->priority;
  92.     snmp_set_var_value(index, (u_char*)&temp,
  93.                  sizeof(temp));
  94.     if ( logh->token )
  95.         snmp_set_var_value(index->next_variable, (const u_char*)logh->token,
  96.                                    strlen(logh->token));
  97.     else
  98.         snmp_set_var_value(index->next_variable, NULL, 0);
  99.     *loop_context = (void*)logh;
  100.     *data_context = (void*)logh;
  101.     return index;
  102. }
  103. int
  104. handle_nsLoggingTable(netsnmp_mib_handler *handler,
  105.                 netsnmp_handler_registration *reginfo,
  106.                 netsnmp_agent_request_info *reqinfo,
  107.                 netsnmp_request_info *requests)
  108. {
  109.     long temp;
  110.     netsnmp_request_info       *request     = NULL;
  111.     netsnmp_table_request_info *table_info  = NULL;
  112.     netsnmp_log_handler        *logh        = NULL;
  113.     netsnmp_variable_list      *idx         = NULL;
  114.     switch (reqinfo->mode) {
  115.     case MODE_GET:
  116.         for (request=requests; request; request=request->next) {
  117.             if (requests->processed != 0)
  118.                 continue;
  119.             logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
  120.             table_info  =                netsnmp_extract_table_info(request);
  121.             switch (table_info->colnum) {
  122.             case NSLOGGING_TYPE:
  123.                 if (!logh) {
  124.                     netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
  125.                     continue;
  126. }
  127. temp = logh->type;
  128.         snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
  129.                                          (u_char*)&temp,
  130.                                             sizeof(temp));
  131.         break;
  132.             case NSLOGGING_MAXLEVEL:
  133.                 if (!logh) {
  134.                     netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
  135.                     continue;
  136. }
  137. temp = logh->pri_max;
  138.         snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
  139.                                          (u_char*)&temp,
  140.                                             sizeof(temp));
  141.         break;
  142.             case NSLOGGING_STATUS:
  143.                 if (!logh) {
  144.                     netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
  145.                     continue;
  146. }
  147. temp = (logh->type ?
  148.                    (logh->enabled ?
  149.                       RS_ACTIVE:
  150.                       RS_NOTINSERVICE) :
  151.                     RS_NOTREADY);
  152.         snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
  153.                                          (u_char*)&temp, sizeof(temp));
  154.         break;
  155.             default:
  156.                 netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  157.                 continue;
  158.     }
  159. }
  160. break;
  161.     case MODE_SET_RESERVE1:
  162.         for (request=requests; request; request=request->next) {
  163.             if ( request->status != 0 ) {
  164.                 return SNMP_ERR_NOERROR; /* Already got an error */
  165.             }
  166.             logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
  167.             table_info  =                 netsnmp_extract_table_info(request);
  168.             switch (table_info->colnum) {
  169.             case NSLOGGING_TYPE:
  170.                 if ( request->requestvb->type != ASN_INTEGER ) {
  171.                     netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
  172.                     return SNMP_ERR_WRONGTYPE;
  173.                 }
  174.                 if (*request->requestvb->val.integer < 0 ) {
  175.                     netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
  176.                     return SNMP_ERR_WRONGVALUE;
  177.                 }
  178. /*
  179.  * It's OK to create a new logging entry
  180.  *  (either in one go, or built up using createAndWait)
  181.  *  but it's not possible to change the type of an entry
  182.  *  once it's been created.
  183.  */
  184.                 if (logh && logh->type) {
  185.                     netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOTWRITABLE);
  186.                     return SNMP_ERR_NOTWRITABLE;
  187. }
  188.         break;
  189.             case NSLOGGING_MAXLEVEL:
  190.                 if ( request->requestvb->type != ASN_INTEGER ) {
  191.                     netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
  192.                     return SNMP_ERR_WRONGTYPE;
  193.                 }
  194.                 if (*request->requestvb->val.integer < 0 ||
  195.                     *request->requestvb->val.integer > 7 ) {
  196.                     netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
  197.                     return SNMP_ERR_WRONGVALUE;
  198.                 }
  199.         break;
  200.             case NSLOGGING_STATUS:
  201.                 if ( request->requestvb->type != ASN_INTEGER ) {
  202.                     netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
  203.                     return SNMP_ERR_WRONGTYPE;
  204.                 }
  205. switch ( *request->requestvb->val.integer ) {
  206.                 case RS_ACTIVE:
  207.                 case RS_NOTINSERVICE:
  208.                     /*
  209.      * Can only work on existing rows
  210.      */
  211.                     if (!logh) {
  212.                         netsnmp_set_request_error(reqinfo, request,
  213.                                                   SNMP_ERR_INCONSISTENTVALUE);
  214.                         return SNMP_ERR_INCONSISTENTVALUE;
  215.                     }
  216.             break;
  217.                 case RS_CREATEANDWAIT:
  218.                 case RS_CREATEANDGO:
  219.                     /*
  220.      * Can only work with new rows
  221.      */
  222.                     if (logh) {
  223.                         netsnmp_set_request_error(reqinfo, request,
  224.                                                   SNMP_ERR_INCONSISTENTVALUE);
  225.                         return SNMP_ERR_INCONSISTENTVALUE;
  226.                     }
  227.                     /*
  228.                      *  Normally, we'd create the row at a later stage
  229.                      *   (probably during the RESERVE2 or ACTION passes)
  230.                      *
  231.                      *  But we need to check that the values are
  232.                      *   consistent during the ACTION pass (which is the
  233.                      *   latest that an error can be safely handled),
  234.                      *   so the values all need to be set up before this
  235.                      *      (i.e. during the RESERVE2 pass)
  236.                      *  So the new row needs to be created before that
  237.                      *   in order to have somewhere to put them.
  238.                      *
  239.                      *  That's why we're doing this here.
  240.                      */
  241.                     idx = table_info->indexes;
  242.             logh = netsnmp_register_loghandler(
  243.     /* not really, but we need a valid type */
  244.     NETSNMP_LOGHANDLER_STDOUT,
  245.     *idx->val.integer);
  246.                     if (!logh) {
  247.                         netsnmp_set_request_error(reqinfo, request,
  248.                                                   SNMP_ERR_GENERR); /* ??? */
  249.                         return SNMP_ERR_GENERR;
  250.                     }
  251.                     idx = idx->next_variable;
  252.             logh->type  = 0;
  253.             logh->token = strdup(idx->val.string);
  254.                     netsnmp_insert_iterator_context(request, (void*)logh);
  255.             break;
  256.                 case RS_DESTROY:
  257.                     /*
  258.      * Can work with new or existing rows
  259.      */
  260.                     break;
  261.                 case RS_NOTREADY:
  262. default:
  263.                     netsnmp_set_request_error(reqinfo, request,
  264.                                               SNMP_ERR_WRONGVALUE);
  265.                     return SNMP_ERR_WRONGVALUE;
  266.                 }
  267.                 break;
  268.             default:
  269.                 netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  270.                 return SNMP_NOSUCHOBJECT;
  271.                 continue;
  272.     }
  273. }
  274. break;
  275.     case MODE_SET_RESERVE2:
  276.         for (request=requests; request; request=request->next) {
  277.             if ( request->status != 0 ) {
  278.                 return SNMP_ERR_NOERROR; /* Already got an error */
  279.             }
  280.             logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
  281.             table_info  =                 netsnmp_extract_table_info(request);
  282.             switch (table_info->colnum) {
  283.             case NSLOGGING_TYPE:
  284.                 /*
  285.  * If we're creating a row using createAndGo,
  286.  * we need to set the type early, so that we
  287.  * can validate it in the ACTION pass.
  288.  *
  289.  * Remember that we need to be able to reverse this
  290.  */
  291.                 if ( logh )
  292.                     logh->type = *request->requestvb->val.integer;
  293.         break;
  294.             /*
  295.      * Don't need to handle nsLogToken or nsLogStatus in this pass
  296.      */
  297.     }
  298. }
  299. break;
  300.     case MODE_SET_ACTION:
  301.         for (request=requests; request; request=request->next) {
  302.             if (requests->processed != 0)
  303.                 continue;
  304.             if ( request->status != 0 ) {
  305.                 return SNMP_ERR_NOERROR; /* Already got an error */
  306.             }
  307.             logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
  308.             table_info  =                 netsnmp_extract_table_info(request);
  309.             switch (table_info->colnum) {
  310.             case NSLOGGING_STATUS:
  311.                 /*
  312.  * This is where we can check the internal consistency
  313.  * of the request.  Basically, for a row to be marked
  314.  * 'active', then there needs to be a valid type value.
  315.  */
  316. switch ( *request->requestvb->val.integer ) {
  317.                 case RS_ACTIVE:
  318.                 case RS_CREATEANDGO:
  319.                     if ( !logh->type ) {
  320.                         netsnmp_set_request_error(reqinfo, request,
  321.                                                   SNMP_ERR_INCONSISTENTVALUE);
  322.                         return SNMP_ERR_INCONSISTENTVALUE;
  323.     }
  324.             break;
  325. }
  326.         break;
  327.             /*
  328.      * Don't need to handle nsLogToken or nsLogType in this pass
  329.      */
  330.     }
  331. }
  332. break;
  333.     case MODE_SET_FREE:
  334.     case MODE_SET_UNDO:
  335.         /*
  336.          * If any resources were allocated in either of the
  337.          *  two RESERVE passes, they need to be released here,
  338.          *  and any assignments (in RESERVE2) reversed.
  339.          *
  340.          * Nothing additional will have been done during ACTION
  341.          *  so this same code can do for UNDO as well.
  342.          */
  343.         for (request=requests; request; request=request->next) {
  344.             if (requests->processed != 0)
  345.                 continue;
  346.             logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
  347.             table_info  =                 netsnmp_extract_table_info(request);
  348.             switch (table_info->colnum) {
  349.             case NSLOGGING_TYPE:
  350.                 /*
  351.  * If we've been setting the type, and the request
  352.  * has failed, then revert to an unset type.
  353.  *
  354.  * We need to be careful here - if the reason it failed is
  355.  *  that the type was already set, then we shouldn't "undo"
  356.  *  the assignment (since it won't actually have been made).
  357.  *
  358.  * Check the current value against the 'new' one.  If they're
  359.  * the same, then this is probably a successful assignment,
  360.  * and the failure was elsewhere, so we need to undo it.
  361.  *  (Or else there was an attempt to write the same value!)
  362.  */
  363.                 if ( logh && logh->type == *request->requestvb->val.integer )
  364.                     logh->type = 0;
  365.         break;
  366.             case NSLOGGING_STATUS:
  367.                 temp = *request->requestvb->val.integer;
  368.                 if ( logh && ( temp == RS_CREATEANDGO ||
  369.                                temp == RS_CREATEANDWAIT)) {
  370.     netsnmp_remove_loghandler( logh );
  371. }
  372.         break;
  373.             /*
  374.      * Don't need to handle nsLogToken in this pass
  375.      */
  376.     }
  377. }
  378. break;
  379.     case MODE_SET_COMMIT:
  380.         for (request=requests; request; request=request->next) {
  381.             if (requests->processed != 0)
  382.                 continue;
  383.             if ( request->status != 0 ) {
  384.                 return SNMP_ERR_NOERROR; /* Already got an error */
  385.             }
  386.             logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
  387.             if (!logh) {
  388.                 netsnmp_set_request_error(reqinfo, request, SNMP_ERR_COMMITFAILED);
  389.                 return SNMP_ERR_COMMITFAILED; /* Shouldn't happen! */
  390.             }
  391.             table_info  =                 netsnmp_extract_table_info(request);
  392.             switch (table_info->colnum) {
  393.             case NSLOGGING_MAXLEVEL:
  394.                 logh->pri_max = *request->requestvb->val.integer;
  395.         break;
  396.             case NSLOGGING_STATUS:
  397.                 switch (*request->requestvb->val.integer) {
  398.                     case RS_ACTIVE:
  399.                     case RS_CREATEANDGO:
  400.                         logh->enabled = 1;
  401.                         break;
  402.                     case RS_NOTINSERVICE:
  403.                     case RS_CREATEANDWAIT:
  404.                         logh->enabled = 0;
  405.                         break;
  406.     case RS_DESTROY:
  407.         netsnmp_remove_loghandler( logh );
  408.                         break;
  409. }
  410.         break;
  411.     }
  412. }
  413. break;
  414.     }
  415.     return SNMP_ERR_NOERROR;
  416. }