static int iface_get_mtu(int fd, const char *device, char *ebuf);
static int iface_get_arptype(int fd, const char *device, char *ebuf);
#ifdef HAVE_PF_PACKET_SOCKETS
-static int iface_bind(int fd, int ifindex, char *ebuf);
+static int iface_bind(int fd, int ifindex, char *ebuf, int protocol);
#ifdef IW_MODE_MONITOR
static int has_wext(int sock_fd, const char *device, char *ebuf);
#endif /* IW_MODE_MONITOR */
}
#endif /* IW_MODE_MONITOR */
+static int pcap_protocol(pcap_t *handle)
+{
+ int protocol;
+
+ protocol = handle->opt.protocol;
+ if (protocol == 0)
+ protocol = ETH_P_ALL;
+
+ return htons(protocol);
+}
+
static int
pcap_can_set_rfmon_linux(pcap_t *handle)
{
* (We assume that if we have Wireless Extensions support
* we also have PF_PACKET support.)
*/
- sock_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ sock_fd = socket(PF_PACKET, SOCK_RAW, pcap_protocol(handle));
if (sock_fd == -1) {
(void)pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
struct pcap_linux *handlep = handle->priv;
const char *device = handle->opt.device;
int is_any_device = (strcmp(device, "any") == 0);
+ int protocol = pcap_protocol(handle);
int sock_fd = -1, arptype;
#ifdef HAVE_PACKET_AUXDATA
int val;
* try a SOCK_RAW socket for the raw interface.
*/
sock_fd = is_any_device ?
- socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)) :
- socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ socket(PF_PACKET, SOCK_DGRAM, protocol) :
+ socket(PF_PACKET, SOCK_RAW, protocol);
if (sock_fd == -1) {
if (errno == EINVAL || errno == EAFNOSUPPORT) {
"close: %s", pcap_strerror(errno));
return PCAP_ERROR;
}
- sock_fd = socket(PF_PACKET, SOCK_DGRAM,
- htons(ETH_P_ALL));
+ sock_fd = socket(PF_PACKET, SOCK_DGRAM, protocol);
if (sock_fd == -1) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
}
if ((err = iface_bind(sock_fd, handlep->ifindex,
- handle->errbuf)) != 1) {
+ handle->errbuf, protocol)) != 1) {
close(sock_fd);
if (err < 0)
return err;
* or a PCAP_ERROR_ value on a hard error.
*/
static int
-iface_bind(int fd, int ifindex, char *ebuf)
+iface_bind(int fd, int ifindex, char *ebuf, int protocol)
{
struct sockaddr_ll sll;
int err;
memset(&sll, 0, sizeof(sll));
sll.sll_family = AF_PACKET;
sll.sll_ifindex = ifindex;
- sll.sll_protocol = htons(ETH_P_ALL);
+ sll.sll_protocol = protocol;
if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) == -1) {
if (errno == ENETDOWN) {
return ("without TPACKET");
#endif
}
+
+int
+pcap_set_protocol(pcap_t *p, int protocol)
+{
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+ p->opt.protocol = protocol;
+ return (0);
+}
--- /dev/null
+.\" Copyright (c) 1994, 1996, 1997
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that: (1) source code distributions
+.\" retain the above copyright notice and this paragraph in its entirety, (2)
+.\" distributions including binary code include the above copyright notice and
+.\" this paragraph in its entirety in the documentation or other materials
+.\" provided with the distribution, and (3) all advertising materials mentioning
+.\" features or use of this software display the following acknowledgement:
+.\" ``This product includes software developed by the University of California,
+.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+.\" the University nor the names of its contributors may be used to endorse
+.\" or promote products derived from this software without specific prior
+.\" written permission.
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.TH PCAP_SET_PROTOCOL 3PCAP "3 January 2014"
+.SH NAME
+pcap_set_protocol \- set capture protocol for a not-yet-activated
+capture handle
+.SH SYNOPSIS
+.nf
+.ft B
+#include <pcap/pcap.h>
+.LP
+.ft B
+int pcap_set_protocol(pcap_t *p, int protocol);
+.ft
+.fi
+.SH DESCRIPTION
+.B pcap_set_protocol()
+sets the capture protocol to use on a capture handle when the handle
+is activated.
+If
+.I protocol
+is non-zero, packets of that protocol will be captured when the
+handle is activated, otherwise, all packets will be captured. This
+function is only provided on Linux.
+.SH RETURN VALUE
+.B pcap_set_protocol()
+returns 0 on success or
+.B PCAP_ERROR_ACTIVATED
+if called on a capture handle that has been activated.
+.SH SEE ALSO
+pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP)