installs that copy; when closing a pcap_t on Linux, free that copy.
*/
#ifndef lint
static const char rcsid[] =
*/
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.123 2000-10-22 04:15:55 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.124 2000-10-25 06:59:09 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#endif
#ifdef HAVE_CONFIG_H
+/*
+ * Clean up a "struct bpf_program" by freeing all the memory allocated
+ * in it.
+ */
+void
+pcap_freecode(pcap_t *p, struct bpf_program *program)
+{
+ program->bf_len = 0;
+ if (program->bf_insns != NULL) {
+ free((char *)program->bf_insns);
+ program->bf_insns = NULL;
+ }
+}
+
/*
* Backpatch the blocks in 'list' to 'target'. The 'sense' field indicates
* which of the jt and jf fields has been resolved and which is a pointer
/*
* Backpatch the blocks in 'list' to 'target'. The 'sense' field indicates
* which of the jt and jf fields has been resolved and which is a pointer
*/
#ifndef lint
static const char rcsid[] =
*/
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.36 2000-10-25 05:59:04 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.37 2000-10-25 06:59:10 guy Exp $ (LBL)";
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
{
/* Allocate a handle for this session. */
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
{
/* Allocate a handle for this session. */
pcap_t *handle = malloc(sizeof(*handle));
if (handle == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_t *handle = malloc(sizeof(*handle));
if (handle == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
* to be compatible with older kernels for a while so we are
* trying both methods with the newer method preferred.
*/
* to be compatible with older kernels for a while so we are
* trying both methods with the newer method preferred.
*/
if (! (live_open_new(handle, device, promisc, to_ms, ebuf) ||
live_open_old(handle, device, promisc, to_ms, ebuf)) )
{
if (! (live_open_new(handle, device, promisc, to_ms, ebuf) ||
live_open_old(handle, device, promisc, to_ms, ebuf)) )
{
free(handle);
return NULL;
}
free(handle);
return NULL;
}
/*
* Okay, now we have a packet stream open. Maybe we need to handle
* a timeout? In that case we set the filehandle to nonblocking
/*
* Okay, now we have a packet stream open. Maybe we need to handle
* a timeout? In that case we set the filehandle to nonblocking
tv.tv_usec = (handle->md.timeout % 1000) * 1000;
tv.tv_sec = (handle->md.timeout / 1000);
}
tv.tv_usec = (handle->md.timeout % 1000) * 1000;
tv.tv_sec = (handle->md.timeout / 1000);
}
/*
* Read packets until the packet limit has been reached or
* an error occured while reading. Call the user function
/*
* Read packets until the packet limit has been reached or
* an error occured while reading. Call the user function
continue;
} else if (status == -1)
return -1;
continue;
} else if (status == -1)
return -1;
/*
* If no packet is available we go to sleep. FIXME: This
* might be better implemented using poll(?)
/*
* If no packet is available we go to sleep. FIXME: This
* might be better implemented using poll(?)
/*
* Read a packet from the socket calling the handler provided by
* the user. Returns the number of packets received or -1 if an
/*
* Read a packet from the socket calling the handler provided by
* the user. Returns the number of packets received or -1 if an
* We don't currently use the from return value of recvfrom but
* this will probably be implemented in the future.
*/
* We don't currently use the from return value of recvfrom but
* this will probably be implemented in the future.
*/
/* Receive a single packet from the kernel */
do {
/* Receive a single packet from the kernel */
do {
* tcpdump is currently fixed by changing the BPF code generator
* to not truncate the received packet.
*/
* tcpdump is currently fixed by changing the BPF code generator
* to not truncate the received packet.
*/
caplen = packet_len;
if (caplen > handle->snapshot)
caplen = handle->snapshot;
caplen = packet_len;
if (caplen > handle->snapshot)
caplen = handle->snapshot;
/* Fill in our own header data */
/* Fill in our own header data */
if (ioctl(handle->fd, SIOCGSTAMP, &pcap_header.ts) == -1) {
snprintf(handle->errbuf, sizeof(handle->errbuf),
"ioctl: %s", pcap_strerror(errno));
if (ioctl(handle->fd, SIOCGSTAMP, &pcap_header.ts) == -1) {
snprintf(handle->errbuf, sizeof(handle->errbuf),
"ioctl: %s", pcap_strerror(errno));
}
pcap_header.caplen = caplen;
pcap_header.len = packet_len;
}
pcap_header.caplen = caplen;
pcap_header.len = packet_len;
/* Call the user supplied callback function */
handle->md.stat.ps_recv++;
callback(userdata, &pcap_header, handle->buffer + handle->offset);
/* Call the user supplied callback function */
handle->md.stat.ps_recv++;
callback(userdata, &pcap_header, handle->buffer + handle->offset);
/* Free old filter code if existing */
/* Free old filter code if existing */
- handle->fcode.bf_len = 0;
- if (handle->fcode.bf_insns) {
- free(handle->fcode.bf_insns);
- handle->fcode.bf_insns = NULL;
- }
-
+ pcap_freecode(handle, &handle->fcode);
/* Make our private copy of the filter */
/* Make our private copy of the filter */
return 0;
/* Install kernel level filter if possible */
return 0;
/* Install kernel level filter if possible */
#ifdef SO_ATTACH_FILTER
/*
* Oh joy, the Linux kernel uses struct sock_fprog instead of
#ifdef SO_ATTACH_FILTER
/*
* Oh joy, the Linux kernel uses struct sock_fprog instead of
handle->linktype = map_arphrd_to_dlt(arptype);
} else
handle->linktype = DLT_RAW;
handle->linktype = map_arphrd_to_dlt(arptype);
} else
handle->linktype = DLT_RAW;
if (handle->linktype == -1) {
/* Unknown interface type - reopen in cooked mode */
if (handle->linktype == -1) {
/* Unknown interface type - reopen in cooked mode */
if (close(sock_fd) == -1) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"close: %s", pcap_strerror(errno));
if (close(sock_fd) == -1) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"close: %s", pcap_strerror(errno));
/* Compute the buffersize */
mtu = iface_get_mtu(sock_fd, device, ebuf);
if (mtu == -1)
break;
handle->bufsize = MAX_LINKHEADER_SIZE + mtu;
/* Compute the buffersize */
mtu = iface_get_mtu(sock_fd, device, ebuf);
if (mtu == -1)
break;
handle->bufsize = MAX_LINKHEADER_SIZE + mtu;
/* Fill in the pcap structure */
handle->fd = sock_fd;
/* Fill in the pcap structure */
handle->fd = sock_fd;
do {
/* Open the socket */
do {
/* Open the socket */
sock_fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
if (sock_fd == -1) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
sock_fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
if (sock_fd == -1) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
/* Compute the buffersize */
mtu = iface_get_mtu(sock_fd, device, ebuf);
/* Compute the buffersize */
mtu = iface_get_mtu(sock_fd, device, ebuf);
handle->bufsize = MAX_LINKHEADER_SIZE + mtu;
if (handle->bufsize < handle->snapshot)
handle->bufsize = handle->snapshot;
handle->bufsize = MAX_LINKHEADER_SIZE + mtu;
if (handle->bufsize < handle->snapshot)
handle->bufsize = handle->snapshot;
/* All done - fill in the pcap handle */
arptype = iface_get_arptype(sock_fd, device, ebuf);
/* All done - fill in the pcap handle */
arptype = iface_get_arptype(sock_fd, device, ebuf);
if (sock_fd != -1)
close(sock_fd);
return 0;
if (sock_fd != -1)
close(sock_fd);
return 0;
#ifndef lint
static const char rcsid[] =
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.33 2000-08-13 10:33:14 torsten Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.34 2000-10-25 06:59:10 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#endif
#ifdef HAVE_CONFIG_H
#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);
* 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.29 2000-10-12 04:16:52 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.30 2000-10-25 06:59:10 guy Exp $ (LBL)
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);
-/* XXX */
-int pcap_freecode(pcap_t *, struct bpf_program *);
+void pcap_freecode(pcap_t *, 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 *);