diff --git a/capinfos.c b/capinfos.c index 684dc79132..8a0a9ad166 100644 --- a/capinfos.c +++ b/capinfos.c @@ -1615,7 +1615,7 @@ main(int argc, char *argv[]) decimal_point = g_strdup(localeconv()->decimal_point); /* Initialize the version information. */ - ws_init_version_info("Capinfos (Wireshark)", NULL, NULL, NULL); + ws_init_version_info("Capinfos", NULL, NULL); #ifdef _WIN32 create_app_running_mutex(); diff --git a/capture/capture-pcap-util-unix.c b/capture/capture-pcap-util-unix.c index adf3084fe1..b11d5f335d 100644 --- a/capture/capture-pcap-util-unix.c +++ b/capture/capture-pcap-util-unix.c @@ -14,6 +14,7 @@ #include #include +#include #ifdef HAVE_LIBPCAP @@ -96,7 +97,7 @@ open_capture_device_local(capture_options *capture_opts * compiled, and append them to a GString. */ void -get_compiled_caplibs_version(GString *str) +gather_caplibs_compile_info(feature_list l) { /* * NOTE: in *some* flavors of UN*X, the data from a shared @@ -118,12 +119,13 @@ get_compiled_caplibs_version(GString *str) * So, for now, we just give up on reporting the version * of libpcap with which we were compiled. */ - g_string_append(str, "with libpcap"); #ifdef HAVE_PCAP_REMOTE /* * We have remote pcap support in libpcap. */ - g_string_append(str, " (including remote capture support)"); + with_feature(l, "libpcap (including remote capture support)"); +#else + with_feature(l, "libpcap"); #endif /* @@ -133,34 +135,34 @@ get_compiled_caplibs_version(GString *str) * having to run dumpcap. */ /* LIBCAP */ - g_string_append(str, ", "); #ifdef HAVE_LIBCAP - g_string_append(str, "with POSIX capabilities"); #ifdef _LINUX_CAPABILITY_VERSION - g_string_append(str, " (Linux)"); + with_feature(l, "POSIX capabilities (Linux)"); +#else /* _LINUX_CAPABILITY_VERSION */ + with_feature(l, "POSIX capabilities"); #endif /* _LINUX_CAPABILITY_VERSION */ #else /* HAVE_LIBCAP */ - g_string_append(str, "without POSIX capabilities"); + without_feature(l, "POSIX capabilities"); #endif /* HAVE_LIBCAP */ #ifdef __linux__ /* This is a Linux-specific library. */ /* LIBNL */ - g_string_append(str, ", "); #if defined(HAVE_LIBNL1) - g_string_append(str, "with libnl 1"); + with_feature(l, "libnl 1"); #elif defined(HAVE_LIBNL2) - g_string_append(str, "with libnl 2"); + with_feature(l, "libnl 2"); #elif defined(HAVE_LIBNL3) - g_string_append(str, "with libnl 3"); + with_feature(l, "libnl 3"); #else /* no libnl */ - g_string_append(str, "without libnl"); + without_feature(l, "libnl"); #endif /* libnl version */ #endif /* __linux__ */ } /* * Append the version of libpcap with which we're running to a GString. + * Used in dumpcap when reporting a pcap bug. */ void get_runtime_caplibs_version(GString *str) @@ -172,9 +174,24 @@ get_runtime_caplibs_version(GString *str) * to be consistent with our format. */ if (g_str_has_prefix(vstr, "libpcap version ")) /* Sanity check */ - g_string_append_printf(str, "with libpcap %s", vstr + strlen("libpcap version ")); + g_string_append_printf(str, "libpcap %s", vstr + strlen("libpcap version ")); else - g_string_append_printf(str, "with %s", vstr); + g_string_append(str, vstr); +} + +void +gather_caplibs_runtime_info(feature_list l) +{ + const char *vstr = pcap_lib_version(); + + /* + * Remove the substring "version" from the output of pcap_lib_version() + * to be consistent with our format. + */ + if (g_str_has_prefix(vstr, "libpcap version ")) /* Sanity check */ + with_feature(l, "libpcap %s", vstr + strlen("libpcap version ")); + else + with_feature(l, "%s", vstr); } #else /* HAVE_LIBPCAP */ @@ -185,9 +202,9 @@ get_runtime_caplibs_version(GString *str) * libraries. */ void -get_compiled_caplibs_version(GString *str) +gather_caplibs_compile_info(feature_list l) { - g_string_append(str, "without libpcap"); + without_feature(l, "libpcap"); } /* @@ -198,6 +215,11 @@ get_runtime_caplibs_version(GString *str _U_) { } +void +gather_caplibs_runtime_info(feature_list l _U_) +{ +} + #endif /* HAVE_LIBPCAP */ /* diff --git a/capture/capture-pcap-util.h b/capture/capture-pcap-util.h index 595f6eb50e..a3fb58bf6d 100644 --- a/capture/capture-pcap-util.h +++ b/capture/capture-pcap-util.h @@ -12,6 +12,8 @@ #ifndef __CAPTURE_PCAP_UTIL_H__ #define __CAPTURE_PCAP_UTIL_H__ +#include + #ifdef HAVE_LIBPCAP #include "wspcap.h" @@ -77,7 +79,7 @@ extern pcap_t *open_capture_device(capture_options *capture_opts, #endif /* HAVE_LIBPCAP */ -extern void get_compiled_caplibs_version(GString *str); +extern void gather_caplibs_compile_info(feature_list l); /* * Append to a GString an indication of the version of capture libraries @@ -87,6 +89,7 @@ extern void get_compiled_caplibs_version(GString *str); * libpcap/WinPcap/Npcap. */ extern void get_runtime_caplibs_version(GString *str); +extern void gather_caplibs_runtime_info(feature_list l); #ifdef __cplusplus } diff --git a/capture/capture-wpcap.c b/capture/capture-wpcap.c index e8d666cbca..9e030923b5 100644 --- a/capture/capture-wpcap.c +++ b/capture/capture-wpcap.c @@ -814,13 +814,15 @@ open_capture_device_local(capture_options *capture_opts, * Append the WinPcap or Npcap SDK version with which we were compiled to a GString. */ void -get_compiled_caplibs_version(GString *str) +gather_caplibs_compile_info(feature_list l) { - g_string_append(str, "with libpcap"); + with_feature(l, "libpcap"); } + /* * Append the version of Npcap with which we're running to a GString. + * Used in dumpcap when reporting a pcap bug. */ void get_runtime_caplibs_version(GString *str) @@ -831,10 +833,22 @@ get_runtime_caplibs_version(GString *str) * not and, if we have it, what version we have. */ if (has_wpcap) { - g_string_append_printf(str, "with "); - g_string_append_printf(str, p_pcap_lib_version()); + g_string_append(str, p_pcap_lib_version()); + } +} + +void +gather_caplibs_runtime_info(feature_list l) +{ + /* + * On Windows, we might have been compiled with WinPcap/Npcap but + * might not have it loaded; indicate whether we have it or + * not and, if we have it, what version we have. + */ + if (has_wpcap) { + with_feature(l, "%s", p_pcap_lib_version()); } else - g_string_append(str, "without Npcap or WinPcap"); + without_feature(l, "Npcap or WinPcap"); } /* @@ -884,11 +898,12 @@ load_wpcap(void) * to a GString. */ void -get_compiled_caplibs_version(GString *str) +gather_caplibs_compile_info(feature_list l) { - g_string_append(str, "without Npcap or WinPcap"); + without_feature(l, "libpcap"); } + /* * Don't append anything, as we weren't even compiled to use WinPcap/Npcap. */ @@ -897,6 +912,11 @@ get_runtime_caplibs_version(GString *str _U_) { } +void +gather_caplibs_runtime_info(feature_list l _U_) +{ +} + #endif /* HAVE_LIBPCAP */ /* diff --git a/captype.c b/captype.c index fe541f5387..189c52801f 100644 --- a/captype.c +++ b/captype.c @@ -122,7 +122,7 @@ main(int argc, char *argv[]) ws_log_parse_args(&argc, argv, vcmdarg_err, 1); /* Initialize the version information. */ - ws_init_version_info("Captype (Wireshark)", NULL, NULL, NULL); + ws_init_version_info("Captype", NULL, NULL); #ifdef _WIN32 create_app_running_mutex(); diff --git a/dumpcap.c b/dumpcap.c index fbd91944e8..5390f6db5e 100644 --- a/dumpcap.c +++ b/dumpcap.c @@ -3868,8 +3868,10 @@ handle_npcap_bug(char *adapter_name _U_, char *cap_err_str _U_) char *msg; pcap_info_str = g_string_new(""); + // TODO: test directly for Npcap here, so we can remove + // get_runtime_caplibs_version() get_runtime_caplibs_version(pcap_info_str); - if (!g_str_has_prefix(pcap_info_str->str, "with Npcap")) { + if (!g_str_has_prefix(pcap_info_str->str, "Npcap")) { /* * We're not using Npcap, so don't recomment a user * file a bug against Npcap. @@ -4814,19 +4816,17 @@ out: } static void -get_dumpcap_compiled_info(GString *str) +gather_dumpcap_compiled_info(feature_list l) { /* Capture libraries */ - g_string_append(str, ", "); - get_compiled_caplibs_version(str); + gather_caplibs_compile_info(l); } static void -get_dumpcap_runtime_info(GString *str) +gather_dumpcap_runtime_info(feature_list l) { /* Capture libraries */ - g_string_append(str, ", "); - get_runtime_caplibs_version(str); + gather_caplibs_runtime_info(l); } #define LONGOPT_IFNAME LONGOPT_BASE_APPLICATION+1 @@ -4931,8 +4931,8 @@ main(int argc, char *argv[]) #endif /* Initialize the version information. */ - ws_init_version_info("Dumpcap (Wireshark)", NULL, get_dumpcap_compiled_info, - get_dumpcap_runtime_info); + ws_init_version_info("Dumpcap", gather_dumpcap_compiled_info, + gather_dumpcap_runtime_info); #ifdef HAVE_PCAP_REMOTE #define OPTSTRING_r "r" diff --git a/editcap.c b/editcap.c index 39ada78874..555888ac37 100644 --- a/editcap.c +++ b/editcap.c @@ -1192,7 +1192,7 @@ main(int argc, char *argv[]) #endif /* _WIN32 */ /* Initialize the version information. */ - ws_init_version_info("Editcap (Wireshark)", NULL, NULL, NULL); + ws_init_version_info("Editcap", NULL, NULL); /* * Get credential information for later use. diff --git a/epan/epan.c b/epan/epan.c index 85a02ed4ac..3a5d86a2ac 100644 --- a/epan/epan.c +++ b/epan/epan.c @@ -33,6 +33,8 @@ #include #include +#include + #include "conversation.h" #include "except.h" #include "packet.h" @@ -767,91 +769,92 @@ epan_dissect_packet_contains_field(epan_dissect_t* edt, * Get compile-time information for libraries used by libwireshark. */ void -epan_get_compiled_version_info(GString *str) +epan_gather_compile_info(feature_list l) { /* Lua */ #ifdef HAVE_LUA - g_string_append(str, ", with " LUA_RELEASE); + with_feature(l, "%s", LUA_RELEASE); #else - g_string_append(str, ", without Lua"); + without_feature(l, "Lua"); #endif /* HAVE_LUA */ /* GnuTLS */ #ifdef HAVE_LIBGNUTLS - g_string_append(str, ", with GnuTLS " LIBGNUTLS_VERSION); #ifdef HAVE_GNUTLS_PKCS11 - g_string_append(str, " and PKCS #11 support"); + with_feature(l, "GnuTLS %s and PKCS #11 support", LIBGNUTLS_VERSION); +#else + with_feature(l, "GnuTLS %s", LIBGNUTLS_VERSION); #endif /* HAVE_GNUTLS_PKCS11 */ #else - g_string_append(str, ", without GnuTLS"); + without_feature(l, "GnuTLS"); #endif /* HAVE_LIBGNUTLS */ /* Gcrypt */ - g_string_append(str, ", with Gcrypt " GCRYPT_VERSION); + with_feature(l, "Gcrypt %s", GCRYPT_VERSION); /* Kerberos */ #if defined(HAVE_MIT_KERBEROS) - g_string_append(str, ", with MIT Kerberos"); + with_feature(l, "Kerberos (MIT)"); #elif defined(HAVE_HEIMDAL_KERBEROS) - g_string_append(str, ", with Heimdal Kerberos"); + with_feature(l, "Kerberos (Heimdal)"); #else - g_string_append(str, ", without Kerberos"); + without_feature(l, "Kerberos"); #endif /* HAVE_KERBEROS */ /* MaxMindDB */ #ifdef HAVE_MAXMINDDB - g_string_append(str, ", with MaxMind DB resolver"); + with_feature(l, "MaxMind"); #else - g_string_append(str, ", without MaxMind DB resolver"); + without_feature(l, "MaxMind"); #endif /* HAVE_MAXMINDDB */ /* nghttp2 */ #ifdef HAVE_NGHTTP2 - g_string_append(str, ", with nghttp2 " NGHTTP2_VERSION); + with_feature(l, "nghttp2 %s", NGHTTP2_VERSION); #else - g_string_append(str, ", without nghttp2"); + without_feature(l, "nghttp2"); #endif /* HAVE_NGHTTP2 */ /* brotli */ #ifdef HAVE_BROTLI - g_string_append(str, ", with brotli"); + with_feature(l, "brotli"); #else - g_string_append(str, ", without brotli"); + without_feature(l, "brotli"); #endif /* HAVE_BROTLI */ /* LZ4 */ #ifdef HAVE_LZ4 - g_string_append(str, ", with LZ4"); + with_feature(l, "LZ4"); #else - g_string_append(str, ", without LZ4"); + without_feature(l, "LZ4"); #endif /* HAVE_LZ4 */ /* Zstandard */ #ifdef HAVE_ZSTD - g_string_append(str, ", with Zstandard"); + with_feature(l, "Zstandard"); #else - g_string_append(str, ", without Zstandard"); + without_feature(l, "Zstandard"); #endif /* HAVE_ZSTD */ /* Snappy */ #ifdef HAVE_SNAPPY - g_string_append(str, ", with Snappy"); + with_feature(l, "Snappy"); #else - g_string_append(str, ", without Snappy"); + without_feature(l, "Snappy"); #endif /* HAVE_SNAPPY */ /* libxml2 */ #ifdef HAVE_LIBXML2 - g_string_append(str, ", with libxml2 " LIBXML_DOTTED_VERSION); + with_feature(l, "libxml2 %s", LIBXML_DOTTED_VERSION); #else - g_string_append(str, ", without libxml2"); + without_feature(l, "libxml2"); #endif /* HAVE_LIBXML2 */ /* libsmi */ #ifdef HAVE_LIBSMI - g_string_append(str, ", with libsmi " SMI_VERSION_STRING); + with_feature(l, "libsmi %s", SMI_VERSION_STRING); #else - g_string_append(str, ", without libsmi"); + without_feature(l, "libsmi"); #endif /* HAVE_LIBSMI */ } @@ -859,44 +862,44 @@ epan_get_compiled_version_info(GString *str) * Get runtime information for libraries used by libwireshark. */ void -epan_get_runtime_version_info(GString *str) +epan_gather_runtime_info(feature_list l) { /* c-ares */ - g_string_append_printf(str, ", with c-ares %s", ares_version(NULL)); + with_feature(l, "c-ares %s", ares_version(NULL)); /* GnuTLS */ #ifdef HAVE_LIBGNUTLS - g_string_append_printf(str, ", with GnuTLS %s", gnutls_check_version(NULL)); + with_feature(l, "GnuTLS %s", gnutls_check_version(NULL)); #endif /* HAVE_LIBGNUTLS */ /* Gcrypt */ - g_string_append_printf(str, ", with Gcrypt %s", gcry_check_version(NULL)); + with_feature(l, "Gcrypt %s", gcry_check_version(NULL)); /* nghttp2 */ #if NGHTTP2_VERSION_AGE >= 1 nghttp2_info *nghttp2_ptr = nghttp2_version(0); - g_string_append_printf(str, ", with nghttp2 %s", nghttp2_ptr->version_str); + with_feature(l, "nghttp2 %s", nghttp2_ptr->version_str); #endif /* NGHTTP2_VERSION_AGE */ /* brotli */ #ifdef HAVE_BROTLI - g_string_append_printf(str, ", with brotli %d.%d.%d", BrotliDecoderVersion() >> 24, + with_feature(l, "brotli %d.%d.%d", BrotliDecoderVersion() >> 24, (BrotliDecoderVersion() >> 12) & 0xFFF, BrotliDecoderVersion() & 0xFFF); #endif /* LZ4 */ #if LZ4_VERSION_NUMBER >= 10703 - g_string_append_printf(str, ", with LZ4 %s", LZ4_versionString()); + with_feature(l, "LZ4 %s", LZ4_versionString()); #endif /* LZ4_VERSION_NUMBER */ /* Zstandard */ #if ZSTD_VERSION_NUMBER >= 10300 - g_string_append_printf(str, ", with Zstandard %s", ZSTD_versionString()); + with_feature(l, "Zstandard %s", ZSTD_versionString()); #endif /* ZSTD_VERSION_NUMBER */ /* libsmi */ #ifdef HAVE_SMI_VERSION_STRING - g_string_append_printf(str, ", with libsmi %s", smi_version_string); + with_feature(l, "libsmi %s", smi_version_string); #endif /* HAVE_SMI_VERSION_STRING */ } diff --git a/epan/epan.h b/epan/epan.h index 7dea46d9c7..7ad546e811 100644 --- a/epan/epan.h +++ b/epan/epan.h @@ -12,6 +12,7 @@ #include +#include #include #include #include @@ -273,14 +274,14 @@ epan_custom_set(epan_dissect_t *edt, GSList *ids, gint occurrence, */ WS_DLL_PUBLIC void -epan_get_compiled_version_info(GString *str); +epan_gather_compile_info(feature_list l); /** * Get runtime information for libraries used by libwireshark. */ WS_DLL_PUBLIC void -epan_get_runtime_version_info(GString *str); +epan_gather_runtime_info(feature_list l); #ifdef __cplusplus } diff --git a/fuzz/fuzzshark.c b/fuzz/fuzzshark.c index 2c5a754ea4..145bec0874 100644 --- a/fuzz/fuzzshark.c +++ b/fuzz/fuzzshark.c @@ -263,8 +263,8 @@ fuzz_init(int argc _U_, char **argv) } /* Initialize the version information. */ - ws_init_version_info("OSS Fuzzshark (Wireshark)", NULL, - epan_get_compiled_version_info, epan_get_runtime_version_info); + ws_init_version_info("OSS Fuzzshark", + epan_gather_compile_info, epan_gather_runtime_info); init_report_message("fuzzshark", &fuzzshark_report_routines); diff --git a/mergecap.c b/mergecap.c index 0a05469678..58e6de23c7 100644 --- a/mergecap.c +++ b/mergecap.c @@ -230,7 +230,7 @@ main(int argc, char *argv[]) #endif /* _WIN32 */ /* Initialize the version information. */ - ws_init_version_info("Mergecap (Wireshark)", NULL, NULL, NULL); + ws_init_version_info("Mergecap", NULL, NULL); /* * Get credential information for later use. diff --git a/packaging/debian/libwireshark0.symbols b/packaging/debian/libwireshark0.symbols index c518ce6a7a..e3ee338a07 100644 --- a/packaging/debian/libwireshark0.symbols +++ b/packaging/debian/libwireshark0.symbols @@ -578,11 +578,11 @@ libwireshark.so.0 libwireshark0 #MINVER# epan_dissect_run@Base 1.9.1 epan_dissect_run_with_taps@Base 1.9.1 epan_free@Base 1.12.0~rc1 - epan_get_compiled_version_info@Base 1.9.1 + epan_gather_compile_info@Base 3.7.0 + epan_gather_runtime_info@Base 3.7.0 epan_get_interface_description@Base 2.3.0 epan_get_interface_name@Base 1.99.2 epan_get_modified_block@Base 3.5.0 - epan_get_runtime_version_info@Base 1.9.1 epan_get_version@Base 1.9.1 epan_get_version_number@Base 2.5.0 epan_init@Base 2.9.0 diff --git a/packaging/debian/libwsutil0.symbols b/packaging/debian/libwsutil0.symbols index 018b0384fa..65acc05c1c 100644 --- a/packaging/debian/libwsutil0.symbols +++ b/packaging/debian/libwsutil0.symbols @@ -77,6 +77,7 @@ libwsutil.so.0 libwsutil0 #MINVER# find_codec@Base 3.1.0 find_last_pathname_separator@Base 1.12.0~rc1 format_size_wmem@Base 3.5.0 + free_features@Base 3.7.0 free_progdirs@Base 2.3.0 get_basename@Base 1.12.0~rc1 get_copyright_info@Base 1.99.0 @@ -212,6 +213,7 @@ libwsutil.so.0 libwsutil0 #MINVER# sober128_add_entropy@Base 1.99.0 sober128_read@Base 1.99.0 sober128_start@Base 1.99.0 + sort_features@Base 3.7.0 started_with_special_privs@Base 1.10.0 test_for_directory@Base 1.12.0~rc1 test_for_fifo@Base 1.12.0~rc1 @@ -226,6 +228,8 @@ libwsutil.so.0 libwsutil0 #MINVER# unix_epoch_to_nstime@Base 3.5.0 update_adler32@Base 1.12.0~rc1 update_crc10_by_bytes@Base 1.10.0 + with_feature@Base 3.7.0 + without_feature@Base 3.7.0 wmem_alloc0@Base 3.5.0 wmem_alloc@Base 3.5.0 wmem_allocator_new@Base 3.5.0 diff --git a/rawshark.c b/rawshark.c index 50e328e907..cf6ea51efc 100644 --- a/rawshark.c +++ b/rawshark.c @@ -449,8 +449,8 @@ main(int argc, char *argv[]) ws_log_parse_args(&argc, argv, vcmdarg_err, INVALID_OPTION); /* Initialize the version information. */ - ws_init_version_info("Rawshark (Wireshark)", NULL, - epan_get_compiled_version_info, + ws_init_version_info("Rawshark", + epan_gather_compile_info, NULL); #ifdef _WIN32 diff --git a/reordercap.c b/reordercap.c index 256a1dd326..4598e0e222 100644 --- a/reordercap.c +++ b/reordercap.c @@ -207,7 +207,7 @@ main(int argc, char *argv[]) ws_log_parse_args(&argc, argv, vcmdarg_err, INVALID_OPTION); /* Initialize the version information. */ - ws_init_version_info("Reordercap (Wireshark)", NULL, NULL, NULL); + ws_init_version_info("Reordercap", NULL, NULL); /* * Get credential information for later use. diff --git a/sharkd.c b/sharkd.c index a0298d2120..371933f466 100644 --- a/sharkd.c +++ b/sharkd.c @@ -143,9 +143,9 @@ main(int argc, char *argv[]) } /* Initialize the version information. */ - ws_init_version_info("Sharkd (Wireshark)", NULL, - epan_get_compiled_version_info, - epan_get_runtime_version_info); + ws_init_version_info("Sharkd", + epan_gather_compile_info, + epan_gather_runtime_info); if (sharkd_init(argc, argv) < 0) { diff --git a/text2pcap.c b/text2pcap.c index 63ea93211c..55152ec354 100644 --- a/text2pcap.c +++ b/text2pcap.c @@ -377,7 +377,7 @@ parse_options(int argc, char *argv[], text_import_info_t * const info, wtap_dump info->payload = "data"; /* Initialize the version information. */ - ws_init_version_info("Text2pcap (Wireshark)", NULL, NULL, NULL); + ws_init_version_info("Text2pcap", NULL, NULL); /* Scan CLI parameters */ while ((c = ws_getopt_long(argc, argv, "hqab:De:E:F:i:l:m:nN:o:u:P:r:s:S:t:T:v4:6:", long_options, NULL)) != -1) { diff --git a/tfshark.c b/tfshark.c index 1d8a6c8a2f..245c5ea8cc 100644 --- a/tfshark.c +++ b/tfshark.c @@ -264,13 +264,6 @@ print_current_user(void) } } -static void -get_tfshark_runtime_version_info(GString *str) -{ - /* stuff used by libwireshark */ - epan_get_runtime_version_info(str); -} - int main(int argc, char *argv[]) { @@ -377,10 +370,9 @@ main(int argc, char *argv[]) initialize_funnel_ops(); /* Initialize the version information. */ - ws_init_version_info("TFShark (Wireshark)", NULL, - epan_get_compiled_version_info, - get_tfshark_runtime_version_info); - + ws_init_version_info("TFShark", + epan_gather_compile_info, + epan_gather_runtime_info); /* * In order to have the -X opts assigned before the wslua machine starts * we need to call getopts before epan_init() gets called. diff --git a/tshark.c b/tshark.c index 6ab5b449c8..3971fac16f 100644 --- a/tshark.c +++ b/tshark.c @@ -587,23 +587,22 @@ print_current_user(void) } static void -get_tshark_compiled_version_info(GString *str) +gather_tshark_compile_info(feature_list l) { /* Capture libraries */ - get_compiled_caplibs_version(str); + gather_caplibs_compile_info(l); + epan_gather_compile_info(l); } static void -get_tshark_runtime_version_info(GString *str) +gather_tshark_runtime_info(feature_list l) { #ifdef HAVE_LIBPCAP - /* Capture libraries */ - g_string_append(str, ", "); - get_runtime_caplibs_version(str); + gather_caplibs_runtime_info(l); #endif /* stuff used by libwireshark */ - epan_get_runtime_version_info(str); + epan_gather_runtime_info(l); } static void @@ -866,9 +865,8 @@ main(int argc, char *argv[]) #endif /* _WIN32 */ /* Initialize the version information. */ - ws_init_version_info("TShark (Wireshark)", get_tshark_compiled_version_info, - epan_get_compiled_version_info, - get_tshark_runtime_version_info); + ws_init_version_info("TShark", + gather_tshark_compile_info, gather_tshark_runtime_info); /* Fail sometimes. Useful for testing fuzz scripts. */ /* if (g_random_int_range(0, 100) < 5) abort(); */ diff --git a/ui/qt/about_dialog.cpp b/ui/qt/about_dialog.cpp index 816ac6a62f..002e4d4ba0 100644 --- a/ui/qt/about_dialog.cpp +++ b/ui/qt/about_dialog.cpp @@ -442,9 +442,8 @@ void AboutDialog::updateWiresharkText() { QString vcs_version_info_str = get_ws_vcs_version_info(); QString copyright_info_str = get_copyright_info(); - QString comp_info_str = gstring_free_to_qbytearray(get_compiled_version_info(get_wireshark_qt_compiled_info, - get_gui_compiled_info)); - QString runtime_info_str = gstring_free_to_qbytearray(get_runtime_version_info(get_wireshark_runtime_info)); + QString comp_info_str = gstring_free_to_qbytearray(get_compiled_version_info(gather_wireshark_qt_compiled_info)); + QString runtime_info_str = gstring_free_to_qbytearray(get_runtime_version_info(gather_wireshark_runtime_info)); QString message = ColorUtils::themeLinkStyle(); @@ -462,9 +461,8 @@ void AboutDialog::updateWiresharkText() /* Save the info for the clipboard copy */ clipboardInfo = ""; clipboardInfo += vcs_version_info_str + "\n\n"; - clipboardInfo += gstring_free_to_qbytearray(get_compiled_version_info(get_wireshark_qt_compiled_info, - get_gui_compiled_info)) + "\n"; - clipboardInfo += gstring_free_to_qbytearray(get_runtime_version_info(get_wireshark_runtime_info)); + clipboardInfo += gstring_free_to_qbytearray(get_compiled_version_info(gather_wireshark_qt_compiled_info)) + "\n"; + clipboardInfo += gstring_free_to_qbytearray(get_runtime_version_info(gather_wireshark_runtime_info)); } void AboutDialog::on_copyToClipboard_clicked() diff --git a/ui/qt/main.cpp b/ui/qt/main.cpp index 2f995cc18e..103b44eadc 100644 --- a/ui/qt/main.cpp +++ b/ui/qt/main.cpp @@ -207,90 +207,72 @@ wireshark_cmdarg_err_cont(const char *fmt, va_list ap) fprintf(stderr, "\n"); } -// xxx based from ../gtk/main.c:get_gtk_compiled_info void -get_wireshark_qt_compiled_info(GString *str) +gather_wireshark_qt_compiled_info(feature_list l) { - g_string_append(str, "with "); - g_string_append_printf(str, #ifdef QT_VERSION - "Qt %s", QT_VERSION_STR); + with_feature(l, "Qt %s", QT_VERSION_STR); #else - "Qt (version unknown)"); + with_feature(l, "Qt (version unknown)"); #endif - - /* Capture libraries */ - g_string_append(str, ", "); - get_compiled_caplibs_version(str); -} - -// xxx copied from ../gtk/main.c -void -get_gui_compiled_info(GString *str) -{ - epan_get_compiled_version_info(str); - - g_string_append(str, ", "); + gather_caplibs_compile_info(l); + epan_gather_compile_info(l); #ifdef QT_MULTIMEDIA_LIB - g_string_append(str, "with QtMultimedia"); + with_feature(l, "QtMultimedia"); #else - g_string_append(str, "without QtMultimedia"); + without_feature(l, "QtMultimedia"); #endif - g_string_append(str, ", "); const char *update_info = software_update_info(); if (update_info) { - g_string_append_printf(str, "with automatic updates using %s", update_info); + with_feature(l, "automatic updates using %s", update_info); } else { - g_string_append_printf(str, "without automatic updates"); + without_feature(l, "automatic updates"); } - #ifdef _WIN32 - g_string_append(str, ", "); #ifdef HAVE_AIRPCAP - get_compiled_airpcap_version(str); + with_feature(l, "AirPcap"); #else - g_string_append(str, "without AirPcap"); + without_feature(l, "AirPcap"); #endif #endif /* _WIN32 */ - #ifdef HAVE_SPEEXDSP - g_string_append(str, ", with SpeexDSP (using system library)"); + with_feature(l, "SpeexDSP (using system library)"); #else - g_string_append(str, ", with SpeexDSP (using bundled resampler)"); + with_feature(l, "SpeexDSP (using bundled resampler)"); #endif #ifdef HAVE_MINIZIP - g_string_append(str, ", with Minizip"); + with_feature(l, "Minizip"); #else - g_string_append(str, ", without Minizip"); + without_feature(l, "Minizip"); #endif } -// xxx copied from ../gtk/main.c void -get_wireshark_runtime_info(GString *str) +gather_wireshark_runtime_info(feature_list l) { - g_string_append_printf(str, ", with Qt %s", qVersion()); - + with_feature(l, "Qt %s", qVersion()); #ifdef HAVE_LIBPCAP - /* Capture libraries */ - g_string_append(str, ", "); - get_runtime_caplibs_version(str); + gather_caplibs_runtime_info(l); #endif - - /* stuff used by libwireshark */ - epan_get_runtime_version_info(str); + epan_gather_runtime_info(l); #ifdef HAVE_AIRPCAP - g_string_append(str, ", "); - get_runtime_airpcap_version(str); + /* See if the DLL has been loaded successfully. Bail if it hasn't */ + if (AirpcapLoaded == FALSE) { + without_feature(l, "AirPcap"); + } + else { + g_PAirpcapGetVersion(&vmaj, &vmin, &vrev, &build); + with_feature(l, "AirPcap %d.%d.%d build %d", vmaj, vmin, vrev, build); + } #endif if (wsApp) { // Display information const char *display_mode = ColorUtils::themeIsDark() ? "dark" : "light"; - g_string_append_printf(str, ", with %s display mode", display_mode); + with_feature(l, "%s display mode", display_mode); int hidpi_count = 0; foreach (QScreen *screen, wsApp->screens()) { @@ -299,11 +281,11 @@ get_wireshark_runtime_info(GString *str) } } if (hidpi_count == wsApp->screens().count()) { - g_string_append(str, ", with HiDPI"); + with_feature(l, "HiDPI"); } else if (hidpi_count) { - g_string_append(str, ", with mixed DPI"); + with_feature(l, "mixed DPI"); } else { - g_string_append(str, ", without HiDPI"); + without_feature(l, "HiDPI"); } } } @@ -638,8 +620,8 @@ int main(int argc, char *qt_argv[]) #endif /* _WIN32 */ /* Get the compile-time version information string */ - ws_init_version_info("Wireshark", get_wireshark_qt_compiled_info, - get_gui_compiled_info, get_wireshark_runtime_info); + ws_init_version_info("Wireshark", gather_wireshark_qt_compiled_info, + gather_wireshark_runtime_info); /* Create the user profiles directory */ if (create_profiles_dir(&rf_path) == -1) { diff --git a/ui/qt/wireshark_application.h b/ui/qt/wireshark_application.h index 08421ad8e7..f13c77d91f 100644 --- a/ui/qt/wireshark_application.h +++ b/ui/qt/wireshark_application.h @@ -14,6 +14,8 @@ #include +#include "wsutil/feature_list.h" + #include "epan/register.h" #include "ui/help_url.h" @@ -229,9 +231,8 @@ private slots: extern WiresharkApplication *wsApp; -/** Global compile time version string */ -extern void get_wireshark_qt_compiled_info(GString *str); -extern void get_gui_compiled_info(GString *str); -/** Global runtime version string */ -extern void get_wireshark_runtime_info(GString *str); +/** Global compile time version info */ +extern void gather_wireshark_qt_compiled_info(feature_list l); +/** Global runtime version info */ +extern void gather_wireshark_runtime_info(feature_list l); #endif // WIRESHARK_APPLICATION_H diff --git a/ui/version_info.c b/ui/version_info.c index 9e2c491c77..86732c7e41 100644 --- a/ui/version_info.c +++ b/ui/version_info.c @@ -46,12 +46,12 @@ static char *comp_info; static char *runtime_info; static void get_compiler_info(GString *str); +static void get_mem_info(GString *str); void ws_init_version_info(const char *appname, - void (*prepend_compile_time_info)(GString *), - void (*append_compile_time_info)(GString *), - void (*additional_run_time_info)(GString *)) + gather_feature_func gather_compile, + gather_feature_func gather_runtime) { GString *comp_info_str, *runtime_info_str; @@ -60,15 +60,20 @@ ws_init_version_info(const char *appname, * version - including the VCS version, for a build from * a checkout. */ - appname_with_version = ws_strdup_printf("%s %s", - appname, get_ws_vcs_version_info()); + if (strstr(appname, "Wireshark") != NULL) { + appname_with_version = ws_strdup_printf("%s %s", + appname, get_ws_vcs_version_info()); + } + else { + appname_with_version = ws_strdup_printf("%s (Wireshark) %s", + appname, get_ws_vcs_version_info()); + } /* Get the compile-time version information string */ - comp_info_str = get_compiled_version_info(prepend_compile_time_info, - append_compile_time_info); + comp_info_str = get_compiled_version_info(gather_compile); /* Get the run-time version information string */ - runtime_info_str = get_runtime_version_info(additional_run_time_info); + runtime_info_str = get_runtime_version_info(gather_runtime); comp_info = g_string_free(comp_info_str, FALSE); runtime_info = g_string_free(runtime_info_str, FALSE); @@ -81,10 +86,22 @@ ws_init_version_info(const char *appname, appname_with_version, comp_info, runtime_info); } -const char * -get_appname_and_version(void) +/* + * Take the gathered list of present/absent features (dependencies) + * and add them to the given string. + * Callback function for g_list_foreach() used in + * get_compiled_version_info() and get_runtime_version_info(). + */ +static void +feature_to_gstring(gpointer data, gpointer user_data) { - return appname_with_version; + gchar *feature = (gchar *)data; + GString *str = (GString *)user_data; + if (str->len > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%s %s", + (*feature == '+' ? "with" : "without"), feature + 1); } /* @@ -117,86 +134,69 @@ end_string(GString *str) } } -static const gchar * -get_zlib_compiled_version_info(void) +const char * +get_appname_and_version(void) +{ + return appname_with_version; +} + +static void +get_zlib_feature_info(feature_list l) { #ifdef HAVE_ZLIB #ifdef ZLIB_VERSION - return "with zlib "ZLIB_VERSION; + with_feature(l, "zlib "ZLIB_VERSION); #else - return "with zlib (version unknown)"; + with_feature(l, "zlib (version unknown)"); #endif /* ZLIB_VERSION */ #else - return "without zlib"; + without_feature(l, "zlib"); #endif /* HAVE_ZLIB */ } /* * Get various library compile-time versions, put them in a GString, * and return the GString. - * - * "prepend_info" is called at the start to prepend any additional - * information before the standard library information. - * - * "append_info" is called at the end to append any additional - * information after the standard library information. This is - * required in order to, for example, put Qt information at the - * end of the string, as we don't use Qt in TShark. */ GString * -get_compiled_version_info(void (*prepend_info)(GString *), - void (*append_info)(GString *)) +get_compiled_version_info(gather_feature_func gather_compile) { GString *str; + GList *l = NULL; str = g_string_new("Compiled "); - - if (sizeof(str) == 4) - g_string_append(str, "(32-bit) "); - else - g_string_append(str, "(64-bit) "); + g_string_append_printf(str, "(%d-bit) ", (int)sizeof(str) * 8); /* Compiler info */ g_string_append(str, "using "); get_compiler_info(str); - g_string_append(str, ", "); - if (prepend_info) { - (*prepend_info)(str); - g_string_append(str, ", "); - } - - /* GLIB */ - g_string_append(str, "with "); - g_string_append_printf(str, #ifdef GLIB_MAJOR_VERSION + with_feature(&l, "GLib %d.%d.%d", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION); #else + with_feature(&l, "GLib (version unknown)"); #endif + with_feature(&l, "PCRE2"); + get_zlib_feature_info(&l); - /* PCRE2 */ - g_string_append(str, ", with PCRE2"); - - /* zlib */ - g_string_append_printf(str, ", %s", get_zlib_compiled_version_info()); - - /* Additional application-dependent information */ - if (append_info) - (*append_info)(str); + if (gather_compile != NULL) { + gather_compile(&l); + } + l = g_list_reverse(l); + g_list_foreach(l, feature_to_gstring, str); #ifdef WS_DISABLE_DEBUG g_string_append(str, ", release build"); #endif - #ifdef WS_DISABLE_ASSERT g_string_append(str, ", without assertions"); #endif - g_string_append(str, "."); - end_string(str); + free_features(&l); return str; } @@ -393,7 +393,7 @@ get_compiler_info(GString *str) } static inline void -get_pcre2_runtime_version_info(GString *str) +get_pcre2_runtime_version_info(feature_list l) { /* From pcre2_api(3): * The where argument should point to a buffer that is at least 24 code @@ -407,13 +407,14 @@ get_pcre2_runtime_version_info(GString *str) char *buf_pcre2; size = pcre2_config(PCRE2_CONFIG_VERSION, NULL); - if (size < 0 || size > 255) + if (size < 0 || size > 255) { + without_feature(l, "PCRE2 (error querying)"); return; + } buf_pcre2 = g_malloc(size + 1); pcre2_config(PCRE2_CONFIG_VERSION, buf_pcre2); buf_pcre2[size] = '\0'; - g_string_append(str, ", with PCRE2 "); - g_string_append(str, buf_pcre2); + with_feature(l, "PCRE2 %s", buf_pcre2); g_free(buf_pcre2); } @@ -427,10 +428,11 @@ get_pcre2_runtime_version_info(GString *str) * don't use libcap in TShark. */ GString * -get_runtime_version_info(void (*additional_info)(GString *)) +get_runtime_version_info(gather_feature_func gather_runtime) { GString *str; gchar *lc; + GList *l = NULL; str = g_string_new("Running on "); @@ -442,46 +444,39 @@ get_runtime_version_info(void (*additional_info)(GString *)) /* Get info about installed memory */ get_mem_info(str); - /* GLib */ - g_string_append_printf(str, ", with GLib %u.%u.%u", + with_feature(&l, "GLib %u.%u.%u", glib_major_version, glib_minor_version, glib_micro_version); - - /* PCRE2 */ - get_pcre2_runtime_version_info(str); - - /* zlib */ + get_pcre2_runtime_version_info(&l); #if defined(HAVE_ZLIB) && !defined(_WIN32) - g_string_append_printf(str, ", with zlib %s", zlibVersion()); + with_feature(&l, "zlib %s", zlibVersion()); #endif - - /* Additional application-dependent information */ - if (additional_info) - (*additional_info)(str); - + if (gather_runtime != NULL) { + gather_runtime(&l); + } /* * Display LC_CTYPE as a relevant, portable and sort of representative * locale configuration without being exceedingly verbose and including * the whole shebang of categories using LC_ALL. */ if ((lc = setlocale(LC_CTYPE, NULL)) != NULL) { - g_string_append_printf(str, ", with LC_TYPE=%s", lc); + with_feature(&l, "LC_TYPE=%s", lc); } - - /* plugins */ #ifdef HAVE_PLUGINS if (g_module_supported()) { - g_string_append_printf(str, ", binary plugins supported (%d loaded)", plugins_get_count()); + with_feature(&l, "binary plugins supported (%d loaded)", plugins_get_count()); } else { - g_string_append(str, ", binary plugins not supported by the platform"); + without_feature(&l, "binary plugins (not supported by the platform)"); } #else - g_string_append(str, ", built without support for binary plugins"); + without_feature(&l, "binary plugins"); #endif - g_string_append(str, "."); - + l = g_list_reverse(l); + g_list_foreach(l, feature_to_gstring, str); + g_string_append_c(str, '.'); end_string(str); + free_features(&l); return str; } diff --git a/ui/version_info.h b/ui/version_info.h index de4b2337fe..612f457a7c 100644 --- a/ui/version_info.h +++ b/ui/version_info.h @@ -14,6 +14,7 @@ #define __WS_VERSION_INFO_H__ #include +#include #ifdef __cplusplus extern "C" { @@ -27,26 +28,20 @@ extern "C" { * if possible. * * "appname" is a string that appears at the beginning of the information; - * it should include the application name, followed by "(Wireshark)" if + * it should be the application name. "(Wireshark)" will be added if * the program isn't Wireshark. * - * "prepend_compile_time_info" is called at the start to prepend any - * additional build information before the standard library information. + * "gather_compile" is called (if non-null) to add any additional build-time + * information. * - * "append_compile_time_info" is called at the end to append any additional - * build information after the standard library information. This is - * required in order to, for example, put Qt information at the - * end of the string, as we don't use Qt in TShark. - * - * "additional_info" is called at the end to append any additional + * "gather_runtime" is called (if non-null) to add any additional * run-time information; this is required in order to, for example, - * put the libcap information at the end of the string, as we currently + * put the libcap information into the string, as we currently * don't use libcap in TShark. */ void ws_init_version_info(const char *appname, - void (*prepend_compile_time_info)(GString *), - void (*append_compile_time_info)(GString *), - void (*additional_run_time_info)(GString *)); + gather_feature_func gather_compile, + gather_feature_func gather_runtime); /* * Get a string giving the application name, as provided to @@ -59,27 +54,21 @@ const char *get_appname_and_version(void); * Get various library compile-time versions, put them in a GString, * and return the GString. * - * "prepend_info" is called at the start to prepend any additional - * information before the standard library information. - * - * "append_info" is called at the end to append any additional - * information after the standard library information. This is - * required in order to, for example, put Qt information at the - * end of the string, as we don't use Qt in TShark. + * "gather_compile" is called (if non-null) to add any additional build-time + * information. */ -GString *get_compiled_version_info(void (*prepend_info)(GString *), - void (*append_info)(GString *)); +GString *get_compiled_version_info(gather_feature_func gather_compile); /* * Get various library run-time versions, and the OS version, put them in * a GString, and return the GString. * - * "additional_info" is called at the end to append any additional - * information; this is required in order to, for example, put the - * libcap information at the end of the string, as we currently + * "gather_runtime" is called (if non-null) to add any additional + * run-time information; this is required in order to, for example, + * put the libcap information into the string, as we currently * don't use libcap in TShark. */ -GString *get_runtime_version_info(void (*additional_info)(GString *)); +GString *get_runtime_version_info(gather_feature_func gather_runtime); /* * Return a version number string for Wireshark, including, for builds diff --git a/wsutil/CMakeLists.txt b/wsutil/CMakeLists.txt index 3ad9950620..a15d44d9bd 100644 --- a/wsutil/CMakeLists.txt +++ b/wsutil/CMakeLists.txt @@ -39,6 +39,7 @@ set(WSUTIL_PUBLIC_HEADERS eax.h epochs.h exported_pdu_tlvs.h + feature_list.h filesystem.h g711.h inet_addr.h @@ -106,6 +107,7 @@ set(WSUTIL_COMMON_FILES curve25519.c dot11decrypt_wep.c eax.c + feature_list.c filesystem.c g711.c inet_addr.c diff --git a/wsutil/feature_list.c b/wsutil/feature_list.c new file mode 100644 index 0000000000..32ee3ba9e2 --- /dev/null +++ b/wsutil/feature_list.c @@ -0,0 +1,54 @@ +/* feature_list.c + * Routines for gathering and handling lists of present/absent features + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "config.h" + +#include + +void +with_feature(feature_list l, const char *fmt, ...) +{ + va_list arg; + GString *msg = g_string_new("+"); + va_start(arg, fmt); + g_string_append_vprintf(msg, fmt, arg); + va_end(arg); + *l = g_list_prepend(*l, g_string_free(msg, FALSE)); +} + +void +without_feature(feature_list l, const char *fmt, ...) +{ + va_list arg; + GString *msg = g_string_new("-"); + va_start(arg, fmt); + g_string_append_vprintf(msg, fmt, arg); + va_end(arg); + *l = g_list_prepend(*l, g_string_free(msg, FALSE)); +} + +static gint +feature_sort_alpha(gconstpointer a, gconstpointer b) +{ + return strcasecmp((gchar *)a + 1, (gchar *)b + 1); +} + +void +sort_features(feature_list l) +{ + *l = g_list_sort(*l, feature_sort_alpha); +} + +void +free_features(feature_list l) +{ + g_list_free_full(*l, g_free); + *l = NULL; +} diff --git a/wsutil/feature_list.h b/wsutil/feature_list.h new file mode 100644 index 0000000000..9cc60945e9 --- /dev/null +++ b/wsutil/feature_list.h @@ -0,0 +1,77 @@ +/** @file + * Declarations of routines for gathering and handling lists of + * present/absent features (usually actually dependencies) + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef __WSUTIL_FEATURE_LIST_H__ +#define __WSUTIL_FEATURE_LIST_H__ + +#include +#include "ws_symbol_export.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Handle to a list of features/dependencies. + * Semi-opaque. Functions which gather the list of features + * will be passed one of these to use with + * `with_feature()`/`without_feature()` (below). + */ +typedef GList **feature_list; + +/* + * The format of entries in a feature_list is a gchar* starting with a + * '+' or '-' character indicating if the feature is respectively + * present or absent, followed by the unchanged feature description. + * This allows the insert order of features to be preserved, + * while still preserving the present/absent status in a simple way. + */ + + +/* + * Pointer to a function which gathers a list of features. + */ +typedef void(*gather_feature_func)(feature_list l); + +/* + * Add an indicator to the given feature_list that the named + * feature is present. + */ +WS_DLL_PUBLIC +void with_feature(feature_list l, const char *fmt, ...) G_GNUC_PRINTF(2,3); + +/* + * Add an indicator to the given feature_list that the named + * feature is absent. + */ +WS_DLL_PUBLIC +void without_feature(feature_list l, const char *fmt, ...) G_GNUC_PRINTF(2,3); + +/* + * Sort the given feature list, alphabetically by feature name. + * (The leading '+' or '-' is not factored into the sort.) + * Currently unused. + */ +WS_DLL_PUBLIC +void sort_features(feature_list l); + +/* + * Free the memory used by the feature list, + * and reset its pointer to NULL. + */ +WS_DLL_PUBLIC +void free_features(feature_list l); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __WSUTIL_FEATURE_LIST_H__ */