tcpdump mailing list archives
Re: Using libnetdissect in other code, outside tcpdump source tree
From: Guy Harris via tcpdump-workers <tcpdump-workers () lists tcpdump org>
Date: Wed, 12 Aug 2020 13:31:36 -0700
--- Begin Message --- From: Guy Harris <gharris () sonic net>
Date: Wed, 12 Aug 2020 13:31:36 -0700
On Aug 11, 2020, at 4:55 AM, Bill Fenner via tcpdump-workers <tcpdump-workers () lists tcpdump org> wrote:Is there a plan for a public face for libnetdissect?At some point we should probably do that. (Back in the late '90's, I discovered a program called tcpview, which was a Motif(!)-based GUI network analyzer based on modified tcpdump code, so people *have* used tcpdump's dissection code in their own programs.)I've tried teasing it out, and I ended up having to install: funcattrs.h print.h config.h netdissect.h ip.h ip6.h compiler-tests.h status-exit-codes.h in /usr/include/tcpdump/ in order to compile a libnetdissect-using program outside of the tcpdump source tree.netdissect.h is the library's main API-declaration header. print.h also declares functions that I'd consider part of libnetdissect's API; status-exit-codes.h is also part of that API. For funcattrs.h and compiler-tests.h, libpcap installs equivalents in the include/pcap directory, for use by pcap.h. We should probably have an include/libnetdissect directory in which we install netdissect.h and the headers it requires. However, API-declaring headers should *NEVER* require config.h (there was a particularly horrible case with OpenBSD's version of libz, forcing a painful workaround in Wireshark: /* * OK, now this is tricky. * * At least on FreeBSD 3.2, "/usr/include/zlib.h" includes * "/usr/include/zconf.h", which, if HAVE_UNISTD_H is defined, * #defines "z_off_t" to be "off_t", and if HAVE_UNISTD_H is * not defined, #defines "z_off_t" to be "long" if it's not * already #defined. * * In 4.4-Lite-derived systems such as FreeBSD, "off_t" is * "long long int", not "long int", so the definition of "z_off_t" - * and therefore the types of the arguments to routines such as * "gzseek()", as declared, with prototypes, in "zlib.h" - depends * on whether HAVE_UNISTD_H is defined prior to including "zlib.h"! * * It's not defined in the FreeBSD 3.2 "zlib", so if we include "zlib.h" * after defining HAVE_UNISTD_H, we get a misdeclaration of "gzseek()", * and, if we're building with "zlib" support, anything that seeks * on a file may not work. * * Other BSDs may have the same problem, if they haven't done something * such as defining HAVE_UNISTD_H in "zconf.h". * * "config.h" defines HAVE_UNISTD_H, on all systems that have it, and all * 4.4-Lite-derived BSDs have it. Therefore, given that "zlib.h" is included * by "file_wrappers.h", that means that unless we include "zlib.h" before * we include "config.h", we get a misdeclaration of "gzseek()". * * Unfortunately, it's "config.h" that tells us whether we have "zlib" * in the first place, so we don't know whether to include "zlib.h" * until we include "config.h".... * * A similar problem appears to occur with "gztell()", at least on * NetBSD. * * To add further complication, on recent versions, at least, of OpenBSD, * the Makefile for zlib defines HAVE_UNISTD_H. * * So what we do is, on all OSes other than OpenBSD, *undefine* HAVE_UNISTD_H * before including "wtap-int.h" (it handles including "zlib.h" if HAVE_ZLIB * is defined, and it includes "wtap.h", which we include to get the * WTAP_ERR_ZLIB values), and, if we have zlib, make "file_seek()" and * "file_tell()" subroutines, so that the only calls to "gzseek()" and * "gztell()" are in this file, which, by dint of the hackery described * above, manages to correctly declare "gzseek()" and "gztell()". * * On OpenBSD, we forcibly *define* HAVE_UNISTD_H if it's not defined. * * Hopefully, the BSDs will, over time, remove the test for HAVE_UNISTD_H * from "zconf.h", so that "gzseek()" and "gztell()" will be declared * with the correct signature regardless of whether HAVE_UNISTD_H is * defined, so that if they change the signature we don't have to worry * about making sure it's defined or not defined. * * DO NOT, UNDER ANY CIRCUMSTANCES, REMOVE THE FOLLOWING LINES, OR MOVE * THEM AFTER THE INCLUDE OF "wtap-int.h"! Doing so will cause any program * using Wiretap to read capture files to fail miserably on a FreeBSD * 3.2 or 3.3 system - and possibly some other BSD systems - if zlib is * installed. If you *must* have HAVE_UNISTD_H defined before including * "wtap-int.h", put "file_error()" into a file by itself, which can * cheerfully include "wtap.h" and get "gzseek()" misdeclared, and include * just "zlib.h" in this file - *after* undefining HAVE_UNISTD_H. */ Furthermore, the result of config.h may *also* reflect: the compiler being used when it was generated, which means that it may not be appropriate on platforms with multiple compilers that would produce different config.h results, if you're compiling with a compiler other than the one used to generate config.h; the instruction set used as the target when config.h was generated, which means that it may not be appropriate on platforms that support fat binaries, such as macOS (Apple now only support little-endian 64-bit platforms, and that will continue, so it's less of an issue, but it could have been an issue back when you could build a fat binary for 32-bit big-endian PowerPC, 64-bit big-endian PowerPC, 32-bit little-endian x86, and 64-bit little-endian x86); the OS used as the target when config.h was generated, which means that it may be a pain to provide a cross-development SDK (build for small embedded Linux on a non-Linux platform - or possibly either on another Linux platform); so if anything in netdissect.h depends on config.h definitions, we should try to fix that. (This is why the compiler-test.h stuff exists - to depend on the compiler being used when building the program using the library, rather than the compiler being used when configuring and building the library.) That leaves ip.h and ip6.h; I'd have to check to see whether they should be considered part of the API or not.Also, netdissect.h likes to #define min() and max() macros, which makes life interesting when you have, say, a struct with min and max elements.It should probably define ND_MIN() and ND_MAX() instead.
--- End Message ---
_______________________________________________ tcpdump-workers mailing list tcpdump-workers () lists tcpdump org https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers
Current thread:
- Using libnetdissect in other code, outside tcpdump source tree Bill Fenner via tcpdump-workers (Aug 12)
- Re: Using libnetdissect in other code, outside tcpdump source tree Guy Harris via tcpdump-workers (Aug 12)
- Re: Using libnetdissect in other code, outside tcpdump source tree Guy Harris via tcpdump-workers (Aug 12)
- Message not available
- Re: Using libnetdissect in other code, outside tcpdump source tree Bill Fenner via tcpdump-workers (Aug 14)
- Re: Using libnetdissect in other code, outside tcpdump source tree Denis Ovsienko via tcpdump-workers (Aug 24)
- Re: Using libnetdissect in other code, outside tcpdump source tree Guy Harris via tcpdump-workers (Aug 12)