forked from osmocom/wireshark
Don't do pcap heuristics on a pipe.
Instead, just: assume a file with the regular pcap magic number is a regular pcap file, not an unhelpfully-modified-without-changing-the-magic-number format such as one of the (fortunately, short-lived) memory-mapped capture formats or the Nokia format; reject a file with the memory-mapped-capture-finally-changed-the- magic-number magic number, as they then changed the *new* format without changing its magic number; and don't even leave a provision for multiple formats using the "nanosecond pcap" magic number - not even when reading from a file - so we can punish bad behavior (which is what changing the format without changing the magic number is). This should get rid of the last place where, when reading a pcap file from a pipe, the first packet isn't displayed as soon as it arrives. Bug: 14345 Change-Id: I2fcb3354dc84cdd2d8ec749a0db883e56971c4b4 Reviewed-on: https://code.wireshark.org/review/25383 Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
parent
ecced16299
commit
5b9e9b3fe3
|
@ -720,6 +720,7 @@ wtap_open_offline(const char *filename, unsigned int type, int *err, char **err_
|
|||
{
|
||||
int fd;
|
||||
ws_statb64 statb;
|
||||
gboolean ispipe = FALSE;
|
||||
wtap *wth;
|
||||
unsigned int i;
|
||||
gboolean use_stdin = FALSE;
|
||||
|
@ -761,6 +762,7 @@ wtap_open_offline(const char *filename, unsigned int type, int *err, char **err_
|
|||
*err = WTAP_ERR_RANDOM_OPEN_PIPE;
|
||||
return NULL;
|
||||
}
|
||||
ispipe = TRUE;
|
||||
} else if (S_ISDIR(statb.st_mode)) {
|
||||
/*
|
||||
* Return different errors for "this is a directory"
|
||||
|
@ -836,6 +838,7 @@ wtap_open_offline(const char *filename, unsigned int type, int *err, char **err_
|
|||
wth->random_fh = NULL;
|
||||
|
||||
/* initialization */
|
||||
wth->ispipe = ispipe;
|
||||
wth->file_encap = WTAP_ENCAP_UNKNOWN;
|
||||
wth->subtype_sequential_close = NULL;
|
||||
wth->subtype_close = NULL;
|
||||
|
|
|
@ -88,12 +88,8 @@ wtap_open_return_val libpcap_open(wtap *wth, int *err, gchar **err_info)
|
|||
WTAP_FILE_TYPE_SUBTYPE_PCAP_NOKIA
|
||||
};
|
||||
#define N_SUBTYPES_STANDARD G_N_ELEMENTS(subtypes_standard)
|
||||
static const int subtypes_nsec[] = {
|
||||
WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC
|
||||
};
|
||||
#define N_SUBTYPES_NSEC G_N_ELEMENTS(subtypes_nsec)
|
||||
#define MAX_FIGURES_OF_MERIT \
|
||||
MAX(MAX(N_SUBTYPES_MODIFIED, N_SUBTYPES_STANDARD), N_SUBTYPES_NSEC)
|
||||
MAX(N_SUBTYPES_MODIFIED, N_SUBTYPES_STANDARD)
|
||||
int figures_of_merit[MAX_FIGURES_OF_MERIT];
|
||||
const int *subtypes;
|
||||
int n_subtypes;
|
||||
|
@ -362,80 +358,118 @@ wtap_open_return_val libpcap_open(wtap *wth, int *err, gchar **err_info)
|
|||
* Oh, and if it has the standard magic number, it might, instead,
|
||||
* be a Nokia libpcap file, so we may need to try that if
|
||||
* neither normal nor ss990417 headers work.
|
||||
*
|
||||
* But don't do that if the input is a pipe; that would mean the
|
||||
* open won't complete until two packets have been written to
|
||||
* the pipe, unless the pipe is closed after one packet has
|
||||
* been written, so a program reading from the file won't see
|
||||
* the first packet until the second packet has been written.
|
||||
*/
|
||||
if (modified) {
|
||||
/*
|
||||
* Well, we have the magic number from Alexey's
|
||||
* later two patches. Try the subtypes for that.
|
||||
* later two patches. Try the subtypes for that,
|
||||
* and fail if we're reading from a pipe.
|
||||
*/
|
||||
wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN;
|
||||
subtypes = subtypes_modified;
|
||||
n_subtypes = N_SUBTYPES_MODIFIED;
|
||||
} else {
|
||||
if (wth->file_tsprec == WTAP_TSPREC_NSEC) {
|
||||
/*
|
||||
* We have nanosecond-format libpcap's magic
|
||||
* number. Try the subtypes for that.
|
||||
* number. There's only one format with that
|
||||
* magic number (if somebody comes up with
|
||||
* another one, we'll just refuse to support
|
||||
* it and tell them to ask The Tcpdump Group
|
||||
* for another magic number).
|
||||
*/
|
||||
subtypes = subtypes_nsec;
|
||||
n_subtypes = N_SUBTYPES_NSEC;
|
||||
wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC;
|
||||
subtypes = NULL;
|
||||
n_subtypes = 0;
|
||||
} else {
|
||||
/*
|
||||
* We have the regular libpcap magic number.
|
||||
* Try the subtypes for that.
|
||||
* Try the subtypes for that, unless we're
|
||||
* reading from a pipe, in which case we
|
||||
* just assume it's a regular libpcap file.
|
||||
*/
|
||||
wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAP;
|
||||
subtypes = subtypes_standard;
|
||||
n_subtypes = N_SUBTYPES_STANDARD;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Try all the subtypes.
|
||||
* Do we have any subtypes to try?
|
||||
*/
|
||||
first_packet_offset = file_tell(wth->fh);
|
||||
for (i = 0; i < n_subtypes; i++) {
|
||||
wth->file_type_subtype = subtypes[i];
|
||||
figures_of_merit[i] = libpcap_try(wth, err, err_info);
|
||||
if (figures_of_merit[i] == -1) {
|
||||
/*
|
||||
* Well, we couldn't even read it.
|
||||
* Give up.
|
||||
*/
|
||||
if (n_subtypes == 0) {
|
||||
/*
|
||||
* No, so just use what we picked.
|
||||
*/
|
||||
goto done;
|
||||
} else if (wth->ispipe) {
|
||||
/*
|
||||
* It's a pipe, so use what we picked, unless we picked
|
||||
* WTAP_FILE_TYPE_SUBTYPE_UNKNOWN, in which case we fail.
|
||||
*/
|
||||
if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN) {
|
||||
*err = WTAP_ERR_UNSUPPORTED;
|
||||
*err_info = g_strdup("pcap: that type of pcap file can't be read from a pipe");
|
||||
return WTAP_OPEN_ERROR;
|
||||
}
|
||||
if (figures_of_merit[i] == 0) {
|
||||
/*
|
||||
* This format doesn't have any issues.
|
||||
* Put the seek pointer back, and finish.
|
||||
*/
|
||||
if (file_seek(wth->fh, first_packet_offset, SEEK_SET, err) == -1) {
|
||||
goto done;
|
||||
} else {
|
||||
first_packet_offset = file_tell(wth->fh);
|
||||
for (i = 0; i < n_subtypes; i++) {
|
||||
wth->file_type_subtype = subtypes[i];
|
||||
figures_of_merit[i] = libpcap_try(wth, err, err_info);
|
||||
if (figures_of_merit[i] == -1) {
|
||||
/*
|
||||
* Well, we couldn't even read it.
|
||||
* Give up.
|
||||
*/
|
||||
return WTAP_OPEN_ERROR;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
if (figures_of_merit[i] == 0) {
|
||||
/*
|
||||
* This format doesn't have any issues.
|
||||
* Put the seek pointer back, and finish,
|
||||
* using that format as the subtype.
|
||||
*/
|
||||
if (file_seek(wth->fh, first_packet_offset,
|
||||
SEEK_SET, err) == -1) {
|
||||
return WTAP_OPEN_ERROR;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, we've recorded the figure of merit for this one;
|
||||
* go back to the first packet and try the next one.
|
||||
*/
|
||||
if (file_seek(wth->fh, first_packet_offset, SEEK_SET, err) == -1) {
|
||||
return WTAP_OPEN_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, none are perfect; let's see which one is least bad.
|
||||
*/
|
||||
best_subtype = INT_MAX;
|
||||
for (i = 0; i < n_subtypes; i++) {
|
||||
/*
|
||||
* Is this subtype better than the last one we saw?
|
||||
*/
|
||||
if (figures_of_merit[i] < best_subtype) {
|
||||
/*
|
||||
* Yes. Choose it until we find a better one.
|
||||
* OK, we've recorded the figure of merit for this
|
||||
* one; go back to the first packet and try the
|
||||
* next one.
|
||||
*/
|
||||
wth->file_type_subtype = subtypes[i];
|
||||
best_subtype = figures_of_merit[i];
|
||||
if (file_seek(wth->fh, first_packet_offset, SEEK_SET,
|
||||
err) == -1) {
|
||||
return WTAP_OPEN_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, none are perfect; let's see which one is least bad.
|
||||
*/
|
||||
best_subtype = INT_MAX;
|
||||
for (i = 0; i < n_subtypes; i++) {
|
||||
/*
|
||||
* Is this subtype better than the last one we saw?
|
||||
*/
|
||||
if (figures_of_merit[i] < best_subtype) {
|
||||
/*
|
||||
* Yes. Choose it until we find a better one.
|
||||
*/
|
||||
wth->file_type_subtype = subtypes[i];
|
||||
best_subtype = figures_of_merit[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ typedef gboolean (*subtype_seek_read_func)(struct wtap*, gint64,
|
|||
struct wtap {
|
||||
FILE_T fh;
|
||||
FILE_T random_fh; /**< Secondary FILE_T for random access */
|
||||
gboolean ispipe; /**< TRUE if the file is a pipe */
|
||||
int file_type_subtype;
|
||||
guint snapshot_length;
|
||||
struct Buffer *frame_buffer;
|
||||
|
|
Loading…
Reference in New Issue