When attaching a "bpf_program" to a "pcap_t" to use as a userland
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.
This commit is contained in:
parent
188fee53cc
commit
82547471f7
|
@ -21,7 +21,7 @@
|
|||
*/
|
||||
#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
|
||||
|
@ -377,7 +377,7 @@ pcap_compile_nopcap(int snaplen_arg, int linktype_arg,
|
|||
* 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) {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* 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. */
|
||||
|
@ -186,6 +186,7 @@ void finish_parse(struct block *);
|
|||
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);
|
||||
|
|
34
optimize.c
34
optimize.c
|
@ -22,7 +22,7 @@
|
|||
*/
|
||||
#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
|
||||
|
@ -36,6 +36,8 @@ static const char rcsid[] =
|
|||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
#include "gencode.h"
|
||||
|
@ -2077,6 +2079,36 @@ icode_to_fcode(root, lenp)
|
|||
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)
|
||||
|
|
14
pcap-bpf.c
14
pcap-bpf.c
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#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
|
||||
|
@ -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.
|
||||
*/
|
||||
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);
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
#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
|
||||
|
@ -555,7 +555,8 @@ int
|
|||
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
|
||||
{
|
||||
|
||||
p->fcode = *fp;
|
||||
if (install_bpf_program(p, fp) < 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
15
pcap-linux.c
15
pcap-linux.c
|
@ -26,7 +26,7 @@
|
|||
*/
|
||||
#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
|
||||
|
||||
/*
|
||||
|
@ -432,22 +432,13 @@ pcap_setfilter(pcap_t *handle, struct bpf_program *filter)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Free old filter code if existing */
|
||||
|
||||
pcap_freecode(handle, &handle->fcode);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
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
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#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
|
||||
|
@ -245,6 +245,7 @@ int
|
|||
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
|
||||
{
|
||||
|
||||
p->fcode = *fp;
|
||||
if (install_bpf_program(p, fp) < 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#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
|
||||
|
@ -68,6 +68,7 @@ pcap_setfilter(pcap_t *p, struct bpf_program *fp)
|
|||
"pcap_setfilter: %s", nosup);
|
||||
return (-1);
|
||||
}
|
||||
p->fcode = *fp;
|
||||
if (install_bpf_program(p, fp) < 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#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
|
||||
|
@ -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;
|
||||
}
|
||||
} else
|
||||
p->fcode = *fp;
|
||||
} else {
|
||||
if (install_bpf_program(p, fp) < 0)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*XXX this goes in tcpdump*/
|
||||
if (p->md.use_bpf)
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#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
|
||||
|
@ -302,6 +302,7 @@ int
|
|||
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
|
||||
{
|
||||
|
||||
p->fcode = *fp;
|
||||
if (install_bpf_program(p, fp) < 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#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
|
||||
|
@ -274,6 +274,7 @@ int
|
|||
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
|
||||
{
|
||||
|
||||
p->fcode = *fp;
|
||||
if (install_bpf_program(p, fp) < 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
|
16
pcap.3
16
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.
|
||||
|
@ -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)
|
||||
void pcap_freecode(struct bpf_program *);
|
||||
.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
|
||||
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
|
||||
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() .
|
||||
|
@ -272,6 +273,15 @@ is returned on failure;
|
|||
.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()
|
||||
|
|
4
pcap.c
4
pcap.c
|
@ -33,7 +33,7 @@
|
|||
|
||||
#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
|
||||
|
@ -219,8 +219,8 @@ pcap_close(pcap_t *p)
|
|||
#ifdef linux
|
||||
if (p->md.device != NULL)
|
||||
free(p->md.device);
|
||||
pcap_freecode(p, &p->fcode);
|
||||
#endif
|
||||
|
||||
pcap_freecode(&p->fcode);
|
||||
free(p);
|
||||
}
|
||||
|
|
4
pcap.h
4
pcap.h
|
@ -30,7 +30,7 @@
|
|||
* 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
|
||||
|
@ -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);
|
||||
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 *);
|
||||
|
|
Reference in New Issue