extend.c

来自「snmp的源代码,已经在我的ubuntu下编译通过」· C语言 代码 · 共 1,364 行 · 第 1/4 页

C
1,364
字号
#include <net-snmp/net-snmp-config.h>#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>#include <net-snmp/agent/watcher.h>#include "agent/extend.h"#include "utilities/execute.h"#include "struct.h"#ifndef USING_UCD_SNMP_EXTENSIBLE_MODULE#include "util_funcs.h"#include "mibdefs.h"#define SHELLCOMMAND 3#endifoid  ns_extend_oid[]    = { 1, 3, 6, 1, 4, 1, 8072, 1, 3, 2 };oid  extend_count_oid[] = { 1, 3, 6, 1, 4, 1, 8072, 1, 3, 2, 1 };oid  extend_config_oid[] = { 1, 3, 6, 1, 4, 1, 8072, 1, 3, 2, 2 };oid  extend_out1_oid[]  = { 1, 3, 6, 1, 4, 1, 8072, 1, 3, 2, 3 };oid  extend_out2_oid[]  = { 1, 3, 6, 1, 4, 1, 8072, 1, 3, 2, 4 };typedef struct extend_registration_block_s {    netsnmp_table_data *dinfo;    oid                *root_oid;    size_t              oid_len;    int                 num_entries;    netsnmp_extend     *ehead;    struct extend_registration_block_s *next;} extend_registration_block;extend_registration_block *ereg_head = NULL;#ifndef USING_UCD_SNMP_EXTENSIBLE_MODULEtypedef struct netsnmp_old_extend_s {    int idx;    netsnmp_extend *exec_entry;    netsnmp_extend *efix_entry;} netsnmp_old_extend;int             num_compatability_entries = 0;int             max_compatability_entries = 50;netsnmp_old_extend *compatability_entries;WriteMethod fixExec2Error;FindVarMethod var_extensible_old;oid  old_extensible_variables_oid[] = { UCDAVIS_MIB, SHELLMIBNUM, 1 };struct variable2 old_extensible_variables[] = {    {MIBINDEX,     ASN_INTEGER,   RONLY, var_extensible_old, 1, {MIBINDEX}},    {ERRORNAME,    ASN_OCTET_STR, RONLY, var_extensible_old, 1, {ERRORNAME}},    {SHELLCOMMAND, ASN_OCTET_STR, RONLY, var_extensible_old, 1, {SHELLCOMMAND}},    {ERRORFLAG,    ASN_INTEGER,   RONLY, var_extensible_old, 1, {ERRORFLAG}},    {ERRORMSG,     ASN_OCTET_STR, RONLY, var_extensible_old, 1, {ERRORMSG}},    {ERRORFIX,     ASN_INTEGER,  RWRITE, var_extensible_old, 1, {ERRORFIX}},    {ERRORFIXCMD,  ASN_OCTET_STR, RONLY, var_extensible_old, 1, {ERRORFIXCMD}}};#endif        /*************************         *         *  Main initialisation routine         *         *************************/extend_registration_block *_find_extension_block( oid *name, size_t name_len ){    extend_registration_block         *eptr;    size_t len;    for ( eptr=ereg_head; eptr; eptr=eptr->next ) {        len = SNMP_MIN(name_len, eptr->oid_len);        if (!snmp_oid_compare( name, len, eptr->root_oid, eptr->oid_len))            return eptr;    }    return NULL;}extend_registration_block *_register_extend( oid *base, size_t len ){    extend_registration_block         *eptr;    oid oid_buf[MAX_OID_LEN];    netsnmp_table_data                *dinfo;    netsnmp_table_registration_info   *tinfo;    netsnmp_watcher_info              *winfo;    netsnmp_handler_registration      *reg;    for ( eptr=ereg_head; eptr; eptr=eptr->next ) {        if (!snmp_oid_compare( base, len, eptr->root_oid, eptr->oid_len))            return eptr;    }    if (!eptr) {        eptr = SNMP_MALLOC_TYPEDEF( extend_registration_block );        eptr->root_oid = snmp_duplicate_objid( base, len );        eptr->oid_len  = len;        eptr->num_entries = 0;        eptr->ehead       = NULL;        eptr->dinfo       = netsnmp_create_table_data( "nsExtendTable" );        eptr->next        = ereg_head;        ereg_head         = eptr;    }    dinfo = eptr->dinfo;    memcpy( oid_buf, base, len*sizeof(oid) );        /*         * Register the configuration table         */    tinfo = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );    netsnmp_table_helper_add_indexes( tinfo, ASN_OCTET_STR, 0 );    tinfo->min_column = COLUMN_EXTCFG_FIRST_COLUMN;    tinfo->max_column = COLUMN_EXTCFG_LAST_COLUMN;    oid_buf[len] = 2;    reg   = netsnmp_create_handler_registration(                "nsExtendConfigTable", handle_nsExtendConfigTable,                 oid_buf, len+1, HANDLER_CAN_RWRITE);    netsnmp_register_table_data( reg, dinfo, tinfo );        /*         * Register the main output table         *   using the same table_data handle.         * This is sufficient to link the two tables,         *   and implement the AUGMENTS behaviour         */    tinfo = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );    netsnmp_table_helper_add_indexes( tinfo, ASN_OCTET_STR, 0 );    tinfo->min_column = COLUMN_EXTOUT1_FIRST_COLUMN;    tinfo->max_column = COLUMN_EXTOUT1_LAST_COLUMN;    oid_buf[len] = 3;    reg   = netsnmp_create_handler_registration(                "nsExtendOut1Table", handle_nsExtendOutput1Table,                 oid_buf, len+1, HANDLER_CAN_RONLY);    netsnmp_register_table_data( reg, dinfo, tinfo );        /*         * Register the multi-line output table         *   using a simple table helper.         * This handles extracting the indexes from         *   the request OID, but leaves most of         *   the work to our handler routine.         * Still, it was nice while it lasted...         */    tinfo = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );    netsnmp_table_helper_add_indexes( tinfo, ASN_OCTET_STR, ASN_INTEGER, 0 );    tinfo->min_column = COLUMN_EXTOUT2_FIRST_COLUMN;    tinfo->max_column = COLUMN_EXTOUT2_LAST_COLUMN;    oid_buf[len] = 4;    reg   = netsnmp_create_handler_registration(                "nsExtendOut2Table", handle_nsExtendOutput2Table,                 oid_buf, len+1, HANDLER_CAN_RONLY);    netsnmp_register_table( reg, tinfo );        /*         * Register a watched scalar to keep track of the number of entries         */    oid_buf[len] = 1;    reg   = netsnmp_create_handler_registration(                "nsExtendNumEntries", NULL,                 oid_buf, len+1, HANDLER_CAN_RONLY);    winfo = netsnmp_create_watcher_info(                &(eptr->num_entries), sizeof(eptr->num_entries),                ASN_INTEGER, WATCHER_FIXED_SIZE);    netsnmp_register_watched_scalar( reg, winfo );    return eptr;}void init_extend( void ){    snmpd_register_config_handler("extend",    extend_parse_config, NULL, NULL);    snmpd_register_config_handler("extend-sh", extend_parse_config, NULL, NULL);    snmpd_register_config_handler("extendfix", extend_parse_config, NULL, NULL);    snmpd_register_config_handler("exec2", extend_parse_config, NULL, NULL);    snmpd_register_config_handler("sh2",   extend_parse_config, NULL, NULL);    snmpd_register_config_handler("execFix2", extend_parse_config, NULL, NULL);    (void)_register_extend( ns_extend_oid, OID_LENGTH(ns_extend_oid));#ifndef USING_UCD_SNMP_EXTENSIBLE_MODULE    snmpd_register_config_handler("exec", extend_parse_config, NULL, NULL);    snmpd_register_config_handler("sh",   extend_parse_config, NULL, NULL);    snmpd_register_config_handler("execFix", extend_parse_config, NULL, NULL);    compatability_entries = calloc( max_compatability_entries,                                    sizeof(netsnmp_old_extend));    REGISTER_MIB("ucd-extensible", old_extensible_variables,                 variable2, old_extensible_variables_oid);#endif}        /*************************         *         *  Cached-data hooks         *  see 'cache_handler' helper         *         *************************/intextend_load_cache(netsnmp_cache *cache, void *magic){    int  out_len = 1024*100;    char out_buf[ 1024*100 ];    int  cmd_len = 255*2 + 2;	/* 2 * DisplayStrings */    char cmd_buf[ 255*2 + 2 ];    int  ret;    char *cp;    char *line_buf[ 1024 ];    netsnmp_extend *extension = (netsnmp_extend *)magic;    if (!magic)        return -1;    DEBUGMSGTL(( "nsExtendTable:cache", "load %s", extension->token ));    if ( extension->args )        snprintf( cmd_buf, cmd_len, "%s %s", extension->command, extension->args );    else         snprintf( cmd_buf, cmd_len, "%s", extension->command );    if ( extension->flags & NS_EXTEND_FLAGS_SHELL )        ret = run_shell_command( cmd_buf, extension->input, out_buf, &out_len);    else        ret = run_exec_command(  cmd_buf, extension->input, out_buf, &out_len);    DEBUGMSG(( "nsExtendTable:cache", ": %s : %d\n", cmd_buf, ret));    if (ret >= 0) {        if (out_buf[   out_len-1 ] == '\n')            out_buf[ --out_len   ] =  '\0';	/* Stomp on trailing newline */        extension->output   = strdup( out_buf );        extension->out_len  = out_len;        /*         * Now we need to pick the output apart into separate lines.         * Start by counting how many lines we've got, and keeping         * track of where each line starts in a static buffer         */        extension->numlines = 1;        line_buf[ 0 ] = extension->output;        for (cp=extension->output; *cp; cp++) {            if (*cp == '\n') {                line_buf[ extension->numlines++ ] = cp+1;            }        }        if ( extension->numlines > 1 ) {            extension->lines = calloc( sizeof(char *), extension->numlines );            memcpy( extension->lines, line_buf,                                       sizeof(char *) * extension->numlines );        }    }    extension->result = ret;    return ret;}voidextend_free_cache(netsnmp_cache *cache, void *magic){    netsnmp_extend *extension = (netsnmp_extend *)magic;    if (!magic)        return;    DEBUGMSGTL(( "nsExtendTable:cache", "free %s\n", extension->token ));    if (extension->output) {        SNMP_FREE(extension->output);        extension->output = NULL;    }    if (extension->lines) {        SNMP_FREE(extension->lines);        extension->lines  = NULL;    }    extension->out_len  = 0;    extension->numlines = 0;}        /*************************         *         *  Utility routines for setting up a new entry         *  (either via SET requests, or the config file)         *         *************************/void_free_extension( netsnmp_extend *extension, extend_registration_block *ereg ){    netsnmp_extend *eptr  = NULL;    netsnmp_extend *eprev = NULL;    if (!extension)        return;    if (ereg) {        /* Unlink from 'ehead' list */        for (eptr=ereg->ehead; eptr; eptr=eptr->next) {            if (eptr == extension)                break;            eprev = eptr;        }        if (eprev)            eprev->next = eptr->next;        else            ereg->ehead = eptr->next;    }    netsnmp_table_data_remove_and_delete_row( ereg->dinfo, extension->row);    SNMP_FREE( extension->token );    SNMP_FREE( extension->cache );    SNMP_FREE( extension->command );    SNMP_FREE( extension->args  );    SNMP_FREE( extension->input );    SNMP_FREE( extension );    return;}netsnmp_extend *_new_extension( char *exec_name, int exec_flags, extend_registration_block *ereg ){    netsnmp_extend     *extension;    netsnmp_table_row  *row;    netsnmp_extend     *eptr1, *eptr2;     netsnmp_table_data *dinfo = ereg->dinfo;    if (!exec_name)        return NULL;    extension = SNMP_MALLOC_TYPEDEF( netsnmp_extend );    if (!extension)        return NULL;    extension->token    = strdup( exec_name );    extension->flags    = exec_flags;    extension->cache    = netsnmp_cache_create( 0, extend_load_cache,                                                   extend_free_cache, NULL, 0 );    if (extension->cache)        extension->cache->magic = extension;    row = netsnmp_create_table_data_row();    if (!row || !extension->cache) {        _free_extension( extension, ereg );        SNMP_FREE( row );        return NULL;    }    row->data = (void *)extension;    extension->row = row;    netsnmp_table_row_add_index( row, ASN_OCTET_STR,                                 exec_name, strlen(exec_name));    netsnmp_table_data_add_row( dinfo, row);    ereg->num_entries++;

⌨️ 快捷键说明

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