[tcpdump-workers] Re: Dropping support in tcpdump for older versions of libpcap?

2024-05-19 Thread Guy Harris
On Apr 12, 2024, at 6:49 PM, Guy Harris  wrote:

> Is there any reason not to require libpcap 1.0 or later?  If there is, is 
> there any reason not to require libpcap 0.7 or later?

OK, support removed, in the main branch. for libpcaps with only pre-1.0 APIs.  
The 4.99 branch still supports them, although I don't know whether we've tested 
all the way back to libpcap 0.4 (the last LBL release).

___
tcpdump-workers mailing list -- tcpdump-workers@lists.tcpdump.org
To unsubscribe send an email to tcpdump-workers-le...@lists.tcpdump.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s


[tcpdump-workers] Re: Dropping support in tcpdump for older versions of libpcap?

2024-05-05 Thread Francois-Xavier Le Bail via tcpdump-workers
--- Begin Message ---
On 25/04/2024 12:25, Denis Ovsienko wrote:
> On Fri, 19 Apr 2024 11:18:47 -0700
> Guy Harris  wrote:
> 
>> On Apr 19, 2024, at 5:49 AM, Denis Ovsienko 
>> wrote:
>>
>>> On Fri, 12 Apr 2024 18:49:05 -0700
>>> Guy Harris  wrote:  
>>
>>  ...
>>
>>> Since tcpdump is the reference implementation of a program that uses
>>> libpcap, it may be a good occasion to improve the solution space
>>> such that other software can copy something that works well in
>>> tcpdump.  It is not entirely obvious the LIBPCAP_HAVE_PCAP_
>>> macros would be worth the burden of maintenance, but the version
>>> macros should be a straightforward improvement, something such as:
>>>
>>> #define PCAP_VERSION_MAJOR 1
>>> #define PCAP_VERSION_MINOR 11
>>> #define PCAP_VERSION_PATCHLEVEL 0
>>> #define PCAP_VERSION_AT_LEAST(a, b, c) ...
>>>
>>> (The GCC and Clang version checks in compiler-tests.h would be
>>> examples of a good macro structure; Sun C, XL C and HP C version
>>> checks look unwieldy and error-prone).  
>>
>> Presumably meaning that we should export version information in the
>> way GCC and Clang do, rather than in the ways that Sun/Oracle C, XL C
>> and HP C do, the latter being why we have to go through all that
>> extra pain (they provide a single #define with the version number
>> components packed in it - or two different defines in different
>> versions as XL C does - rather than separate #defines for major and
>> minor versions, as GCC and Clang do).
> 
> On a second thought, the best way to describe the desired result would
> be that from the library users' point of view the version macros should
> be easy to use correctly and difficult to use incorrectly.  This would
> justify some inconvenience in the library code, if necessary.
> 
> An advantage of correctly sized BCD versions is that two packed integer
> values compare in a straightforward way, so every end user does not
> have to remember how to compare two version triplets correctly.  A
> disadvantage of BCD versions is the need to unpack them if one needs
> individual components.
> 
> Perhaps the best balance would be in defining the individual version
> components as individual macros, and defining one-way "make this a BCD"
> and "make the current libpcap version a BCD" macros.
> 
> For example, instead of
> 
> // require libpcap >= 1.10.2
> PCAP_VERSION_MAJOR > 1 ||
> (PCAP_VERSION_MAJOR == 1 && PCAP_VERSION_MINOR > 10) ||
> (PCAP_VERSION_MAJOR == 1 && PCAP_VERSION_MINOR == 10 &&
> PCAP_VERSION_PATCH >= 2)
> 
> the users could use the following:
> 
> // require libpcap >= 1.10.2
> PCAP_VERSION_BCD_CURRENT >= PCAP_VERSION_BCD(1, 10, 2)
> 
> (where the exact number of bits allocated to each version component and
> the definitions of PCAP_VERSION_BCD_CURRENT and PCAP_VERSION_BCD() are
> an internal detail so long as the same values compare the same in
> different versions of libpcap)
> 
>>> There could be a run-time check as well:
>>>
>>> extern int pcap_version_at_least (unsigned char major, unsigned char
>>> minor, unsigned char patchlevel);  
>>
>> So how would that be used?
>>
>> If a program is dynamically linked with libpcap, and includes calls
>> to routines that were added in libpcap 1.12 or later, if you try to
>> run it with libpcap 1.11, the run-time linker will fail to load it,
>> as some symbols requested by the executable won't be present in the
>> library. The only OS on which this can be made to work is macOS, with
>> its weak linking mechanism:
> 
> [...]
> 
>> But *all* of those require either run-time checks for a particular OS
>> version in macOS, in cases where you're using the libpcap that comes
>> with macOS, or require loading the library at run time, finding
>> particular routines at run time, and checking at run time whether the
>> routine was found.
> 
> Thank you for the overview of weak linking means.  I suppose it would be
> best to keep out of this space to keep the task relatively manageable.
> The only use case for the C function I currently see is the
> command-line version tester.
> 
>>> The latter could be available via a build helper binary, such as
>>> (using the binary operators from test(1) and version-aware
>>> comparison):
>>>
>>> pcap-version -ge 1 # same as 1 0 0
>>> pcap-version -ge 1 10 # same as 1 10 0
>>> pcap-version -ne 1 10 4
>>> pcap-version -eq 1 10 4
>>> pcap-version -ge 1 9 1 && pcap-version -le 1 9 3  
>>
>> So would this be used in a Makefile/configure
>> script/CMakeFile.txt/etc. to check whether the libpcap on the system
>> is sufficiently recent to include the routines your program needs,
>> and fail if it isn't?
> 
> Yes (as the tcpdump dependency would be).  And not just the routines,
> but their behaviour, as some software could require.
> 
 Is there any reason not to require libpcap 1.0 or later?  If there
 is, is there any reason not to require libpcap 0.7 or later?  
>>>
>>> Such use cases may exist, but I am not aware of any.  
>>
>> So my inclination would be 

[tcpdump-workers] Re: Dropping support in tcpdump for older versions of libpcap?

2024-04-25 Thread Denis Ovsienko
On Fri, 19 Apr 2024 11:18:47 -0700
Guy Harris  wrote:

> On Apr 19, 2024, at 5:49 AM, Denis Ovsienko 
> wrote:
> 
> > On Fri, 12 Apr 2024 18:49:05 -0700
> > Guy Harris  wrote:  
> 
>   ...
> 
> > Since tcpdump is the reference implementation of a program that uses
> > libpcap, it may be a good occasion to improve the solution space
> > such that other software can copy something that works well in
> > tcpdump.  It is not entirely obvious the LIBPCAP_HAVE_PCAP_
> > macros would be worth the burden of maintenance, but the version
> > macros should be a straightforward improvement, something such as:
> > 
> > #define PCAP_VERSION_MAJOR 1
> > #define PCAP_VERSION_MINOR 11
> > #define PCAP_VERSION_PATCHLEVEL 0
> > #define PCAP_VERSION_AT_LEAST(a, b, c) ...
> > 
> > (The GCC and Clang version checks in compiler-tests.h would be
> > examples of a good macro structure; Sun C, XL C and HP C version
> > checks look unwieldy and error-prone).  
> 
> Presumably meaning that we should export version information in the
> way GCC and Clang do, rather than in the ways that Sun/Oracle C, XL C
> and HP C do, the latter being why we have to go through all that
> extra pain (they provide a single #define with the version number
> components packed in it - or two different defines in different
> versions as XL C does - rather than separate #defines for major and
> minor versions, as GCC and Clang do).

On a second thought, the best way to describe the desired result would
be that from the library users' point of view the version macros should
be easy to use correctly and difficult to use incorrectly.  This would
justify some inconvenience in the library code, if necessary.

An advantage of correctly sized BCD versions is that two packed integer
values compare in a straightforward way, so every end user does not
have to remember how to compare two version triplets correctly.  A
disadvantage of BCD versions is the need to unpack them if one needs
individual components.

Perhaps the best balance would be in defining the individual version
components as individual macros, and defining one-way "make this a BCD"
and "make the current libpcap version a BCD" macros.

For example, instead of

// require libpcap >= 1.10.2
PCAP_VERSION_MAJOR > 1 ||
(PCAP_VERSION_MAJOR == 1 && PCAP_VERSION_MINOR > 10) ||
(PCAP_VERSION_MAJOR == 1 && PCAP_VERSION_MINOR == 10 &&
PCAP_VERSION_PATCH >= 2)

the users could use the following:

// require libpcap >= 1.10.2
PCAP_VERSION_BCD_CURRENT >= PCAP_VERSION_BCD(1, 10, 2)

(where the exact number of bits allocated to each version component and
the definitions of PCAP_VERSION_BCD_CURRENT and PCAP_VERSION_BCD() are
an internal detail so long as the same values compare the same in
different versions of libpcap)

> > There could be a run-time check as well:
> > 
> > extern int pcap_version_at_least (unsigned char major, unsigned char
> > minor, unsigned char patchlevel);  
> 
> So how would that be used?
> 
> If a program is dynamically linked with libpcap, and includes calls
> to routines that were added in libpcap 1.12 or later, if you try to
> run it with libpcap 1.11, the run-time linker will fail to load it,
> as some symbols requested by the executable won't be present in the
> library. The only OS on which this can be made to work is macOS, with
> its weak linking mechanism:

[...]

> But *all* of those require either run-time checks for a particular OS
> version in macOS, in cases where you're using the libpcap that comes
> with macOS, or require loading the library at run time, finding
> particular routines at run time, and checking at run time whether the
> routine was found.

Thank you for the overview of weak linking means.  I suppose it would be
best to keep out of this space to keep the task relatively manageable.
The only use case for the C function I currently see is the
command-line version tester.

> > The latter could be available via a build helper binary, such as
> > (using the binary operators from test(1) and version-aware
> > comparison):
> > 
> > pcap-version -ge 1 # same as 1 0 0
> > pcap-version -ge 1 10 # same as 1 10 0
> > pcap-version -ne 1 10 4
> > pcap-version -eq 1 10 4
> > pcap-version -ge 1 9 1 && pcap-version -le 1 9 3  
> 
> So would this be used in a Makefile/configure
> script/CMakeFile.txt/etc. to check whether the libpcap on the system
> is sufficiently recent to include the routines your program needs,
> and fail if it isn't?

Yes (as the tcpdump dependency would be).  And not just the routines,
but their behaviour, as some software could require.

> >> Is there any reason not to require libpcap 1.0 or later?  If there
> >> is, is there any reason not to require libpcap 0.7 or later?  
> > 
> > Such use cases may exist, but I am not aware of any.  
> 
> So my inclination would be to require libpcap 1.0 for tcpdump 5.0.

Let's aim for that then?

-- 
Denis Ovsienko
___
tcpdump-workers mailing list -- 

[tcpdump-workers] Re: Dropping support in tcpdump for older versions of libpcap?

2024-04-19 Thread Guy Harris
On Apr 19, 2024, at 5:49 AM, Denis Ovsienko  wrote:

> On Fri, 12 Apr 2024 18:49:05 -0700
> Guy Harris  wrote:

...

> Since tcpdump is the reference implementation of a program that uses
> libpcap, it may be a good occasion to improve the solution space such
> that other software can copy something that works well in tcpdump.  It
> is not entirely obvious the LIBPCAP_HAVE_PCAP_ macros would be worth
> the burden of maintenance, but the version macros should be a
> straightforward improvement, something such as:
> 
> #define PCAP_VERSION_MAJOR 1
> #define PCAP_VERSION_MINOR 11
> #define PCAP_VERSION_PATCHLEVEL 0
> #define PCAP_VERSION_AT_LEAST(a, b, c) ...
> 
> (The GCC and Clang version checks in compiler-tests.h would be examples
> of a good macro structure; Sun C, XL C and HP C version checks look
> unwieldy and error-prone).

Presumably meaning that we should export version information in the way GCC and 
Clang do, rather than in the ways that Sun/Oracle C, XL C and HP C do, the 
latter being why we have to go through all that extra pain (they provide a 
single #define with the version number components packed in it - or two 
different defines in different versions as XL C does - rather than separate 
#defines for major and minor versions, as GCC and Clang do).

> There could be a run-time check as well:
> 
> extern int pcap_version_at_least (unsigned char major, unsigned char
> minor, unsigned char patchlevel);

So how would that be used?

If a program is dynamically linked with libpcap, and includes calls to routines 
that were added in libpcap 1.12 or later, if you try to run it with libpcap 
1.11, the run-time linker will fail to load it, as some symbols requested by 
the executable won't be present in the library. The only OS on which this can 
be made to work is macOS, with its weak linking mechanism:


https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html

although Apple didn't set up the header file to weakly link symbols until Xcode 
15, and Sonoma was the first release built with Xcode 15, so I think the first 
OS in which you can arrange that the run-time linker not fail would be Sonoma.

With the macOS scheme, there are *run-time* checks for the OS version you're 
running on, although Apple have done rather a crap job of documenting the 
mechanism, especially as used in C and C++ code, where it's done with the 
__builtin_available() pseudo-function, e.g.:

if (__builtin_available(macOS 10.12, *)) {
if (clock_gettime(CLOCK_REALTIME, ) == 0) {
printf("Realtime seconds: %ld\n", value.tv_sec);
}
} else {
// clock_gettime not available!
return 1;
}

as per

https://epir.at/2019/10/30/api-availability-and-target-conditionals/

If you *don't* do the check, you'll get, I think, a run-time failure if you try 
to call a routine that's not available; there's a compiler option, 
-Wunguarded-availability, to produce a warning if you make a call to a routine 
that's not available on the minimum-targeted OS version.

16-bit Windows also supported that - in the same way that macOS used to do it, 
with "the pointer to the function is NULL if a weakly-linked symbol isn't 
available" - but they decided that was too ugly, and got rid of it in 32-bit 
and 64-bit Windows:

https://devblogs.microsoft.com/oldnewthing/20160317-00/?p=93173

Apple probably also decided it was too ugly, and added __builtin_available() 
(and Objective-C @available, and something similar for Swift) as well as the 
compiler warning.

The Microsoft blog post indicates how you do this in Windows, namely by loading 
the library at run time with LoadLibrary() and attempting to get pointers to 
individual routines with GetProcAddress() and testing if the result is NULL; 
the same thing can be done on UN*Xes with dlopen() and dlsym().

But *all* of those require either run-time checks for a particular OS version 
in macOS, in cases where you're using the libpcap that comes with macOS, or 
require loading the library at run time, finding particular routines at run 
time, and checking at run time whether the routine was found.

> The latter could be available via a build helper binary, such as (using
> the binary operators from test(1) and version-aware comparison):
> 
> pcap-version -ge 1 # same as 1 0 0
> pcap-version -ge 1 10 # same as 1 10 0
> pcap-version -ne 1 10 4
> pcap-version -eq 1 10 4
> pcap-version -ge 1 9 1 && pcap-version -le 1 9 3

So would this be used in a Makefile/configure script/CMakeFile.txt/etc. to 
check whether the libpcap on the system is sufficiently recent to include the 
routines your program needs, and fail if it isn't?

>> Is there any reason not to require libpcap 1.0 or later?  If there
>> is, is there any reason not to require libpcap 0.7 or later?
> 
> Such use cases may 

[tcpdump-workers] Re: Dropping support in tcpdump for older versions of libpcap?

2024-04-19 Thread Denis Ovsienko
On Fri, 12 Apr 2024 18:49:05 -0700
Guy Harris  wrote:

> A while ago, tcpdump and its configuration script were modified -
> mainly by Bill Fenner, as I remember - so that it didn't require a
> contemporary version of libpcap, and could be built with older
> versions of libpcap.
> 
> The intent, as I remember, was to allow somebody who was using a
> system that provided both libpcap and tcpdump to build a more recent
> version of tcpdump without having to download and build a newer
> version of libpcap.

Specifically, tcpdump tests for particular functions one-by-one and
then enables specific code paths depending on specific HAVE_PCAP_x
macros.  This covers some use cases, however...

First, the solution is not always convenient: every program that uses
libpcap has to make the build-time checks without much assistance from
libpcap headers: i.e. instead of hinging the conditionals on
hypothetical PCAP_HAVE_PCAP_ macros pre-defined (or not) in a
libpcap header the checks have to be duplicated: tcpdump uses one set
in Autoconf and another in CMake.  Other software has to use its own
means to detect particular functions.  This complicates usage
unnecessarily (as soon as a particular revision of libpcap has
compiled, the fact it implements a particular function is a constant).

Second, the solution space does not always match the problem space:
sometimes the software that uses libpcap needs to know not just that a
particular function is available, but also whether it implements a
particular detail (default behaviour, a feature or a bug/fix).  In
practice this boils down to checking libpcap version.  The latter is not
as trivial as it should be.  I remember one program parsing the [string]
result of pcap_lib_version() because there wasn't a  more appropriate
way to do it.

Since tcpdump is the reference implementation of a program that uses
libpcap, it may be a good occasion to improve the solution space such
that other software can copy something that works well in tcpdump.  It
is not entirely obvious the LIBPCAP_HAVE_PCAP_ macros would be worth
the burden of maintenance, but the version macros should be a
straightforward improvement, something such as:

#define PCAP_VERSION_MAJOR 1
#define PCAP_VERSION_MINOR 11
#define PCAP_VERSION_PATCHLEVEL 0
#define PCAP_VERSION_AT_LEAST(a, b, c) ...

(The GCC and Clang version checks in compiler-tests.h would be examples
of a good macro structure; Sun C, XL C and HP C version checks look
unwieldy and error-prone).

There could be a run-time check as well:

extern int pcap_version_at_least (unsigned char major, unsigned char
minor, unsigned char patchlevel);

The latter could be available via a build helper binary, such as (using
the binary operators from test(1) and version-aware comparison):

pcap-version -ge 1 # same as 1 0 0
pcap-version -ge 1 10 # same as 1 10 0
pcap-version -ne 1 10 4
pcap-version -eq 1 10 4
pcap-version -ge 1 9 1 && pcap-version -le 1 9 3

Obviously, any such improvements would not cover any earlier releases of
libpcap, so would need time to propagate.

Would this make sense?

> Currently, at least in theory, we support versions of libpcap at
> least as old as 0.4, which was the last version released by LBL.
> 
> tcpdump, for example, supports versions of libpcap that don't include
> pcap_findalldevs(); that routine first appeared in libpcap 0.7, which
> was released in 2001, almost 23 years ago.
> 
> It also supports versions of libpcap that don't include pcap_create()
> and pcap_activate(); those first appeared in libpcap 1.0, which was
> released in 2008, almost 16 years ago.
> 
> Is there any reason not to require libpcap 1.0 or later?  If there
> is, is there any reason not to require libpcap 0.7 or later?

Such use cases may exist, but I am not aware of any.

-- 
Denis Ovsienko
___
tcpdump-workers mailing list -- tcpdump-workers@lists.tcpdump.org
To unsubscribe send an email to tcpdump-workers-le...@lists.tcpdump.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s


[tcpdump-workers] Re: Dropping support in tcpdump for older versions of libpcap?

2024-04-14 Thread Michael Richardson

Guy Harris  wrote:
> A while ago, tcpdump and its configuration script were modified -
> mainly by Bill Fenner, as I remember - so that it didn't require a
> contemporary version of libpcap, and could be built with older versions
> of libpcap.

For instance, I think, the FreeBSD that is JUNOS is an example of that.
I don't know if the libpcap is built in some special way to accomodate
Juniper hardware. Maybe.  I don't think it's that old anymore.

> It also supports versions of libpcap that don't include pcap_create()
> and pcap_activate(); those first appeared in libpcap 1.0, which was
> released in 2008, almost 16 years ago.

> Is there any reason not to require libpcap 1.0 or later?  If there is,
> is there any reason not to require libpcap 0.7 or later?

I think libpcap 1.0 or later is good.


--
Michael Richardson. o O ( IPv6 IøT consulting )
   Sandelman Software Works Inc, Ottawa and Worldwide




___
tcpdump-workers mailing list -- tcpdump-workers@lists.tcpdump.org
To unsubscribe send an email to tcpdump-workers-le...@lists.tcpdump.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s