dect
/
libpcap
Archived
13
0
Fork 0

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:
guy 2000-10-28 00:01:26 +00:00
parent 188fee53cc
commit 82547471f7
14 changed files with 85 additions and 42 deletions

View File

@ -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) {

View File

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

View File

@ -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)

View File

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

View File

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

View File

@ -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

View File

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

View File

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

View File

@ -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)

View File

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

View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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 *);