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
Net-snmp-users@lists.sourceforge.net
Please see the following page to unsubscribe or change other options:
https://lists.sourceforge.net/lists/listinfo/net-snmp-users

Reply via email to