--- Begin Message ---
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.
 * 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 

        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

Reply via email to