On 12/29/12 10:23, Nuno Magalhães wrote:
I installed the version 5.6.1.1 (Windows Extension mode) of the windows
Net-SNMP on my Windows Server 2007 machine.
I'm facing an issue and here are the steps described:
1) I generated a couple of source files from the MIB (with the tool
mib2c) with no problems.
2) The configuration was scalar, so I implemented responses of raw values.
3) The problem: whenever I launch the snmpd with the necessary arguments:
snmpd.exe -V -f -Lo
-I-udp,udpTable,tcp,tcpTable,icmp,ip,interfaces,system_mib,sysORTable
-DnstAgentPluginObject,dlmod,winExtDLL
It tells me at some point in the log that the generated DLL (extension)
could not be parsed in snmpd.conf:
"C:/Program Files/Net-SNMP 5.6.1.1/etc/snmp/snmpd.conf: line 19:
Warning: Unknown token: dlmod."
The configuration file is specifying the Dlmod like the following:
dlmod obu_agent.dll "C:\Program Files\Net-SNMP 5.6.1.1"
I think I'm stuck on this... the DLL is not being loaded/started but I
can see the requests coming whenever I call a specific OID with the
snmpget command.
Does the attached patch help (compile-tested only) ?
Bart.
diff --git a/agent/mibgroup/ucd-snmp/dlmod.c b/agent/mibgroup/ucd-snmp/dlmod.c
index 32f29a4..5b90bcb 100644
--- a/agent/mibgroup/ucd-snmp/dlmod.c
+++ b/agent/mibgroup/ucd-snmp/dlmod.c
@@ -4,6 +4,7 @@
*/
#include <net-snmp/net-snmp-config.h>
+#include <ctype.h>
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -24,10 +25,14 @@
#include "struct.h"
#include "util_funcs.h"
+#if defined(WIN32)
+#include <windows.h>
+#else
#include <dlfcn.h>
+#endif
#include "dlmod.h"
-static struct dlmod *dlmods = NULL;
+static struct dlmod *dlmods;
static unsigned int dlmod_next_index = 1;
static char dlmod_path[1024];
@@ -73,10 +78,10 @@ init_dlmod(void)
const char * const p = getenv("SNMPDLMODPATH");
strlcpy(dlmod_path, SNMPDLMODPATH, sizeof(dlmod_path));
if (p) {
- if (p[0] == ':') {
+ if (p[0] == ENV_SEPARATOR_CHAR) {
int len = strlen(dlmod_path);
- if (len >= 1 && dlmod_path[len - 1] != ':')
- strlcat(dlmod_path, ":", sizeof(dlmod_path));
+ if (len >= 1 && dlmod_path[len - 1] != ENV_SEPARATOR_CHAR)
+ strlcat(dlmod_path, ENV_SEPARATOR, sizeof(dlmod_path));
strlcat(dlmod_path, p + 1, sizeof(dlmod_path));
} else
strlcpy(dlmod_path, p, sizeof(dlmod_path));
@@ -99,15 +104,16 @@ dlmod_create_module(void)
struct dlmod **pdlmod, *dlm;
DEBUGMSGTL(("dlmod", "dlmod_create_module\n"));
- dlm = (struct dlmod *) calloc(1, sizeof(struct dlmod));
+ dlm = calloc(1, sizeof(struct dlmod));
if (dlm == NULL)
return NULL;
- dlm->index = (int)dlmod_next_index++;
+ dlm->index = dlmod_next_index++;
dlm->status = DLMOD_UNLOADED;
- for (pdlmod = &dlmods; *pdlmod != NULL; pdlmod = &((*pdlmod)->next));
- (*pdlmod) = dlm;
+ for (pdlmod = &dlmods; *pdlmod != NULL; pdlmod = &((*pdlmod)->next))
+ ;
+ *pdlmod = dlm;
return dlm;
}
@@ -129,6 +135,83 @@ dlmod_delete_module(struct dlmod *dlm)
}
}
+#if defined(WIN32)
+/* MSVC or MinGW but not Cygwin or native Unix */
+static const char netsnmp_dl_suffix[] = "dll";
+#else
+static const char netsnmp_dl_suffix[] = "so";
+#endif
+
+static void* netsnmp_dlopen(const char *path)
+{
+#if defined(WIN32)
+ return LoadLibrary(path);
+#elif defined(RTLD_NOW)
+ return dlopen(path, RTLD_NOW);
+#else
+ return dlopen(path, RTLD_LAZY);
+#endif
+}
+
+static void netsnmp_dlclose(void *handle)
+{
+#if defined(WIN32)
+ FreeLibrary(handle);
+#else
+ dlclose(handle);
+#endif
+}
+
+static void *netsnmp_dlsym(void *handle, const char *symbol)
+{
+#if defined(WIN32)
+ return GetProcAddress(handle, symbol);
+#else
+ return dlsym(handle, symbol);
+#endif
+}
+
+static const char *netsnmp_dlerror(void)
+{
+#if defined(WIN32)
+ static char errstr[256];
+ const DWORD dwErrorcode = GetLastError();
+ LPTSTR lpMsgBuf;
+
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, dwErrorcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf, 0, NULL);
+ if (lpMsgBuf) {
+ LPTSTR p;
+
+ /*
+ * Remove trailing "\r\n".
+ */
+ p = strchr(lpMsgBuf, '\r');
+ if (p)
+ *p = '\0';
+ snprintf(errstr, sizeof(errstr), "%s", lpMsgBuf);
+ LocalFree(lpMsgBuf);
+ } else {
+ snprintf(errstr, sizeof(errstr), "error code %ld", dwErrorcode);
+ }
+ return errstr;
+#else
+ return dlerror();
+#endif
+}
+
+static int dlmod_is_abs_path(const char *path)
+{
+#if defined(WIN32)
+ return (strncmp(path, "//", 2) == 0 || strncmp(path, "\\\\", 2) == 0) ||
+ (isalpha((u_char)path[0]) && path[1] == ':' &&
+ (path[2] == '/' || path[2] == '\\'));
+#else
+ return path[0] == '/';
+#endif
+}
+
void
dlmod_load_module(struct dlmod *dlm)
{
@@ -144,30 +227,24 @@ dlmod_load_module(struct dlmod *dlm)
(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 (dlmod_is_abs_path(dlm->path)) {
+ dlm->handle = netsnmp_dlopen(dlm->path);
if (dlm->handle == NULL) {
snprintf(dlm->error, sizeof(dlm->error),
- "dlopen failed: %s", dlerror());
+ "dlopen(%s) failed: %s", dlm->path, netsnmp_dlerror());
dlm->status = DLMOD_ERROR;
return;
}
} else {
- for (p = strtok_r(dlmod_path, ":", &st); p; p = strtok_r(NULL, ":", &st)) {
- snprintf(tmp_path, sizeof(tmp_path), "%s/%s.so", p, dlm->path);
+ for (p = strtok_r(dlmod_path, ENV_SEPARATOR, &st); p;
+ p = strtok_r(NULL, ENV_SEPARATOR, &st)) {
+ snprintf(tmp_path, sizeof(tmp_path), "%s/%s.%s", p, dlm->path,
+ netsnmp_dl_suffix);
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
+ dlm->handle = netsnmp_dlopen(tmp_path);
if (dlm->handle == NULL) {
snprintf(dlm->error, sizeof(dlm->error),
- "dlopen failed: %s", dlerror());
+ "dlopen(%s) failed: %s", tmp_path, netsnmp_dlerror());
dlm->status = DLMOD_ERROR;
}
}
@@ -176,9 +253,9 @@ dlmod_load_module(struct dlmod *dlm)
return;
}
snprintf(sym_init, sizeof(sym_init), "init_%s", dlm->name);
- dl_init = dlsym(dlm->handle, sym_init);
+ dl_init = netsnmp_dlsym(dlm->handle, sym_init);
if (dl_init == NULL) {
- dlclose(dlm->handle);
+ netsnmp_dlclose(dlm->handle);
snprintf(dlm->error, sizeof(dlm->error),
"dlsym failed: can't find \'%s\'", sym_init);
dlm->status = DLMOD_ERROR;
@@ -200,13 +277,13 @@ dlmod_unload_module(struct dlmod *dlm)
return;
snprintf(sym_deinit, sizeof(sym_deinit), "deinit_%s", dlm->name);
- dl_deinit = dlsym(dlm->handle, sym_deinit);
+ dl_deinit = netsnmp_dlsym(dlm->handle, sym_deinit);
if (dl_deinit) {
DEBUGMSGTL(("dlmod", "Calling deinit_%s()\n", dlm->name));
dl_deinit();
} else {
snprintf(sym_deinit, sizeof(sym_deinit), "shutdown_%s", dlm->name);
- dl_deinit = dlsym(dlm->handle, sym_deinit);
+ dl_deinit = netsnmp_dlsym(dlm->handle, sym_deinit);
if (dl_deinit) {
DEBUGMSGTL(("dlmod", "Calling shutdown_%s()\n", dlm->name));
dl_deinit();
@@ -214,7 +291,7 @@ dlmod_unload_module(struct dlmod *dlm)
DEBUGMSGTL(("dlmod", "No destructor for %s\n", dlm->name));
}
}
- dlclose(dlm->handle);
+ netsnmp_dlclose(dlm->handle);
dlm->status = DLMOD_UNLOADED;
DEBUGMSGTL(("dlmod", "Module %s unloaded\n", dlm->name));
}
@@ -313,18 +390,15 @@ header_dlmod(struct variable *vp,
oid newname[MAX_OID_LEN];
int result;
- memcpy((char *) newname, (char *) vp->name,
- (int) vp->namelen * sizeof(oid));
+ memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid));
newname[DLMOD_NAME_LENGTH] = 0;
- result =
- snmp_oid_compare(name, *length, newname, (int) vp->namelen + 1);
+ result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
if ((exact && (result != 0)) || (!exact && (result >= 0))) {
return MATCH_FAILED;
}
- memcpy((char *) name, (char *) newname,
- ((int) vp->namelen + 1) * sizeof(oid));
+ memcpy((char *) name, (char *) newname, (vp->namelen + 1) * sizeof(oid));
*length = vp->namelen + 1;
*write_method = 0;
*var_len = sizeof(long); /* default to 'long' results */
@@ -343,9 +417,8 @@ var_dlmod(struct variable * vp,
* 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 */
+ *write_method = 0; /* assume it isn't 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)
@@ -391,8 +464,7 @@ header_dlmodEntry(struct variable *vp,
struct dlmod *dlm = NULL;
unsigned int dlmod_index;
- memcpy((char *) newname, (char *) vp->name,
- (int) vp->namelen * sizeof(oid));
+ memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid));
*write_method = 0;
for (dlmod_index = 1; dlmod_index < dlmod_next_index; dlmod_index++) {
@@ -403,8 +475,7 @@ header_dlmodEntry(struct variable *vp,
if (dlm) {
newname[12] = dlmod_index;
- result = snmp_oid_compare(name, *length, newname,
- (int) vp->namelen + 1);
+ result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
if ((exact && (result == 0)) || (!exact && (result < 0)))
break;
@@ -419,8 +490,7 @@ header_dlmodEntry(struct variable *vp,
return NULL;
}
- memcpy((char *) name, (char *) newname,
- ((int) vp->namelen + 1) * sizeof(oid));
+ memcpy((char *) name, (char *) newname, (vp->namelen + 1) * sizeof(oid));
*length = vp->namelen + 1;
*var_len = sizeof(long);
return dlm;
@@ -440,8 +510,7 @@ var_dlmodEntry(struct variable * vp,
*var_len = sizeof(int); /* assume an integer and change later
* if not */
- dlm =
- header_dlmodEntry(vp, name, length, exact, var_len, write_method);
+ dlm = header_dlmodEntry(vp, name, length, exact, var_len, write_method);
if (dlm == NULL)
return NULL;
diff --git a/agent/mibgroup/ucd-snmp/dlmod.h b/agent/mibgroup/ucd-snmp/dlmod.h
index 971a32c..4fbfb9e 100644
--- a/agent/mibgroup/ucd-snmp/dlmod.h
+++ b/agent/mibgroup/ucd-snmp/dlmod.h
@@ -9,7 +9,7 @@
/*
* TODO #include "mibdefs.h"
*/
-#if !defined(HAVE_DLFCN_H) || !defined(HAVE_DLOPEN)
+#if (!defined(HAVE_DLFCN_H) || !defined(HAVE_DLOPEN)) && !defined(WIN32)
config_error(Dynamic modules not supported on this platform)
#endif
------------------------------------------------------------------------------
Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS,
MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current
with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft
MVPs and experts. SALE $99.99 this month only -- learn more at:
http://p.sf.net/sfu/learnmore_122912
_______________________________________________
Net-snmp-users mailing list
[email protected]
Please see the following page to unsubscribe or change other options:
https://lists.sourceforge.net/lists/listinfo/net-snmp-users