pcap-linux.c revision 75107
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> 675107Sfenner * 775107Sfenner * License: BSD 875107Sfenner * 975107Sfenner * Redistribution and use in source and binary forms, with or without 1075107Sfenner * modification, are permitted provided that the following conditions 1175107Sfenner * are met: 1275107Sfenner * 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. 2275107Sfenner * 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. 2626175Sfenner */ 2726175Sfenner#ifndef lint 2826175Sfennerstatic const char rcsid[] = 2975107Sfenner "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.51.2.3 2001/01/18 03:59:56 guy Exp $ (LBL)"; 3026175Sfenner#endif 3126175Sfenner 3275107Sfenner/* 3375107Sfenner * Known problems with 2.0[.x] kernels: 3475107Sfenner * 3575107Sfenner * - The loopback device gives every packet twice; on 2.2[.x] kernels, 3675107Sfenner * if we use PF_PACKET, we can filter out the transmitted version 3775107Sfenner * of the packet by using data in the "sockaddr_ll" returned by 3875107Sfenner * "recvfrom()", but, on 2.0[.x] kernels, we have to use 3975107Sfenner * PF_INET/SOCK_PACKET, which means "recvfrom()" supplies a 4075107Sfenner * "sockaddr_pkt" which doesn't give us enough information to let 4175107Sfenner * us do that. 4275107Sfenner * 4375107Sfenner * - We have to set the interface's IFF_PROMISC flag ourselves, if 4475107Sfenner * we're to run in promiscuous mode, which means we have to turn 4575107Sfenner * it off ourselves when we're done; the kernel doesn't keep track 4675107Sfenner * of how many sockets are listening promiscuously, which means 4775107Sfenner * it won't get turned off automatically when no sockets are 4875107Sfenner * listening promiscuously. We catch "pcap_close()" and, for 4975107Sfenner * interfaces we put into promiscuous mode, take them out of 5075107Sfenner * promiscuous mode - which isn't necessarily the right thing to 5175107Sfenner * do, if another socket also requested promiscuous mode between 5275107Sfenner * the time when we opened the socket and the time when we close 5375107Sfenner * the socket. 5475107Sfenner */ 5526175Sfenner 5675107Sfenner 5775107Sfenner#ifdef HAVE_CONFIG_H 5875107Sfenner#include "config.h" 5939291Sfenner#endif 6026175Sfenner 6175107Sfenner#include "pcap-int.h" 6275107Sfenner#include "sll.h" 6326175Sfenner 6426175Sfenner#include <errno.h> 6526175Sfenner#include <stdlib.h> 6675107Sfenner#include <unistd.h> 6775107Sfenner#include <fcntl.h> 6826175Sfenner#include <string.h> 6975107Sfenner#include <sys/socket.h> 7075107Sfenner#include <sys/ioctl.h> 7175107Sfenner#include <sys/utsname.h> 7275107Sfenner#include <net/if.h> 7375107Sfenner#include <netinet/in.h> 7475107Sfenner#include <linux/if_ether.h> 7575107Sfenner#include <net/if_arp.h> 7626175Sfenner 7775107Sfenner#ifdef HAVE_NETPACKET_PACKET_H 7875107Sfenner# include <netpacket/packet.h> 7926175Sfenner 8075107Sfenner /* 8175107Sfenner * We assume this means we really do have PF_PACKET sockets. 8275107Sfenner */ 8375107Sfenner# define HAVE_PF_PACKET_SOCKETS 8475107Sfenner#else 8575107Sfenner /* 8675107Sfenner * Oh, joy. Some Linux distributions have 2.2 or later kernels and 8775107Sfenner * libc5. On at least one of those systems (Slackware 4.0), it 8875107Sfenner * appears that "/usr/include/sys/socket.h" includes <linux/socket.h>, 8975107Sfenner * which means it picks up all the AF_, PF_, and SO_ definitions 9075107Sfenner * appropriate for the current kernel; however, it also appears that 9175107Sfenner * they did not see fit to provide a "/usr/include/netpacket/packet.h" 9275107Sfenner * file. 9375107Sfenner * 9475107Sfenner * However, you should be able to get the right definitions by including 9575107Sfenner * <linux/if_packet.h>. 9675107Sfenner * 9775107Sfenner * So if this system has PF_PACKET defined but doesn't have the 9875107Sfenner * <netpacket/packet.h> header file, we include <linux/if_packet.h> 9975107Sfenner * instead. 10075107Sfenner */ 10175107Sfenner# ifdef PF_PACKET 10275107Sfenner# include <linux/if_packet.h> 10326175Sfenner 10475107Sfenner /* 10575107Sfenner * However, on at least some Linux distributions (for example, Red Hat 10675107Sfenner * 5.2), there's no <netpacket/packet.h> file, but PF_PACKET is defined 10775107Sfenner * if you include <sys/socket.h>, but <linux/if_packet.h> doesn't define 10875107Sfenner * any of the PF_PACKET stuff such as "struct sockaddr_ll" or any of 10975107Sfenner * the PACKET_xxx stuff. 11075107Sfenner * 11175107Sfenner * So we check whether PACKET_HOST is defined, and assume that we have 11275107Sfenner * PF_PACKET sockets only if it is defined. 11375107Sfenner */ 11475107Sfenner# ifdef PACKET_HOST 11575107Sfenner# define HAVE_PF_PACKET_SOCKETS 11675107Sfenner# endif /* PACKET_HOST */ 11775107Sfenner# endif /* PF_PACKET */ 11875107Sfenner#endif /* HAVE_NETPACKET_PACKET_H */ 11975107Sfenner 12075107Sfenner#ifdef SO_ATTACH_FILTER 12175107Sfenner#include <linux/types.h> 12275107Sfenner#include <linux/filter.h> 12326175Sfenner#endif 12426175Sfenner 12575107Sfenner#ifndef __GLIBC__ 12675107Sfennertypedef int socklen_t; 12775107Sfenner#endif 12826175Sfenner 12975107Sfenner#ifndef MSG_TRUNC 13075107Sfenner#define MSG_TRUNC 0 13175107Sfenner#endif 13275107Sfenner 13375107Sfenner#define MAX_LINKHEADER_SIZE 256 13475107Sfenner 13575107Sfenner/* 13675107Sfenner * When capturing on all interfaces we use this as the buffer size. 13775107Sfenner * Should be bigger then all MTUs that occur in real life. 13875107Sfenner * 64kB should be enough for now. 13975107Sfenner */ 14075107Sfenner#define BIGGER_THAN_ALL_MTUS (64*1024) 14175107Sfenner 14275107Sfenner/* 14375107Sfenner * Prototypes for internal functions 14475107Sfenner */ 14575107Sfennerstatic int map_arphrd_to_dlt(int arptype ); 14675107Sfennerstatic int live_open_old(pcap_t *, char *, int, int, char *); 14775107Sfennerstatic int live_open_new(pcap_t *, char *, int, int, char *); 14875107Sfennerstatic int pcap_read_packet(pcap_t *, pcap_handler, u_char *); 14975107Sfenner 15075107Sfenner/* 15175107Sfenner * Wrap some ioctl calls 15275107Sfenner */ 15375107Sfenner#ifdef HAVE_PF_PACKET_SOCKETS 15475107Sfennerstatic int iface_get_id(int fd, const char *device, char *ebuf); 15575107Sfenner#endif 15675107Sfennerstatic int iface_get_mtu(int fd, const char *device, char *ebuf); 15775107Sfennerstatic int iface_get_arptype(int fd, const char *device, char *ebuf); 15875107Sfenner#ifdef HAVE_PF_PACKET_SOCKETS 15975107Sfennerstatic int iface_bind(int fd, int ifindex, char *ebuf); 16075107Sfenner#endif 16175107Sfennerstatic int iface_bind_old(int fd, const char *device, char *ebuf); 16275107Sfenner 16375107Sfenner#ifdef SO_ATTACH_FILTER 16475107Sfennerstatic int fix_program(pcap_t *handle, struct sock_fprog *fcode); 16575107Sfennerstatic int fix_offset(struct bpf_insn *p); 16675107Sfenner#endif 16775107Sfenner 16875107Sfenner/* 16975107Sfenner * Get a handle for a live capture from the given device. You can 17075107Sfenner * pass NULL as device to get all packages (without link level 17175107Sfenner * information of course). If you pass 1 as promisc the interface 17275107Sfenner * will be set to promiscous mode (XXX: I think this usage should 17375107Sfenner * be deprecated and functions be added to select that later allow 17475107Sfenner * modification of that values -- Torsten). 17575107Sfenner * 17675107Sfenner * See also pcap(3). 17775107Sfenner */ 17875107Sfennerpcap_t * 17975107Sfennerpcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) 18026175Sfenner{ 18175107Sfenner /* Allocate a handle for this session. */ 18226175Sfenner 18375107Sfenner pcap_t *handle = malloc(sizeof(*handle)); 18475107Sfenner if (handle == NULL) { 18575107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", 18675107Sfenner pcap_strerror(errno)); 18775107Sfenner return NULL; 18875107Sfenner } 18975107Sfenner 19075107Sfenner /* Initialize some components of the pcap structure. */ 19175107Sfenner 19275107Sfenner memset(handle, 0, sizeof(*handle)); 19375107Sfenner handle->snapshot = snaplen; 19475107Sfenner handle->md.timeout = to_ms; 19575107Sfenner 19675107Sfenner /* 19775107Sfenner * NULL and "any" are special devices which give us the hint to 19875107Sfenner * monitor all devices. 19975107Sfenner */ 20075107Sfenner if (!device || strcmp(device, "any") == 0) { 20175107Sfenner device = NULL; 20275107Sfenner handle->md.device = strdup("any"); 20375107Sfenner } else 20475107Sfenner handle->md.device = strdup(device); 20575107Sfenner 20675107Sfenner if (handle->md.device == NULL) { 20775107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, "strdup: %s", 20875107Sfenner pcap_strerror(errno) ); 20975107Sfenner free(handle); 21075107Sfenner return NULL; 21175107Sfenner } 21275107Sfenner 21375107Sfenner /* 21475107Sfenner * Current Linux kernels use the protocol family PF_PACKET to 21575107Sfenner * allow direct access to all packets on the network while 21675107Sfenner * older kernels had a special socket type SOCK_PACKET to 21775107Sfenner * implement this feature. 21875107Sfenner * While this old implementation is kind of obsolete we need 21975107Sfenner * to be compatible with older kernels for a while so we are 22075107Sfenner * trying both methods with the newer method preferred. 22175107Sfenner */ 22275107Sfenner 22375107Sfenner if (! (live_open_new(handle, device, promisc, to_ms, ebuf) || 22475107Sfenner live_open_old(handle, device, promisc, to_ms, ebuf)) ) 22575107Sfenner { 22675107Sfenner /* 22775107Sfenner * Both methods to open the packet socket failed. Tidy 22875107Sfenner * up and report our failure (ebuf is expected to be 22975107Sfenner * set by the functions above). 23075107Sfenner */ 23175107Sfenner 23275107Sfenner free(handle->md.device); 23375107Sfenner free(handle); 23475107Sfenner return NULL; 23575107Sfenner } 23675107Sfenner 23775107Sfenner return handle; 23826175Sfenner} 23926175Sfenner 24075107Sfenner/* 24175107Sfenner * Read at most max_packets from the capture stream and call the callback 24275107Sfenner * for each of them. Returns the number of packets handled or -1 if an 24375107Sfenner * error occured. 24475107Sfenner */ 24526175Sfennerint 24675107Sfennerpcap_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) 24726175Sfenner{ 24875107Sfenner /* 24975107Sfenner * Currently, on Linux only one packet is delivered per read, 25075107Sfenner * so we don't loop. 25175107Sfenner */ 25275107Sfenner return pcap_read_packet(handle, callback, user); 25375107Sfenner} 25426175Sfenner 25575107Sfenner/* 25675107Sfenner * Read a packet from the socket calling the handler provided by 25775107Sfenner * the user. Returns the number of packets received or -1 if an 25875107Sfenner * error occured. 25975107Sfenner */ 26075107Sfennerstatic int 26175107Sfennerpcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata) 26275107Sfenner{ 26375107Sfenner int offset; 26475107Sfenner#ifdef HAVE_PF_PACKET_SOCKETS 26575107Sfenner struct sockaddr_ll from; 26675107Sfenner struct sll_header *hdrp; 26775107Sfenner#else 26875107Sfenner struct sockaddr from; 26975107Sfenner#endif 27075107Sfenner socklen_t fromlen; 27175107Sfenner int packet_len, caplen; 27275107Sfenner struct pcap_pkthdr pcap_header; 27326175Sfenner 27475107Sfenner#ifdef HAVE_PF_PACKET_SOCKETS 27575107Sfenner /* 27675107Sfenner * If this is a cooked device, leave extra room for a 27775107Sfenner * fake packet header. 27875107Sfenner */ 27975107Sfenner if (handle->md.cooked) 28075107Sfenner offset = SLL_HDR_LEN; 28175107Sfenner else 28275107Sfenner offset = 0; 28375107Sfenner#else 28475107Sfenner /* 28575107Sfenner * This system doesn't have PF_PACKET sockets, so it doesn't 28675107Sfenner * support cooked devices. 28775107Sfenner */ 28875107Sfenner offset = 0; 28975107Sfenner#endif 29075107Sfenner 29175107Sfenner /* Receive a single packet from the kernel */ 29275107Sfenner 29326175Sfenner do { 29426175Sfenner fromlen = sizeof(from); 29575107Sfenner packet_len = recvfrom( 29675107Sfenner handle->fd, handle->buffer + offset + handle->offset, 29775107Sfenner handle->md.readlen - offset, MSG_TRUNC, 29875107Sfenner (struct sockaddr *) &from, &fromlen); 29975107Sfenner } while (packet_len == -1 && errno == EINTR); 30026175Sfenner 30175107Sfenner /* Check if an error occured */ 30226175Sfenner 30375107Sfenner if (packet_len == -1) { 30475107Sfenner if (errno == EAGAIN) 30575107Sfenner return 0; /* no packet there */ 30675107Sfenner else { 30775107Sfenner snprintf(handle->errbuf, sizeof(handle->errbuf), 30875107Sfenner "recvfrom: %s", pcap_strerror(errno)); 30975107Sfenner return -1; 31026175Sfenner } 31175107Sfenner } 31226175Sfenner 31375107Sfenner#ifdef HAVE_PF_PACKET_SOCKETS 31475107Sfenner /* 31575107Sfenner * If this is from the loopback device, reject outgoing packets; 31675107Sfenner * we'll see the packet as an incoming packet as well, and 31775107Sfenner * we don't want to see it twice. 31875107Sfenner * 31975107Sfenner * We can only do this if we're using PF_PACKET; the address 32075107Sfenner * returned for SOCK_PACKET is a "sockaddr_pkt" which lacks 32175107Sfenner * the relevant packet type information. 32275107Sfenner */ 32375107Sfenner if (!handle->md.sock_packet && 32475107Sfenner from.sll_ifindex == handle->md.lo_ifindex && 32575107Sfenner from.sll_pkttype == PACKET_OUTGOING) 32675107Sfenner return 0; 32775107Sfenner#endif 32826175Sfenner 32975107Sfenner#ifdef HAVE_PF_PACKET_SOCKETS 33075107Sfenner /* 33175107Sfenner * If this is a cooked device, fill in the fake packet header. 33275107Sfenner */ 33375107Sfenner if (handle->md.cooked) { 33475107Sfenner /* 33575107Sfenner * Add the length of the fake header to the length 33675107Sfenner * of packet data we read. 33775107Sfenner */ 33875107Sfenner packet_len += SLL_HDR_LEN; 33926175Sfenner 34075107Sfenner hdrp = (struct sll_header *)handle->buffer; 34126175Sfenner 34275107Sfenner /* 34375107Sfenner * Map the PACKET_ value to a LINUX_SLL_ value; we 34475107Sfenner * want the same numerical value to be used in 34575107Sfenner * the link-layer header even if the numerical values 34675107Sfenner * for the PACKET_ #defines change, so that programs 34775107Sfenner * that look at the packet type field will always be 34875107Sfenner * able to handle DLT_LINUX_SLL captures. 34975107Sfenner */ 35075107Sfenner switch (from.sll_pkttype) { 35126175Sfenner 35275107Sfenner case PACKET_HOST: 35375107Sfenner hdrp->sll_pkttype = htons(LINUX_SLL_HOST); 35475107Sfenner break; 35526175Sfenner 35675107Sfenner case PACKET_BROADCAST: 35775107Sfenner hdrp->sll_pkttype = htons(LINUX_SLL_BROADCAST); 35875107Sfenner break; 35975107Sfenner 36075107Sfenner case PACKET_MULTICAST: 36175107Sfenner hdrp->sll_pkttype = htons(LINUX_SLL_MULTICAST); 36275107Sfenner break; 36375107Sfenner 36475107Sfenner case PACKET_OTHERHOST: 36575107Sfenner hdrp->sll_pkttype = htons(LINUX_SLL_OTHERHOST); 36675107Sfenner break; 36775107Sfenner 36875107Sfenner case PACKET_OUTGOING: 36975107Sfenner hdrp->sll_pkttype = htons(LINUX_SLL_OUTGOING); 37075107Sfenner break; 37175107Sfenner 37275107Sfenner default: 37375107Sfenner hdrp->sll_pkttype = -1; 37475107Sfenner break; 37526175Sfenner } 37675107Sfenner 37775107Sfenner hdrp->sll_hatype = htons(from.sll_hatype); 37875107Sfenner hdrp->sll_halen = htons(from.sll_halen); 37975107Sfenner memcpy(hdrp->sll_addr, from.sll_addr, 38075107Sfenner (from.sll_halen > SLL_ADDRLEN) ? 38175107Sfenner SLL_ADDRLEN : 38275107Sfenner from.sll_halen); 38375107Sfenner hdrp->sll_protocol = from.sll_protocol; 38426175Sfenner } 38575107Sfenner#endif 38675107Sfenner 38775107Sfenner /* 38875107Sfenner * XXX: According to the kernel source we should get the real 38975107Sfenner * packet len if calling recvfrom with MSG_TRUNC set. It does 39075107Sfenner * not seem to work here :(, but it is supported by this code 39175107Sfenner * anyway. 39275107Sfenner * To be honest the code RELIES on that feature so this is really 39375107Sfenner * broken with 2.2.x kernels. 39475107Sfenner * I spend a day to figure out what's going on and I found out 39575107Sfenner * that the following is happening: 39675107Sfenner * 39775107Sfenner * The packet comes from a random interface and the packet_rcv 39875107Sfenner * hook is called with a clone of the packet. That code inserts 39975107Sfenner * the packet into the receive queue of the packet socket. 40075107Sfenner * If a filter is attached to that socket that filter is run 40175107Sfenner * first - and there lies the problem. The default filter always 40275107Sfenner * cuts the packet at the snaplen: 40375107Sfenner * 40475107Sfenner * # tcpdump -d 40575107Sfenner * (000) ret #68 40675107Sfenner * 40775107Sfenner * So the packet filter cuts down the packet. The recvfrom call 40875107Sfenner * says "hey, it's only 68 bytes, it fits into the buffer" with 40975107Sfenner * the result that we don't get the real packet length. This 41075107Sfenner * is valid at least until kernel 2.2.17pre6. 41175107Sfenner * 41275107Sfenner * We currently handle this by making a copy of the filter 41375107Sfenner * program, fixing all "ret" instructions with non-zero 41475107Sfenner * operands to have an operand of 65535 so that the filter 41575107Sfenner * doesn't truncate the packet, and supplying that modified 41675107Sfenner * filter to the kernel. 41775107Sfenner */ 41875107Sfenner 41975107Sfenner caplen = packet_len; 42075107Sfenner if (caplen > handle->snapshot) 42175107Sfenner caplen = handle->snapshot; 42275107Sfenner 42375107Sfenner /* Run the packet filter if not using kernel filter */ 42475107Sfenner if (!handle->md.use_bpf && handle->fcode.bf_insns) { 42575107Sfenner if (bpf_filter(handle->fcode.bf_insns, handle->buffer, 42675107Sfenner packet_len, caplen) == 0) 42775107Sfenner { 42875107Sfenner /* rejected by filter */ 42975107Sfenner return 0; 43075107Sfenner } 43175107Sfenner } 43275107Sfenner 43375107Sfenner /* Fill in our own header data */ 43475107Sfenner 43575107Sfenner if (ioctl(handle->fd, SIOCGSTAMP, &pcap_header.ts) == -1) { 43675107Sfenner snprintf(handle->errbuf, sizeof(handle->errbuf), 43775107Sfenner "ioctl: %s", pcap_strerror(errno)); 43875107Sfenner return -1; 43975107Sfenner } 44075107Sfenner pcap_header.caplen = caplen; 44175107Sfenner pcap_header.len = packet_len; 44275107Sfenner 44375107Sfenner /* Call the user supplied callback function */ 44475107Sfenner handle->md.stat.ps_recv++; 44575107Sfenner callback(userdata, &pcap_header, handle->buffer + handle->offset); 44675107Sfenner 44775107Sfenner return 1; 44826175Sfenner} 44926175Sfenner 45075107Sfenner/* 45175107Sfenner * Get the statistics for the given packet capture handle. 45275107Sfenner * FIXME: Currently does not report the number of dropped packets. 45375107Sfenner */ 45475107Sfennerint 45575107Sfennerpcap_stats(pcap_t *handle, struct pcap_stat *stats) 45626175Sfenner{ 45775107Sfenner *stats = handle->md.stat; 45875107Sfenner return 0; 45975107Sfenner} 46026175Sfenner 46175107Sfenner/* 46275107Sfenner * Attach the given BPF code to the packet capture device. 46375107Sfenner */ 46475107Sfennerint 46575107Sfennerpcap_setfilter(pcap_t *handle, struct bpf_program *filter) 46675107Sfenner{ 46775107Sfenner#ifdef SO_ATTACH_FILTER 46875107Sfenner struct sock_fprog fcode; 46975107Sfenner int can_filter_in_kernel; 47075107Sfenner#endif 47175107Sfenner 47275107Sfenner if (!handle) 47375107Sfenner return -1; 47475107Sfenner if (!filter) { 47575107Sfenner strncpy(handle->errbuf, "setfilter: No filter specified", 47675107Sfenner sizeof(handle->errbuf)); 47775107Sfenner return -1; 47826175Sfenner } 47926175Sfenner 48075107Sfenner /* Make our private copy of the filter */ 48175107Sfenner 48275107Sfenner if (install_bpf_program(handle, filter) < 0) { 48375107Sfenner snprintf(handle->errbuf, sizeof(handle->errbuf), 48475107Sfenner "malloc: %s", pcap_strerror(errno)); 48575107Sfenner return -1; 48639291Sfenner } 48739291Sfenner 48875107Sfenner /* 48975107Sfenner * Run user level packet filter by default. Will be overriden if 49075107Sfenner * installing a kernel filter succeeds. 49175107Sfenner */ 49275107Sfenner handle->md.use_bpf = 0; 49375107Sfenner 49475107Sfenner /* 49575107Sfenner * If we're reading from a savefile, don't try to install 49675107Sfenner * a kernel filter. 49775107Sfenner */ 49875107Sfenner if (handle->sf.rfile != NULL) 49975107Sfenner return 0; 50075107Sfenner 50175107Sfenner /* Install kernel level filter if possible */ 50275107Sfenner 50375107Sfenner#ifdef SO_ATTACH_FILTER 50475107Sfenner#ifdef USHRT_MAX 50575107Sfenner if (handle->fcode.bf_len > USHRT_MAX) { 50675107Sfenner /* 50775107Sfenner * fcode.len is an unsigned short for current kernel. 50875107Sfenner * I have yet to see BPF-Code with that much 50975107Sfenner * instructions but still it is possible. So for the 51075107Sfenner * sake of correctness I added this check. 51175107Sfenner */ 51275107Sfenner fprintf(stderr, "Warning: Filter too complex for kernel\n"); 51375107Sfenner fcode.filter = NULL; 51475107Sfenner can_filter_in_kernel = 0; 51575107Sfenner } else 51675107Sfenner#endif /* USHRT_MAX */ 51775107Sfenner { 51875107Sfenner /* 51975107Sfenner * Oh joy, the Linux kernel uses struct sock_fprog instead 52075107Sfenner * of struct bpf_program and of course the length field is 52175107Sfenner * of different size. Pointed out by Sebastian 52275107Sfenner * 52375107Sfenner * Oh, and we also need to fix it up so that all "ret" 52475107Sfenner * instructions with non-zero operands have 65535 as the 52575107Sfenner * operand, and so that, if we're in cooked mode, all 52675107Sfenner * memory-reference instructions use special magic offsets 52775107Sfenner * in references to the link-layer header and assume that 52875107Sfenner * the link-layer payload begins at 0; "fix_program()" 52975107Sfenner * will do that. 53075107Sfenner */ 53175107Sfenner switch (fix_program(handle, &fcode)) { 53275107Sfenner 53375107Sfenner case -1: 53475107Sfenner default: 53575107Sfenner /* 53675107Sfenner * Fatal error; just quit. 53775107Sfenner * (The "default" case shouldn't happen; we 53875107Sfenner * return -1 for that reason.) 53975107Sfenner */ 54075107Sfenner return -1; 54175107Sfenner 54275107Sfenner case 0: 54375107Sfenner /* 54475107Sfenner * The program performed checks that we can't make 54575107Sfenner * work in the kernel. 54675107Sfenner */ 54775107Sfenner can_filter_in_kernel = 0; 54875107Sfenner break; 54975107Sfenner 55075107Sfenner case 1: 55175107Sfenner /* 55275107Sfenner * We have a filter that'll work in the kernel. 55375107Sfenner */ 55475107Sfenner can_filter_in_kernel = 1; 55575107Sfenner break; 55675107Sfenner } 55739291Sfenner } 55839291Sfenner 55975107Sfenner if (can_filter_in_kernel) { 56075107Sfenner if (setsockopt(handle->fd, SOL_SOCKET, SO_ATTACH_FILTER, 56175107Sfenner &fcode, sizeof(fcode)) == 0) 56275107Sfenner { 56375107Sfenner /* Installation succeded - using kernel filter. */ 56475107Sfenner handle->md.use_bpf = 1; 56575107Sfenner } 56675107Sfenner else 56775107Sfenner { 56875107Sfenner /* 56975107Sfenner * Print a warning if we weren't able to install 57075107Sfenner * the filter for a reason other than "this kernel 57175107Sfenner * isn't configured to support socket filters. 57275107Sfenner */ 57375107Sfenner if (errno != ENOPROTOOPT && errno != EOPNOTSUPP) { 57475107Sfenner fprintf(stderr, 57575107Sfenner "Warning: Kernel filter failed: %s\n", 57675107Sfenner pcap_strerror(errno)); 57775107Sfenner } 57875107Sfenner } 57939291Sfenner } 58039291Sfenner 58175107Sfenner /* 58275107Sfenner * Free up the copy of the filter that was made by "fix_program()". 58375107Sfenner */ 58475107Sfenner if (fcode.filter != NULL) 58575107Sfenner free(fcode.filter); 58675107Sfenner#endif /* SO_ATTACH_FILTER */ 58775107Sfenner 58875107Sfenner return 0; 58975107Sfenner} 59075107Sfenner 59175107Sfenner/* 59275107Sfenner * Linux uses the ARP hardware type to identify the type of an 59375107Sfenner * interface. pcap uses the DLT_xxx constants for this. This 59475107Sfenner * function maps the ARPHRD_xxx constant to an appropriate 59575107Sfenner * DLT_xxx constant. 59675107Sfenner * 59775107Sfenner * Returns -1 if unable to map the type; we print a message and, 59875107Sfenner * if we're using PF_PACKET/SOCK_RAW rather than PF_INET/SOCK_PACKET, 59975107Sfenner * we fall back on using PF_PACKET/SOCK_DGRAM. 60075107Sfenner */ 60175107Sfennerstatic int map_arphrd_to_dlt(int arptype) 60275107Sfenner{ 60375107Sfenner switch (arptype) { 60439291Sfenner case ARPHRD_ETHER: 60539291Sfenner case ARPHRD_METRICOM: 60675107Sfenner case ARPHRD_LOOPBACK: return DLT_EN10MB; 60775107Sfenner case ARPHRD_EETHER: return DLT_EN3MB; 60875107Sfenner case ARPHRD_AX25: return DLT_AX25; 60975107Sfenner case ARPHRD_PRONET: return DLT_PRONET; 61075107Sfenner case ARPHRD_CHAOS: return DLT_CHAOS; 61175107Sfenner#ifndef ARPHRD_IEEE802_TR 61275107Sfenner#define ARPHRD_IEEE802_TR 800 /* From Linux 2.4 */ 61375107Sfenner#endif 61475107Sfenner case ARPHRD_IEEE802_TR: 61575107Sfenner case ARPHRD_IEEE802: return DLT_IEEE802; 61675107Sfenner case ARPHRD_ARCNET: return DLT_ARCNET; 61775107Sfenner case ARPHRD_FDDI: return DLT_FDDI; 61839291Sfenner 61975107Sfenner#ifndef ARPHRD_ATM /* FIXME: How to #include this? */ 62075107Sfenner#define ARPHRD_ATM 19 62175107Sfenner#endif 62275107Sfenner case ARPHRD_ATM: return DLT_ATM_CLIP; 62339291Sfenner 62475107Sfenner case ARPHRD_PPP: 62575107Sfenner /* Not sure if this is correct for all tunnels, but it 62675107Sfenner * works for CIPE */ 62775107Sfenner case ARPHRD_TUNNEL: 62875107Sfenner#ifndef ARPHRD_SIT 62975107Sfenner#define ARPHRD_SIT 776 /* From Linux 2.2.14 */ 63075107Sfenner#endif 63175107Sfenner case ARPHRD_SIT: 63275107Sfenner case ARPHRD_CSLIP: 63375107Sfenner case ARPHRD_SLIP6: 63475107Sfenner case ARPHRD_CSLIP6: 63575107Sfenner case ARPHRD_SLIP: return DLT_RAW; 63675107Sfenner } 63739291Sfenner 63875107Sfenner return -1; 63975107Sfenner} 64039291Sfenner 64175107Sfenner/* ===== Functions to interface to the newer kernels ================== */ 64239291Sfenner 64375107Sfenner/* 64475107Sfenner * Try to open a packet socket using the new kernel interface. 64575107Sfenner * Returns 0 on failure. 64675107Sfenner * FIXME: 0 uses to mean success (Sebastian) 64775107Sfenner */ 64875107Sfennerstatic int 64975107Sfennerlive_open_new(pcap_t *handle, char *device, int promisc, 65075107Sfenner int to_ms, char *ebuf) 65175107Sfenner{ 65275107Sfenner#ifdef HAVE_PF_PACKET_SOCKETS 65375107Sfenner int sock_fd = -1, device_id, mtu, arptype; 65475107Sfenner struct packet_mreq mr; 65539291Sfenner 65675107Sfenner /* One shot loop used for error handling - bail out with break */ 65739291Sfenner 65875107Sfenner do { 65975107Sfenner /* 66075107Sfenner * Open a socket with protocol family packet. If a device is 66175107Sfenner * given we try to open it in raw mode otherwise we use 66275107Sfenner * the cooked interface. 66375107Sfenner */ 66475107Sfenner sock_fd = device ? 66575107Sfenner socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) 66675107Sfenner : socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)); 66739291Sfenner 66875107Sfenner if (sock_fd == -1) { 66975107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, "socket: %s", 67075107Sfenner pcap_strerror(errno) ); 67175107Sfenner break; 67275107Sfenner } 67339291Sfenner 67475107Sfenner /* It seems the kernel supports the new interface. */ 67575107Sfenner handle->md.sock_packet = 0; 67675107Sfenner 67775107Sfenner /* 67875107Sfenner * Get the interface index of the loopback device. 67975107Sfenner * If the attempt fails, don't fail, just set the 68075107Sfenner * "md.lo_ifindex" to -1. 68175107Sfenner * 68275107Sfenner * XXX - can there be more than one device that loops 68375107Sfenner * packets back, i.e. devices other than "lo"? If so, 68475107Sfenner * we'd need to find them all, and have an array of 68575107Sfenner * indices for them, and check all of them in 68675107Sfenner * "pcap_read_packet()". 68775107Sfenner */ 68875107Sfenner handle->md.lo_ifindex = iface_get_id(sock_fd, "lo", ebuf); 68975107Sfenner 69075107Sfenner /* 69175107Sfenner * What kind of frames do we have to deal with? Fall back 69275107Sfenner * to cooked mode if we have an unknown interface type. 69375107Sfenner */ 69475107Sfenner 69575107Sfenner if (device) { 69675107Sfenner /* Assume for now we don't need cooked mode. */ 69775107Sfenner handle->md.cooked = 0; 69875107Sfenner 69975107Sfenner arptype = iface_get_arptype(sock_fd, device, ebuf); 70075107Sfenner if (arptype == -1) 70175107Sfenner break; 70275107Sfenner handle->linktype = map_arphrd_to_dlt(arptype); 70375107Sfenner if (handle->linktype == -1 || 70475107Sfenner (handle->linktype == DLT_EN10MB && 70575107Sfenner (strncmp("isdn", device, 4) == 0 || 70675107Sfenner strncmp("isdY", device, 4) == 0)) || 70775107Sfenner (handle->linktype == DLT_RAW && 70875107Sfenner (strncmp("ippp", device, 4) == 0))) { 70975107Sfenner /* 71075107Sfenner * Unknown interface type (-1), or an ISDN 71175107Sfenner * device (whose link-layer type we 71275107Sfenner * can only determine by using APIs 71375107Sfenner * that may be different on different 71475107Sfenner * kernels) - reopen in cooked mode. 71575107Sfenner * 71675107Sfenner * XXX - do that with DLT_RAW as well? 71775107Sfenner */ 71875107Sfenner if (close(sock_fd) == -1) { 71975107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, 72075107Sfenner "close: %s", pcap_strerror(errno)); 72175107Sfenner break; 72275107Sfenner } 72375107Sfenner sock_fd = socket(PF_PACKET, SOCK_DGRAM, 72475107Sfenner htons(ETH_P_ALL)); 72575107Sfenner if (sock_fd == -1) { 72675107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, 72775107Sfenner "socket: %s", pcap_strerror(errno)); 72875107Sfenner break; 72975107Sfenner } 73075107Sfenner handle->md.cooked = 1; 73175107Sfenner 73275107Sfenner if (handle->linktype == -1) { 73375107Sfenner /* 73475107Sfenner * Warn that we're falling back on 73575107Sfenner * cooked mode; we may want to 73675107Sfenner * update "map_arphrd_to_dlt()" 73775107Sfenner * to handle the new type. 73875107Sfenner */ 73975107Sfenner fprintf(stderr, 74075107Sfenner "Warning: arptype %d not " 74175107Sfenner "supported by libpcap - " 74275107Sfenner "falling back to cooked " 74375107Sfenner "socket\n", 74475107Sfenner arptype); 74575107Sfenner } 74675107Sfenner handle->linktype = DLT_LINUX_SLL; 74775107Sfenner } 74875107Sfenner 74975107Sfenner device_id = iface_get_id(sock_fd, device, ebuf); 75075107Sfenner if (device_id == -1) 75175107Sfenner break; 75275107Sfenner 75375107Sfenner if (iface_bind(sock_fd, device_id, ebuf) == -1) 75475107Sfenner break; 75575107Sfenner } else { 75675107Sfenner /* 75775107Sfenner * This is cooked mode. 75875107Sfenner */ 75975107Sfenner handle->md.cooked = 1; 76075107Sfenner handle->linktype = DLT_LINUX_SLL; 76175107Sfenner 76275107Sfenner /* 76375107Sfenner * XXX - squelch GCC complaints about 76475107Sfenner * uninitialized variables; if we can't 76575107Sfenner * select promiscuous mode on all interfaces, 76675107Sfenner * we should move the code below into the 76775107Sfenner * "if (device)" branch of the "if" and 76875107Sfenner * get rid of the next statement. 76975107Sfenner */ 77075107Sfenner device_id = -1; 77175107Sfenner } 77275107Sfenner 77375107Sfenner /* Select promiscuous mode on/off */ 77475107Sfenner 77575107Sfenner#ifdef SOL_PACKET 77675107Sfenner /* 77775107Sfenner * Hmm, how can we set promiscuous mode on all interfaces? 77875107Sfenner * I am not sure if that is possible at all. 77975107Sfenner */ 78075107Sfenner 78175107Sfenner if (device) { 78275107Sfenner memset(&mr, 0, sizeof(mr)); 78375107Sfenner mr.mr_ifindex = device_id; 78475107Sfenner mr.mr_type = promisc ? 78575107Sfenner PACKET_MR_PROMISC : PACKET_MR_ALLMULTI; 78675107Sfenner if (setsockopt(sock_fd, SOL_PACKET, 78775107Sfenner PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) == -1) 78875107Sfenner { 78975107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, 79075107Sfenner "setsockopt: %s", pcap_strerror(errno)); 79175107Sfenner break; 79275107Sfenner } 79375107Sfenner } 79439291Sfenner#endif 79539291Sfenner 79675107Sfenner /* Compute the buffersize */ 79775107Sfenner 79875107Sfenner mtu = iface_get_mtu(sock_fd, device, ebuf); 79975107Sfenner if (mtu == -1) 80075107Sfenner break; 80175107Sfenner handle->bufsize = MAX_LINKHEADER_SIZE + mtu; 80275107Sfenner 80375107Sfenner /* Fill in the pcap structure */ 80475107Sfenner 80575107Sfenner handle->fd = sock_fd; 80675107Sfenner handle->offset = 0; 80775107Sfenner 80875107Sfenner handle->buffer = malloc(handle->bufsize); 80975107Sfenner if (!handle->buffer) { 81075107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, 81175107Sfenner "malloc: %s", pcap_strerror(errno)); 81275107Sfenner break; 81375107Sfenner } 81475107Sfenner 81575107Sfenner /* 81675107Sfenner * This is a 2.2 or later kernel, as it has PF_PACKET; 81775107Sfenner * "recvfrom()", when passed the MSG_TRUNC flag, will 81875107Sfenner * return the actual length of the packet, not the 81975107Sfenner * number of bytes from the packet copied to userland, 82075107Sfenner * so we can safely pass it a byte count based on the 82175107Sfenner * snapshot length. 82275107Sfenner */ 82375107Sfenner handle->md.readlen = handle->snapshot; 82475107Sfenner return 1; 82575107Sfenner 82675107Sfenner } while(0); 82775107Sfenner 82875107Sfenner if (sock_fd != -1) 82975107Sfenner close(sock_fd); 83075107Sfenner return 0; 83175107Sfenner#else 83275107Sfenner strncpy(ebuf, 83375107Sfenner "New packet capturing interface not supported by build " 83475107Sfenner "environment", PCAP_ERRBUF_SIZE); 83575107Sfenner return 0; 83639291Sfenner#endif 83775107Sfenner} 83839291Sfenner 83975107Sfenner#ifdef HAVE_PF_PACKET_SOCKETS 84075107Sfenner/* 84175107Sfenner * Return the index of the given device name. Fill ebuf and return 84275107Sfenner * -1 on failure. 84375107Sfenner */ 84475107Sfennerstatic int 84575107Sfenneriface_get_id(int fd, const char *device, char *ebuf) 84675107Sfenner{ 84775107Sfenner struct ifreq ifr; 84826175Sfenner 84939291Sfenner memset(&ifr, 0, sizeof(ifr)); 85039291Sfenner strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 85175107Sfenner 85275107Sfenner if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) { 85375107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, 85475107Sfenner "ioctl: %s", pcap_strerror(errno)); 85575107Sfenner return -1; 85626175Sfenner } 85726175Sfenner 85875107Sfenner return ifr.ifr_ifindex; 85975107Sfenner} 86026175Sfenner 86175107Sfenner/* 86275107Sfenner * Bind the socket associated with FD to the given device. 86375107Sfenner */ 86475107Sfennerstatic int 86575107Sfenneriface_bind(int fd, int ifindex, char *ebuf) 86675107Sfenner{ 86775107Sfenner struct sockaddr_ll sll; 86875107Sfenner 86975107Sfenner memset(&sll, 0, sizeof(sll)); 87075107Sfenner sll.sll_family = AF_PACKET; 87175107Sfenner sll.sll_ifindex = ifindex; 87275107Sfenner sll.sll_protocol = htons(ETH_P_ALL); 87375107Sfenner 87475107Sfenner if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) == -1) { 87575107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, 87675107Sfenner "bind: %s", pcap_strerror(errno)); 87775107Sfenner return -1; 87826175Sfenner } 87926175Sfenner 88075107Sfenner return 0; 88175107Sfenner} 88275107Sfenner 88375107Sfenner#endif 88475107Sfenner 88575107Sfenner 88675107Sfenner/* ===== Functions to interface to the older kernels ================== */ 88775107Sfenner 88875107Sfenner/* 88975107Sfenner * With older kernels promiscuous mode is kind of interesting because we 89075107Sfenner * have to reset the interface before exiting. The problem can't really 89175107Sfenner * be solved without some daemon taking care of managing usage counts. 89275107Sfenner * If we put the interface into promiscuous mode, we set a flag indicating 89375107Sfenner * that we must take it out of that mode when the interface is closed, 89475107Sfenner * and, when closing the interface, if that flag is set we take it out 89575107Sfenner * of promiscuous mode. 89675107Sfenner */ 89775107Sfenner 89875107Sfenner/* 89975107Sfenner * List of pcaps for which we turned promiscuous mode on by hand. 90075107Sfenner * If there are any such pcaps, we arrange to call "pcap_close_all()" 90175107Sfenner * when we exit, and have it close all of them to turn promiscuous mode 90275107Sfenner * off. 90375107Sfenner */ 90475107Sfennerstatic struct pcap *pcaps_to_close; 90575107Sfenner 90675107Sfenner/* 90775107Sfenner * TRUE if we've already called "atexit()" to cause "pcap_close_all()" to 90875107Sfenner * be called on exit. 90975107Sfenner */ 91075107Sfennerstatic int did_atexit; 91175107Sfenner 91275107Sfennerstatic void pcap_close_all(void) 91375107Sfenner{ 91475107Sfenner struct pcap *handle; 91575107Sfenner 91675107Sfenner while ((handle = pcaps_to_close) != NULL) 91775107Sfenner pcap_close(handle); 91875107Sfenner} 91975107Sfenner 92075107Sfennervoid pcap_close_linux( pcap_t *handle ) 92175107Sfenner{ 92275107Sfenner struct pcap *p, *prevp; 92375107Sfenner struct ifreq ifr; 92475107Sfenner 92575107Sfenner if (handle->md.clear_promisc) { 92675107Sfenner /* 92775107Sfenner * We put the interface into promiscuous mode; take 92875107Sfenner * it out of promiscuous mode. 92975107Sfenner * 93075107Sfenner * XXX - if somebody else wants it in promiscuous mode, 93175107Sfenner * this code cannot know that, so it'll take it out 93275107Sfenner * of promiscuous mode. That's not fixable in 2.0[.x] 93375107Sfenner * kernels. 93475107Sfenner */ 93526175Sfenner memset(&ifr, 0, sizeof(ifr)); 93675107Sfenner strncpy(ifr.ifr_name, handle->md.device, sizeof(ifr.ifr_name)); 93775107Sfenner if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) == -1) { 93875107Sfenner fprintf(stderr, 93975107Sfenner "Can't restore interface flags (SIOCGIFFLAGS failed: %s).\n" 94075107Sfenner "Please adjust manually.\n" 94175107Sfenner "Hint: This can't happen with Linux >= 2.2.0.\n", 94275107Sfenner strerror(errno)); 94375107Sfenner } else { 94475107Sfenner if (ifr.ifr_flags & IFF_PROMISC) { 94575107Sfenner /* 94675107Sfenner * Promiscuous mode is currently on; turn it 94775107Sfenner * off. 94875107Sfenner */ 94975107Sfenner ifr.ifr_flags &= ~IFF_PROMISC; 95075107Sfenner if (ioctl(handle->fd, SIOCSIFFLAGS, &ifr) == -1) { 95175107Sfenner fprintf(stderr, 95275107Sfenner "Can't restore interface flags (SIOCSIFFLAGS failed: %s).\n" 95375107Sfenner "Please adjust manually.\n" 95475107Sfenner "Hint: This can't happen with Linux >= 2.2.0.\n", 95575107Sfenner strerror(errno)); 95675107Sfenner } 95775107Sfenner } 95826175Sfenner } 95975107Sfenner 96075107Sfenner /* 96175107Sfenner * Take this pcap out of the list of pcaps for which we 96275107Sfenner * have to take the interface out of promiscuous mode. 96375107Sfenner */ 96475107Sfenner for (p = pcaps_to_close, prevp = NULL; p != NULL; 96575107Sfenner prevp = p, p = p->md.next) { 96675107Sfenner if (p == handle) { 96775107Sfenner /* 96875107Sfenner * Found it. Remove it from the list. 96975107Sfenner */ 97075107Sfenner if (prevp == NULL) { 97175107Sfenner /* 97275107Sfenner * It was at the head of the list. 97375107Sfenner */ 97475107Sfenner pcaps_to_close = p->md.next; 97575107Sfenner } else { 97675107Sfenner /* 97775107Sfenner * It was in the middle of the list. 97875107Sfenner */ 97975107Sfenner prevp->md.next = p->md.next; 98075107Sfenner } 98175107Sfenner break; 98275107Sfenner } 98326175Sfenner } 98426175Sfenner } 98575107Sfenner if (handle->md.device != NULL) 98675107Sfenner free(handle->md.device); 98775107Sfenner} 98826175Sfenner 98975107Sfenner/* 99075107Sfenner * Try to open a packet socket using the old kernel interface. 99175107Sfenner * Returns 0 on failure. 99275107Sfenner * FIXME: 0 uses to mean success (Sebastian) 99375107Sfenner */ 99475107Sfennerstatic int 99575107Sfennerlive_open_old(pcap_t *handle, char *device, int promisc, 99675107Sfenner int to_ms, char *ebuf) 99775107Sfenner{ 99875107Sfenner int sock_fd = -1, mtu, arptype; 99975107Sfenner struct utsname utsname; 100075107Sfenner struct ifreq ifr; 100175107Sfenner 100275107Sfenner do { 100375107Sfenner /* Open the socket */ 100475107Sfenner 100575107Sfenner sock_fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL)); 100675107Sfenner if (sock_fd == -1) { 100775107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, 100875107Sfenner "socket: %s", pcap_strerror(errno)); 100975107Sfenner break; 101075107Sfenner } 101175107Sfenner 101275107Sfenner /* It worked - we are using the old interface */ 101375107Sfenner handle->md.sock_packet = 1; 101475107Sfenner 101575107Sfenner /* ...which means we get the link-layer header. */ 101675107Sfenner handle->md.cooked = 0; 101775107Sfenner 101875107Sfenner /* Bind to the given device */ 101975107Sfenner 102075107Sfenner if (!device) { 102175107Sfenner strncpy(ebuf, "pcap_open_live: The \"any\" device isn't supported on 2.0[.x]-kernel systems", 102275107Sfenner PCAP_ERRBUF_SIZE); 102375107Sfenner break; 102475107Sfenner } 102575107Sfenner if (iface_bind_old(sock_fd, device, ebuf) == -1) 102675107Sfenner break; 102775107Sfenner 102875107Sfenner /* Go to promisc mode */ 102975107Sfenner if (promisc) { 103075107Sfenner memset(&ifr, 0, sizeof(ifr)); 103175107Sfenner strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 103275107Sfenner if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) == -1) { 103375107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, 103475107Sfenner "ioctl: %s", pcap_strerror(errno)); 103575107Sfenner break; 103675107Sfenner } 103775107Sfenner if ((ifr.ifr_flags & IFF_PROMISC) == 0) { 103875107Sfenner /* 103975107Sfenner * Promiscuous mode isn't currently on, 104075107Sfenner * so turn it on, and remember that 104175107Sfenner * we should turn it off when the 104275107Sfenner * pcap_t is closed. 104375107Sfenner */ 104475107Sfenner 104575107Sfenner /* 104675107Sfenner * If we haven't already done so, arrange 104775107Sfenner * to have "pcap_close_all()" called when 104875107Sfenner * we exit. 104975107Sfenner */ 105075107Sfenner if (!did_atexit) { 105175107Sfenner if (atexit(pcap_close_all) == -1) { 105275107Sfenner /* 105375107Sfenner * "atexit()" failed; don't 105475107Sfenner * put the interface in 105575107Sfenner * promiscuous mode, just 105675107Sfenner * give up. 105775107Sfenner */ 105875107Sfenner strncpy(ebuf, "atexit failed", 105975107Sfenner PCAP_ERRBUF_SIZE); 106075107Sfenner break; 106175107Sfenner } 106275107Sfenner } 106375107Sfenner 106475107Sfenner ifr.ifr_flags |= IFF_PROMISC; 106575107Sfenner if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1) { 106675107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, 106775107Sfenner "ioctl: %s", 106875107Sfenner pcap_strerror(errno)); 106975107Sfenner break; 107075107Sfenner } 107175107Sfenner handle->md.clear_promisc = 1; 107275107Sfenner 107375107Sfenner /* 107475107Sfenner * Add this to the list of pcaps 107575107Sfenner * to close when we exit. 107675107Sfenner */ 107775107Sfenner handle->md.next = pcaps_to_close; 107875107Sfenner pcaps_to_close = handle; 107975107Sfenner } 108075107Sfenner } 108175107Sfenner 108275107Sfenner /* Compute the buffersize */ 108375107Sfenner 108475107Sfenner mtu = iface_get_mtu(sock_fd, device, ebuf); 108575107Sfenner if (mtu == -1) 108675107Sfenner break; 108775107Sfenner handle->bufsize = MAX_LINKHEADER_SIZE + mtu; 108875107Sfenner if (handle->bufsize < handle->snapshot) 108975107Sfenner handle->bufsize = handle->snapshot; 109075107Sfenner 109175107Sfenner /* All done - fill in the pcap handle */ 109275107Sfenner 109375107Sfenner arptype = iface_get_arptype(sock_fd, device, ebuf); 109475107Sfenner if (arptype == -1) 109575107Sfenner break; 109675107Sfenner 109775107Sfenner handle->fd = sock_fd; 109875107Sfenner handle->offset = 0; 109975107Sfenner handle->linktype = map_arphrd_to_dlt(arptype); 110075107Sfenner /* 110175107Sfenner * XXX - handle ISDN types here? We can't fall back on 110275107Sfenner * cooked sockets, so we'd have to figure out from the 110375107Sfenner * device name what type of link-layer encapsulation 110475107Sfenner * it's using, and map that to an appropriate DLT_ 110575107Sfenner * value, meaning we'd map "isdnN" devices to DLT_RAW 110675107Sfenner * (they supply raw IP packets with no link-layer 110775107Sfenner * header) and "isdY" devices to a new DLT_I4L_IP 110875107Sfenner * type that has only an Ethernet packet type as 110975107Sfenner * a link-layer header. 111075107Sfenner */ 111175107Sfenner if (handle->linktype == -1) { 111275107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, 111375107Sfenner "interface type of %s not supported", device); 111475107Sfenner break; 111575107Sfenner } 111675107Sfenner handle->buffer = malloc(handle->bufsize); 111775107Sfenner if (!handle->buffer) { 111875107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, 111975107Sfenner "malloc: %s", pcap_strerror(errno)); 112075107Sfenner break; 112175107Sfenner } 112275107Sfenner 112375107Sfenner /* 112475107Sfenner * This might be a 2.0[.x] kernel - check. 112575107Sfenner */ 112675107Sfenner if (uname(&utsname) < 0 || 112775107Sfenner strncmp(utsname.release, "2.0", 3) == 0) { 112875107Sfenner /* 112975107Sfenner * Either we couldn't find out what kernel release 113075107Sfenner * this is, or it's a 2.0[.x] kernel. 113175107Sfenner * 113275107Sfenner * In the 2.0[.x] kernel, a "recvfrom()" on 113375107Sfenner * a SOCK_PACKET socket, with MSG_TRUNC set, will 113475107Sfenner * return the number of bytes read, so if we pass 113575107Sfenner * a length based on the snapshot length, it'll 113675107Sfenner * return the number of bytes from the packet 113775107Sfenner * copied to userland, not the actual length 113875107Sfenner * of the packet. 113975107Sfenner * 114075107Sfenner * This means that, for example, the IP dissector 114175107Sfenner * in tcpdump will get handed a packet length less 114275107Sfenner * than the length in the IP header, and will 114375107Sfenner * complain about "truncated-ip". 114475107Sfenner * 114575107Sfenner * So we don't bother trying to copy from the 114675107Sfenner * kernel only the bytes in which we're interested, 114775107Sfenner * but instead copy them all, just as the older 114875107Sfenner * versions of libpcap for Linux did. 114975107Sfenner * 115075107Sfenner * Just one of many problems with packet capture 115175107Sfenner * on 2.0[.x] kernels; you really want a 2.2[.x] 115275107Sfenner * or later kernel if you want packet capture to 115375107Sfenner * work well. 115475107Sfenner */ 115575107Sfenner handle->md.readlen = handle->bufsize; 115675107Sfenner } else { 115775107Sfenner /* 115875107Sfenner * This is a 2.2[.x] or later kernel (although 115975107Sfenner * why we're using SOCK_PACKET on such a system 116075107Sfenner * is unknown to me). 116175107Sfenner * 116275107Sfenner * We can safely pass "recvfrom()" a byte count 116375107Sfenner * based on the snapshot length. 116475107Sfenner */ 116575107Sfenner handle->md.readlen = handle->snapshot; 116675107Sfenner } 116775107Sfenner return 1; 116875107Sfenner 116975107Sfenner } while (0); 117075107Sfenner 117175107Sfenner if (sock_fd != -1) 117275107Sfenner close(sock_fd); 117375107Sfenner return 0; 117475107Sfenner} 117575107Sfenner 117675107Sfenner/* 117775107Sfenner * Bind the socket associated with FD to the given device using the 117875107Sfenner * interface of the old kernels. 117975107Sfenner */ 118075107Sfennerstatic int 118175107Sfenneriface_bind_old(int fd, const char *device, char *ebuf) 118275107Sfenner{ 118375107Sfenner struct sockaddr saddr; 118475107Sfenner 118575107Sfenner memset(&saddr, 0, sizeof(saddr)); 118675107Sfenner strncpy(saddr.sa_data, device, sizeof(saddr.sa_data)); 118775107Sfenner if (bind(fd, &saddr, sizeof(saddr)) == -1) { 118875107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, 118975107Sfenner "bind: %s", pcap_strerror(errno)); 119075107Sfenner return -1; 119126175Sfenner } 119226175Sfenner 119375107Sfenner return 0; 119426175Sfenner} 119526175Sfenner 119675107Sfenner 119775107Sfenner/* ===== System calls available on all supported kernels ============== */ 119875107Sfenner 119975107Sfenner/* 120075107Sfenner * Query the kernel for the MTU of the given interface. 120175107Sfenner */ 120275107Sfennerstatic int 120375107Sfenneriface_get_mtu(int fd, const char *device, char *ebuf) 120426175Sfenner{ 120575107Sfenner struct ifreq ifr; 120626175Sfenner 120775107Sfenner if (!device) 120875107Sfenner return BIGGER_THAN_ALL_MTUS; 120975107Sfenner 121075107Sfenner memset(&ifr, 0, sizeof(ifr)); 121175107Sfenner strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 121275107Sfenner 121375107Sfenner if (ioctl(fd, SIOCGIFMTU, &ifr) == -1) { 121475107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, 121575107Sfenner "ioctl: %s", pcap_strerror(errno)); 121675107Sfenner return -1; 121775107Sfenner } 121875107Sfenner 121975107Sfenner return ifr.ifr_mtu; 122026175Sfenner} 122126175Sfenner 122275107Sfenner/* 122375107Sfenner * Get the hardware type of the given interface as ARPHRD_xxx constant. 122475107Sfenner */ 122575107Sfennerstatic int 122675107Sfenneriface_get_arptype(int fd, const char *device, char *ebuf) 122726175Sfenner{ 122875107Sfenner struct ifreq ifr; 122926175Sfenner 123075107Sfenner memset(&ifr, 0, sizeof(ifr)); 123175107Sfenner strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 123275107Sfenner 123375107Sfenner if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) { 123475107Sfenner snprintf(ebuf, PCAP_ERRBUF_SIZE, 123575107Sfenner "ioctl: %s", pcap_strerror(errno)); 123675107Sfenner return -1; 123775107Sfenner } 123875107Sfenner 123975107Sfenner return ifr.ifr_hwaddr.sa_family; 124026175Sfenner} 124175107Sfenner 124275107Sfenner#ifdef HAVE_PF_PACKET_SOCKETS 124375107Sfennerstatic int 124475107Sfennerfix_program(pcap_t *handle, struct sock_fprog *fcode) 124575107Sfenner{ 124675107Sfenner size_t prog_size; 124775107Sfenner register int i; 124875107Sfenner register struct bpf_insn *p; 124975107Sfenner struct bpf_insn *f; 125075107Sfenner int len; 125175107Sfenner 125275107Sfenner /* 125375107Sfenner * Make a copy of the filter, and modify that copy if 125475107Sfenner * necessary. 125575107Sfenner */ 125675107Sfenner prog_size = sizeof(*handle->fcode.bf_insns) * handle->fcode.bf_len; 125775107Sfenner len = handle->fcode.bf_len; 125875107Sfenner f = (struct bpf_insn *)malloc(prog_size); 125975107Sfenner if (f == NULL) { 126075107Sfenner snprintf(handle->errbuf, sizeof(handle->errbuf), 126175107Sfenner "malloc: %s", pcap_strerror(errno)); 126275107Sfenner return -1; 126375107Sfenner } 126475107Sfenner memcpy(f, handle->fcode.bf_insns, prog_size); 126575107Sfenner fcode->len = len; 126675107Sfenner fcode->filter = (struct sock_filter *) f; 126775107Sfenner 126875107Sfenner for (i = 0; i < len; ++i) { 126975107Sfenner p = &f[i]; 127075107Sfenner /* 127175107Sfenner * What type of instruction is this? 127275107Sfenner */ 127375107Sfenner switch (BPF_CLASS(p->code)) { 127475107Sfenner 127575107Sfenner case BPF_RET: 127675107Sfenner /* 127775107Sfenner * It's a return instruction; is the snapshot 127875107Sfenner * length a constant, rather than the contents 127975107Sfenner * of the accumulator? 128075107Sfenner */ 128175107Sfenner if (BPF_MODE(p->code) == BPF_K) { 128275107Sfenner /* 128375107Sfenner * Yes - if the value to be returned, 128475107Sfenner * i.e. the snapshot length, is anything 128575107Sfenner * other than 0, make it 65535, so that 128675107Sfenner * the packet is truncated by "recvfrom()", 128775107Sfenner * not by the filter. 128875107Sfenner * 128975107Sfenner * XXX - there's nothing we can easily do 129075107Sfenner * if it's getting the value from the 129175107Sfenner * accumulator; we'd have to insert 129275107Sfenner * code to force non-zero values to be 129375107Sfenner * 65535. 129475107Sfenner */ 129575107Sfenner if (p->k != 0) 129675107Sfenner p->k = 65535; 129775107Sfenner } 129875107Sfenner break; 129975107Sfenner 130075107Sfenner case BPF_LD: 130175107Sfenner case BPF_LDX: 130275107Sfenner /* 130375107Sfenner * It's a load instruction; is it loading 130475107Sfenner * from the packet? 130575107Sfenner */ 130675107Sfenner switch (BPF_MODE(p->code)) { 130775107Sfenner 130875107Sfenner case BPF_ABS: 130975107Sfenner case BPF_IND: 131075107Sfenner case BPF_MSH: 131175107Sfenner /* 131275107Sfenner * Yes; are we in cooked mode? 131375107Sfenner */ 131475107Sfenner if (handle->md.cooked) { 131575107Sfenner /* 131675107Sfenner * Yes, so we need to fix this 131775107Sfenner * instruction. 131875107Sfenner */ 131975107Sfenner if (fix_offset(p) < 0) { 132075107Sfenner /* 132175107Sfenner * We failed to do so. 132275107Sfenner * Return 0, so our caller 132375107Sfenner * knows to punt to userland. 132475107Sfenner */ 132575107Sfenner return 0; 132675107Sfenner } 132775107Sfenner } 132875107Sfenner break; 132975107Sfenner } 133075107Sfenner break; 133175107Sfenner } 133275107Sfenner } 133375107Sfenner return 1; /* we succeeded */ 133475107Sfenner} 133575107Sfenner 133675107Sfennerstatic int 133775107Sfennerfix_offset(struct bpf_insn *p) 133875107Sfenner{ 133975107Sfenner /* 134075107Sfenner * What's the offset? 134175107Sfenner */ 134275107Sfenner if (p->k >= SLL_HDR_LEN) { 134375107Sfenner /* 134475107Sfenner * It's within the link-layer payload; that starts at an 134575107Sfenner * offset of 0, as far as the kernel packet filter is 134675107Sfenner * concerned, so subtract the length of the link-layer 134775107Sfenner * header. 134875107Sfenner */ 134975107Sfenner p->k -= SLL_HDR_LEN; 135075107Sfenner } else if (p->k == 14) { 135175107Sfenner /* 135275107Sfenner * It's the protocol field; map it to the special magic 135375107Sfenner * kernel offset for that field. 135475107Sfenner */ 135575107Sfenner p->k = SKF_AD_OFF + SKF_AD_PROTOCOL; 135675107Sfenner } else { 135775107Sfenner /* 135875107Sfenner * It's within the header, but it's not one of those 135975107Sfenner * fields; we can't do that in the kernel, so punt 136075107Sfenner * to userland. 136175107Sfenner */ 136275107Sfenner return -1; 136375107Sfenner } 136475107Sfenner return 0; 136575107Sfenner} 136675107Sfenner#endif 1367