Subject: bin/8798: libpcap LP64 problem -- can't read files from LP32 tcpdump
To: None <gnats-bugs@gnats.netbsd.org>
From: Havard Eidnes <he@runit.no>
List: netbsd-bugs
Date: 11/14/1999 09:48:50
>Number: 8798
>Category: bin
>Synopsis: libpcap LP64 problem -- can't read files from LP32 tcpdump
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Nov 14 09:48:00 1999
>Last-Modified:
>Originator: Havard Eidnes
>Organization:
Me, myself.
>Release: NetBSD 1.4.1
>Environment:
System: NetBSD albatross.runit.sintef.no 1.4.1 NetBSD 1.4.1 (ALBATROSS) #13: Fri Nov 5 13:42:55 MET 1999 he@albatross.runit.sintef.no:/usr/src/sys/arch/alpha/compile/ALBATROSS alpha
>Description:
Tcpdump on NetBSD/alpha cannot read a tcpdump file produced
with "tcpdump -w" on NetBSD/i386 or any other LP32 platform. The
problem is that the "packet header" includes a "struct timeval", which
has "u_long"s as components, resulting in different results for LP64
platforms.
>How-To-Repeat:
Take packet dump on NetBSD/i386, try to read it with "tcpdump
-r" on NetBDS/alpha.
>Fix:
This fix makes the on-disk format conform to the LP32 model,
reintroducing a year-2032 (or thereabouts) problem for this code on
the Alpha. However, I expect we can deal with that when the time
comes...
Index: pcap.h
===================================================================
RCS file: /cvsroot/basesrc/lib/libpcap/pcap.h,v
retrieving revision 1.7
diff -u -r1.7 pcap.h
--- pcap.h 1998/07/26 14:49:36 1.7
+++ pcap.h 1999/11/14 17:38:52
@@ -90,6 +90,17 @@
};
/*
+ * Well, "struct timeval" has different size between LP32 and LP64,
+ * so here's the LP32 version of the on-disk format.
+ */
+struct pcap_f_pkthdr {
+ bpf_u_int32 tv_sec;
+ bpf_u_int32 tv_usec;
+ bpf_u_int32 caplen;
+ bpf_u_int32 len;
+};
+
+/*
* As returned by the pcap_stats()
*/
struct pcap_stat {
Index: savefile.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libpcap/savefile.c,v
retrieving revision 1.5
diff -u -r1.5 savefile.c
--- savefile.c 1997/10/03 15:53:17 1.5
+++ savefile.c 1999/11/14 17:38:53
@@ -205,12 +205,17 @@
sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
{
FILE *fp = p->sf.rfile;
+ struct pcap_f_pkthdr pfh;
/* read the stamp */
- if (fread((char *)hdr, sizeof(struct pcap_pkthdr), 1, fp) != 1) {
+ if (fread((char *)&pfh, sizeof(struct pcap_f_pkthdr), 1, fp) != 1) {
/* probably an EOF, though could be a truncated packet */
return (1);
}
+ hdr->ts.tv_sec = pfh.tv_sec;
+ hdr->ts.tv_usec = pfh.tv_usec;
+ hdr->caplen = pfh.caplen;
+ hdr->len = pfh.len;
if (p->sf.swapped) {
/* these were written in opposite byte order */
@@ -322,10 +327,16 @@
pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
{
register FILE *f;
+ struct pcap_f_pkthdr fh;
+ fh.tv_sec = h->ts.tv_sec;
+ fh.tv_usec = h->ts.tv_usec;
+ fh.caplen = h->caplen;
+ fh.len = h->len;
+
f = (FILE *)user;
/* XXX we should check the return status */
- (void)fwrite((char *)h, sizeof(*h), 1, f);
+ (void)fwrite((char *)&fh, sizeof(fh), 1, f);
(void)fwrite((char *)sp, h->caplen, 1, f);
}
>Audit-Trail:
>Unformatted: