diff -ur libpcap-orig/pcap-bpf.c libpcap-divert/pcap-bpf.c
--- libpcap-orig/pcap-bpf.c	Wed Apr 23 22:17:41 2003
+++ libpcap-divert/pcap-bpf.c	Wed Apr 23 22:38:24 2003
@@ -27,6 +27,7 @@
 #include "config.h"
 #endif
 
+#include <sys/types.h>
 #include <sys/param.h>			/* optionally get BSD define */
 #include <sys/time.h>
 #include <sys/timeb.h>
@@ -35,6 +36,7 @@
 #include <sys/ioctl.h>
 
 #include <net/if.h>
+#include <netinet/in.h>
 
 #ifdef _AIX
 
@@ -128,17 +130,40 @@
 	return (0);
 }
 
+/*
+ * IPDIVERT info from rwatson:
+20:23 #bsdco   rwatson> int
+20:23 #bsdco   rwatson> socket_divert_get(struct sockaddr_in *sa, char *buf, int
+ buflen)
+20:23 #bsdco   rwatson> {
+20:23 #bsdco   rwatson>         int     len, addrlen;
+20:23 #bsdco   rwatson>         addrlen = sizeof(*sa);
+20:23 #bsdco   rwatson>         len = recvfrom(socket_divert, buf, buflen, 0,
+20:23 #bsdco   rwatson>             (struct sockaddr *) sa, &addrlen);
+20:23 #bsdco   rwatson>         if (len == -1)
+20:23 #bsdco   rwatson>                 perror("recvfrom");
+20:23 #bsdco   rwatson>         return (len);
+20:23 #bsdco   rwatson> }
+*/
 int
 pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
 {
+	int addrlen;
 	int cc;
 	int n = 0;
 	register u_char *bp, *ep;
+	struct pcap_pkthdr pph;
+	register int caplen, hdrlen;
 
  again:
 	cc = p->cc;
 	if (p->cc == 0) {
-		cc = read(p->fd, (char *)p->buffer, p->bufsize);
+		if (p->divert) {
+			addrlen = sizeof(p->sa);
+			cc = recvfrom(p->fd, (char *)p->buffer, p->bufsize, 0,
+			    &p->sa, &addrlen);
+		} else
+			cc = read(p->fd, (char *)p->buffer, p->bufsize);
 		if (cc < 0) {
 			/* Don't choke when we get ptraced */
 			switch (errno) {
@@ -200,42 +225,62 @@
 	/*
 	 * Loop through each packet.
 	 */
+
+	if (p->divert) {
+		gettimeofday(&pph.ts, NULL);
+		pph.caplen = cc;
+		pph.len = cc;
+		(*callback)(user, &pph, bp);
+		n = 1;
+	} else {
 #define bhp ((struct bpf_hdr *)bp)
-	ep = bp + cc;
-	while (bp < ep) {
-		register int caplen, hdrlen;
-		caplen = bhp->bh_caplen;
-		hdrlen = bhp->bh_hdrlen;
-		/*
-		 * XXX A bpf_hdr matches a pcap_pkthdr.
-		 */
+		ep = bp + cc;
+		while (bp < ep) {
+			register int caplen, hdrlen;
+			caplen = bhp->bh_caplen;
+			hdrlen = bhp->bh_hdrlen;
+			/*
+			 * XXX A bpf_hdr matches a pcap_pkthdr.
+			 */
 #ifdef _AIX
-		/*
-		 * AIX's BPF returns seconds/nanoseconds time stamps, not
-		 * seconds/microseconds time stamps.
-		 *
-		 * XXX - I'm guessing here that it's a "struct timestamp";
-		 * if not, this code won't compile, but, if not, you
-		 * want to send us a bug report and fall back on using
-		 * DLPI.  It's not as if BPF used to work right on
-		 * AIX before this change; this change attempts to fix
-		 * the fact that it didn't....
-		 */
-		bhp->bh_tstamp.tv_usec = bhp->bh_tstamp.tv_usec/1000;
+			/*
+			 * AIX's BPF returns seconds/nanoseconds time stamps, not
+			 * seconds/microseconds time stamps.
+			 *
+			 * XXX - I'm guessing here that it's a "struct timestamp";
+			 * if not, this code won't compile, but, if not, you
+			 * want to send us a bug report and fall back on using
+			 * DLPI.  It's not as if BPF used to work right on
+			 * AIX before this change; this change attempts to fix
+			 * the fact that it didn't....
+			 */
+			bhp->bh_tstamp.tv_usec = bhp->bh_tstamp.tv_usec/1000;
 #endif
-		(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
-		bp += BPF_WORDALIGN(caplen + hdrlen);
-		if (++n >= cnt && cnt > 0) {
-			p->bp = bp;
-			p->cc = ep - bp;
-			return (n);
+			(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
+			bp += BPF_WORDALIGN(caplen + hdrlen);
+			if (++n >= cnt && cnt > 0) {
+				p->bp = bp;
+				p->cc = ep - bp;
+				return (n);
+			}
 		}
-	}
 #undef bhp
+	}
 	p->cc = 0;
 	return (n);
 }
 
+int
+pcap_get_last_sockaddr(pcap_t *p, struct sockaddr *in)
+{
+	if (!p->divert)
+		return -1;
+
+	memcpy (in, &(p->sa), sizeof(struct sockaddr));
+
+	return 0;
+}
+
 #ifdef _AIX
 static int 
 bpf_odminit(char *errbuf)
@@ -424,6 +469,37 @@
 	return (fd);
 }
 
+static int
+divert_open(pcap_t *p, char *device, int *port, char *errbuf)
+{
+	int fd;
+	char *end;
+	struct sockaddr_in addr;
+
+	*port = strtoul(device, &end, 0);
+	if (device == end || end != device + strlen(device))
+		return -2;
+
+	if ((fd = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT)) == -1) {
+		snprintf(errbuf, PCAP_ERRBUF_SIZE,
+		         "(unable to open diverted socket) %d: %s",
+		         *port, pcap_strerror(errno));
+		return fd;
+	}
+
+	addr.sin_family = AF_INET;
+	addr.sin_addr.s_addr = INADDR_ANY;
+	addr.sin_port = htons(*port);
+
+	if (bind(fd, (struct sockaddr *) &addr, sizeof addr) == -1) {
+		snprintf(errbuf, PCAP_ERRBUF_SIZE,
+		         "(unable to bind diverted socket) %d: %s",
+		         *port, pcap_strerror(errno));
+		return -1;
+	}
+	return fd;
+}
+
 /*
  * XXX - on AIX, IBM's tcpdump (and perhaps the incompatible-with-everybody-
  * else's libpcap in AIX 5.1) appears to forcibly load the BPF driver
@@ -438,6 +514,7 @@
 pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
     char *ebuf)
 {
+	int port;
 	int fd;
 	struct ifreq ifr;
 	struct bpf_version bv;
@@ -458,20 +535,33 @@
 		return (NULL);
 	}
 	memset(p, 0, sizeof(*p));
-	fd = bpf_open(p, ebuf);
-	if (fd < 0)
+
+	switch ((fd = divert_open(p, device, &port, ebuf))) {
+	case -2:
+		p->divert = 0;
+		break;
+	case -1:
 		goto bad;
+	default:
+		p->divert = 1;
+	}
+
+	if (!p->divert) {
+		fd = bpf_open(p, ebuf);
+		if (fd < 0)
+			goto bad;
+	}
 
 	p->fd = fd;
 	p->snapshot = snaplen;
 
-	if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) {
+	if (!p->divert && ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) {
 		snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s",
 		    pcap_strerror(errno));
 		goto bad;
 	}
-	if (bv.bv_major != BPF_MAJOR_VERSION ||
-	    bv.bv_minor < BPF_MINOR_VERSION) {
+	if (!p->divert && (bv.bv_major != BPF_MAJOR_VERSION ||
+	    bv.bv_minor < BPF_MINOR_VERSION)) {
 		snprintf(ebuf, PCAP_ERRBUF_SIZE,
 		    "kernel bpf filter out of date");
 		goto bad;
@@ -494,27 +584,33 @@
 		 * the call fails, it's no big deal, we just continue to
 		 * use the standard buffer size.
 		 */
-		(void) ioctl(fd, BIOCSBLEN, (caddr_t)&v);
+		if (!p->divert)
+			(void) ioctl(fd, BIOCSBLEN, (caddr_t)&v);
 
 		(void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
-		if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0)
-			break;	/* that size worked; we're done */
 
-		if (errno != ENOBUFS) {
-			snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s",
-			    device, pcap_strerror(errno));
-			goto bad;
+		if (!p->divert) {
+			if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0)
+				break;	/* that size worked; we're done */
+
+			if (errno != ENOBUFS) {
+				snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s",
+				    device, pcap_strerror(errno));
+				goto bad;
+			}
 		}
 	}
 
-	if (v == 0) {
+	if (!p->divert && v == 0) {
 		snprintf(ebuf, PCAP_ERRBUF_SIZE,
 			 "BIOCSBLEN: %s: No buffer size worked", device);
 		goto bad;
 	}
 
 	/* Get the data link layer type. */
-	if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) {
+	if (p->divert)
+		v = DLT_RAW;
+	else if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) {
 		snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s",
 		    pcap_strerror(errno));
 		goto bad;
@@ -580,7 +676,7 @@
 	 * this interface supports.  If this fails with EINVAL, it's
 	 * not fatal; we just don't get to use the feature later.
 	 */
-	if (ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) == 0) {
+	if (!p->divert && ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) == 0) {
 		bdl.bfl_list = (u_int *) malloc(sizeof(u_int) * bdl.bfl_len);
 		if (bdl.bfl_list == NULL) {
 			(void)snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
@@ -606,7 +702,7 @@
 #endif
 
 	/* set timeout */
-	if (to_ms != 0) {
+	if (!p->divert && to_ms != 0) {
 		/*
 		 * XXX - is this seconds/nanoseconds in AIX?
 		 * (Treating it as such doesn't fix the timeout
@@ -679,7 +775,7 @@
 #endif	/* BIOCIMMEDIATE */
 #endif	/* _AIX */
 
-	if (promisc) {
+	if (!p->divert && promisc) {
 		/* set promiscuous mode, okay if it fails */
 		if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) {
 			snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s",
@@ -687,7 +783,9 @@
 		}
 	}
 
-	if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) {
+	if (p->divert)
+		v = 2048;
+	else if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) {
 		snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s",
 		    pcap_strerror(errno));
 		goto bad;
@@ -736,7 +834,7 @@
 	} else if (p->sf.rfile != NULL) {
 		if (install_bpf_program(p, fp) < 0)
 			return (-1);
-	} else if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
+	} else if (!p->divert && ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
 		    pcap_strerror(errno));
 		return (-1);
diff -ur libpcap-orig/pcap-int.h libpcap-divert/pcap-int.h
--- libpcap-orig/pcap-int.h	Wed Apr 23 22:17:41 2003
+++ libpcap-divert/pcap-int.h	Wed Apr 23 22:30:39 2003
@@ -91,6 +91,8 @@
 	int linktype;
 	int tzoff;		/* timezone offset */
 	int offset;		/* offset for proper alignment */
+	int divert;		/* this is a divert socket */
+	struct sockaddr sa;	/* this is socket address for re-writing in divert */
 
 	struct pcap_sf sf;
 	struct pcap_md md;
diff -ur libpcap-orig/pcap.h libpcap-divert/pcap.h
--- libpcap-orig/pcap.h	Wed Apr 23 22:17:42 2003
+++ libpcap-divert/pcap.h	Wed Apr 23 22:31:40 2003
@@ -42,6 +42,7 @@
 #else /* WIN32 */
 #include <sys/types.h>
 #include <sys/time.h>
+#include <sys/socket.h>
 #endif /* WIN32 */
 
 #ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H
@@ -203,6 +204,7 @@
 /* XXX */
 FILE	*pcap_file(pcap_t *);
 int	pcap_fileno(pcap_t *);
+int 	pcap_get_last_sockaddr (pcap_t *p, struct sockaddr *in);
 
 pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
 int	pcap_dump_flush(pcap_dumper_t *);
