]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Merge pull request #588 from glebius/casper
authorGuy Harris <[email protected]>
Thu, 2 Feb 2017 20:18:56 +0000 (12:18 -0800)
committerGitHub <[email protected]>
Thu, 2 Feb 2017 20:18:56 +0000 (12:18 -0800)
Add support for libcasper library available on FreeBSD 11.0 and newer.

1  2 
addrtoname.c
configure
configure.in
tcpdump.c

diff --combined addrtoname.c
index 6975b7134e23c39e91eef115885b63dc6e8e1ac3,c679c83fad2b058d1b900d6ed1d6ce1adacacaef..85cbf7b73179799d3c6391306d750ca946930cff
  #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
@@@ -197,6 -202,9 +202,9 @@@ intoa(uint32_t addr
  
  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
@@@ -242,7 -250,13 +250,13 @@@ getname(netdissect_options *ndo, const 
         */
        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;
  
@@@ -297,7 -311,14 +311,14 @@@ getname6(netdissect_options *ndo, cons
         * 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;
  
@@@ -406,15 -427,14 +427,15 @@@ lookup_bytestring(netdissect_options *n
  /* Find the hash node that corresponds the NSAP 'nsap' */
  
  static inline struct enamemem *
 -lookup_nsap(netdissect_options *ndo, register const u_char *nsap)
 +lookup_nsap(netdissect_options *ndo, register const u_char *nsap,
 +          register u_int nsap_length)
  {
        register u_int i, j, k;
 -      unsigned int nlen = *nsap;
        struct enamemem *tp;
 -      const u_char *ensap = nsap + nlen - 6;
 +      const u_char *ensap;
  
 -      if (nlen > 6) {
 +      if (nsap_length > 6) {
 +              ensap = nsap + nsap_length - 6;
                k = (ensap[0] << 8) | ensap[1];
                j = (ensap[2] << 8) | ensap[3];
                i = (ensap[4] << 8) | ensap[5];
                if (tp->e_addr0 == i &&
                    tp->e_addr1 == j &&
                    tp->e_addr2 == k &&
 -                  tp->e_nsap[0] == nlen &&
 +                  tp->e_nsap[0] == nsap_length &&
                    memcmp((const char *)&(nsap[1]),
 -                      (char *)&(tp->e_nsap[1]), nlen) == 0)
 +                      (char *)&(tp->e_nsap[1]), nsap_length) == 0)
                        return tp;
                else
                        tp = tp->e_nxt;
        tp->e_addr0 = i;
        tp->e_addr1 = j;
        tp->e_addr2 = k;
 -      tp->e_nsap = (u_char *)malloc(nlen + 1);
 +      tp->e_nsap = (u_char *)malloc(nsap_length + 1);
        if (tp->e_nsap == NULL)
                (*ndo->ndo_error)(ndo, "lookup_nsap: malloc");
 -      memcpy((char *)tp->e_nsap, (const char *)nsap, nlen + 1);
 +      tp->e_nsap[0] = (u_char)nsap_length;    /* guaranteed < ISONSAP_MAX_LENGTH */
 +      memcpy((char *)&tp->e_nsap[1], (const char *)nsap, nsap_length);
        tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
        if (tp->e_nxt == NULL)
                (*ndo->ndo_error)(ndo, "lookup_nsap: calloc");
@@@ -656,7 -675,7 +677,7 @@@ isonsap_string(netdissect_options *ndo
        if (nsap_length < 1 || nsap_length > ISONSAP_MAX_LENGTH)
                return ("isonsap_string: illegal length");
  
 -      tp = lookup_nsap(ndo, nsap);
 +      tp = lookup_nsap(ndo, nsap, nsap_length);
        if (tp->e_name)
                return tp->e_name;
  
diff --combined configure
index d2c3eeb479429c89d621e3facd2d4204e8246efc,79226387298d7741493c6a8c3456c64737b02bdb..3eba815eb434eb22563147135b21192ea433b084
+++ b/configure
  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,
  
  
  
 -
                  LBL_LIBS="$LIBS"
      pfopen=/usr/examples/packetfilter/pfopen.c
      if test -f $pfopen ; then
@@@ -5801,7 -5894,7 +5893,7 @@@ if test "x$ac_cv_func_pcap_loop" = xyes
  
  else
  
 -          as_fn_error $? "Report this to [email protected], and include the
 +          as_fn_error $? "This is a bug, please follow the guidelines in CONTRIBUTING and include the
  config.log file in your report.  If you have downloaded libpcap from
  tcpdump.org, and built it yourself, please also include the config.log
  file from the libpcap source directory, the Makefile from the libpcap
diff --combined configure.in
index a78a12666347f6871966c8a1b209e82fa3f66a57,d8cc3882abc676a7d4f715b4674e8fc97bcc232c..9b06fd9255308cb0a65f134cf679545fd9553463
@@@ -225,6 -225,8 +225,8 @@@ if test ! -z "$with_sandbox-capsicum" &
        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,
@@@ -418,6 -427,9 +427,6 @@@ dnl Some platforms may need -lnsl for g
  AC_SEARCH_LIBS(getrpcbynumber, nsl,
      AC_DEFINE(HAVE_GETRPCBYNUMBER, 1, [define if you have getrpcbynumber()]))
  
 -dnl AC_CHECK_LIB(z, uncompress)
 -dnl AC_CHECK_HEADERS(zlib.h)
 -
  AC_LBL_LIBPCAP(V_PCAPDEP, V_INCLS)
  
  #
diff --combined tcpdump.c
index e26fbafdd7013dde2b494cbd815d644eb6ccd570,a0c273af86282a779f5f7684349b98420567dc96..2bfc6b0f2cf5ef864c501a747ed83d8d40665f06
+++ b/tcpdump.c
@@@ -80,6 -80,11 +80,11 @@@ The Regents of the University of Califo
  #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>
@@@ -170,6 -175,10 +175,10 @@@ static int infoprint
  
  char *program_name;
  
+ #ifdef HAVE_CASPER
+ cap_channel_t *capdns;
+ #endif
  /* Forwards */
  static void error(const char *, ...)
       __attribute__((noreturn))
@@@ -720,6 -729,35 +729,35 @@@ get_next_file(FILE *VFile, char *ptr
        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)
@@@ -1779,6 -1817,12 +1817,12 @@@ main(int argc, char **argv
                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
        if (RFileName == NULL && VFileName == NULL) {
                static const unsigned long cmds[] = { BIOCGSTATS, BIOCROTZBUF };
  
 -              cap_rights_init(&rights, CAP_IOCTL, CAP_READ);
 +              /*
 +               * The various libpcap devices use a combination of
 +               * read (bpf), ioctl (bpf, netmap), poll (netmap)
 +               * so we add the relevant access rights.
 +               */
 +              cap_rights_init(&rights, CAP_IOCTL, CAP_READ, CAP_EVENT);
                if (cap_rights_limit(pcap_fileno(pd), &rights) < 0 &&
                    errno != ENOSYS) {
                        error("unable to limit pcap descriptor");
        }
  
  #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 */