⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 delayed_instance.c

📁 snmp的源代码,已经在我的ubuntu下编译通过
💻 C
字号:
/**  @example delayed_instance.c *  This example implements the netSnmpExampleSleeper object. * *  It demonstrates 2 things: * *  - The instance helper, which is a way of registering an exact OID *    such that GENEXT requests are handled entirely by the helper. * *  - how to implement objects which normally would block the agent as *    it waits for external events in such a way that the agent can *    continue responding to other requests while this implementation *    waits. * *  - Added bonus: normally the nsTransactionTable is empty, since *    there aren't any outstanding requests generally.  When accessed, *    this module will create some however.  Try setting *    netSnmpExampleSleeper.0 to 10 and then accessing it (use *    "snmpget -t 15 ..." to access it), and then walk the *    nsTransactionTable from another shell to see that not only is *    the walk not blocked, but that the nsTransactionTable is not *    empty. * */#include <net-snmp/net-snmp-config.h>#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>#include "delayed_instance.h"static u_long   delay_time = 1;voidinit_delayed_instance(void){    static oid      my_delayed_oid[] =        { 1, 3, 6, 1, 4, 1, 8072, 2, 1, 2, 0 };    /*     * delayed handler test     */    netsnmp_handler_registration *my_test;    my_test =        netsnmp_create_handler_registration("delayed_instance_example",                                            delayed_instance_handler,                                            my_delayed_oid,                                            OID_LENGTH(my_delayed_oid),                                            HANDLER_CAN_RWRITE);    netsnmp_register_instance(my_test);}#define DELAYED_INSTANCE_SET_NAME "test_delayed"intdelayed_instance_handler(netsnmp_mib_handler *handler,                         netsnmp_handler_registration *reginfo,                         netsnmp_agent_request_info *reqinfo,                         netsnmp_request_info *requests){    DEBUGMSGTL(("delayed_instance", "Got request, mode = %d:\n",                reqinfo->mode));    switch (reqinfo->mode) {        /*         * here we merely mention that we'll answer this request         * later.  we don't actually care about the mode type in this         * example, but for certain cases you may, so I'll leave in the         * otherwise useless switch and case statements          */    default:        /*         * mark this variable as something that can't be handled now.         * We'll answer it later.          */        requests->delegated = 1;        /*         * register an alarm to update the results at a later         * time.  Normally, we might have to query something else         * (like an external request sent to a different network         * or system socket, etc), but for this example we'll do         * something really simply and just insert an alarm for a         * certain period of time          */        snmp_alarm_register(delay_time, /* seconds */                            0,  /* dont repeat. */                            return_delayed_response,    /* the function                                                         * to call */                            /*                             * here we create a "cache" of useful                             * information that we'll want later                             * on.  This argument is passed back                             * to us in the callback function for                             * an alarm                              */                            (void *)                            netsnmp_create_delegated_cache(handler,                                                           reginfo,                                                           reqinfo,                                                           requests,                                                           NULL));        break;    }    return SNMP_ERR_NOERROR;}voidreturn_delayed_response(unsigned int clientreg, void *clientarg){    /*     * extract the cache from the passed argument      */    netsnmp_delegated_cache *cache = (netsnmp_delegated_cache *) clientarg;    netsnmp_request_info *requests;    netsnmp_agent_request_info *reqinfo;    u_long         *delay_time_cache = NULL;    /*     * here we double check that the cache we created earlier is still     * * valid.  If not, the request timed out for some reason and we     * * don't need to keep processing things.  Should never happen, but     * * this double checks.      */    cache = netsnmp_handler_check_cache(cache);    if (!cache) {        snmp_log(LOG_ERR, "illegal call to return delayed response\n");        return;    }    /*     * re-establish the previous pointers we are used to having      */    reqinfo = cache->reqinfo;    requests = cache->requests;    DEBUGMSGTL(("delayed_instance",                "continuing delayed request, mode = %d\n",                cache->reqinfo->mode));    /*     * mention that it's no longer delegated, and we've now answered     * the query (which we'll do down below).      */    requests->delegated = 0;    switch (cache->reqinfo->mode) {        /*         * registering as an instance means we don't need to deal with         * getnext processing, so we don't handle it here at all.         *          * However, since the instance handler already reset the mode         * back to GETNEXT from the faked GET mode, we need to do the         * same thing in both cases.  This should be fixed in future         * versions of net-snmp hopefully.          */    case MODE_GET:    case MODE_GETNEXT:        /*         * return the currend delay time          */        snmp_set_var_typed_value(cache->requests->requestvb,                                 ASN_INTEGER,                                 (u_char *) & delay_time,                                 sizeof(delay_time));        break;    case MODE_SET_RESERVE1:        /*         * check type          */        if (requests->requestvb->type != ASN_INTEGER) {            /*             * not an integer.  Bad dog, no bone.              */            netsnmp_set_request_error(reqinfo, requests,                                      SNMP_ERR_WRONGTYPE);            /*             * we don't need the cache any longer              */            netsnmp_free_delegated_cache(cache);            return;        }        break;    case MODE_SET_RESERVE2:        /*         * store old value for UNDO support in the future.          */        memdup((u_char **) & delay_time_cache,               (u_char *) & delay_time, sizeof(delay_time));        /*         * malloc failed          */        if (delay_time_cache == NULL) {            netsnmp_set_request_error(reqinfo, requests,                                      SNMP_ERR_RESOURCEUNAVAILABLE);            netsnmp_free_delegated_cache(cache);            return;        }        /*         * Add our temporary information to the request itself.         * This is then retrivable later.  The free function         * passed auto-frees it when the request is later         * deleted.           */        netsnmp_request_add_list_data(requests,                                      netsnmp_create_data_list                                      (DELAYED_INSTANCE_SET_NAME,                                       delay_time_cache, free));        break;    case MODE_SET_ACTION:        /*         * update current value          */        delay_time = *(requests->requestvb->val.integer);        DEBUGMSGTL(("testhandler", "updated delay_time -> %d\n",                    delay_time));        break;    case MODE_SET_UNDO:        /*         * ack, something somewhere failed.  We reset back to the         * previously old value by extracting the previosuly         * stored information back out of the request          */        delay_time =            *((u_long *) netsnmp_request_get_list_data(requests,                                                       DELAYED_INSTANCE_SET_NAME));        break;    case MODE_SET_COMMIT:    case MODE_SET_FREE:        /*         * the only thing to do here is free the old memdup'ed         * value, but it's auto-freed by the datalist recovery, so         * we don't have anything to actually do here          */        break;    }    /*     * free the information cache      */    netsnmp_free_delegated_cache(cache);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -