pcap-linux.c revision 242484
126175Sfenner/* 275107Sfenner * pcap-linux.c: Packet capture interface to the Linux kernel 326175Sfenner * 475107Sfenner * Copyright (c) 2000 Torsten Landschoff <torsten@debian.org> 575107Sfenner * Sebastian Krahmer <krahmer@cs.uni-potsdam.de> 6127664Sbms * 775107Sfenner * License: BSD 8127664Sbms * 975107Sfenner * Redistribution and use in source and binary forms, with or without 1075107Sfenner * modification, are permitted provided that the following conditions 1175107Sfenner * are met: 12127664Sbms * 1375107Sfenner * 1. Redistributions of source code must retain the above copyright 1475107Sfenner * notice, this list of conditions and the following disclaimer. 1575107Sfenner * 2. Redistributions in binary form must reproduce the above copyright 1675107Sfenner * notice, this list of conditions and the following disclaimer in 1775107Sfenner * the documentation and/or other materials provided with the 1875107Sfenner * distribution. 1975107Sfenner * 3. The names of the authors may not be used to endorse or promote 2075107Sfenner * products derived from this software without specific prior 2175107Sfenner * written permission. 22127664Sbms * 2375107Sfenner * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 2475107Sfenner * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 2575107Sfenner * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 26190225Srpaulo * 27190225Srpaulo * Modifications: Added PACKET_MMAP support 28190225Srpaulo * Paolo Abeni <paolo.abeni@email.it> 29190225Srpaulo * 30190225Srpaulo * based on previous works of: 31190225Srpaulo * Simon Patarin <patarin@cs.unibo.it> 32190225Srpaulo * Phil Wood <cpw@lanl.gov> 33214518Srpaulo * 34214518Srpaulo * Monitor-mode support for mac80211 includes code taken from the iw 35214518Srpaulo * command; the copyright notice for that code is 36214518Srpaulo * 37214518Srpaulo * Copyright (c) 2007, 2008 Johannes Berg 38214518Srpaulo * Copyright (c) 2007 Andy Lutomirski 39214518Srpaulo * Copyright (c) 2007 Mike Kershaw 40214518Srpaulo * Copyright (c) 2008 G��bor Stefanik 41214518Srpaulo * 42214518Srpaulo * All rights reserved. 43214518Srpaulo * 44214518Srpaulo * Redistribution and use in source and binary forms, with or without 45214518Srpaulo * modification, are permitted provided that the following conditions 46214518Srpaulo * are met: 47214518Srpaulo * 1. Redistributions of source code must retain the above copyright 48214518Srpaulo * notice, this list of conditions and the following disclaimer. 49214518Srpaulo * 2. Redistributions in binary form must reproduce the above copyright 50214518Srpaulo * notice, this list of conditions and the following disclaimer in the 51214518Srpaulo * documentation and/or other materials provided with the distribution. 52214518Srpaulo * 3. The name of the author may not be used to endorse or promote products 53214518Srpaulo * derived from this software without specific prior written permission. 54214518Srpaulo * 55214518Srpaulo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 56214518Srpaulo * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 57214518Srpaulo * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 58214518Srpaulo * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 59214518Srpaulo * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 60214518Srpaulo * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 61214518Srpaulo * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 62214518Srpaulo * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 63214518Srpaulo * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 64214518Srpaulo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 65214518Srpaulo * SUCH DAMAGE. 6626175Sfenner */ 67127664Sbms 6826175Sfenner#ifndef lint 69127664Sbmsstatic const char rcsid[] _U_ = 70214518Srpaulo "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.164 2008-12-14 22:00:57 guy Exp $ (LBL)"; 7126175Sfenner#endif 7226175Sfenner 7375107Sfenner/* 7475107Sfenner * Known problems with 2.0[.x] kernels: 7575107Sfenner * 7675107Sfenner * - The loopback device gives every packet twice; on 2.2[.x] kernels, 7775107Sfenner * if we use PF_PACKET, we can filter out the transmitted version 7875107Sfenner * of the packet by using data in the "sockaddr_ll" returned by 7975107Sfenner * "recvfrom()", but, on 2.0[.x] kernels, we have to use 8075107Sfenner * PF_INET/SOCK_PACKET, which means "recvfrom()" supplies a 8175107Sfenner * "sockaddr_pkt" which doesn't give us enough information to let 8275107Sfenner * us do that. 8375107Sfenner * 8475107Sfenner * - We have to set the interface's IFF_PROMISC flag ourselves, if 8575107Sfenner * we're to run in promiscuous mode, which means we have to turn 8675107Sfenner * it off ourselves when we're done; the kernel doesn't keep track 8775107Sfenner * of how many sockets are listening promiscuously, which means 8875107Sfenner * it won't get turned off automatically when no sockets are 8975107Sfenner * listening promiscuously. We catch "pcap_close()" and, for 9075107Sfenner * interfaces we put into promiscuous mode, take them out of 9175107Sfenner * promiscuous mode - which isn't necessarily the right thing to 9275107Sfenner * do, if another socket also requested promiscuous mode between 9375107Sfenner * the time when we opened the socket and the time when we close 9475107Sfenner * the socket. 9598530Sfenner * 9698530Sfenner * - MSG_TRUNC isn't supported, so you can't specify that "recvfrom()" 9798530Sfenner * return the amount of data that you could have read, rather than 9898530Sfenner * the amount that was returned, so we can't just allocate a buffer 9998530Sfenner * whose size is the snapshot length and pass the snapshot length 10098530Sfenner * as the byte count, and also pass MSG_TRUNC, so that the return 10198530Sfenner * value tells us how long the packet was on the wire. 10298530Sfenner * 10398530Sfenner * This means that, if we want to get the actual size of the packet, 10498530Sfenner * so we can return it in the "len" field of the packet header, 10598530Sfenner * we have to read the entire packet, not just the part that fits 10698530Sfenner * within the snapshot length, and thus waste CPU time copying data 10798530Sfenner * from the kernel that our caller won't see. 10898530Sfenner * 10998530Sfenner * We have to get the actual size, and supply it in "len", because 11098530Sfenner * otherwise, the IP dissector in tcpdump, for example, will complain 11198530Sfenner * about "truncated-ip", as the packet will appear to have been 11298530Sfenner * shorter, on the wire, than the IP header said it should have been. 11375107Sfenner */ 11426175Sfenner 11575107Sfenner 116214518Srpaulo#define _GNU_SOURCE 117214518Srpaulo 11875107Sfenner#ifdef HAVE_CONFIG_H 11975107Sfenner#include "config.h" 12039291Sfenner#endif 12126175Sfenner 12226175Sfenner#include <errno.h> 123214518Srpaulo#include <stdio.h> 12426175Sfenner#include <stdlib.h> 125214518Srpaulo#include <ctype.h> 12675107Sfenner#include <unistd.h> 12775107Sfenner#include <fcntl.h> 12826175Sfenner#include <string.h> 129214518Srpaulo#include <limits.h> 13075107Sfenner#include <sys/socket.h> 13175107Sfenner#include <sys/ioctl.h> 13275107Sfenner#include <sys/utsname.h> 133190225Srpaulo#include <sys/mman.h> 134214518Srpaulo#include <linux/if.h> 13575107Sfenner#include <netinet/in.h> 13675107Sfenner#include <linux/if_ether.h> 13775107Sfenner#include <net/if_arp.h> 138190225Srpaulo#include <poll.h> 139214518Srpaulo#include <dirent.h> 14026175Sfenner 141190225Srpaulo#include "pcap-int.h" 142190225Srpaulo#include "pcap/sll.h" 143190225Srpaulo#include "pcap/vlan.h" 144190225Srpaulo 145190225Srpaulo#ifdef HAVE_DAG_API 146190225Srpaulo#include "pcap-dag.h" 147190225Srpaulo#endif /* HAVE_DAG_API */ 148190225Srpaulo 149190225Srpaulo#ifdef HAVE_SEPTEL_API 150190225Srpaulo#include "pcap-septel.h" 151190225Srpaulo#endif /* HAVE_SEPTEL_API */ 152190225Srpaulo 153214518Srpaulo#ifdef HAVE_SNF_API 154214518Srpaulo#include "pcap-snf.h" 155214518Srpaulo#endif /* HAVE_SNF_API */ 156214518Srpaulo 157190225Srpaulo#ifdef PCAP_SUPPORT_USB 158190225Srpaulo#include "pcap-usb-linux.h" 159190225Srpaulo#endif 160190225Srpaulo 161190225Srpaulo#ifdef PCAP_SUPPORT_BT 162190225Srpaulo#include "pcap-bt-linux.h" 163190225Srpaulo#endif 164190225Srpaulo 165214518Srpaulo#ifdef PCAP_SUPPORT_CAN 166214518Srpaulo#include "pcap-can-linux.h" 167214518Srpaulo#endif 168214518Srpaulo 169242484Sdelphij#if PCAP_SUPPORT_CANUSB 170242484Sdelphij#include "pcap-canusb-linux.h" 171242484Sdelphij#endif 172242484Sdelphij 173236167Sdelphij#ifdef PCAP_SUPPORT_NETFILTER 174236167Sdelphij#include "pcap-netfilter-linux.h" 175236167Sdelphij#endif 176236167Sdelphij 177190225Srpaulo/* 17898530Sfenner * If PF_PACKET is defined, we can use {SOCK_RAW,SOCK_DGRAM}/PF_PACKET 17998530Sfenner * sockets rather than SOCK_PACKET sockets. 18098530Sfenner * 18198530Sfenner * To use them, we include <linux/if_packet.h> rather than 18298530Sfenner * <netpacket/packet.h>; we do so because 18398530Sfenner * 18498530Sfenner * some Linux distributions (e.g., Slackware 4.0) have 2.2 or 18598530Sfenner * later kernels and libc5, and don't provide a <netpacket/packet.h> 18698530Sfenner * file; 18798530Sfenner * 18898530Sfenner * not all versions of glibc2 have a <netpacket/packet.h> file 18998530Sfenner * that defines stuff needed for some of the 2.4-or-later-kernel 19098530Sfenner * features, so if the system has a 2.4 or later kernel, we 19198530Sfenner * still can't use those features. 19298530Sfenner * 19398530Sfenner * We're already including a number of other <linux/XXX.h> headers, and 19498530Sfenner * this code is Linux-specific (no other OS has PF_PACKET sockets as 19598530Sfenner * a raw packet capture mechanism), so it's not as if you gain any 19698530Sfenner * useful portability by using <netpacket/packet.h> 19798530Sfenner * 19898530Sfenner * XXX - should we just include <linux/if_packet.h> even if PF_PACKET 19998530Sfenner * isn't defined? It only defines one data structure in 2.0.x, so 20098530Sfenner * it shouldn't cause any problems. 20198530Sfenner */ 202127664Sbms#ifdef PF_PACKET 20398530Sfenner# include <linux/if_packet.h> 20426175Sfenner 20575107Sfenner /* 20698530Sfenner * On at least some Linux distributions (for example, Red Hat 5.2), 20798530Sfenner * there's no <netpacket/packet.h> file, but PF_PACKET is defined if 20898530Sfenner * you include <sys/socket.h>, but <linux/if_packet.h> doesn't define 20975107Sfenner * any of the PF_PACKET stuff such as "struct sockaddr_ll" or any of 21075107Sfenner * the PACKET_xxx stuff. 21175107Sfenner * 21275107Sfenner * So we check whether PACKET_HOST is defined, and assume that we have 21375107Sfenner * PF_PACKET sockets only if it is defined. 21475107Sfenner */ 21575107Sfenner# ifdef PACKET_HOST 21675107Sfenner# define HAVE_PF_PACKET_SOCKETS 217190225Srpaulo# ifdef PACKET_AUXDATA 218190225Srpaulo# define HAVE_PACKET_AUXDATA 219190225Srpaulo# endif /* PACKET_AUXDATA */ 22075107Sfenner# endif /* PACKET_HOST */ 221190225Srpaulo 222190225Srpaulo 223190225Srpaulo /* check for memory mapped access avaibility. We assume every needed 224190225Srpaulo * struct is defined if the macro TPACKET_HDRLEN is defined, because it 225190225Srpaulo * uses many ring related structs and macros */ 226190225Srpaulo# ifdef TPACKET_HDRLEN 227190225Srpaulo# define HAVE_PACKET_RING 228190225Srpaulo# ifdef TPACKET2_HDRLEN 229190225Srpaulo# define HAVE_TPACKET2 230190225Srpaulo# else 231190225Srpaulo# define TPACKET_V1 0 232190225Srpaulo# endif /* TPACKET2_HDRLEN */ 233190225Srpaulo# endif /* TPACKET_HDRLEN */ 23498530Sfenner#endif /* PF_PACKET */ 23575107Sfenner 23675107Sfenner#ifdef SO_ATTACH_FILTER 23775107Sfenner#include <linux/types.h> 23875107Sfenner#include <linux/filter.h> 23926175Sfenner#endif 24026175Sfenner 241236167Sdelphij/* 242236167Sdelphij * We need linux/sockios.h if we have linux/net_tstamp.h (for time stamp 243236167Sdelphij * specification) or linux/ethtool.h (for ethtool ioctls to get offloading 244236167Sdelphij * information). 245236167Sdelphij */ 246236167Sdelphij#if defined(HAVE_LINUX_NET_TSTAMP_H) || defined(HAVE_LINUX_ETHTOOL_H) 247236167Sdelphij#include <linux/sockios.h> 248236167Sdelphij#endif 249236167Sdelphij 250236167Sdelphij#ifdef HAVE_LINUX_NET_TSTAMP_H 251236167Sdelphij#include <linux/net_tstamp.h> 252236167Sdelphij#endif 253236167Sdelphij 254236167Sdelphij/* 255236167Sdelphij * Got Wireless Extensions? 256236167Sdelphij */ 257236167Sdelphij#ifdef HAVE_LINUX_WIRELESS_H 258236167Sdelphij#include <linux/wireless.h> 259236167Sdelphij#endif /* HAVE_LINUX_WIRELESS_H */ 260236167Sdelphij 261236167Sdelphij/* 262236167Sdelphij * Got libnl? 263236167Sdelphij */ 264236167Sdelphij#ifdef HAVE_LIBNL 265236167Sdelphij#include <linux/nl80211.h> 266236167Sdelphij 267236167Sdelphij#include <netlink/genl/genl.h> 268236167Sdelphij#include <netlink/genl/family.h> 269236167Sdelphij#include <netlink/genl/ctrl.h> 270236167Sdelphij#include <netlink/msg.h> 271236167Sdelphij#include <netlink/attr.h> 272236167Sdelphij#endif /* HAVE_LIBNL */ 273236167Sdelphij 274236167Sdelphij/* 275236167Sdelphij * Got ethtool support? 276236167Sdelphij */ 277236167Sdelphij#ifdef HAVE_LINUX_ETHTOOL_H 278236167Sdelphij#include <linux/ethtool.h> 279236167Sdelphij#endif 280236167Sdelphij 281190225Srpaulo#ifndef HAVE_SOCKLEN_T 28275107Sfennertypedef int socklen_t; 28375107Sfenner#endif 28426175Sfenner 28575107Sfenner#ifndef MSG_TRUNC 28698530Sfenner/* 28798530Sfenner * This is being compiled on a system that lacks MSG_TRUNC; define it 28898530Sfenner * with the value it has in the 2.2 and later kernels, so that, on 28998530Sfenner * those kernels, when we pass it in the flags argument to "recvfrom()" 29098530Sfenner * we're passing the right value and thus get the MSG_TRUNC behavior 29198530Sfenner * we want. (We don't get that behavior on 2.0[.x] kernels, because 29298530Sfenner * they didn't support MSG_TRUNC.) 29398530Sfenner */ 29498530Sfenner#define MSG_TRUNC 0x20 29575107Sfenner#endif 29675107Sfenner 297127664Sbms#ifndef SOL_PACKET 298127664Sbms/* 299127664Sbms * This is being compiled on a system that lacks SOL_PACKET; define it 300127664Sbms * with the value it has in the 2.2 and later kernels, so that we can 301127664Sbms * set promiscuous mode in the good modern way rather than the old 302127664Sbms * 2.0-kernel crappy way. 303127664Sbms */ 304127664Sbms#define SOL_PACKET 263 305127664Sbms#endif 306127664Sbms 30775107Sfenner#define MAX_LINKHEADER_SIZE 256 30875107Sfenner 309127664Sbms/* 310127664Sbms * When capturing on all interfaces we use this as the buffer size. 31175107Sfenner * Should be bigger then all MTUs that occur in real life. 31275107Sfenner * 64kB should be enough for now. 31375107Sfenner */ 31475107Sfenner#define BIGGER_THAN_ALL_MTUS (64*1024) 31575107Sfenner 31675107Sfenner/* 317190225Srpaulo * Prototypes for internal functions and methods. 31875107Sfenner */ 319127664Sbmsstatic void map_arphrd_to_dlt(pcap_t *, int, int); 320190225Srpaulo#ifdef HAVE_PF_PACKET_SOCKETS 321190225Srpaulostatic short int map_packet_type_to_sll_type(short int); 322190225Srpaulo#endif 323190225Srpaulostatic int pcap_activate_linux(pcap_t *); 324190225Srpaulostatic int activate_old(pcap_t *); 325190225Srpaulostatic int activate_new(pcap_t *); 326236167Sdelphijstatic int activate_mmap(pcap_t *, int *); 327190225Srpaulostatic int pcap_can_set_rfmon_linux(pcap_t *); 328127664Sbmsstatic int pcap_read_linux(pcap_t *, int, pcap_handler, u_char *); 32975107Sfennerstatic int pcap_read_packet(pcap_t *, pcap_handler, u_char *); 330146768Ssamstatic int pcap_inject_linux(pcap_t *, const void *, size_t); 331127664Sbmsstatic int pcap_stats_linux(pcap_t *, struct pcap_stat *); 332127664Sbmsstatic int pcap_setfilter_linux(pcap_t *, struct bpf_program *); 333162012Ssamstatic int pcap_setdirection_linux(pcap_t *, pcap_direction_t); 334190225Srpaulostatic void pcap_cleanup_linux(pcap_t *); 33575107Sfenner 336190225Srpaulounion thdr { 337190225Srpaulo struct tpacket_hdr *h1; 338190225Srpaulo struct tpacket2_hdr *h2; 339190225Srpaulo void *raw; 340190225Srpaulo}; 341190225Srpaulo 342190225Srpaulo#ifdef HAVE_PACKET_RING 343190225Srpaulo#define RING_GET_FRAME(h) (((union thdr **)h->buffer)[h->offset]) 344190225Srpaulo 345190225Srpaulostatic void destroy_ring(pcap_t *handle); 346236167Sdelphijstatic int create_ring(pcap_t *handle, int *status); 347190225Srpaulostatic int prepare_tpacket_socket(pcap_t *handle); 348190225Srpaulostatic void pcap_cleanup_linux_mmap(pcap_t *); 349190225Srpaulostatic int pcap_read_linux_mmap(pcap_t *, int, pcap_handler , u_char *); 350190225Srpaulostatic int pcap_setfilter_linux_mmap(pcap_t *, struct bpf_program *); 351190225Srpaulostatic int pcap_setnonblock_mmap(pcap_t *p, int nonblock, char *errbuf); 352190225Srpaulostatic int pcap_getnonblock_mmap(pcap_t *p, char *errbuf); 353214518Srpaulostatic void pcap_oneshot_mmap(u_char *user, const struct pcap_pkthdr *h, 354214518Srpaulo const u_char *bytes); 355190225Srpaulo#endif 356190225Srpaulo 35775107Sfenner/* 35875107Sfenner * Wrap some ioctl calls 35975107Sfenner */ 36075107Sfenner#ifdef HAVE_PF_PACKET_SOCKETS 36175107Sfennerstatic int iface_get_id(int fd, const char *device, char *ebuf); 362236167Sdelphij#endif /* HAVE_PF_PACKET_SOCKETS */ 36375107Sfennerstatic int iface_get_mtu(int fd, const char *device, char *ebuf); 36475107Sfennerstatic int iface_get_arptype(int fd, const char *device, char *ebuf); 36575107Sfenner#ifdef HAVE_PF_PACKET_SOCKETS 36675107Sfennerstatic int iface_bind(int fd, int ifindex, char *ebuf); 367214518Srpaulo#ifdef IW_MODE_MONITOR 368190225Srpaulostatic int has_wext(int sock_fd, const char *device, char *ebuf); 369214518Srpaulo#endif /* IW_MODE_MONITOR */ 370214518Srpaulostatic int enter_rfmon_mode(pcap_t *handle, int sock_fd, 371190225Srpaulo const char *device); 372214518Srpaulo#endif /* HAVE_PF_PACKET_SOCKETS */ 373236167Sdelphijstatic int iface_get_offload(pcap_t *handle); 37475107Sfennerstatic int iface_bind_old(int fd, const char *device, char *ebuf); 37575107Sfenner 37675107Sfenner#ifdef SO_ATTACH_FILTER 377214518Srpaulostatic int fix_program(pcap_t *handle, struct sock_fprog *fcode, 378214518Srpaulo int is_mapped); 37975107Sfennerstatic int fix_offset(struct bpf_insn *p); 38098530Sfennerstatic int set_kernel_filter(pcap_t *handle, struct sock_fprog *fcode); 38198530Sfennerstatic int reset_kernel_filter(pcap_t *handle); 38298530Sfenner 38398530Sfennerstatic struct sock_filter total_insn 38498530Sfenner = BPF_STMT(BPF_RET | BPF_K, 0); 38598530Sfennerstatic struct sock_fprog total_fcode 38698530Sfenner = { 1, &total_insn }; 387236167Sdelphij#endif /* SO_ATTACH_FILTER */ 38875107Sfenner 38975107Sfennerpcap_t * 390190225Srpaulopcap_create(const char *device, char *ebuf) 39126175Sfenner{ 392190225Srpaulo pcap_t *handle; 39398530Sfenner 394214518Srpaulo /* 395214518Srpaulo * A null device name is equivalent to the "any" device. 396214518Srpaulo */ 397214518Srpaulo if (device == NULL) 398214518Srpaulo device = "any"; 399214518Srpaulo 400127664Sbms#ifdef HAVE_DAG_API 401127664Sbms if (strstr(device, "dag")) { 402190225Srpaulo return dag_create(device, ebuf); 403127664Sbms } 404127664Sbms#endif /* HAVE_DAG_API */ 405127664Sbms 406147894Ssam#ifdef HAVE_SEPTEL_API 407147894Ssam if (strstr(device, "septel")) { 408190225Srpaulo return septel_create(device, ebuf); 409147894Ssam } 410147894Ssam#endif /* HAVE_SEPTEL_API */ 41126175Sfenner 412214518Srpaulo#ifdef HAVE_SNF_API 413214518Srpaulo handle = snf_create(device, ebuf); 414214518Srpaulo if (strstr(device, "snf") || handle != NULL) 415214518Srpaulo return handle; 416214518Srpaulo 417214518Srpaulo#endif /* HAVE_SNF_API */ 418214518Srpaulo 419190225Srpaulo#ifdef PCAP_SUPPORT_BT 420190225Srpaulo if (strstr(device, "bluetooth")) { 421190225Srpaulo return bt_create(device, ebuf); 422190225Srpaulo } 423190225Srpaulo#endif 424147894Ssam 425242484Sdelphij#if PCAP_SUPPORT_CANUSB 426242484Sdelphij if (strstr(device, "canusb")) { 427242484Sdelphij return canusb_create(device, ebuf); 428242484Sdelphij } 429242484Sdelphij#endif 430242484Sdelphij 431214518Srpaulo#ifdef PCAP_SUPPORT_CAN 432242484Sdelphij if ((strncmp(device, "can", 3) == 0 && isdigit(device[3])) || 433242484Sdelphij (strncmp(device, "vcan", 4) == 0 && isdigit(device[4]))) { 434214518Srpaulo return can_create(device, ebuf); 435214518Srpaulo } 436214518Srpaulo#endif 437214518Srpaulo 438190225Srpaulo#ifdef PCAP_SUPPORT_USB 439214518Srpaulo if (strstr(device, "usbmon")) { 440190225Srpaulo return usb_create(device, ebuf); 441190225Srpaulo } 442190225Srpaulo#endif 443190225Srpaulo 444236167Sdelphij#ifdef PCAP_SUPPORT_NETFILTER 445236167Sdelphij if (strncmp(device, "nflog", strlen("nflog")) == 0) { 446236167Sdelphij return nflog_create(device, ebuf); 447236167Sdelphij } 448236167Sdelphij#endif 449236167Sdelphij 450190225Srpaulo handle = pcap_create_common(device, ebuf); 451190225Srpaulo if (handle == NULL) 45275107Sfenner return NULL; 453190225Srpaulo 454190225Srpaulo handle->activate_op = pcap_activate_linux; 455190225Srpaulo handle->can_set_rfmon_op = pcap_can_set_rfmon_linux; 456236167Sdelphij#if defined(HAVE_LINUX_NET_TSTAMP_H) && defined(PACKET_TIMESTAMP) 457236167Sdelphij /* 458236167Sdelphij * We claim that we support: 459236167Sdelphij * 460236167Sdelphij * software time stamps, with no details about their precision; 461236167Sdelphij * hardware time stamps, synced to the host time; 462236167Sdelphij * hardware time stamps, not synced to the host time. 463236167Sdelphij * 464236167Sdelphij * XXX - we can't ask a device whether it supports 465236167Sdelphij * hardware time stamps, so we just claim all devices do. 466236167Sdelphij */ 467236167Sdelphij handle->tstamp_type_count = 3; 468236167Sdelphij handle->tstamp_type_list = malloc(3 * sizeof(u_int)); 469236167Sdelphij if (handle->tstamp_type_list == NULL) { 470236167Sdelphij free(handle); 471236167Sdelphij return NULL; 472236167Sdelphij } 473236167Sdelphij handle->tstamp_type_list[0] = PCAP_TSTAMP_HOST; 474236167Sdelphij handle->tstamp_type_list[1] = PCAP_TSTAMP_ADAPTER; 475236167Sdelphij handle->tstamp_type_list[2] = PCAP_TSTAMP_ADAPTER_UNSYNCED; 476236167Sdelphij#endif 477236167Sdelphij 478190225Srpaulo return handle; 479190225Srpaulo} 480190225Srpaulo 481214518Srpaulo#ifdef HAVE_LIBNL 482214518Srpaulo/* 483236167Sdelphij * If interface {if} is a mac80211 driver, the file 484236167Sdelphij * /sys/class/net/{if}/phy80211 is a symlink to 485236167Sdelphij * /sys/class/ieee80211/{phydev}, for some {phydev}. 486236167Sdelphij * 487236167Sdelphij * On Fedora 9, with a 2.6.26.3-29 kernel, my Zydas stick, at 488236167Sdelphij * least, has a "wmaster0" device and a "wlan0" device; the 489236167Sdelphij * latter is the one with the IP address. Both show up in 490236167Sdelphij * "tcpdump -D" output. Capturing on the wmaster0 device 491236167Sdelphij * captures with 802.11 headers. 492236167Sdelphij * 493236167Sdelphij * airmon-ng searches through /sys/class/net for devices named 494236167Sdelphij * monN, starting with mon0; as soon as one *doesn't* exist, 495236167Sdelphij * it chooses that as the monitor device name. If the "iw" 496236167Sdelphij * command exists, it does "iw dev {if} interface add {monif} 497236167Sdelphij * type monitor", where {monif} is the monitor device. It 498236167Sdelphij * then (sigh) sleeps .1 second, and then configures the 499236167Sdelphij * device up. Otherwise, if /sys/class/ieee80211/{phydev}/add_iface 500236167Sdelphij * is a file, it writes {mondev}, without a newline, to that file, 501236167Sdelphij * and again (sigh) sleeps .1 second, and then iwconfig's that 502236167Sdelphij * device into monitor mode and configures it up. Otherwise, 503236167Sdelphij * you can't do monitor mode. 504236167Sdelphij * 505236167Sdelphij * All these devices are "glued" together by having the 506236167Sdelphij * /sys/class/net/{device}/phy80211 links pointing to the same 507236167Sdelphij * place, so, given a wmaster, wlan, or mon device, you can 508236167Sdelphij * find the other devices by looking for devices with 509236167Sdelphij * the same phy80211 link. 510236167Sdelphij * 511236167Sdelphij * To turn monitor mode off, delete the monitor interface, 512236167Sdelphij * either with "iw dev {monif} interface del" or by sending 513236167Sdelphij * {monif}, with no NL, down /sys/class/ieee80211/{phydev}/remove_iface 514236167Sdelphij * 515236167Sdelphij * Note: if you try to create a monitor device named "monN", and 516236167Sdelphij * there's already a "monN" device, it fails, as least with 517236167Sdelphij * the netlink interface (which is what iw uses), with a return 518236167Sdelphij * value of -ENFILE. (Return values are negative errnos.) We 519236167Sdelphij * could probably use that to find an unused device. 520236167Sdelphij * 521236167Sdelphij * Yes, you can have multiple monitor devices for a given 522236167Sdelphij * physical device. 523214518Srpaulo*/ 524214518Srpaulo 525214518Srpaulo/* 526214518Srpaulo * Is this a mac80211 device? If so, fill in the physical device path and 527214518Srpaulo * return 1; if not, return 0. On an error, fill in handle->errbuf and 528214518Srpaulo * return PCAP_ERROR. 529214518Srpaulo */ 530190225Srpaulostatic int 531214518Srpauloget_mac80211_phydev(pcap_t *handle, const char *device, char *phydev_path, 532214518Srpaulo size_t phydev_max_pathlen) 533190225Srpaulo{ 534214518Srpaulo char *pathstr; 535214518Srpaulo ssize_t bytes_read; 536214518Srpaulo 537214518Srpaulo /* 538214518Srpaulo * Generate the path string for the symlink to the physical device. 539214518Srpaulo */ 540214518Srpaulo if (asprintf(&pathstr, "/sys/class/net/%s/phy80211", device) == -1) { 541214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 542214518Srpaulo "%s: Can't generate path name string for /sys/class/net device", 543214518Srpaulo device); 544214518Srpaulo return PCAP_ERROR; 545214518Srpaulo } 546214518Srpaulo bytes_read = readlink(pathstr, phydev_path, phydev_max_pathlen); 547214518Srpaulo if (bytes_read == -1) { 548214518Srpaulo if (errno == ENOENT || errno == EINVAL) { 549214518Srpaulo /* 550214518Srpaulo * Doesn't exist, or not a symlink; assume that 551214518Srpaulo * means it's not a mac80211 device. 552214518Srpaulo */ 553214518Srpaulo free(pathstr); 554214518Srpaulo return 0; 555214518Srpaulo } 556214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 557214518Srpaulo "%s: Can't readlink %s: %s", device, pathstr, 558214518Srpaulo strerror(errno)); 559214518Srpaulo free(pathstr); 560214518Srpaulo return PCAP_ERROR; 561214518Srpaulo } 562214518Srpaulo free(pathstr); 563214518Srpaulo phydev_path[bytes_read] = '\0'; 564214518Srpaulo return 1; 565214518Srpaulo} 566214518Srpaulo 567236167Sdelphij#ifdef HAVE_LIBNL_2_x 568236167Sdelphij#define get_nl_errmsg nl_geterror 569236167Sdelphij#else 570236167Sdelphij/* libnl 2.x compatibility code */ 571236167Sdelphij 572236167Sdelphij#define nl_sock nl_handle 573236167Sdelphij 574236167Sdelphijstatic inline struct nl_handle * 575236167Sdelphijnl_socket_alloc(void) 576236167Sdelphij{ 577236167Sdelphij return nl_handle_alloc(); 578236167Sdelphij} 579236167Sdelphij 580236167Sdelphijstatic inline void 581236167Sdelphijnl_socket_free(struct nl_handle *h) 582236167Sdelphij{ 583236167Sdelphij nl_handle_destroy(h); 584236167Sdelphij} 585236167Sdelphij 586236167Sdelphij#define get_nl_errmsg strerror 587236167Sdelphij 588236167Sdelphijstatic inline int 589236167Sdelphij__genl_ctrl_alloc_cache(struct nl_handle *h, struct nl_cache **cache) 590236167Sdelphij{ 591236167Sdelphij struct nl_cache *tmp = genl_ctrl_alloc_cache(h); 592236167Sdelphij if (!tmp) 593236167Sdelphij return -ENOMEM; 594236167Sdelphij *cache = tmp; 595236167Sdelphij return 0; 596236167Sdelphij} 597236167Sdelphij#define genl_ctrl_alloc_cache __genl_ctrl_alloc_cache 598236167Sdelphij#endif /* !HAVE_LIBNL_2_x */ 599236167Sdelphij 600214518Srpaulostruct nl80211_state { 601236167Sdelphij struct nl_sock *nl_sock; 602214518Srpaulo struct nl_cache *nl_cache; 603214518Srpaulo struct genl_family *nl80211; 604214518Srpaulo}; 605214518Srpaulo 606214518Srpaulostatic int 607214518Srpaulonl80211_init(pcap_t *handle, struct nl80211_state *state, const char *device) 608214518Srpaulo{ 609236167Sdelphij int err; 610236167Sdelphij 611236167Sdelphij state->nl_sock = nl_socket_alloc(); 612236167Sdelphij if (!state->nl_sock) { 613214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 614214518Srpaulo "%s: failed to allocate netlink handle", device); 615214518Srpaulo return PCAP_ERROR; 616214518Srpaulo } 617214518Srpaulo 618236167Sdelphij if (genl_connect(state->nl_sock)) { 619214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 620214518Srpaulo "%s: failed to connect to generic netlink", device); 621214518Srpaulo goto out_handle_destroy; 622214518Srpaulo } 623214518Srpaulo 624236167Sdelphij err = genl_ctrl_alloc_cache(state->nl_sock, &state->nl_cache); 625236167Sdelphij if (err < 0) { 626214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 627236167Sdelphij "%s: failed to allocate generic netlink cache: %s", 628236167Sdelphij device, get_nl_errmsg(-err)); 629214518Srpaulo goto out_handle_destroy; 630214518Srpaulo } 631214518Srpaulo 632214518Srpaulo state->nl80211 = genl_ctrl_search_by_name(state->nl_cache, "nl80211"); 633214518Srpaulo if (!state->nl80211) { 634214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 635214518Srpaulo "%s: nl80211 not found", device); 636214518Srpaulo goto out_cache_free; 637214518Srpaulo } 638214518Srpaulo 639214518Srpaulo return 0; 640214518Srpaulo 641214518Srpauloout_cache_free: 642214518Srpaulo nl_cache_free(state->nl_cache); 643214518Srpauloout_handle_destroy: 644236167Sdelphij nl_socket_free(state->nl_sock); 645214518Srpaulo return PCAP_ERROR; 646214518Srpaulo} 647214518Srpaulo 648214518Srpaulostatic void 649214518Srpaulonl80211_cleanup(struct nl80211_state *state) 650214518Srpaulo{ 651214518Srpaulo genl_family_put(state->nl80211); 652214518Srpaulo nl_cache_free(state->nl_cache); 653236167Sdelphij nl_socket_free(state->nl_sock); 654214518Srpaulo} 655214518Srpaulo 656214518Srpaulostatic int 657214518Srpauloadd_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state, 658214518Srpaulo const char *device, const char *mondevice) 659214518Srpaulo{ 660214518Srpaulo int ifindex; 661214518Srpaulo struct nl_msg *msg; 662214518Srpaulo int err; 663214518Srpaulo 664214518Srpaulo ifindex = iface_get_id(sock_fd, device, handle->errbuf); 665214518Srpaulo if (ifindex == -1) 666214518Srpaulo return PCAP_ERROR; 667214518Srpaulo 668214518Srpaulo msg = nlmsg_alloc(); 669214518Srpaulo if (!msg) { 670214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 671214518Srpaulo "%s: failed to allocate netlink msg", device); 672214518Srpaulo return PCAP_ERROR; 673214518Srpaulo } 674214518Srpaulo 675214518Srpaulo genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0, 676214518Srpaulo 0, NL80211_CMD_NEW_INTERFACE, 0); 677214518Srpaulo NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex); 678214518Srpaulo NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, mondevice); 679214518Srpaulo NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR); 680214518Srpaulo 681236167Sdelphij err = nl_send_auto_complete(state->nl_sock, msg); 682214518Srpaulo if (err < 0) { 683236167Sdelphij#ifdef HAVE_LIBNL_2_x 684236167Sdelphij if (err == -NLE_FAILURE) { 685236167Sdelphij#else 686214518Srpaulo if (err == -ENFILE) { 687236167Sdelphij#endif 688214518Srpaulo /* 689214518Srpaulo * Device not available; our caller should just 690236167Sdelphij * keep trying. (libnl 2.x maps ENFILE to 691236167Sdelphij * NLE_FAILURE; it can also map other errors 692236167Sdelphij * to that, but there's not much we can do 693236167Sdelphij * about that.) 694214518Srpaulo */ 695214518Srpaulo nlmsg_free(msg); 696214518Srpaulo return 0; 697214518Srpaulo } else { 698214518Srpaulo /* 699214518Srpaulo * Real failure, not just "that device is not 700214518Srpaulo * available. 701214518Srpaulo */ 702214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 703214518Srpaulo "%s: nl_send_auto_complete failed adding %s interface: %s", 704236167Sdelphij device, mondevice, get_nl_errmsg(-err)); 705214518Srpaulo nlmsg_free(msg); 706214518Srpaulo return PCAP_ERROR; 707214518Srpaulo } 708214518Srpaulo } 709236167Sdelphij err = nl_wait_for_ack(state->nl_sock); 710214518Srpaulo if (err < 0) { 711236167Sdelphij#ifdef HAVE_LIBNL_2_x 712236167Sdelphij if (err == -NLE_FAILURE) { 713236167Sdelphij#else 714214518Srpaulo if (err == -ENFILE) { 715236167Sdelphij#endif 716214518Srpaulo /* 717214518Srpaulo * Device not available; our caller should just 718236167Sdelphij * keep trying. (libnl 2.x maps ENFILE to 719236167Sdelphij * NLE_FAILURE; it can also map other errors 720236167Sdelphij * to that, but there's not much we can do 721236167Sdelphij * about that.) 722214518Srpaulo */ 723214518Srpaulo nlmsg_free(msg); 724214518Srpaulo return 0; 725214518Srpaulo } else { 726214518Srpaulo /* 727214518Srpaulo * Real failure, not just "that device is not 728214518Srpaulo * available. 729214518Srpaulo */ 730214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 731214518Srpaulo "%s: nl_wait_for_ack failed adding %s interface: %s", 732236167Sdelphij device, mondevice, get_nl_errmsg(-err)); 733214518Srpaulo nlmsg_free(msg); 734214518Srpaulo return PCAP_ERROR; 735214518Srpaulo } 736214518Srpaulo } 737214518Srpaulo 738214518Srpaulo /* 739214518Srpaulo * Success. 740214518Srpaulo */ 741214518Srpaulo nlmsg_free(msg); 742214518Srpaulo return 1; 743214518Srpaulo 744214518Srpaulonla_put_failure: 745214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 746214518Srpaulo "%s: nl_put failed adding %s interface", 747214518Srpaulo device, mondevice); 748214518Srpaulo nlmsg_free(msg); 749214518Srpaulo return PCAP_ERROR; 750214518Srpaulo} 751214518Srpaulo 752214518Srpaulostatic int 753214518Srpaulodel_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state, 754214518Srpaulo const char *device, const char *mondevice) 755214518Srpaulo{ 756214518Srpaulo int ifindex; 757214518Srpaulo struct nl_msg *msg; 758214518Srpaulo int err; 759214518Srpaulo 760214518Srpaulo ifindex = iface_get_id(sock_fd, mondevice, handle->errbuf); 761214518Srpaulo if (ifindex == -1) 762214518Srpaulo return PCAP_ERROR; 763214518Srpaulo 764214518Srpaulo msg = nlmsg_alloc(); 765214518Srpaulo if (!msg) { 766214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 767214518Srpaulo "%s: failed to allocate netlink msg", device); 768214518Srpaulo return PCAP_ERROR; 769214518Srpaulo } 770214518Srpaulo 771214518Srpaulo genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0, 772214518Srpaulo 0, NL80211_CMD_DEL_INTERFACE, 0); 773214518Srpaulo NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex); 774214518Srpaulo 775236167Sdelphij err = nl_send_auto_complete(state->nl_sock, msg); 776214518Srpaulo if (err < 0) { 777236167Sdelphij snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 778236167Sdelphij "%s: nl_send_auto_complete failed deleting %s interface: %s", 779236167Sdelphij device, mondevice, get_nl_errmsg(-err)); 780236167Sdelphij nlmsg_free(msg); 781236167Sdelphij return PCAP_ERROR; 782214518Srpaulo } 783236167Sdelphij err = nl_wait_for_ack(state->nl_sock); 784214518Srpaulo if (err < 0) { 785236167Sdelphij snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 786236167Sdelphij "%s: nl_wait_for_ack failed adding %s interface: %s", 787236167Sdelphij device, mondevice, get_nl_errmsg(-err)); 788236167Sdelphij nlmsg_free(msg); 789236167Sdelphij return PCAP_ERROR; 790214518Srpaulo } 791214518Srpaulo 792214518Srpaulo /* 793214518Srpaulo * Success. 794214518Srpaulo */ 795214518Srpaulo nlmsg_free(msg); 796214518Srpaulo return 1; 797214518Srpaulo 798214518Srpaulonla_put_failure: 799214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 800214518Srpaulo "%s: nl_put failed deleting %s interface", 801214518Srpaulo device, mondevice); 802214518Srpaulo nlmsg_free(msg); 803214518Srpaulo return PCAP_ERROR; 804214518Srpaulo} 805214518Srpaulo 806214518Srpaulostatic int 807214518Srpauloenter_rfmon_mode_mac80211(pcap_t *handle, int sock_fd, const char *device) 808214518Srpaulo{ 809214518Srpaulo int ret; 810214518Srpaulo char phydev_path[PATH_MAX+1]; 811214518Srpaulo struct nl80211_state nlstate; 812214518Srpaulo struct ifreq ifr; 813214518Srpaulo u_int n; 814214518Srpaulo 815214518Srpaulo /* 816214518Srpaulo * Is this a mac80211 device? 817214518Srpaulo */ 818214518Srpaulo ret = get_mac80211_phydev(handle, device, phydev_path, PATH_MAX); 819214518Srpaulo if (ret < 0) 820214518Srpaulo return ret; /* error */ 821214518Srpaulo if (ret == 0) 822214518Srpaulo return 0; /* no error, but not mac80211 device */ 823214518Srpaulo 824214518Srpaulo /* 825214518Srpaulo * XXX - is this already a monN device? 826214518Srpaulo * If so, we're done. 827214518Srpaulo * Is that determined by old Wireless Extensions ioctls? 828214518Srpaulo */ 829214518Srpaulo 830214518Srpaulo /* 831214518Srpaulo * OK, it's apparently a mac80211 device. 832214518Srpaulo * Try to find an unused monN device for it. 833214518Srpaulo */ 834214518Srpaulo ret = nl80211_init(handle, &nlstate, device); 835214518Srpaulo if (ret != 0) 836214518Srpaulo return ret; 837214518Srpaulo for (n = 0; n < UINT_MAX; n++) { 838214518Srpaulo /* 839214518Srpaulo * Try mon{n}. 840214518Srpaulo */ 841214518Srpaulo char mondevice[3+10+1]; /* mon{UINT_MAX}\0 */ 842214518Srpaulo 843214518Srpaulo snprintf(mondevice, sizeof mondevice, "mon%u", n); 844214518Srpaulo ret = add_mon_if(handle, sock_fd, &nlstate, device, mondevice); 845214518Srpaulo if (ret == 1) { 846214518Srpaulo handle->md.mondevice = strdup(mondevice); 847214518Srpaulo goto added; 848214518Srpaulo } 849214518Srpaulo if (ret < 0) { 850214518Srpaulo /* 851214518Srpaulo * Hard failure. Just return ret; handle->errbuf 852214518Srpaulo * has already been set. 853214518Srpaulo */ 854214518Srpaulo nl80211_cleanup(&nlstate); 855214518Srpaulo return ret; 856214518Srpaulo } 857214518Srpaulo } 858214518Srpaulo 859214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 860214518Srpaulo "%s: No free monN interfaces", device); 861214518Srpaulo nl80211_cleanup(&nlstate); 862214518Srpaulo return PCAP_ERROR; 863214518Srpaulo 864214518Srpauloadded: 865214518Srpaulo 866214518Srpaulo#if 0 867214518Srpaulo /* 868214518Srpaulo * Sleep for .1 seconds. 869214518Srpaulo */ 870214518Srpaulo delay.tv_sec = 0; 871214518Srpaulo delay.tv_nsec = 500000000; 872214518Srpaulo nanosleep(&delay, NULL); 873214518Srpaulo#endif 874214518Srpaulo 875214518Srpaulo /* 876236167Sdelphij * If we haven't already done so, arrange to have 877236167Sdelphij * "pcap_close_all()" called when we exit. 878236167Sdelphij */ 879236167Sdelphij if (!pcap_do_addexit(handle)) { 880236167Sdelphij /* 881236167Sdelphij * "atexit()" failed; don't put the interface 882236167Sdelphij * in rfmon mode, just give up. 883236167Sdelphij */ 884236167Sdelphij return PCAP_ERROR_RFMON_NOTSUP; 885236167Sdelphij } 886236167Sdelphij 887236167Sdelphij /* 888214518Srpaulo * Now configure the monitor interface up. 889214518Srpaulo */ 890214518Srpaulo memset(&ifr, 0, sizeof(ifr)); 891214518Srpaulo strncpy(ifr.ifr_name, handle->md.mondevice, sizeof(ifr.ifr_name)); 892214518Srpaulo if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) == -1) { 893214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 894214518Srpaulo "%s: Can't get flags for %s: %s", device, 895214518Srpaulo handle->md.mondevice, strerror(errno)); 896214518Srpaulo del_mon_if(handle, sock_fd, &nlstate, device, 897214518Srpaulo handle->md.mondevice); 898214518Srpaulo nl80211_cleanup(&nlstate); 899214518Srpaulo return PCAP_ERROR; 900214518Srpaulo } 901214518Srpaulo ifr.ifr_flags |= IFF_UP|IFF_RUNNING; 902214518Srpaulo if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1) { 903214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 904214518Srpaulo "%s: Can't set flags for %s: %s", device, 905214518Srpaulo handle->md.mondevice, strerror(errno)); 906214518Srpaulo del_mon_if(handle, sock_fd, &nlstate, device, 907214518Srpaulo handle->md.mondevice); 908214518Srpaulo nl80211_cleanup(&nlstate); 909214518Srpaulo return PCAP_ERROR; 910214518Srpaulo } 911214518Srpaulo 912214518Srpaulo /* 913214518Srpaulo * Success. Clean up the libnl state. 914214518Srpaulo */ 915214518Srpaulo nl80211_cleanup(&nlstate); 916214518Srpaulo 917214518Srpaulo /* 918214518Srpaulo * Note that we have to delete the monitor device when we close 919214518Srpaulo * the handle. 920214518Srpaulo */ 921214518Srpaulo handle->md.must_do_on_close |= MUST_DELETE_MONIF; 922214518Srpaulo 923214518Srpaulo /* 924214518Srpaulo * Add this to the list of pcaps to close when we exit. 925214518Srpaulo */ 926214518Srpaulo pcap_add_to_pcaps_to_close(handle); 927214518Srpaulo 928214518Srpaulo return 1; 929214518Srpaulo} 930214518Srpaulo#endif /* HAVE_LIBNL */ 931214518Srpaulo 932214518Srpaulostatic int 933214518Srpaulopcap_can_set_rfmon_linux(pcap_t *handle) 934214518Srpaulo{ 935214518Srpaulo#ifdef HAVE_LIBNL 936214518Srpaulo char phydev_path[PATH_MAX+1]; 937214518Srpaulo int ret; 938214518Srpaulo#endif 939190225Srpaulo#ifdef IW_MODE_MONITOR 940190225Srpaulo int sock_fd; 941190225Srpaulo struct iwreq ireq; 942190225Srpaulo#endif 943190225Srpaulo 944214518Srpaulo if (strcmp(handle->opt.source, "any") == 0) { 945190225Srpaulo /* 946214518Srpaulo * Monitor mode makes no sense on the "any" device. 947190225Srpaulo */ 948190225Srpaulo return 0; 94975107Sfenner } 95075107Sfenner 951214518Srpaulo#ifdef HAVE_LIBNL 952214518Srpaulo /* 953214518Srpaulo * Bleah. There doesn't seem to be a way to ask a mac80211 954214518Srpaulo * device, through libnl, whether it supports monitor mode; 955214518Srpaulo * we'll just check whether the device appears to be a 956214518Srpaulo * mac80211 device and, if so, assume the device supports 957214518Srpaulo * monitor mode. 958214518Srpaulo * 959214518Srpaulo * wmaster devices don't appear to support the Wireless 960214518Srpaulo * Extensions, but we can create a mon device for a 961214518Srpaulo * wmaster device, so we don't bother checking whether 962214518Srpaulo * a mac80211 device supports the Wireless Extensions. 963214518Srpaulo */ 964214518Srpaulo ret = get_mac80211_phydev(handle, handle->opt.source, phydev_path, 965214518Srpaulo PATH_MAX); 966214518Srpaulo if (ret < 0) 967214518Srpaulo return ret; /* error */ 968214518Srpaulo if (ret == 1) 969214518Srpaulo return 1; /* mac80211 device */ 970214518Srpaulo#endif 971214518Srpaulo 972190225Srpaulo#ifdef IW_MODE_MONITOR 973190225Srpaulo /* 974190225Srpaulo * Bleah. There doesn't appear to be an ioctl to use to ask 975190225Srpaulo * whether a device supports monitor mode; we'll just do 976190225Srpaulo * SIOCGIWMODE and, if it succeeds, assume the device supports 977190225Srpaulo * monitor mode. 978190225Srpaulo * 979190225Srpaulo * Open a socket on which to attempt to get the mode. 980190225Srpaulo * (We assume that if we have Wireless Extensions support 981190225Srpaulo * we also have PF_PACKET support.) 982190225Srpaulo */ 983190225Srpaulo sock_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 984190225Srpaulo if (sock_fd == -1) { 985214518Srpaulo (void)snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 986190225Srpaulo "socket: %s", pcap_strerror(errno)); 987190225Srpaulo return PCAP_ERROR; 988190225Srpaulo } 98975107Sfenner 990190225Srpaulo /* 991190225Srpaulo * Attempt to get the current mode. 992190225Srpaulo */ 993214518Srpaulo strncpy(ireq.ifr_ifrn.ifrn_name, handle->opt.source, 994190225Srpaulo sizeof ireq.ifr_ifrn.ifrn_name); 995190225Srpaulo ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0; 996190225Srpaulo if (ioctl(sock_fd, SIOCGIWMODE, &ireq) != -1) { 997190225Srpaulo /* 998190225Srpaulo * Well, we got the mode; assume we can set it. 999190225Srpaulo */ 1000190225Srpaulo close(sock_fd); 1001190225Srpaulo return 1; 1002190225Srpaulo } 1003190225Srpaulo if (errno == ENODEV) { 1004190225Srpaulo /* The device doesn't even exist. */ 1005214518Srpaulo (void)snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 1006214518Srpaulo "SIOCGIWMODE failed: %s", pcap_strerror(errno)); 1007190225Srpaulo close(sock_fd); 1008190225Srpaulo return PCAP_ERROR_NO_SUCH_DEVICE; 1009190225Srpaulo } 1010190225Srpaulo close(sock_fd); 1011190225Srpaulo#endif 1012190225Srpaulo return 0; 1013190225Srpaulo} 101475107Sfenner 1015190225Srpaulo/* 1016214518Srpaulo * Grabs the number of dropped packets by the interface from /proc/net/dev. 1017214518Srpaulo * 1018214518Srpaulo * XXX - what about /sys/class/net/{interface name}/rx_*? There are 1019214518Srpaulo * individual devices giving, in ASCII, various rx_ and tx_ statistics. 1020214518Srpaulo * 1021214518Srpaulo * Or can we get them in binary form from netlink? 1022214518Srpaulo */ 1023214518Srpaulostatic long int 1024214518Srpaulolinux_if_drops(const char * if_name) 1025214518Srpaulo{ 1026214518Srpaulo char buffer[512]; 1027214518Srpaulo char * bufptr; 1028214518Srpaulo FILE * file; 1029214518Srpaulo int field_to_convert = 3, if_name_sz = strlen(if_name); 1030214518Srpaulo long int dropped_pkts = 0; 1031214518Srpaulo 1032214518Srpaulo file = fopen("/proc/net/dev", "r"); 1033214518Srpaulo if (!file) 1034214518Srpaulo return 0; 1035214518Srpaulo 1036214518Srpaulo while (!dropped_pkts && fgets( buffer, sizeof(buffer), file )) 1037214518Srpaulo { 1038214518Srpaulo /* search for 'bytes' -- if its in there, then 1039214518Srpaulo that means we need to grab the fourth field. otherwise 1040214518Srpaulo grab the third field. */ 1041214518Srpaulo if (field_to_convert != 4 && strstr(buffer, "bytes")) 1042214518Srpaulo { 1043214518Srpaulo field_to_convert = 4; 1044214518Srpaulo continue; 1045214518Srpaulo } 1046214518Srpaulo 1047214518Srpaulo /* find iface and make sure it actually matches -- space before the name and : after it */ 1048214518Srpaulo if ((bufptr = strstr(buffer, if_name)) && 1049214518Srpaulo (bufptr == buffer || *(bufptr-1) == ' ') && 1050214518Srpaulo *(bufptr + if_name_sz) == ':') 1051214518Srpaulo { 1052214518Srpaulo bufptr = bufptr + if_name_sz + 1; 1053214518Srpaulo 1054214518Srpaulo /* grab the nth field from it */ 1055214518Srpaulo while( --field_to_convert && *bufptr != '\0') 1056214518Srpaulo { 1057214518Srpaulo while (*bufptr != '\0' && *(bufptr++) == ' '); 1058214518Srpaulo while (*bufptr != '\0' && *(bufptr++) != ' '); 1059214518Srpaulo } 1060214518Srpaulo 1061214518Srpaulo /* get rid of any final spaces */ 1062214518Srpaulo while (*bufptr != '\0' && *bufptr == ' ') bufptr++; 1063214518Srpaulo 1064214518Srpaulo if (*bufptr != '\0') 1065214518Srpaulo dropped_pkts = strtol(bufptr, NULL, 10); 1066214518Srpaulo 1067214518Srpaulo break; 1068214518Srpaulo } 1069214518Srpaulo } 1070214518Srpaulo 1071214518Srpaulo fclose(file); 1072214518Srpaulo return dropped_pkts; 1073214518Srpaulo} 1074214518Srpaulo 1075214518Srpaulo 1076214518Srpaulo/* 1077190225Srpaulo * With older kernels promiscuous mode is kind of interesting because we 1078190225Srpaulo * have to reset the interface before exiting. The problem can't really 1079190225Srpaulo * be solved without some daemon taking care of managing usage counts. 1080190225Srpaulo * If we put the interface into promiscuous mode, we set a flag indicating 1081190225Srpaulo * that we must take it out of that mode when the interface is closed, 1082190225Srpaulo * and, when closing the interface, if that flag is set we take it out 1083190225Srpaulo * of promiscuous mode. 1084190225Srpaulo * 1085190225Srpaulo * Even with newer kernels, we have the same issue with rfmon mode. 1086190225Srpaulo */ 1087190225Srpaulo 1088190225Srpaulostatic void pcap_cleanup_linux( pcap_t *handle ) 1089190225Srpaulo{ 1090190225Srpaulo struct ifreq ifr; 1091214518Srpaulo#ifdef HAVE_LIBNL 1092214518Srpaulo struct nl80211_state nlstate; 1093214518Srpaulo int ret; 1094214518Srpaulo#endif /* HAVE_LIBNL */ 1095190225Srpaulo#ifdef IW_MODE_MONITOR 1096236167Sdelphij int oldflags; 1097190225Srpaulo struct iwreq ireq; 1098214518Srpaulo#endif /* IW_MODE_MONITOR */ 1099190225Srpaulo 1100214518Srpaulo if (handle->md.must_do_on_close != 0) { 1101190225Srpaulo /* 1102190225Srpaulo * There's something we have to do when closing this 1103190225Srpaulo * pcap_t. 1104190225Srpaulo */ 1105214518Srpaulo if (handle->md.must_do_on_close & MUST_CLEAR_PROMISC) { 1106190225Srpaulo /* 1107190225Srpaulo * We put the interface into promiscuous mode; 1108190225Srpaulo * take it out of promiscuous mode. 1109190225Srpaulo * 1110190225Srpaulo * XXX - if somebody else wants it in promiscuous 1111190225Srpaulo * mode, this code cannot know that, so it'll take 1112190225Srpaulo * it out of promiscuous mode. That's not fixable 1113190225Srpaulo * in 2.0[.x] kernels. 1114190225Srpaulo */ 1115190225Srpaulo memset(&ifr, 0, sizeof(ifr)); 1116190225Srpaulo strncpy(ifr.ifr_name, handle->md.device, 1117190225Srpaulo sizeof(ifr.ifr_name)); 1118190225Srpaulo if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) == -1) { 1119190225Srpaulo fprintf(stderr, 1120236167Sdelphij "Can't restore interface %s flags (SIOCGIFFLAGS failed: %s).\n" 1121190225Srpaulo "Please adjust manually.\n" 1122190225Srpaulo "Hint: This can't happen with Linux >= 2.2.0.\n", 1123236167Sdelphij handle->md.device, strerror(errno)); 1124190225Srpaulo } else { 1125190225Srpaulo if (ifr.ifr_flags & IFF_PROMISC) { 1126190225Srpaulo /* 1127190225Srpaulo * Promiscuous mode is currently on; 1128190225Srpaulo * turn it off. 1129190225Srpaulo */ 1130190225Srpaulo ifr.ifr_flags &= ~IFF_PROMISC; 1131190225Srpaulo if (ioctl(handle->fd, SIOCSIFFLAGS, 1132190225Srpaulo &ifr) == -1) { 1133190225Srpaulo fprintf(stderr, 1134236167Sdelphij "Can't restore interface %s flags (SIOCSIFFLAGS failed: %s).\n" 1135190225Srpaulo "Please adjust manually.\n" 1136190225Srpaulo "Hint: This can't happen with Linux >= 2.2.0.\n", 1137236167Sdelphij handle->md.device, 1138190225Srpaulo strerror(errno)); 1139190225Srpaulo } 1140190225Srpaulo } 1141190225Srpaulo } 1142190225Srpaulo } 1143190225Srpaulo 1144214518Srpaulo#ifdef HAVE_LIBNL 1145214518Srpaulo if (handle->md.must_do_on_close & MUST_DELETE_MONIF) { 1146214518Srpaulo ret = nl80211_init(handle, &nlstate, handle->md.device); 1147214518Srpaulo if (ret >= 0) { 1148214518Srpaulo ret = del_mon_if(handle, handle->fd, &nlstate, 1149214518Srpaulo handle->md.device, handle->md.mondevice); 1150214518Srpaulo nl80211_cleanup(&nlstate); 1151214518Srpaulo } 1152214518Srpaulo if (ret < 0) { 1153214518Srpaulo fprintf(stderr, 1154214518Srpaulo "Can't delete monitor interface %s (%s).\n" 1155214518Srpaulo "Please delete manually.\n", 1156214518Srpaulo handle->md.mondevice, handle->errbuf); 1157214518Srpaulo } 1158214518Srpaulo } 1159214518Srpaulo#endif /* HAVE_LIBNL */ 1160214518Srpaulo 1161190225Srpaulo#ifdef IW_MODE_MONITOR 1162214518Srpaulo if (handle->md.must_do_on_close & MUST_CLEAR_RFMON) { 1163190225Srpaulo /* 1164190225Srpaulo * We put the interface into rfmon mode; 1165190225Srpaulo * take it out of rfmon mode. 1166190225Srpaulo * 1167190225Srpaulo * XXX - if somebody else wants it in rfmon 1168190225Srpaulo * mode, this code cannot know that, so it'll take 1169190225Srpaulo * it out of rfmon mode. 1170190225Srpaulo */ 1171236167Sdelphij 1172236167Sdelphij /* 1173236167Sdelphij * First, take the interface down if it's up; 1174236167Sdelphij * otherwise, we might get EBUSY. 1175236167Sdelphij * If we get errors, just drive on and print 1176236167Sdelphij * a warning if we can't restore the mode. 1177236167Sdelphij */ 1178236167Sdelphij oldflags = 0; 1179236167Sdelphij memset(&ifr, 0, sizeof(ifr)); 1180236167Sdelphij strncpy(ifr.ifr_name, handle->md.device, 1181236167Sdelphij sizeof(ifr.ifr_name)); 1182236167Sdelphij if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) != -1) { 1183236167Sdelphij if (ifr.ifr_flags & IFF_UP) { 1184236167Sdelphij oldflags = ifr.ifr_flags; 1185236167Sdelphij ifr.ifr_flags &= ~IFF_UP; 1186236167Sdelphij if (ioctl(handle->fd, SIOCSIFFLAGS, &ifr) == -1) 1187236167Sdelphij oldflags = 0; /* didn't set, don't restore */ 1188236167Sdelphij } 1189236167Sdelphij } 1190236167Sdelphij 1191236167Sdelphij /* 1192236167Sdelphij * Now restore the mode. 1193236167Sdelphij */ 1194190225Srpaulo strncpy(ireq.ifr_ifrn.ifrn_name, handle->md.device, 1195190225Srpaulo sizeof ireq.ifr_ifrn.ifrn_name); 1196190225Srpaulo ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] 1197190225Srpaulo = 0; 1198190225Srpaulo ireq.u.mode = handle->md.oldmode; 1199190225Srpaulo if (ioctl(handle->fd, SIOCSIWMODE, &ireq) == -1) { 1200190225Srpaulo /* 1201190225Srpaulo * Scientist, you've failed. 1202190225Srpaulo */ 1203190225Srpaulo fprintf(stderr, 1204236167Sdelphij "Can't restore interface %s wireless mode (SIOCSIWMODE failed: %s).\n" 1205190225Srpaulo "Please adjust manually.\n", 1206236167Sdelphij handle->md.device, strerror(errno)); 1207190225Srpaulo } 1208236167Sdelphij 1209236167Sdelphij /* 1210236167Sdelphij * Now bring the interface back up if we brought 1211236167Sdelphij * it down. 1212236167Sdelphij */ 1213236167Sdelphij if (oldflags != 0) { 1214236167Sdelphij ifr.ifr_flags = oldflags; 1215236167Sdelphij if (ioctl(handle->fd, SIOCSIFFLAGS, &ifr) == -1) { 1216236167Sdelphij fprintf(stderr, 1217236167Sdelphij "Can't bring interface %s back up (SIOCSIFFLAGS failed: %s).\n" 1218236167Sdelphij "Please adjust manually.\n", 1219236167Sdelphij handle->md.device, strerror(errno)); 1220236167Sdelphij } 1221236167Sdelphij } 1222190225Srpaulo } 1223214518Srpaulo#endif /* IW_MODE_MONITOR */ 1224190225Srpaulo 1225190225Srpaulo /* 1226190225Srpaulo * Take this pcap out of the list of pcaps for which we 1227190225Srpaulo * have to take the interface out of some mode. 1228190225Srpaulo */ 1229190225Srpaulo pcap_remove_from_pcaps_to_close(handle); 1230190225Srpaulo } 1231190225Srpaulo 1232214518Srpaulo if (handle->md.mondevice != NULL) { 1233214518Srpaulo free(handle->md.mondevice); 1234214518Srpaulo handle->md.mondevice = NULL; 1235214518Srpaulo } 1236190225Srpaulo if (handle->md.device != NULL) { 1237190225Srpaulo free(handle->md.device); 1238190225Srpaulo handle->md.device = NULL; 1239190225Srpaulo } 1240190225Srpaulo pcap_cleanup_live_common(handle); 1241190225Srpaulo} 1242190225Srpaulo 1243190225Srpaulo/* 1244190225Srpaulo * Get a handle for a live capture from the given device. You can 1245190225Srpaulo * pass NULL as device to get all packages (without link level 1246190225Srpaulo * information of course). If you pass 1 as promisc the interface 1247190225Srpaulo * will be set to promiscous mode (XXX: I think this usage should 1248190225Srpaulo * be deprecated and functions be added to select that later allow 1249190225Srpaulo * modification of that values -- Torsten). 1250190225Srpaulo */ 1251190225Srpaulostatic int 1252190225Srpaulopcap_activate_linux(pcap_t *handle) 1253190225Srpaulo{ 1254190225Srpaulo const char *device; 1255190225Srpaulo int status = 0; 1256190225Srpaulo 1257190225Srpaulo device = handle->opt.source; 1258190225Srpaulo 1259190225Srpaulo handle->inject_op = pcap_inject_linux; 1260190225Srpaulo handle->setfilter_op = pcap_setfilter_linux; 1261190225Srpaulo handle->setdirection_op = pcap_setdirection_linux; 1262190225Srpaulo handle->set_datalink_op = NULL; /* can't change data link type */ 1263190225Srpaulo handle->getnonblock_op = pcap_getnonblock_fd; 1264190225Srpaulo handle->setnonblock_op = pcap_setnonblock_fd; 1265190225Srpaulo handle->cleanup_op = pcap_cleanup_linux; 1266190225Srpaulo handle->read_op = pcap_read_linux; 1267190225Srpaulo handle->stats_op = pcap_stats_linux; 1268190225Srpaulo 126975107Sfenner /* 1270214518Srpaulo * The "any" device is a special device which causes us not 1271214518Srpaulo * to bind to a particular device and thus to look at all 1272214518Srpaulo * devices. 127375107Sfenner */ 1274214518Srpaulo if (strcmp(device, "any") == 0) { 1275190225Srpaulo if (handle->opt.promisc) { 1276190225Srpaulo handle->opt.promisc = 0; 127798530Sfenner /* Just a warning. */ 1278190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 127998530Sfenner "Promiscuous mode not supported on the \"any\" device"); 1280190225Srpaulo status = PCAP_WARNING_PROMISC_NOTSUP; 128198530Sfenner } 1282214518Srpaulo } 1283127664Sbms 1284214518Srpaulo handle->md.device = strdup(device); 128575107Sfenner if (handle->md.device == NULL) { 1286190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s", 128775107Sfenner pcap_strerror(errno) ); 1288190225Srpaulo return PCAP_ERROR; 128975107Sfenner } 1290214518Srpaulo 1291214518Srpaulo /* 1292214518Srpaulo * If we're in promiscuous mode, then we probably want 1293214518Srpaulo * to see when the interface drops packets too, so get an 1294214518Srpaulo * initial count from /proc/net/dev 1295214518Srpaulo */ 1296214518Srpaulo if (handle->opt.promisc) 1297214518Srpaulo handle->md.proc_dropped = linux_if_drops(handle->md.device); 129875107Sfenner 1299127664Sbms /* 1300127664Sbms * Current Linux kernels use the protocol family PF_PACKET to 1301127664Sbms * allow direct access to all packets on the network while 1302127664Sbms * older kernels had a special socket type SOCK_PACKET to 130375107Sfenner * implement this feature. 130475107Sfenner * While this old implementation is kind of obsolete we need 1305127664Sbms * to be compatible with older kernels for a while so we are 130675107Sfenner * trying both methods with the newer method preferred. 130775107Sfenner */ 1308236167Sdelphij status = activate_new(handle); 1309236167Sdelphij if (status < 0) { 1310190225Srpaulo /* 1311236167Sdelphij * Fatal error with the new way; just fail. 1312236167Sdelphij * status has the error return; if it's PCAP_ERROR, 1313236167Sdelphij * handle->errbuf has been set appropriately. 1314236167Sdelphij */ 1315236167Sdelphij goto fail; 1316236167Sdelphij } 1317236167Sdelphij if (status == 1) { 1318236167Sdelphij /* 1319214518Srpaulo * Success. 1320190225Srpaulo * Try to use memory-mapped access. 1321190225Srpaulo */ 1322236167Sdelphij switch (activate_mmap(handle, &status)) { 1323214518Srpaulo 1324214518Srpaulo case 1: 1325236167Sdelphij /* 1326236167Sdelphij * We succeeded. status has been 1327236167Sdelphij * set to the status to return, 1328236167Sdelphij * which might be 0, or might be 1329236167Sdelphij * a PCAP_WARNING_ value. 1330236167Sdelphij */ 1331236167Sdelphij return status; 1332214518Srpaulo 1333214518Srpaulo case 0: 1334214518Srpaulo /* 1335214518Srpaulo * Kernel doesn't support it - just continue 1336214518Srpaulo * with non-memory-mapped access. 1337214518Srpaulo */ 1338214518Srpaulo break; 1339214518Srpaulo 1340214518Srpaulo case -1: 1341214518Srpaulo /* 1342236167Sdelphij * We failed to set up to use it, or the kernel 1343236167Sdelphij * supports it, but we failed to enable it. 1344236167Sdelphij * status has been set to the error status to 1345236167Sdelphij * return and, if it's PCAP_ERROR, handle->errbuf 1346236167Sdelphij * contains the error message. 1347214518Srpaulo */ 1348214518Srpaulo goto fail; 1349214518Srpaulo } 1350190225Srpaulo } 1351190225Srpaulo else if (status == 0) { 1352127664Sbms /* Non-fatal error; try old way */ 1353214518Srpaulo if ((status = activate_old(handle)) != 1) { 1354214518Srpaulo /* 1355214518Srpaulo * Both methods to open the packet socket failed. 1356214518Srpaulo * Tidy up and report our failure (handle->errbuf 1357214518Srpaulo * is expected to be set by the functions above). 1358214518Srpaulo */ 1359214518Srpaulo goto fail; 1360214518Srpaulo } 136175107Sfenner } 136275107Sfenner 1363214518Srpaulo /* 1364214518Srpaulo * We set up the socket, but not with memory-mapped access. 1365214518Srpaulo */ 1366236167Sdelphij status = 0; 1367190225Srpaulo if (handle->opt.buffer_size != 0) { 136898530Sfenner /* 1369190225Srpaulo * Set the socket buffer size to the specified value. 137098530Sfenner */ 1371190225Srpaulo if (setsockopt(handle->fd, SOL_SOCKET, SO_RCVBUF, 1372190225Srpaulo &handle->opt.buffer_size, 1373190225Srpaulo sizeof(handle->opt.buffer_size)) == -1) { 1374190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 1375190225Srpaulo "SO_RCVBUF: %s", pcap_strerror(errno)); 1376190225Srpaulo status = PCAP_ERROR; 1377190225Srpaulo goto fail; 137898530Sfenner } 137998530Sfenner } 138098530Sfenner 138198530Sfenner /* Allocate the buffer */ 138298530Sfenner 138398530Sfenner handle->buffer = malloc(handle->bufsize + handle->offset); 138498530Sfenner if (!handle->buffer) { 1385190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 138698530Sfenner "malloc: %s", pcap_strerror(errno)); 1387190225Srpaulo status = PCAP_ERROR; 1388190225Srpaulo goto fail; 138998530Sfenner } 139098530Sfenner 1391127664Sbms /* 1392127664Sbms * "handle->fd" is a socket, so "select()" and "poll()" 1393127664Sbms * should work on it. 1394127664Sbms */ 1395127664Sbms handle->selectable_fd = handle->fd; 1396127664Sbms 1397190225Srpaulo return status; 1398127664Sbms 1399190225Srpaulofail: 1400190225Srpaulo pcap_cleanup_linux(handle); 1401190225Srpaulo return status; 140226175Sfenner} 140326175Sfenner 140475107Sfenner/* 140575107Sfenner * Read at most max_packets from the capture stream and call the callback 140675107Sfenner * for each of them. Returns the number of packets handled or -1 if an 1407127664Sbms * error occured. 140875107Sfenner */ 1409127664Sbmsstatic int 1410127664Sbmspcap_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) 141126175Sfenner{ 141275107Sfenner /* 141375107Sfenner * Currently, on Linux only one packet is delivered per read, 141475107Sfenner * so we don't loop. 141575107Sfenner */ 141675107Sfenner return pcap_read_packet(handle, callback, user); 141775107Sfenner} 141826175Sfenner 141975107Sfenner/* 1420127664Sbms * Read a packet from the socket calling the handler provided by 142175107Sfenner * the user. Returns the number of packets received or -1 if an 142275107Sfenner * error occured. 142375107Sfenner */ 142475107Sfennerstatic int 142575107Sfennerpcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata) 142675107Sfenner{ 142798530Sfenner u_char *bp; 142875107Sfenner int offset; 142975107Sfenner#ifdef HAVE_PF_PACKET_SOCKETS 143075107Sfenner struct sockaddr_ll from; 143175107Sfenner struct sll_header *hdrp; 143275107Sfenner#else 143375107Sfenner struct sockaddr from; 143475107Sfenner#endif 1435190225Srpaulo#if defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI) 1436190225Srpaulo struct iovec iov; 1437190225Srpaulo struct msghdr msg; 1438190225Srpaulo struct cmsghdr *cmsg; 1439190225Srpaulo union { 1440190225Srpaulo struct cmsghdr cmsg; 1441190225Srpaulo char buf[CMSG_SPACE(sizeof(struct tpacket_auxdata))]; 1442190225Srpaulo } cmsg_buf; 1443190225Srpaulo#else /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI) */ 144475107Sfenner socklen_t fromlen; 1445190225Srpaulo#endif /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI) */ 144675107Sfenner int packet_len, caplen; 144775107Sfenner struct pcap_pkthdr pcap_header; 144826175Sfenner 144975107Sfenner#ifdef HAVE_PF_PACKET_SOCKETS 145075107Sfenner /* 145175107Sfenner * If this is a cooked device, leave extra room for a 145275107Sfenner * fake packet header. 145375107Sfenner */ 145475107Sfenner if (handle->md.cooked) 145575107Sfenner offset = SLL_HDR_LEN; 145675107Sfenner else 145775107Sfenner offset = 0; 145875107Sfenner#else 145975107Sfenner /* 146075107Sfenner * This system doesn't have PF_PACKET sockets, so it doesn't 146175107Sfenner * support cooked devices. 146275107Sfenner */ 146375107Sfenner offset = 0; 146475107Sfenner#endif 146575107Sfenner 1466190225Srpaulo /* 1467190225Srpaulo * Receive a single packet from the kernel. 1468190225Srpaulo * We ignore EINTR, as that might just be due to a signal 1469190225Srpaulo * being delivered - if the signal should interrupt the 1470190225Srpaulo * loop, the signal handler should call pcap_breakloop() 1471190225Srpaulo * to set handle->break_loop (we ignore it on other 1472190225Srpaulo * platforms as well). 1473190225Srpaulo * We also ignore ENETDOWN, so that we can continue to 1474190225Srpaulo * capture traffic if the interface goes down and comes 1475190225Srpaulo * back up again; comments in the kernel indicate that 1476190225Srpaulo * we'll just block waiting for packets if we try to 1477190225Srpaulo * receive from a socket that delivered ENETDOWN, and, 1478190225Srpaulo * if we're using a memory-mapped buffer, we won't even 1479190225Srpaulo * get notified of "network down" events. 1480190225Srpaulo */ 1481190225Srpaulo bp = handle->buffer + handle->offset; 148275107Sfenner 1483190225Srpaulo#if defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI) 1484190225Srpaulo msg.msg_name = &from; 1485190225Srpaulo msg.msg_namelen = sizeof(from); 1486190225Srpaulo msg.msg_iov = &iov; 1487190225Srpaulo msg.msg_iovlen = 1; 1488190225Srpaulo msg.msg_control = &cmsg_buf; 1489190225Srpaulo msg.msg_controllen = sizeof(cmsg_buf); 1490190225Srpaulo msg.msg_flags = 0; 1491190225Srpaulo 1492190225Srpaulo iov.iov_len = handle->bufsize - offset; 1493190225Srpaulo iov.iov_base = bp + offset; 1494190225Srpaulo#endif /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI) */ 1495190225Srpaulo 149626175Sfenner do { 1497127664Sbms /* 1498127664Sbms * Has "pcap_breakloop()" been called? 1499127664Sbms */ 1500127664Sbms if (handle->break_loop) { 1501127664Sbms /* 1502214518Srpaulo * Yes - clear the flag that indicates that it has, 1503214518Srpaulo * and return PCAP_ERROR_BREAK as an indication that 1504214518Srpaulo * we were told to break out of the loop. 1505127664Sbms */ 1506127664Sbms handle->break_loop = 0; 1507214518Srpaulo return PCAP_ERROR_BREAK; 1508127664Sbms } 1509190225Srpaulo 1510190225Srpaulo#if defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI) 1511190225Srpaulo packet_len = recvmsg(handle->fd, &msg, MSG_TRUNC); 1512190225Srpaulo#else /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI) */ 151326175Sfenner fromlen = sizeof(from); 1514127664Sbms packet_len = recvfrom( 151598530Sfenner handle->fd, bp + offset, 1516127664Sbms handle->bufsize - offset, MSG_TRUNC, 151775107Sfenner (struct sockaddr *) &from, &fromlen); 1518190225Srpaulo#endif /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI) */ 1519214518Srpaulo } while (packet_len == -1 && errno == EINTR); 152026175Sfenner 152175107Sfenner /* Check if an error occured */ 152226175Sfenner 152375107Sfenner if (packet_len == -1) { 1524214518Srpaulo switch (errno) { 1525214518Srpaulo 1526214518Srpaulo case EAGAIN: 152775107Sfenner return 0; /* no packet there */ 1528214518Srpaulo 1529214518Srpaulo case ENETDOWN: 1530214518Srpaulo /* 1531214518Srpaulo * The device on which we're capturing went away. 1532214518Srpaulo * 1533214518Srpaulo * XXX - we should really return 1534214518Srpaulo * PCAP_ERROR_IFACE_NOT_UP, but pcap_dispatch() 1535214518Srpaulo * etc. aren't defined to return that. 1536214518Srpaulo */ 1537190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 1538214518Srpaulo "The interface went down"); 1539214518Srpaulo return PCAP_ERROR; 1540214518Srpaulo 1541214518Srpaulo default: 1542214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 154375107Sfenner "recvfrom: %s", pcap_strerror(errno)); 1544214518Srpaulo return PCAP_ERROR; 154526175Sfenner } 154675107Sfenner } 154726175Sfenner 154875107Sfenner#ifdef HAVE_PF_PACKET_SOCKETS 1549147894Ssam if (!handle->md.sock_packet) { 1550147894Ssam /* 1551172677Smlaier * Unfortunately, there is a window between socket() and 1552172677Smlaier * bind() where the kernel may queue packets from any 1553172677Smlaier * interface. If we're bound to a particular interface, 1554172677Smlaier * discard packets not from that interface. 1555172677Smlaier * 1556172677Smlaier * (If socket filters are supported, we could do the 1557172677Smlaier * same thing we do when changing the filter; however, 1558172677Smlaier * that won't handle packet sockets without socket 1559172677Smlaier * filter support, and it's a bit more complicated. 1560172677Smlaier * It would save some instructions per packet, however.) 1561172677Smlaier */ 1562172677Smlaier if (handle->md.ifindex != -1 && 1563172677Smlaier from.sll_ifindex != handle->md.ifindex) 1564172677Smlaier return 0; 1565172677Smlaier 1566172677Smlaier /* 1567147894Ssam * Do checks based on packet direction. 1568147894Ssam * We can only do this if we're using PF_PACKET; the 1569147894Ssam * address returned for SOCK_PACKET is a "sockaddr_pkt" 1570147894Ssam * which lacks the relevant packet type information. 1571147894Ssam */ 1572147894Ssam if (from.sll_pkttype == PACKET_OUTGOING) { 1573147894Ssam /* 1574147894Ssam * Outgoing packet. 1575147894Ssam * If this is from the loopback device, reject it; 1576147894Ssam * we'll see the packet as an incoming packet as well, 1577147894Ssam * and we don't want to see it twice. 1578147894Ssam */ 1579147894Ssam if (from.sll_ifindex == handle->md.lo_ifindex) 1580147894Ssam return 0; 1581147894Ssam 1582147894Ssam /* 1583147894Ssam * If the user only wants incoming packets, reject it. 1584147894Ssam */ 1585162012Ssam if (handle->direction == PCAP_D_IN) 1586147894Ssam return 0; 1587147894Ssam } else { 1588147894Ssam /* 1589147894Ssam * Incoming packet. 1590147894Ssam * If the user only wants outgoing packets, reject it. 1591147894Ssam */ 1592162012Ssam if (handle->direction == PCAP_D_OUT) 1593147894Ssam return 0; 1594147894Ssam } 1595147894Ssam } 159675107Sfenner#endif 159726175Sfenner 159875107Sfenner#ifdef HAVE_PF_PACKET_SOCKETS 159975107Sfenner /* 160075107Sfenner * If this is a cooked device, fill in the fake packet header. 160175107Sfenner */ 160275107Sfenner if (handle->md.cooked) { 160375107Sfenner /* 160475107Sfenner * Add the length of the fake header to the length 160575107Sfenner * of packet data we read. 160675107Sfenner */ 160775107Sfenner packet_len += SLL_HDR_LEN; 160826175Sfenner 160998530Sfenner hdrp = (struct sll_header *)bp; 1610190225Srpaulo hdrp->sll_pkttype = map_packet_type_to_sll_type(from.sll_pkttype); 1611190225Srpaulo hdrp->sll_hatype = htons(from.sll_hatype); 1612190225Srpaulo hdrp->sll_halen = htons(from.sll_halen); 1613190225Srpaulo memcpy(hdrp->sll_addr, from.sll_addr, 1614190225Srpaulo (from.sll_halen > SLL_ADDRLEN) ? 1615190225Srpaulo SLL_ADDRLEN : 1616190225Srpaulo from.sll_halen); 1617190225Srpaulo hdrp->sll_protocol = from.sll_protocol; 1618190225Srpaulo } 161926175Sfenner 1620190225Srpaulo#if defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI) 1621190225Srpaulo for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { 1622190225Srpaulo struct tpacket_auxdata *aux; 1623190225Srpaulo unsigned int len; 1624190225Srpaulo struct vlan_tag *tag; 162526175Sfenner 1626190225Srpaulo if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct tpacket_auxdata)) || 1627190225Srpaulo cmsg->cmsg_level != SOL_PACKET || 1628190225Srpaulo cmsg->cmsg_type != PACKET_AUXDATA) 1629190225Srpaulo continue; 163026175Sfenner 1631190225Srpaulo aux = (struct tpacket_auxdata *)CMSG_DATA(cmsg); 1632190225Srpaulo if (aux->tp_vlan_tci == 0) 1633190225Srpaulo continue; 163475107Sfenner 1635190225Srpaulo len = packet_len > iov.iov_len ? iov.iov_len : packet_len; 1636190225Srpaulo if (len < 2 * ETH_ALEN) 163775107Sfenner break; 163875107Sfenner 1639190225Srpaulo bp -= VLAN_TAG_LEN; 1640190225Srpaulo memmove(bp, bp + VLAN_TAG_LEN, 2 * ETH_ALEN); 164175107Sfenner 1642190225Srpaulo tag = (struct vlan_tag *)(bp + 2 * ETH_ALEN); 1643190225Srpaulo tag->vlan_tpid = htons(ETH_P_8021Q); 1644190225Srpaulo tag->vlan_tci = htons(aux->tp_vlan_tci); 164575107Sfenner 1646190225Srpaulo packet_len += VLAN_TAG_LEN; 164726175Sfenner } 1648190225Srpaulo#endif /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI) */ 1649190225Srpaulo#endif /* HAVE_PF_PACKET_SOCKETS */ 165075107Sfenner 165175107Sfenner /* 1652127664Sbms * XXX: According to the kernel source we should get the real 1653127664Sbms * packet len if calling recvfrom with MSG_TRUNC set. It does 165475107Sfenner * not seem to work here :(, but it is supported by this code 1655127664Sbms * anyway. 165675107Sfenner * To be honest the code RELIES on that feature so this is really 165775107Sfenner * broken with 2.2.x kernels. 165875107Sfenner * I spend a day to figure out what's going on and I found out 1659127664Sbms * that the following is happening: 166075107Sfenner * 1661127664Sbms * The packet comes from a random interface and the packet_rcv 166275107Sfenner * hook is called with a clone of the packet. That code inserts 166375107Sfenner * the packet into the receive queue of the packet socket. 166475107Sfenner * If a filter is attached to that socket that filter is run 166575107Sfenner * first - and there lies the problem. The default filter always 166675107Sfenner * cuts the packet at the snaplen: 166775107Sfenner * 166875107Sfenner * # tcpdump -d 166975107Sfenner * (000) ret #68 167075107Sfenner * 1671127664Sbms * So the packet filter cuts down the packet. The recvfrom call 167275107Sfenner * says "hey, it's only 68 bytes, it fits into the buffer" with 1673127664Sbms * the result that we don't get the real packet length. This 1674127664Sbms * is valid at least until kernel 2.2.17pre6. 167575107Sfenner * 167675107Sfenner * We currently handle this by making a copy of the filter 167775107Sfenner * program, fixing all "ret" instructions with non-zero 167875107Sfenner * operands to have an operand of 65535 so that the filter 167975107Sfenner * doesn't truncate the packet, and supplying that modified 168075107Sfenner * filter to the kernel. 168175107Sfenner */ 168275107Sfenner 168375107Sfenner caplen = packet_len; 168475107Sfenner if (caplen > handle->snapshot) 168575107Sfenner caplen = handle->snapshot; 168675107Sfenner 168775107Sfenner /* Run the packet filter if not using kernel filter */ 168875107Sfenner if (!handle->md.use_bpf && handle->fcode.bf_insns) { 168998530Sfenner if (bpf_filter(handle->fcode.bf_insns, bp, 169075107Sfenner packet_len, caplen) == 0) 169175107Sfenner { 169275107Sfenner /* rejected by filter */ 169375107Sfenner return 0; 169475107Sfenner } 169575107Sfenner } 169675107Sfenner 169775107Sfenner /* Fill in our own header data */ 169875107Sfenner 169975107Sfenner if (ioctl(handle->fd, SIOCGSTAMP, &pcap_header.ts) == -1) { 1700190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 1701172677Smlaier "SIOCGSTAMP: %s", pcap_strerror(errno)); 1702214518Srpaulo return PCAP_ERROR; 170375107Sfenner } 170475107Sfenner pcap_header.caplen = caplen; 170575107Sfenner pcap_header.len = packet_len; 170675107Sfenner 170798530Sfenner /* 170898530Sfenner * Count the packet. 170998530Sfenner * 171098530Sfenner * Arguably, we should count them before we check the filter, 171198530Sfenner * as on many other platforms "ps_recv" counts packets 171298530Sfenner * handed to the filter rather than packets that passed 171398530Sfenner * the filter, but if filtering is done in the kernel, we 171498530Sfenner * can't get a count of packets that passed the filter, 171598530Sfenner * and that would mean the meaning of "ps_recv" wouldn't 171698530Sfenner * be the same on all Linux systems. 171798530Sfenner * 171898530Sfenner * XXX - it's not the same on all systems in any case; 171998530Sfenner * ideally, we should have a "get the statistics" call 172098530Sfenner * that supplies more counts and indicates which of them 172198530Sfenner * it supplies, so that we supply a count of packets 172298530Sfenner * handed to the filter only on platforms where that 172398530Sfenner * information is available. 172498530Sfenner * 172598530Sfenner * We count them here even if we can get the packet count 172698530Sfenner * from the kernel, as we can only determine at run time 172798530Sfenner * whether we'll be able to get it from the kernel (if 172898530Sfenner * HAVE_TPACKET_STATS isn't defined, we can't get it from 172998530Sfenner * the kernel, but if it is defined, the library might 173098530Sfenner * have been built with a 2.4 or later kernel, but we 173198530Sfenner * might be running on a 2.2[.x] kernel without Alexey 173298530Sfenner * Kuznetzov's turbopacket patches, and thus the kernel 173398530Sfenner * might not be able to supply those statistics). We 173498530Sfenner * could, I guess, try, when opening the socket, to get 173598530Sfenner * the statistics, and if we can not increment the count 173698530Sfenner * here, but it's not clear that always incrementing 173798530Sfenner * the count is more expensive than always testing a flag 173898530Sfenner * in memory. 1739172677Smlaier * 1740172677Smlaier * We keep the count in "md.packets_read", and use that for 1741172677Smlaier * "ps_recv" if we can't get the statistics from the kernel. 1742172677Smlaier * We do that because, if we *can* get the statistics from 1743172677Smlaier * the kernel, we use "md.stat.ps_recv" and "md.stat.ps_drop" 1744172677Smlaier * as running counts, as reading the statistics from the 1745172677Smlaier * kernel resets the kernel statistics, and if we directly 1746172677Smlaier * increment "md.stat.ps_recv" here, that means it will 1747172677Smlaier * count packets *twice* on systems where we can get kernel 1748172677Smlaier * statistics - once here, and once in pcap_stats_linux(). 174998530Sfenner */ 1750172677Smlaier handle->md.packets_read++; 175175107Sfenner 175298530Sfenner /* Call the user supplied callback function */ 175398530Sfenner callback(userdata, &pcap_header, bp); 175498530Sfenner 175575107Sfenner return 1; 175626175Sfenner} 175726175Sfenner 1758146768Ssamstatic int 1759146768Ssampcap_inject_linux(pcap_t *handle, const void *buf, size_t size) 1760146768Ssam{ 1761146768Ssam int ret; 1762146768Ssam 1763146768Ssam#ifdef HAVE_PF_PACKET_SOCKETS 1764146768Ssam if (!handle->md.sock_packet) { 1765146768Ssam /* PF_PACKET socket */ 1766146768Ssam if (handle->md.ifindex == -1) { 1767146768Ssam /* 1768146768Ssam * We don't support sending on the "any" device. 1769146768Ssam */ 1770146768Ssam strlcpy(handle->errbuf, 1771146768Ssam "Sending packets isn't supported on the \"any\" device", 1772146768Ssam PCAP_ERRBUF_SIZE); 1773146768Ssam return (-1); 1774146768Ssam } 1775146768Ssam 1776146768Ssam if (handle->md.cooked) { 1777146768Ssam /* 1778146768Ssam * We don't support sending on the "any" device. 1779146768Ssam * 1780146768Ssam * XXX - how do you send on a bound cooked-mode 1781146768Ssam * socket? 1782146768Ssam * Is a "sendto()" required there? 1783146768Ssam */ 1784146768Ssam strlcpy(handle->errbuf, 1785146768Ssam "Sending packets isn't supported in cooked mode", 1786146768Ssam PCAP_ERRBUF_SIZE); 1787146768Ssam return (-1); 1788146768Ssam } 1789146768Ssam } 1790146768Ssam#endif 1791146768Ssam 1792146768Ssam ret = send(handle->fd, buf, size, 0); 1793146768Ssam if (ret == -1) { 1794146768Ssam snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "send: %s", 1795146768Ssam pcap_strerror(errno)); 1796146768Ssam return (-1); 1797146768Ssam } 1798146768Ssam return (ret); 1799146768Ssam} 1800146768Ssam 180175107Sfenner/* 180275107Sfenner * Get the statistics for the given packet capture handle. 180398530Sfenner * Reports the number of dropped packets iff the kernel supports 180498530Sfenner * the PACKET_STATISTICS "getsockopt()" argument (2.4 and later 180598530Sfenner * kernels, and 2.2[.x] kernels with Alexey Kuznetzov's turbopacket 180698530Sfenner * patches); otherwise, that information isn't available, and we lie 180798530Sfenner * and report 0 as the count of dropped packets. 180875107Sfenner */ 1809127664Sbmsstatic int 1810127664Sbmspcap_stats_linux(pcap_t *handle, struct pcap_stat *stats) 181126175Sfenner{ 181298530Sfenner#ifdef HAVE_TPACKET_STATS 181398530Sfenner struct tpacket_stats kstats; 181498530Sfenner socklen_t len = sizeof (struct tpacket_stats); 1815127664Sbms#endif 181698530Sfenner 1817214518Srpaulo long if_dropped = 0; 1818214518Srpaulo 1819214518Srpaulo /* 1820214518Srpaulo * To fill in ps_ifdrop, we parse /proc/net/dev for the number 1821214518Srpaulo */ 1822214518Srpaulo if (handle->opt.promisc) 1823214518Srpaulo { 1824214518Srpaulo if_dropped = handle->md.proc_dropped; 1825214518Srpaulo handle->md.proc_dropped = linux_if_drops(handle->md.device); 1826214518Srpaulo handle->md.stat.ps_ifdrop += (handle->md.proc_dropped - if_dropped); 1827214518Srpaulo } 1828214518Srpaulo 1829127664Sbms#ifdef HAVE_TPACKET_STATS 183098530Sfenner /* 183198530Sfenner * Try to get the packet counts from the kernel. 183298530Sfenner */ 183398530Sfenner if (getsockopt(handle->fd, SOL_PACKET, PACKET_STATISTICS, 183498530Sfenner &kstats, &len) > -1) { 183598530Sfenner /* 1836172677Smlaier * On systems where the PACKET_STATISTICS "getsockopt()" 1837172677Smlaier * argument is supported on PF_PACKET sockets: 1838172677Smlaier * 1839172677Smlaier * "ps_recv" counts only packets that *passed* the 1840172677Smlaier * filter, not packets that didn't pass the filter. 1841172677Smlaier * This includes packets later dropped because we 1842172677Smlaier * ran out of buffer space. 1843172677Smlaier * 1844172677Smlaier * "ps_drop" counts packets dropped because we ran 1845172677Smlaier * out of buffer space. It doesn't count packets 1846172677Smlaier * dropped by the interface driver. It counts only 1847172677Smlaier * packets that passed the filter. 1848172677Smlaier * 1849214518Srpaulo * See above for ps_ifdrop. 1850214518Srpaulo * 1851172677Smlaier * Both statistics include packets not yet read from 1852172677Smlaier * the kernel by libpcap, and thus not yet seen by 1853172677Smlaier * the application. 1854172677Smlaier * 185598530Sfenner * In "linux/net/packet/af_packet.c", at least in the 185698530Sfenner * 2.4.9 kernel, "tp_packets" is incremented for every 185798530Sfenner * packet that passes the packet filter *and* is 185898530Sfenner * successfully queued on the socket; "tp_drops" is 185998530Sfenner * incremented for every packet dropped because there's 186098530Sfenner * not enough free space in the socket buffer. 186198530Sfenner * 186298530Sfenner * When the statistics are returned for a PACKET_STATISTICS 186398530Sfenner * "getsockopt()" call, "tp_drops" is added to "tp_packets", 186498530Sfenner * so that "tp_packets" counts all packets handed to 186598530Sfenner * the PF_PACKET socket, including packets dropped because 186698530Sfenner * there wasn't room on the socket buffer - but not 186798530Sfenner * including packets that didn't pass the filter. 186898530Sfenner * 186998530Sfenner * In the BSD BPF, the count of received packets is 187098530Sfenner * incremented for every packet handed to BPF, regardless 187198530Sfenner * of whether it passed the filter. 187298530Sfenner * 187398530Sfenner * We can't make "pcap_stats()" work the same on both 187498530Sfenner * platforms, but the best approximation is to return 187598530Sfenner * "tp_packets" as the count of packets and "tp_drops" 187698530Sfenner * as the count of drops. 1877146768Ssam * 1878146768Ssam * Keep a running total because each call to 1879146768Ssam * getsockopt(handle->fd, SOL_PACKET, PACKET_STATISTICS, .... 1880146768Ssam * resets the counters to zero. 188198530Sfenner */ 1882146768Ssam handle->md.stat.ps_recv += kstats.tp_packets; 1883146768Ssam handle->md.stat.ps_drop += kstats.tp_drops; 1884172677Smlaier *stats = handle->md.stat; 1885172677Smlaier return 0; 188698530Sfenner } 188798530Sfenner else 188898530Sfenner { 188998530Sfenner /* 189098530Sfenner * If the error was EOPNOTSUPP, fall through, so that 189198530Sfenner * if you build the library on a system with 189298530Sfenner * "struct tpacket_stats" and run it on a system 189398530Sfenner * that doesn't, it works as it does if the library 189498530Sfenner * is built on a system without "struct tpacket_stats". 189598530Sfenner */ 189698530Sfenner if (errno != EOPNOTSUPP) { 189798530Sfenner snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 189898530Sfenner "pcap_stats: %s", pcap_strerror(errno)); 189998530Sfenner return -1; 190098530Sfenner } 190198530Sfenner } 190298530Sfenner#endif 190398530Sfenner /* 190498530Sfenner * On systems where the PACKET_STATISTICS "getsockopt()" argument 190598530Sfenner * is not supported on PF_PACKET sockets: 190698530Sfenner * 190798530Sfenner * "ps_recv" counts only packets that *passed* the filter, 190898530Sfenner * not packets that didn't pass the filter. It does not 190998530Sfenner * count packets dropped because we ran out of buffer 191098530Sfenner * space. 191198530Sfenner * 191298530Sfenner * "ps_drop" is not supported. 191398530Sfenner * 1914214518Srpaulo * "ps_ifdrop" is supported. It will return the number 1915214518Srpaulo * of drops the interface reports in /proc/net/dev, 1916214518Srpaulo * if that is available. 1917214518Srpaulo * 191898530Sfenner * "ps_recv" doesn't include packets not yet read from 191998530Sfenner * the kernel by libpcap. 1920172677Smlaier * 1921172677Smlaier * We maintain the count of packets processed by libpcap in 1922172677Smlaier * "md.packets_read", for reasons described in the comment 1923172677Smlaier * at the end of pcap_read_packet(). We have no idea how many 1924214518Srpaulo * packets were dropped by the kernel buffers -- but we know 1925214518Srpaulo * how many the interface dropped, so we can return that. 192698530Sfenner */ 1927214518Srpaulo 1928172677Smlaier stats->ps_recv = handle->md.packets_read; 1929172677Smlaier stats->ps_drop = 0; 1930214518Srpaulo stats->ps_ifdrop = handle->md.stat.ps_ifdrop; 193175107Sfenner return 0; 193275107Sfenner} 193326175Sfenner 193475107Sfenner/* 1935214518Srpaulo * Get from "/sys/class/net" all interfaces listed there; if they're 1936214518Srpaulo * already in the list of interfaces we have, that won't add another 1937214518Srpaulo * instance, but if they're not, that'll add them. 1938214518Srpaulo * 1939214518Srpaulo * We don't bother getting any addresses for them; it appears you can't 1940214518Srpaulo * use SIOCGIFADDR on Linux to get IPv6 addresses for interfaces, and, 1941214518Srpaulo * although some other types of addresses can be fetched with SIOCGIFADDR, 1942214518Srpaulo * we don't bother with them for now. 1943214518Srpaulo * 1944214518Srpaulo * We also don't fail if we couldn't open "/sys/class/net"; we just leave 1945214518Srpaulo * the list of interfaces as is, and return 0, so that we can try 1946214518Srpaulo * scanning /proc/net/dev. 1947214518Srpaulo */ 1948214518Srpaulostatic int 1949214518Srpauloscan_sys_class_net(pcap_if_t **devlistp, char *errbuf) 1950214518Srpaulo{ 1951214518Srpaulo DIR *sys_class_net_d; 1952214518Srpaulo int fd; 1953214518Srpaulo struct dirent *ent; 1954214518Srpaulo char *p; 1955214518Srpaulo char name[512]; /* XXX - pick a size */ 1956214518Srpaulo char *q, *saveq; 1957214518Srpaulo struct ifreq ifrflags; 1958214518Srpaulo int ret = 1; 1959214518Srpaulo 1960214518Srpaulo sys_class_net_d = opendir("/sys/class/net"); 1961236167Sdelphij if (sys_class_net_d == NULL) { 1962236167Sdelphij /* 1963236167Sdelphij * Don't fail if it doesn't exist at all. 1964236167Sdelphij */ 1965236167Sdelphij if (errno == ENOENT) 1966236167Sdelphij return (0); 1967214518Srpaulo 1968236167Sdelphij /* 1969236167Sdelphij * Fail if we got some other error. 1970236167Sdelphij */ 1971236167Sdelphij (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 1972236167Sdelphij "Can't open /sys/class/net: %s", pcap_strerror(errno)); 1973236167Sdelphij return (-1); 1974236167Sdelphij } 1975236167Sdelphij 1976214518Srpaulo /* 1977214518Srpaulo * Create a socket from which to fetch interface information. 1978214518Srpaulo */ 1979214518Srpaulo fd = socket(AF_INET, SOCK_DGRAM, 0); 1980214518Srpaulo if (fd < 0) { 1981214518Srpaulo (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 1982214518Srpaulo "socket: %s", pcap_strerror(errno)); 1983236167Sdelphij (void)closedir(sys_class_net_d); 1984214518Srpaulo return (-1); 1985214518Srpaulo } 1986214518Srpaulo 1987214518Srpaulo for (;;) { 1988214518Srpaulo errno = 0; 1989214518Srpaulo ent = readdir(sys_class_net_d); 1990214518Srpaulo if (ent == NULL) { 1991214518Srpaulo /* 1992214518Srpaulo * Error or EOF; if errno != 0, it's an error. 1993214518Srpaulo */ 1994214518Srpaulo break; 1995214518Srpaulo } 1996214518Srpaulo 1997214518Srpaulo /* 1998214518Srpaulo * Ignore directories (".", "..", and any subdirectories). 1999214518Srpaulo */ 2000214518Srpaulo if (ent->d_type == DT_DIR) 2001214518Srpaulo continue; 2002214518Srpaulo 2003214518Srpaulo /* 2004214518Srpaulo * Get the interface name. 2005214518Srpaulo */ 2006214518Srpaulo p = &ent->d_name[0]; 2007214518Srpaulo q = &name[0]; 2008214518Srpaulo while (*p != '\0' && isascii(*p) && !isspace(*p)) { 2009214518Srpaulo if (*p == ':') { 2010214518Srpaulo /* 2011214518Srpaulo * This could be the separator between a 2012214518Srpaulo * name and an alias number, or it could be 2013214518Srpaulo * the separator between a name with no 2014214518Srpaulo * alias number and the next field. 2015214518Srpaulo * 2016214518Srpaulo * If there's a colon after digits, it 2017214518Srpaulo * separates the name and the alias number, 2018214518Srpaulo * otherwise it separates the name and the 2019214518Srpaulo * next field. 2020214518Srpaulo */ 2021214518Srpaulo saveq = q; 2022214518Srpaulo while (isascii(*p) && isdigit(*p)) 2023214518Srpaulo *q++ = *p++; 2024214518Srpaulo if (*p != ':') { 2025214518Srpaulo /* 2026214518Srpaulo * That was the next field, 2027214518Srpaulo * not the alias number. 2028214518Srpaulo */ 2029214518Srpaulo q = saveq; 2030214518Srpaulo } 2031214518Srpaulo break; 2032214518Srpaulo } else 2033214518Srpaulo *q++ = *p++; 2034214518Srpaulo } 2035214518Srpaulo *q = '\0'; 2036214518Srpaulo 2037214518Srpaulo /* 2038214518Srpaulo * Get the flags for this interface, and skip it if 2039214518Srpaulo * it's not up. 2040214518Srpaulo */ 2041214518Srpaulo strncpy(ifrflags.ifr_name, name, sizeof(ifrflags.ifr_name)); 2042214518Srpaulo if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) { 2043236167Sdelphij if (errno == ENXIO || errno == ENODEV) 2044214518Srpaulo continue; 2045214518Srpaulo (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 2046214518Srpaulo "SIOCGIFFLAGS: %.*s: %s", 2047214518Srpaulo (int)sizeof(ifrflags.ifr_name), 2048214518Srpaulo ifrflags.ifr_name, 2049214518Srpaulo pcap_strerror(errno)); 2050214518Srpaulo ret = -1; 2051214518Srpaulo break; 2052214518Srpaulo } 2053214518Srpaulo if (!(ifrflags.ifr_flags & IFF_UP)) 2054214518Srpaulo continue; 2055214518Srpaulo 2056214518Srpaulo /* 2057214518Srpaulo * Add an entry for this interface, with no addresses. 2058214518Srpaulo */ 2059214518Srpaulo if (pcap_add_if(devlistp, name, ifrflags.ifr_flags, NULL, 2060214518Srpaulo errbuf) == -1) { 2061214518Srpaulo /* 2062214518Srpaulo * Failure. 2063214518Srpaulo */ 2064214518Srpaulo ret = -1; 2065214518Srpaulo break; 2066214518Srpaulo } 2067214518Srpaulo } 2068214518Srpaulo if (ret != -1) { 2069214518Srpaulo /* 2070214518Srpaulo * Well, we didn't fail for any other reason; did we 2071214518Srpaulo * fail due to an error reading the directory? 2072214518Srpaulo */ 2073214518Srpaulo if (errno != 0) { 2074214518Srpaulo (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 2075214518Srpaulo "Error reading /sys/class/net: %s", 2076214518Srpaulo pcap_strerror(errno)); 2077214518Srpaulo ret = -1; 2078214518Srpaulo } 2079214518Srpaulo } 2080214518Srpaulo 2081214518Srpaulo (void)close(fd); 2082214518Srpaulo (void)closedir(sys_class_net_d); 2083214518Srpaulo return (ret); 2084214518Srpaulo} 2085214518Srpaulo 2086214518Srpaulo/* 2087214518Srpaulo * Get from "/proc/net/dev" all interfaces listed there; if they're 2088214518Srpaulo * already in the list of interfaces we have, that won't add another 2089214518Srpaulo * instance, but if they're not, that'll add them. 2090214518Srpaulo * 2091214518Srpaulo * See comments from scan_sys_class_net(). 2092214518Srpaulo */ 2093214518Srpaulostatic int 2094214518Srpauloscan_proc_net_dev(pcap_if_t **devlistp, char *errbuf) 2095214518Srpaulo{ 2096214518Srpaulo FILE *proc_net_f; 2097214518Srpaulo int fd; 2098214518Srpaulo char linebuf[512]; 2099214518Srpaulo int linenum; 2100214518Srpaulo char *p; 2101214518Srpaulo char name[512]; /* XXX - pick a size */ 2102214518Srpaulo char *q, *saveq; 2103214518Srpaulo struct ifreq ifrflags; 2104214518Srpaulo int ret = 0; 2105214518Srpaulo 2106214518Srpaulo proc_net_f = fopen("/proc/net/dev", "r"); 2107236167Sdelphij if (proc_net_f == NULL) { 2108236167Sdelphij /* 2109236167Sdelphij * Don't fail if it doesn't exist at all. 2110236167Sdelphij */ 2111236167Sdelphij if (errno == ENOENT) 2112236167Sdelphij return (0); 2113214518Srpaulo 2114236167Sdelphij /* 2115236167Sdelphij * Fail if we got some other error. 2116236167Sdelphij */ 2117236167Sdelphij (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 2118236167Sdelphij "Can't open /proc/net/dev: %s", pcap_strerror(errno)); 2119236167Sdelphij return (-1); 2120236167Sdelphij } 2121236167Sdelphij 2122214518Srpaulo /* 2123214518Srpaulo * Create a socket from which to fetch interface information. 2124214518Srpaulo */ 2125214518Srpaulo fd = socket(AF_INET, SOCK_DGRAM, 0); 2126214518Srpaulo if (fd < 0) { 2127214518Srpaulo (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 2128214518Srpaulo "socket: %s", pcap_strerror(errno)); 2129236167Sdelphij (void)fclose(proc_net_f); 2130214518Srpaulo return (-1); 2131214518Srpaulo } 2132214518Srpaulo 2133214518Srpaulo for (linenum = 1; 2134214518Srpaulo fgets(linebuf, sizeof linebuf, proc_net_f) != NULL; linenum++) { 2135214518Srpaulo /* 2136214518Srpaulo * Skip the first two lines - they're headers. 2137214518Srpaulo */ 2138214518Srpaulo if (linenum <= 2) 2139214518Srpaulo continue; 2140214518Srpaulo 2141214518Srpaulo p = &linebuf[0]; 2142214518Srpaulo 2143214518Srpaulo /* 2144214518Srpaulo * Skip leading white space. 2145214518Srpaulo */ 2146214518Srpaulo while (*p != '\0' && isascii(*p) && isspace(*p)) 2147214518Srpaulo p++; 2148214518Srpaulo if (*p == '\0' || *p == '\n') 2149214518Srpaulo continue; /* blank line */ 2150214518Srpaulo 2151214518Srpaulo /* 2152214518Srpaulo * Get the interface name. 2153214518Srpaulo */ 2154214518Srpaulo q = &name[0]; 2155214518Srpaulo while (*p != '\0' && isascii(*p) && !isspace(*p)) { 2156214518Srpaulo if (*p == ':') { 2157214518Srpaulo /* 2158214518Srpaulo * This could be the separator between a 2159214518Srpaulo * name and an alias number, or it could be 2160214518Srpaulo * the separator between a name with no 2161214518Srpaulo * alias number and the next field. 2162214518Srpaulo * 2163214518Srpaulo * If there's a colon after digits, it 2164214518Srpaulo * separates the name and the alias number, 2165214518Srpaulo * otherwise it separates the name and the 2166214518Srpaulo * next field. 2167214518Srpaulo */ 2168214518Srpaulo saveq = q; 2169214518Srpaulo while (isascii(*p) && isdigit(*p)) 2170214518Srpaulo *q++ = *p++; 2171214518Srpaulo if (*p != ':') { 2172214518Srpaulo /* 2173214518Srpaulo * That was the next field, 2174214518Srpaulo * not the alias number. 2175214518Srpaulo */ 2176214518Srpaulo q = saveq; 2177214518Srpaulo } 2178214518Srpaulo break; 2179214518Srpaulo } else 2180214518Srpaulo *q++ = *p++; 2181214518Srpaulo } 2182214518Srpaulo *q = '\0'; 2183214518Srpaulo 2184214518Srpaulo /* 2185214518Srpaulo * Get the flags for this interface, and skip it if 2186214518Srpaulo * it's not up. 2187214518Srpaulo */ 2188214518Srpaulo strncpy(ifrflags.ifr_name, name, sizeof(ifrflags.ifr_name)); 2189214518Srpaulo if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) { 2190214518Srpaulo if (errno == ENXIO) 2191214518Srpaulo continue; 2192214518Srpaulo (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 2193214518Srpaulo "SIOCGIFFLAGS: %.*s: %s", 2194214518Srpaulo (int)sizeof(ifrflags.ifr_name), 2195214518Srpaulo ifrflags.ifr_name, 2196214518Srpaulo pcap_strerror(errno)); 2197214518Srpaulo ret = -1; 2198214518Srpaulo break; 2199214518Srpaulo } 2200214518Srpaulo if (!(ifrflags.ifr_flags & IFF_UP)) 2201214518Srpaulo continue; 2202214518Srpaulo 2203214518Srpaulo /* 2204214518Srpaulo * Add an entry for this interface, with no addresses. 2205214518Srpaulo */ 2206214518Srpaulo if (pcap_add_if(devlistp, name, ifrflags.ifr_flags, NULL, 2207214518Srpaulo errbuf) == -1) { 2208214518Srpaulo /* 2209214518Srpaulo * Failure. 2210214518Srpaulo */ 2211214518Srpaulo ret = -1; 2212214518Srpaulo break; 2213214518Srpaulo } 2214214518Srpaulo } 2215214518Srpaulo if (ret != -1) { 2216214518Srpaulo /* 2217214518Srpaulo * Well, we didn't fail for any other reason; did we 2218214518Srpaulo * fail due to an error reading the file? 2219214518Srpaulo */ 2220214518Srpaulo if (ferror(proc_net_f)) { 2221214518Srpaulo (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 2222214518Srpaulo "Error reading /proc/net/dev: %s", 2223214518Srpaulo pcap_strerror(errno)); 2224214518Srpaulo ret = -1; 2225214518Srpaulo } 2226214518Srpaulo } 2227214518Srpaulo 2228214518Srpaulo (void)close(fd); 2229214518Srpaulo (void)fclose(proc_net_f); 2230214518Srpaulo return (ret); 2231214518Srpaulo} 2232214518Srpaulo 2233214518Srpaulo/* 2234127664Sbms * Description string for the "any" device. 223575107Sfenner */ 2236127664Sbmsstatic const char any_descr[] = "Pseudo-device that captures on all interfaces"; 2237127664Sbms 223875107Sfennerint 2239127664Sbmspcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) 224075107Sfenner{ 2241214518Srpaulo int ret; 2242214518Srpaulo 2243214518Srpaulo /* 2244214518Srpaulo * Read "/sys/class/net", and add to the list of interfaces all 2245214518Srpaulo * interfaces listed there that we don't already have, because, 2246214518Srpaulo * on Linux, SIOCGIFCONF reports only interfaces with IPv4 addresses, 2247214518Srpaulo * and even getifaddrs() won't return information about 2248214518Srpaulo * interfaces with no addresses, so you need to read "/sys/class/net" 2249214518Srpaulo * to get the names of the rest of the interfaces. 2250214518Srpaulo */ 2251214518Srpaulo ret = scan_sys_class_net(alldevsp, errbuf); 2252214518Srpaulo if (ret == -1) 2253214518Srpaulo return (-1); /* failed */ 2254214518Srpaulo if (ret == 0) { 2255214518Srpaulo /* 2256214518Srpaulo * No /sys/class/net; try reading /proc/net/dev instead. 2257214518Srpaulo */ 2258214518Srpaulo if (scan_proc_net_dev(alldevsp, errbuf) == -1) 2259214518Srpaulo return (-1); 2260214518Srpaulo } 2261214518Srpaulo 2262214518Srpaulo /* 2263214518Srpaulo * Add the "any" device. 2264214518Srpaulo */ 2265127664Sbms if (pcap_add_if(alldevsp, "any", 0, any_descr, errbuf) < 0) 2266127664Sbms return (-1); 2267127664Sbms 2268127664Sbms#ifdef HAVE_DAG_API 2269214518Srpaulo /* 2270214518Srpaulo * Add DAG devices. 2271214518Srpaulo */ 2272127664Sbms if (dag_platform_finddevs(alldevsp, errbuf) < 0) 2273127664Sbms return (-1); 2274127664Sbms#endif /* HAVE_DAG_API */ 2275127664Sbms 2276147894Ssam#ifdef HAVE_SEPTEL_API 2277214518Srpaulo /* 2278214518Srpaulo * Add Septel devices. 2279214518Srpaulo */ 2280147894Ssam if (septel_platform_finddevs(alldevsp, errbuf) < 0) 2281147894Ssam return (-1); 2282147894Ssam#endif /* HAVE_SEPTEL_API */ 2283147894Ssam 2284214518Srpaulo#ifdef HAVE_SNF_API 2285214518Srpaulo if (snf_platform_finddevs(alldevsp, errbuf) < 0) 2286214518Srpaulo return (-1); 2287214518Srpaulo#endif /* HAVE_SNF_API */ 2288214518Srpaulo 2289190225Srpaulo#ifdef PCAP_SUPPORT_BT 2290214518Srpaulo /* 2291214518Srpaulo * Add Bluetooth devices. 2292214518Srpaulo */ 2293190225Srpaulo if (bt_platform_finddevs(alldevsp, errbuf) < 0) 2294190225Srpaulo return (-1); 2295190225Srpaulo#endif 2296190225Srpaulo 2297190225Srpaulo#ifdef PCAP_SUPPORT_USB 2298214518Srpaulo /* 2299214518Srpaulo * Add USB devices. 2300214518Srpaulo */ 2301190225Srpaulo if (usb_platform_finddevs(alldevsp, errbuf) < 0) 2302190225Srpaulo return (-1); 2303190225Srpaulo#endif 2304190225Srpaulo 2305236167Sdelphij#ifdef PCAP_SUPPORT_NETFILTER 2306236167Sdelphij /* 2307236167Sdelphij * Add netfilter devices. 2308236167Sdelphij */ 2309236167Sdelphij if (netfilter_platform_finddevs(alldevsp, errbuf) < 0) 2310236167Sdelphij return (-1); 2311236167Sdelphij#endif 2312236167Sdelphij 2313242484Sdelphij#if PCAP_SUPPORT_CANUSB 2314242484Sdelphij if (canusb_platform_finddevs(alldevsp, errbuf) < 0) 2315242484Sdelphij return (-1); 2316242484Sdelphij#endif 2317242484Sdelphij 2318127664Sbms return (0); 2319127664Sbms} 2320127664Sbms 2321127664Sbms/* 2322127664Sbms * Attach the given BPF code to the packet capture device. 2323127664Sbms */ 2324127664Sbmsstatic int 2325214518Srpaulopcap_setfilter_linux_common(pcap_t *handle, struct bpf_program *filter, 2326214518Srpaulo int is_mmapped) 2327127664Sbms{ 232875107Sfenner#ifdef SO_ATTACH_FILTER 232975107Sfenner struct sock_fprog fcode; 233075107Sfenner int can_filter_in_kernel; 2331127664Sbms int err = 0; 233275107Sfenner#endif 233375107Sfenner 233475107Sfenner if (!handle) 233575107Sfenner return -1; 233675107Sfenner if (!filter) { 233775107Sfenner strncpy(handle->errbuf, "setfilter: No filter specified", 2338190225Srpaulo PCAP_ERRBUF_SIZE); 233975107Sfenner return -1; 234026175Sfenner } 234126175Sfenner 234275107Sfenner /* Make our private copy of the filter */ 234375107Sfenner 2344127664Sbms if (install_bpf_program(handle, filter) < 0) 2345127664Sbms /* install_bpf_program() filled in errbuf */ 234675107Sfenner return -1; 234739291Sfenner 2348127664Sbms /* 2349127664Sbms * Run user level packet filter by default. Will be overriden if 2350127664Sbms * installing a kernel filter succeeds. 235175107Sfenner */ 235275107Sfenner handle->md.use_bpf = 0; 235375107Sfenner 235475107Sfenner /* Install kernel level filter if possible */ 235575107Sfenner 235675107Sfenner#ifdef SO_ATTACH_FILTER 235775107Sfenner#ifdef USHRT_MAX 235875107Sfenner if (handle->fcode.bf_len > USHRT_MAX) { 235975107Sfenner /* 2360127664Sbms * fcode.len is an unsigned short for current kernel. 236175107Sfenner * I have yet to see BPF-Code with that much 236275107Sfenner * instructions but still it is possible. So for the 236375107Sfenner * sake of correctness I added this check. 236475107Sfenner */ 236575107Sfenner fprintf(stderr, "Warning: Filter too complex for kernel\n"); 2366172677Smlaier fcode.len = 0; 236775107Sfenner fcode.filter = NULL; 236875107Sfenner can_filter_in_kernel = 0; 236975107Sfenner } else 237075107Sfenner#endif /* USHRT_MAX */ 237175107Sfenner { 237275107Sfenner /* 237375107Sfenner * Oh joy, the Linux kernel uses struct sock_fprog instead 237475107Sfenner * of struct bpf_program and of course the length field is 237575107Sfenner * of different size. Pointed out by Sebastian 237675107Sfenner * 237775107Sfenner * Oh, and we also need to fix it up so that all "ret" 237875107Sfenner * instructions with non-zero operands have 65535 as the 2379214518Srpaulo * operand if we're not capturing in memory-mapped modee, 2380214518Srpaulo * and so that, if we're in cooked mode, all memory-reference 2381214518Srpaulo * instructions use special magic offsets in references to 2382214518Srpaulo * the link-layer header and assume that the link-layer 2383214518Srpaulo * payload begins at 0; "fix_program()" will do that. 238475107Sfenner */ 2385214518Srpaulo switch (fix_program(handle, &fcode, is_mmapped)) { 238675107Sfenner 238775107Sfenner case -1: 238875107Sfenner default: 238975107Sfenner /* 239075107Sfenner * Fatal error; just quit. 239175107Sfenner * (The "default" case shouldn't happen; we 239275107Sfenner * return -1 for that reason.) 239375107Sfenner */ 239475107Sfenner return -1; 239575107Sfenner 239675107Sfenner case 0: 239775107Sfenner /* 239875107Sfenner * The program performed checks that we can't make 239975107Sfenner * work in the kernel. 240075107Sfenner */ 240175107Sfenner can_filter_in_kernel = 0; 240275107Sfenner break; 240375107Sfenner 240475107Sfenner case 1: 240575107Sfenner /* 240675107Sfenner * We have a filter that'll work in the kernel. 240775107Sfenner */ 240875107Sfenner can_filter_in_kernel = 1; 240975107Sfenner break; 241075107Sfenner } 241139291Sfenner } 241239291Sfenner 2413236167Sdelphij /* 2414236167Sdelphij * NOTE: at this point, we've set both the "len" and "filter" 2415236167Sdelphij * fields of "fcode". As of the 2.6.32.4 kernel, at least, 2416236167Sdelphij * those are the only members of the "sock_fprog" structure, 2417236167Sdelphij * so we initialize every member of that structure. 2418236167Sdelphij * 2419236167Sdelphij * If there is anything in "fcode" that is not initialized, 2420236167Sdelphij * it is either a field added in a later kernel, or it's 2421236167Sdelphij * padding. 2422236167Sdelphij * 2423236167Sdelphij * If a new field is added, this code needs to be updated 2424236167Sdelphij * to set it correctly. 2425236167Sdelphij * 2426236167Sdelphij * If there are no other fields, then: 2427236167Sdelphij * 2428236167Sdelphij * if the Linux kernel looks at the padding, it's 2429236167Sdelphij * buggy; 2430236167Sdelphij * 2431236167Sdelphij * if the Linux kernel doesn't look at the padding, 2432236167Sdelphij * then if some tool complains that we're passing 2433236167Sdelphij * uninitialized data to the kernel, then the tool 2434236167Sdelphij * is buggy and needs to understand that it's just 2435236167Sdelphij * padding. 2436236167Sdelphij */ 243775107Sfenner if (can_filter_in_kernel) { 2438127664Sbms if ((err = set_kernel_filter(handle, &fcode)) == 0) 243975107Sfenner { 244075107Sfenner /* Installation succeded - using kernel filter. */ 244175107Sfenner handle->md.use_bpf = 1; 244275107Sfenner } 2443127664Sbms else if (err == -1) /* Non-fatal error */ 244475107Sfenner { 2445127664Sbms /* 244675107Sfenner * Print a warning if we weren't able to install 244775107Sfenner * the filter for a reason other than "this kernel 244875107Sfenner * isn't configured to support socket filters. 244975107Sfenner */ 245075107Sfenner if (errno != ENOPROTOOPT && errno != EOPNOTSUPP) { 245175107Sfenner fprintf(stderr, 2452127664Sbms "Warning: Kernel filter failed: %s\n", 245375107Sfenner pcap_strerror(errno)); 245475107Sfenner } 245575107Sfenner } 245639291Sfenner } 245739291Sfenner 245875107Sfenner /* 245998530Sfenner * If we're not using the kernel filter, get rid of any kernel 246098530Sfenner * filter that might've been there before, e.g. because the 246198530Sfenner * previous filter could work in the kernel, or because some other 246298530Sfenner * code attached a filter to the socket by some means other than 246398530Sfenner * calling "pcap_setfilter()". Otherwise, the kernel filter may 246498530Sfenner * filter out packets that would pass the new userland filter. 246598530Sfenner */ 246698530Sfenner if (!handle->md.use_bpf) 246798530Sfenner reset_kernel_filter(handle); 246898530Sfenner 246998530Sfenner /* 247075107Sfenner * Free up the copy of the filter that was made by "fix_program()". 247175107Sfenner */ 247275107Sfenner if (fcode.filter != NULL) 247375107Sfenner free(fcode.filter); 2474127664Sbms 2475127664Sbms if (err == -2) 2476127664Sbms /* Fatal error */ 2477127664Sbms return -1; 247875107Sfenner#endif /* SO_ATTACH_FILTER */ 247975107Sfenner 248075107Sfenner return 0; 248175107Sfenner} 248275107Sfenner 2483214518Srpaulostatic int 2484214518Srpaulopcap_setfilter_linux(pcap_t *handle, struct bpf_program *filter) 2485214518Srpaulo{ 2486214518Srpaulo return pcap_setfilter_linux_common(handle, filter, 0); 2487214518Srpaulo} 2488214518Srpaulo 2489214518Srpaulo 249075107Sfenner/* 2491147894Ssam * Set direction flag: Which packets do we accept on a forwarding 2492147894Ssam * single device? IN, OUT or both? 2493147894Ssam */ 2494147894Ssamstatic int 2495162012Ssampcap_setdirection_linux(pcap_t *handle, pcap_direction_t d) 2496147894Ssam{ 2497147894Ssam#ifdef HAVE_PF_PACKET_SOCKETS 2498147894Ssam if (!handle->md.sock_packet) { 2499147894Ssam handle->direction = d; 2500147894Ssam return 0; 2501147894Ssam } 2502147894Ssam#endif 2503147894Ssam /* 2504147894Ssam * We're not using PF_PACKET sockets, so we can't determine 2505147894Ssam * the direction of the packet. 2506147894Ssam */ 2507190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 2508147894Ssam "Setting direction is not supported on SOCK_PACKET sockets"); 2509147894Ssam return -1; 2510147894Ssam} 2511147894Ssam 2512190225Srpaulo#ifdef HAVE_PF_PACKET_SOCKETS 2513147894Ssam/* 2514190225Srpaulo * Map the PACKET_ value to a LINUX_SLL_ value; we 2515190225Srpaulo * want the same numerical value to be used in 2516190225Srpaulo * the link-layer header even if the numerical values 2517190225Srpaulo * for the PACKET_ #defines change, so that programs 2518190225Srpaulo * that look at the packet type field will always be 2519190225Srpaulo * able to handle DLT_LINUX_SLL captures. 2520190225Srpaulo */ 2521190225Srpaulostatic short int 2522190225Srpaulomap_packet_type_to_sll_type(short int sll_pkttype) 2523190225Srpaulo{ 2524190225Srpaulo switch (sll_pkttype) { 2525190225Srpaulo 2526190225Srpaulo case PACKET_HOST: 2527190225Srpaulo return htons(LINUX_SLL_HOST); 2528190225Srpaulo 2529190225Srpaulo case PACKET_BROADCAST: 2530190225Srpaulo return htons(LINUX_SLL_BROADCAST); 2531190225Srpaulo 2532190225Srpaulo case PACKET_MULTICAST: 2533190225Srpaulo return htons(LINUX_SLL_MULTICAST); 2534190225Srpaulo 2535190225Srpaulo case PACKET_OTHERHOST: 2536190225Srpaulo return htons(LINUX_SLL_OTHERHOST); 2537190225Srpaulo 2538190225Srpaulo case PACKET_OUTGOING: 2539190225Srpaulo return htons(LINUX_SLL_OUTGOING); 2540190225Srpaulo 2541190225Srpaulo default: 2542190225Srpaulo return -1; 2543190225Srpaulo } 2544190225Srpaulo} 2545190225Srpaulo#endif 2546190225Srpaulo 2547190225Srpaulo/* 2548127664Sbms * Linux uses the ARP hardware type to identify the type of an 2549127664Sbms * interface. pcap uses the DLT_xxx constants for this. This 255098530Sfenner * function takes a pointer to a "pcap_t", and an ARPHRD_xxx 255198530Sfenner * constant, as arguments, and sets "handle->linktype" to the 255298530Sfenner * appropriate DLT_XXX constant and sets "handle->offset" to 255398530Sfenner * the appropriate value (to make "handle->offset" plus link-layer 255498530Sfenner * header length be a multiple of 4, so that the link-layer payload 255598530Sfenner * will be aligned on a 4-byte boundary when capturing packets). 255698530Sfenner * (If the offset isn't set here, it'll be 0; add code as appropriate 255798530Sfenner * for cases where it shouldn't be 0.) 2558127664Sbms * 2559127664Sbms * If "cooked_ok" is non-zero, we can use DLT_LINUX_SLL and capture 2560127664Sbms * in cooked mode; otherwise, we can't use cooked mode, so we have 2561127664Sbms * to pick some type that works in raw mode, or fail. 2562127664Sbms * 256398530Sfenner * Sets the link type to -1 if unable to map the type. 256475107Sfenner */ 2565127664Sbmsstatic void map_arphrd_to_dlt(pcap_t *handle, int arptype, int cooked_ok) 256675107Sfenner{ 256775107Sfenner switch (arptype) { 256898530Sfenner 256939291Sfenner case ARPHRD_ETHER: 2570146768Ssam /* 2571146768Ssam * This is (presumably) a real Ethernet capture; give it a 2572146768Ssam * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so 2573146768Ssam * that an application can let you choose it, in case you're 2574146768Ssam * capturing DOCSIS traffic that a Cisco Cable Modem 2575146768Ssam * Termination System is putting out onto an Ethernet (it 2576146768Ssam * doesn't put an Ethernet header onto the wire, it puts raw 2577146768Ssam * DOCSIS frames out on the wire inside the low-level 2578146768Ssam * Ethernet framing). 2579146768Ssam * 2580146768Ssam * XXX - are there any sorts of "fake Ethernet" that have 2581146768Ssam * ARPHRD_ETHER but that *shouldn't offer DLT_DOCSIS as 2582146768Ssam * a Cisco CMTS won't put traffic onto it or get traffic 2583190225Srpaulo * bridged onto it? ISDN is handled in "activate_new()", 2584146768Ssam * as we fall back on cooked mode there; are there any 2585146768Ssam * others? 2586146768Ssam */ 2587146768Ssam handle->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); 2588146768Ssam /* 2589146768Ssam * If that fails, just leave the list empty. 2590146768Ssam */ 2591146768Ssam if (handle->dlt_list != NULL) { 2592146768Ssam handle->dlt_list[0] = DLT_EN10MB; 2593146768Ssam handle->dlt_list[1] = DLT_DOCSIS; 2594146768Ssam handle->dlt_count = 2; 2595146768Ssam } 2596146768Ssam /* FALLTHROUGH */ 2597146768Ssam 259839291Sfenner case ARPHRD_METRICOM: 259998530Sfenner case ARPHRD_LOOPBACK: 260098530Sfenner handle->linktype = DLT_EN10MB; 260198530Sfenner handle->offset = 2; 260298530Sfenner break; 260398530Sfenner 260498530Sfenner case ARPHRD_EETHER: 260598530Sfenner handle->linktype = DLT_EN3MB; 260698530Sfenner break; 260798530Sfenner 260898530Sfenner case ARPHRD_AX25: 2609190225Srpaulo handle->linktype = DLT_AX25_KISS; 261098530Sfenner break; 261198530Sfenner 261298530Sfenner case ARPHRD_PRONET: 261398530Sfenner handle->linktype = DLT_PRONET; 261498530Sfenner break; 261598530Sfenner 261698530Sfenner case ARPHRD_CHAOS: 261798530Sfenner handle->linktype = DLT_CHAOS; 261898530Sfenner break; 2619214518Srpaulo#ifndef ARPHRD_CAN 2620214518Srpaulo#define ARPHRD_CAN 280 2621214518Srpaulo#endif 2622214518Srpaulo case ARPHRD_CAN: 2623214518Srpaulo handle->linktype = DLT_CAN_SOCKETCAN; 2624214518Srpaulo break; 262598530Sfenner 262675107Sfenner#ifndef ARPHRD_IEEE802_TR 262775107Sfenner#define ARPHRD_IEEE802_TR 800 /* From Linux 2.4 */ 262875107Sfenner#endif 262975107Sfenner case ARPHRD_IEEE802_TR: 263098530Sfenner case ARPHRD_IEEE802: 263198530Sfenner handle->linktype = DLT_IEEE802; 263298530Sfenner handle->offset = 2; 263398530Sfenner break; 263439291Sfenner 263598530Sfenner case ARPHRD_ARCNET: 2636127664Sbms handle->linktype = DLT_ARCNET_LINUX; 263798530Sfenner break; 263898530Sfenner 2639127664Sbms#ifndef ARPHRD_FDDI /* From Linux 2.2.13 */ 2640127664Sbms#define ARPHRD_FDDI 774 2641127664Sbms#endif 264298530Sfenner case ARPHRD_FDDI: 264398530Sfenner handle->linktype = DLT_FDDI; 264498530Sfenner handle->offset = 3; 264598530Sfenner break; 264698530Sfenner 264775107Sfenner#ifndef ARPHRD_ATM /* FIXME: How to #include this? */ 264875107Sfenner#define ARPHRD_ATM 19 264975107Sfenner#endif 265098530Sfenner case ARPHRD_ATM: 265198530Sfenner /* 265298530Sfenner * The Classical IP implementation in ATM for Linux 265398530Sfenner * supports both what RFC 1483 calls "LLC Encapsulation", 265498530Sfenner * in which each packet has an LLC header, possibly 265598530Sfenner * with a SNAP header as well, prepended to it, and 265698530Sfenner * what RFC 1483 calls "VC Based Multiplexing", in which 265798530Sfenner * different virtual circuits carry different network 265898530Sfenner * layer protocols, and no header is prepended to packets. 265998530Sfenner * 266098530Sfenner * They both have an ARPHRD_ type of ARPHRD_ATM, so 266198530Sfenner * you can't use the ARPHRD_ type to find out whether 266298530Sfenner * captured packets will have an LLC header, and, 266398530Sfenner * while there's a socket ioctl to *set* the encapsulation 266498530Sfenner * type, there's no ioctl to *get* the encapsulation type. 266598530Sfenner * 266698530Sfenner * This means that 266798530Sfenner * 266898530Sfenner * programs that dissect Linux Classical IP frames 266998530Sfenner * would have to check for an LLC header and, 267098530Sfenner * depending on whether they see one or not, dissect 267198530Sfenner * the frame as LLC-encapsulated or as raw IP (I 267298530Sfenner * don't know whether there's any traffic other than 267398530Sfenner * IP that would show up on the socket, or whether 267498530Sfenner * there's any support for IPv6 in the Linux 267598530Sfenner * Classical IP code); 267698530Sfenner * 267798530Sfenner * filter expressions would have to compile into 267898530Sfenner * code that checks for an LLC header and does 267998530Sfenner * the right thing. 268098530Sfenner * 268198530Sfenner * Both of those are a nuisance - and, at least on systems 268298530Sfenner * that support PF_PACKET sockets, we don't have to put 268398530Sfenner * up with those nuisances; instead, we can just capture 2684127664Sbms * in cooked mode. That's what we'll do, if we can. 2685127664Sbms * Otherwise, we'll just fail. 268698530Sfenner */ 2687127664Sbms if (cooked_ok) 2688127664Sbms handle->linktype = DLT_LINUX_SLL; 2689127664Sbms else 2690127664Sbms handle->linktype = -1; 269198530Sfenner break; 269239291Sfenner 269398530Sfenner#ifndef ARPHRD_IEEE80211 /* From Linux 2.4.6 */ 269498530Sfenner#define ARPHRD_IEEE80211 801 269598530Sfenner#endif 269698530Sfenner case ARPHRD_IEEE80211: 269798530Sfenner handle->linktype = DLT_IEEE802_11; 269898530Sfenner break; 269998530Sfenner 2700127664Sbms#ifndef ARPHRD_IEEE80211_PRISM /* From Linux 2.4.18 */ 2701127664Sbms#define ARPHRD_IEEE80211_PRISM 802 2702127664Sbms#endif 2703127664Sbms case ARPHRD_IEEE80211_PRISM: 2704127664Sbms handle->linktype = DLT_PRISM_HEADER; 2705127664Sbms break; 2706127664Sbms 2707162012Ssam#ifndef ARPHRD_IEEE80211_RADIOTAP /* new */ 2708162012Ssam#define ARPHRD_IEEE80211_RADIOTAP 803 2709162012Ssam#endif 2710162012Ssam case ARPHRD_IEEE80211_RADIOTAP: 2711162012Ssam handle->linktype = DLT_IEEE802_11_RADIO; 2712162012Ssam break; 2713162012Ssam 271475107Sfenner case ARPHRD_PPP: 271598530Sfenner /* 271698530Sfenner * Some PPP code in the kernel supplies no link-layer 271798530Sfenner * header whatsoever to PF_PACKET sockets; other PPP 271898530Sfenner * code supplies PPP link-layer headers ("syncppp.c"); 271998530Sfenner * some PPP code might supply random link-layer 272098530Sfenner * headers (PPP over ISDN - there's code in Ethereal, 272198530Sfenner * for example, to cope with PPP-over-ISDN captures 272298530Sfenner * with which the Ethereal developers have had to cope, 272398530Sfenner * heuristically trying to determine which of the 272498530Sfenner * oddball link-layer headers particular packets have). 272598530Sfenner * 272698530Sfenner * As such, we just punt, and run all PPP interfaces 2727127664Sbms * in cooked mode, if we can; otherwise, we just treat 2728127664Sbms * it as DLT_RAW, for now - if somebody needs to capture, 2729127664Sbms * on a 2.0[.x] kernel, on PPP devices that supply a 2730127664Sbms * link-layer header, they'll have to add code here to 2731127664Sbms * map to the appropriate DLT_ type (possibly adding a 2732127664Sbms * new DLT_ type, if necessary). 273398530Sfenner */ 2734127664Sbms if (cooked_ok) 2735127664Sbms handle->linktype = DLT_LINUX_SLL; 2736127664Sbms else { 2737127664Sbms /* 2738127664Sbms * XXX - handle ISDN types here? We can't fall 2739127664Sbms * back on cooked sockets, so we'd have to 2740127664Sbms * figure out from the device name what type of 2741127664Sbms * link-layer encapsulation it's using, and map 2742127664Sbms * that to an appropriate DLT_ value, meaning 2743127664Sbms * we'd map "isdnN" devices to DLT_RAW (they 2744127664Sbms * supply raw IP packets with no link-layer 2745127664Sbms * header) and "isdY" devices to a new DLT_I4L_IP 2746127664Sbms * type that has only an Ethernet packet type as 2747127664Sbms * a link-layer header. 2748127664Sbms * 2749127664Sbms * But sometimes we seem to get random crap 2750127664Sbms * in the link-layer header when capturing on 2751127664Sbms * ISDN devices.... 2752127664Sbms */ 2753127664Sbms handle->linktype = DLT_RAW; 2754127664Sbms } 275598530Sfenner break; 275698530Sfenner 2757127664Sbms#ifndef ARPHRD_CISCO 2758127664Sbms#define ARPHRD_CISCO 513 /* previously ARPHRD_HDLC */ 2759127664Sbms#endif 2760127664Sbms case ARPHRD_CISCO: 276198530Sfenner handle->linktype = DLT_C_HDLC; 276298530Sfenner break; 276398530Sfenner 276475107Sfenner /* Not sure if this is correct for all tunnels, but it 276575107Sfenner * works for CIPE */ 276675107Sfenner case ARPHRD_TUNNEL: 276775107Sfenner#ifndef ARPHRD_SIT 2768127664Sbms#define ARPHRD_SIT 776 /* From Linux 2.2.13 */ 276975107Sfenner#endif 277075107Sfenner case ARPHRD_SIT: 277175107Sfenner case ARPHRD_CSLIP: 277275107Sfenner case ARPHRD_SLIP6: 277375107Sfenner case ARPHRD_CSLIP6: 277498530Sfenner case ARPHRD_ADAPT: 277598530Sfenner case ARPHRD_SLIP: 2776127664Sbms#ifndef ARPHRD_RAWHDLC 2777127664Sbms#define ARPHRD_RAWHDLC 518 2778127664Sbms#endif 2779127664Sbms case ARPHRD_RAWHDLC: 2780127664Sbms#ifndef ARPHRD_DLCI 2781127664Sbms#define ARPHRD_DLCI 15 2782127664Sbms#endif 2783127664Sbms case ARPHRD_DLCI: 278498530Sfenner /* 278598530Sfenner * XXX - should some of those be mapped to DLT_LINUX_SLL 278698530Sfenner * instead? Should we just map all of them to DLT_LINUX_SLL? 278798530Sfenner */ 278898530Sfenner handle->linktype = DLT_RAW; 278998530Sfenner break; 279098530Sfenner 2791127664Sbms#ifndef ARPHRD_FRAD 2792127664Sbms#define ARPHRD_FRAD 770 2793127664Sbms#endif 2794127664Sbms case ARPHRD_FRAD: 2795127664Sbms handle->linktype = DLT_FRELAY; 2796127664Sbms break; 2797127664Sbms 279898530Sfenner case ARPHRD_LOCALTLK: 279998530Sfenner handle->linktype = DLT_LTALK; 280098530Sfenner break; 280198530Sfenner 2802127664Sbms#ifndef ARPHRD_FCPP 2803127664Sbms#define ARPHRD_FCPP 784 2804127664Sbms#endif 2805127664Sbms case ARPHRD_FCPP: 2806127664Sbms#ifndef ARPHRD_FCAL 2807127664Sbms#define ARPHRD_FCAL 785 2808127664Sbms#endif 2809127664Sbms case ARPHRD_FCAL: 2810127664Sbms#ifndef ARPHRD_FCPL 2811127664Sbms#define ARPHRD_FCPL 786 2812127664Sbms#endif 2813127664Sbms case ARPHRD_FCPL: 2814127664Sbms#ifndef ARPHRD_FCFABRIC 2815127664Sbms#define ARPHRD_FCFABRIC 787 2816127664Sbms#endif 2817127664Sbms case ARPHRD_FCFABRIC: 2818127664Sbms /* 2819127664Sbms * We assume that those all mean RFC 2625 IP-over- 2820127664Sbms * Fibre Channel, with the RFC 2625 header at 2821127664Sbms * the beginning of the packet. 2822127664Sbms */ 2823127664Sbms handle->linktype = DLT_IP_OVER_FC; 2824127664Sbms break; 2825127664Sbms 2826146768Ssam#ifndef ARPHRD_IRDA 2827146768Ssam#define ARPHRD_IRDA 783 2828146768Ssam#endif 2829127664Sbms case ARPHRD_IRDA: 2830127664Sbms /* Don't expect IP packet out of this interfaces... */ 2831127664Sbms handle->linktype = DLT_LINUX_IRDA; 2832127664Sbms /* We need to save packet direction for IrDA decoding, 2833127664Sbms * so let's use "Linux-cooked" mode. Jean II */ 2834127664Sbms //handle->md.cooked = 1; 2835127664Sbms break; 2836127664Sbms 2837172677Smlaier /* ARPHRD_LAPD is unofficial and randomly allocated, if reallocation 2838172677Smlaier * is needed, please report it to <daniele@orlandi.com> */ 2839172677Smlaier#ifndef ARPHRD_LAPD 2840172677Smlaier#define ARPHRD_LAPD 8445 2841172677Smlaier#endif 2842172677Smlaier case ARPHRD_LAPD: 2843172677Smlaier /* Don't expect IP packet out of this interfaces... */ 2844172677Smlaier handle->linktype = DLT_LINUX_LAPD; 2845172677Smlaier break; 2846172677Smlaier 2847190225Srpaulo#ifndef ARPHRD_NONE 2848190225Srpaulo#define ARPHRD_NONE 0xFFFE 2849190225Srpaulo#endif 2850190225Srpaulo case ARPHRD_NONE: 2851190225Srpaulo /* 2852190225Srpaulo * No link-layer header; packets are just IP 2853190225Srpaulo * packets, so use DLT_RAW. 2854190225Srpaulo */ 2855190225Srpaulo handle->linktype = DLT_RAW; 2856190225Srpaulo break; 2857190225Srpaulo 2858236167Sdelphij#ifndef ARPHRD_IEEE802154 2859236167Sdelphij#define ARPHRD_IEEE802154 804 2860236167Sdelphij#endif 2861236167Sdelphij case ARPHRD_IEEE802154: 2862236167Sdelphij handle->linktype = DLT_IEEE802_15_4_NOFCS; 2863236167Sdelphij break; 2864236167Sdelphij 286598530Sfenner default: 286698530Sfenner handle->linktype = -1; 286798530Sfenner break; 286875107Sfenner } 286975107Sfenner} 287039291Sfenner 287175107Sfenner/* ===== Functions to interface to the newer kernels ================== */ 287239291Sfenner 287375107Sfenner/* 2874190225Srpaulo * Try to open a packet socket using the new kernel PF_PACKET interface. 2875190225Srpaulo * Returns 1 on success, 0 on an error that means the new interface isn't 2876190225Srpaulo * present (so the old SOCK_PACKET interface should be tried), and a 2877190225Srpaulo * PCAP_ERROR_ value on an error that means that the old mechanism won't 2878190225Srpaulo * work either (so it shouldn't be tried). 287975107Sfenner */ 288075107Sfennerstatic int 2881190225Srpauloactivate_new(pcap_t *handle) 288275107Sfenner{ 288375107Sfenner#ifdef HAVE_PF_PACKET_SOCKETS 2884214518Srpaulo const char *device = handle->opt.source; 2885214518Srpaulo int is_any_device = (strcmp(device, "any") == 0); 2886214518Srpaulo int sock_fd = -1, arptype; 2887214518Srpaulo#ifdef HAVE_PACKET_AUXDATA 2888214518Srpaulo int val; 2889214518Srpaulo#endif 2890190225Srpaulo int err = 0; 289175107Sfenner struct packet_mreq mr; 289239291Sfenner 2893190225Srpaulo /* 2894214518Srpaulo * Open a socket with protocol family packet. If the 2895214518Srpaulo * "any" device was specified, we open a SOCK_DGRAM 2896214518Srpaulo * socket for the cooked interface, otherwise we first 2897214518Srpaulo * try a SOCK_RAW socket for the raw interface. 2898190225Srpaulo */ 2899214518Srpaulo sock_fd = is_any_device ? 2900214518Srpaulo socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)) : 2901214518Srpaulo socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 290239291Sfenner 2903190225Srpaulo if (sock_fd == -1) { 2904236167Sdelphij if (errno == EINVAL || errno == EAFNOSUPPORT) { 2905236167Sdelphij /* 2906236167Sdelphij * We don't support PF_PACKET/SOCK_whatever 2907236167Sdelphij * sockets; try the old mechanism. 2908236167Sdelphij */ 2909236167Sdelphij return 0; 2910236167Sdelphij } 2911236167Sdelphij 2912190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "socket: %s", 2913190225Srpaulo pcap_strerror(errno) ); 2914236167Sdelphij if (errno == EPERM || errno == EACCES) { 2915236167Sdelphij /* 2916236167Sdelphij * You don't have permission to open the 2917236167Sdelphij * socket. 2918236167Sdelphij */ 2919236167Sdelphij return PCAP_ERROR_PERM_DENIED; 2920236167Sdelphij } else { 2921236167Sdelphij /* 2922236167Sdelphij * Other error. 2923236167Sdelphij */ 2924236167Sdelphij return PCAP_ERROR; 2925236167Sdelphij } 2926190225Srpaulo } 292739291Sfenner 2928190225Srpaulo /* It seems the kernel supports the new interface. */ 2929190225Srpaulo handle->md.sock_packet = 0; 293039291Sfenner 2931190225Srpaulo /* 2932190225Srpaulo * Get the interface index of the loopback device. 2933190225Srpaulo * If the attempt fails, don't fail, just set the 2934190225Srpaulo * "md.lo_ifindex" to -1. 2935190225Srpaulo * 2936190225Srpaulo * XXX - can there be more than one device that loops 2937190225Srpaulo * packets back, i.e. devices other than "lo"? If so, 2938190225Srpaulo * we'd need to find them all, and have an array of 2939190225Srpaulo * indices for them, and check all of them in 2940190225Srpaulo * "pcap_read_packet()". 2941190225Srpaulo */ 2942190225Srpaulo handle->md.lo_ifindex = iface_get_id(sock_fd, "lo", handle->errbuf); 294375107Sfenner 2944190225Srpaulo /* 2945190225Srpaulo * Default value for offset to align link-layer payload 2946190225Srpaulo * on a 4-byte boundary. 2947190225Srpaulo */ 2948190225Srpaulo handle->offset = 0; 294975107Sfenner 2950190225Srpaulo /* 2951190225Srpaulo * What kind of frames do we have to deal with? Fall back 2952190225Srpaulo * to cooked mode if we have an unknown interface type 2953190225Srpaulo * or a type we know doesn't work well in raw mode. 2954190225Srpaulo */ 2955214518Srpaulo if (!is_any_device) { 2956190225Srpaulo /* Assume for now we don't need cooked mode. */ 2957190225Srpaulo handle->md.cooked = 0; 295898530Sfenner 2959190225Srpaulo if (handle->opt.rfmon) { 2960190225Srpaulo /* 2961190225Srpaulo * We were asked to turn on monitor mode. 2962190225Srpaulo * Do so before we get the link-layer type, 2963190225Srpaulo * because entering monitor mode could change 2964190225Srpaulo * the link-layer type. 2965190225Srpaulo */ 2966214518Srpaulo err = enter_rfmon_mode(handle, sock_fd, device); 2967190225Srpaulo if (err < 0) { 2968190225Srpaulo /* Hard failure */ 2969190225Srpaulo close(sock_fd); 2970190225Srpaulo return err; 2971127664Sbms } 2972190225Srpaulo if (err == 0) { 297375107Sfenner /* 2974190225Srpaulo * Nothing worked for turning monitor mode 2975190225Srpaulo * on. 297675107Sfenner */ 2977190225Srpaulo close(sock_fd); 2978190225Srpaulo return PCAP_ERROR_RFMON_NOTSUP; 2979190225Srpaulo } 2980214518Srpaulo 2981214518Srpaulo /* 2982214518Srpaulo * Either monitor mode has been turned on for 2983214518Srpaulo * the device, or we've been given a different 2984214518Srpaulo * device to open for monitor mode. If we've 2985214518Srpaulo * been given a different device, use it. 2986214518Srpaulo */ 2987214518Srpaulo if (handle->md.mondevice != NULL) 2988214518Srpaulo device = handle->md.mondevice; 2989190225Srpaulo } 2990190225Srpaulo arptype = iface_get_arptype(sock_fd, device, handle->errbuf); 2991190225Srpaulo if (arptype < 0) { 2992190225Srpaulo close(sock_fd); 2993190225Srpaulo return arptype; 2994190225Srpaulo } 2995190225Srpaulo map_arphrd_to_dlt(handle, arptype, 1); 2996190225Srpaulo if (handle->linktype == -1 || 2997190225Srpaulo handle->linktype == DLT_LINUX_SLL || 2998190225Srpaulo handle->linktype == DLT_LINUX_IRDA || 2999190225Srpaulo handle->linktype == DLT_LINUX_LAPD || 3000190225Srpaulo (handle->linktype == DLT_EN10MB && 3001190225Srpaulo (strncmp("isdn", device, 4) == 0 || 3002190225Srpaulo strncmp("isdY", device, 4) == 0))) { 3003190225Srpaulo /* 3004190225Srpaulo * Unknown interface type (-1), or a 3005190225Srpaulo * device we explicitly chose to run 3006190225Srpaulo * in cooked mode (e.g., PPP devices), 3007190225Srpaulo * or an ISDN device (whose link-layer 3008190225Srpaulo * type we can only determine by using 3009190225Srpaulo * APIs that may be different on different 3010190225Srpaulo * kernels) - reopen in cooked mode. 3011190225Srpaulo */ 3012190225Srpaulo if (close(sock_fd) == -1) { 3013190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3014190225Srpaulo "close: %s", pcap_strerror(errno)); 3015190225Srpaulo return PCAP_ERROR; 3016190225Srpaulo } 3017190225Srpaulo sock_fd = socket(PF_PACKET, SOCK_DGRAM, 3018190225Srpaulo htons(ETH_P_ALL)); 3019190225Srpaulo if (sock_fd == -1) { 3020190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3021190225Srpaulo "socket: %s", pcap_strerror(errno)); 3022236167Sdelphij if (errno == EPERM || errno == EACCES) { 3023236167Sdelphij /* 3024236167Sdelphij * You don't have permission to 3025236167Sdelphij * open the socket. 3026236167Sdelphij */ 3027236167Sdelphij return PCAP_ERROR_PERM_DENIED; 3028236167Sdelphij } else { 3029236167Sdelphij /* 3030236167Sdelphij * Other error. 3031236167Sdelphij */ 3032236167Sdelphij return PCAP_ERROR; 3033236167Sdelphij } 3034190225Srpaulo } 3035190225Srpaulo handle->md.cooked = 1; 303675107Sfenner 3037190225Srpaulo /* 3038190225Srpaulo * Get rid of any link-layer type list 3039190225Srpaulo * we allocated - this only supports cooked 3040190225Srpaulo * capture. 3041190225Srpaulo */ 3042190225Srpaulo if (handle->dlt_list != NULL) { 3043190225Srpaulo free(handle->dlt_list); 3044190225Srpaulo handle->dlt_list = NULL; 3045190225Srpaulo handle->dlt_count = 0; 3046190225Srpaulo } 3047190225Srpaulo 3048190225Srpaulo if (handle->linktype == -1) { 3049146768Ssam /* 3050190225Srpaulo * Warn that we're falling back on 3051190225Srpaulo * cooked mode; we may want to 3052190225Srpaulo * update "map_arphrd_to_dlt()" 3053190225Srpaulo * to handle the new type. 3054146768Ssam */ 3055190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3056190225Srpaulo "arptype %d not " 3057190225Srpaulo "supported by libpcap - " 3058190225Srpaulo "falling back to cooked " 3059190225Srpaulo "socket", 3060190225Srpaulo arptype); 306175107Sfenner } 306275107Sfenner 306375107Sfenner /* 3064190225Srpaulo * IrDA capture is not a real "cooked" capture, 3065190225Srpaulo * it's IrLAP frames, not IP packets. The 3066190225Srpaulo * same applies to LAPD capture. 306775107Sfenner */ 3068190225Srpaulo if (handle->linktype != DLT_LINUX_IRDA && 3069190225Srpaulo handle->linktype != DLT_LINUX_LAPD) 3070190225Srpaulo handle->linktype = DLT_LINUX_SLL; 3071190225Srpaulo } 307275107Sfenner 3073190225Srpaulo handle->md.ifindex = iface_get_id(sock_fd, device, 3074190225Srpaulo handle->errbuf); 3075190225Srpaulo if (handle->md.ifindex == -1) { 3076190225Srpaulo close(sock_fd); 3077190225Srpaulo return PCAP_ERROR; 307875107Sfenner } 307975107Sfenner 3080190225Srpaulo if ((err = iface_bind(sock_fd, handle->md.ifindex, 3081190225Srpaulo handle->errbuf)) != 1) { 3082190225Srpaulo close(sock_fd); 3083190225Srpaulo if (err < 0) 3084190225Srpaulo return err; 3085190225Srpaulo else 3086190225Srpaulo return 0; /* try old mechanism */ 3087190225Srpaulo } 3088190225Srpaulo } else { 3089127664Sbms /* 3090214518Srpaulo * The "any" device. 3091127664Sbms */ 3092214518Srpaulo if (handle->opt.rfmon) { 3093214518Srpaulo /* 3094214518Srpaulo * It doesn't support monitor mode. 3095214518Srpaulo */ 3096214518Srpaulo return PCAP_ERROR_RFMON_NOTSUP; 3097214518Srpaulo } 3098214518Srpaulo 3099214518Srpaulo /* 3100214518Srpaulo * It uses cooked mode. 3101214518Srpaulo */ 3102190225Srpaulo handle->md.cooked = 1; 3103190225Srpaulo handle->linktype = DLT_LINUX_SLL; 310475107Sfenner 3105127664Sbms /* 3106190225Srpaulo * We're not bound to a device. 3107190225Srpaulo * For now, we're using this as an indication 3108190225Srpaulo * that we can't transmit; stop doing that only 3109190225Srpaulo * if we figure out how to transmit in cooked 3110190225Srpaulo * mode. 311175107Sfenner */ 3112190225Srpaulo handle->md.ifindex = -1; 3113190225Srpaulo } 311475107Sfenner 3115190225Srpaulo /* 3116190225Srpaulo * Select promiscuous mode on if "promisc" is set. 3117190225Srpaulo * 3118190225Srpaulo * Do not turn allmulti mode on if we don't select 3119190225Srpaulo * promiscuous mode - on some devices (e.g., Orinoco 3120190225Srpaulo * wireless interfaces), allmulti mode isn't supported 3121190225Srpaulo * and the driver implements it by turning promiscuous 3122190225Srpaulo * mode on, and that screws up the operation of the 3123190225Srpaulo * card as a normal networking interface, and on no 3124190225Srpaulo * other platform I know of does starting a non- 3125190225Srpaulo * promiscuous capture affect which multicast packets 3126190225Srpaulo * are received by the interface. 3127190225Srpaulo */ 312839291Sfenner 3129190225Srpaulo /* 3130190225Srpaulo * Hmm, how can we set promiscuous mode on all interfaces? 3131214518Srpaulo * I am not sure if that is possible at all. For now, we 3132214518Srpaulo * silently ignore attempts to turn promiscuous mode on 3133214518Srpaulo * for the "any" device (so you don't have to explicitly 3134214518Srpaulo * disable it in programs such as tcpdump). 3135190225Srpaulo */ 313675107Sfenner 3137214518Srpaulo if (!is_any_device && handle->opt.promisc) { 3138190225Srpaulo memset(&mr, 0, sizeof(mr)); 3139190225Srpaulo mr.mr_ifindex = handle->md.ifindex; 3140190225Srpaulo mr.mr_type = PACKET_MR_PROMISC; 3141190225Srpaulo if (setsockopt(sock_fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, 3142190225Srpaulo &mr, sizeof(mr)) == -1) { 3143190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3144190225Srpaulo "setsockopt: %s", pcap_strerror(errno)); 3145190225Srpaulo close(sock_fd); 3146190225Srpaulo return PCAP_ERROR; 3147190225Srpaulo } 3148190225Srpaulo } 314975107Sfenner 3150190225Srpaulo /* Enable auxillary data if supported and reserve room for 3151190225Srpaulo * reconstructing VLAN headers. */ 3152190225Srpaulo#ifdef HAVE_PACKET_AUXDATA 3153190225Srpaulo val = 1; 3154190225Srpaulo if (setsockopt(sock_fd, SOL_PACKET, PACKET_AUXDATA, &val, 3155190225Srpaulo sizeof(val)) == -1 && errno != ENOPROTOOPT) { 3156190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3157190225Srpaulo "setsockopt: %s", pcap_strerror(errno)); 3158190225Srpaulo close(sock_fd); 3159190225Srpaulo return PCAP_ERROR; 3160190225Srpaulo } 3161190225Srpaulo handle->offset += VLAN_TAG_LEN; 3162190225Srpaulo#endif /* HAVE_PACKET_AUXDATA */ 316375107Sfenner 3164190225Srpaulo /* 3165190225Srpaulo * This is a 2.2[.x] or later kernel (we know that 3166190225Srpaulo * because we're not using a SOCK_PACKET socket - 3167190225Srpaulo * PF_PACKET is supported only in 2.2 and later 3168190225Srpaulo * kernels). 3169190225Srpaulo * 3170190225Srpaulo * We can safely pass "recvfrom()" a byte count 3171190225Srpaulo * based on the snapshot length. 3172190225Srpaulo * 3173190225Srpaulo * If we're in cooked mode, make the snapshot length 3174190225Srpaulo * large enough to hold a "cooked mode" header plus 3175190225Srpaulo * 1 byte of packet data (so we don't pass a byte 3176190225Srpaulo * count of 0 to "recvfrom()"). 3177190225Srpaulo */ 3178190225Srpaulo if (handle->md.cooked) { 3179190225Srpaulo if (handle->snapshot < SLL_HDR_LEN + 1) 3180190225Srpaulo handle->snapshot = SLL_HDR_LEN + 1; 3181190225Srpaulo } 3182190225Srpaulo handle->bufsize = handle->snapshot; 318375107Sfenner 3184190225Srpaulo /* Save the socket FD in the pcap structure */ 3185190225Srpaulo handle->fd = sock_fd; 3186127664Sbms 3187190225Srpaulo return 1; 318875107Sfenner#else 3189127664Sbms strncpy(ebuf, 3190127664Sbms "New packet capturing interface not supported by build " 319175107Sfenner "environment", PCAP_ERRBUF_SIZE); 319275107Sfenner return 0; 319339291Sfenner#endif 319475107Sfenner} 319539291Sfenner 3196236167Sdelphij#ifdef HAVE_PACKET_RING 3197236167Sdelphij/* 3198236167Sdelphij * Attempt to activate with memory-mapped access. 3199236167Sdelphij * 3200236167Sdelphij * On success, returns 1, and sets *status to 0 if there are no warnings 3201236167Sdelphij * or to a PCAP_WARNING_ code if there is a warning. 3202236167Sdelphij * 3203236167Sdelphij * On failure due to lack of support for memory-mapped capture, returns 3204236167Sdelphij * 0. 3205236167Sdelphij * 3206236167Sdelphij * On error, returns -1, and sets *status to the appropriate error code; 3207236167Sdelphij * if that is PCAP_ERROR, sets handle->errbuf to the appropriate message. 3208236167Sdelphij */ 3209190225Srpaulostatic int 3210236167Sdelphijactivate_mmap(pcap_t *handle, int *status) 3211190225Srpaulo{ 3212190225Srpaulo int ret; 3213190225Srpaulo 3214214518Srpaulo /* 3215214518Srpaulo * Attempt to allocate a buffer to hold the contents of one 3216214518Srpaulo * packet, for use by the oneshot callback. 3217214518Srpaulo */ 3218214518Srpaulo handle->md.oneshot_buffer = malloc(handle->snapshot); 3219214518Srpaulo if (handle->md.oneshot_buffer == NULL) { 3220214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3221214518Srpaulo "can't allocate oneshot buffer: %s", 3222214518Srpaulo pcap_strerror(errno)); 3223236167Sdelphij *status = PCAP_ERROR; 3224236167Sdelphij return -1; 3225214518Srpaulo } 3226214518Srpaulo 3227190225Srpaulo if (handle->opt.buffer_size == 0) { 3228190225Srpaulo /* by default request 2M for the ring buffer */ 3229190225Srpaulo handle->opt.buffer_size = 2*1024*1024; 3230190225Srpaulo } 3231190225Srpaulo ret = prepare_tpacket_socket(handle); 3232236167Sdelphij if (ret == -1) { 3233214518Srpaulo free(handle->md.oneshot_buffer); 3234236167Sdelphij *status = PCAP_ERROR; 3235190225Srpaulo return ret; 3236214518Srpaulo } 3237236167Sdelphij ret = create_ring(handle, status); 3238236167Sdelphij if (ret == 0) { 3239236167Sdelphij /* 3240236167Sdelphij * We don't support memory-mapped capture; our caller 3241236167Sdelphij * will fall back on reading from the socket. 3242236167Sdelphij */ 3243214518Srpaulo free(handle->md.oneshot_buffer); 3244236167Sdelphij return 0; 3245214518Srpaulo } 3246236167Sdelphij if (ret == -1) { 3247236167Sdelphij /* 3248236167Sdelphij * Error attempting to enable memory-mapped capture; 3249236167Sdelphij * fail. create_ring() has set *status. 3250236167Sdelphij */ 3251236167Sdelphij free(handle->md.oneshot_buffer); 3252236167Sdelphij return -1; 3253236167Sdelphij } 3254190225Srpaulo 3255236167Sdelphij /* 3256236167Sdelphij * Success. *status has been set either to 0 if there are no 3257236167Sdelphij * warnings or to a PCAP_WARNING_ value if there is a warning. 3258236167Sdelphij * 3259236167Sdelphij * Override some defaults and inherit the other fields from 3260236167Sdelphij * activate_new. 3261236167Sdelphij * handle->offset is used to get the current position into the rx ring. 3262236167Sdelphij * handle->cc is used to store the ring size. 3263236167Sdelphij */ 3264190225Srpaulo handle->read_op = pcap_read_linux_mmap; 3265190225Srpaulo handle->cleanup_op = pcap_cleanup_linux_mmap; 3266190225Srpaulo handle->setfilter_op = pcap_setfilter_linux_mmap; 3267190225Srpaulo handle->setnonblock_op = pcap_setnonblock_mmap; 3268190225Srpaulo handle->getnonblock_op = pcap_getnonblock_mmap; 3269214518Srpaulo handle->oneshot_callback = pcap_oneshot_mmap; 3270190225Srpaulo handle->selectable_fd = handle->fd; 3271190225Srpaulo return 1; 3272236167Sdelphij} 3273190225Srpaulo#else /* HAVE_PACKET_RING */ 3274236167Sdelphijstatic int 3275236167Sdelphijactivate_mmap(pcap_t *handle _U_, int *status _U_) 3276236167Sdelphij{ 3277190225Srpaulo return 0; 3278236167Sdelphij} 3279190225Srpaulo#endif /* HAVE_PACKET_RING */ 3280190225Srpaulo 3281190225Srpaulo#ifdef HAVE_PACKET_RING 3282236167Sdelphij/* 3283236167Sdelphij * Attempt to set the socket to version 2 of the memory-mapped header. 3284236167Sdelphij * Return 1 if we succeed or if we fail because version 2 isn't 3285236167Sdelphij * supported; return -1 on any other error, and set handle->errbuf. 3286236167Sdelphij */ 3287190225Srpaulostatic int 3288190225Srpauloprepare_tpacket_socket(pcap_t *handle) 3289190225Srpaulo{ 3290190225Srpaulo#ifdef HAVE_TPACKET2 3291190225Srpaulo socklen_t len; 3292190225Srpaulo int val; 3293190225Srpaulo#endif 3294190225Srpaulo 3295190225Srpaulo handle->md.tp_version = TPACKET_V1; 3296190225Srpaulo handle->md.tp_hdrlen = sizeof(struct tpacket_hdr); 3297190225Srpaulo 3298190225Srpaulo#ifdef HAVE_TPACKET2 3299190225Srpaulo /* Probe whether kernel supports TPACKET_V2 */ 3300190225Srpaulo val = TPACKET_V2; 3301190225Srpaulo len = sizeof(val); 3302190225Srpaulo if (getsockopt(handle->fd, SOL_PACKET, PACKET_HDRLEN, &val, &len) < 0) { 3303190225Srpaulo if (errno == ENOPROTOOPT) 3304214518Srpaulo return 1; /* no - just drive on */ 3305214518Srpaulo 3306214518Srpaulo /* Yes - treat as a failure. */ 3307190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3308214518Srpaulo "can't get TPACKET_V2 header len on packet socket: %s", 3309214518Srpaulo pcap_strerror(errno)); 3310214518Srpaulo return -1; 3311190225Srpaulo } 3312190225Srpaulo handle->md.tp_hdrlen = val; 3313190225Srpaulo 3314190225Srpaulo val = TPACKET_V2; 3315190225Srpaulo if (setsockopt(handle->fd, SOL_PACKET, PACKET_VERSION, &val, 3316190225Srpaulo sizeof(val)) < 0) { 3317190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3318214518Srpaulo "can't activate TPACKET_V2 on packet socket: %s", 3319214518Srpaulo pcap_strerror(errno)); 3320214518Srpaulo return -1; 3321190225Srpaulo } 3322190225Srpaulo handle->md.tp_version = TPACKET_V2; 3323190225Srpaulo 3324190225Srpaulo /* Reserve space for VLAN tag reconstruction */ 3325190225Srpaulo val = VLAN_TAG_LEN; 3326190225Srpaulo if (setsockopt(handle->fd, SOL_PACKET, PACKET_RESERVE, &val, 3327190225Srpaulo sizeof(val)) < 0) { 3328190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3329214518Srpaulo "can't set up reserve on packet socket: %s", 3330214518Srpaulo pcap_strerror(errno)); 3331214518Srpaulo return -1; 3332190225Srpaulo } 3333190225Srpaulo 3334190225Srpaulo#endif /* HAVE_TPACKET2 */ 3335190225Srpaulo return 1; 3336190225Srpaulo} 3337190225Srpaulo 3338236167Sdelphij/* 3339236167Sdelphij * Attempt to set up memory-mapped access. 3340236167Sdelphij * 3341236167Sdelphij * On success, returns 1, and sets *status to 0 if there are no warnings 3342236167Sdelphij * or to a PCAP_WARNING_ code if there is a warning. 3343236167Sdelphij * 3344236167Sdelphij * On failure due to lack of support for memory-mapped capture, returns 3345236167Sdelphij * 0. 3346236167Sdelphij * 3347236167Sdelphij * On error, returns -1, and sets *status to the appropriate error code; 3348236167Sdelphij * if that is PCAP_ERROR, sets handle->errbuf to the appropriate message. 3349236167Sdelphij */ 3350190225Srpaulostatic int 3351236167Sdelphijcreate_ring(pcap_t *handle, int *status) 3352190225Srpaulo{ 3353214518Srpaulo unsigned i, j, frames_per_block; 3354190225Srpaulo struct tpacket_req req; 3355236167Sdelphij socklen_t len; 3356236167Sdelphij unsigned int sk_type, tp_reserve, maclen, tp_hdrlen, netoff, macoff; 3357236167Sdelphij unsigned int frame_size; 3358190225Srpaulo 3359236167Sdelphij /* 3360236167Sdelphij * Start out assuming no warnings or errors. 3361236167Sdelphij */ 3362236167Sdelphij *status = 0; 3363236167Sdelphij 3364236167Sdelphij /* Note that with large snapshot length (say 64K, which is the default 3365236167Sdelphij * for recent versions of tcpdump, the value that "-s 0" has given 3366236167Sdelphij * for a long time with tcpdump, and the default in Wireshark/TShark), 3367236167Sdelphij * if we use the snapshot length to calculate the frame length, 3368236167Sdelphij * only a few frames will be available in the ring even with pretty 3369236167Sdelphij * large ring size (and a lot of memory will be unused). 3370236167Sdelphij * 3371236167Sdelphij * Ideally, we should choose a frame length based on the 3372236167Sdelphij * minimum of the specified snapshot length and the maximum 3373236167Sdelphij * packet size. That's not as easy as it sounds; consider, for 3374236167Sdelphij * example, an 802.11 interface in monitor mode, where the 3375236167Sdelphij * frame would include a radiotap header, where the maximum 3376236167Sdelphij * radiotap header length is device-dependent. 3377236167Sdelphij * 3378236167Sdelphij * So, for now, we just do this for Ethernet devices, where 3379236167Sdelphij * there's no metadata header, and the link-layer header is 3380236167Sdelphij * fixed length. We can get the maximum packet size by 3381236167Sdelphij * adding 18, the Ethernet header length plus the CRC length 3382236167Sdelphij * (just in case we happen to get the CRC in the packet), to 3383236167Sdelphij * the MTU of the interface; we fetch the MTU in the hopes 3384236167Sdelphij * that it reflects support for jumbo frames. (Even if the 3385236167Sdelphij * interface is just being used for passive snooping, the driver 3386236167Sdelphij * might set the size of buffers in the receive ring based on 3387236167Sdelphij * the MTU, so that the MTU limits the maximum size of packets 3388236167Sdelphij * that we can receive.) 3389236167Sdelphij * 3390236167Sdelphij * We don't do that if segmentation/fragmentation or receive 3391236167Sdelphij * offload are enabled, so we don't get rudely surprised by 3392236167Sdelphij * "packets" bigger than the MTU. */ 3393236167Sdelphij frame_size = handle->snapshot; 3394236167Sdelphij if (handle->linktype == DLT_EN10MB) { 3395236167Sdelphij int mtu; 3396236167Sdelphij int offload; 3397236167Sdelphij 3398236167Sdelphij offload = iface_get_offload(handle); 3399236167Sdelphij if (offload == -1) { 3400236167Sdelphij *status = PCAP_ERROR; 3401236167Sdelphij return -1; 3402236167Sdelphij } 3403236167Sdelphij if (!offload) { 3404236167Sdelphij mtu = iface_get_mtu(handle->fd, handle->opt.source, 3405236167Sdelphij handle->errbuf); 3406236167Sdelphij if (mtu == -1) { 3407236167Sdelphij *status = PCAP_ERROR; 3408236167Sdelphij return -1; 3409236167Sdelphij } 3410236167Sdelphij if (frame_size > mtu + 18) 3411236167Sdelphij frame_size = mtu + 18; 3412236167Sdelphij } 3413236167Sdelphij } 3414236167Sdelphij 3415236167Sdelphij /* NOTE: calculus matching those in tpacket_rcv() 3416236167Sdelphij * in linux-2.6/net/packet/af_packet.c 3417236167Sdelphij */ 3418236167Sdelphij len = sizeof(sk_type); 3419236167Sdelphij if (getsockopt(handle->fd, SOL_SOCKET, SO_TYPE, &sk_type, &len) < 0) { 3420236167Sdelphij snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "getsockopt: %s", pcap_strerror(errno)); 3421236167Sdelphij *status = PCAP_ERROR; 3422236167Sdelphij return -1; 3423236167Sdelphij } 3424236167Sdelphij#ifdef PACKET_RESERVE 3425236167Sdelphij len = sizeof(tp_reserve); 3426236167Sdelphij if (getsockopt(handle->fd, SOL_PACKET, PACKET_RESERVE, &tp_reserve, &len) < 0) { 3427236167Sdelphij if (errno != ENOPROTOOPT) { 3428236167Sdelphij /* 3429236167Sdelphij * ENOPROTOOPT means "kernel doesn't support 3430236167Sdelphij * PACKET_RESERVE", in which case we fall back 3431236167Sdelphij * as best we can. 3432236167Sdelphij */ 3433236167Sdelphij snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "getsockopt: %s", pcap_strerror(errno)); 3434236167Sdelphij *status = PCAP_ERROR; 3435236167Sdelphij return -1; 3436236167Sdelphij } 3437236167Sdelphij tp_reserve = 0; /* older kernel, reserve not supported */ 3438236167Sdelphij } 3439236167Sdelphij#else 3440236167Sdelphij tp_reserve = 0; /* older kernel, reserve not supported */ 3441236167Sdelphij#endif 3442236167Sdelphij maclen = (sk_type == SOCK_DGRAM) ? 0 : MAX_LINKHEADER_SIZE; 3443236167Sdelphij /* XXX: in the kernel maclen is calculated from 3444236167Sdelphij * LL_ALLOCATED_SPACE(dev) and vnet_hdr.hdr_len 3445236167Sdelphij * in: packet_snd() in linux-2.6/net/packet/af_packet.c 3446236167Sdelphij * then packet_alloc_skb() in linux-2.6/net/packet/af_packet.c 3447236167Sdelphij * then sock_alloc_send_pskb() in linux-2.6/net/core/sock.c 3448236167Sdelphij * but I see no way to get those sizes in userspace, 3449236167Sdelphij * like for instance with an ifreq ioctl(); 3450236167Sdelphij * the best thing I've found so far is MAX_HEADER in the kernel 3451236167Sdelphij * part of linux-2.6/include/linux/netdevice.h 3452236167Sdelphij * which goes up to 128+48=176; since pcap-linux.c defines 3453236167Sdelphij * a MAX_LINKHEADER_SIZE of 256 which is greater than that, 3454236167Sdelphij * let's use it.. maybe is it even large enough to directly 3455236167Sdelphij * replace macoff.. 3456236167Sdelphij */ 3457236167Sdelphij tp_hdrlen = TPACKET_ALIGN(handle->md.tp_hdrlen) + sizeof(struct sockaddr_ll) ; 3458236167Sdelphij netoff = TPACKET_ALIGN(tp_hdrlen + (maclen < 16 ? 16 : maclen)) + tp_reserve; 3459236167Sdelphij /* NOTE: AFAICS tp_reserve may break the TPACKET_ALIGN of 3460236167Sdelphij * netoff, which contradicts 3461236167Sdelphij * linux-2.6/Documentation/networking/packet_mmap.txt 3462236167Sdelphij * documenting that: 3463236167Sdelphij * "- Gap, chosen so that packet data (Start+tp_net) 3464236167Sdelphij * aligns to TPACKET_ALIGNMENT=16" 3465236167Sdelphij */ 3466236167Sdelphij /* NOTE: in linux-2.6/include/linux/skbuff.h: 3467236167Sdelphij * "CPUs often take a performance hit 3468236167Sdelphij * when accessing unaligned memory locations" 3469236167Sdelphij */ 3470236167Sdelphij macoff = netoff - maclen; 3471236167Sdelphij req.tp_frame_size = TPACKET_ALIGN(macoff + frame_size); 3472190225Srpaulo req.tp_frame_nr = handle->opt.buffer_size/req.tp_frame_size; 3473214518Srpaulo 3474214518Srpaulo /* compute the minumum block size that will handle this frame. 3475214518Srpaulo * The block has to be page size aligned. 3476214518Srpaulo * The max block size allowed by the kernel is arch-dependent and 3477214518Srpaulo * it's not explicitly checked here. */ 3478214518Srpaulo req.tp_block_size = getpagesize(); 3479214518Srpaulo while (req.tp_block_size < req.tp_frame_size) 3480214518Srpaulo req.tp_block_size <<= 1; 3481214518Srpaulo 3482214518Srpaulo frames_per_block = req.tp_block_size/req.tp_frame_size; 3483214518Srpaulo 3484236167Sdelphij /* 3485236167Sdelphij * PACKET_TIMESTAMP was added after linux/net_tstamp.h was, 3486236167Sdelphij * so we check for PACKET_TIMESTAMP. We check for 3487236167Sdelphij * linux/net_tstamp.h just in case a system somehow has 3488236167Sdelphij * PACKET_TIMESTAMP but not linux/net_tstamp.h; that might 3489236167Sdelphij * be unnecessary. 3490236167Sdelphij * 3491236167Sdelphij * SIOCSHWTSTAMP was introduced in the patch that introduced 3492236167Sdelphij * linux/net_tstamp.h, so we don't bother checking whether 3493236167Sdelphij * SIOCSHWTSTAMP is defined (if your Linux system has 3494236167Sdelphij * linux/net_tstamp.h but doesn't define SIOCSHWTSTAMP, your 3495236167Sdelphij * Linux system is badly broken). 3496236167Sdelphij */ 3497236167Sdelphij#if defined(HAVE_LINUX_NET_TSTAMP_H) && defined(PACKET_TIMESTAMP) 3498236167Sdelphij /* 3499236167Sdelphij * If we were told to do so, ask the kernel and the driver 3500236167Sdelphij * to use hardware timestamps. 3501236167Sdelphij * 3502236167Sdelphij * Hardware timestamps are only supported with mmapped 3503236167Sdelphij * captures. 3504236167Sdelphij */ 3505236167Sdelphij if (handle->opt.tstamp_type == PCAP_TSTAMP_ADAPTER || 3506236167Sdelphij handle->opt.tstamp_type == PCAP_TSTAMP_ADAPTER_UNSYNCED) { 3507236167Sdelphij struct hwtstamp_config hwconfig; 3508236167Sdelphij struct ifreq ifr; 3509236167Sdelphij int timesource; 3510236167Sdelphij 3511236167Sdelphij /* 3512236167Sdelphij * Ask for hardware time stamps on all packets, 3513236167Sdelphij * including transmitted packets. 3514236167Sdelphij */ 3515236167Sdelphij memset(&hwconfig, 0, sizeof(hwconfig)); 3516236167Sdelphij hwconfig.tx_type = HWTSTAMP_TX_ON; 3517236167Sdelphij hwconfig.rx_filter = HWTSTAMP_FILTER_ALL; 3518236167Sdelphij 3519236167Sdelphij memset(&ifr, 0, sizeof(ifr)); 3520236167Sdelphij strcpy(ifr.ifr_name, handle->opt.source); 3521236167Sdelphij ifr.ifr_data = (void *)&hwconfig; 3522236167Sdelphij 3523236167Sdelphij if (ioctl(handle->fd, SIOCSHWTSTAMP, &ifr) < 0) { 3524236167Sdelphij switch (errno) { 3525236167Sdelphij 3526236167Sdelphij case EPERM: 3527236167Sdelphij /* 3528236167Sdelphij * Treat this as an error, as the 3529236167Sdelphij * user should try to run this 3530236167Sdelphij * with the appropriate privileges - 3531236167Sdelphij * and, if they can't, shouldn't 3532236167Sdelphij * try requesting hardware time stamps. 3533236167Sdelphij */ 3534236167Sdelphij *status = PCAP_ERROR_PERM_DENIED; 3535236167Sdelphij return -1; 3536236167Sdelphij 3537236167Sdelphij case EOPNOTSUPP: 3538236167Sdelphij /* 3539236167Sdelphij * Treat this as a warning, as the 3540236167Sdelphij * only way to fix the warning is to 3541236167Sdelphij * get an adapter that supports hardware 3542236167Sdelphij * time stamps. We'll just fall back 3543236167Sdelphij * on the standard host time stamps. 3544236167Sdelphij */ 3545236167Sdelphij *status = PCAP_WARNING_TSTAMP_TYPE_NOTSUP; 3546236167Sdelphij break; 3547236167Sdelphij 3548236167Sdelphij default: 3549236167Sdelphij snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3550236167Sdelphij "SIOCSHWTSTAMP failed: %s", 3551236167Sdelphij pcap_strerror(errno)); 3552236167Sdelphij *status = PCAP_ERROR; 3553236167Sdelphij return -1; 3554236167Sdelphij } 3555236167Sdelphij } else { 3556236167Sdelphij /* 3557236167Sdelphij * Well, that worked. Now specify the type of 3558236167Sdelphij * hardware time stamp we want for this 3559236167Sdelphij * socket. 3560236167Sdelphij */ 3561236167Sdelphij if (handle->opt.tstamp_type == PCAP_TSTAMP_ADAPTER) { 3562236167Sdelphij /* 3563236167Sdelphij * Hardware timestamp, synchronized 3564236167Sdelphij * with the system clock. 3565236167Sdelphij */ 3566236167Sdelphij timesource = SOF_TIMESTAMPING_SYS_HARDWARE; 3567236167Sdelphij } else { 3568236167Sdelphij /* 3569236167Sdelphij * PCAP_TSTAMP_ADAPTER_UNSYNCED - hardware 3570236167Sdelphij * timestamp, not synchronized with the 3571236167Sdelphij * system clock. 3572236167Sdelphij */ 3573236167Sdelphij timesource = SOF_TIMESTAMPING_RAW_HARDWARE; 3574236167Sdelphij } 3575236167Sdelphij if (setsockopt(handle->fd, SOL_PACKET, PACKET_TIMESTAMP, 3576236167Sdelphij (void *)×ource, sizeof(timesource))) { 3577236167Sdelphij snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3578236167Sdelphij "can't set PACKET_TIMESTAMP: %s", 3579236167Sdelphij pcap_strerror(errno)); 3580236167Sdelphij *status = PCAP_ERROR; 3581236167Sdelphij return -1; 3582236167Sdelphij } 3583236167Sdelphij } 3584236167Sdelphij } 3585236167Sdelphij#endif /* HAVE_LINUX_NET_TSTAMP_H && PACKET_TIMESTAMP */ 3586236167Sdelphij 3587214518Srpaulo /* ask the kernel to create the ring */ 3588214518Srpauloretry: 3589190225Srpaulo req.tp_block_nr = req.tp_frame_nr / frames_per_block; 3590190225Srpaulo 3591190225Srpaulo /* req.tp_frame_nr is requested to match frames_per_block*req.tp_block_nr */ 3592190225Srpaulo req.tp_frame_nr = req.tp_block_nr * frames_per_block; 3593214518Srpaulo 3594190225Srpaulo if (setsockopt(handle->fd, SOL_PACKET, PACKET_RX_RING, 3595190225Srpaulo (void *) &req, sizeof(req))) { 3596190225Srpaulo if ((errno == ENOMEM) && (req.tp_block_nr > 1)) { 3597214518Srpaulo /* 3598214518Srpaulo * Memory failure; try to reduce the requested ring 3599214518Srpaulo * size. 3600214518Srpaulo * 3601214518Srpaulo * We used to reduce this by half -- do 5% instead. 3602214518Srpaulo * That may result in more iterations and a longer 3603214518Srpaulo * startup, but the user will be much happier with 3604214518Srpaulo * the resulting buffer size. 3605214518Srpaulo */ 3606214518Srpaulo if (req.tp_frame_nr < 20) 3607214518Srpaulo req.tp_frame_nr -= 1; 3608214518Srpaulo else 3609214518Srpaulo req.tp_frame_nr -= req.tp_frame_nr/20; 3610190225Srpaulo goto retry; 3611190225Srpaulo } 3612214518Srpaulo if (errno == ENOPROTOOPT) { 3613214518Srpaulo /* 3614214518Srpaulo * We don't have ring buffer support in this kernel. 3615214518Srpaulo */ 3616214518Srpaulo return 0; 3617214518Srpaulo } 3618214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3619214518Srpaulo "can't create rx ring on packet socket: %s", 3620214518Srpaulo pcap_strerror(errno)); 3621236167Sdelphij *status = PCAP_ERROR; 3622214518Srpaulo return -1; 3623190225Srpaulo } 3624190225Srpaulo 3625190225Srpaulo /* memory map the rx ring */ 3626214518Srpaulo handle->md.mmapbuflen = req.tp_block_nr * req.tp_block_size; 3627214518Srpaulo handle->md.mmapbuf = mmap(0, handle->md.mmapbuflen, 3628214518Srpaulo PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); 3629214518Srpaulo if (handle->md.mmapbuf == MAP_FAILED) { 3630214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3631214518Srpaulo "can't mmap rx ring: %s", pcap_strerror(errno)); 3632190225Srpaulo 3633190225Srpaulo /* clear the allocated ring on error*/ 3634190225Srpaulo destroy_ring(handle); 3635236167Sdelphij *status = PCAP_ERROR; 3636214518Srpaulo return -1; 3637190225Srpaulo } 3638190225Srpaulo 3639190225Srpaulo /* allocate a ring for each frame header pointer*/ 3640190225Srpaulo handle->cc = req.tp_frame_nr; 3641190225Srpaulo handle->buffer = malloc(handle->cc * sizeof(union thdr *)); 3642190225Srpaulo if (!handle->buffer) { 3643214518Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3644214518Srpaulo "can't allocate ring of frame headers: %s", 3645214518Srpaulo pcap_strerror(errno)); 3646214518Srpaulo 3647190225Srpaulo destroy_ring(handle); 3648236167Sdelphij *status = PCAP_ERROR; 3649214518Srpaulo return -1; 3650190225Srpaulo } 3651190225Srpaulo 3652190225Srpaulo /* fill the header ring with proper frame ptr*/ 3653190225Srpaulo handle->offset = 0; 3654190225Srpaulo for (i=0; i<req.tp_block_nr; ++i) { 3655214518Srpaulo void *base = &handle->md.mmapbuf[i*req.tp_block_size]; 3656190225Srpaulo for (j=0; j<frames_per_block; ++j, ++handle->offset) { 3657190225Srpaulo RING_GET_FRAME(handle) = base; 3658190225Srpaulo base += req.tp_frame_size; 3659190225Srpaulo } 3660190225Srpaulo } 3661190225Srpaulo 3662190225Srpaulo handle->bufsize = req.tp_frame_size; 3663190225Srpaulo handle->offset = 0; 3664190225Srpaulo return 1; 3665190225Srpaulo} 3666190225Srpaulo 3667190225Srpaulo/* free all ring related resources*/ 3668190225Srpaulostatic void 3669190225Srpaulodestroy_ring(pcap_t *handle) 3670190225Srpaulo{ 3671190225Srpaulo /* tell the kernel to destroy the ring*/ 3672190225Srpaulo struct tpacket_req req; 3673190225Srpaulo memset(&req, 0, sizeof(req)); 3674190225Srpaulo setsockopt(handle->fd, SOL_PACKET, PACKET_RX_RING, 3675190225Srpaulo (void *) &req, sizeof(req)); 3676190225Srpaulo 3677190225Srpaulo /* if ring is mapped, unmap it*/ 3678214518Srpaulo if (handle->md.mmapbuf) { 3679214518Srpaulo /* do not test for mmap failure, as we can't recover from any error */ 3680214518Srpaulo munmap(handle->md.mmapbuf, handle->md.mmapbuflen); 3681214518Srpaulo handle->md.mmapbuf = NULL; 3682190225Srpaulo } 3683190225Srpaulo} 3684190225Srpaulo 3685214518Srpaulo/* 3686214518Srpaulo * Special one-shot callback, used for pcap_next() and pcap_next_ex(), 3687214518Srpaulo * for Linux mmapped capture. 3688214518Srpaulo * 3689214518Srpaulo * The problem is that pcap_next() and pcap_next_ex() expect the packet 3690214518Srpaulo * data handed to the callback to be valid after the callback returns, 3691214518Srpaulo * but pcap_read_linux_mmap() has to release that packet as soon as 3692214518Srpaulo * the callback returns (otherwise, the kernel thinks there's still 3693214518Srpaulo * at least one unprocessed packet available in the ring, so a select() 3694214518Srpaulo * will immediately return indicating that there's data to process), so, 3695214518Srpaulo * in the callback, we have to make a copy of the packet. 3696214518Srpaulo * 3697214518Srpaulo * Yes, this means that, if the capture is using the ring buffer, using 3698214518Srpaulo * pcap_next() or pcap_next_ex() requires more copies than using 3699214518Srpaulo * pcap_loop() or pcap_dispatch(). If that bothers you, don't use 3700214518Srpaulo * pcap_next() or pcap_next_ex(). 3701214518Srpaulo */ 3702190225Srpaulostatic void 3703214518Srpaulopcap_oneshot_mmap(u_char *user, const struct pcap_pkthdr *h, 3704214518Srpaulo const u_char *bytes) 3705214518Srpaulo{ 3706214518Srpaulo struct oneshot_userdata *sp = (struct oneshot_userdata *)user; 3707214518Srpaulo 3708214518Srpaulo *sp->hdr = *h; 3709214518Srpaulo memcpy(sp->pd->md.oneshot_buffer, bytes, h->caplen); 3710214518Srpaulo *sp->pkt = sp->pd->md.oneshot_buffer; 3711214518Srpaulo} 3712214518Srpaulo 3713214518Srpaulostatic void 3714190225Srpaulopcap_cleanup_linux_mmap( pcap_t *handle ) 3715190225Srpaulo{ 3716190225Srpaulo destroy_ring(handle); 3717214518Srpaulo if (handle->md.oneshot_buffer != NULL) { 3718214518Srpaulo free(handle->md.oneshot_buffer); 3719214518Srpaulo handle->md.oneshot_buffer = NULL; 3720214518Srpaulo } 3721190225Srpaulo pcap_cleanup_linux(handle); 3722190225Srpaulo} 3723190225Srpaulo 3724190225Srpaulo 3725190225Srpaulostatic int 3726190225Srpaulopcap_getnonblock_mmap(pcap_t *p, char *errbuf) 3727190225Srpaulo{ 3728190225Srpaulo /* use negative value of timeout to indicate non blocking ops */ 3729190225Srpaulo return (p->md.timeout<0); 3730190225Srpaulo} 3731190225Srpaulo 3732190225Srpaulostatic int 3733190225Srpaulopcap_setnonblock_mmap(pcap_t *p, int nonblock, char *errbuf) 3734190225Srpaulo{ 3735190225Srpaulo /* map each value to the corresponding 2's complement, to 3736190225Srpaulo * preserve the timeout value provided with pcap_set_timeout */ 3737190225Srpaulo if (nonblock) { 3738214518Srpaulo if (p->md.timeout >= 0) { 3739214518Srpaulo /* 3740214518Srpaulo * Timeout is non-negative, so we're not already 3741214518Srpaulo * in non-blocking mode; set it to the 2's 3742214518Srpaulo * complement, to make it negative, as an 3743214518Srpaulo * indication that we're in non-blocking mode. 3744214518Srpaulo */ 3745190225Srpaulo p->md.timeout = p->md.timeout*-1 - 1; 3746214518Srpaulo } 3747214518Srpaulo } else { 3748214518Srpaulo if (p->md.timeout < 0) { 3749214518Srpaulo /* 3750214518Srpaulo * Timeout is negative, so we're not already 3751214518Srpaulo * in blocking mode; reverse the previous 3752214518Srpaulo * operation, to make the timeout non-negative 3753214518Srpaulo * again. 3754214518Srpaulo */ 3755190225Srpaulo p->md.timeout = (p->md.timeout+1)*-1; 3756214518Srpaulo } 3757214518Srpaulo } 3758190225Srpaulo return 0; 3759190225Srpaulo} 3760190225Srpaulo 3761190225Srpaulostatic inline union thdr * 3762190225Srpaulopcap_get_ring_frame(pcap_t *handle, int status) 3763190225Srpaulo{ 3764190225Srpaulo union thdr h; 3765190225Srpaulo 3766190225Srpaulo h.raw = RING_GET_FRAME(handle); 3767190225Srpaulo switch (handle->md.tp_version) { 3768190225Srpaulo case TPACKET_V1: 3769190225Srpaulo if (status != (h.h1->tp_status ? TP_STATUS_USER : 3770190225Srpaulo TP_STATUS_KERNEL)) 3771190225Srpaulo return NULL; 3772190225Srpaulo break; 3773190225Srpaulo#ifdef HAVE_TPACKET2 3774190225Srpaulo case TPACKET_V2: 3775190225Srpaulo if (status != (h.h2->tp_status ? TP_STATUS_USER : 3776190225Srpaulo TP_STATUS_KERNEL)) 3777190225Srpaulo return NULL; 3778190225Srpaulo break; 3779190225Srpaulo#endif 3780190225Srpaulo } 3781190225Srpaulo return h.raw; 3782190225Srpaulo} 3783190225Srpaulo 3784214518Srpaulo#ifndef POLLRDHUP 3785214518Srpaulo#define POLLRDHUP 0 3786214518Srpaulo#endif 3787214518Srpaulo 3788190225Srpaulostatic int 3789190225Srpaulopcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, 3790190225Srpaulo u_char *user) 3791190225Srpaulo{ 3792214518Srpaulo int timeout; 3793190225Srpaulo int pkts = 0; 3794214518Srpaulo char c; 3795190225Srpaulo 3796190225Srpaulo /* wait for frames availability.*/ 3797214518Srpaulo if (!pcap_get_ring_frame(handle, TP_STATUS_USER)) { 3798190225Srpaulo struct pollfd pollinfo; 3799190225Srpaulo int ret; 3800190225Srpaulo 3801190225Srpaulo pollinfo.fd = handle->fd; 3802190225Srpaulo pollinfo.events = POLLIN; 3803190225Srpaulo 3804214518Srpaulo if (handle->md.timeout == 0) 3805214518Srpaulo timeout = -1; /* block forever */ 3806214518Srpaulo else if (handle->md.timeout > 0) 3807214518Srpaulo timeout = handle->md.timeout; /* block for that amount of time */ 3808214518Srpaulo else 3809214518Srpaulo timeout = 0; /* non-blocking mode - poll to pick up errors */ 3810190225Srpaulo do { 3811214518Srpaulo ret = poll(&pollinfo, 1, timeout); 3812214518Srpaulo if (ret < 0 && errno != EINTR) { 3813190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3814214518Srpaulo "can't poll on packet socket: %s", 3815214518Srpaulo pcap_strerror(errno)); 3816214518Srpaulo return PCAP_ERROR; 3817214518Srpaulo } else if (ret > 0 && 3818214518Srpaulo (pollinfo.revents & (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL))) { 3819214518Srpaulo /* 3820214518Srpaulo * There's some indication other than 3821214518Srpaulo * "you can read on this descriptor" on 3822214518Srpaulo * the descriptor. 3823214518Srpaulo */ 3824214518Srpaulo if (pollinfo.revents & (POLLHUP | POLLRDHUP)) { 3825214518Srpaulo snprintf(handle->errbuf, 3826214518Srpaulo PCAP_ERRBUF_SIZE, 3827214518Srpaulo "Hangup on packet socket"); 3828214518Srpaulo return PCAP_ERROR; 3829214518Srpaulo } 3830214518Srpaulo if (pollinfo.revents & POLLERR) { 3831214518Srpaulo /* 3832214518Srpaulo * A recv() will give us the 3833214518Srpaulo * actual error code. 3834214518Srpaulo * 3835214518Srpaulo * XXX - make the socket non-blocking? 3836214518Srpaulo */ 3837214518Srpaulo if (recv(handle->fd, &c, sizeof c, 3838214518Srpaulo MSG_PEEK) != -1) 3839214518Srpaulo continue; /* what, no error? */ 3840214518Srpaulo if (errno == ENETDOWN) { 3841214518Srpaulo /* 3842214518Srpaulo * The device on which we're 3843214518Srpaulo * capturing went away. 3844214518Srpaulo * 3845214518Srpaulo * XXX - we should really return 3846214518Srpaulo * PCAP_ERROR_IFACE_NOT_UP, 3847214518Srpaulo * but pcap_dispatch() etc. 3848214518Srpaulo * aren't defined to return 3849214518Srpaulo * that. 3850214518Srpaulo */ 3851214518Srpaulo snprintf(handle->errbuf, 3852214518Srpaulo PCAP_ERRBUF_SIZE, 3853214518Srpaulo "The interface went down"); 3854214518Srpaulo } else { 3855214518Srpaulo snprintf(handle->errbuf, 3856214518Srpaulo PCAP_ERRBUF_SIZE, 3857214518Srpaulo "Error condition on packet socket: %s", 3858214518Srpaulo strerror(errno)); 3859214518Srpaulo } 3860214518Srpaulo return PCAP_ERROR; 3861214518Srpaulo } 3862214518Srpaulo if (pollinfo.revents & POLLNVAL) { 3863214518Srpaulo snprintf(handle->errbuf, 3864214518Srpaulo PCAP_ERRBUF_SIZE, 3865214518Srpaulo "Invalid polling request on packet socket"); 3866214518Srpaulo return PCAP_ERROR; 3867214518Srpaulo } 3868214518Srpaulo } 3869190225Srpaulo /* check for break loop condition on interrupted syscall*/ 3870190225Srpaulo if (handle->break_loop) { 3871190225Srpaulo handle->break_loop = 0; 3872214518Srpaulo return PCAP_ERROR_BREAK; 3873190225Srpaulo } 3874190225Srpaulo } while (ret < 0); 3875190225Srpaulo } 3876190225Srpaulo 3877190225Srpaulo /* non-positive values of max_packets are used to require all 3878190225Srpaulo * packets currently available in the ring */ 3879190225Srpaulo while ((pkts < max_packets) || (max_packets <= 0)) { 3880190225Srpaulo int run_bpf; 3881190225Srpaulo struct sockaddr_ll *sll; 3882190225Srpaulo struct pcap_pkthdr pcaphdr; 3883190225Srpaulo unsigned char *bp; 3884190225Srpaulo union thdr h; 3885190225Srpaulo unsigned int tp_len; 3886190225Srpaulo unsigned int tp_mac; 3887190225Srpaulo unsigned int tp_snaplen; 3888190225Srpaulo unsigned int tp_sec; 3889190225Srpaulo unsigned int tp_usec; 3890190225Srpaulo 3891190225Srpaulo h.raw = pcap_get_ring_frame(handle, TP_STATUS_USER); 3892190225Srpaulo if (!h.raw) 3893190225Srpaulo break; 3894190225Srpaulo 3895190225Srpaulo switch (handle->md.tp_version) { 3896190225Srpaulo case TPACKET_V1: 3897190225Srpaulo tp_len = h.h1->tp_len; 3898190225Srpaulo tp_mac = h.h1->tp_mac; 3899190225Srpaulo tp_snaplen = h.h1->tp_snaplen; 3900190225Srpaulo tp_sec = h.h1->tp_sec; 3901190225Srpaulo tp_usec = h.h1->tp_usec; 3902190225Srpaulo break; 3903190225Srpaulo#ifdef HAVE_TPACKET2 3904190225Srpaulo case TPACKET_V2: 3905190225Srpaulo tp_len = h.h2->tp_len; 3906190225Srpaulo tp_mac = h.h2->tp_mac; 3907190225Srpaulo tp_snaplen = h.h2->tp_snaplen; 3908190225Srpaulo tp_sec = h.h2->tp_sec; 3909190225Srpaulo tp_usec = h.h2->tp_nsec / 1000; 3910190225Srpaulo break; 3911190225Srpaulo#endif 3912190225Srpaulo default: 3913190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3914190225Srpaulo "unsupported tpacket version %d", 3915190225Srpaulo handle->md.tp_version); 3916190225Srpaulo return -1; 3917190225Srpaulo } 3918190225Srpaulo /* perform sanity check on internal offset. */ 3919190225Srpaulo if (tp_mac + tp_snaplen > handle->bufsize) { 3920190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3921190225Srpaulo "corrupted frame on kernel ring mac " 3922190225Srpaulo "offset %d + caplen %d > frame len %d", 3923190225Srpaulo tp_mac, tp_snaplen, handle->bufsize); 3924190225Srpaulo return -1; 3925190225Srpaulo } 3926190225Srpaulo 3927190225Srpaulo /* run filter on received packet 3928190225Srpaulo * If the kernel filtering is enabled we need to run the 3929190225Srpaulo * filter until all the frames present into the ring 3930190225Srpaulo * at filter creation time are processed. 3931190225Srpaulo * In such case md.use_bpf is used as a counter for the 3932190225Srpaulo * packet we need to filter. 3933190225Srpaulo * Note: alternatively it could be possible to stop applying 3934190225Srpaulo * the filter when the ring became empty, but it can possibly 3935190225Srpaulo * happen a lot later... */ 3936190225Srpaulo bp = (unsigned char*)h.raw + tp_mac; 3937190225Srpaulo run_bpf = (!handle->md.use_bpf) || 3938190225Srpaulo ((handle->md.use_bpf>1) && handle->md.use_bpf--); 3939190225Srpaulo if (run_bpf && handle->fcode.bf_insns && 3940190225Srpaulo (bpf_filter(handle->fcode.bf_insns, bp, 3941190225Srpaulo tp_len, tp_snaplen) == 0)) 3942190225Srpaulo goto skip; 3943190225Srpaulo 3944214518Srpaulo /* 3945214518Srpaulo * Do checks based on packet direction. 3946214518Srpaulo */ 3947190225Srpaulo sll = (void *)h.raw + TPACKET_ALIGN(handle->md.tp_hdrlen); 3948214518Srpaulo if (sll->sll_pkttype == PACKET_OUTGOING) { 3949214518Srpaulo /* 3950214518Srpaulo * Outgoing packet. 3951214518Srpaulo * If this is from the loopback device, reject it; 3952214518Srpaulo * we'll see the packet as an incoming packet as well, 3953214518Srpaulo * and we don't want to see it twice. 3954214518Srpaulo */ 3955214518Srpaulo if (sll->sll_ifindex == handle->md.lo_ifindex) 3956214518Srpaulo goto skip; 3957190225Srpaulo 3958214518Srpaulo /* 3959214518Srpaulo * If the user only wants incoming packets, reject it. 3960214518Srpaulo */ 3961214518Srpaulo if (handle->direction == PCAP_D_IN) 3962214518Srpaulo goto skip; 3963214518Srpaulo } else { 3964214518Srpaulo /* 3965214518Srpaulo * Incoming packet. 3966214518Srpaulo * If the user only wants outgoing packets, reject it. 3967214518Srpaulo */ 3968214518Srpaulo if (handle->direction == PCAP_D_OUT) 3969214518Srpaulo goto skip; 3970214518Srpaulo } 3971214518Srpaulo 3972190225Srpaulo /* get required packet info from ring header */ 3973190225Srpaulo pcaphdr.ts.tv_sec = tp_sec; 3974190225Srpaulo pcaphdr.ts.tv_usec = tp_usec; 3975190225Srpaulo pcaphdr.caplen = tp_snaplen; 3976190225Srpaulo pcaphdr.len = tp_len; 3977190225Srpaulo 3978190225Srpaulo /* if required build in place the sll header*/ 3979190225Srpaulo if (handle->md.cooked) { 3980190225Srpaulo struct sll_header *hdrp; 3981190225Srpaulo 3982190225Srpaulo /* 3983190225Srpaulo * The kernel should have left us with enough 3984190225Srpaulo * space for an sll header; back up the packet 3985190225Srpaulo * data pointer into that space, as that'll be 3986190225Srpaulo * the beginning of the packet we pass to the 3987190225Srpaulo * callback. 3988190225Srpaulo */ 3989190225Srpaulo bp -= SLL_HDR_LEN; 3990190225Srpaulo 3991190225Srpaulo /* 3992190225Srpaulo * Let's make sure that's past the end of 3993190225Srpaulo * the tpacket header, i.e. >= 3994190225Srpaulo * ((u_char *)thdr + TPACKET_HDRLEN), so we 3995190225Srpaulo * don't step on the header when we construct 3996190225Srpaulo * the sll header. 3997190225Srpaulo */ 3998190225Srpaulo if (bp < (u_char *)h.raw + 3999190225Srpaulo TPACKET_ALIGN(handle->md.tp_hdrlen) + 4000190225Srpaulo sizeof(struct sockaddr_ll)) { 4001190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 4002190225Srpaulo "cooked-mode frame doesn't have room for sll header"); 4003190225Srpaulo return -1; 4004190225Srpaulo } 4005190225Srpaulo 4006190225Srpaulo /* 4007190225Srpaulo * OK, that worked; construct the sll header. 4008190225Srpaulo */ 4009190225Srpaulo hdrp = (struct sll_header *)bp; 4010190225Srpaulo hdrp->sll_pkttype = map_packet_type_to_sll_type( 4011190225Srpaulo sll->sll_pkttype); 4012190225Srpaulo hdrp->sll_hatype = htons(sll->sll_hatype); 4013190225Srpaulo hdrp->sll_halen = htons(sll->sll_halen); 4014190225Srpaulo memcpy(hdrp->sll_addr, sll->sll_addr, SLL_ADDRLEN); 4015190225Srpaulo hdrp->sll_protocol = sll->sll_protocol; 4016190225Srpaulo 4017190225Srpaulo /* update packet len */ 4018190225Srpaulo pcaphdr.caplen += SLL_HDR_LEN; 4019190225Srpaulo pcaphdr.len += SLL_HDR_LEN; 4020190225Srpaulo } 4021190225Srpaulo 4022190225Srpaulo#ifdef HAVE_TPACKET2 4023190225Srpaulo if (handle->md.tp_version == TPACKET_V2 && h.h2->tp_vlan_tci && 4024190225Srpaulo tp_snaplen >= 2 * ETH_ALEN) { 4025190225Srpaulo struct vlan_tag *tag; 4026190225Srpaulo 4027190225Srpaulo bp -= VLAN_TAG_LEN; 4028190225Srpaulo memmove(bp, bp + VLAN_TAG_LEN, 2 * ETH_ALEN); 4029190225Srpaulo 4030190225Srpaulo tag = (struct vlan_tag *)(bp + 2 * ETH_ALEN); 4031190225Srpaulo tag->vlan_tpid = htons(ETH_P_8021Q); 4032190225Srpaulo tag->vlan_tci = htons(h.h2->tp_vlan_tci); 4033190225Srpaulo 4034190225Srpaulo pcaphdr.caplen += VLAN_TAG_LEN; 4035190225Srpaulo pcaphdr.len += VLAN_TAG_LEN; 4036190225Srpaulo } 4037190225Srpaulo#endif 4038190225Srpaulo 4039214518Srpaulo /* 4040214518Srpaulo * The only way to tell the kernel to cut off the 4041214518Srpaulo * packet at a snapshot length is with a filter program; 4042214518Srpaulo * if there's no filter program, the kernel won't cut 4043214518Srpaulo * the packet off. 4044214518Srpaulo * 4045214518Srpaulo * Trim the snapshot length to be no longer than the 4046214518Srpaulo * specified snapshot length. 4047214518Srpaulo */ 4048214518Srpaulo if (pcaphdr.caplen > handle->snapshot) 4049214518Srpaulo pcaphdr.caplen = handle->snapshot; 4050214518Srpaulo 4051190225Srpaulo /* pass the packet to the user */ 4052190225Srpaulo pkts++; 4053190225Srpaulo callback(user, &pcaphdr, bp); 4054190225Srpaulo handle->md.packets_read++; 4055190225Srpaulo 4056190225Srpauloskip: 4057190225Srpaulo /* next packet */ 4058190225Srpaulo switch (handle->md.tp_version) { 4059190225Srpaulo case TPACKET_V1: 4060190225Srpaulo h.h1->tp_status = TP_STATUS_KERNEL; 4061190225Srpaulo break; 4062190225Srpaulo#ifdef HAVE_TPACKET2 4063190225Srpaulo case TPACKET_V2: 4064190225Srpaulo h.h2->tp_status = TP_STATUS_KERNEL; 4065190225Srpaulo break; 4066190225Srpaulo#endif 4067190225Srpaulo } 4068190225Srpaulo if (++handle->offset >= handle->cc) 4069190225Srpaulo handle->offset = 0; 4070190225Srpaulo 4071190225Srpaulo /* check for break loop condition*/ 4072190225Srpaulo if (handle->break_loop) { 4073190225Srpaulo handle->break_loop = 0; 4074214518Srpaulo return PCAP_ERROR_BREAK; 4075190225Srpaulo } 4076190225Srpaulo } 4077190225Srpaulo return pkts; 4078190225Srpaulo} 4079190225Srpaulo 4080190225Srpaulostatic int 4081190225Srpaulopcap_setfilter_linux_mmap(pcap_t *handle, struct bpf_program *filter) 4082190225Srpaulo{ 4083190225Srpaulo int n, offset; 4084214518Srpaulo int ret; 4085214518Srpaulo 4086214518Srpaulo /* 4087214518Srpaulo * Don't rewrite "ret" instructions; we don't need to, as 4088214518Srpaulo * we're not reading packets with recvmsg(), and we don't 4089214518Srpaulo * want to, as, by not rewriting them, the kernel can avoid 4090214518Srpaulo * copying extra data. 4091214518Srpaulo */ 4092214518Srpaulo ret = pcap_setfilter_linux_common(handle, filter, 1); 4093190225Srpaulo if (ret < 0) 4094190225Srpaulo return ret; 4095190225Srpaulo 4096190225Srpaulo /* if the kernel filter is enabled, we need to apply the filter on 4097190225Srpaulo * all packets present into the ring. Get an upper bound of their number 4098190225Srpaulo */ 4099190225Srpaulo if (!handle->md.use_bpf) 4100190225Srpaulo return ret; 4101190225Srpaulo 4102190225Srpaulo /* walk the ring backward and count the free slot */ 4103190225Srpaulo offset = handle->offset; 4104190225Srpaulo if (--handle->offset < 0) 4105190225Srpaulo handle->offset = handle->cc - 1; 4106190225Srpaulo for (n=0; n < handle->cc; ++n) { 4107190225Srpaulo if (--handle->offset < 0) 4108190225Srpaulo handle->offset = handle->cc - 1; 4109190225Srpaulo if (!pcap_get_ring_frame(handle, TP_STATUS_KERNEL)) 4110190225Srpaulo break; 4111190225Srpaulo } 4112190225Srpaulo 4113190225Srpaulo /* be careful to not change current ring position */ 4114190225Srpaulo handle->offset = offset; 4115190225Srpaulo 4116190225Srpaulo /* store the number of packets currently present in the ring */ 4117190225Srpaulo handle->md.use_bpf = 1 + (handle->cc - n); 4118190225Srpaulo return ret; 4119190225Srpaulo} 4120190225Srpaulo 4121190225Srpaulo#endif /* HAVE_PACKET_RING */ 4122190225Srpaulo 4123190225Srpaulo 412475107Sfenner#ifdef HAVE_PF_PACKET_SOCKETS 412575107Sfenner/* 4126127664Sbms * Return the index of the given device name. Fill ebuf and return 412775107Sfenner * -1 on failure. 412875107Sfenner */ 412975107Sfennerstatic int 413075107Sfenneriface_get_id(int fd, const char *device, char *ebuf) 413175107Sfenner{ 413275107Sfenner struct ifreq ifr; 413326175Sfenner 413439291Sfenner memset(&ifr, 0, sizeof(ifr)); 413539291Sfenner strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 413675107Sfenner 413775107Sfenner if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) { 413875107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, 4139172677Smlaier "SIOCGIFINDEX: %s", pcap_strerror(errno)); 414075107Sfenner return -1; 414126175Sfenner } 414226175Sfenner 414375107Sfenner return ifr.ifr_ifindex; 414475107Sfenner} 414526175Sfenner 414675107Sfenner/* 4147127664Sbms * Bind the socket associated with FD to the given device. 4148190225Srpaulo * Return 1 on success, 0 if we should try a SOCK_PACKET socket, 4149190225Srpaulo * or a PCAP_ERROR_ value on a hard error. 415075107Sfenner */ 415175107Sfennerstatic int 415275107Sfenneriface_bind(int fd, int ifindex, char *ebuf) 415375107Sfenner{ 415475107Sfenner struct sockaddr_ll sll; 4155127664Sbms int err; 4156127664Sbms socklen_t errlen = sizeof(err); 415775107Sfenner 415875107Sfenner memset(&sll, 0, sizeof(sll)); 415975107Sfenner sll.sll_family = AF_PACKET; 416075107Sfenner sll.sll_ifindex = ifindex; 416175107Sfenner sll.sll_protocol = htons(ETH_P_ALL); 416275107Sfenner 416375107Sfenner if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) == -1) { 4164190225Srpaulo if (errno == ENETDOWN) { 4165190225Srpaulo /* 4166190225Srpaulo * Return a "network down" indication, so that 4167190225Srpaulo * the application can report that rather than 4168190225Srpaulo * saying we had a mysterious failure and 4169190225Srpaulo * suggest that they report a problem to the 4170190225Srpaulo * libpcap developers. 4171190225Srpaulo */ 4172190225Srpaulo return PCAP_ERROR_IFACE_NOT_UP; 4173190225Srpaulo } else { 4174190225Srpaulo snprintf(ebuf, PCAP_ERRBUF_SIZE, 4175190225Srpaulo "bind: %s", pcap_strerror(errno)); 4176190225Srpaulo return PCAP_ERROR; 4177190225Srpaulo } 417826175Sfenner } 417926175Sfenner 4180127664Sbms /* Any pending errors, e.g., network is down? */ 4181127664Sbms 4182127664Sbms if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) { 4183127664Sbms snprintf(ebuf, PCAP_ERRBUF_SIZE, 4184127664Sbms "getsockopt: %s", pcap_strerror(errno)); 4185190225Srpaulo return 0; 4186127664Sbms } 4187127664Sbms 4188190225Srpaulo if (err == ENETDOWN) { 4189190225Srpaulo /* 4190190225Srpaulo * Return a "network down" indication, so that 4191190225Srpaulo * the application can report that rather than 4192190225Srpaulo * saying we had a mysterious failure and 4193190225Srpaulo * suggest that they report a problem to the 4194190225Srpaulo * libpcap developers. 4195190225Srpaulo */ 4196190225Srpaulo return PCAP_ERROR_IFACE_NOT_UP; 4197190225Srpaulo } else if (err > 0) { 4198127664Sbms snprintf(ebuf, PCAP_ERRBUF_SIZE, 4199127664Sbms "bind: %s", pcap_strerror(err)); 4200190225Srpaulo return 0; 4201127664Sbms } 4202127664Sbms 4203190225Srpaulo return 1; 420475107Sfenner} 420575107Sfenner 4206214518Srpaulo#ifdef IW_MODE_MONITOR 420775107Sfenner/* 4208190225Srpaulo * Check whether the device supports the Wireless Extensions. 4209190225Srpaulo * Returns 1 if it does, 0 if it doesn't, PCAP_ERROR_NO_SUCH_DEVICE 4210190225Srpaulo * if the device doesn't even exist. 421175107Sfenner */ 4212190225Srpaulostatic int 4213190225Srpaulohas_wext(int sock_fd, const char *device, char *ebuf) 4214190225Srpaulo{ 4215190225Srpaulo struct iwreq ireq; 421675107Sfenner 4217190225Srpaulo strncpy(ireq.ifr_ifrn.ifrn_name, device, 4218190225Srpaulo sizeof ireq.ifr_ifrn.ifrn_name); 4219190225Srpaulo ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0; 4220190225Srpaulo if (ioctl(sock_fd, SIOCGIWNAME, &ireq) >= 0) 4221190225Srpaulo return 1; /* yes */ 4222190225Srpaulo snprintf(ebuf, PCAP_ERRBUF_SIZE, 4223190225Srpaulo "%s: SIOCGIWPRIV: %s", device, pcap_strerror(errno)); 4224190225Srpaulo if (errno == ENODEV) 4225190225Srpaulo return PCAP_ERROR_NO_SUCH_DEVICE; 4226190225Srpaulo return 0; 4227190225Srpaulo} 4228190225Srpaulo 422975107Sfenner/* 4230190225Srpaulo * Per me si va ne la citta dolente, 4231190225Srpaulo * Per me si va ne l'etterno dolore, 4232190225Srpaulo * ... 4233190225Srpaulo * Lasciate ogne speranza, voi ch'intrate. 4234190225Srpaulo * 4235190225Srpaulo * XXX - airmon-ng does special stuff with the Orinoco driver and the 4236190225Srpaulo * wlan-ng driver. 423775107Sfenner */ 4238190225Srpaulotypedef enum { 4239190225Srpaulo MONITOR_WEXT, 4240190225Srpaulo MONITOR_HOSTAP, 4241190225Srpaulo MONITOR_PRISM, 4242190225Srpaulo MONITOR_PRISM54, 4243190225Srpaulo MONITOR_ACX100, 4244190225Srpaulo MONITOR_RT2500, 4245190225Srpaulo MONITOR_RT2570, 4246190225Srpaulo MONITOR_RT73, 4247190225Srpaulo MONITOR_RTL8XXX 4248190225Srpaulo} monitor_type; 424975107Sfenner 425075107Sfenner/* 4251190225Srpaulo * Use the Wireless Extensions, if we have them, to try to turn monitor mode 4252190225Srpaulo * on if it's not already on. 4253190225Srpaulo * 4254190225Srpaulo * Returns 1 on success, 0 if we don't support the Wireless Extensions 4255190225Srpaulo * on this device, or a PCAP_ERROR_ value if we do support them but 4256190225Srpaulo * we weren't able to turn monitor mode on. 425775107Sfenner */ 4258190225Srpaulostatic int 4259190225Srpauloenter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device) 426075107Sfenner{ 4261190225Srpaulo /* 4262190225Srpaulo * XXX - at least some adapters require non-Wireless Extensions 4263190225Srpaulo * mechanisms to turn monitor mode on. 4264190225Srpaulo * 4265190225Srpaulo * Atheros cards might require that a separate "monitor virtual access 4266190225Srpaulo * point" be created, with later versions of the madwifi driver. 4267190225Srpaulo * airmon-ng does "wlanconfig ath create wlandev {if} wlanmode 4268190225Srpaulo * monitor -bssid", which apparently spits out a line "athN" 4269190225Srpaulo * where "athN" is the monitor mode device. To leave monitor 4270190225Srpaulo * mode, it destroys the monitor mode device. 4271190225Srpaulo * 4272190225Srpaulo * Some Intel Centrino adapters might require private ioctls to get 4273190225Srpaulo * radio headers; the ipw2200 and ipw3945 drivers allow you to 4274190225Srpaulo * configure a separate "rtapN" interface to capture in monitor 4275190225Srpaulo * mode without preventing the adapter from operating normally. 4276190225Srpaulo * (airmon-ng doesn't appear to use that, though.) 4277190225Srpaulo * 4278190225Srpaulo * It would be Truly Wonderful if mac80211 and nl80211 cleaned this 4279190225Srpaulo * up, and if all drivers were converted to mac80211 drivers. 4280190225Srpaulo * 4281190225Srpaulo * If interface {if} is a mac80211 driver, the file 4282190225Srpaulo * /sys/class/net/{if}/phy80211 is a symlink to 4283190225Srpaulo * /sys/class/ieee80211/{phydev}, for some {phydev}. 4284190225Srpaulo * 4285190225Srpaulo * On Fedora 9, with a 2.6.26.3-29 kernel, my Zydas stick, at 4286190225Srpaulo * least, has a "wmaster0" device and a "wlan0" device; the 4287190225Srpaulo * latter is the one with the IP address. Both show up in 4288190225Srpaulo * "tcpdump -D" output. Capturing on the wmaster0 device 4289190225Srpaulo * captures with 802.11 headers. 4290190225Srpaulo * 4291190225Srpaulo * airmon-ng searches through /sys/class/net for devices named 4292190225Srpaulo * monN, starting with mon0; as soon as one *doesn't* exist, 4293190225Srpaulo * it chooses that as the monitor device name. If the "iw" 4294190225Srpaulo * command exists, it does "iw dev {if} interface add {monif} 4295190225Srpaulo * type monitor", where {monif} is the monitor device. It 4296190225Srpaulo * then (sigh) sleeps .1 second, and then configures the 4297190225Srpaulo * device up. Otherwise, if /sys/class/ieee80211/{phydev}/add_iface 4298190225Srpaulo * is a file, it writes {mondev}, without a newline, to that file, 4299190225Srpaulo * and again (sigh) sleeps .1 second, and then iwconfig's that 4300190225Srpaulo * device into monitor mode and configures it up. Otherwise, 4301190225Srpaulo * you can't do monitor mode. 4302190225Srpaulo * 4303190225Srpaulo * All these devices are "glued" together by having the 4304190225Srpaulo * /sys/class/net/{device}/phy80211 links pointing to the same 4305190225Srpaulo * place, so, given a wmaster, wlan, or mon device, you can 4306190225Srpaulo * find the other devices by looking for devices with 4307190225Srpaulo * the same phy80211 link. 4308190225Srpaulo * 4309190225Srpaulo * To turn monitor mode off, delete the monitor interface, 4310190225Srpaulo * either with "iw dev {monif} interface del" or by sending 4311190225Srpaulo * {monif}, with no NL, down /sys/class/ieee80211/{phydev}/remove_iface 4312190225Srpaulo * 4313190225Srpaulo * Note: if you try to create a monitor device named "monN", and 4314190225Srpaulo * there's already a "monN" device, it fails, as least with 4315190225Srpaulo * the netlink interface (which is what iw uses), with a return 4316190225Srpaulo * value of -ENFILE. (Return values are negative errnos.) We 4317190225Srpaulo * could probably use that to find an unused device. 4318190225Srpaulo */ 4319190225Srpaulo int err; 4320190225Srpaulo struct iwreq ireq; 4321190225Srpaulo struct iw_priv_args *priv; 4322190225Srpaulo monitor_type montype; 4323190225Srpaulo int i; 4324190225Srpaulo __u32 cmd; 4325236167Sdelphij struct ifreq ifr; 4326236167Sdelphij int oldflags; 4327190225Srpaulo int args[2]; 4328190225Srpaulo int channel; 432975107Sfenner 4330190225Srpaulo /* 4331190225Srpaulo * Does this device *support* the Wireless Extensions? 4332190225Srpaulo */ 4333190225Srpaulo err = has_wext(sock_fd, device, handle->errbuf); 4334190225Srpaulo if (err <= 0) 4335190225Srpaulo return err; /* either it doesn't or the device doesn't even exist */ 4336190225Srpaulo /* 4337236167Sdelphij * Start out assuming we have no private extensions to control 4338236167Sdelphij * radio metadata. 4339236167Sdelphij */ 4340236167Sdelphij montype = MONITOR_WEXT; 4341236167Sdelphij cmd = 0; 4342236167Sdelphij 4343236167Sdelphij /* 4344190225Srpaulo * Try to get all the Wireless Extensions private ioctls 4345190225Srpaulo * supported by this device. 4346190225Srpaulo * 4347190225Srpaulo * First, get the size of the buffer we need, by supplying no 4348190225Srpaulo * buffer and a length of 0. If the device supports private 4349190225Srpaulo * ioctls, it should return E2BIG, with ireq.u.data.length set 4350190225Srpaulo * to the length we need. If it doesn't support them, it should 4351190225Srpaulo * return EOPNOTSUPP. 4352190225Srpaulo */ 4353190225Srpaulo memset(&ireq, 0, sizeof ireq); 4354190225Srpaulo strncpy(ireq.ifr_ifrn.ifrn_name, device, 4355190225Srpaulo sizeof ireq.ifr_ifrn.ifrn_name); 4356190225Srpaulo ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0; 4357214518Srpaulo ireq.u.data.pointer = (void *)args; 4358190225Srpaulo ireq.u.data.length = 0; 4359190225Srpaulo ireq.u.data.flags = 0; 4360190225Srpaulo if (ioctl(sock_fd, SIOCGIWPRIV, &ireq) != -1) { 4361190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 4362190225Srpaulo "%s: SIOCGIWPRIV with a zero-length buffer didn't fail!", 4363190225Srpaulo device); 4364190225Srpaulo return PCAP_ERROR; 4365190225Srpaulo } 4366236167Sdelphij if (errno != EOPNOTSUPP) { 4367190225Srpaulo /* 4368236167Sdelphij * OK, it's not as if there are no private ioctls. 4369190225Srpaulo */ 4370236167Sdelphij if (errno != E2BIG) { 4371190225Srpaulo /* 4372236167Sdelphij * Failed. 4373190225Srpaulo */ 4374236167Sdelphij snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 4375236167Sdelphij "%s: SIOCGIWPRIV: %s", device, 4376236167Sdelphij pcap_strerror(errno)); 4377236167Sdelphij return PCAP_ERROR; 4378190225Srpaulo } 4379236167Sdelphij 4380236167Sdelphij /* 4381236167Sdelphij * OK, try to get the list of private ioctls. 4382236167Sdelphij */ 4383236167Sdelphij priv = malloc(ireq.u.data.length * sizeof (struct iw_priv_args)); 4384236167Sdelphij if (priv == NULL) { 4385236167Sdelphij snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 4386236167Sdelphij "malloc: %s", pcap_strerror(errno)); 4387236167Sdelphij return PCAP_ERROR; 4388190225Srpaulo } 4389236167Sdelphij ireq.u.data.pointer = (void *)priv; 4390236167Sdelphij if (ioctl(sock_fd, SIOCGIWPRIV, &ireq) == -1) { 4391236167Sdelphij snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 4392236167Sdelphij "%s: SIOCGIWPRIV: %s", device, 4393236167Sdelphij pcap_strerror(errno)); 4394236167Sdelphij free(priv); 4395236167Sdelphij return PCAP_ERROR; 4396190225Srpaulo } 4397236167Sdelphij 4398236167Sdelphij /* 4399236167Sdelphij * Look for private ioctls to turn monitor mode on or, if 4400236167Sdelphij * monitor mode is on, to set the header type. 4401236167Sdelphij */ 4402236167Sdelphij for (i = 0; i < ireq.u.data.length; i++) { 4403236167Sdelphij if (strcmp(priv[i].name, "monitor_type") == 0) { 4404236167Sdelphij /* 4405236167Sdelphij * Hostap driver, use this one. 4406236167Sdelphij * Set monitor mode first. 4407236167Sdelphij * You can set it to 0 to get DLT_IEEE80211, 4408236167Sdelphij * 1 to get DLT_PRISM, 2 to get 4409236167Sdelphij * DLT_IEEE80211_RADIO_AVS, and, with more 4410236167Sdelphij * recent versions of the driver, 3 to get 4411236167Sdelphij * DLT_IEEE80211_RADIO. 4412236167Sdelphij */ 4413236167Sdelphij if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT) 4414236167Sdelphij break; 4415236167Sdelphij if (!(priv[i].set_args & IW_PRIV_SIZE_FIXED)) 4416236167Sdelphij break; 4417236167Sdelphij if ((priv[i].set_args & IW_PRIV_SIZE_MASK) != 1) 4418236167Sdelphij break; 4419236167Sdelphij montype = MONITOR_HOSTAP; 4420236167Sdelphij cmd = priv[i].cmd; 4421190225Srpaulo break; 4422236167Sdelphij } 4423236167Sdelphij if (strcmp(priv[i].name, "set_prismhdr") == 0) { 4424236167Sdelphij /* 4425236167Sdelphij * Prism54 driver, use this one. 4426236167Sdelphij * Set monitor mode first. 4427236167Sdelphij * You can set it to 2 to get DLT_IEEE80211 4428236167Sdelphij * or 3 or get DLT_PRISM. 4429236167Sdelphij */ 4430236167Sdelphij if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT) 4431236167Sdelphij break; 4432236167Sdelphij if (!(priv[i].set_args & IW_PRIV_SIZE_FIXED)) 4433236167Sdelphij break; 4434236167Sdelphij if ((priv[i].set_args & IW_PRIV_SIZE_MASK) != 1) 4435236167Sdelphij break; 4436236167Sdelphij montype = MONITOR_PRISM54; 4437236167Sdelphij cmd = priv[i].cmd; 4438190225Srpaulo break; 4439236167Sdelphij } 4440236167Sdelphij if (strcmp(priv[i].name, "forceprismheader") == 0) { 4441236167Sdelphij /* 4442236167Sdelphij * RT2570 driver, use this one. 4443236167Sdelphij * Do this after turning monitor mode on. 4444236167Sdelphij * You can set it to 1 to get DLT_PRISM or 2 4445236167Sdelphij * to get DLT_IEEE80211. 4446236167Sdelphij */ 4447236167Sdelphij if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT) 4448236167Sdelphij break; 4449236167Sdelphij if (!(priv[i].set_args & IW_PRIV_SIZE_FIXED)) 4450236167Sdelphij break; 4451236167Sdelphij if ((priv[i].set_args & IW_PRIV_SIZE_MASK) != 1) 4452236167Sdelphij break; 4453236167Sdelphij montype = MONITOR_RT2570; 4454236167Sdelphij cmd = priv[i].cmd; 4455190225Srpaulo break; 4456236167Sdelphij } 4457236167Sdelphij if (strcmp(priv[i].name, "forceprism") == 0) { 4458236167Sdelphij /* 4459236167Sdelphij * RT73 driver, use this one. 4460236167Sdelphij * Do this after turning monitor mode on. 4461236167Sdelphij * Its argument is a *string*; you can 4462236167Sdelphij * set it to "1" to get DLT_PRISM or "2" 4463236167Sdelphij * to get DLT_IEEE80211. 4464236167Sdelphij */ 4465236167Sdelphij if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_CHAR) 4466236167Sdelphij break; 4467236167Sdelphij if (priv[i].set_args & IW_PRIV_SIZE_FIXED) 4468236167Sdelphij break; 4469236167Sdelphij montype = MONITOR_RT73; 4470236167Sdelphij cmd = priv[i].cmd; 4471190225Srpaulo break; 4472236167Sdelphij } 4473236167Sdelphij if (strcmp(priv[i].name, "prismhdr") == 0) { 4474236167Sdelphij /* 4475236167Sdelphij * One of the RTL8xxx drivers, use this one. 4476236167Sdelphij * It can only be done after monitor mode 4477236167Sdelphij * has been turned on. You can set it to 1 4478236167Sdelphij * to get DLT_PRISM or 0 to get DLT_IEEE80211. 4479236167Sdelphij */ 4480236167Sdelphij if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT) 4481236167Sdelphij break; 4482236167Sdelphij if (!(priv[i].set_args & IW_PRIV_SIZE_FIXED)) 4483236167Sdelphij break; 4484236167Sdelphij if ((priv[i].set_args & IW_PRIV_SIZE_MASK) != 1) 4485236167Sdelphij break; 4486236167Sdelphij montype = MONITOR_RTL8XXX; 4487190225Srpaulo cmd = priv[i].cmd; 4488190225Srpaulo break; 4489236167Sdelphij } 4490236167Sdelphij if (strcmp(priv[i].name, "rfmontx") == 0) { 4491236167Sdelphij /* 4492236167Sdelphij * RT2500 or RT61 driver, use this one. 4493236167Sdelphij * It has one one-byte parameter; set 4494236167Sdelphij * u.data.length to 1 and u.data.pointer to 4495236167Sdelphij * point to the parameter. 4496236167Sdelphij * It doesn't itself turn monitor mode on. 4497236167Sdelphij * You can set it to 1 to allow transmitting 4498236167Sdelphij * in monitor mode(?) and get DLT_IEEE80211, 4499236167Sdelphij * or set it to 0 to disallow transmitting in 4500236167Sdelphij * monitor mode(?) and get DLT_PRISM. 4501236167Sdelphij */ 4502236167Sdelphij if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT) 4503236167Sdelphij break; 4504236167Sdelphij if ((priv[i].set_args & IW_PRIV_SIZE_MASK) != 2) 4505236167Sdelphij break; 4506236167Sdelphij montype = MONITOR_RT2500; 4507190225Srpaulo cmd = priv[i].cmd; 4508190225Srpaulo break; 4509236167Sdelphij } 4510236167Sdelphij if (strcmp(priv[i].name, "monitor") == 0) { 4511236167Sdelphij /* 4512236167Sdelphij * Either ACX100 or hostap, use this one. 4513236167Sdelphij * It turns monitor mode on. 4514236167Sdelphij * If it takes two arguments, it's ACX100; 4515236167Sdelphij * the first argument is 1 for DLT_PRISM 4516236167Sdelphij * or 2 for DLT_IEEE80211, and the second 4517236167Sdelphij * argument is the channel on which to 4518236167Sdelphij * run. If it takes one argument, it's 4519236167Sdelphij * HostAP, and the argument is 2 for 4520236167Sdelphij * DLT_IEEE80211 and 3 for DLT_PRISM. 4521236167Sdelphij * 4522236167Sdelphij * If we see this, we don't quit, as this 4523236167Sdelphij * might be a version of the hostap driver 4524236167Sdelphij * that also supports "monitor_type". 4525236167Sdelphij */ 4526236167Sdelphij if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT) 4527236167Sdelphij break; 4528236167Sdelphij if (!(priv[i].set_args & IW_PRIV_SIZE_FIXED)) 4529236167Sdelphij break; 4530236167Sdelphij switch (priv[i].set_args & IW_PRIV_SIZE_MASK) { 4531190225Srpaulo 4532236167Sdelphij case 1: 4533236167Sdelphij montype = MONITOR_PRISM; 4534236167Sdelphij cmd = priv[i].cmd; 4535236167Sdelphij break; 4536236167Sdelphij 4537236167Sdelphij case 2: 4538236167Sdelphij montype = MONITOR_ACX100; 4539236167Sdelphij cmd = priv[i].cmd; 4540236167Sdelphij break; 4541236167Sdelphij 4542236167Sdelphij default: 4543236167Sdelphij break; 4544236167Sdelphij } 4545190225Srpaulo } 4546190225Srpaulo } 4547236167Sdelphij free(priv); 4548190225Srpaulo } 4549190225Srpaulo 4550190225Srpaulo /* 4551190225Srpaulo * XXX - ipw3945? islism? 4552190225Srpaulo */ 4553190225Srpaulo 4554190225Srpaulo /* 4555190225Srpaulo * Get the old mode. 4556190225Srpaulo */ 4557190225Srpaulo strncpy(ireq.ifr_ifrn.ifrn_name, device, 4558190225Srpaulo sizeof ireq.ifr_ifrn.ifrn_name); 4559190225Srpaulo ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0; 4560190225Srpaulo if (ioctl(sock_fd, SIOCGIWMODE, &ireq) == -1) { 456175107Sfenner /* 4562190225Srpaulo * We probably won't be able to set the mode, either. 4563190225Srpaulo */ 4564190225Srpaulo return PCAP_ERROR_RFMON_NOTSUP; 4565190225Srpaulo } 4566190225Srpaulo 4567190225Srpaulo /* 4568190225Srpaulo * Is it currently in monitor mode? 4569190225Srpaulo */ 4570190225Srpaulo if (ireq.u.mode == IW_MODE_MONITOR) { 4571190225Srpaulo /* 4572190225Srpaulo * Yes. Just leave things as they are. 4573190225Srpaulo * We don't offer multiple link-layer types, as 4574190225Srpaulo * changing the link-layer type out from under 4575190225Srpaulo * somebody else capturing in monitor mode would 4576190225Srpaulo * be considered rude. 4577190225Srpaulo */ 4578190225Srpaulo return 1; 4579190225Srpaulo } 4580190225Srpaulo /* 4581190225Srpaulo * No. We have to put the adapter into rfmon mode. 4582190225Srpaulo */ 4583190225Srpaulo 4584190225Srpaulo /* 4585190225Srpaulo * If we haven't already done so, arrange to have 4586190225Srpaulo * "pcap_close_all()" called when we exit. 4587190225Srpaulo */ 4588190225Srpaulo if (!pcap_do_addexit(handle)) { 4589190225Srpaulo /* 4590190225Srpaulo * "atexit()" failed; don't put the interface 4591190225Srpaulo * in rfmon mode, just give up. 4592190225Srpaulo */ 4593190225Srpaulo return PCAP_ERROR_RFMON_NOTSUP; 4594190225Srpaulo } 4595190225Srpaulo 4596190225Srpaulo /* 4597190225Srpaulo * Save the old mode. 4598190225Srpaulo */ 4599190225Srpaulo handle->md.oldmode = ireq.u.mode; 4600190225Srpaulo 4601190225Srpaulo /* 4602190225Srpaulo * Put the adapter in rfmon mode. How we do this depends 4603190225Srpaulo * on whether we have a special private ioctl or not. 4604190225Srpaulo */ 4605190225Srpaulo if (montype == MONITOR_PRISM) { 4606190225Srpaulo /* 4607190225Srpaulo * We have the "monitor" private ioctl, but none of 4608190225Srpaulo * the other private ioctls. Use this, and select 4609190225Srpaulo * the Prism header. 461075107Sfenner * 4611190225Srpaulo * If it fails, just fall back on SIOCSIWMODE. 461275107Sfenner */ 4613190225Srpaulo memset(&ireq, 0, sizeof ireq); 4614190225Srpaulo strncpy(ireq.ifr_ifrn.ifrn_name, device, 4615190225Srpaulo sizeof ireq.ifr_ifrn.ifrn_name); 4616190225Srpaulo ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0; 4617190225Srpaulo ireq.u.data.length = 1; /* 1 argument */ 4618190225Srpaulo args[0] = 3; /* request Prism header */ 4619190225Srpaulo memcpy(ireq.u.name, args, IFNAMSIZ); 4620190225Srpaulo if (ioctl(sock_fd, cmd, &ireq) != -1) { 4621190225Srpaulo /* 4622190225Srpaulo * Success. 4623190225Srpaulo * Note that we have to put the old mode back 4624190225Srpaulo * when we close the device. 4625190225Srpaulo */ 4626214518Srpaulo handle->md.must_do_on_close |= MUST_CLEAR_RFMON; 4627190225Srpaulo 4628190225Srpaulo /* 4629190225Srpaulo * Add this to the list of pcaps to close 4630190225Srpaulo * when we exit. 4631190225Srpaulo */ 4632190225Srpaulo pcap_add_to_pcaps_to_close(handle); 4633190225Srpaulo 4634190225Srpaulo return 1; 463526175Sfenner } 463675107Sfenner 463775107Sfenner /* 4638190225Srpaulo * Failure. Fall back on SIOCSIWMODE. 463975107Sfenner */ 4640190225Srpaulo } 4641190225Srpaulo 4642190225Srpaulo /* 4643236167Sdelphij * First, take the interface down if it's up; otherwise, we 4644236167Sdelphij * might get EBUSY. 4645190225Srpaulo */ 4646236167Sdelphij memset(&ifr, 0, sizeof(ifr)); 4647236167Sdelphij strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 4648236167Sdelphij if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) == -1) { 4649236167Sdelphij snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 4650236167Sdelphij "%s: Can't get flags: %s", device, strerror(errno)); 4651236167Sdelphij return PCAP_ERROR; 4652236167Sdelphij } 4653236167Sdelphij oldflags = 0; 4654236167Sdelphij if (ifr.ifr_flags & IFF_UP) { 4655236167Sdelphij oldflags = ifr.ifr_flags; 4656236167Sdelphij ifr.ifr_flags &= ~IFF_UP; 4657236167Sdelphij if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1) { 4658236167Sdelphij snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 4659236167Sdelphij "%s: Can't set flags: %s", device, strerror(errno)); 4660236167Sdelphij return PCAP_ERROR; 4661236167Sdelphij } 4662236167Sdelphij } 4663236167Sdelphij 4664236167Sdelphij /* 4665236167Sdelphij * Then turn monitor mode on. 4666236167Sdelphij */ 4667190225Srpaulo strncpy(ireq.ifr_ifrn.ifrn_name, device, 4668190225Srpaulo sizeof ireq.ifr_ifrn.ifrn_name); 4669190225Srpaulo ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0; 4670190225Srpaulo ireq.u.mode = IW_MODE_MONITOR; 4671190225Srpaulo if (ioctl(sock_fd, SIOCSIWMODE, &ireq) == -1) { 4672190225Srpaulo /* 4673190225Srpaulo * Scientist, you've failed. 4674236167Sdelphij * Bring the interface back up if we shut it down. 4675190225Srpaulo */ 4676236167Sdelphij ifr.ifr_flags = oldflags; 4677236167Sdelphij if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1) { 4678236167Sdelphij snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 4679236167Sdelphij "%s: Can't set flags: %s", device, strerror(errno)); 4680236167Sdelphij return PCAP_ERROR; 4681236167Sdelphij } 4682190225Srpaulo return PCAP_ERROR_RFMON_NOTSUP; 4683190225Srpaulo } 4684190225Srpaulo 4685190225Srpaulo /* 4686190225Srpaulo * XXX - airmon-ng does "iwconfig {if} key off" after setting 4687190225Srpaulo * monitor mode and setting the channel, and then does 4688190225Srpaulo * "iwconfig up". 4689190225Srpaulo */ 4690190225Srpaulo 4691190225Srpaulo /* 4692190225Srpaulo * Now select the appropriate radio header. 4693190225Srpaulo */ 4694190225Srpaulo switch (montype) { 4695190225Srpaulo 4696190225Srpaulo case MONITOR_WEXT: 4697190225Srpaulo /* 4698190225Srpaulo * We don't have any private ioctl to set the header. 4699190225Srpaulo */ 4700190225Srpaulo break; 4701190225Srpaulo 4702190225Srpaulo case MONITOR_HOSTAP: 4703190225Srpaulo /* 4704214518Srpaulo * Try to select the radiotap header. 4705190225Srpaulo */ 4706190225Srpaulo memset(&ireq, 0, sizeof ireq); 4707190225Srpaulo strncpy(ireq.ifr_ifrn.ifrn_name, device, 4708190225Srpaulo sizeof ireq.ifr_ifrn.ifrn_name); 4709190225Srpaulo ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0; 4710214518Srpaulo args[0] = 3; /* request radiotap header */ 4711214518Srpaulo memcpy(ireq.u.name, args, sizeof (int)); 4712214518Srpaulo if (ioctl(sock_fd, cmd, &ireq) != -1) 4713214518Srpaulo break; /* success */ 4714214518Srpaulo 4715214518Srpaulo /* 4716214518Srpaulo * That failed. Try to select the AVS header. 4717214518Srpaulo */ 4718214518Srpaulo memset(&ireq, 0, sizeof ireq); 4719214518Srpaulo strncpy(ireq.ifr_ifrn.ifrn_name, device, 4720214518Srpaulo sizeof ireq.ifr_ifrn.ifrn_name); 4721214518Srpaulo ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0; 4722190225Srpaulo args[0] = 2; /* request AVS header */ 4723190225Srpaulo memcpy(ireq.u.name, args, sizeof (int)); 4724214518Srpaulo if (ioctl(sock_fd, cmd, &ireq) != -1) 4725214518Srpaulo break; /* success */ 4726214518Srpaulo 4727214518Srpaulo /* 4728214518Srpaulo * That failed. Try to select the Prism header. 4729214518Srpaulo */ 4730214518Srpaulo memset(&ireq, 0, sizeof ireq); 4731214518Srpaulo strncpy(ireq.ifr_ifrn.ifrn_name, device, 4732214518Srpaulo sizeof ireq.ifr_ifrn.ifrn_name); 4733214518Srpaulo ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0; 4734214518Srpaulo args[0] = 1; /* request Prism header */ 4735214518Srpaulo memcpy(ireq.u.name, args, sizeof (int)); 4736214518Srpaulo ioctl(sock_fd, cmd, &ireq); 4737190225Srpaulo break; 4738190225Srpaulo 4739190225Srpaulo case MONITOR_PRISM: 4740190225Srpaulo /* 4741190225Srpaulo * The private ioctl failed. 4742190225Srpaulo */ 4743190225Srpaulo break; 4744190225Srpaulo 4745190225Srpaulo case MONITOR_PRISM54: 4746190225Srpaulo /* 4747190225Srpaulo * Select the Prism header. 4748190225Srpaulo */ 4749190225Srpaulo memset(&ireq, 0, sizeof ireq); 4750190225Srpaulo strncpy(ireq.ifr_ifrn.ifrn_name, device, 4751190225Srpaulo sizeof ireq.ifr_ifrn.ifrn_name); 4752190225Srpaulo ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0; 4753190225Srpaulo args[0] = 3; /* request Prism header */ 4754190225Srpaulo memcpy(ireq.u.name, args, sizeof (int)); 4755190225Srpaulo ioctl(sock_fd, cmd, &ireq); 4756190225Srpaulo break; 4757190225Srpaulo 4758190225Srpaulo case MONITOR_ACX100: 4759190225Srpaulo /* 4760190225Srpaulo * Get the current channel. 4761190225Srpaulo */ 4762190225Srpaulo memset(&ireq, 0, sizeof ireq); 4763190225Srpaulo strncpy(ireq.ifr_ifrn.ifrn_name, device, 4764190225Srpaulo sizeof ireq.ifr_ifrn.ifrn_name); 4765190225Srpaulo ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0; 4766190225Srpaulo if (ioctl(sock_fd, SIOCGIWFREQ, &ireq) == -1) { 4767190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 4768190225Srpaulo "%s: SIOCGIWFREQ: %s", device, 4769190225Srpaulo pcap_strerror(errno)); 4770190225Srpaulo return PCAP_ERROR; 4771190225Srpaulo } 4772190225Srpaulo channel = ireq.u.freq.m; 4773190225Srpaulo 4774190225Srpaulo /* 4775190225Srpaulo * Select the Prism header, and set the channel to the 4776190225Srpaulo * current value. 4777190225Srpaulo */ 4778190225Srpaulo memset(&ireq, 0, sizeof ireq); 4779190225Srpaulo strncpy(ireq.ifr_ifrn.ifrn_name, device, 4780190225Srpaulo sizeof ireq.ifr_ifrn.ifrn_name); 4781190225Srpaulo ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0; 4782190225Srpaulo args[0] = 1; /* request Prism header */ 4783190225Srpaulo args[1] = channel; /* set channel */ 4784190225Srpaulo memcpy(ireq.u.name, args, 2*sizeof (int)); 4785190225Srpaulo ioctl(sock_fd, cmd, &ireq); 4786190225Srpaulo break; 4787190225Srpaulo 4788190225Srpaulo case MONITOR_RT2500: 4789190225Srpaulo /* 4790190225Srpaulo * Disallow transmission - that turns on the 4791190225Srpaulo * Prism header. 4792190225Srpaulo */ 4793190225Srpaulo memset(&ireq, 0, sizeof ireq); 4794190225Srpaulo strncpy(ireq.ifr_ifrn.ifrn_name, device, 4795190225Srpaulo sizeof ireq.ifr_ifrn.ifrn_name); 4796190225Srpaulo ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0; 4797190225Srpaulo args[0] = 0; /* disallow transmitting */ 4798190225Srpaulo memcpy(ireq.u.name, args, sizeof (int)); 4799190225Srpaulo ioctl(sock_fd, cmd, &ireq); 4800190225Srpaulo break; 4801190225Srpaulo 4802190225Srpaulo case MONITOR_RT2570: 4803190225Srpaulo /* 4804190225Srpaulo * Force the Prism header. 4805190225Srpaulo */ 4806190225Srpaulo memset(&ireq, 0, sizeof ireq); 4807190225Srpaulo strncpy(ireq.ifr_ifrn.ifrn_name, device, 4808190225Srpaulo sizeof ireq.ifr_ifrn.ifrn_name); 4809190225Srpaulo ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0; 4810190225Srpaulo args[0] = 1; /* request Prism header */ 4811190225Srpaulo memcpy(ireq.u.name, args, sizeof (int)); 4812190225Srpaulo ioctl(sock_fd, cmd, &ireq); 4813190225Srpaulo break; 4814190225Srpaulo 4815190225Srpaulo case MONITOR_RT73: 4816190225Srpaulo /* 4817190225Srpaulo * Force the Prism header. 4818190225Srpaulo */ 4819190225Srpaulo memset(&ireq, 0, sizeof ireq); 4820190225Srpaulo strncpy(ireq.ifr_ifrn.ifrn_name, device, 4821190225Srpaulo sizeof ireq.ifr_ifrn.ifrn_name); 4822190225Srpaulo ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0; 4823190225Srpaulo ireq.u.data.length = 1; /* 1 argument */ 4824190225Srpaulo ireq.u.data.pointer = "1"; 4825190225Srpaulo ireq.u.data.flags = 0; 4826190225Srpaulo ioctl(sock_fd, cmd, &ireq); 4827190225Srpaulo break; 4828190225Srpaulo 4829190225Srpaulo case MONITOR_RTL8XXX: 4830190225Srpaulo /* 4831190225Srpaulo * Force the Prism header. 4832190225Srpaulo */ 4833190225Srpaulo memset(&ireq, 0, sizeof ireq); 4834190225Srpaulo strncpy(ireq.ifr_ifrn.ifrn_name, device, 4835190225Srpaulo sizeof ireq.ifr_ifrn.ifrn_name); 4836190225Srpaulo ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0; 4837190225Srpaulo args[0] = 1; /* request Prism header */ 4838190225Srpaulo memcpy(ireq.u.name, args, sizeof (int)); 4839190225Srpaulo ioctl(sock_fd, cmd, &ireq); 4840190225Srpaulo break; 484126175Sfenner } 4842127664Sbms 4843190225Srpaulo /* 4844236167Sdelphij * Now bring the interface back up if we brought it down. 4845236167Sdelphij */ 4846236167Sdelphij if (oldflags != 0) { 4847236167Sdelphij ifr.ifr_flags = oldflags; 4848236167Sdelphij if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1) { 4849236167Sdelphij snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 4850236167Sdelphij "%s: Can't set flags: %s", device, strerror(errno)); 4851236167Sdelphij 4852236167Sdelphij /* 4853236167Sdelphij * At least try to restore the old mode on the 4854236167Sdelphij * interface. 4855236167Sdelphij */ 4856236167Sdelphij if (ioctl(handle->fd, SIOCSIWMODE, &ireq) == -1) { 4857236167Sdelphij /* 4858236167Sdelphij * Scientist, you've failed. 4859236167Sdelphij */ 4860236167Sdelphij fprintf(stderr, 4861236167Sdelphij "Can't restore interface wireless mode (SIOCSIWMODE failed: %s).\n" 4862236167Sdelphij "Please adjust manually.\n", 4863236167Sdelphij strerror(errno)); 4864236167Sdelphij } 4865236167Sdelphij return PCAP_ERROR; 4866236167Sdelphij } 4867236167Sdelphij } 4868236167Sdelphij 4869236167Sdelphij /* 4870190225Srpaulo * Note that we have to put the old mode back when we 4871190225Srpaulo * close the device. 4872190225Srpaulo */ 4873214518Srpaulo handle->md.must_do_on_close |= MUST_CLEAR_RFMON; 4874190225Srpaulo 4875190225Srpaulo /* 4876190225Srpaulo * Add this to the list of pcaps to close when we exit. 4877190225Srpaulo */ 4878190225Srpaulo pcap_add_to_pcaps_to_close(handle); 4879190225Srpaulo 4880190225Srpaulo return 1; 4881214518Srpaulo} 4882214518Srpaulo#endif /* IW_MODE_MONITOR */ 4883214518Srpaulo 4884214518Srpaulo/* 4885214518Srpaulo * Try various mechanisms to enter monitor mode. 4886214518Srpaulo */ 4887214518Srpaulostatic int 4888214518Srpauloenter_rfmon_mode(pcap_t *handle, int sock_fd, const char *device) 4889214518Srpaulo{ 4890214518Srpaulo#if defined(HAVE_LIBNL) || defined(IW_MODE_MONITOR) 4891214518Srpaulo int ret; 4892214518Srpaulo#endif 4893214518Srpaulo 4894214518Srpaulo#ifdef HAVE_LIBNL 4895214518Srpaulo ret = enter_rfmon_mode_mac80211(handle, sock_fd, device); 4896214518Srpaulo if (ret < 0) 4897214518Srpaulo return ret; /* error attempting to do so */ 4898214518Srpaulo if (ret == 1) 4899214518Srpaulo return 1; /* success */ 4900214518Srpaulo#endif /* HAVE_LIBNL */ 4901214518Srpaulo 4902214518Srpaulo#ifdef IW_MODE_MONITOR 4903214518Srpaulo ret = enter_rfmon_mode_wext(handle, sock_fd, device); 4904214518Srpaulo if (ret < 0) 4905214518Srpaulo return ret; /* error attempting to do so */ 4906214518Srpaulo if (ret == 1) 4907214518Srpaulo return 1; /* success */ 4908214518Srpaulo#endif /* IW_MODE_MONITOR */ 4909214518Srpaulo 4910190225Srpaulo /* 4911214518Srpaulo * Either none of the mechanisms we know about work or none 4912214518Srpaulo * of those mechanisms are available, so we can't do monitor 4913214518Srpaulo * mode. 4914190225Srpaulo */ 4915190225Srpaulo return 0; 491675107Sfenner} 491726175Sfenner 4918236167Sdelphij/* 4919236167Sdelphij * Find out if we have any form of fragmentation/reassembly offloading. 4920236167Sdelphij * 4921236167Sdelphij * We do so using SIOCETHTOOL checking for various types of offloading; 4922236167Sdelphij * if SIOCETHTOOL isn't defined, or we don't have any #defines for any 4923236167Sdelphij * of the types of offloading, there's nothing we can do to check, so 4924236167Sdelphij * we just say "no, we don't". 4925236167Sdelphij */ 4926236167Sdelphij#if defined(SIOCETHTOOL) && (defined(ETHTOOL_GTSO) || defined(ETHTOOL_GUFO) || defined(ETHTOOL_GGSO) || defined(ETHTOOL_GFLAGS) || defined(ETHTOOL_GGRO)) 4927236167Sdelphijstatic int 4928236167Sdelphijiface_ethtool_ioctl(pcap_t *handle, int cmd, const char *cmdname) 4929236167Sdelphij{ 4930236167Sdelphij struct ifreq ifr; 4931236167Sdelphij struct ethtool_value eval; 4932236167Sdelphij 4933236167Sdelphij memset(&ifr, 0, sizeof(ifr)); 4934236167Sdelphij strncpy(ifr.ifr_name, handle->opt.source, sizeof(ifr.ifr_name)); 4935236167Sdelphij eval.cmd = cmd; 4936236167Sdelphij ifr.ifr_data = (caddr_t)&eval; 4937236167Sdelphij if (ioctl(handle->fd, SIOCETHTOOL, &ifr) == -1) { 4938236167Sdelphij if (errno == EOPNOTSUPP) { 4939236167Sdelphij /* 4940236167Sdelphij * OK, let's just return 0, which, in our 4941236167Sdelphij * case, either means "no, what we're asking 4942236167Sdelphij * about is not enabled" or "all the flags 4943236167Sdelphij * are clear (i.e., nothing is enabled)". 4944236167Sdelphij */ 4945236167Sdelphij return 0; 4946236167Sdelphij } 4947236167Sdelphij snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 4948236167Sdelphij "%s: SIOETHTOOL(%s) ioctl failed: %s", handle->opt.source, 4949236167Sdelphij cmdname, strerror(errno)); 4950236167Sdelphij return -1; 4951236167Sdelphij } 4952236167Sdelphij return eval.data; 4953236167Sdelphij} 4954236167Sdelphij 4955236167Sdelphijstatic int 4956236167Sdelphijiface_get_offload(pcap_t *handle) 4957236167Sdelphij{ 4958236167Sdelphij int ret; 4959236167Sdelphij 4960236167Sdelphij#ifdef ETHTOOL_GTSO 4961236167Sdelphij ret = iface_ethtool_ioctl(handle, ETHTOOL_GTSO, "ETHTOOL_GTSO"); 4962236167Sdelphij if (ret == -1) 4963236167Sdelphij return -1; 4964236167Sdelphij if (ret) 4965236167Sdelphij return 1; /* TCP segmentation offloading on */ 4966236167Sdelphij#endif 4967236167Sdelphij 4968236167Sdelphij#ifdef ETHTOOL_GUFO 4969236167Sdelphij ret = iface_ethtool_ioctl(handle, ETHTOOL_GUFO, "ETHTOOL_GUFO"); 4970236167Sdelphij if (ret == -1) 4971236167Sdelphij return -1; 4972236167Sdelphij if (ret) 4973236167Sdelphij return 1; /* UDP fragmentation offloading on */ 4974236167Sdelphij#endif 4975236167Sdelphij 4976236167Sdelphij#ifdef ETHTOOL_GGSO 4977236167Sdelphij /* 4978236167Sdelphij * XXX - will this cause large unsegmented packets to be 4979236167Sdelphij * handed to PF_PACKET sockets on transmission? If not, 4980236167Sdelphij * this need not be checked. 4981236167Sdelphij */ 4982236167Sdelphij ret = iface_ethtool_ioctl(handle, ETHTOOL_GGSO, "ETHTOOL_GGSO"); 4983236167Sdelphij if (ret == -1) 4984236167Sdelphij return -1; 4985236167Sdelphij if (ret) 4986236167Sdelphij return 1; /* generic segmentation offloading on */ 4987236167Sdelphij#endif 4988236167Sdelphij 4989236167Sdelphij#ifdef ETHTOOL_GFLAGS 4990236167Sdelphij ret = iface_ethtool_ioctl(handle, ETHTOOL_GFLAGS, "ETHTOOL_GFLAGS"); 4991236167Sdelphij if (ret == -1) 4992236167Sdelphij return -1; 4993236167Sdelphij if (ret & ETH_FLAG_LRO) 4994236167Sdelphij return 1; /* large receive offloading on */ 4995236167Sdelphij#endif 4996236167Sdelphij 4997236167Sdelphij#ifdef ETHTOOL_GGRO 4998236167Sdelphij /* 4999236167Sdelphij * XXX - will this cause large reassembled packets to be 5000236167Sdelphij * handed to PF_PACKET sockets on receipt? If not, 5001236167Sdelphij * this need not be checked. 5002236167Sdelphij */ 5003236167Sdelphij ret = iface_ethtool_ioctl(handle, ETHTOOL_GGRO, "ETHTOOL_GGRO"); 5004236167Sdelphij if (ret == -1) 5005236167Sdelphij return -1; 5006236167Sdelphij if (ret) 5007236167Sdelphij return 1; /* generic (large) receive offloading on */ 5008236167Sdelphij#endif 5009236167Sdelphij 5010236167Sdelphij return 0; 5011236167Sdelphij} 5012236167Sdelphij#else /* SIOCETHTOOL */ 5013236167Sdelphijstatic int 5014236167Sdelphijiface_get_offload(pcap_t *handle _U_) 5015236167Sdelphij{ 5016236167Sdelphij /* 5017236167Sdelphij * XXX - do we need to get this information if we don't 5018236167Sdelphij * have the ethtool ioctls? If so, how do we do that? 5019236167Sdelphij */ 5020236167Sdelphij return 0; 5021236167Sdelphij} 5022236167Sdelphij#endif /* SIOCETHTOOL */ 5023236167Sdelphij 5024190225Srpaulo#endif /* HAVE_PF_PACKET_SOCKETS */ 5025190225Srpaulo 5026190225Srpaulo/* ===== Functions to interface to the older kernels ================== */ 5027190225Srpaulo 502875107Sfenner/* 5029190225Srpaulo * Try to open a packet socket using the old kernel interface. 5030190225Srpaulo * Returns 1 on success and a PCAP_ERROR_ value on an error. 503175107Sfenner */ 503275107Sfennerstatic int 5033190225Srpauloactivate_old(pcap_t *handle) 503475107Sfenner{ 5035127664Sbms int arptype; 503675107Sfenner struct ifreq ifr; 5037190225Srpaulo const char *device = handle->opt.source; 5038190225Srpaulo struct utsname utsname; 5039190225Srpaulo int mtu; 504075107Sfenner 5041190225Srpaulo /* Open the socket */ 504275107Sfenner 5043190225Srpaulo handle->fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL)); 5044190225Srpaulo if (handle->fd == -1) { 5045190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 5046190225Srpaulo "socket: %s", pcap_strerror(errno)); 5047236167Sdelphij if (errno == EPERM || errno == EACCES) { 5048236167Sdelphij /* 5049236167Sdelphij * You don't have permission to open the 5050236167Sdelphij * socket. 5051236167Sdelphij */ 5052236167Sdelphij return PCAP_ERROR_PERM_DENIED; 5053236167Sdelphij } else { 5054236167Sdelphij /* 5055236167Sdelphij * Other error. 5056236167Sdelphij */ 5057236167Sdelphij return PCAP_ERROR; 5058236167Sdelphij } 5059190225Srpaulo } 506075107Sfenner 5061190225Srpaulo /* It worked - we are using the old interface */ 5062190225Srpaulo handle->md.sock_packet = 1; 506375107Sfenner 5064190225Srpaulo /* ...which means we get the link-layer header. */ 5065190225Srpaulo handle->md.cooked = 0; 506675107Sfenner 5067190225Srpaulo /* Bind to the given device */ 506875107Sfenner 5069214518Srpaulo if (strcmp(device, "any") == 0) { 5070190225Srpaulo strncpy(handle->errbuf, "pcap_activate: The \"any\" device isn't supported on 2.0[.x]-kernel systems", 5071190225Srpaulo PCAP_ERRBUF_SIZE); 5072190225Srpaulo return PCAP_ERROR; 5073190225Srpaulo } 5074190225Srpaulo if (iface_bind_old(handle->fd, device, handle->errbuf) == -1) 5075190225Srpaulo return PCAP_ERROR; 507675107Sfenner 5077190225Srpaulo /* 5078190225Srpaulo * Try to get the link-layer type. 5079190225Srpaulo */ 5080190225Srpaulo arptype = iface_get_arptype(handle->fd, device, handle->errbuf); 5081190225Srpaulo if (arptype < 0) 5082190225Srpaulo return PCAP_ERROR; 5083127664Sbms 5084190225Srpaulo /* 5085190225Srpaulo * Try to find the DLT_ type corresponding to that 5086190225Srpaulo * link-layer type. 5087190225Srpaulo */ 5088190225Srpaulo map_arphrd_to_dlt(handle, arptype, 0); 5089190225Srpaulo if (handle->linktype == -1) { 5090190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 5091190225Srpaulo "unknown arptype %d", arptype); 5092190225Srpaulo return PCAP_ERROR; 5093190225Srpaulo } 5094127664Sbms 5095190225Srpaulo /* Go to promisc mode if requested */ 5096127664Sbms 5097190225Srpaulo if (handle->opt.promisc) { 5098190225Srpaulo memset(&ifr, 0, sizeof(ifr)); 5099190225Srpaulo strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 5100190225Srpaulo if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) == -1) { 5101190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 5102190225Srpaulo "SIOCGIFFLAGS: %s", pcap_strerror(errno)); 5103190225Srpaulo return PCAP_ERROR; 5104190225Srpaulo } 5105190225Srpaulo if ((ifr.ifr_flags & IFF_PROMISC) == 0) { 5106190225Srpaulo /* 5107190225Srpaulo * Promiscuous mode isn't currently on, 5108190225Srpaulo * so turn it on, and remember that 5109190225Srpaulo * we should turn it off when the 5110190225Srpaulo * pcap_t is closed. 5111190225Srpaulo */ 511275107Sfenner 5113190225Srpaulo /* 5114190225Srpaulo * If we haven't already done so, arrange 5115190225Srpaulo * to have "pcap_close_all()" called when 5116190225Srpaulo * we exit. 5117190225Srpaulo */ 5118190225Srpaulo if (!pcap_do_addexit(handle)) { 511975107Sfenner /* 5120190225Srpaulo * "atexit()" failed; don't put 5121190225Srpaulo * the interface in promiscuous 5122190225Srpaulo * mode, just give up. 512375107Sfenner */ 5124190225Srpaulo return PCAP_ERROR; 5125190225Srpaulo } 512675107Sfenner 5127190225Srpaulo ifr.ifr_flags |= IFF_PROMISC; 5128190225Srpaulo if (ioctl(handle->fd, SIOCSIFFLAGS, &ifr) == -1) { 5129190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 5130190225Srpaulo "SIOCSIFFLAGS: %s", 5131190225Srpaulo pcap_strerror(errno)); 5132190225Srpaulo return PCAP_ERROR; 5133190225Srpaulo } 5134214518Srpaulo handle->md.must_do_on_close |= MUST_CLEAR_PROMISC; 513575107Sfenner 5136190225Srpaulo /* 5137190225Srpaulo * Add this to the list of pcaps 5138190225Srpaulo * to close when we exit. 5139190225Srpaulo */ 5140190225Srpaulo pcap_add_to_pcaps_to_close(handle); 514175107Sfenner } 5142190225Srpaulo } 514375107Sfenner 5144190225Srpaulo /* 5145190225Srpaulo * Compute the buffer size. 5146190225Srpaulo * 5147190225Srpaulo * We're using SOCK_PACKET, so this might be a 2.0[.x] 5148190225Srpaulo * kernel, and might require special handling - check. 5149190225Srpaulo */ 5150190225Srpaulo if (uname(&utsname) < 0 || 5151190225Srpaulo strncmp(utsname.release, "2.0", 3) == 0) { 515298530Sfenner /* 5153190225Srpaulo * Either we couldn't find out what kernel release 5154190225Srpaulo * this is, or it's a 2.0[.x] kernel. 5155190225Srpaulo * 5156190225Srpaulo * In the 2.0[.x] kernel, a "recvfrom()" on 5157190225Srpaulo * a SOCK_PACKET socket, with MSG_TRUNC set, will 5158190225Srpaulo * return the number of bytes read, so if we pass 5159190225Srpaulo * a length based on the snapshot length, it'll 5160190225Srpaulo * return the number of bytes from the packet 5161190225Srpaulo * copied to userland, not the actual length 5162190225Srpaulo * of the packet. 5163190225Srpaulo * 5164190225Srpaulo * This means that, for example, the IP dissector 5165190225Srpaulo * in tcpdump will get handed a packet length less 5166190225Srpaulo * than the length in the IP header, and will 5167190225Srpaulo * complain about "truncated-ip". 5168190225Srpaulo * 5169190225Srpaulo * So we don't bother trying to copy from the 5170190225Srpaulo * kernel only the bytes in which we're interested, 5171190225Srpaulo * but instead copy them all, just as the older 5172190225Srpaulo * versions of libpcap for Linux did. 5173190225Srpaulo * 5174190225Srpaulo * The buffer therefore needs to be big enough to 5175190225Srpaulo * hold the largest packet we can get from this 5176190225Srpaulo * device. Unfortunately, we can't get the MRU 5177190225Srpaulo * of the network; we can only get the MTU. The 5178190225Srpaulo * MTU may be too small, in which case a packet larger 5179190225Srpaulo * than the buffer size will be truncated *and* we 5180190225Srpaulo * won't get the actual packet size. 5181190225Srpaulo * 5182190225Srpaulo * However, if the snapshot length is larger than 5183190225Srpaulo * the buffer size based on the MTU, we use the 5184190225Srpaulo * snapshot length as the buffer size, instead; 5185190225Srpaulo * this means that with a sufficiently large snapshot 5186190225Srpaulo * length we won't artificially truncate packets 5187190225Srpaulo * to the MTU-based size. 5188190225Srpaulo * 5189190225Srpaulo * This mess just one of many problems with packet 5190190225Srpaulo * capture on 2.0[.x] kernels; you really want a 5191190225Srpaulo * 2.2[.x] or later kernel if you want packet capture 5192190225Srpaulo * to work well. 519398530Sfenner */ 5194190225Srpaulo mtu = iface_get_mtu(handle->fd, device, handle->errbuf); 5195190225Srpaulo if (mtu == -1) 5196190225Srpaulo return PCAP_ERROR; 5197190225Srpaulo handle->bufsize = MAX_LINKHEADER_SIZE + mtu; 5198190225Srpaulo if (handle->bufsize < handle->snapshot) 5199190225Srpaulo handle->bufsize = handle->snapshot; 5200190225Srpaulo } else { 5201190225Srpaulo /* 5202190225Srpaulo * This is a 2.2[.x] or later kernel. 5203190225Srpaulo * 5204190225Srpaulo * We can safely pass "recvfrom()" a byte count 5205190225Srpaulo * based on the snapshot length. 5206190225Srpaulo */ 5207190225Srpaulo handle->bufsize = handle->snapshot; 5208190225Srpaulo } 520998530Sfenner 5210190225Srpaulo /* 5211190225Srpaulo * Default value for offset to align link-layer payload 5212190225Srpaulo * on a 4-byte boundary. 5213190225Srpaulo */ 5214190225Srpaulo handle->offset = 0; 521575107Sfenner 5216190225Srpaulo return 1; 521775107Sfenner} 521875107Sfenner 521975107Sfenner/* 5220127664Sbms * Bind the socket associated with FD to the given device using the 522175107Sfenner * interface of the old kernels. 522275107Sfenner */ 522375107Sfennerstatic int 522475107Sfenneriface_bind_old(int fd, const char *device, char *ebuf) 522575107Sfenner{ 522675107Sfenner struct sockaddr saddr; 5227127664Sbms int err; 5228127664Sbms socklen_t errlen = sizeof(err); 522975107Sfenner 523075107Sfenner memset(&saddr, 0, sizeof(saddr)); 523175107Sfenner strncpy(saddr.sa_data, device, sizeof(saddr.sa_data)); 523275107Sfenner if (bind(fd, &saddr, sizeof(saddr)) == -1) { 523375107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, 523475107Sfenner "bind: %s", pcap_strerror(errno)); 523575107Sfenner return -1; 523626175Sfenner } 523726175Sfenner 5238127664Sbms /* Any pending errors, e.g., network is down? */ 5239127664Sbms 5240127664Sbms if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) { 5241127664Sbms snprintf(ebuf, PCAP_ERRBUF_SIZE, 5242127664Sbms "getsockopt: %s", pcap_strerror(errno)); 5243127664Sbms return -1; 5244127664Sbms } 5245127664Sbms 5246127664Sbms if (err > 0) { 5247127664Sbms snprintf(ebuf, PCAP_ERRBUF_SIZE, 5248127664Sbms "bind: %s", pcap_strerror(err)); 5249127664Sbms return -1; 5250127664Sbms } 5251127664Sbms 525275107Sfenner return 0; 525326175Sfenner} 525426175Sfenner 525575107Sfenner 525675107Sfenner/* ===== System calls available on all supported kernels ============== */ 525775107Sfenner 525875107Sfenner/* 5259127664Sbms * Query the kernel for the MTU of the given interface. 526075107Sfenner */ 526175107Sfennerstatic int 526275107Sfenneriface_get_mtu(int fd, const char *device, char *ebuf) 526326175Sfenner{ 526475107Sfenner struct ifreq ifr; 526526175Sfenner 526675107Sfenner if (!device) 526775107Sfenner return BIGGER_THAN_ALL_MTUS; 526875107Sfenner 526975107Sfenner memset(&ifr, 0, sizeof(ifr)); 527075107Sfenner strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 527175107Sfenner 527275107Sfenner if (ioctl(fd, SIOCGIFMTU, &ifr) == -1) { 527375107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, 5274172677Smlaier "SIOCGIFMTU: %s", pcap_strerror(errno)); 527575107Sfenner return -1; 527675107Sfenner } 527775107Sfenner 527875107Sfenner return ifr.ifr_mtu; 527926175Sfenner} 528026175Sfenner 528175107Sfenner/* 528275107Sfenner * Get the hardware type of the given interface as ARPHRD_xxx constant. 528375107Sfenner */ 528475107Sfennerstatic int 528575107Sfenneriface_get_arptype(int fd, const char *device, char *ebuf) 528626175Sfenner{ 528775107Sfenner struct ifreq ifr; 528826175Sfenner 528975107Sfenner memset(&ifr, 0, sizeof(ifr)); 529075107Sfenner strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 529175107Sfenner 529275107Sfenner if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) { 529375107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, 5294172677Smlaier "SIOCGIFHWADDR: %s", pcap_strerror(errno)); 5295190225Srpaulo if (errno == ENODEV) { 5296190225Srpaulo /* 5297190225Srpaulo * No such device. 5298190225Srpaulo */ 5299190225Srpaulo return PCAP_ERROR_NO_SUCH_DEVICE; 5300190225Srpaulo } 5301190225Srpaulo return PCAP_ERROR; 530275107Sfenner } 530375107Sfenner 530475107Sfenner return ifr.ifr_hwaddr.sa_family; 530526175Sfenner} 530675107Sfenner 530798530Sfenner#ifdef SO_ATTACH_FILTER 530875107Sfennerstatic int 5309214518Srpaulofix_program(pcap_t *handle, struct sock_fprog *fcode, int is_mmapped) 531075107Sfenner{ 531175107Sfenner size_t prog_size; 531275107Sfenner register int i; 531375107Sfenner register struct bpf_insn *p; 531475107Sfenner struct bpf_insn *f; 531575107Sfenner int len; 531675107Sfenner 531775107Sfenner /* 531875107Sfenner * Make a copy of the filter, and modify that copy if 531975107Sfenner * necessary. 532075107Sfenner */ 532175107Sfenner prog_size = sizeof(*handle->fcode.bf_insns) * handle->fcode.bf_len; 532275107Sfenner len = handle->fcode.bf_len; 532375107Sfenner f = (struct bpf_insn *)malloc(prog_size); 532475107Sfenner if (f == NULL) { 5325190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 532675107Sfenner "malloc: %s", pcap_strerror(errno)); 532775107Sfenner return -1; 532875107Sfenner } 532975107Sfenner memcpy(f, handle->fcode.bf_insns, prog_size); 533075107Sfenner fcode->len = len; 533175107Sfenner fcode->filter = (struct sock_filter *) f; 533275107Sfenner 533375107Sfenner for (i = 0; i < len; ++i) { 533475107Sfenner p = &f[i]; 533575107Sfenner /* 533675107Sfenner * What type of instruction is this? 533775107Sfenner */ 533875107Sfenner switch (BPF_CLASS(p->code)) { 533975107Sfenner 534075107Sfenner case BPF_RET: 534175107Sfenner /* 5342214518Srpaulo * It's a return instruction; are we capturing 5343214518Srpaulo * in memory-mapped mode? 534475107Sfenner */ 5345214518Srpaulo if (!is_mmapped) { 534675107Sfenner /* 5347214518Srpaulo * No; is the snapshot length a constant, 5348214518Srpaulo * rather than the contents of the 5349214518Srpaulo * accumulator? 535075107Sfenner */ 5351214518Srpaulo if (BPF_MODE(p->code) == BPF_K) { 5352214518Srpaulo /* 5353214518Srpaulo * Yes - if the value to be returned, 5354214518Srpaulo * i.e. the snapshot length, is 5355214518Srpaulo * anything other than 0, make it 5356214518Srpaulo * 65535, so that the packet is 5357214518Srpaulo * truncated by "recvfrom()", 5358214518Srpaulo * not by the filter. 5359214518Srpaulo * 5360214518Srpaulo * XXX - there's nothing we can 5361214518Srpaulo * easily do if it's getting the 5362214518Srpaulo * value from the accumulator; we'd 5363214518Srpaulo * have to insert code to force 5364214518Srpaulo * non-zero values to be 65535. 5365214518Srpaulo */ 5366214518Srpaulo if (p->k != 0) 5367214518Srpaulo p->k = 65535; 5368214518Srpaulo } 536975107Sfenner } 537075107Sfenner break; 537175107Sfenner 537275107Sfenner case BPF_LD: 537375107Sfenner case BPF_LDX: 537475107Sfenner /* 537575107Sfenner * It's a load instruction; is it loading 537675107Sfenner * from the packet? 537775107Sfenner */ 537875107Sfenner switch (BPF_MODE(p->code)) { 537975107Sfenner 538075107Sfenner case BPF_ABS: 538175107Sfenner case BPF_IND: 538275107Sfenner case BPF_MSH: 538375107Sfenner /* 538475107Sfenner * Yes; are we in cooked mode? 538575107Sfenner */ 538675107Sfenner if (handle->md.cooked) { 538775107Sfenner /* 538875107Sfenner * Yes, so we need to fix this 538975107Sfenner * instruction. 539075107Sfenner */ 539175107Sfenner if (fix_offset(p) < 0) { 539275107Sfenner /* 539375107Sfenner * We failed to do so. 539475107Sfenner * Return 0, so our caller 539575107Sfenner * knows to punt to userland. 539675107Sfenner */ 539775107Sfenner return 0; 539875107Sfenner } 539975107Sfenner } 540075107Sfenner break; 540175107Sfenner } 540275107Sfenner break; 540375107Sfenner } 540475107Sfenner } 540575107Sfenner return 1; /* we succeeded */ 540675107Sfenner} 540775107Sfenner 540875107Sfennerstatic int 540975107Sfennerfix_offset(struct bpf_insn *p) 541075107Sfenner{ 541175107Sfenner /* 541275107Sfenner * What's the offset? 541375107Sfenner */ 541475107Sfenner if (p->k >= SLL_HDR_LEN) { 541575107Sfenner /* 541675107Sfenner * It's within the link-layer payload; that starts at an 541775107Sfenner * offset of 0, as far as the kernel packet filter is 541875107Sfenner * concerned, so subtract the length of the link-layer 541975107Sfenner * header. 542075107Sfenner */ 542175107Sfenner p->k -= SLL_HDR_LEN; 5422242484Sdelphij } else if (p->k == 0) { 5423242484Sdelphij /* 5424242484Sdelphij * It's the packet type field; map it to the special magic 5425242484Sdelphij * kernel offset for that field. 5426242484Sdelphij */ 5427242484Sdelphij p->k = SKF_AD_OFF + SKF_AD_PKTTYPE; 542875107Sfenner } else if (p->k == 14) { 542975107Sfenner /* 543075107Sfenner * It's the protocol field; map it to the special magic 543175107Sfenner * kernel offset for that field. 543275107Sfenner */ 543375107Sfenner p->k = SKF_AD_OFF + SKF_AD_PROTOCOL; 5434242484Sdelphij } else if ((bpf_int32)(p->k) > 0) { 543575107Sfenner /* 543675107Sfenner * It's within the header, but it's not one of those 543775107Sfenner * fields; we can't do that in the kernel, so punt 543875107Sfenner * to userland. 543975107Sfenner */ 544075107Sfenner return -1; 544175107Sfenner } 544275107Sfenner return 0; 544375107Sfenner} 544498530Sfenner 544598530Sfennerstatic int 544698530Sfennerset_kernel_filter(pcap_t *handle, struct sock_fprog *fcode) 544798530Sfenner{ 544898530Sfenner int total_filter_on = 0; 544998530Sfenner int save_mode; 545098530Sfenner int ret; 545198530Sfenner int save_errno; 545298530Sfenner 545398530Sfenner /* 545498530Sfenner * The socket filter code doesn't discard all packets queued 545598530Sfenner * up on the socket when the filter is changed; this means 545698530Sfenner * that packets that don't match the new filter may show up 545798530Sfenner * after the new filter is put onto the socket, if those 545898530Sfenner * packets haven't yet been read. 545998530Sfenner * 546098530Sfenner * This means, for example, that if you do a tcpdump capture 546198530Sfenner * with a filter, the first few packets in the capture might 546298530Sfenner * be packets that wouldn't have passed the filter. 546398530Sfenner * 546498530Sfenner * We therefore discard all packets queued up on the socket 546598530Sfenner * when setting a kernel filter. (This isn't an issue for 546698530Sfenner * userland filters, as the userland filtering is done after 546798530Sfenner * packets are queued up.) 546898530Sfenner * 546998530Sfenner * To flush those packets, we put the socket in read-only mode, 547098530Sfenner * and read packets from the socket until there are no more to 547198530Sfenner * read. 547298530Sfenner * 547398530Sfenner * In order to keep that from being an infinite loop - i.e., 547498530Sfenner * to keep more packets from arriving while we're draining 547598530Sfenner * the queue - we put the "total filter", which is a filter 547698530Sfenner * that rejects all packets, onto the socket before draining 547798530Sfenner * the queue. 547898530Sfenner * 547998530Sfenner * This code deliberately ignores any errors, so that you may 548098530Sfenner * get bogus packets if an error occurs, rather than having 548198530Sfenner * the filtering done in userland even if it could have been 548298530Sfenner * done in the kernel. 548398530Sfenner */ 5484127664Sbms if (setsockopt(handle->fd, SOL_SOCKET, SO_ATTACH_FILTER, 548598530Sfenner &total_fcode, sizeof(total_fcode)) == 0) { 548698530Sfenner char drain[1]; 548798530Sfenner 548898530Sfenner /* 548998530Sfenner * Note that we've put the total filter onto the socket. 549098530Sfenner */ 549198530Sfenner total_filter_on = 1; 549298530Sfenner 549398530Sfenner /* 549498530Sfenner * Save the socket's current mode, and put it in 549598530Sfenner * non-blocking mode; we drain it by reading packets 5496127664Sbms * until we get an error (which is normally a 549798530Sfenner * "nothing more to be read" error). 549898530Sfenner */ 549998530Sfenner save_mode = fcntl(handle->fd, F_GETFL, 0); 550098530Sfenner if (save_mode != -1 && 550198530Sfenner fcntl(handle->fd, F_SETFL, save_mode | O_NONBLOCK) >= 0) { 550298530Sfenner while (recv(handle->fd, &drain, sizeof drain, 550398530Sfenner MSG_TRUNC) >= 0) 550498530Sfenner ; 5505127664Sbms save_errno = errno; 550698530Sfenner fcntl(handle->fd, F_SETFL, save_mode); 5507127664Sbms if (save_errno != EAGAIN) { 5508127664Sbms /* Fatal error */ 5509127664Sbms reset_kernel_filter(handle); 5510190225Srpaulo snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 5511127664Sbms "recv: %s", pcap_strerror(save_errno)); 5512127664Sbms return -2; 5513127664Sbms } 551498530Sfenner } 551598530Sfenner } 551698530Sfenner 551798530Sfenner /* 551898530Sfenner * Now attach the new filter. 551998530Sfenner */ 5520127664Sbms ret = setsockopt(handle->fd, SOL_SOCKET, SO_ATTACH_FILTER, 552198530Sfenner fcode, sizeof(*fcode)); 552298530Sfenner if (ret == -1 && total_filter_on) { 552398530Sfenner /* 552498530Sfenner * Well, we couldn't set that filter on the socket, 552598530Sfenner * but we could set the total filter on the socket. 552698530Sfenner * 552798530Sfenner * This could, for example, mean that the filter was 552898530Sfenner * too big to put into the kernel, so we'll have to 552998530Sfenner * filter in userland; in any case, we'll be doing 553098530Sfenner * filtering in userland, so we need to remove the 553198530Sfenner * total filter so we see packets. 553298530Sfenner */ 553398530Sfenner save_errno = errno; 553498530Sfenner 553598530Sfenner /* 553698530Sfenner * XXX - if this fails, we're really screwed; 553798530Sfenner * we have the total filter on the socket, 553898530Sfenner * and it won't come off. What do we do then? 553998530Sfenner */ 554098530Sfenner reset_kernel_filter(handle); 554198530Sfenner 554298530Sfenner errno = save_errno; 554398530Sfenner } 5544127664Sbms return ret; 554598530Sfenner} 554698530Sfenner 554798530Sfennerstatic int 554898530Sfennerreset_kernel_filter(pcap_t *handle) 554998530Sfenner{ 5550172677Smlaier /* 5551172677Smlaier * setsockopt() barfs unless it get a dummy parameter. 5552172677Smlaier * valgrind whines unless the value is initialized, 5553172677Smlaier * as it has no idea that setsockopt() ignores its 5554172677Smlaier * parameter. 5555172677Smlaier */ 5556172677Smlaier int dummy = 0; 555798530Sfenner 555898530Sfenner return setsockopt(handle->fd, SOL_SOCKET, SO_DETACH_FILTER, 555998530Sfenner &dummy, sizeof(dummy)); 556098530Sfenner} 556175107Sfenner#endif 5562