This fixes a number of things (including it not compiling under 1.1.x.
After you apply this patch, read the README.linux in the tcpdump directory.

diff -u --recursive --new-file tcpdump/libpcap-0.0/pcap-linux.c tcpdump-3.0/libpcap-0.0/pcap-linux.c
--- tcpdump/libpcap-0.0/pcap-linux.c	Tue Jul 12 16:30:32 1994
+++ tcpdump-3.0/libpcap-0.0/pcap-linux.c	Thu Jul 21 16:26:50 1994
@@ -32,6 +32,21 @@
 #include "pcap-int.h"
 
 static char snoop_device[255];
+struct ifreq ifr_orig;
+
+void restore_interface()
+{
+  int fd;
+
+  fd = socket(PF_INET, SOCK_PACKET, htons(0x0003));
+  if (fd < 0) {
+    printf("Warning: could not restore interface to normal.\n");
+    return;
+  }
+
+  if (ioctl(fd, SIOCSIFFLAGS, &ifr_orig)<0)
+    printf("Warning: could not restore interface to normal.\n");
+}
 
 int pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
 {
@@ -39,9 +54,20 @@
   register int caplen;
   struct sockaddr from;
   int from_len;
+  char *buf;
+  int bufsize;
+
+  if (p->linktype == DLT_SLIP) {
+    buf = (char *)p->buffer+16;
+    bufsize = p->bufsize - 16;
+    memset(p->buffer,0,16);
+  } else {
+    buf = (char *)p->buffer;
+    bufsize = p->bufsize;
+  }
 
   do {
-    datalen = recvfrom(p->fd,(char *)p->buffer,p->bufsize,0,&from,&from_len);
+    datalen = recvfrom(p->fd,buf,bufsize,0,&from,&from_len);
 
     if (datalen < 0) {
       switch (errno) {
@@ -54,7 +80,11 @@
   } while (strcmp(snoop_device,from.sa_data)); /* go until we find something
 						 from the right interface */
 
+  if (p->linktype == DLT_SLIP)
+    datalen+=16;
+
   caplen = (datalen > p->bufsize) ? datalen : p->bufsize;
+
   if (caplen > p->snapshot)
     caplen = p->snapshot;
 
@@ -63,7 +93,11 @@
     struct pcap_pkthdr h;
     ++p->md.stat.ps_recv;
 
-    gettimeofday(&h.ts,0);
+#ifdef SIOCGSTAMP
+    if (ioctl(p->fd,SIOCGSTAMP,&h.ts)<0) /* ask for the timestamp */
+#endif
+      gettimeofday(&h.ts,0);
+
     h.len = datalen;
     h.caplen = caplen;
     (*callback)(user, &h, (char *)p->buffer);
@@ -113,17 +147,20 @@
     goto bad;
   }
 
-  strcpy(ifr.ifr_name, device);       /* interface we're gonna use */
-  if (ioctl(p->fd, SIOCGIFFLAGS, &ifr) < 0 ) {    /* get flags */
-    sprintf(ebuf, "socket ioctl get: %s", pcap_strerror(errno));
-    goto bad;
-  }
-  if (promisc)
+  if (p->linktype != DLT_SLIP && promisc) {
+    strcpy(ifr.ifr_name, device);       /* interface we're gonna use */
+    if (ioctl(p->fd, SIOCGIFFLAGS, &ifr) < 0 ) {    /* get flags */
+      sprintf(ebuf, "socket ioctl get: %s", pcap_strerror(errno));
+      goto bad;
+    }
+    ifr_orig = ifr;
+    atexit(restore_interface);
     ifr.ifr_flags |= IFF_PROMISC;         /* set promiscuous mode */
 
-  if (ioctl(p->fd, SIOCSIFFLAGS, &ifr) < 0 ) {    /* set flags */
-    sprintf(ebuf, "socket ioctl set: %s", pcap_strerror(errno));
-    goto bad;
+    if (ioctl(p->fd, SIOCSIFFLAGS, &ifr) < 0 ) {    /* set flags */
+      sprintf(ebuf, "socket ioctl set: %s", pcap_strerror(errno));
+      goto bad;
+    }
   }
   strcpy(snoop_device,device);
 
diff -u --recursive --new-file tcpdump/linux-include/linux/if_arp.h tcpdump-3.0/linux-include/linux/if_arp.h
--- tcpdump/linux-include/linux/if_arp.h	Wed Dec 31 19:00:00 1969
+++ tcpdump-3.0/linux-include/linux/if_arp.h	Wed Jul 20 20:07:31 1994
@@ -0,0 +1,45 @@
+/*	@(#)if_arp.h 1.5 88/08/19 SMI; from UCB 7.1 1/24/86	*/
+/*
+ * Copyright (c) 1986 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef _net_if_arp_h
+#define _net_if_arp_h
+
+/*
+ * Address Resolution Protocol.
+ *
+ * See RFC 826 for protocol description.  ARP packets are variable
+ * in size; the arphdr structure defines the fixed-length portion.
+ * Protocol type values are the same as those for 10 Mb/s Ethernet.
+ * It is followed by the variable-sized fields ar_sha, arp_spa,
+ * arp_tha and arp_tpa in that order, according to the lengths
+ * specified.  Field names used correspond to RFC 826.
+ */
+struct	arphdr {
+	u_short	ar_hrd;		/* format of hardware address */
+#define ARPHRD_ETHER 	1	/* ethernet hardware address */
+	u_short	ar_pro;		/* format of protocol address */
+	u_char	ar_hln;		/* length of hardware address */
+	u_char	ar_pln;		/* length of protocol address */
+	u_short	ar_op;		/* one of: */
+#define	ARPOP_REQUEST	1	/* request to resolve address */
+#define	ARPOP_REPLY	2	/* response to previous request */
+#define	REVARP_REQUEST	3	/* Reverse ARP request */
+#define	REVARP_REPLY	4	/* Reverse ARP reply */
+	/*
+	 * The remaining fields are variable in size,
+	 * according to the sizes above, and are defined
+	 * as appropriate for specific hardware/protocol
+	 * combinations.  (E.g., see <netinet/if_ether.h>.)
+	 */
+#ifdef	notdef
+	u_char	ar_sha[];	/* sender hardware address */
+	u_char	ar_spa[];	/* sender protocol address */
+	u_char	ar_tha[];	/* target hardware address */
+	u_char	ar_tpa[];	/* target protocol address */
+#endif	notdef
+};
+#endif
diff -u --recursive --new-file tcpdump/linux-include/net/slip.h tcpdump-3.0/linux-include/net/slip.h
--- tcpdump/linux-include/net/slip.h	Thu Jul  7 16:25:46 1994
+++ tcpdump-3.0/linux-include/net/slip.h	Wed Jul 20 20:07:30 1994
@@ -1,5 +1,5 @@
 /* linux does not give us the link level header */
-#define SLIP_HDRLEN 0
+#define SLIP_HDRLEN 16
 
 #define SLX_DIR 0
 #define SLX_CHDR 1
diff -u --recursive --new-file tcpdump/tcpdump-3.0/README.linux tcpdump-3.0/tcpdump-3.0/README.linux
--- tcpdump/tcpdump-3.0/README.linux	Tue Jul 12 16:36:06 1994
+++ tcpdump-3.0/tcpdump-3.0/README.linux	Thu Jul 21 16:52:47 1994
@@ -9,15 +9,14 @@
      contained the needed definitions.
   2) This program compiles using gcc 2.5.8, flex 2.4.6, bison 1.22, 
      whatever include files came with Slackware 1.2.0 (presumably the ones
-     that go with gcc 2.5.8), and kernel version 1.0.8
-  3) The slip level of the kernel doesn't return the "low level" header, so
-     I had to slightly hack the pr-slip.c file to fix that annoyance.
+     that go with gcc 2.5.8), and kernel version 1.0.8 (and 1.1.33)
+  3) The kernel keeps track of the exact time a packet was received.
+     the newer kernels provide a way to get to this, so I put in a modification
+     to ask for it.... If it the newer interface doesn't exist (ie old kernel)
+     it will revert back to using gettimeofday().
+  4) I put in a hook so that it can clean up after itself (ie turn off promisc
+     mode if it turned it on.
 
 Things to do:
   1) The kernel keeps track of interface statistics... I took the easy way
      out and didn't ask for them.
-  2) The kernel keeps track of the exact time a packet was received... I
-     wanted to keep this as portable between kernel versions as possible, so
-     I did not modify the kernel to return that information.  I don't know
-     how much of a difference it really makes... I just used gettimeofday()
-     when it recieved the packet at the software level.
diff -u --recursive --new-file tcpdump/tcpdump-3.0/print-sl.c tcpdump-3.0/tcpdump-3.0/print-sl.c
--- tcpdump/tcpdump-3.0/print-sl.c	Thu Jul  7 16:27:32 1994
+++ tcpdump-3.0/tcpdump-3.0/print-sl.c	Thu Jul 21 16:48:28 1994
@@ -88,13 +88,8 @@
 
 	ip = (struct ip *)(p + SLIP_HDRLEN);
 
-#if SLIP_HDRLEN > 0
-/* for some reason, linux doesn't give us the link level information....
-   its probably a kernel oversite and may be fixed by some future version
-*/
 	if (eflag)
 		sliplink_print(p, ip, length);
-#endif
 
 	ip_print((u_char *)ip, length);
 
