From: Guy Harris Date: Thu, 31 Dec 2015 02:49:37 +0000 (-0800) Subject: Use the new debugging routines in libpcap. X-Git-Tag: tcpdump-4.8.0~46 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/817aadf8bb2f67efced4c26f7335db0f64d67783 Use the new debugging routines in libpcap. 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. --- diff --git a/config.h.in b/config.h.in index e45a2de8..6f6bb11a 100644 --- a/config.h.in +++ b/config.h.in @@ -142,6 +142,12 @@ /* 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 diff --git a/configure b/configure index 57234921..a3a3e01e 100755 --- 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 diff --git a/configure.in b/configure.in index 0fb86a7a..8ceb46bb 100644 --- a/configure.in +++ b/configure.in @@ -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 diff --git a/tcpdump.c b/tcpdump.c index d8f0129c..e0237061 100644 --- 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) {