that case usually represent a small subset of the parameters
                  supported by the system. Unprivileged users MUST use the
                  **unprivileged** keyword: This is to avoid misdetection if
-                 bpftool is inadvertently run as non-root, for example.
+                 bpftool is inadvertently run as non-root, for example. This
+                 keyword is unavailable if bpftool was compiled without
+                 libcap.
 
        **bpftool feature probe dev** *NAME* [**full**] [**macros** [**prefix** *PREFIX*]]
                  Probe network device for supported eBPF features and dump
 
 LDFLAGS += $(EXTRA_LDFLAGS)
 endif
 
-LIBS = $(LIBBPF) -lelf -lz -lcap
-
 INSTALL ?= install
 RM ?= rm -f
 CLANG ?= clang
 
 FEATURE_USER = .bpftool
-FEATURE_TESTS = libbfd disassembler-four-args reallocarray zlib \
+FEATURE_TESTS = libbfd disassembler-four-args reallocarray zlib libcap \
+       clang-bpf-global-var
+FEATURE_DISPLAY = libbfd disassembler-four-args zlib libcap \
        clang-bpf-global-var
-FEATURE_DISPLAY = libbfd disassembler-four-args zlib clang-bpf-global-var
 
 check_feat := 1
 NON_CHECK_FEAT_TARGETS := clean uninstall doc doc-clean doc-install doc-uninstall
 CFLAGS += -DCOMPAT_NEED_REALLOCARRAY
 endif
 
+LIBS = $(LIBBPF) -lelf -lz
+ifeq ($(feature-libcap), 1)
+CFLAGS += -DUSE_LIBCAP
+LIBS += -lcap
+endif
+
 include $(wildcard $(OUTPUT)*.d)
 
 all: $(OUTPUT)bpftool
 
 #include <string.h>
 #include <unistd.h>
 #include <net/if.h>
+#ifdef USE_LIBCAP
 #include <sys/capability.h>
+#endif
 #include <sys/utsname.h>
 #include <sys/vfs.h>
 
 #undef BPF_HELPER_MAKE_ENTRY
 
 static bool full_mode;
+#ifdef USE_LIBCAP
 static bool run_as_unprivileged;
+#endif
 
 /* Miscellaneous utility functions */
 
                }
 
        res = bpf_probe_prog_type(prog_type, ifindex);
+#ifdef USE_LIBCAP
        /* Probe may succeed even if program load fails, for unprivileged users
         * check that we did not fail because of insufficient permissions
         */
        if (run_as_unprivileged && errno == EPERM)
                res = false;
+#endif
 
        supported_types[prog_type] |= res;
 
 
        if (supported_type) {
                res = bpf_probe_helper(id, prog_type, ifindex);
+#ifdef USE_LIBCAP
                /* Probe may succeed even if program load fails, for
                 * unprivileged users check that we did not fail because of
                 * insufficient permissions
                 */
                if (run_as_unprivileged && errno == EPERM)
                        res = false;
+#endif
        }
 
        if (json_output) {
 
 static int handle_perms(void)
 {
+#ifdef USE_LIBCAP
        cap_value_t cap_list[1] = { CAP_SYS_ADMIN };
        bool has_sys_admin_cap = false;
        cap_flag_value_t val;
        }
 
        return res;
+#else
+       /* Detection assumes user has sufficient privileges (CAP_SYS_ADMIN).
+        * We do not use libpcap so let's approximate, and restrict usage to
+        * root user only.
+        */
+       if (geteuid()) {
+               p_err("full feature probing requires root privileges");
+               return -1;
+       }
+
+       return 0;
+#endif /* USE_LIBCAP */
 }
 
 static int do_probe(int argc, char **argv)
                                return -1;
                        define_prefix = GET_ARG();
                } else if (is_prefix(*argv, "unprivileged")) {
+#ifdef USE_LIBCAP
                        run_as_unprivileged = true;
                        NEXT_ARG();
+#else
+                       p_err("unprivileged run not supported, recompile bpftool with libcap");
+                       return -1;
+#endif
                } else {
                        p_err("expected no more arguments, 'kernel', 'dev', 'macros' or 'prefix', got: '%s'?",
                              *argv);