]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
iptables: improve error reporting with extension loading troubles
authorJan Engelhardt <jengelh@medozas.de>
Sun, 30 Jan 2011 13:18:17 +0000 (14:18 +0100)
committerJan Engelhardt <jengelh@medozas.de>
Mon, 31 Jan 2011 00:44:51 +0000 (01:44 +0100)
ip6tables v1.4.8: Could not load match "osf":
/usr/lib/xtables/libip6t_osf.so: cannot open shared object file: No
such file or directory

Given that libxt_osf.so exists, a better error is now emitted.

References: http://bugzilla.netfilter.org/show_bug.cgi?id=637
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
xtables.c

index eec1733459c06a1f75ccf68a464628e82f18bc5e..00362992f848a5876d465fcffccca44d59ff8497 100644 (file)
--- a/xtables.c
+++ b/xtables.c
@@ -492,9 +492,11 @@ void xtables_parse_interface(const char *arg, char *vianame,
 }
 
 #ifndef NO_SHARED_LIBS
-static void *load_extension(const char *search_path, const char *prefix,
+static void *load_extension(const char *search_path, const char *af_prefix,
     const char *name, bool is_target)
 {
+       const char *all_prefixes[] = {"libxt_", af_prefix, NULL};
+       const char **prefix;
        const char *dir = search_path, *next;
        void *ptr = NULL;
        struct stat sb;
@@ -504,39 +506,38 @@ static void *load_extension(const char *search_path, const char *prefix,
                next = strchr(dir, ':');
                if (next == NULL)
                        next = dir + strlen(dir);
-               snprintf(path, sizeof(path), "%.*s/libxt_%s.so",
-                        (unsigned int)(next - dir), dir, name);
 
-               if (dlopen(path, RTLD_NOW) != NULL) {
-                       /* Found library.  If it didn't register itself,
-                          maybe they specified target as match. */
-                       if (is_target)
-                               ptr = xtables_find_target(name, XTF_DONT_LOAD);
-                       else
-                               ptr = xtables_find_match(name,
-                                     XTF_DONT_LOAD, NULL);
-               } else if (stat(path, &sb) == 0) {
-                       fprintf(stderr, "%s: %s\n", path, dlerror());
-               }
+               for (prefix = all_prefixes; *prefix != NULL; ++prefix) {
+                       snprintf(path, sizeof(path), "%.*s/%s%s.so",
+                                (unsigned int)(next - dir), dir,
+                                *prefix, name);
 
-               if (ptr != NULL)
-                       return ptr;
+                       if (stat(path, &sb) != 0) {
+                               if (errno == ENOENT)
+                                       continue;
+                               fprintf(stderr, "%s: %s\n", path,
+                                       strerror(errno));
+                               return NULL;
+                       }
+                       if (dlopen(path, RTLD_NOW) == NULL) {
+                               fprintf(stderr, "%s: %s\n", path, dlerror());
+                               break;
+                       }
 
-               snprintf(path, sizeof(path), "%.*s/%s%s.so",
-                        (unsigned int)(next - dir), dir, prefix, name);
-               if (dlopen(path, RTLD_NOW) != NULL) {
                        if (is_target)
                                ptr = xtables_find_target(name, XTF_DONT_LOAD);
                        else
                                ptr = xtables_find_match(name,
                                      XTF_DONT_LOAD, NULL);
-               } else if (stat(path, &sb) == 0) {
-                       fprintf(stderr, "%s: %s\n", path, dlerror());
-               }
 
-               if (ptr != NULL)
-                       return ptr;
+                       if (ptr != NULL)
+                               return ptr;
 
+                       fprintf(stderr, "%s: no \"%s\" extension found for "
+                               "this protocol\n", path, name);
+                       errno = ENOENT;
+                       return NULL;
+               }
                dir = next + 1;
        } while (*next != '\0');
 
@@ -591,7 +592,7 @@ xtables_find_match(const char *name, enum xtables_tryload tryload,
                if (ptr == NULL && tryload == XTF_LOAD_MUST_SUCCEED)
                        xt_params->exit_err(PARAMETER_PROBLEM,
                                   "Couldn't load match `%s':%s\n",
-                                  name, dlerror());
+                                  name, strerror(errno));
        }
 #else
        if (ptr && !ptr->loaded) {
@@ -651,7 +652,7 @@ xtables_find_target(const char *name, enum xtables_tryload tryload)
                if (ptr == NULL && tryload == XTF_LOAD_MUST_SUCCEED)
                        xt_params->exit_err(PARAMETER_PROBLEM,
                                   "Couldn't load target `%s':%s\n",
-                                  name, dlerror());
+                                  name, strerror(errno));
        }
 #else
        if (ptr && !ptr->loaded) {