diff options
Diffstat (limited to 'contrib/libpcap/pcap-linux.c')
-rw-r--r-- | contrib/libpcap/pcap-linux.c | 87 |
1 files changed, 72 insertions, 15 deletions
diff --git a/contrib/libpcap/pcap-linux.c b/contrib/libpcap/pcap-linux.c index 89ad5c4..0cd6ca8 100644 --- a/contrib/libpcap/pcap-linux.c +++ b/contrib/libpcap/pcap-linux.c @@ -27,7 +27,7 @@ #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.110.2.2 2005/06/20 21:30:18 guy Exp $ (LBL)"; #endif /* @@ -83,6 +83,10 @@ static const char rcsid[] _U_ = #ifdef HAVE_DAG_API #include "pcap-dag.h" #endif /* HAVE_DAG_API */ + +#ifdef HAVE_SEPTEL_API +#include "pcap-septel.h" +#endif /* HAVE_SEPTEL_API */ #include <errno.h> #include <stdlib.h> @@ -191,6 +195,7 @@ static int pcap_read_packet(pcap_t *, pcap_handler, u_char *); 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 *); /* @@ -244,7 +249,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, } #endif /* HAVE_DAG_API */ - /* Allocate a handle for this session. */ +#ifdef HAVE_SEPTEL_API + if (strstr(device, "septel")) { + return septel_open_live(device, snaplen, promisc, to_ms, ebuf); + } +#endif /* HAVE_SEPTEL_API */ + + /* Allocate a handle for this session. */ handle = malloc(sizeof(*handle)); if (handle == NULL) { @@ -407,6 +418,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, 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; @@ -504,19 +516,37 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata) } #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 @@ -835,6 +865,11 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) return (-1); #endif /* HAVE_DAG_API */ +#ifdef HAVE_SEPTEL_API + if (septel_platform_finddevs(alldevsp, errbuf) < 0) + return (-1); +#endif /* HAVE_SEPTEL_API */ + return (0); } @@ -975,6 +1010,28 @@ pcap_setfilter_linux(pcap_t *handle, struct bpf_program *filter) } /* + * 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 * function takes a pointer to a "pcap_t", and an ARPHRD_xxx |