1478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 2478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Copyright (c) 1993, 1994, 1995, 1996, 1998 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#ifndef lint 22478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic const char rcsid[] _U_ = 23478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.86.2.12 2007/06/15 17:57:27 guy Exp $ (LBL)"; 24478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 25478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 26478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_CONFIG_H 27478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "config.h" 28478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 29478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 30478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/param.h> /* optionally get BSD define */ 31478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/time.h> 32478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/timeb.h> 33478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/socket.h> 34478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/file.h> 35478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/ioctl.h> 36478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/utsname.h> 37478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 38478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if.h> 39478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 40478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef _AIX 41478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 42478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 43478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Make "pcap.h" not include "pcap-bpf.h"; we are going to include the 44478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * native OS version, as we need "struct bpf_config" from it. 45478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 46478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define PCAP_DONT_INCLUDE_PCAP_BPF_H 47478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 48478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/types.h> 49478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 50478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 51478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Prevent bpf.h from redefining the DLT_ values to their 52478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * IFT_ values, as we're going to return the standard libpcap 53478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * values, not IBM's non-standard IFT_ values. 54478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 55478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#undef _AIX 56478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/bpf.h> 57478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define _AIX 58478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 59478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if_types.h> /* for IFT_ values */ 60478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/sysconfig.h> 61478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/device.h> 62478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/cfgodm.h> 63478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <cf.h> 64478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 65478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef __64BIT__ 66478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define domakedev makedev64 67478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define getmajor major64 68478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define bpf_hdr bpf_hdr32 69478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else /* __64BIT__ */ 70478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define domakedev makedev 71478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define getmajor major 72478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* __64BIT__ */ 73478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 74478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define BPF_NAME "bpf" 75478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define BPF_MINORS 4 76478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define DRIVER_PATH "/usr/lib/drivers" 77478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define BPF_NODE "/dev/bpf" 78478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int bpfloadedflag = 0; 79478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int odmlockid = 0; 80478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 81478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else /* _AIX */ 82478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 83478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/bpf.h> 84478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 85478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* _AIX */ 86478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 87478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <ctype.h> 88478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <errno.h> 89478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netdb.h> 90478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdio.h> 91478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdlib.h> 92478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <string.h> 93478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <unistd.h> 94478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 95478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap-int.h" 96478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 97478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_API 98478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap-dag.h" 99478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_API */ 100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_OS_PROTO_H 102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "os-proto.h" 103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "gencode.h" /* for "no_optimize" */ 106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp); 108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pcap_setdirection_bpf(pcap_t *, pcap_direction_t); 109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pcap_set_datalink_bpf(pcap_t *p, int dlt); 110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_stats_bpf(pcap_t *p, struct pcap_stat *ps) 113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct bpf_stat s; 115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_recv" counts packets handed to the filter, not packets 118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that passed the filter. This includes packets later dropped 119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * because we ran out of buffer space. 120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_drop" counts packets dropped inside the BPF device 122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * because we ran out of buffer space. It doesn't count 123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * packets dropped by the interface driver. It counts 124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * only packets that passed the filter. 125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Both statistics include packets not yet read from the kernel 127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * by libpcap, and thus not yet seen by the application. 128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, BIOCGSTATS, (caddr_t)&s) < 0) { 130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGSTATS: %s", 131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ps->ps_recv = s.bs_recv; 136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ps->ps_drop = s.bs_drop; 137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int cc; 144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int n = 0; 145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register u_char *bp, *ep; 146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_char *datap; 147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct bpf_insn *fcode; 148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef PCAP_FDDIPAD 149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int pad; 150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fcode = p->md.use_bpf ? NULL : p->fcode.bf_insns; 153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project again: 154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Has "pcap_breakloop()" been called? 156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->break_loop) { 158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Yes - clear the flag that indicates that it 160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * has, and return -2 to indicate that we were 161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * told to break out of the loop. 162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->break_loop = 0; 164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-2); 165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cc = p->cc; 167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->cc == 0) { 168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cc = read(p->fd, (char *)p->buffer, p->bufsize); 169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (cc < 0) { 170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Don't choke when we get ptraced */ 171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (errno) { 172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case EINTR: 174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto again; 175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef _AIX 177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case EFAULT: 178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Sigh. More AIX wonderfulness. 180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For some unknown reason the uiomove() 182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * operation in the bpf kernel extension 183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * used to copy the buffer into user 184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * space sometimes returns EFAULT. I have 185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * no idea why this is the case given that 186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a kernel debugger shows the user buffer 187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is correct. This problem appears to 188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * be mostly mitigated by the memset of 189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the buffer before it is first used. 190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Very strange.... Shaun Clowes 191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * In any case this means that we shouldn't 193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * treat EFAULT as a fatal error; as we 194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * don't have an API for returning 195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a "some packets were dropped since 196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the last packet you saw" indication, 197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we just ignore EFAULT and keep reading. 198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto again; 200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case EWOULDBLOCK: 203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(sun) && !defined(BSD) 205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Due to a SunOS bug, after 2^31 bytes, the kernel 207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * file offset overflows and read fails with EINVAL. 208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The lseek() to 0 will fix things. 209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case EINVAL: 211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (lseek(p->fd, 0L, SEEK_CUR) + 212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->bufsize < 0) { 213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)lseek(p->fd, 0L, SEEK_SET); 214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto again; 215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* fall through */ 217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read: %s", 220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bp = p->buffer; 224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bp = p->bp; 226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Loop through each packet. 229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define bhp ((struct bpf_hdr *)bp) 231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ep = bp + cc; 232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef PCAP_FDDIPAD 233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pad = p->fddipad; 234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (bp < ep) { 236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int caplen, hdrlen; 237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Has "pcap_breakloop()" been called? 240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If so, return immediately - if we haven't read any 241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * packets, clear the flag and return -2 to indicate 242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that we were told to break out of the loop, otherwise 243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * leave the flag set, so that the *next* call will break 244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * out of the loop without having read any packets, and 245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * return the number of packets we've processed so far. 246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->break_loop) { 248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (n == 0) { 249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->break_loop = 0; 250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-2); 251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->bp = bp; 253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->cc = ep - bp; 254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (n); 255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project caplen = bhp->bh_caplen; 259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project hdrlen = bhp->bh_hdrlen; 260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project datap = bp + hdrlen; 261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Short-circuit evaluation: if using BPF filter 263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in kernel, no need to do it now. 264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef PCAP_FDDIPAD 266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Note: the filter code was generated assuming 267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that p->fddipad was the amount of padding 268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * before the header, as that's what's required 269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in the kernel, so we run the filter before 270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * skipping that padding. 271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (fcode == NULL || 274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_filter(fcode, datap, bhp->bh_datalen, caplen)) { 275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct pcap_pkthdr pkthdr; 276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pkthdr.ts.tv_sec = bhp->bh_tstamp.tv_sec; 278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef _AIX 279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * AIX's BPF returns seconds/nanoseconds time 281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * stamps, not seconds/microseconds time stamps. 282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pkthdr.ts.tv_usec = bhp->bh_tstamp.tv_usec/1000; 284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pkthdr.ts.tv_usec = bhp->bh_tstamp.tv_usec; 286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef PCAP_FDDIPAD 288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (caplen > pad) 289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pkthdr.caplen = caplen - pad; 290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pkthdr.caplen = 0; 292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (bhp->bh_datalen > pad) 293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pkthdr.len = bhp->bh_datalen - pad; 294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pkthdr.len = 0; 296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project datap += pad; 297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pkthdr.caplen = caplen; 299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pkthdr.len = bhp->bh_datalen; 300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (*callback)(user, &pkthdr, datap); 302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bp += BPF_WORDALIGN(caplen + hdrlen); 303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (++n >= cnt && cnt > 0) { 304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->bp = bp; 305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->cc = ep - bp; 306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (n); 307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Skip this packet. 311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bp += BPF_WORDALIGN(caplen + hdrlen); 313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#undef bhp 316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->cc = 0; 317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (n); 318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_inject_bpf(pcap_t *p, const void *buf, size_t size) 322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int ret; 324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = write(p->fd, buf, size); 326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef __APPLE__ 327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ret == -1 && errno == EAFNOSUPPORT) { 328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * In Mac OS X, there's a bug wherein setting the 330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * BIOCSHDRCMPLT flag causes writes to fail; see, 331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * for example: 332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * http://cerberus.sourcefire.com/~jeff/archives/patches/macosx/BIOCSHDRCMPLT-10.3.3.patch 334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * So, if, on OS X, we get EAFNOSUPPORT from the write, we 336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * assume it's due to that bug, and turn off that flag 337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and try again. If we succeed, it either means that 338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * somebody applied the fix from that URL, or other patches 339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * for that bug from 340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * http://cerberus.sourcefire.com/~jeff/archives/patches/macosx/ 342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and are running a Darwin kernel with those fixes, or 344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that Apple fixed the problem in some OS X release. 345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int spoof_eth_src = 0; 347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) { 349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "send: can't turn off BIOCSHDRCMPLT: %s", 351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now try the write again. 357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = write(p->fd, buf, size); 359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* __APPLE__ */ 361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ret == -1) { 362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s", 363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (ret); 367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef _AIX 370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectbpf_odminit(char *errbuf) 372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project char *errstr; 374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (odm_initialize() == -1) { 376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (odm_err_msg(odmerrno, &errstr) == -1) 377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project errstr = "Unknown error"; 378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(errbuf, PCAP_ERRBUF_SIZE, 379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "bpf_load: odm_initialize failed: %s", 380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project errstr); 381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ((odmlockid = odm_lock("/etc/objrepos/config_lock", ODM_WAIT)) == -1) { 385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (odm_err_msg(odmerrno, &errstr) == -1) 386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project errstr = "Unknown error"; 387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(errbuf, PCAP_ERRBUF_SIZE, 388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "bpf_load: odm_lock of /etc/objrepos/config_lock failed: %s", 389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project errstr); 390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectbpf_odmcleanup(char *errbuf) 398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project char *errstr; 400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (odm_unlock(odmlockid) == -1) { 402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (odm_err_msg(odmerrno, &errstr) == -1) 403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project errstr = "Unknown error"; 404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(errbuf, PCAP_ERRBUF_SIZE, 405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "bpf_load: odm_unlock failed: %s", 406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project errstr); 407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (odm_terminate() == -1) { 411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (odm_err_msg(odmerrno, &errstr) == -1) 412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project errstr = "Unknown error"; 413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(errbuf, PCAP_ERRBUF_SIZE, 414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "bpf_load: odm_terminate failed: %s", 415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project errstr); 416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectbpf_load(char *errbuf) 424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project long major; 426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int *minors; 427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int numminors, i, rc; 428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project char buf[1024]; 429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct stat sbuf; 430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct bpf_config cfg_bpf; 431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct cfg_load cfg_ld; 432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct cfg_kmod cfg_km; 433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is very very close to what happens in the real implementation 436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * but I've fixed some (unlikely) bug situations. 437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (bpfloadedflag) 439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (bpf_odminit(errbuf) != 0) 442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project major = genmajor(BPF_NAME); 445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (major == -1) { 446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(errbuf, PCAP_ERRBUF_SIZE, 447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "bpf_load: genmajor failed: %s", pcap_strerror(errno)); 448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project minors = getminor(major, &numminors, BPF_NAME); 452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!minors) { 453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project minors = genminor("bpf", major, 0, BPF_MINORS, 1, 1); 454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!minors) { 455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(errbuf, PCAP_ERRBUF_SIZE, 456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "bpf_load: genminor failed: %s", 457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (bpf_odmcleanup(errbuf)) 463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project rc = stat(BPF_NODE "0", &sbuf); 466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (rc == -1 && errno != ENOENT) { 467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(errbuf, PCAP_ERRBUF_SIZE, 468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "bpf_load: can't stat %s: %s", 469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project BPF_NODE "0", pcap_strerror(errno)); 470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (rc == -1 || getmajor(sbuf.st_rdev) != major) { 474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project for (i = 0; i < BPF_MINORS; i++) { 475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sprintf(buf, "%s%d", BPF_NODE, i); 476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project unlink(buf); 477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (mknod(buf, S_IRUSR | S_IFCHR, domakedev(major, i)) == -1) { 478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(errbuf, PCAP_ERRBUF_SIZE, 479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "bpf_load: can't mknod %s: %s", 480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project buf, pcap_strerror(errno)); 481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Check if the driver is loaded */ 487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(&cfg_ld, 0x0, sizeof(cfg_ld)); 488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cfg_ld.path = buf; 489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sprintf(cfg_ld.path, "%s/%s", DRIVER_PATH, BPF_NAME); 490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ((sysconfig(SYS_QUERYLOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) || 491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (cfg_ld.kmid == 0)) { 492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Driver isn't loaded, load it now */ 493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (sysconfig(SYS_SINGLELOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) { 494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(errbuf, PCAP_ERRBUF_SIZE, 495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "bpf_load: could not load driver: %s", 496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strerror(errno)); 497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Configure the driver */ 502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cfg_km.cmd = CFG_INIT; 503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cfg_km.kmid = cfg_ld.kmid; 504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cfg_km.mdilen = sizeof(cfg_bpf); 505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cfg_km.mdiptr = (void *)&cfg_bpf; 506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project for (i = 0; i < BPF_MINORS; i++) { 507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cfg_bpf.devno = domakedev(major, i); 508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (sysconfig(SYS_CFGKMOD, (void *)&cfg_km, sizeof(cfg_km)) == -1) { 509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(errbuf, PCAP_ERRBUF_SIZE, 510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "bpf_load: could not configure driver: %s", 511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strerror(errno)); 512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpfloadedflag = 1; 517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline int 523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectbpf_open(pcap_t *p, char *errbuf) 524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int fd; 526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_CLONING_BPF 527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project static const char device[] = "/dev/bpf"; 528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int n = 0; 530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project char device[sizeof "/dev/bpf0000000000"]; 531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef _AIX 534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the bpf driver, if it isn't already loaded, 536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and create the BPF device entries, if they don't 537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * already exist. 538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (bpf_load(errbuf) == -1) 540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_CLONING_BPF 544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ((fd = open(device, O_RDWR)) == -1 && 545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (errno != EACCES || (fd = open(device, O_RDONLY)) == -1)) 546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(errbuf, PCAP_ERRBUF_SIZE, 547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "(cannot open device) %s: %s", device, pcap_strerror(errno)); 548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Go through all the minors and find one that isn't in use. 551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project do { 553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)snprintf(device, sizeof(device), "/dev/bpf%d", n++); 554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Initially try a read/write open (to allow the inject 556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * method to work). If that fails due to permission 557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * issues, fall back to read-only. This allows a 558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * non-root user to be granted specific access to pcap 559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * capabilities via file permissions. 560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - we should have an API that has a flag that 562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * controls whether to open read-only or read-write, 563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * so that denial of permission to send (or inability 564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to send, if sending packets isn't supported on 565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the device in question) can be indicated at open 566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * time. 567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fd = open(device, O_RDWR); 569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (fd == -1 && errno == EACCES) 570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fd = open(device, O_RDONLY); 571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } while (fd < 0 && errno == EBUSY); 572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX better message for all minors used 575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (fd < 0) 577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(errbuf, PCAP_ERRBUF_SIZE, "(no devices found) %s: %s", 578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project device, pcap_strerror(errno)); 579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (fd); 582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We include the OS's <net/bpf.h>, not our "pcap-bpf.h", so we probably 586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * don't get DLT_DOCSIS defined. 587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef DLT_DOCSIS 589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define DLT_DOCSIS 143 590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_t * 593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_open_live(const char *device, int snaplen, int promisc, int to_ms, 594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project char *ebuf) 595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int fd; 597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct ifreq ifr; 598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct bpf_version bv; 599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef BIOCGDLTLIST 600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct bpf_dltlist bdl; 601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) 603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int spoof_eth_src = 1; 604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int v; 606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_t *p; 607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct bpf_insn total_insn; 608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct bpf_program total_prog; 609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct utsname osinfo; 610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_API 612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (strstr(device, "dag")) { 613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return dag_open_live(device, snaplen, promisc, to_ms, ebuf); 614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_API */ 616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef BIOCGDLTLIST 618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(&bdl, 0, sizeof(bdl)); 619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p = (pcap_t *)malloc(sizeof(*p)); 622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p == NULL) { 623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", 624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(p, 0, sizeof(*p)); 628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fd = bpf_open(p, ebuf); 629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (fd < 0) 630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->fd = fd; 633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->snapshot = snaplen; 634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) { 636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s", 637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (bv.bv_major != BPF_MAJOR_VERSION || 641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bv.bv_minor < BPF_MINOR_VERSION) { 642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, 643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "kernel bpf filter out of date"); 644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Try finding a good size for the buffer; 32768 may be too 649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * big, so keep cutting it in half until we find a size 650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that works, or run out of sizes to try. If the default 651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is larger, don't make it smaller. 652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - there should be a user-accessible hook to set the 654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * initial buffer size. 655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ((ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) || v < 32768) 657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = 32768; 658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project for ( ; v != 0; v >>= 1) { 659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Ignore the return value - this is because the call fails 660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * on BPF systems that don't have kernel malloc. And if 661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the call fails, it's no big deal, we just continue to 662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * use the standard buffer size. 663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void) ioctl(fd, BIOCSBLEN, (caddr_t)&v); 665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0) 668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; /* that size worked; we're done */ 669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (errno != ENOBUFS) { 671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s", 672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project device, pcap_strerror(errno)); 673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (v == 0) { 678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, 679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "BIOCSBLEN: %s: No buffer size worked", device); 680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Get the data link layer type. */ 684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) { 685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s", 686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef _AIX 690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * AIX's BPF returns IFF_ types, not DLT_ types, in BIOCGDLT. 692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (v) { 694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IFT_ETHER: 696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IFT_ISO88023: 697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = DLT_EN10MB; 698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IFT_FDDI: 701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = DLT_FDDI; 702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IFT_ISO88025: 705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = DLT_IEEE802; 706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IFT_LOOP: 709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = DLT_NULL; 710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We don't know what to map this to yet. 715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown interface type %u", 717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v); 718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if _BSDI_VERSION - 0 >= 199510 722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* The SLIP and PPP link layer header changed in BSD/OS 2.1 */ 723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (v) { 724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_SLIP: 726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = DLT_SLIP_BSDOS; 727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP: 730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = DLT_PPP_BSDOS; 731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case 11: /*DLT_FR*/ 734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = DLT_FRELAY; 735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case 12: /*DLT_C_HDLC*/ 738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = DLT_CHDLC; 739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef PCAP_FDDIPAD 743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (v == DLT_FDDI) 744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->fddipad = PCAP_FDDIPAD; 745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->fddipad = 0; 747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = v; 749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef BIOCGDLTLIST 751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We know the default link type -- now determine all the DLTs 753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * this interface supports. If this fails with EINVAL, it's 754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * not fatal; we just don't get to use the feature later. 755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) == 0) { 757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int i; 758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int is_ethernet; 759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bdl.bfl_list = (u_int *) malloc(sizeof(u_int) * (bdl.bfl_len + 1)); 761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (bdl.bfl_list == NULL) { 762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", 763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) < 0) { 768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, 769478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "BIOCGDLTLIST: %s", pcap_strerror(errno)); 770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(bdl.bfl_list); 771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OK, for real Ethernet devices, add DLT_DOCSIS to the 776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * list, so that an application can let you choose it, 777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in case you're capturing DOCSIS traffic that a Cisco 778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Cable Modem Termination System is putting out onto 779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * an Ethernet (it doesn't put an Ethernet header onto 780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the wire, it puts raw DOCSIS frames out on the wire 781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * inside the low-level Ethernet framing). 782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * A "real Ethernet device" is defined here as a device 784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that has a link-layer type of DLT_EN10MB and that has 785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * no alternate link-layer types; that's done to exclude 786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 802.11 interfaces (which might or might not be the 787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * right thing to do, but I suspect it is - Ethernet <-> 788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 802.11 bridges would probably badly mishandle frames 789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that don't have Ethernet headers). 790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->linktype == DLT_EN10MB) { 792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project is_ethernet = 1; 793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project for (i = 0; i < bdl.bfl_len; i++) { 794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (bdl.bfl_list[i] != DLT_EN10MB) { 795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project is_ethernet = 0; 796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (is_ethernet) { 800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We reserved one more slot at the end of 802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the list. 803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bdl.bfl_list[bdl.bfl_len] = DLT_DOCSIS; 805478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bdl.bfl_len++; 806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 807478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_count = bdl.bfl_len; 809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list = bdl.bfl_list; 810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (errno != EINVAL) { 812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, 813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "BIOCGDLTLIST: %s", pcap_strerror(errno)); 814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 818478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If this is an Ethernet device, and we don't have a DLT_ list, 821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * give it a list with DLT_EN10MB and DLT_DOCSIS. (That'd give 822478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 802.11 interfaces DLT_DOCSIS, which isn't the right thing to 823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * do, but there's not much we can do about that without finding 824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * some other way of determining whether it's an Ethernet or 802.11 825478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * device.) 826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->linktype == DLT_EN10MB && p->dlt_count == 0) { 828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); 829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If that fails, just leave the list empty. 831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->dlt_list != NULL) { 833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list[0] = DLT_EN10MB; 834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list[1] = DLT_DOCSIS; 835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_count = 2; 836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) 840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Do a BIOCSHDRCMPLT, if defined, to turn that flag on, so 842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the link-layer source address isn't forcibly overwritten. 843478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (Should we ignore errors? Should we do this only if 844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we're open for writing?) 845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - I seem to remember some packet-sending bug in some 847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * BSDs - check CVS log for "bpf.c"? 848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 849478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) { 850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, 851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "BIOCSHDRCMPLT: %s", pcap_strerror(errno)); 852478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* set timeout */ 856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (to_ms != 0) { 857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - is this seconds/nanoseconds in AIX? 859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (Treating it as such doesn't fix the timeout 860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * problem described below.) 861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct timeval to; 863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project to.tv_sec = to_ms / 1000; 864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project to.tv_usec = (to_ms * 1000) % 1000000; 865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) { 866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s", 867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef _AIX 873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef BIOCIMMEDIATE 874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Darren Reed notes that 876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * On AIX (4.2 at least), if BIOCIMMEDIATE is not set, the 878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * timeout appears to be ignored and it waits until the buffer 879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is filled before returning. The result of not having it 880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * set is almost worse than useless if your BPF filter 881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is reducing things to only a few packets (i.e. one every 882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * second or so). 883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * so we turn BIOCIMMEDIATE mode on if this is AIX. 885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We don't turn it on for other platforms, as that means we 887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * get woken up for every packet, which may not be what we want; 888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in the Winter 1993 USENIX paper on BPF, they say: 889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Since a process might want to look at every packet on a 891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * network and the time between packets can be only a few 892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * microseconds, it is not possible to do a read system call 893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * per packet and BPF must collect the data from several 894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * packets and return it as a unit when the monitoring 895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * application does a read. 896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * which I infer is the reason for the timeout - it means we 898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * wait that amount of time, in the hopes that more packets 899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * will arrive and we'll get them all with one read. 900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Setting BIOCIMMEDIATE mode on FreeBSD (and probably other 902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * BSDs) causes the timeout to be ignored. 903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * On the other hand, some platforms (e.g., Linux) don't support 905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * timeouts, they just hand stuff to you as soon as it arrives; 906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * if that doesn't cause a problem on those platforms, it may 907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * be OK to have BIOCIMMEDIATE mode on BSD as well. 908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (Note, though, that applications may depend on the read 910478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * completing, even if no packets have arrived, when the timeout 911478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * expires, e.g. GUI applications that have to check for input 912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * while waiting for packets to arrive; a non-zero timeout 913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * prevents "select()" from working right on FreeBSD and 914478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * possibly other BSDs, as the timer doesn't start until a 915478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "read()" is done, so the timer isn't in effect if the 916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * application is blocked on a "select()", and the "select()" 917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * doesn't get woken up for a BPF device until the buffer 918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * fills up.) 919478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 920478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = 1; 921478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) { 922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCIMMEDIATE: %s", 923478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 924478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 925478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 926478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* BIOCIMMEDIATE */ 927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* _AIX */ 928478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 929478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (promisc) { 930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* set promiscuous mode, okay if it fails */ 931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) { 932478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s", 933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) { 938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s", 939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->bufsize = v; 943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->buffer = (u_char *)malloc(p->bufsize); 944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->buffer == NULL) { 945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", 946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef _AIX 950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* For some strange reason this seems to prevent the EFAULT 951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * problems we have experienced from AIX BPF. */ 952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(p->buffer, 0x0, p->bufsize); 953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If there's no filter program installed, there's 957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * no indication to the kernel of what the snapshot 958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * length should be, so no snapshotting is done. 959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Therefore, when we open the device, we install 961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * an "accept everything" filter with the specified 962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * snapshot length. 963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project total_insn.code = (u_short)(BPF_RET | BPF_K); 965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project total_insn.jt = 0; 966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project total_insn.jf = 0; 967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project total_insn.k = snaplen; 968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project total_prog.bf_len = 1; 970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project total_prog.bf_insns = &total_insn; 971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, BIOCSETF, (caddr_t)&total_prog) < 0) { 972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s", 973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * On most BPF platforms, either you can do a "select()" or 979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "poll()" on a BPF file descriptor and it works correctly, 980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * or you can do it and it will return "readable" if the 981478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * hold buffer is full but not if the timeout expires *and* 982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a non-blocking read will, if the hold buffer is empty 983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * but the store buffer isn't empty, rotate the buffers 984478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and return what packets are available. 985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * In the latter case, the fact that a non-blocking read 987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * will give you the available packets means you can work 988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * around the failure of "select()" and "poll()" to wake up 989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and return "readable" when the timeout expires by using 990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the timeout as the "select()" or "poll()" timeout, putting 991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the BPF descriptor into non-blocking mode, and read from 992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * it regardless of whether "select()" reports it as readable 993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * or not. 994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * However, in FreeBSD 4.3 and 4.4, "select()" and "poll()" 996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * won't wake up and return "readable" if the timer expires 997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and non-blocking reads return EWOULDBLOCK if the hold 998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * buffer is empty, even if the store buffer is non-empty. 999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This means the workaround in question won't work. 1001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Therefore, on FreeBSD 4.3 and 4.4, we set "p->selectable_fd" 1003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to -1, which means "sorry, you can't use 'select()' or 'poll()' 1004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * here". On all other BPF platforms, we set it to the FD for 1005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the BPF device; in NetBSD, OpenBSD, and Darwin, a non-blocking 1006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * read will, if the hold buffer is empty and the store buffer 1007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * isn't empty, rotate the buffers and return what packets are 1008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * there (and in sufficiently recent versions of OpenBSD 1009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "select()" and "poll()" should work correctly). 1010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - what about AIX? 1012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->selectable_fd = p->fd; /* assume select() works until we know otherwise */ 1014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (uname(&osinfo) == 0) { 1015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We can check what OS this is. 1017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (strcmp(osinfo.sysname, "FreeBSD") == 0) { 1019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (strncmp(osinfo.release, "4.3-", 4) == 0 || 1020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncmp(osinfo.release, "4.4-", 4) == 0) 1021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->selectable_fd = -1; 1022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->read_op = pcap_read_bpf; 1026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->inject_op = pcap_inject_bpf; 1027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->setfilter_op = pcap_setfilter_bpf; 1028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->setdirection_op = pcap_setdirection_bpf; 1029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->set_datalink_op = pcap_set_datalink_bpf; 1030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->getnonblock_op = pcap_getnonblock_fd; 1031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->setnonblock_op = pcap_setnonblock_fd; 1032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->stats_op = pcap_stats_bpf; 1033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->close_op = pcap_close_common; 1034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (p); 1036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bad: 1037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)close(fd); 1038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->dlt_list != NULL) 1039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(p->dlt_list); 1040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(p); 1041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 1042478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint 1045478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) 1046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_API 1048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (dag_platform_finddevs(alldevsp, errbuf) < 0) 1049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 1050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_API */ 1051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1052478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 1053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 1056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp) 1057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * It looks that BPF code generated by gen_protochain() is not 1060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * compatible with some of kernel BPF code (for example BSD/OS 3.1). 1061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Take a safer side for now. 1062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (no_optimize) { 1064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1065478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - what if we already have a filter in the kernel? 1066478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (install_bpf_program(p, fp) < 0) 1068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 1069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->md.use_bpf = 0; /* filtering in userland */ 1070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 1071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1074478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Free any user-mode filter we might happen to have installed. 1075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_freecode(&p->fcode); 1077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1078478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Try to install the kernel filter. 1080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) { 1082478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s", 1083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 1084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 1085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->md.use_bpf = 1; /* filtering in the kernel */ 1087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Discard any previously-received packets, as they might have 1090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * passed whatever filter was formerly in effect, but might 1091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * not pass this filter (BIOCSETF discards packets buffered 1092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in the kernel, so you can lose packets in any case). 1093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->cc = 0; 1095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 1096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 1099478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Set direction flag: Which packets do we accept on a forwarding 1100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * single device? IN, OUT or both? 1101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 1103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_setdirection_bpf(pcap_t *p, pcap_direction_t d) 1104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(BIOCSDIRECTION) 1106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int direction; 1107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project direction = (d == PCAP_D_IN) ? BPF_D_IN : 1109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ((d == PCAP_D_OUT) ? BPF_D_OUT : BPF_D_INOUT); 1110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, BIOCSDIRECTION, &direction) == -1) { 1111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void) snprintf(p->errbuf, sizeof(p->errbuf), 1112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "Cannot set direction to %s: %s", 1113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (d == PCAP_D_IN) ? "PCAP_D_IN" : 1114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ((d == PCAP_D_OUT) ? "PCAP_D_OUT" : "PCAP_D_INOUT"), 1115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strerror(errno)); 1116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 1117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 1119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#elif defined(BIOCSSEESENT) 1120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int seesent; 1121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We don't support PCAP_D_OUT. 1124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (d == PCAP_D_OUT) { 1126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(p->errbuf, sizeof(p->errbuf), 1127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "Setting direction to PCAP_D_OUT is not supported on BPF"); 1128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return -1; 1129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project seesent = (d == PCAP_D_INOUT); 1132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, BIOCSSEESENT, &seesent) == -1) { 1133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void) snprintf(p->errbuf, sizeof(p->errbuf), 1134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "Cannot set direction to %s: %s", 1135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (d == PCAP_D_INOUT) ? "PCAP_D_INOUT" : "PCAP_D_IN", 1136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strerror(errno)); 1137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 1138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 1140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 1141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void) snprintf(p->errbuf, sizeof(p->errbuf), 1142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "This system doesn't support BIOCSSEESENT, so the direction can't be set"); 1143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 1144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 1145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 1148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_set_datalink_bpf(pcap_t *p, int dlt) 1149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef BIOCSDLT 1151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) { 1152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void) snprintf(p->errbuf, sizeof(p->errbuf), 1153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "Cannot set DLT %d: %s", dlt, strerror(errno)); 1154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 1155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 1157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 1158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1159