Add support for libcasper library available on FreeBSD 11.0 and newer.
#include "config.h"
#endif
+#ifdef HAVE_CASPER
+#include <libcasper.h>
+#include <casper/cap_dns.h>
+#endif /* HAVE_CASPER */
+
#include <netdissect-stdinc.h>
#ifdef USE_ETHER_NTOHOST
static uint32_t f_netmask;
static uint32_t f_localnet;
+#ifdef HAVE_CASPER
+extern cap_channel_t *capdns;
+#endif
/*
* Return a name for the IP address pointed to by ap. This address
*/
if (!ndo->ndo_nflag &&
(addr & f_netmask) == f_localnet) {
- hp = gethostbyaddr((char *)&addr, 4, AF_INET);
+#ifdef HAVE_CASPER
+ if (capdns != NULL) {
+ hp = cap_gethostbyaddr(capdns, (char *)&addr, 4,
+ AF_INET);
+ } else
+#endif
+ hp = gethostbyaddr((char *)&addr, 4, AF_INET);
if (hp) {
char *dotp;
* Do not print names if -n was given.
*/
if (!ndo->ndo_nflag) {
- hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6);
+#ifdef HAVE_CASPER
+ if (capdns != NULL) {
+ hp = cap_gethostbyaddr(capdns, (char *)&addr,
+ sizeof(addr), AF_INET6);
+ } else
+#endif
+ hp = gethostbyaddr((char *)&addr, sizeof(addr),
+ AF_INET6);
if (hp) {
char *dotp;
/* capsicum support available */
#undef HAVE_CAPSICUM
-/* Define to 1 if you have the `cap_enter' function. */
-#undef HAVE_CAP_ENTER
+/* Casper library available */
+#undef HAVE_CASPER
/* Define to 1 if you have the `cap_ioctls_limit' function. */
#undef HAVE_CAP_IOCTLS_LIMIT
fi
done
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cap_init in -lcasper" >&5
+$as_echo_n "checking for cap_init in -lcasper... " >&6; }
+if ${ac_cv_lib_casper_cap_init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcasper $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cap_init ();
+int
+main ()
+{
+return cap_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_casper_cap_init=yes
+else
+ ac_cv_lib_casper_cap_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_casper_cap_init" >&5
+$as_echo "$ac_cv_lib_casper_cap_init" >&6; }
+if test "x$ac_cv_lib_casper_cap_init" = xyes; then :
+ LIBS="$LIBS -lcasper"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cap_gethostbyaddr in -lcap_dns" >&5
+$as_echo_n "checking for cap_gethostbyaddr in -lcap_dns... " >&6; }
+if ${ac_cv_lib_cap_dns_cap_gethostbyaddr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcap_dns $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cap_gethostbyaddr ();
+int
+main ()
+{
+return cap_gethostbyaddr ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_cap_dns_cap_gethostbyaddr=yes
+else
+ ac_cv_lib_cap_dns_cap_gethostbyaddr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cap_dns_cap_gethostbyaddr" >&5
+$as_echo "$ac_cv_lib_cap_dns_cap_gethostbyaddr" >&6; }
+if test "x$ac_cv_lib_cap_dns_cap_gethostbyaddr" = xyes; then :
+ LIBS="$LIBS -lcap_dns"
+fi
+
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to sandbox using capsicum" >&5
$as_echo_n "checking whether to sandbox using capsicum... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to sandbox using Casper library" >&5
+$as_echo_n "checking whether to sandbox using Casper library... " >&6; }
+if test "x$ac_cv_lib_casper_cap_init" = "xyes" -a "x$ac_cv_lib_cap_dns_cap_gethostbyaddr" = "xyes"; then
+
+$as_echo "#define HAVE_CASPER 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
#
# We must check this before checking whether to check the OS's IPv6,
AC_CHECK_FUNCS(cap_enter cap_rights_limit cap_ioctls_limit openat,
ac_lbl_capsicum_function_seen=yes,
ac_lbl_capsicum_function_not_seen=yes)
+ AC_CHECK_LIB(casper, cap_init, LIBS="$LIBS -lcasper")
+ AC_CHECK_LIB(cap_dns, cap_gethostbyaddr, LIBS="$LIBS -lcap_dns")
fi
AC_MSG_CHECKING([whether to sandbox using capsicum])
if test "x$ac_lbl_capsicum_function_seen" = "xyes" -a "x$ac_lbl_capsicum_function_not_seen" != "xyes"; then
else
AC_MSG_RESULT(no)
fi
+AC_MSG_CHECKING([whether to sandbox using Casper library])
+if test "x$ac_cv_lib_casper_cap_init" = "xyes" -a "x$ac_cv_lib_cap_dns_cap_gethostbyaddr" = "xyes"; then
+ AC_DEFINE(HAVE_CASPER, 1, [Casper support available])
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
#
# We must check this before checking whether to check the OS's IPv6,
#include <sys/ioccom.h>
#include <net/bpf.h>
#include <libgen.h>
+#ifdef HAVE_CASPER
+#include <libcasper.h>
+#include <casper/cap_dns.h>
+#include <sys/nv.h>
+#endif /* HAVE_CASPER */
#endif /* HAVE_CAPSICUM */
#include <pcap.h>
#include <signal.h>
char *program_name;
+#ifdef HAVE_CASPER
+cap_channel_t *capdns;
+#endif
+
/* Forwards */
static void error(const char *, ...)
__attribute__((noreturn))
return ret;
}
+#ifdef HAVE_CASPER
+static cap_channel_t *
+capdns_setup(void)
+{
+ cap_channel_t *capcas, *capdnsloc;
+ const char *types[1];
+ int families[2];
+
+ capcas = cap_init();
+ if (capcas == NULL)
+ error("unable to create casper process");
+ capdnsloc = cap_service_open(capcas, "system.dns");
+ /* Casper capability no longer needed. */
+ cap_close(capcas);
+ if (capdnsloc == NULL)
+ error("unable to open system.dns service");
+ /* Limit system.dns to reverse DNS lookups. */
+ types[0] = "ADDR";
+ if (cap_dns_type_limit(capdnsloc, types, 1) < 0)
+ error("unable to limit access to system.dns service");
+ families[0] = AF_INET;
+ families[1] = AF_INET6;
+ if (cap_dns_family_limit(capdnsloc, families, 2) < 0)
+ error("unable to limit access to system.dns service");
+
+ return (capdnsloc);
+}
+#endif /* HAVE_CASPER */
+
#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
static int
tstamp_precision_from_string(const char *precision)
pcap_freecode(&fcode);
exit_tcpdump(0);
}
+
+#ifdef HAVE_CASPER
+ if (!ndo->ndo_nflag)
+ capdns = capdns_setup();
+#endif /* HAVE_CASPER */
+
init_print(ndo, localnet, netmask, timezone_offset);
#ifndef _WIN32
}
#ifdef HAVE_CAPSICUM
- cansandbox = (ndo->ndo_nflag && VFileName == NULL && zflag == NULL);
+ cansandbox = (VFileName == NULL && zflag == NULL);
+#ifdef HAVE_CASPER
+ cansandbox = (cansandbox && (ndo->ndo_nflag || capdns != NULL));
+#else
+ cansandbox = (cansandbox && ndo->ndo_nflag);
+#endif /* HAVE_CASPER */
if (cansandbox && cap_enter() < 0 && errno != ENOSYS)
error("unable to enter the capability mode");
#endif /* HAVE_CAPSICUM */