]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Use the new debugging routines in libpcap.
authorGuy Harris <[email protected]>
Thu, 31 Dec 2015 02:49:37 +0000 (18:49 -0800)
committerGuy Harris <[email protected]>
Thu, 31 Dec 2015 02:49:37 +0000 (18:49 -0800)
Newer versions of libpcap, when configured to provide debugging
printouts for the filter expression parser or optimizer, provide
routines to set the "debug the parser" and "debug the optimizer" flags;
use them if the library has them.  If the library doesn't have them, do
our best to try to use the older mechanisms for requesting debugging, if
present.

config.h.in
configure
configure.in
tcpdump.c

index e45a2de82dd13f66a00855ed0708f34b0a405f36..6f6bb11aa9ea8858f798e29e922cdcefea9b09be 100644 (file)
 /* Define to 1 if you have the `pcap_set_immediate_mode' function. */
 #undef HAVE_PCAP_SET_IMMEDIATE_MODE
 
+/* Define to 1 if you have the `pcap_set_optimizer_debug' function. */
+#undef HAVE_PCAP_SET_OPTIMIZER_DEBUG
+
+/* Define to 1 if you have the `pcap_set_parser_debug' function. */
+#undef HAVE_PCAP_SET_PARSER_DEBUG
+
 /* Define to 1 if you have the `pcap_set_tstamp_precision' function. */
 #undef HAVE_PCAP_SET_TSTAMP_PRECISION
 
index 57234921b8cd6e361c3f6a9707c3e64fb2afa745..a3a3e01e78634b83876a33473215b58a1cd33d8c 100755 (executable)
--- a/configure
+++ b/configure
@@ -6258,18 +6258,38 @@ $as_echo "#define HAVE_PCAP_VERSION 1" >>confdefs.h
 $as_echo "no" >&6; }
     fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pcap_debug is defined by libpcap" >&5
+
+#
+# Check for special debugging functions
+#
+for ac_func in pcap_set_parser_debug
+do :
+  ac_fn_c_check_func "$LINENO" "pcap_set_parser_debug" "ac_cv_func_pcap_set_parser_debug"
+if test "x$ac_cv_func_pcap_set_parser_debug" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_PCAP_SET_PARSER_DEBUG 1
+_ACEOF
+
+fi
+done
+
+if test "$ac_cv_func_pcap_set_parser_debug" = "no" ; then
+       #
+       # OK, we don't have pcap_set_parser_debug() to set the libpcap
+       # filter expression parser debug flag; can we directly set the
+       # flag?
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pcap_debug is defined by libpcap" >&5
 $as_echo_n "checking whether pcap_debug is defined by libpcap... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
 main ()
 {
 
-       extern int pcap_debug;
+               extern int pcap_debug;
 
-       return pcap_debug;
+               return pcap_debug;
 
   ;
   return 0;
@@ -6282,30 +6302,30 @@ else
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-if test "$ac_lbl_cv_pcap_debug_defined" = yes ; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+       if test "$ac_lbl_cv_pcap_debug_defined" = yes ; then
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
 
 $as_echo "#define HAVE_PCAP_DEBUG 1" >>confdefs.h
 
-else
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+       else
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-       #
-       # OK, what about "yydebug"?
-       #
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yydebug is defined by libpcap" >&5
+               #
+               # OK, what about "yydebug"?
+               #
+               { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yydebug is defined by libpcap" >&5
 $as_echo_n "checking whether yydebug is defined by libpcap... " >&6; }
-       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+               cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
 main ()
 {
 
-               extern int yydebug;
+                       extern int yydebug;
 
-               return yydebug;
+                       return yydebug;
 
   ;
   return 0;
@@ -6318,17 +6338,29 @@ else
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-       if test "$ac_lbl_cv_yydebug_defined" = yes ; then
-               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+               if test "$ac_lbl_cv_yydebug_defined" = yes ; then
+                       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
 
 $as_echo "#define HAVE_YYDEBUG 1" >>confdefs.h
 
-       else
-               { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+               else
+                       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
+               fi
        fi
 fi
+for ac_func in pcap_set_optimizer_debug
+do :
+  ac_fn_c_check_func "$LINENO" "pcap_set_optimizer_debug" "ac_cv_func_pcap_set_optimizer_debug"
+if test "x$ac_cv_func_pcap_set_optimizer_debug" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_PCAP_SET_OPTIMIZER_DEBUG 1
+_ACEOF
+
+fi
+done
+
 ac_fn_c_check_func "$LINENO" "bpf_dump" "ac_cv_func_bpf_dump"
 if test "x$ac_cv_func_bpf_dump" = xyes; then :
   $as_echo "#define HAVE_BPF_DUMP 1" >>confdefs.h
index 0fb86a7a7b3d2a424a3576fcf42a879ec011dfb4..8ceb46bbad9eb1ef1c6dbcb1b7edd7755a79f85a 100644 (file)
@@ -644,39 +644,51 @@ if test $ac_cv_func_pcap_lib_version = "no" ; then
        AC_MSG_RESULT(no)
     fi
 fi
-AC_MSG_CHECKING(whether pcap_debug is defined by libpcap)
-AC_TRY_LINK([],
-   [
-       extern int pcap_debug;
-
-       return pcap_debug;
-   ],
-   ac_lbl_cv_pcap_debug_defined=yes,
-   ac_lbl_cv_pcap_debug_defined=no)
-if test "$ac_lbl_cv_pcap_debug_defined" = yes ; then
-       AC_MSG_RESULT(yes)
-       AC_DEFINE(HAVE_PCAP_DEBUG, 1, [define if libpcap has pcap_debug])
-else
-       AC_MSG_RESULT(no)
-       #
-       # OK, what about "yydebug"?
+
+#
+# Check for special debugging functions
+#
+AC_CHECK_FUNCS(pcap_set_parser_debug)
+if test "$ac_cv_func_pcap_set_parser_debug" = "no" ; then
        #
-       AC_MSG_CHECKING(whether yydebug is defined by libpcap)
+       # OK, we don't have pcap_set_parser_debug() to set the libpcap
+       # filter expression parser debug flag; can we directly set the
+       # flag?
+       AC_MSG_CHECKING(whether pcap_debug is defined by libpcap)
        AC_TRY_LINK([],
           [
-               extern int yydebug;
+               extern int pcap_debug;
 
-               return yydebug;
+               return pcap_debug;
           ],
-          ac_lbl_cv_yydebug_defined=yes,
-          ac_lbl_cv_yydebug_defined=no)
-       if test "$ac_lbl_cv_yydebug_defined" = yes ; then
+          ac_lbl_cv_pcap_debug_defined=yes,
+          ac_lbl_cv_pcap_debug_defined=no)
+       if test "$ac_lbl_cv_pcap_debug_defined" = yes ; then
                AC_MSG_RESULT(yes)
-               AC_DEFINE(HAVE_YYDEBUG, 1, [define if libpcap has yydebug])
+               AC_DEFINE(HAVE_PCAP_DEBUG, 1, [define if libpcap has pcap_debug])
        else
                AC_MSG_RESULT(no)
+               #
+               # OK, what about "yydebug"?
+               #
+               AC_MSG_CHECKING(whether yydebug is defined by libpcap)
+               AC_TRY_LINK([],
+                  [
+                       extern int yydebug;
+
+                       return yydebug;
+                  ],
+                  ac_lbl_cv_yydebug_defined=yes,
+                  ac_lbl_cv_yydebug_defined=no)
+               if test "$ac_lbl_cv_yydebug_defined" = yes ; then
+                       AC_MSG_RESULT(yes)
+                       AC_DEFINE(HAVE_YYDEBUG, 1, [define if libpcap has yydebug])
+               else
+                       AC_MSG_RESULT(no)
+               fi
        fi
 fi
+AC_CHECK_FUNCS(pcap_set_optimizer_debug)
 AC_REPLACE_FUNCS(bpf_dump)     dnl moved to libpcap in 0.6
 
 V_GROUP=0
index d8f0129c622cd473d414489303d1ff987d30f767..e0237061902a89817cd7866d5deaf97d0dc1a682 100644 (file)
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -130,7 +130,19 @@ The Regents of the University of California.  All rights reserved.\n";
 static int Cflag;                      /* rotate dump files after this many bytes */
 static int Cflag_count;                        /* Keep track of which file number we're writing */
 static int Dflag;                      /* list available devices and exit */
-static int dflag;                      /* print filter code */
+/*
+ * This is exported because, in some versions of libpcap, if libpcap
+ * is built with optimizer debugging code (which is *NOT* the default
+ * configuration!), the library *imports*(!) a variable named dflag,
+ * under the expectation that tcpdump is exporting it, to govern
+ * how much debugging information to print when optimizing
+ * the generated BPF code.
+ *
+ * This is a horrible hack; newer versions of libpcap don't import
+ * dflag but, instead, *if* built with optimizer debugging code,
+ * *export* a routine to set that flag.
+ */
+int dflag;                             /* print filter code */
 static int Gflag;                      /* rotate dump files after this many seconds */
 static int Gflag_count;                        /* number of files created with Gflag rotation */
 static time_t Gflag_time;              /* The last time_t the dump file was rotated. */
@@ -209,6 +221,57 @@ struct dump_info {
 #endif
 };
 
+#if defined(HAVE_PCAP_SET_PARSER_DEBUG)
+/*
+ * We have pcap_set_parser_debug() in libpcap; declare it (it's not declared
+ * by any libpcap header, because it's a special hack, only available if
+ * libpcap was configured to include it, and only intended for use by
+ * libpcap developers trying to debug the parser for filter expressions).
+ */
+#ifdef _WIN32
+__declspec(dllimport)
+#else /* _WIN32 */
+extern
+#endif /* _WIN32 */
+void pcap_set_parser_debug(int);
+#elif defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG)
+/*
+ * We don't have pcap_set_parser_debug() in libpcap, but we do have
+ * pcap_debug or yydebug.  Make a local version of pcap_set_parser_debug()
+ * to set the flag, and define HAVE_PCAP_SET_PARSER_DEBUG.
+ */
+static void
+pcap_set_parser_debug(int value)
+{
+#ifdef HAVE_PCAP_DEBUG
+       extern int pcap_debug;
+
+       pcap_debug = value;
+#else /* HAVE_PCAP_DEBUG */
+       extern int yydebug;
+
+       yydebug = value;
+#endif /* HAVE_PCAP_DEBUG */
+}
+
+#define HAVE_PCAP_SET_PARSER_DEBUG
+#endif
+
+#if defined(HAVE_PCAP_SET_OPTIMIZER_DEBUG)
+/*
+ * We have pcap_set_optimizer_debug() in libpcap; declare it (it's not declared
+ * by any libpcap header, because it's a special hack, only available if
+ * libpcap was configured to include it, and only intended for use by
+ * libpcap developers trying to debug the optimizer for filter expressions).
+ */
+#ifdef _WIN32
+__declspec(dllimport)
+#else /* _WIN32 */
+extern
+#endif /* _WIN32 */
+void pcap_set_optimizer_debug(int);
+#endif
+
 #ifdef HAVE_PCAP_SET_TSTAMP_TYPE
 static void
 show_tstamp_types_and_exit(const char *device)
@@ -453,7 +516,7 @@ static const struct option longopts[] = {
 #ifdef HAVE_PCAP_SET_IMMEDIATE_MODE
        { "immediate-mode", no_argument, NULL, OPTION_IMMEDIATE_MODE },
 #endif
-#if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG)
+#ifdef HAVE_PCAP_SET_PARSER_DEBUG
        { "debug-filter-parser", no_argument, NULL, 'Y' },
 #endif
        { "relinquish-privileges", required_argument, NULL, 'Z' },
@@ -1104,17 +1167,11 @@ main(int argc, char **argv)
                                error("invalid data link type %s", yflag_dlt_name);
                        break;
 
-#if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG)
+#ifdef HAVE_PCAP_SET_PARSER_DEBUG
                case 'Y':
                        {
                        /* Undocumented flag */
-#ifdef HAVE_PCAP_DEBUG
-                       extern int pcap_debug;
-                       pcap_debug = 1;
-#else
-                       extern int yydebug;
-                       yydebug = 1;
-#endif
+                       pcap_set_parser_debug(1);
                        }
                        break;
 #endif
@@ -1476,6 +1533,9 @@ main(int argc, char **argv)
        else
                cmdbuf = copy_argv(&argv[optind]);
 
+#ifdef HAVE_PCAP_SET_OPTIMIZER_DEBUG
+       pcap_set_optimizer_debug(dflag);
+#endif
        if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
                error("%s", pcap_geterr(pd));
        if (dflag) {