pcap-common: Account for padding in ENCAP_ERF len and caplen

Set len and caplen in pcap_read_post_process to actual wlen/payload length like for native ERF.
This fixes padding incorrectly showing as an Ethernet trailer or equivalent as
well as packet length calculations being incorrect.

Fix up rlen when writing ENCAP_ERF so it isn't longer than the actual record
length. This differs from native ERF behaviour which pads the record instead
but there is currently no non-hackish way to do this for pcap/pcap-ng.

Note: This means records captured from a DAG card in Wireshark (or old
PCAP(-NG) files opened) will have padding stripped when saved as PCAP(-NG) and
thus cannot be transmitted when converted to native ERF without aligning first.
However, if the file is saved as native ERF originally the padding will be
preserved (and zeroed). Given that extension header write support was very
broken and transmission of PCAP(-NG) is not supported without conversion this
is not expected to have been common.

Ping-Bug: 3606
Change-Id: I49dce03984d7f07431b6eb7e16a993aeb571f288
Reviewed-on: https://code.wireshark.org/review/15359
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
Anthony Coddington 2016-04-18 13:44:35 +12:00 committed by Michael Mann
parent f295bf1960
commit c38f4e1391
1 changed files with 20 additions and 1 deletions

View File

@ -1892,6 +1892,15 @@ pcap_read_post_process(int file_type, int wtap_encap,
if (bytes_swapped)
pcap_byteswap_nflog_pseudoheader(phdr, pd);
break;
case WTAP_ENCAP_ERF:
/*
* Update packet size to account for ERF padding and snapping.
* Captured length is minimum of wlen and previously calculated
* caplen (which would have included padding but not phdr).
*/
phdr->len = phdr->pseudo_header.erf.phdr.wlen;
phdr->caplen = MIN(phdr->len, phdr->caplen);
break;
default:
break;
@ -2119,7 +2128,17 @@ pcap_write_phdr(wtap_dumper *wdh, int encap, const union wtap_pseudo_header *pse
phtolell(&erf_hdr[0], pseudo_header->erf.phdr.ts);
erf_hdr[8] = pseudo_header->erf.phdr.type;
erf_hdr[9] = pseudo_header->erf.phdr.flags;
phtons(&erf_hdr[10], pseudo_header->erf.phdr.rlen);
/*
* Recalculate rlen as padding (and maybe extension headers)
* have been stripped from caplen.
*
* XXX: Since we don't have phdr->caplen here, assume caplen was
* calculated correctly and recalculate from wlen.
*/
phtons(&erf_hdr[10],
MIN(pseudo_header->erf.phdr.rlen, pseudo_header->erf.phdr.wlen + pcap_get_phdr_size(WTAP_ENCAP_ERF, pseudo_header)));
phtons(&erf_hdr[12], pseudo_header->erf.phdr.lctr);
phtons(&erf_hdr[14], pseudo_header->erf.phdr.wlen);
size = sizeof(struct erf_phdr);