Michael Richardson wrote:
> Guy> This might be better done by adding another "pcap_open_XXX()" call
> Guy> ("pcap_open_foreign()"?), rather than overloading "pcap_open_dead()" and
> Guy> giving it another argument, changing its API.
>
> Uros, would you be willing to revise your patch in this direction?
I have actually submitted a patch which follows Guy's suggestion (I called the
function pcap_open_user instead of pcap_open_foreign).
> Have we resolved this difference yet?
Guy had a reservation about my patch changing `struct pcap' to include a pointer to
the input function. This is a generic change which required me to modify a number
of files (pcap-bpf.c, pcap-linux, ...) with a small change -- function pcap_read()
would be called through a pointer stored in struct pcap instead of being called
directly. Guy suggested that I modify my capture program to print output in tcpdump
archive format -- this would require a (new) function which would be similar to
pcap_open_offline() only that it would take a file descriptor instead of a file
name.
I have thought about Guy's suggestion but at present I cannot modify my capture
program to use tcpdump archive format (due to, among other reasons, the buffering
introduced by fopen/fclose calls) so I am still using a locally modified version of
libpcap. I am resending my patch. If you feel that my patch is too intrusive and
you have a suggestion how I can reimplement pcap_open_user() so that it keeps my
current semantics I am willing to recode.
Thanks,
Uros
--
Uros Prestor
[EMAIL PROTECTED]
Index: pcap-bpf.c
===================================================================
RCS file: /tcpdump/master/libpcap/pcap-bpf.c,v
retrieving revision 1.44
diff -u -r1.44 pcap-bpf.c
--- pcap-bpf.c 2000/10/28 00:01:28 1.44
+++ pcap-bpf.c 2001/03/01 03:42:04
@@ -356,6 +356,7 @@
pcap_strerror(errno));
goto bad;
}
+ p->reader = pcap_read;
return (p);
bad:
Index: pcap-dlpi.c
===================================================================
RCS file: /tcpdump/master/libpcap/pcap-dlpi.c,v
retrieving revision 1.64
diff -u -r1.64 pcap-dlpi.c
--- pcap-dlpi.c 2001/02/21 09:07:41 1.64
+++ pcap-dlpi.c 2001/03/01 03:42:05
@@ -549,6 +549,7 @@
/* Allocate data buffer */
p->bufsize = MAXDLBUF * sizeof(bpf_u_int32);
p->buffer = (u_char *)malloc(p->bufsize + p->offset);
+ p->reader = pcap_read;
return (p);
bad:
Index: pcap-int.h
===================================================================
RCS file: /tcpdump/master/libpcap/pcap-int.h,v
retrieving revision 1.32
diff -u -r1.32 pcap-int.h
--- pcap-int.h 2000/12/21 10:29:23 1.32
+++ pcap-int.h 2001/03/01 03:42:05
@@ -93,6 +93,9 @@
u_char *bp;
int cc;
+ /* input function */
+ pcap_reader reader;
+
/*
* Place holder for pcap_next().
*/
Index: pcap-linux.c
===================================================================
RCS file: /tcpdump/master/libpcap/pcap-linux.c,v
retrieving revision 1.55
diff -u -r1.55 pcap-linux.c
--- pcap-linux.c 2001/01/20 07:47:54 1.55
+++ pcap-linux.c 2001/03/01 03:42:05
@@ -233,6 +233,7 @@
free(handle);
return NULL;
}
+ handle->reader = pcap_read;
return handle;
}
Index: pcap-nit.c
===================================================================
RCS file: /tcpdump/master/libpcap/pcap-nit.c,v
retrieving revision 1.39
diff -u -r1.39 pcap-nit.c
--- pcap-nit.c 2000/10/28 00:01:29 1.39
+++ pcap-nit.c 2001/03/01 03:42:05
@@ -233,6 +233,7 @@
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad;
}
+ p->reader = pcap_read;
return (p);
bad:
if (fd >= 0)
Index: pcap-pf.c
===================================================================
RCS file: /tcpdump/master/libpcap/pcap-pf.c,v
retrieving revision 1.62
diff -u -r1.62 pcap-pf.c
--- pcap-pf.c 2000/10/28 00:01:30 1.62
+++ pcap-pf.c 2001/03/01 03:42:05
@@ -315,6 +315,7 @@
}
p->bufsize = BUFSPACE;
p->buffer = (u_char*)malloc(p->bufsize + p->offset);
+ p->reader = pcap_read;
return (p);
bad:
Index: pcap-snit.c
===================================================================
RCS file: /tcpdump/master/libpcap/pcap-snit.c,v
retrieving revision 1.54
diff -u -r1.54 pcap-snit.c
--- pcap-snit.c 2000/10/28 00:01:30 1.54
+++ pcap-snit.c 2001/03/01 03:42:05
@@ -290,6 +290,7 @@
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad;
}
+ p->reader = pcap_read;
return (p);
bad:
if (fd >= 0)
Index: pcap-snoop.c
===================================================================
RCS file: /tcpdump/master/libpcap/pcap-snoop.c,v
retrieving revision 1.30
diff -u -r1.30 pcap-snoop.c
--- pcap-snoop.c 2000/10/28 00:01:30 1.30
+++ pcap-snoop.c 2001/03/01 03:42:06
@@ -262,6 +262,7 @@
pcap_strerror(errno));
goto bad;
}
+ p->reader = pcap_read;
return (p);
bad:
Index: pcap.c
===================================================================
RCS file: /tcpdump/master/libpcap/pcap.c,v
retrieving revision 1.36
diff -u -r1.36 pcap.c
--- pcap.c 2000/12/16 10:43:31 1.36
+++ pcap.c 2001/03/01 03:42:06
@@ -56,10 +56,10 @@
int
pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
+ if (p->reader == NULL)
+ return -1;
- if (p->sf.rfile != NULL)
- return (pcap_offline_read(p, cnt, callback, user));
- return (pcap_read(p, cnt, callback, user));
+ return (*p->reader)(p, cnt, callback, user);
}
int
@@ -68,23 +68,28 @@
register int n;
for (;;) {
- if (p->sf.rfile != NULL)
- n = pcap_offline_read(p, cnt, callback, user);
- else {
- /*
- * XXX keep reading until we get something
- * (or an error occurs)
- */
- do {
- n = pcap_read(p, cnt, callback, user);
- } while (n == 0);
- }
- if (n <= 0)
+ /*
+ * XXX keep reading until we get something
+ * (or an error occurs)
+ */
+ do {
+ n = (*p->reader)(p, cnt, callback, user);
+ } while (n == 0);
+
+ switch (n) {
+ case -1: /* true error */
return (n);
- if (cnt > 0) {
- cnt -= n;
- if (cnt <= 0)
- return (0);
+
+ case -2: /* end-of-file */
+ return 0;
+
+ default:
+ if (cnt > 0) {
+ cnt -= n;
+ if (cnt <= 0)
+ return (0);
+ }
+ break;
}
}
}
@@ -200,6 +205,23 @@
p->fd = -1;
p->snapshot = snaplen;
p->linktype = linktype;
+ p->reader = 0;
+ return p;
+}
+
+pcap_t *
+pcap_open_user(int linktype, int snaplen, pcap_reader reader)
+{
+ pcap_t *p;
+
+ p = malloc(sizeof(*p));
+ if (p == NULL)
+ return NULL;
+ memset (p, 0, sizeof(*p));
+ p->fd = -1;
+ p->snapshot = snaplen;
+ p->linktype = linktype;
+ p->reader = reader;
return p;
}
Index: pcap.h
===================================================================
RCS file: /tcpdump/master/libpcap/pcap.h,v
retrieving revision 1.31
diff -u -r1.31 pcap.h
--- pcap.h 2000/10/28 00:01:31 1.31
+++ pcap.h 2001/03/01 03:42:06
@@ -131,10 +131,13 @@
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
const u_char *);
+typedef int (*pcap_reader)(pcap_t*, int, pcap_handler, u_char*);
+
char *pcap_lookupdev(char *);
int pcap_lookupnet(char *, bpf_u_int32 *, bpf_u_int32 *, char *);
pcap_t *pcap_open_live(char *, int, int, int, char *);
pcap_t *pcap_open_dead(int, int);
+pcap_t *pcap_open_user(int, int, pcap_reader);
pcap_t *pcap_open_offline(const char *, char *);
void pcap_close(pcap_t *);
int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
Index: savefile.c
===================================================================
RCS file: /tcpdump/master/libpcap/savefile.c,v
retrieving revision 1.49
diff -u -r1.49 savefile.c
--- savefile.c 2000/12/21 10:29:23 1.49
+++ savefile.c 2001/03/01 03:42:06
@@ -413,6 +413,8 @@
pcap_fddipad = 0;
#endif
+ p->reader = pcap_offline_read;
+
return (p);
bad:
free(p);
@@ -538,8 +540,8 @@
status = sf_next_packet(p, &h, p->buffer, p->bufsize);
if (status) {
- if (status == 1)
- return (0);
+ if (status == 1) /* end of file */
+ return (-2);
return (status);
}