*/
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.88 2005-04-21 02:41:12 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.89 2005-05-03 18:53:58 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "gencode.h" /* for "no_optimize" */
static int pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp);
+static int pcap_setdirection_bpf(pcap_t *, direction_t);
static int pcap_set_datalink_bpf(pcap_t *p, int dlt);
static int
p->read_op = pcap_read_bpf;
p->inject_op = pcap_inject_bpf;
p->setfilter_op = pcap_setfilter_bpf;
+ p->setdirection_op = pcap_setdirection_bpf;
p->set_datalink_op = pcap_set_datalink_bpf;
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
return (0);
}
+/*
+ * Set direction flag: Which packets do we accept on a forwarding
+ * single device? IN, OUT or both?
+ */
+static int
+pcap_setdirection_bpf(pcap_t *p, direction_t d)
+{
+#ifdef BIOCSSEESENT
+ u_int seesent;
+#endif
+
+ /*
+ * We don't support D_OUT.
+ */
+ if (d == D_OUT) {
+ snprintf(p->errbuf, sizeof(p->errbuf),
+ "Setting direction to D_OUT is not supported on BPF");
+ return -1;
+ }
+#ifdef BIOCSSEESENT
+ seesent = (d == D_INOUT);
+ if (ioctl(p->fd, BIOCSSEESENT, &seesent) == -1) {
+ (void) snprintf(p->errbuf, sizeof(p->errbuf),
+ "Cannot set direction to %s: %s",
+ (d == D_INOUT) ? "D_INOUT" : "D_IN",
+ strerror(errno));
+ return (-1);
+ }
+ return (0);
+#else
+ (void) snprintf(p->errbuf, sizeof(p->errbuf),
+ "This system doesn't support BIOCSSEESENT, so the direction can't be set");
+ return (-1);
+#endif
+}
+
static int
pcap_set_datalink_bpf(pcap_t *p, int dlt)
{
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.21 2005-04-03 23:56:47 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.22 2005-05-03 18:53:58 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
handle->read_op = dag_read;
handle->inject_op = dag_inject;
handle->setfilter_op = dag_setfilter;
+ handle->setdirection_op = NULL; /* Not implemented.*/
handle->set_datalink_op = dag_set_datalink;
handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = dag_setnonblock;
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.113 2005-04-17 17:25:51 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.114 2005-05-03 18:53:58 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
p->read_op = pcap_read_dlpi;
p->inject_op = pcap_inject_dlpi;
p->setfilter_op = install_bpf_program; /* no kernel filtering */
+ p->setdirection_op = NULL; /* Not implemented.*/
p->set_datalink_op = NULL; /* can't change data link type */
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
* pcap-dos.c: Interface to PKTDRVR, NDIS2 and 32-bit pmode
* network drivers.
*
- * @(#) $Header: /tcpdump/master/libpcap/pcap-dos.c,v 1.1 2004-12-18 08:52:10 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/libpcap/pcap-dos.c,v 1.2 2005-05-03 18:53:59 guy Exp $ (LBL)
*/
#include <stdio.h>
pcap->stats_op = pcap_stats_dos;
pcap->inject_op = pcap_sendpacket_dos;
pcap->setfilter_op = pcap_setfilter_dos;
+ pcap->setdirection_op = NULL; /* Not implemented.*/
pcap->fd = ++ref_count;
if (pcap->fd == 1) /* first time we're called */
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.70 2005-04-07 02:47:34 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.71 2005-05-03 18:53:59 guy Exp $ (LBL)
*/
#ifndef pcap_int_h
*/
u_char *pkt;
+ /* We're accepting only packets in this direction/these directions. */
+ direction_t direction;
+
/*
* Methods.
*/
int (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *);
int (*inject_op)(pcap_t *, const void *, size_t);
int (*setfilter_op)(pcap_t *, struct bpf_program *);
+ int (*setdirection_op)(pcap_t *, direction_t);
int (*set_datalink_op)(pcap_t *, int);
int (*getnonblock_op)(pcap_t *, char *);
int (*setnonblock_op)(pcap_t *, int, char *);
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.110 2004-10-19 07:06:12 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.111 2005-05-03 18:53:59 guy Exp $ (LBL)";
#endif
/*
static int pcap_inject_linux(pcap_t *, const void *, size_t);
static int pcap_stats_linux(pcap_t *, struct pcap_stat *);
static int pcap_setfilter_linux(pcap_t *, struct bpf_program *);
+static int pcap_setdirection_linux(pcap_t *, direction_t);
static void pcap_close_linux(pcap_t *);
/*
handle->read_op = pcap_read_linux;
handle->inject_op = pcap_inject_linux;
handle->setfilter_op = pcap_setfilter_linux;
+ handle->setdirection_op = pcap_setdirection_linux;
handle->set_datalink_op = NULL; /* can't change data link type */
handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = pcap_setnonblock_fd;
}
#ifdef HAVE_PF_PACKET_SOCKETS
- /*
- * If this is from the loopback device, reject outgoing packets;
- * we'll see the packet as an incoming packet as well, and
- * we don't want to see it twice.
- *
- * We can only do this if we're using PF_PACKET; the address
- * returned for SOCK_PACKET is a "sockaddr_pkt" which lacks
- * the relevant packet type information.
- */
- if (!handle->md.sock_packet &&
- from.sll_ifindex == handle->md.lo_ifindex &&
- from.sll_pkttype == PACKET_OUTGOING)
- return 0;
+ if (!handle->md.sock_packet) {
+ /*
+ * Do checks based on packet direction.
+ * We can only do this if we're using PF_PACKET; the
+ * address returned for SOCK_PACKET is a "sockaddr_pkt"
+ * which lacks the relevant packet type information.
+ */
+ if (from.sll_pkttype == PACKET_OUTGOING) {
+ /*
+ * Outgoing packet.
+ * If this is from the loopback device, reject it;
+ * we'll see the packet as an incoming packet as well,
+ * and we don't want to see it twice.
+ */
+ if (from.sll_ifindex == handle->md.lo_ifindex)
+ return 0;
+
+ /*
+ * If the user only wants incoming packets, reject it.
+ */
+ if (handle->direction == D_IN)
+ return 0;
+ } else {
+ /*
+ * Incoming packet.
+ * If the user only wants outgoing packets, reject it.
+ */
+ if (handle->direction == D_OUT)
+ return 0;
+ }
+ }
#endif
#ifdef HAVE_PF_PACKET_SOCKETS
return 0;
}
+/*
+ * Set direction flag: Which packets do we accept on a forwarding
+ * single device? IN, OUT or both?
+ */
+static int
+pcap_setdirection_linux(pcap_t *handle, direction_t d)
+{
+#ifdef HAVE_PF_PACKET_SOCKETS
+ if (!handle->md.sock_packet) {
+ handle->direction = d;
+ return 0;
+ }
+#endif
+ /*
+ * We're not using PF_PACKET sockets, so we can't determine
+ * the direction of the packet.
+ */
+ snprintf(handle->errbuf, sizeof(handle->errbuf),
+ "Setting direction is not supported on SOCK_PACKET sockets");
+ return -1;
+}
+
/*
* Linux uses the ARP hardware type to identify the type of an
* interface. pcap uses the DLT_xxx constants for this. This
*/
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.57 2004-10-19 07:06:13 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.58 2005-05-03 18:54:00 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
p->read_op = pcap_read_nit;
p->inject_op = pcap_inject_nit;
p->setfilter_op = install_bpf_program; /* no kernel filtering */
+ p->setdirection_op = NULL; /* Not implemented. */
p->set_datalink_op = NULL; /* can't change data link type */
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.92 2005-04-19 00:55:48 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.93 2005-05-03 18:54:00 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
p->read_op = pcap_read_pf;
p->inject_op = pcap_inject_pf;
p->setfilter_op = pcap_setfilter_pf;
+ p->setdirection_op = NULL; /* Not implemented. */
p->set_datalink_op = NULL; /* can't change data link type */
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.72 2004-10-19 07:06:13 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.73 2005-05-03 18:54:00 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
p->read_op = pcap_read_snit;
p->inject_op = pcap_inject_snit;
p->setfilter_op = install_bpf_program; /* no kernel filtering */
+ p->setdirection_op = NULL; /* Not implemented. */
p->set_datalink_op = NULL; /* can't change data link type */
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
*/
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.54 2004-10-19 07:06:14 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.55 2005-05-03 18:54:00 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
p->read_op = pcap_read_snoop;
p->inject_op = pcap_inject_snoop;
p->setfilter_op = install_bpf_program; /* no kernel filtering */
+ p->setdirection_op = NULL; /* Not implemented. */
p->set_datalink_op = NULL; /* can't change data link type */
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.25 2005-02-26 21:58:06 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.26 2005-05-03 18:54:01 guy Exp $ (LBL)";
#endif
#include <pcap-int.h>
#ifdef HAVE_DAG_API
}
#endif /* HAVE_DAG_API */
+ p->setdirection_op = NULL; /* Not implemented. */
+ /* XXX - can this be implemented on some versions of Windows? */
p->inject_op = pcap_inject_win32;
p->set_datalink_op = NULL; /* can't change data link type */
p->getnonblock_op = pcap_getnonblock_win32;
-.\" @(#) $Header: /tcpdump/master/libpcap/Attic/pcap.3,v 1.65 2005-04-13 18:59:41 mcr Exp $
+.\" @(#) $Header: /tcpdump/master/libpcap/Attic/pcap.3,v 1.66 2005-05-03 18:54:01 guy Exp $
.\"
.\" Copyright (c) 1994, 1996, 1997
.\" The Regents of the University of California. All rights reserved.
.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 *);
+void pcap_freecode(struct bpf_program *)
+int pcap_setdirection(pcap_t *p, direction_t d)
.ft
.LP
.ft B
has been made the filter program for a pcap structure by a call to
.BR pcap_setfilter() .
.PP
+.B pcap_setdirection()
+is used to specify a direction that packets will be captured.
+.I direction_t
+is one of the constants
+.BR D_IN ,
+.B D_OUT
+or
+.BR D_INOUT .
+.B D_IN
+will only capture packets received by the device,
+.B D_OUT
+will only capture packets sent by the device and
+.B D_INOUT
+will capture packets received by or sent by the device.
+.B D_INOUT
+is the default setting if this function is not called. This isn't
+necessarily supported on all platforms; some platforms might return an
+error, and some other platforms might not support
+.BR D_OUT .
+.B \-1
+is returned on failure,
+.B 0
+is returned on success.
+.PP
.B pcap_datalink()
returns the link layer type; link layer types it can return include:
.PP
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.88 2005-02-08 20:03:15 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.89 2005-05-03 18:54:01 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
return p->setfilter_op(p, fp);
}
+/*
+ * Set direction flag, which controls whether we accept only incoming
+ * packets, only outgoing packets, or both.
+ * Note that, depending on the platform, some or all direction arguments
+ * might not be supported.
+ */
+int
+pcap_setdirection(pcap_t *p, direction_t d)
+{
+ if (p->setdirection_op == NULL) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Setting direction is not implemented on this platform");
+ return -1;
+ } else
+ return p->setdirection_op(p, d);
+}
+
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.52 2004-12-18 08:52:11 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.53 2005-05-03 18:54:02 guy Exp $ (LBL)
*/
#ifndef lib_pcap_h
bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
};
+typedef enum {
+ D_INOUT = 0,
+ D_IN,
+ D_OUT
+} direction_t;
+
/*
* Each packet in the dump file is prepended with this generic header.
* This gets around the problem of different headers for different
void pcap_breakloop(pcap_t *);
int pcap_stats(pcap_t *, struct pcap_stat *);
int pcap_setfilter(pcap_t *, struct bpf_program *);
+int pcap_setdirection(pcap_t *, direction_t);
int pcap_getnonblock(pcap_t *, char *);
int pcap_setnonblock(pcap_t *, int, char *);
void pcap_perror(pcap_t *, char *);