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

📄 dlmod.c

📁 Snmp(简单网管协议)软件包。
💻 C
字号:
/* *  Dynamic Loadable Agent Modules MIB (UCD-DLMOD-MIB) - dlmod.c * */#include <config.h>#if HAVE_STDLIB_H#include <stdlib.h>#endif#include <stdio.h>#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#if HAVE_UNISTD_H#include <unistd.h>#endif#include <ctype.h>#if HAVE_WINSOCK_H#include <winsock.h>#endif#include "mibincl.h"#include "struct.h"#include "read_config.h"#include "agent_read_config.h"#include "util_funcs.h"#include "snmp_debug.h"#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)#include <dlfcn.h>#include "dlmod.h"static struct dlmod *dlmods = NULL;static int          dlmod_next_index = 1;static char         dlmod_path[1024];static void dlmod_parse_config(const char *, char *);static void dlmod_free_config(void);/* * this variable defines function callbacks and type return * information for the dlmod mib */static struct variable4 dlmod_variables[] = {    {DLMODNEXTINDEX, ASN_INTEGER, RONLY, var_dlmod, 1, {1}},    {DLMODNAME, ASN_OCTET_STR, RWRITE, var_dlmodEntry, 3, {2, 1, 2}},    {DLMODPATH, ASN_OCTET_STR, RWRITE, var_dlmodEntry, 3, {2, 1, 3}},    {DLMODERROR, ASN_OCTET_STR, RONLY, var_dlmodEntry, 3, {2, 1, 4}},    {DLMODSTATUS, ASN_INTEGER, RWRITE, var_dlmodEntry, 3, {2, 1, 5}},};static oid dlmod_variables_oid[] = {1, 3, 6, 1, 4, 1, 2021, 13, 14};static int dlmod_variables_oid_len = 9;void init_dlmod (void) {    char *p;    int l;    REGISTER_MIB("dlmod", dlmod_variables, variable4, dlmod_variables_oid);    /* TODO: REGISTER_SYSOR_ENTRY */        DEBUGMSGTL(("dlmod", "register mib\n"));    snmpd_register_config_handler("dlmod", dlmod_parse_config,				  dlmod_free_config,				  "module-name module-path");    p = getenv("SNMPDLMODPATH");    strncpy(dlmod_path, SNMPDLMODPATH, sizeof(dlmod_path));    if (p) {	if (p[0] == ':') {	    l = strlen(dlmod_path);	    if (dlmod_path[l - 1] != ':') 		strncat(dlmod_path, ":", sizeof(dlmod_path) - l);	    strncat(dlmod_path, p + 1, 		    sizeof(dlmod_path) - strlen(dlmod_path));	} else 	    strncpy(dlmod_path, p, sizeof(dlmod_path));    }    DEBUGMSGTL(("dlmod", "dlmod_path: %s\n", dlmod_path));}void deinit_dlmod (void){    unregister_mib(dlmod_variables_oid, dlmod_variables_oid_len);    snmpd_unregister_config_handler("dlmod");}struct dlmod *dlmod_create_module (void) {    struct dlmod **pdlmod, *dlm;    DEBUGMSGTL(("dlmod", "dlmod_create_module\n"));    dlm = calloc(1, sizeof(struct dlmod));    if (dlm == NULL) 	return NULL;    dlm->index = dlmod_next_index++;    dlm->status = DLMOD_UNLOADED;    for (pdlmod = &dlmods; *pdlmod != NULL; pdlmod = &((*pdlmod)->next)) 	;    (*pdlmod) = dlm;    return dlm;}voiddlmod_delete_module(struct dlmod *dlm){    struct dlmod **pdlmod;     DEBUGMSGTL(("dlmod", "dlmod_delete_module\n"));    if (!dlm || dlm->status != DLMOD_UNLOADED)	return;    for (pdlmod = &dlmods; *pdlmod; pdlmod = &((*pdlmod)->next)) 	if (*pdlmod == dlm) {	    *pdlmod = dlm->next;	    free(dlm);	    return;	}}voiddlmod_load_module(struct dlmod *dlm){    char sym_init[64];    char *p, tmp_path[255];    int (*dl_init)(void);        DEBUGMSGTL(("dlmod", "dlmod_load_module %s: %s\n", dlm->name, dlm->path));      if (!dlm || !dlm->path || !dlm->name ||	(dlm->status != DLMOD_UNLOADED && dlm->status != DLMOD_ERROR))	return;    if (dlm->path[0] == '/') { #ifdef RTLD_NOW	dlm->handle = dlopen(dlm->path, RTLD_NOW);#else	dlm->handle = dlopen(dlm->path, RTLD_LAZY);#endif	if (dlm->handle == NULL) {	    snprintf(dlm->error, sizeof(dlm->error), 		     "dlopen failed: %s", dlerror());	    dlm->status = DLMOD_ERROR;	    return;	}    } else {	for (p = strtok(dlmod_path, ":"); p; p = strtok(NULL, ":")) {	    snprintf(tmp_path, sizeof(tmp_path), "%s/%s.so", p, dlm->path);	    DEBUGMSGTL(("dlmod", "p: %s tmp_path: %s\n", p, tmp_path));#ifdef RTLD_NOW	    dlm->handle = dlopen(tmp_path, RTLD_NOW);#else	    dlm->handle = dlopen(tmp_path, RTLD_LAZY);#endif	    if (dlm->handle == NULL) {		snprintf(dlm->error, sizeof(dlm->error), 			 "dlopen failed: %s", dlerror());		dlm->status = DLMOD_ERROR;	    }	}	strncpy(dlm->path, tmp_path, sizeof(dlm->path));	if (dlm->status == DLMOD_ERROR) 	    return;    }    snprintf(sym_init, sizeof(sym_init), "init_%s", dlm->name);    dl_init = dlsym(dlm->handle, sym_init);    if (dl_init == NULL) {	dlclose(dlm->handle);	snprintf(dlm->error, sizeof(dlm->error), 		 "dlsym failed: can't find \'%s\'", sym_init);	dlm->status = DLMOD_ERROR;	return;    }	    dl_init();    dlm->error[0] = '\0';    dlm->status = DLMOD_LOADED;}void dlmod_unload_module (struct dlmod *dlm){    char sym_deinit[64];    int (* dl_deinit)(void);      if (!dlm || dlm->status != DLMOD_LOADED) 	return;    snprintf(sym_deinit, sizeof(sym_deinit), "deinit_%s", dlm->name);    dl_deinit = dlsym(dlm->handle, sym_deinit);    if (dl_deinit == NULL) {	snprintf(dlm->error, sizeof(dlm->error), 		 "dlsym failed: can't find \'%s\'", sym_deinit);    } else {	dl_deinit();    }    dlclose(dlm->handle);    dlm->status = DLMOD_UNLOADED;    DEBUGMSGTL(("dlmod", "Module %s unloaded\n", dlm->name));}struct dlmod *dlmod_get_by_index (int iindex){    struct dlmod *dlmod;      for (dlmod = dlmods; dlmod; dlmod=dlmod->next) 	if (dlmod->index == iindex)	    return dlmod;    return NULL;}static void dlmod_parse_config(const char *token,		   char *cptr){    char *dlm_name, *dlm_path;    struct dlmod *dlm;      if (cptr == NULL) {	config_perror("Bad dlmod line");	return;    }    /* remove comments */    *(cptr + strcspn(cptr, "#;\r\n")) = '\0';    dlm = dlmod_create_module();    if (!dlm)	return;    /* dynamic module name */    dlm_name = strtok(cptr, "\t ");     if (dlm_name == NULL) {	config_perror("Bad dlmod line");	dlmod_delete_module(dlm);	return;    }    strncpy(dlm->name, dlm_name, sizeof(dlm->name));    /* dynamic module path */    dlm_path = strtok(NULL, "\t ");    if (dlm_path) 	strncpy(dlm->path, dlm_path, sizeof(dlm->path));    else	strncpy(dlm->path, dlm_name, sizeof(dlm->path));    dlmod_load_module(dlm);	    if (dlm->status == DLMOD_ERROR) 	snmp_log(LOG_ERR, "%s\n", dlm->error);}static void dlmod_free_config (void) {    struct dlmod *dtmp, *dtmp2;      for (dtmp = dlmods; dtmp != NULL;) {	dtmp2 = dtmp;	dtmp = dtmp->next;	dlmod_unload_module(dtmp2);	free(dtmp2);    }    dlmods = NULL;}/*  header_dlmod(...  Arguments:  vp	  IN      - pointer to variable entry that points here  name    IN/OUT  - IN/name requested, OUT/name found  length  IN/OUT  - length of IN/OUT oid's   exact   IN      - TRUE if an exact match was requested  var_len OUT     - length of variable or 0 if function returned  write_method*/static intheader_dlmod(struct variable *vp,	     oid *name,	     size_t *length,	     int exact,	     size_t *var_len,	     WriteMethod **write_method){#define DLMOD_NAME_LENGTH 10    oid             newname[MAX_OID_LEN];    int             result;        memcpy((char *)newname, (char *)vp->name, (int) vp->namelen * sizeof(oid));    newname[DLMOD_NAME_LENGTH] = 0;    result = snmp_oid_compare(name, *length, newname, (int)vp->namelen + 1);    if ((exact && (result != 0)) || (!exact && (result >= 0))) {	return MATCH_FAILED;    }	    memcpy((char *)name, (char *)newname,	   ((int)vp->namelen + 1) * sizeof(oid));    *length = vp->namelen + 1;    *write_method = 0;    *var_len = sizeof(long); /* default to 'long' results */    return MATCH_SUCCEEDED;}u_char *var_dlmod(struct variable *vp,	  oid *name,	  size_t *length,	  int exact,	  size_t *var_len,	  WriteMethod **write_method){    /* variables we may use later */    *write_method = 0;       /* assume it isnt writable for the time being */    *var_len = sizeof(int);  /* assume an integer and change later			      * if not */        if (header_dlmod(vp, name, length, exact,		     var_len, write_method) == MATCH_FAILED)	return 0;        /* this is where we do the value assignments for the mib results. */    switch (vp->magic) {    case DLMODNEXTINDEX:        long_return = dlmod_next_index;	return (unsigned char *)&long_return;    default:	DEBUGMSGTL(("dlmod", "unknown sub-id %d in var_dlmod\n", vp->magic));    }    return 0;}/*  header_dlmodEntry(...  Arguments:  vp	  IN      - pointer to variable entry that points here  name    IN/OUT  - IN/name requested, OUT/name found  length  IN/OUT  - length of IN/OUT oid's   exact   IN      - TRUE if an exact match was requested  var_len OUT     - length of variable or 0 if function returned  write_method  */static struct dlmod *header_dlmodEntry(struct variable *vp,		  oid *name,		  size_t *length,		  int exact,		  size_t *var_len,		  WriteMethod **write_method){#define DLMODENTRY_NAME_LENGTH 12    oid	newname[MAX_OID_LEN];    int	result;    struct dlmod   *dlm = 0;    int dlmod_index;        memcpy((char *)newname, (char *)vp->name, (int)vp->namelen * sizeof(oid));    *write_method = 0;    for (dlmod_index = 1; dlmod_index < dlmod_next_index; dlmod_index++)  {	dlm = dlmod_get_by_index(dlmod_index);	DEBUGMSGTL(("dlmod", "dlmodEntry dlm: %x dlmod_index: %d\n",		    (int)dlm, dlmod_index));		if (dlm) {	    newname[12] = dlmod_index;	    result = snmp_oid_compare(name, *length, newname,				      (int)vp->namelen + 1);	    if ((exact && (result == 0)) || (!exact && (result < 0))) 		break;	}    }        if (dlmod_index >= dlmod_next_index) {	if (dlmod_index == dlmod_next_index && 	    exact && vp->magic == DLMODSTATUS)  	    	    *write_method = write_dlmodStatus;	return NULL;    }        memcpy((char *)name, (char *)newname,	   ((int)vp->namelen + 1) * sizeof(oid));    *length = vp->namelen + 1;    *var_len = sizeof(long);    return dlm;}u_char *var_dlmodEntry(struct variable *vp,	       oid *name,	       size_t *length,	       int exact,	       size_t *var_len,	       WriteMethod **write_method){    /* variables we may use later */    struct dlmod   *dlm;    *var_len = sizeof(int);	/* assume an integer and change later				 * if not */    dlm = header_dlmodEntry(vp, name, length, exact, var_len, write_method);    if (dlm == NULL)	return 0;    /* this is where we do the value assignments for the mib results. */    switch (vp->magic) {    case DLMODNAME:	*write_method = write_dlmodName;	*var_len = strlen(dlm->name);	return (unsigned char*) dlm->name;    case DLMODPATH:	*write_method = write_dlmodPath;	*var_len = strlen(dlm->path);	return (unsigned char*) dlm->path;    case DLMODERROR:	*var_len = strlen(dlm->error);	return (unsigned char*) dlm->error;    case DLMODSTATUS:	*write_method = write_dlmodStatus;	long_return = dlm->status;	return (unsigned char *) &long_return;    default:	DEBUGMSGTL(("dlmod", "unknown sub-id %d in var_dlmodEntry\n",		    vp->magic));    }    return 0;}intwrite_dlmodName(int action,		u_char *var_val,		u_char var_val_type,		size_t var_val_len,		u_char *statP,		oid *name,		size_t name_len){    static struct dlmod  *dlm;    if (var_val_type != ASN_OCTET_STR) {	snmp_log(LOG_ERR, "write to dlmodName not ASN_OCTET_STR\n");	return SNMP_ERR_WRONGTYPE;    }    if (var_val_len > sizeof(dlm->name)) {	snmp_log(LOG_ERR, "write to dlmodName: bad length\n");	return SNMP_ERR_WRONGLENGTH;    }    if (action == COMMIT) {	dlm = dlmod_get_by_index(name[12]);	if (!dlm || dlm->status == DLMOD_LOADED) 	    return SNMP_ERR_RESOURCEUNAVAILABLE;	strncpy(dlm->name, (const char*)var_val, var_val_len);	dlm->name[var_val_len] = 0;    }    return SNMP_ERR_NOERROR;}intwrite_dlmodPath(int action,		u_char *var_val,		u_char var_val_type,		size_t var_val_len,		u_char *statP,		oid *name,		size_t name_len){    static struct dlmod  *dlm;        if (var_val_type != ASN_OCTET_STR) {	snmp_log(LOG_ERR, "write to dlmodPath not ASN_OCTET_STR\n");	return SNMP_ERR_WRONGTYPE;    }    if (var_val_len > sizeof(dlm->path)) {	snmp_log(LOG_ERR, "write to dlmodPath: bad length\n");	return SNMP_ERR_WRONGLENGTH;    }    if (action == COMMIT) {	dlm = dlmod_get_by_index(name[12]);	if (!dlm || dlm->status == DLMOD_LOADED) 	    return SNMP_ERR_RESOURCEUNAVAILABLE;	strncpy(dlm->path, (const char*)var_val, var_val_len);	dlm->path[var_val_len] = 0;    }    return SNMP_ERR_NOERROR;}intwrite_dlmodStatus(int action,		  u_char *var_val,		  u_char var_val_type,		  size_t var_val_len,		  u_char *statP,		  oid *name,		  size_t name_len){    /* variables we may use later */    struct dlmod *dlm;    if (var_val_type != ASN_INTEGER) {	snmp_log(LOG_ERR, "write to dlmodStatus not ASN_INTEGER\n");	return SNMP_ERR_WRONGTYPE;    }    if (var_val_len > sizeof(long)) {	snmp_log(LOG_ERR, "write to dlmodStatus: bad length\n");	return SNMP_ERR_WRONGLENGTH;    }    if (action == COMMIT) {	/* object identifier in form .1.3.6.1.4.1.2021.13.14.2.1.4.x 	   where X is index with offset 12 */	dlm = dlmod_get_by_index(name[12]);	switch (*((long *)var_val)) {	case DLMOD_CREATE:	    if (dlm || (name[12] != dlmod_next_index))		return SNMP_ERR_RESOURCEUNAVAILABLE;	    dlm = dlmod_create_module();	    if (!dlm) 		return SNMP_ERR_RESOURCEUNAVAILABLE;	    break;	case DLMOD_LOAD:	    if (!dlm || dlm->status == DLMOD_LOADED) 		return SNMP_ERR_RESOURCEUNAVAILABLE;	    dlmod_load_module(dlm);	    break;		case DLMOD_UNLOAD:	    if (!dlm || dlm->status != DLMOD_LOADED) 		return SNMP_ERR_RESOURCEUNAVAILABLE;	    dlmod_unload_module(dlm);	    break;		case DLMOD_DELETE:	    if (!dlm || dlm->status == DLMOD_LOADED) 		return SNMP_ERR_RESOURCEUNAVAILABLE;	    dlmod_delete_module(dlm);	    break;		default:	    return SNMP_ERR_WRONGVALUE;	}    }    return SNMP_ERR_NOERROR;}#else /* no dlopen support */void init_dlmod (void){    DEBUGMSGTL(("dlmod","Dynamic modules not support on this platform\n"));}#endif

⌨️ 快捷键说明

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