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);
                }
 

Reply via email to