1478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*- 2478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 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 * This code is derived from the Stanford/CMU enet packet filter, 6478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (net/enet.c) distributed as part of 4.3BSD, and code contributed 7478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence 8478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Berkeley Laboratory. 9478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 10478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Redistribution and use in source and binary forms, with or without 11478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * modification, are permitted provided that the following conditions 12478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * are met: 13478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 14478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * notice, this list of conditions and the following disclaimer. 15478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 16478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 17478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * documentation and/or other materials provided with the distribution. 18478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3. All advertising materials mentioning features or use of this software 19478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * must display the following acknowledgement: 20478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This product includes software developed by the University of 21478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * California, Berkeley and its contributors. 22478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4. Neither the name of the University nor the names of its contributors 23478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * may be used to endorse or promote products derived from this software 24478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * without specific prior written permission. 25478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 26478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SUCH DAMAGE. 37478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 38478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * @(#)bpf.c 7.5 (Berkeley) 7/15/91 39478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 40478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 41478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if !(defined(lint) || defined(KERNEL) || defined(_KERNEL)) 42478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic const char rcsid[] _U_ = 43478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.44 2003/11/15 23:24:07 guy Exp $ (LBL)"; 44478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 45478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 46478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_CONFIG_H 47478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "config.h" 48478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 49478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 50478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef WIN32 51478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 52478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <pcap-stdinc.h> 53478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 54478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else /* WIN32 */ 55478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 56478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/param.h> 57478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/types.h> 58478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/time.h> 59478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 60478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define SOLARIS (defined(sun) && (defined(__SVR4) || defined(__svr4__))) 61478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(__hpux) || SOLARIS 62478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project# include <sys/sysmacros.h> 63478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project# include <sys/stream.h> 64478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project# define mbuf msgb 65478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project# define m_next b_cont 66478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project# define MLEN(m) ((m)->b_wptr - (m)->b_rptr) 67478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project# define mtod(m,t) ((t)(m)->b_rptr) 68478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 69478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project# define MLEN(m) ((m)->m_len) 70478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 71478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 72478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* WIN32 */ 73478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 74478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <pcap-bpf.h> 75478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 76478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if !defined(KERNEL) && !defined(_KERNEL) 77478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdlib.h> 78478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 79478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 80478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define int32 bpf_int32 81478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define u_int32 bpf_u_int32 82478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 83478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef LBL_ALIGN 84478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 85478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - IA-64? If not, this probably won't work on Win64 IA-64 86478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * systems, unless LBL_ALIGN is defined elsewhere for them. 87478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - SuperH? If not, this probably won't work on WinCE SuperH 88478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * systems, unless LBL_ALIGN is defined elsewhere for them. 89478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 90478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(sparc) || defined(__sparc__) || defined(mips) || \ 91478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project defined(ibm032) || defined(__alpha) || defined(__hpux) || \ 92478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project defined(__arm__) 93478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define LBL_ALIGN 94478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 95478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 96478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 97478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef LBL_ALIGN 98478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef WIN32 99478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/in.h> 100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define EXTRACT_SHORT(p) ((u_short)ntohs(*(u_short *)p)) 103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define EXTRACT_LONG(p) (ntohl(*(u_int32 *)p)) 104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define EXTRACT_SHORT(p)\ 106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ((u_short)\ 107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ((u_short)*((u_char *)p+0)<<8|\ 108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (u_short)*((u_char *)p+1)<<0)) 109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define EXTRACT_LONG(p)\ 110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ((u_int32)*((u_char *)p+0)<<24|\ 111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (u_int32)*((u_char *)p+1)<<16|\ 112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (u_int32)*((u_char *)p+2)<<8|\ 113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (u_int32)*((u_char *)p+3)<<0) 114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(KERNEL) || defined(_KERNEL) 117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project# if !defined(__hpux) && !SOLARIS 118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/mbuf.h> 119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project# endif 120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define MINDEX(len, _m, _k) \ 121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ \ 122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project len = MLEN(m); \ 123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while ((_k) >= len) { \ 124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (_k) -= len; \ 125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (_m) = (_m)->m_next; \ 126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ((_m) == 0) \ 127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; \ 128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project len = MLEN(m); \ 129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } \ 130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectm_xword(m, k, err) 134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct mbuf *m; 135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int k, *err; 136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int len; 138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register u_char *cp, *np; 139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct mbuf *m0; 140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project MINDEX(len, m, k); 142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cp = mtod(m, u_char *) + k; 143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (len - k >= 4) { 144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *err = 0; 145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return EXTRACT_LONG(cp); 146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project m0 = m->m_next; 148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (m0 == 0 || MLEN(m0) + len - k < 4) 149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *err = 0; 151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project np = mtod(m0, u_char *); 152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (len - k) { 153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case 1: 155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (cp[0] << 24) | (np[0] << 16) | (np[1] << 8) | np[2]; 156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case 2: 158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (cp[0] << 24) | (cp[1] << 16) | (np[0] << 8) | np[1]; 159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | np[0]; 162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bad: 164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *err = 1; 165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectm_xhalf(m, k, err) 170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct mbuf *m; 171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int k, *err; 172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int len; 174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register u_char *cp; 175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct mbuf *m0; 176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project MINDEX(len, m, k); 178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cp = mtod(m, u_char *) + k; 179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (len - k >= 2) { 180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *err = 0; 181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return EXTRACT_SHORT(cp); 182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project m0 = m->m_next; 184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (m0 == 0) 185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *err = 0; 187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (cp[0] << 8) | mtod(m0, u_char *)[0]; 188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bad: 189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *err = 1; 190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Execute the filter program starting at pc on the packet p 196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * wirelen is the length of the original packet 197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * buflen is the amount of data present 198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For the kernel, p is assumed to be a pointer to an mbuf if buflen is 0, 199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in all other cases, p is a pointer to a buffer and buflen is its size. 200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectu_int 202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectbpf_filter(pc, p, wirelen, buflen) 203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct bpf_insn *pc; 204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register u_char *p; 205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int wirelen; 206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register u_int buflen; 207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register u_int32 A, X; 209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int k; 210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int32 mem[BPF_MEMWORDS]; 211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(KERNEL) || defined(_KERNEL) 212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct mbuf *m, *n; 213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int merr, len; 214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (buflen == 0) { 216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project m = (struct mbuf *)p; 217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p = mtod(m, u_char *); 218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project buflen = MLEN(m); 219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project m = NULL; 221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (pc == 0) 224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * No filter means accept all. 226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (u_int)-1; 228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A = 0; 229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project X = 0; 230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project --pc; 231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (1) { 232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ++pc; 233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (pc->code) { 234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(KERNEL) || defined(_KERNEL) 237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_RET|BPF_K: 242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (u_int)pc->k; 243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_RET|BPF_A: 245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (u_int)A; 246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_LD|BPF_W|BPF_ABS: 248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project k = pc->k; 249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (k + sizeof(int32) > buflen) { 250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(KERNEL) || defined(_KERNEL) 251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (m == NULL) 252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A = m_xword(m, k, &merr); 254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (merr != 0) 255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A = EXTRACT_LONG(&p[k]); 262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_LD|BPF_H|BPF_ABS: 265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project k = pc->k; 266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (k + sizeof(short) > buflen) { 267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(KERNEL) || defined(_KERNEL) 268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (m == NULL) 269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A = m_xhalf(m, k, &merr); 271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (merr != 0) 272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A = EXTRACT_SHORT(&p[k]); 279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_LD|BPF_B|BPF_ABS: 282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project k = pc->k; 283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (k >= buflen) { 284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(KERNEL) || defined(_KERNEL) 285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (m == NULL) 286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project n = m; 288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project MINDEX(len, n, k); 289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A = mtod(n, u_char *)[k]; 290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A = p[k]; 296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_LD|BPF_W|BPF_LEN: 299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A = wirelen; 300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_LDX|BPF_W|BPF_LEN: 303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project X = wirelen; 304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_LD|BPF_W|BPF_IND: 307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project k = X + pc->k; 308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (k + sizeof(int32) > buflen) { 309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(KERNEL) || defined(_KERNEL) 310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (m == NULL) 311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A = m_xword(m, k, &merr); 313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (merr != 0) 314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A = EXTRACT_LONG(&p[k]); 321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_LD|BPF_H|BPF_IND: 324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project k = X + pc->k; 325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (k + sizeof(short) > buflen) { 326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(KERNEL) || defined(_KERNEL) 327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (m == NULL) 328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A = m_xhalf(m, k, &merr); 330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (merr != 0) 331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A = EXTRACT_SHORT(&p[k]); 338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_LD|BPF_B|BPF_IND: 341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project k = X + pc->k; 342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (k >= buflen) { 343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(KERNEL) || defined(_KERNEL) 344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (m == NULL) 345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project n = m; 347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project MINDEX(len, n, k); 348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A = mtod(n, u_char *)[k]; 349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A = p[k]; 355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_LDX|BPF_MSH|BPF_B: 358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project k = pc->k; 359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (k >= buflen) { 360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(KERNEL) || defined(_KERNEL) 361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (m == NULL) 362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project n = m; 364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project MINDEX(len, n, k); 365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project X = (mtod(n, char *)[k] & 0xf) << 2; 366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project X = (p[pc->k] & 0xf) << 2; 372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_LD|BPF_IMM: 375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A = pc->k; 376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_LDX|BPF_IMM: 379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project X = pc->k; 380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_LD|BPF_MEM: 383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A = mem[pc->k]; 384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_LDX|BPF_MEM: 387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project X = mem[pc->k]; 388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_ST: 391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project mem[pc->k] = A; 392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_STX: 395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project mem[pc->k] = X; 396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_JMP|BPF_JA: 399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc += pc->k; 400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_JMP|BPF_JGT|BPF_K: 403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc += (A > pc->k) ? pc->jt : pc->jf; 404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_JMP|BPF_JGE|BPF_K: 407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc += (A >= pc->k) ? pc->jt : pc->jf; 408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_JMP|BPF_JEQ|BPF_K: 411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc += (A == pc->k) ? pc->jt : pc->jf; 412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_JMP|BPF_JSET|BPF_K: 415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc += (A & pc->k) ? pc->jt : pc->jf; 416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_JMP|BPF_JGT|BPF_X: 419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc += (A > X) ? pc->jt : pc->jf; 420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_JMP|BPF_JGE|BPF_X: 423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc += (A >= X) ? pc->jt : pc->jf; 424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_JMP|BPF_JEQ|BPF_X: 427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc += (A == X) ? pc->jt : pc->jf; 428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_JMP|BPF_JSET|BPF_X: 431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pc += (A & X) ? pc->jt : pc->jf; 432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_ALU|BPF_ADD|BPF_X: 435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A += X; 436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_ALU|BPF_SUB|BPF_X: 439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A -= X; 440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_ALU|BPF_MUL|BPF_X: 443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A *= X; 444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_ALU|BPF_DIV|BPF_X: 447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (X == 0) 448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A /= X; 450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_ALU|BPF_AND|BPF_X: 453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A &= X; 454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_ALU|BPF_OR|BPF_X: 457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A |= X; 458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_ALU|BPF_LSH|BPF_X: 461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A <<= X; 462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_ALU|BPF_RSH|BPF_X: 465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A >>= X; 466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_ALU|BPF_ADD|BPF_K: 469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A += pc->k; 470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_ALU|BPF_SUB|BPF_K: 473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A -= pc->k; 474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_ALU|BPF_MUL|BPF_K: 477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A *= pc->k; 478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_ALU|BPF_DIV|BPF_K: 481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A /= pc->k; 482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_ALU|BPF_AND|BPF_K: 485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A &= pc->k; 486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_ALU|BPF_OR|BPF_K: 489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A |= pc->k; 490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_ALU|BPF_LSH|BPF_K: 493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A <<= pc->k; 494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_ALU|BPF_RSH|BPF_K: 497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A >>= pc->k; 498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_ALU|BPF_NEG: 501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A = -A; 502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_MISC|BPF_TAX: 505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project X = A; 506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case BPF_MISC|BPF_TXA: 509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project A = X; 510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Return true if the 'fcode' is a valid filter program. 518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The constraints are that each jump be forward and to a valid 519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * code. The code must terminate with either an accept or reject. 520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 'valid' is an array for use by the routine (it must be at least 521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 'len' bytes long). 522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The kernel needs to be able to verify an application's filter code. 524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Otherwise, a bogus program could easily crash the system. 525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint 527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectbpf_validate(f, len) 528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct bpf_insn *f; 529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int len; 530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int i; 532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct bpf_insn *p; 533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project for (i = 0; i < len; ++i) { 535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check that that jumps are forward, and within 537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the code block. 538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p = &f[i]; 540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (BPF_CLASS(p->code) == BPF_JMP) { 541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int from = i + 1; 542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (BPF_OP(p->code) == BPF_JA) { 544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (from + p->k >= (unsigned)len) 545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (from + p->jt >= len || from + p->jf >= len) 548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check that memory operations use valid addresses. 552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ((BPF_CLASS(p->code) == BPF_ST || 554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (BPF_CLASS(p->code) == BPF_LD && 555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (p->code & 0xe0) == BPF_MEM)) && 556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (p->k >= BPF_MEMWORDS || p->k < 0)) 557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for constant division by 0. 560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0) 562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return BPF_CLASS(f[len - 1].code) == BPF_RET; 565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 566