1478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 2478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 3478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The Regents of the University of California. All rights reserved. 4478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Redistribution and use in source and binary forms, with or without 6478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * modification, are permitted provided that: (1) source code distributions 7478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * retain the above copyright notice and this paragraph in its entirety, (2) 8478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * distributions including binary code include the above copyright notice and 9478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * this paragraph in its entirety in the documentation or other materials 10478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * provided with the distribution, and (3) all advertising materials mentioning 11478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * features or use of this software display the following acknowledgement: 12478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ``This product includes software developed by the University of California, 13478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the University nor the names of its contributors may be used to endorse 15478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * or promote products derived from this software without specific prior 16478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * written permission. 17478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 21478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * packet filter subroutines for tcpdump 22478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Extraction/creation by Jeffrey Mogul, DECWRL 23478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 24478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 25478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef lint 26478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic const char rcsid[] _U_ = 27511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.97 2008-04-14 20:40:58 guy Exp $ (LBL)"; 28478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 29478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 30478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_CONFIG_H 31478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "config.h" 32478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 33478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 34478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/types.h> 35478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/time.h> 36478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/timeb.h> 37478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/socket.h> 38478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/file.h> 39478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/ioctl.h> 40478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/pfilt.h> 41478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 42478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct mbuf; 43478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct rtentry; 44478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if.h> 45478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 46478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/in.h> 47478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/in_systm.h> 48478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/ip.h> 49478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/if_ether.h> 50478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/ip_var.h> 51478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/udp.h> 52478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/udp_var.h> 53478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/tcp.h> 54478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/tcpip.h> 55478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 56478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <ctype.h> 57478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <errno.h> 58478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netdb.h> 59478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdio.h> 60478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdlib.h> 61478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <string.h> 62478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <unistd.h> 63478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 64478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 65511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Make "pcap.h" not include "pcap/bpf.h"; we are going to include the 66478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * native OS version, as we need various BPF ioctls from it. 67478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 68478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define PCAP_DONT_INCLUDE_PCAP_BPF_H 69478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/bpf.h> 70478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 71478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap-int.h" 72478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 73478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_OS_PROTO_H 74478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "os-proto.h" 75478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 76478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 77511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 78511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * FDDI packets are padded to make everything line up on a nice boundary. 79511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 80511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define PCAP_FDDIPAD 3 81511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 82511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 83511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Private data for capturing on Ultrix and DEC OSF/1^WDigital UNIX^W^W 84511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Tru64 UNIX packetfilter devices. 85511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 86511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct pcap_pf { 87511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int filtering_in_kernel; /* using kernel filter */ 88511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall u_long TotPkts; /* can't oflow for 79 hrs on ether */ 89511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall u_long TotAccepted; /* count accepted by filter */ 90511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall u_long TotDrops; /* count of dropped packets */ 91511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall long TotMissed; /* missed by i/f during this run */ 92511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall long OrigMissed; /* missed by i/f before this run */ 93511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}; 94511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 95478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pcap_setfilter_pf(pcap_t *, struct bpf_program *); 96478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 97478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 98478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * BUFSPACE is the size in bytes of the packet read buffer. Most tcpdump 99478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * applications aren't going to need more than 200 bytes of packet header 100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and the read shouldn't return more packets than packetfilter's internal 101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * queue limit (bounded at 256). 102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define BUFSPACE (200 * 256) 104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user) 107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 108511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct pcap_pf *pf = pc->priv; 109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register u_char *p, *bp; 110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int cc, n, buflen, inc; 111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct enstamp *sp; 112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef LBL_ALIGN 113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct enstamp stamp; 114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int pad; 116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project again: 118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cc = pc->cc; 119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (cc == 0) { 120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cc = read(pc->fd, (char *)pc->buffer + pc->offset, pc->bufsize); 121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (cc < 0) { 122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (errno == EWOULDBLOCK) 123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (errno == EINVAL && 125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project lseek(pc->fd, 0L, SEEK_CUR) + pc->bufsize < 0) { 126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Due to a kernel bug, after 2^31 bytes, 128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the kernel file offset overflows and 129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * read fails with EINVAL. The lseek() 130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to 0 will fix things. 131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)lseek(pc->fd, 0L, SEEK_SET); 133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto again; 134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(pc->errbuf, sizeof(pc->errbuf), "pf read: %s", 136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bp = pc->buffer + pc->offset; 140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bp = pc->bp; 142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Loop through each packet. 144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project n = 0; 146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pad = pc->fddipad; 147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (cc > 0) { 148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Has "pcap_breakloop()" been called? 150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If so, return immediately - if we haven't read any 151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * packets, clear the flag and return -2 to indicate 152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that we were told to break out of the loop, otherwise 153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * leave the flag set, so that the *next* call will break 154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * out of the loop without having read any packets, and 155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * return the number of packets we've processed so far. 156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (pc->break_loop) { 158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (n == 0) { 159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc->break_loop = 0; 160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-2); 161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc->cc = cc; 163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc->bp = bp; 164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (n); 165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (cc < sizeof(*sp)) { 168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(pc->errbuf, sizeof(pc->errbuf), 169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "pf short read (%d)", cc); 170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef LBL_ALIGN 173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ((long)bp & 3) { 174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sp = &stamp; 175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memcpy((char *)sp, (char *)bp, sizeof(*sp)); 176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sp = (struct enstamp *)bp; 179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (sp->ens_stamplen != sizeof(*sp)) { 180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(pc->errbuf, sizeof(pc->errbuf), 181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "pf short stamplen (%d)", 182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sp->ens_stamplen); 183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p = bp + sp->ens_stamplen; 187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project buflen = sp->ens_count; 188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (buflen > pc->snapshot) 189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project buflen = pc->snapshot; 190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Calculate inc before possible pad update */ 192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project inc = ENALIGN(buflen + sp->ens_stamplen); 193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cc -= inc; 194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bp += inc; 195511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pf->TotPkts++; 196511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pf->TotDrops += sp->ens_dropped; 197511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pf->TotMissed = sp->ens_ifoverflows; 198511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pf->OrigMissed < 0) 199511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pf->OrigMissed = pf->TotMissed; 200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Short-circuit evaluation: if using BPF filter 203511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * in kernel, no need to do it now - we already know 204511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the packet passed the filter. 205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Note: the filter code was generated assuming 207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that pc->fddipad was the amount of padding 208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * before the header, as that's what's required 209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in the kernel, so we run the filter before 210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * skipping that padding. 211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 212511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pf->filtering_in_kernel || 213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_filter(pc->fcode.bf_insns, p, sp->ens_count, buflen)) { 214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct pcap_pkthdr h; 215511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pf->TotAccepted++; 216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project h.ts = sp->ens_tstamp; 217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project h.len = sp->ens_count - pad; 218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p += pad; 219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project buflen -= pad; 220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project h.caplen = buflen; 221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (*callback)(user, &h, p); 222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) { 223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc->cc = cc; 224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc->bp = bp; 225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (n); 226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc->cc = 0; 230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (n); 231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_inject_pf(pcap_t *p, const void *buf, size_t size) 235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int ret; 237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = write(p->fd, buf, size); 239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ret == -1) { 240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s", 241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (ret); 245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_stats_pf(pcap_t *p, struct pcap_stat *ps) 249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 250511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct pcap_pf *pf = p->priv; 251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If packet filtering is being done in the kernel: 254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_recv" counts only packets that passed the filter. 256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This does not include packets dropped because we 257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ran out of buffer space. (XXX - perhaps it should, 258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * by adding "ps_drop" to "ps_recv", for compatibility 259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with some other platforms. On the other hand, on 260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * some platforms "ps_recv" counts only packets that 261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * passed the filter, and on others it counts packets 262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that didn't pass the filter....) 263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_drop" counts packets that passed the kernel filter 265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (if any) but were dropped because the input queue was 266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * full. 267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_ifdrop" counts packets dropped by the network 269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * inteface (regardless of whether they would have passed 270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the input filter, of course). 271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If packet filtering is not being done in the kernel: 273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_recv" counts only packets that passed the filter. 275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_drop" counts packets that were dropped because the 277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * input queue was full, regardless of whether they passed 278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the userland filter. 279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_ifdrop" counts packets dropped by the network 281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * inteface (regardless of whether they would have passed 282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the input filter, of course). 283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * These statistics don't include packets not yet read from 285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the kernel by libpcap, but they may include packets not 286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * yet read from libpcap by the application. 287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 288511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ps->ps_recv = pf->TotAccepted; 289511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ps->ps_drop = pf->TotDrops; 290511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ps->ps_ifdrop = pf->TotMissed - pf->OrigMissed; 291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 295511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * We include the OS's <net/bpf.h>, not our "pcap/bpf.h", so we probably 296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * don't get DLT_DOCSIS defined. 297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef DLT_DOCSIS 299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define DLT_DOCSIS 143 300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 302511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int 303511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_activate_pf(pcap_t *p) 304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 305511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct pcap_pf *pf = p->priv; 306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project short enmode; 307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int backlog = -1; /* request the most */ 308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct enfilter Filter; 309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct endevp devparams; 310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Initially try a read/write open (to allow the inject 313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * method to work). If that fails due to permission 314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * issues, fall back to read-only. This allows a 315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * non-root user to be granted specific access to pcap 316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * capabilities via file permissions. 317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - we should have an API that has a flag that 319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * controls whether to open read-only or read-write, 320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * so that denial of permission to send (or inability 321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to send, if sending packets isn't supported on 322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the device in question) can be indicated at open 323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * time. 324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - we assume here that "pfopen()" does not, in fact, modify 326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * its argument, even though it takes a "char *" rather than a 327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "const char *" as its first argument. That appears to be 328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the case, at least on Digital UNIX 4.0. 329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 330511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->fd = pfopen(p->opt.source, O_RDWR); 331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->fd == -1 && errno == EACCES) 332511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->fd = pfopen(p->opt.source, O_RDONLY); 333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->fd < 0) { 334511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\ 335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectyour system may not be properly configured; see the packetfilter(4) man page\n", 336511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->opt.source, pcap_strerror(errno)); 337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 339511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pf->OrigMissed = -1; 340511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall enmode = ENTSTAMP|ENNONEXCL; 341511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (!p->opt.immediate) 342511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall enmode |= ENBATCH; 343511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (p->opt.promisc) 344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project enmode |= ENPROMISC; 345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) { 346511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s", 347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef ENCOPYALL 351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Try to set COPYALL mode so that we see packets to ourself */ 352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project enmode = ENCOPYALL; 353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode);/* OK if this fails */ 354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* set the backlog */ 356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) { 357511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s", 358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* discover interface type */ 362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) { 363511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s", 364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* HACK: to compile prior to Ultrix 4.2 */ 368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef ENDT_FDDI 369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define ENDT_FDDI 4 370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (devparams.end_dev_type) { 372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ENDT_10MB: 374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_EN10MB; 375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->offset = 2; 376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is (presumably) a real Ethernet capture; give it a 378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so 379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that an application can let you choose it, in case you're 380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * capturing DOCSIS traffic that a Cisco Cable Modem 381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Termination System is putting out onto an Ethernet (it 382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * doesn't put an Ethernet header onto the wire, it puts raw 383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DOCSIS frames out on the wire inside the low-level 384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet framing). 385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); 387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If that fails, just leave the list empty. 389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->dlt_list != NULL) { 391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list[0] = DLT_EN10MB; 392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list[1] = DLT_DOCSIS; 393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_count = 2; 394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ENDT_FDDI: 398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_FDDI; 399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef ENDT_SLIP 402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ENDT_SLIP: 403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_SLIP; 404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef ENDT_PPP 408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ENDT_PPP: 409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_PPP; 410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef ENDT_LOOPBACK 414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ENDT_LOOPBACK: 415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * It appears to use Ethernet framing, at least on 417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Digital UNIX 4.0. 418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_EN10MB; 420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->offset = 2; 421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef ENDT_TRN 425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ENDT_TRN: 426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_IEEE802; 427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - what about ENDT_IEEE802? The pfilt.h header 433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * file calls this "IEEE 802 networks (non-Ethernet)", 434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * but that doesn't specify a specific link layer type; 435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * it could be 802.4, or 802.5 (except that 802.5 is 436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ENDT_TRN), or 802.6, or 802.11, or.... That's why 437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DLT_IEEE802 was hijacked to mean Token Ring in various 438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * BSDs, and why we went along with that hijacking. 439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - what about ENDT_HDLC and ENDT_NULL? 441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Presumably, as ENDT_OTHER is just "Miscellaneous 442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * framing", there's not much we can do, as that 443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * doesn't specify a particular type of header. 444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 445511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 446511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "unknown data-link type %u", devparams.end_dev_type); 447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* set truncation */ 450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->linktype == DLT_FDDI) { 451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->fddipad = PCAP_FDDIPAD; 452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* packetfilter includes the padding in the snapshot */ 454511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->snapshot += PCAP_FDDIPAD; 455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->fddipad = 0; 457511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&p->snapshot) < 0) { 458511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s", 459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* accept all packets */ 463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(&Filter, 0, sizeof(Filter)); 464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project Filter.enf_Priority = 37; /* anything > 2 */ 465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project Filter.enf_FilterLen = 0; /* means "always true" */ 466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) { 467511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s", 468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 472511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (p->opt.timeout != 0) { 473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct timeval timeout; 474511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall timeout.tv_sec = p->opt.timeout / 1000; 475511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall timeout.tv_usec = (p->opt.timeout * 1000) % 1000000; 476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) { 477511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s", 478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->bufsize = BUFSPACE; 484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->buffer = (u_char*)malloc(p->bufsize + p->offset); 485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->buffer == NULL) { 486511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); 487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "select()" and "poll()" work on packetfilter devices. 492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->selectable_fd = p->fd; 494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->read_op = pcap_read_pf; 496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->inject_op = pcap_inject_pf; 497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->setfilter_op = pcap_setfilter_pf; 498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->setdirection_op = NULL; /* Not implemented. */ 499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->set_datalink_op = NULL; /* can't change data link type */ 500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->getnonblock_op = pcap_getnonblock_fd; 501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->setnonblock_op = pcap_setnonblock_fd; 502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->stats_op = pcap_stats_pf; 503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 504511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (0); 505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bad: 506511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pcap_cleanup_live_common(p); 507511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (PCAP_ERROR); 508511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 509511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 510511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_t * 511511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_create_interface(const char *device, char *ebuf) 512511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 513511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pcap_t *p; 514511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 515511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p = pcap_create_common(device, ebuf, sizeof (struct pcap_pf)); 516511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (p == NULL) 517511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (NULL); 518511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 519511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->activate_op = pcap_activate_pf; 520511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (p); 521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint 524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) 525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_setfilter_pf(pcap_t *p, struct bpf_program *fp) 531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 532511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct pcap_pf *pf = p->priv; 533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct bpf_version bv; 534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * See if BIOCVERSION works. If not, we assume the kernel doesn't 537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * support BPF-style filters (it's not documented in the bpf(7) 538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * or packetfiler(7) man pages, but the code used to fail if 539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * BIOCSETF worked but BIOCVERSION didn't, and I've seen it do 540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * kernel filtering in DU 4.0, so presumably BIOCVERSION works 541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * there, at least). 542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, BIOCVERSION, (caddr_t)&bv) >= 0) { 544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OK, we have the version of the BPF interpreter; 546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is it the same major version as us, and the same 547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * or better minor version? 548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (bv.bv_major == BPF_MAJOR_VERSION && 550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bv.bv_minor >= BPF_MINOR_VERSION) { 551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Yes. Try to install the filter. 553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) { 555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(p->errbuf, sizeof(p->errbuf), 556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "BIOCSETF: %s", pcap_strerror(errno)); 557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OK, that succeeded. We're doing filtering in 562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the kernel. (We assume we don't have a 563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * userland filter installed - that'd require 564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a previous version check to have failed but 565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * this one to succeed.) 566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - this message should be supplied to the 568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * application as a warning of some sort, 569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * except that if it's a GUI application, it's 570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * not clear that it should be displayed in 571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a window to annoy the user. 572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fprintf(stderr, "tcpdump: Using kernel BPF filter\n"); 574511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pf->filtering_in_kernel = 1; 575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Discard any previously-received packets, 578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as they might have passed whatever filter 579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * was formerly in effect, but might not pass 580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * this filter (BIOCSETF discards packets buffered 581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in the kernel, so you can lose packets in any 582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * case). 583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->cc = 0; 585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We can't use the kernel's BPF interpreter; don't give 590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * up, just log a message and be inefficient. 591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - this should really be supplied to the application 593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as a warning of some sort. 594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fprintf(stderr, 596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "tcpdump: Requires BPF language %d.%d or higher; kernel is %d.%d\n", 597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project BPF_MAJOR_VERSION, BPF_MINOR_VERSION, 598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bv.bv_major, bv.bv_minor); 599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We couldn't do filtering in the kernel; do it in userland. 603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (install_bpf_program(p, fp) < 0) 605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - this message should be supplied by the application as 609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a warning of some sort. 610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fprintf(stderr, "tcpdump: Filtering in user process\n"); 612511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pf->filtering_in_kernel = 0; 613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 615