pcap-pf.c revision 478ab6c8b5bc982589be32eae1e5736efe721b58
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_ = 27478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.91.2.2 2005/05/03 18:54:37 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/* 65478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 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 77478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pcap_setfilter_pf(pcap_t *, struct bpf_program *); 78478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 79478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 80478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * BUFSPACE is the size in bytes of the packet read buffer. Most tcpdump 81478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * applications aren't going to need more than 200 bytes of packet header 82478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and the read shouldn't return more packets than packetfilter's internal 83478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * queue limit (bounded at 256). 84478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 85478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define BUFSPACE (200 * 256) 86478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 87478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 88478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user) 89478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 90478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register u_char *p, *bp; 91478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct bpf_insn *fcode; 92478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int cc, n, buflen, inc; 93478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct enstamp *sp; 94478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef LBL_ALIGN 95478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct enstamp stamp; 96478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 97478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef PCAP_FDDIPAD 98478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int pad; 99478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fcode = pc->md.use_bpf ? NULL : pc->fcode.bf_insns; 102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project again: 103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cc = pc->cc; 104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (cc == 0) { 105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cc = read(pc->fd, (char *)pc->buffer + pc->offset, pc->bufsize); 106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (cc < 0) { 107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (errno == EWOULDBLOCK) 108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (errno == EINVAL && 110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project lseek(pc->fd, 0L, SEEK_CUR) + pc->bufsize < 0) { 111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Due to a kernel bug, after 2^31 bytes, 113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the kernel file offset overflows and 114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * read fails with EINVAL. The lseek() 115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to 0 will fix things. 116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)lseek(pc->fd, 0L, SEEK_SET); 118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto again; 119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(pc->errbuf, sizeof(pc->errbuf), "pf read: %s", 121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bp = pc->buffer + pc->offset; 125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bp = pc->bp; 127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Loop through each packet. 129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project n = 0; 131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef PCAP_FDDIPAD 132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pad = pc->fddipad; 133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (cc > 0) { 135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Has "pcap_breakloop()" been called? 137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If so, return immediately - if we haven't read any 138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * packets, clear the flag and return -2 to indicate 139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that we were told to break out of the loop, otherwise 140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * leave the flag set, so that the *next* call will break 141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * out of the loop without having read any packets, and 142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * return the number of packets we've processed so far. 143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (pc->break_loop) { 145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (n == 0) { 146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc->break_loop = 0; 147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-2); 148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc->cc = cc; 150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc->bp = bp; 151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (n); 152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (cc < sizeof(*sp)) { 155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(pc->errbuf, sizeof(pc->errbuf), 156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "pf short read (%d)", cc); 157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef LBL_ALIGN 160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ((long)bp & 3) { 161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sp = &stamp; 162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memcpy((char *)sp, (char *)bp, sizeof(*sp)); 163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sp = (struct enstamp *)bp; 166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (sp->ens_stamplen != sizeof(*sp)) { 167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(pc->errbuf, sizeof(pc->errbuf), 168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "pf short stamplen (%d)", 169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sp->ens_stamplen); 170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p = bp + sp->ens_stamplen; 174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project buflen = sp->ens_count; 175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (buflen > pc->snapshot) 176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project buflen = pc->snapshot; 177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Calculate inc before possible pad update */ 179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project inc = ENALIGN(buflen + sp->ens_stamplen); 180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cc -= inc; 181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bp += inc; 182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc->md.TotPkts++; 183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc->md.TotDrops += sp->ens_dropped; 184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc->md.TotMissed = sp->ens_ifoverflows; 185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (pc->md.OrigMissed < 0) 186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc->md.OrigMissed = pc->md.TotMissed; 187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Short-circuit evaluation: if using BPF filter 190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in kernel, no need to do it now. 191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef PCAP_FDDIPAD 193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Note: the filter code was generated assuming 194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that pc->fddipad was the amount of padding 195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * before the header, as that's what's required 196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in the kernel, so we run the filter before 197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * skipping that padding. 198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (fcode == NULL || 201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_filter(fcode, p, sp->ens_count, buflen)) { 202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct pcap_pkthdr h; 203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc->md.TotAccepted++; 204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project h.ts = sp->ens_tstamp; 205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef PCAP_FDDIPAD 206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project h.len = sp->ens_count - pad; 207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project h.len = sp->ens_count; 209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef PCAP_FDDIPAD 211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p += pad; 212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project buflen -= pad; 213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project h.caplen = buflen; 215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (*callback)(user, &h, p); 216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (++n >= cnt && cnt > 0) { 217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc->cc = cc; 218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc->bp = bp; 219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (n); 220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc->cc = 0; 224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (n); 225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_inject_pf(pcap_t *p, const void *buf, size_t size) 229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int ret; 231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = write(p->fd, buf, size); 233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ret == -1) { 234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s", 235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (ret); 239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_stats_pf(pcap_t *p, struct pcap_stat *ps) 243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If packet filtering is being done in the kernel: 247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_recv" counts only packets that passed the filter. 249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This does not include packets dropped because we 250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ran out of buffer space. (XXX - perhaps it should, 251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * by adding "ps_drop" to "ps_recv", for compatibility 252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with some other platforms. On the other hand, on 253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * some platforms "ps_recv" counts only packets that 254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * passed the filter, and on others it counts packets 255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that didn't pass the filter....) 256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_drop" counts packets that passed the kernel filter 258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (if any) but were dropped because the input queue was 259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * full. 260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_ifdrop" counts packets dropped by the network 262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * inteface (regardless of whether they would have passed 263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the input filter, of course). 264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If packet filtering is not being done in the kernel: 266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_recv" counts only packets that passed the filter. 268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_drop" counts packets that were dropped because the 270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * input queue was full, regardless of whether they passed 271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the userland filter. 272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_ifdrop" counts packets dropped by the network 274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * inteface (regardless of whether they would have passed 275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the input filter, of course). 276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * These statistics don't include packets not yet read from 278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the kernel by libpcap, but they may include packets not 279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * yet read from libpcap by the application. 280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ps->ps_recv = p->md.TotAccepted; 282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ps->ps_drop = p->md.TotDrops; 283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ps->ps_ifdrop = p->md.TotMissed - p->md.OrigMissed; 284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We include the OS's <net/bpf.h>, not our "pcap-bpf.h", so we probably 289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * don't get DLT_DOCSIS defined. 290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef DLT_DOCSIS 292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define DLT_DOCSIS 143 293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_t * 296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_open_live(const char *device, int snaplen, int promisc, int to_ms, 297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project char *ebuf) 298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_t *p; 300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project short enmode; 301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int backlog = -1; /* request the most */ 302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct enfilter Filter; 303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct endevp devparams; 304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p = (pcap_t *)malloc(sizeof(*p)); 306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p == NULL) { 307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, 308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "pcap_open_live: %s", pcap_strerror(errno)); 309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(p, 0, sizeof(*p)); 312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Initially try a read/write open (to allow the inject 314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * method to work). If that fails due to permission 315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * issues, fall back to read-only. This allows a 316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * non-root user to be granted specific access to pcap 317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * capabilities via file permissions. 318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - we should have an API that has a flag that 320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * controls whether to open read-only or read-write, 321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * so that denial of permission to send (or inability 322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to send, if sending packets isn't supported on 323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the device in question) can be indicated at open 324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * time. 325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - we assume here that "pfopen()" does not, in fact, modify 327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * its argument, even though it takes a "char *" rather than a 328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "const char *" as its first argument. That appears to be 329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the case, at least on Digital UNIX 4.0. 330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->fd = pfopen(device, O_RDWR); 332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->fd == -1 && errno == EACCES) 333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->fd = pfopen(device, O_RDONLY); 334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->fd < 0) { 335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\ 336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectyour system may not be properly configured; see the packetfilter(4) man page\n", 337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project device, pcap_strerror(errno)); 338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->md.OrigMissed = -1; 341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project enmode = ENTSTAMP|ENBATCH|ENNONEXCL; 342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (promisc) 343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project enmode |= ENPROMISC; 344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) { 345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s", 346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef ENCOPYALL 350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Try to set COPYALL mode so that we see packets to ourself */ 351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project enmode = ENCOPYALL; 352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode);/* OK if this fails */ 353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* set the backlog */ 355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) { 356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s", 357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* discover interface type */ 361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) { 362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s", 363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* HACK: to compile prior to Ultrix 4.2 */ 367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef ENDT_FDDI 368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define ENDT_FDDI 4 369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (devparams.end_dev_type) { 371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ENDT_10MB: 373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_EN10MB; 374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->offset = 2; 375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is (presumably) a real Ethernet capture; give it a 377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so 378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that an application can let you choose it, in case you're 379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * capturing DOCSIS traffic that a Cisco Cable Modem 380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Termination System is putting out onto an Ethernet (it 381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * doesn't put an Ethernet header onto the wire, it puts raw 382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DOCSIS frames out on the wire inside the low-level 383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet framing). 384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); 386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If that fails, just leave the list empty. 388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->dlt_list != NULL) { 390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list[0] = DLT_EN10MB; 391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list[1] = DLT_DOCSIS; 392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_count = 2; 393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ENDT_FDDI: 397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_FDDI; 398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef ENDT_SLIP 401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ENDT_SLIP: 402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_SLIP; 403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef ENDT_PPP 407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ENDT_PPP: 408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_PPP; 409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef ENDT_LOOPBACK 413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ENDT_LOOPBACK: 414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * It appears to use Ethernet framing, at least on 416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Digital UNIX 4.0. 417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_EN10MB; 419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->offset = 2; 420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef ENDT_TRN 424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ENDT_TRN: 425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_IEEE802; 426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - what about ENDT_IEEE802? The pfilt.h header 432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * file calls this "IEEE 802 networks (non-Ethernet)", 433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * but that doesn't specify a specific link layer type; 434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * it could be 802.4, or 802.5 (except that 802.5 is 435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ENDT_TRN), or 802.6, or 802.11, or.... That's why 436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DLT_IEEE802 was hijacked to mean Token Ring in various 437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * BSDs, and why we went along with that hijacking. 438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - what about ENDT_HDLC and ENDT_NULL? 440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Presumably, as ENDT_OTHER is just "Miscellaneous 441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * framing", there's not much we can do, as that 442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * doesn't specify a particular type of header. 443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown data-link type %u", 445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project devparams.end_dev_type); 446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* set truncation */ 449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef PCAP_FDDIPAD 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 */ 454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snaplen += PCAP_FDDIPAD; 455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->fddipad = 0; 457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&snaplen) < 0) { 459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s", 460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->snapshot = snaplen; 464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* accept all packets */ 465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(&Filter, 0, sizeof(Filter)); 466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project Filter.enf_Priority = 37; /* anything > 2 */ 467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project Filter.enf_FilterLen = 0; /* means "always true" */ 468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) { 469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s", 470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (to_ms != 0) { 475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct timeval timeout; 476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project timeout.tv_sec = to_ms / 1000; 477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project timeout.tv_usec = (to_ms * 1000) % 1000000; 478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) { 479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s", 480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->bufsize = BUFSPACE; 486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->buffer = (u_char*)malloc(p->bufsize + p->offset); 487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->buffer == NULL) { 488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); 489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "select()" and "poll()" work on packetfilter devices. 494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->selectable_fd = p->fd; 496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->read_op = pcap_read_pf; 498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->inject_op = pcap_inject_pf; 499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->setfilter_op = pcap_setfilter_pf; 500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->setdirection_op = NULL; /* Not implemented. */ 501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->set_datalink_op = NULL; /* can't change data link type */ 502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->getnonblock_op = pcap_getnonblock_fd; 503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->setnonblock_op = pcap_setnonblock_fd; 504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->stats_op = pcap_stats_pf; 505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->close_op = pcap_close_common; 506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (p); 508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bad: 509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->fd >= 0) 510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project close(p->fd); 511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Get rid of any link-layer type list we allocated. 513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->dlt_list != NULL) 515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(p->dlt_list); 516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(p); 517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint 521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) 522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_setfilter_pf(pcap_t *p, struct bpf_program *fp) 528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct bpf_version bv; 530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * See if BIOCVERSION works. If not, we assume the kernel doesn't 533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * support BPF-style filters (it's not documented in the bpf(7) 534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * or packetfiler(7) man pages, but the code used to fail if 535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * BIOCSETF worked but BIOCVERSION didn't, and I've seen it do 536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * kernel filtering in DU 4.0, so presumably BIOCVERSION works 537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * there, at least). 538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, BIOCVERSION, (caddr_t)&bv) >= 0) { 540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OK, we have the version of the BPF interpreter; 542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is it the same major version as us, and the same 543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * or better minor version? 544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (bv.bv_major == BPF_MAJOR_VERSION && 546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bv.bv_minor >= BPF_MINOR_VERSION) { 547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Yes. Try to install the filter. 549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) { 551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(p->errbuf, sizeof(p->errbuf), 552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "BIOCSETF: %s", pcap_strerror(errno)); 553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OK, that succeeded. We're doing filtering in 558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the kernel. (We assume we don't have a 559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * userland filter installed - that'd require 560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a previous version check to have failed but 561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * this one to succeed.) 562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - this message should be supplied to the 564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * application as a warning of some sort, 565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * except that if it's a GUI application, it's 566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * not clear that it should be displayed in 567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a window to annoy the user. 568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fprintf(stderr, "tcpdump: Using kernel BPF filter\n"); 570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->md.use_bpf = 1; 571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Discard any previously-received packets, 574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as they might have passed whatever filter 575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * was formerly in effect, but might not pass 576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * this filter (BIOCSETF discards packets buffered 577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in the kernel, so you can lose packets in any 578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * case). 579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->cc = 0; 581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We can't use the kernel's BPF interpreter; don't give 586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * up, just log a message and be inefficient. 587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - this should really be supplied to the application 589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as a warning of some sort. 590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fprintf(stderr, 592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "tcpdump: Requires BPF language %d.%d or higher; kernel is %d.%d\n", 593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project BPF_MAJOR_VERSION, BPF_MINOR_VERSION, 594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bv.bv_major, bv.bv_minor); 595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We couldn't do filtering in the kernel; do it in userland. 599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (install_bpf_program(p, fp) < 0) 601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - this message should be supplied by the application as 605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a warning of some sort. 606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fprintf(stderr, "tcpdump: Filtering in user process\n"); 608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->md.use_bpf = 0; 609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 611