Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Raybellis gzip v2 #982

Closed
wants to merge 3 commits into from
Closed

Raybellis gzip v2 #982

wants to merge 3 commits into from

Conversation

mcr
Copy link
Member

@mcr mcr commented Dec 19, 2020

This is a rebase of Ray Bellis' gzip interface for pcap.

@mcr mcr requested a review from guyharris December 19, 2020 19:06
fp = stdin;
if (stdin == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"The standard input is not open");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a good test for a safe use of stdin since it could be a fixed address (like on djgpp).
Perhaps if (!stdin || ferror(stdin)) is better.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is djgpp still a build target that matters? (I'm seriously asking: I didn't think so).
I'm happy to do something different here, but I want to make sure that it's really better.
I don't understand what !stdin would do? That's the same as stdin != NULL, isn't it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed based upon suggestion.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is djgpp still a build target that matters?

Not really. But there could be other exotic targets were #define stdin (&__internal_stdin).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On my Solaris 11 VM:

/usr/include/stdio.h includes

#include <iso/stdio_iso.h>

and /usr/include/iso/stdio_ios.h includes

#if defined(__STDC__)
extern __FILE	__iob[_NFILE];
#define	stdin	(&__iob[0])
#define	stdout	(&__iob[1])
#define	stderr	(&__iob[2])
#else
extern __FILE	_iob[_NFILE];
#define	stdin	(&_iob[0])
#define	stdout	(&_iob[1])
#define	stderr	(&_iob[2])
#endif	/* __STDC__ */

That goes all the way back to System N, for some Roman-numeral version of N, so other commercial UN*Xes may do that, too.

(GNU libc doesn't, so few Linux distributions do that; as far as I know, Chris Torek's stdio code doesn't, either, so I don't think any of the BSD-favored UN*Xes, including macOS, do that.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what !stdin would do? That's the same as stdin != NULL, isn't it?

Yes.


if (strcmp(fname, "-") == 0) {
fp = stdout;
if (stdout == NULL) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also updated.

@@ -4643,7 +4658,7 @@ else
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@guyharris is this an error, or something we should be doing?
This seems to have jumped into this patch, and I don't know why.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might just be a case of different versions of autoconf generating different code.

@@ -74,7 +74,7 @@ main(int argc, char **argv)
struct bpf_program fcode;
char ebuf[PCAP_ERRBUF_SIZE];
pcap_if_t *devlist;
int selectable_fd;
int selectable_fd = -1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is presumably done to work around compilers that don't figure out that if neither doselect nor dopoll are set, selectable_fd isn't used.

It belongs in a separate change (which shouldn't require any review, so you might as well just commit it).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed on main in fbb5e9e

@@ -821,23 +805,19 @@ pcap_dump_open(pcap_t *p, const char *fname)
"A null pointer was supplied as the file name");
return NULL;
}
if (fname[0] == '-' && fname[1] == '\0') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If all plugins are supposed to treat "-" as meaning "write to the standard output", pcap_setup_dump() should probably do so as well, and report that a write error occurred to "(the) standard output" rather than to "-", as the code currently does.

@@ -794,6 +777,7 @@ pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname)
pcap_dumper_t *
pcap_dump_open(pcap_t *p, const char *fname)
{
const pcap_ioplugin_t *plugin = pcap_ioplugin_init(getenv("PCAP_IOPLUGIN_WRITE"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Presumably your other pull request will eventually allow a program using libpcap to choose to use different I/O routines, so that, for example, a program could provide a command-line flag, or a GUI checkbox, or something such as that to do compressed output, rather than requiring the user to set an environment variable.

@guyharris
Copy link
Member

The use of space indentation vs. tab indentation isn't consistent.

@guyharris
Copy link
Member

@mcr: Speaking of I/O plugins, would that be something that could be used to do asynchronous I/O, especially when writing a capture file? I think you have some ideas about doing async I/O when writing.

#include "ftmacros.h"

#ifdef _WIN32
#include <pcap-stdinc.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That file no longer exists; to quote the message in the commit that removed it:

commit 787f37eeffdc3c37beeca8357d667ef35880c62b
Author: Guy Harris <gharris@sonic.net>
Date:   Tue Sep 5 13:51:37 2017 -0700
    
    Get rid of pcap-stdinc.h.
    
    On Windows, in each file, include whatever that particular file needs,
    just as we do on UN*X and MS-DOS.

@guyharris
Copy link
Member

I presume there's no guarantee that, for an arbitrary plugin, there will be a FILE * corresponding to the input or output stream - or that, even if there is, it will contain the full state of the stream, given that the compression/decompression code might require its own state.

In addition, I'm not sure how control gets handed to the plugin when the sf-pcap.c code attempts to read from or write to the file - or how this handles reading from pcapng files at all (we don't yet support writing pcapng files, so that's not an issue, yet).

Thus, on the read side, we might want to:

  • add a flag to a struct pcap to indicate whether it's for a live capture or a savefile;
  • put some members of struct pcap into a union, with one element of the union being a structure for live captures and another one being a structure for savefiles;
  • put the rfile member into the union for savefiles, and change it to be a void *;
  • have pcap_file() return NULL for a live capture and return the rfile member, cast to FILE * for a savefile;
  • deprecate pcap_file(), as, in the general case, all we can guarantee is that it'll return NULL for a live capture and something non-NULL, but not guaranteed to be usable with standard I/O routines, for a savefile;
  • add pcap_is_savefile(), which returns 0 for live captures and 1 for savefiles (meaning "return the "this is a savefile" flag mentioned above;
  • have read plugins have a read routine as well as an open-for-reading routine, and write plugins have a write routine as well as an open-for-writing routine, with the read and write routines taking fread() and fwrite()-style arguments, but with the void * passed, rather than a FILE *, as the handle argument, and with the stdio read and write routines being tiny wrappers around fread() and fwrite();
  • have a pointer to the read routine, and a pointer to the handle returned by the open-for-reading routine, be members of the savefile structure mentioned above;
  • have the sf-pcap.c and sf-pcapng.c code call the read routine, handing it the pointer to the handle, whenever they nee to read data from the savefile.

@guyharris
Copy link
Member

It looks as if his code depended on the standard I/O routines supporting the caller being able to supply I/O methods to use on the FILE *; that works with GNU libc and with BSD-flavored libc's, but not with all UN*Xes and not on Windows.

I guess we could do step 1, using a FILE *, and then later redo it with a more general mechanism that allows arbitrary handles to be associated with the pcap_t; that would allow, for example, an asynchronous I/O backend to be provided, but it'd mean that existing plugins would have to be changed.

@guyharris
Copy link
Member

This also needs CMake changes and a cmakeconfig.h.in file.

@guyharris
Copy link
Member

Thus, on the read side, we might want to:

Unfortunately, there's no data structure on the write side, so we're stuck, for now, with relying on the standard I/O library allowing write routines to be added, unless we make a pcap_dumper_t not be a FILE *, which might break some code using libpcap that "knows" that it's a FILE *.

We should provide new writing routines that don't work that way.

@mcr
Copy link
Member Author

mcr commented Dec 29, 2020

@mcr: Speaking of I/O plugins, would that be something that could be used to do asynchronous I/O, especially when writing a capture file? I think you have some ideas about doing async I/O when writing.

Maybe. But, as currently structured in libpcap, it would require making a copy of the buffer.
I have some ideas and some code from a failed project earlier in 2020 on doing it without a copy.
It will only work if pcap asks the kernel for rather big ring size, but on machines that want to capture everything, that seems a reasonable thing to do.

@mcr
Copy link
Member Author

mcr commented Dec 29, 2020

fxlb pushed a commit to fxlb/libpcap that referenced this pull request Jan 1, 2021
@infrastation infrastation deleted the raybellis-gzip-v2 branch November 14, 2021 16:42
@infrastation
Copy link
Member

These changes are a strict subset of pull request #914.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants