]> The Tcpdump Group git mirrors - libpcap/commitdiff
When attaching a "bpf_program" to a "pcap_t" to use as a userland
authorguy <guy>
Sat, 28 Oct 2000 00:01:26 +0000 (00:01 +0000)
committerguy <guy>
Sat, 28 Oct 2000 00:01:26 +0000 (00:01 +0000)
filter, always attach a copy, as "pcap-linux.c" does; that way, after a
program uses "pcap_setfilter()", it can safely use "pcap_freecode()" to
free up the BPF instructions allocated by "pcap_compile()".  Also,
always free it up when the "pcap_t" is closed.

Get rid of the "pcap_t *" argument to "pcap_freecode()", as it's not
necessary.

Document "pcap_freecode()", for the benefit of programs that might
repeatedly compile filter programs and attach them, so that they can
free them up after attaching them and avoid leaking memory for them.

14 files changed:
gencode.c
gencode.h
optimize.c
pcap-bpf.c
pcap-dlpi.c
pcap-linux.c
pcap-nit.c
pcap-null.c
pcap-pf.c
pcap-snit.c
pcap-snoop.c
pcap.3
pcap.c
pcap.h

index 0ff11fc97acb5d6b9d6c06b0ff3fb21567c91d09..12706b65234c96b2d24384a24fd89f90f585449b 100644 (file)
--- a/gencode.c
+++ b/gencode.c
@@ -21,7 +21,7 @@
  */
 #ifndef lint
 static const char rcsid[] =
  */
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.125 2000-10-25 07:28:22 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.126 2000-10-28 00:01:26 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -377,7 +377,7 @@ pcap_compile_nopcap(int snaplen_arg, int linktype_arg,
  * in it.
  */
 void
  * in it.
  */
 void
-pcap_freecode(pcap_t *p, struct bpf_program *program)
+pcap_freecode(struct bpf_program *program)
 {
        program->bf_len = 0;
        if (program->bf_insns != NULL) {
 {
        program->bf_len = 0;
        if (program->bf_insns != NULL) {
index 8feffb06b119d7b228105319eb0fd6898336a82a..96c2bdee4b4d67c900b0f9831d309cba9f40abfb 100644 (file)
--- a/gencode.h
+++ b/gencode.h
@@ -18,7 +18,7 @@
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.42 2000-10-22 04:15:56 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.43 2000-10-28 00:01:27 guy Exp $ (LBL)
  */
 
 /* Address qualifiers. */
  */
 
 /* Address qualifiers. */
@@ -186,6 +186,7 @@ void finish_parse(struct block *);
 char *sdup(const char *);
 
 struct bpf_insn *icode_to_fcode(struct block *, int *);
 char *sdup(const char *);
 
 struct bpf_insn *icode_to_fcode(struct block *, int *);
+int install_bpf_program(pcap_t *, struct bpf_program *);
 int pcap_parse(void);
 void lex_init(char *);
 void lex_cleanup(void);
 int pcap_parse(void);
 void lex_init(char *);
 void lex_cleanup(void);
index c39f899265e150a4b28bdc28cf7a03d438eb82cf..fe2c2cae155008573904faa84ccfd05ca8441163 100644 (file)
@@ -22,7 +22,7 @@
  */
 #ifndef lint
 static const char rcsid[] =
  */
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.64 2000-09-06 07:40:03 itojun Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.65 2000-10-28 00:01:27 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -36,6 +36,8 @@ static const char rcsid[] =
 #include <stdlib.h>
 #include <memory.h>
 
 #include <stdlib.h>
 #include <memory.h>
 
+#include <errno.h>
+
 #include "pcap-int.h"
 
 #include "gencode.h"
 #include "pcap-int.h"
 
 #include "gencode.h"
@@ -2077,6 +2079,36 @@ icode_to_fcode(root, lenp)
        return fp;
 }
 
        return fp;
 }
 
+/*
+ * Make a copy of a BPF program and put it in the "fcode" member of
+ * a "pcap_t".
+ *
+ * If we fail to allocate memory for the copy, fill in the "errbuf"
+ * member of the "pcap_t" with an error message, and return -1;
+ * otherwise, return 0.
+ */
+int
+install_bpf_program(pcap_t *p, struct bpf_program *fp)
+{
+       size_t prog_size;
+
+       /*
+        * Free up any already installed program.
+        */
+       pcap_freecode(&p->fcode);
+
+       prog_size = sizeof(*fp->bf_insns) * fp->bf_len;
+       p->fcode.bf_len = fp->bf_len;
+       p->fcode.bf_insns = (struct bpf_insn *)malloc(prog_size);
+       if (p->fcode.bf_insns == NULL) {
+               snprintf(p->errbuf, sizeof(p->errbuf),
+                        "malloc: %s", pcap_strerror(errno));
+               return (-1);
+       }
+       memcpy(p->fcode.bf_insns, fp->bf_insns, prog_size);
+       return (0);
+}
+
 #ifdef BDEBUG
 static void
 opt_dump(root)
 #ifdef BDEBUG
 static void
 opt_dump(root)
index a0d89ed6d3a370308f50a756eeb49fc3ccd97aae..e8a2d404cd20035eb76b68083e57481da0c6dc7d 100644 (file)
@@ -20,7 +20,7 @@
  */
 #ifndef lint
 static const char rcsid[] =
  */
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.43 2000-10-12 03:53:58 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.44 2000-10-28 00:01:28 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -372,11 +372,13 @@ pcap_setfilter(pcap_t *p, struct bpf_program *fp)
         * compatible with some of kernel BPF code (for example BSD/OS 3.1).
         * Take a safer side for now.
         */
         * compatible with some of kernel BPF code (for example BSD/OS 3.1).
         * Take a safer side for now.
         */
-       if (no_optimize)
-               p->fcode = *fp;
-       else if (p->sf.rfile != NULL)
-               p->fcode = *fp;
-       else if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
+       if (no_optimize) {
+               if (install_bpf_program(p, fp) < 0)
+                       return (-1);
+       } 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) {
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
                    pcap_strerror(errno));
                return (-1);
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
                    pcap_strerror(errno));
                return (-1);
index 608c8a23b81789c8f3c68b0ac4a0d59bec5abd60..153896a0f07d85a3c4757697bf6cccbbaf654bfa 100644 (file)
@@ -38,7 +38,7 @@
 
 #ifndef lint
 static const char rcsid[] =
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.61 2000-10-12 03:53:58 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.62 2000-10-28 00:01:28 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -555,7 +555,8 @@ int
 pcap_setfilter(pcap_t *p, struct bpf_program *fp)
 {
 
 pcap_setfilter(pcap_t *p, struct bpf_program *fp)
 {
 
-       p->fcode = *fp;
+       if (install_bpf_program(p, fp) < 0)
+               return (-1);
        return (0);
 }
 
        return (0);
 }
 
index d5e4f53d31df14ec8c37e5232916bd0a885b7ba4..f3a636f95039405775564f53b893c3ac2343f951 100644 (file)
@@ -26,7 +26,7 @@
  */
 #ifndef lint
 static const char rcsid[] =
  */
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.38 2000-10-25 07:46:50 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.39 2000-10-28 00:01:29 guy Exp $ (LBL)";
 #endif
 
 /*
 #endif
 
 /*
@@ -432,22 +432,13 @@ pcap_setfilter(pcap_t *handle, struct bpf_program *filter)
                return -1;
        }
 
                return -1;
        }
 
-       /* Free old filter code if existing */
-
-       pcap_freecode(handle, &handle->fcode);
-
        /* Make our private copy of the filter */
 
        /* Make our private copy of the filter */
 
-       handle->fcode.bf_len   = filter->bf_len;
-       handle->fcode.bf_insns = 
-               malloc(filter->bf_len * sizeof(*filter->bf_insns));
-       if (handle->fcode.bf_insns == NULL) {
+       if (install_bpf_program(handle, filter) < 0) {
                snprintf(handle->errbuf, sizeof(handle->errbuf),
                         "malloc: %s", pcap_strerror(errno));
                return -1;
                snprintf(handle->errbuf, sizeof(handle->errbuf),
                         "malloc: %s", pcap_strerror(errno));
                return -1;
-       } 
-       memcpy(handle->fcode.bf_insns, filter->bf_insns, 
-              filter->bf_len * sizeof(*filter->bf_insns));
+       }
 
        /* 
         * Run user level packet filter by default. Will be overriden if 
 
        /* 
         * Run user level packet filter by default. Will be overriden if 
index c15704b47191bcc5383de40b05df4bc00ef744f9..524d8c38343a8fd2fb073a71392986b0400d0165 100644 (file)
@@ -20,7 +20,7 @@
  */
 #ifndef lint
 static const char rcsid[] =
  */
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.38 2000-10-12 03:54:00 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.39 2000-10-28 00:01:29 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -245,6 +245,7 @@ int
 pcap_setfilter(pcap_t *p, struct bpf_program *fp)
 {
 
 pcap_setfilter(pcap_t *p, struct bpf_program *fp)
 {
 
-       p->fcode = *fp;
+       if (install_bpf_program(p, fp) < 0)
+               return (-1);
        return (0);
 }
        return (0);
 }
index 588c4d320a3c3c5a39ea1830cbe9ec63171854cb..e952c98824a72767177aa65060be3348ded113bd 100644 (file)
@@ -20,7 +20,7 @@
  */
 #ifndef lint
 static const char rcsid[] =
  */
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/libpcap/pcap-null.c,v 1.12 2000-07-11 00:37:06 assar Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/pcap-null.c,v 1.13 2000-10-28 00:01:29 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -68,6 +68,7 @@ pcap_setfilter(pcap_t *p, struct bpf_program *fp)
                    "pcap_setfilter: %s", nosup);
                return (-1);
        }
                    "pcap_setfilter: %s", nosup);
                return (-1);
        }
-       p->fcode = *fp;
+       if (install_bpf_program(p, fp) < 0)
+               return (-1);
        return (0);
 }
        return (0);
 }
index 58e85269b3a997aa13f90541af8dcd6063b5a66e..6a68a5041ce9c0d9784d8a599ad0fa7108f82bf3 100644 (file)
--- a/pcap-pf.c
+++ b/pcap-pf.c
@@ -24,7 +24,7 @@
 
 #ifndef lint
 static const char rcsid[] =
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.61 2000-10-12 03:54:00 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.62 2000-10-28 00:01:30 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -347,8 +347,10 @@ pcap_setfilter(pcap_t *p, struct bpf_program *fp)
                        /* don't give up, just be inefficient */
                        p->md.use_bpf = 0;
                }
                        /* don't give up, just be inefficient */
                        p->md.use_bpf = 0;
                }
-       } else
-               p->fcode = *fp;
+       } else {
+               if (install_bpf_program(p, fp) < 0)
+                       return (-1);
+       }
 
        /*XXX this goes in tcpdump*/
        if (p->md.use_bpf)
 
        /*XXX this goes in tcpdump*/
        if (p->md.use_bpf)
index e20a28aecddf7798f39b5f6c6c10f14c1787bc0d..47818e4fe01bb174acb20cfbc567c46f4867f8a1 100644 (file)
@@ -25,7 +25,7 @@
 
 #ifndef lint
 static const char rcsid[] =
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.53 2000-10-12 03:54:00 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.54 2000-10-28 00:01:30 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -302,6 +302,7 @@ int
 pcap_setfilter(pcap_t *p, struct bpf_program *fp)
 {
 
 pcap_setfilter(pcap_t *p, struct bpf_program *fp)
 {
 
-       p->fcode = *fp;
+       if (install_bpf_program(p, fp) < 0)
+               return (-1);
        return (0);
 }
        return (0);
 }
index 7268500cd09ec36192f5ba640fecf58d2ebf140b..82e51c4f55494189766fbc82e6c28baa0dead3fb 100644 (file)
@@ -20,7 +20,7 @@
  */
 #ifndef lint
 static const char rcsid[] =
  */
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.29 2000-10-12 03:54:01 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.30 2000-10-28 00:01:30 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -274,6 +274,7 @@ int
 pcap_setfilter(pcap_t *p, struct bpf_program *fp)
 {
 
 pcap_setfilter(pcap_t *p, struct bpf_program *fp)
 {
 
-       p->fcode = *fp;
+       if (install_bpf_program(p, fp) < 0)
+               return (-1);
        return (0);
 }
        return (0);
 }
diff --git a/pcap.3 b/pcap.3
index 18bcb4ad53aa3e7167af1e3aa7138da90078bbd5..2dc98ea7904f29a0b2c56b209c02e12aba08063a 100644 (file)
--- a/pcap.3
+++ b/pcap.3
@@ -1,4 +1,4 @@
-.\" @(#) $Header: /tcpdump/master/libpcap/Attic/pcap.3,v 1.12 2000-10-22 02:21:34 guy Exp $
+.\" @(#) $Header: /tcpdump/master/libpcap/Attic/pcap.3,v 1.13 2000-10-28 00:01:31 guy Exp $
 .\"
 .\" Copyright (c) 1994, 1996, 1997
 .\"    The Regents of the University of California.  All rights reserved.
 .\"
 .\" Copyright (c) 1994, 1996, 1997
 .\"    The Regents of the University of California.  All rights reserved.
@@ -62,6 +62,7 @@ int pcap_compile(pcap_t *p, struct bpf_program *fp,
 .ti +8
 char *str, int optimize, bpf_u_int32 netmask)
 int pcap_setfilter(pcap_t *p, struct bpf_program *fp)
 .ti +8
 char *str, int optimize, bpf_u_int32 netmask)
 int pcap_setfilter(pcap_t *p, struct bpf_program *fp)
+void pcap_freecode(struct bpf_program *);
 .ft
 .LP
 .ft B
 .ft
 .LP
 .ft B
@@ -256,14 +257,14 @@ is similar to
 .B pcap_compile()
 except that instead of passing a pcap structure, one passes the
 snaplen and linktype explicitly.  It is intended to be used for
 .B pcap_compile()
 except that instead of passing a pcap structure, one passes the
 snaplen and linktype explicitly.  It is intended to be used for
-compiling filters for direct bpf usage, without necessarily having
+compiling filters for direct BPF usage, without necessarily having
 called
 .BR pcap_open() .
 .PP
 .B pcap_setfilter()
 is used to specify a filter program.
 .I fp
 called
 .BR pcap_open() .
 .PP
 .B pcap_setfilter()
 is used to specify a filter program.
 .I fp
-is a pointer to an array of
+is a pointer to a
 .I bpf_program
 struct, usually the result of a call to
 .BR pcap_compile() .
 .I bpf_program
 struct, usually the result of a call to
 .BR pcap_compile() .
@@ -272,6 +273,15 @@ is returned on failure;
 .B 0
 is returned on success.
 .PP
 .B 0
 is returned on success.
 .PP
+.B pcap_freecode()
+is used to free up allocated memory pointed to by a
+.I bpf_program
+struct generated by
+.B pcap_compile()
+when that BPF program is no longer needed, for example after it
+has been made the filter program for a pcap structure by a call to
+.BR pcap_setfilter() .
+.PP
 .B pcap_loop()
 is similar to
 .B pcap_dispatch()
 .B pcap_loop()
 is similar to
 .B pcap_dispatch()
diff --git a/pcap.c b/pcap.c
index 72caa6fb6ee5edfb8ae606e348d4cebe58c94070..fd9dc9f1e55cc1ad9269db5bc97b4f1337498198 100644 (file)
--- a/pcap.c
+++ b/pcap.c
@@ -33,7 +33,7 @@
 
 #ifndef lint
 static const char rcsid[] =
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.34 2000-10-25 06:59:10 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.35 2000-10-28 00:01:31 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -219,8 +219,8 @@ pcap_close(pcap_t *p)
 #ifdef linux
        if (p->md.device != NULL)
                free(p->md.device);
 #ifdef linux
        if (p->md.device != NULL)
                free(p->md.device);
-       pcap_freecode(p, &p->fcode);
 #endif
        
 #endif
        
+       pcap_freecode(&p->fcode);
        free(p);
 }
        free(p);
 }
diff --git a/pcap.h b/pcap.h
index 57b7bc9c690c6eca5d0a7e0d91e37800223f02f3..7d62728f587a2a5363734f573adf46374442d27b 100644 (file)
--- a/pcap.h
+++ b/pcap.h
@@ -30,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.30 2000-10-25 06:59:10 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.31 2000-10-28 00:01:31 guy Exp $ (LBL)
  */
 
 #ifndef lib_pcap_h
  */
 
 #ifndef lib_pcap_h
@@ -150,7 +150,7 @@ int pcap_compile(pcap_t *, struct bpf_program *, char *, int,
            bpf_u_int32);
 int    pcap_compile_nopcap(int, int, struct bpf_program *,
            char *, int, bpf_u_int32);
            bpf_u_int32);
 int    pcap_compile_nopcap(int, int, struct bpf_program *,
            char *, int, bpf_u_int32);
-void   pcap_freecode(pcap_t *, struct bpf_program *);
+void   pcap_freecode(struct bpf_program *);
 int    pcap_datalink(pcap_t *);
 int    pcap_snapshot(pcap_t *);
 int    pcap_is_swapped(pcap_t *);
 int    pcap_datalink(pcap_t *);
 int    pcap_snapshot(pcap_t *);
 int    pcap_is_swapped(pcap_t *);