📄 extend.c
字号:
#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 <net-snmp/agent/agent_callbacks.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; long num_entries; netsnmp_extend *ehead; netsnmp_handler_registration *reg[3]; 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[] = { NETSNMP_UCDAVIS_MIB, NETSNMP_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 ); eptr->reg[0] = reg; /* * 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 ); eptr->reg[1] = reg; /* * 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 ); eptr->reg[2] = reg; /* * 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;}intextend_clear_callback(int majorID, int minorID, void *serverarg, void *clientarg){ extend_registration_block *eptr, *enext = NULL; for ( eptr=ereg_head; eptr; eptr=enext ) { enext=eptr->next; netsnmp_unregister_handler( eptr->reg[0] ); netsnmp_unregister_handler( eptr->reg[1] ); netsnmp_unregister_handler( eptr->reg[2] ); SNMP_FREE(eptr); } ereg_head = NULL; return 0;}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 snmp_register_callback(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_PRE_UPDATE_CONFIG, extend_clear_callback, NULL);} /************************* * * 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 ); } else { extension->lines = &extension->output; } } 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->numlines > 1 ) { 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 (!eptr) { snmp_log(LOG_ERR, "extend: fell off end of list before finding extension\n"); return; } 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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -