1139823Simp/*- 21541Srgrimes * Copyright (c) 1990, 1991, 1993 31541Srgrimes * The Regents of the University of California. All rights reserved. 41541Srgrimes * 51541Srgrimes * This code is derived from the Stanford/CMU enet packet filter, 61541Srgrimes * (net/enet.c) distributed as part of 4.3BSD, and code contributed 71541Srgrimes * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence 81541Srgrimes * Berkeley Laboratory. 91541Srgrimes * 101541Srgrimes * Redistribution and use in source and binary forms, with or without 111541Srgrimes * modification, are permitted provided that the following conditions 121541Srgrimes * are met: 131541Srgrimes * 1. Redistributions of source code must retain the above copyright 141541Srgrimes * notice, this list of conditions and the following disclaimer. 151541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 161541Srgrimes * notice, this list of conditions and the following disclaimer in the 171541Srgrimes * documentation and/or other materials provided with the distribution. 181541Srgrimes * 4. Neither the name of the University nor the names of its contributors 191541Srgrimes * may be used to endorse or promote products derived from this software 201541Srgrimes * without specific prior written permission. 211541Srgrimes * 221541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 231541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 241541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 251541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 261541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 271541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 281541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 291541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 301541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 311541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 321541Srgrimes * SUCH DAMAGE. 331541Srgrimes * 341541Srgrimes * @(#)bpf_filter.c 8.1 (Berkeley) 6/10/93 351541Srgrimes */ 361541Srgrimes 37174895Srwatson#include <sys/cdefs.h> 38174895Srwatson__FBSDID("$FreeBSD$"); 39174895Srwatson 401541Srgrimes#include <sys/param.h> 411541Srgrimes 42182184Sjkim#if !defined(_KERNEL) || defined(sun) 431541Srgrimes#include <netinet/in.h> 441541Srgrimes#endif 451541Srgrimes 4699419Speter#ifndef __i386__ 471541Srgrimes#define BPF_ALIGN 481541Srgrimes#endif 491541Srgrimes 501541Srgrimes#ifndef BPF_ALIGN 5140779Sdfr#define EXTRACT_SHORT(p) ((u_int16_t)ntohs(*(u_int16_t *)p)) 5240779Sdfr#define EXTRACT_LONG(p) (ntohl(*(u_int32_t *)p)) 531541Srgrimes#else 541541Srgrimes#define EXTRACT_SHORT(p)\ 5540779Sdfr ((u_int16_t)\ 5640779Sdfr ((u_int16_t)*((u_char *)p+0)<<8|\ 5740779Sdfr (u_int16_t)*((u_char *)p+1)<<0)) 581541Srgrimes#define EXTRACT_LONG(p)\ 5940779Sdfr ((u_int32_t)*((u_char *)p+0)<<24|\ 6040779Sdfr (u_int32_t)*((u_char *)p+1)<<16|\ 6140779Sdfr (u_int32_t)*((u_char *)p+2)<<8|\ 6240779Sdfr (u_int32_t)*((u_char *)p+3)<<0) 631541Srgrimes#endif 641541Srgrimes 6555205Speter#ifdef _KERNEL 661541Srgrimes#include <sys/mbuf.h> 67182184Sjkim#else 68182184Sjkim#include <stdlib.h> 6941588Seivind#endif 7041588Seivind#include <net/bpf.h> 7155205Speter#ifdef _KERNEL 721541Srgrimes#define MINDEX(m, k) \ 731541Srgrimes{ \ 741541Srgrimes register int len = m->m_len; \ 751541Srgrimes \ 761541Srgrimes while (k >= len) { \ 771541Srgrimes k -= len; \ 781541Srgrimes m = m->m_next; \ 791541Srgrimes if (m == 0) \ 80182455Sjkim return (0); \ 811541Srgrimes len = m->m_len; \ 821541Srgrimes } \ 831541Srgrimes} 841541Srgrimes 8592725Salfredstatic u_int16_t m_xhalf(struct mbuf *m, bpf_u_int32 k, int *err); 8692725Salfredstatic u_int32_t m_xword(struct mbuf *m, bpf_u_int32 k, int *err); 8712579Sbde 8841588Seivindstatic u_int32_t 89177003Srwatsonm_xword(struct mbuf *m, bpf_u_int32 k, int *err) 901541Srgrimes{ 91177003Srwatson size_t len; 92177003Srwatson u_char *cp, *np; 93177003Srwatson struct mbuf *m0; 941541Srgrimes 951541Srgrimes len = m->m_len; 961541Srgrimes while (k >= len) { 971541Srgrimes k -= len; 981541Srgrimes m = m->m_next; 991541Srgrimes if (m == 0) 1001541Srgrimes goto bad; 1011541Srgrimes len = m->m_len; 1021541Srgrimes } 1031541Srgrimes cp = mtod(m, u_char *) + k; 1041541Srgrimes if (len - k >= 4) { 1051541Srgrimes *err = 0; 106182456Sjkim return (EXTRACT_LONG(cp)); 1071541Srgrimes } 1081541Srgrimes m0 = m->m_next; 1091541Srgrimes if (m0 == 0 || m0->m_len + len - k < 4) 1101541Srgrimes goto bad; 1111541Srgrimes *err = 0; 1121541Srgrimes np = mtod(m0, u_char *); 1131541Srgrimes switch (len - k) { 1141541Srgrimes case 1: 115182455Sjkim return (((u_int32_t)cp[0] << 24) | 11641588Seivind ((u_int32_t)np[0] << 16) | 11741588Seivind ((u_int32_t)np[1] << 8) | 118182455Sjkim (u_int32_t)np[2]); 1191541Srgrimes 1201541Srgrimes case 2: 121182455Sjkim return (((u_int32_t)cp[0] << 24) | 12241588Seivind ((u_int32_t)cp[1] << 16) | 12341588Seivind ((u_int32_t)np[0] << 8) | 124182455Sjkim (u_int32_t)np[1]); 1251541Srgrimes 1261541Srgrimes default: 127182455Sjkim return (((u_int32_t)cp[0] << 24) | 12841588Seivind ((u_int32_t)cp[1] << 16) | 12941588Seivind ((u_int32_t)cp[2] << 8) | 130182455Sjkim (u_int32_t)np[0]); 1311541Srgrimes } 1321541Srgrimes bad: 1331541Srgrimes *err = 1; 134177003Srwatson return (0); 1351541Srgrimes} 1361541Srgrimes 13741588Seivindstatic u_int16_t 138177003Srwatsonm_xhalf(struct mbuf *m, bpf_u_int32 k, int *err) 1391541Srgrimes{ 140177003Srwatson size_t len; 141177003Srwatson u_char *cp; 142177003Srwatson struct mbuf *m0; 1431541Srgrimes 1441541Srgrimes len = m->m_len; 1451541Srgrimes while (k >= len) { 1461541Srgrimes k -= len; 1471541Srgrimes m = m->m_next; 1481541Srgrimes if (m == 0) 1491541Srgrimes goto bad; 1501541Srgrimes len = m->m_len; 1511541Srgrimes } 1521541Srgrimes cp = mtod(m, u_char *) + k; 1531541Srgrimes if (len - k >= 2) { 1541541Srgrimes *err = 0; 155177003Srwatson return (EXTRACT_SHORT(cp)); 1561541Srgrimes } 1571541Srgrimes m0 = m->m_next; 1581541Srgrimes if (m0 == 0) 1591541Srgrimes goto bad; 1601541Srgrimes *err = 0; 161177003Srwatson return ((cp[0] << 8) | mtod(m0, u_char *)[0]); 1621541Srgrimes bad: 1631541Srgrimes *err = 1; 164177003Srwatson return (0); 1651541Srgrimes} 1661541Srgrimes#endif 1671541Srgrimes 1681541Srgrimes/* 1691541Srgrimes * Execute the filter program starting at pc on the packet p 1701541Srgrimes * wirelen is the length of the original packet 1711541Srgrimes * buflen is the amount of data present 1721541Srgrimes */ 1731541Srgrimesu_int 174177003Srwatsonbpf_filter(const struct bpf_insn *pc, u_char *p, u_int wirelen, u_int buflen) 1751541Srgrimes{ 176177003Srwatson u_int32_t A = 0, X = 0; 177177003Srwatson bpf_u_int32 k; 178172154Sdwmalone u_int32_t mem[BPF_MEMWORDS]; 1791541Srgrimes 180224044Smp bzero(mem, sizeof(mem)); 181224044Smp 182177003Srwatson if (pc == NULL) 1831541Srgrimes /* 1841541Srgrimes * No filter means accept all. 1851541Srgrimes */ 186177003Srwatson return ((u_int)-1); 1871549Srgrimes 1881541Srgrimes --pc; 1891541Srgrimes while (1) { 1901541Srgrimes ++pc; 1911541Srgrimes switch (pc->code) { 1921541Srgrimes default: 19355205Speter#ifdef _KERNEL 194182455Sjkim return (0); 1951541Srgrimes#else 1961541Srgrimes abort(); 1978876Srgrimes#endif 198177003Srwatson 1991541Srgrimes case BPF_RET|BPF_K: 200177003Srwatson return ((u_int)pc->k); 2011541Srgrimes 2021541Srgrimes case BPF_RET|BPF_A: 203177003Srwatson return ((u_int)A); 2041541Srgrimes 2051541Srgrimes case BPF_LD|BPF_W|BPF_ABS: 2061541Srgrimes k = pc->k; 20741588Seivind if (k > buflen || sizeof(int32_t) > buflen - k) { 20855205Speter#ifdef _KERNEL 2091541Srgrimes int merr; 2101541Srgrimes 2111541Srgrimes if (buflen != 0) 212182455Sjkim return (0); 2131541Srgrimes A = m_xword((struct mbuf *)p, k, &merr); 2141541Srgrimes if (merr != 0) 215182455Sjkim return (0); 2161541Srgrimes continue; 2171541Srgrimes#else 218177003Srwatson return (0); 2191541Srgrimes#endif 2201541Srgrimes } 2211541Srgrimes#ifdef BPF_ALIGN 22240779Sdfr if (((intptr_t)(p + k) & 3) != 0) 2231541Srgrimes A = EXTRACT_LONG(&p[k]); 2241541Srgrimes else 2251541Srgrimes#endif 22640779Sdfr A = ntohl(*(int32_t *)(p + k)); 2271541Srgrimes continue; 2281541Srgrimes 2291541Srgrimes case BPF_LD|BPF_H|BPF_ABS: 2301541Srgrimes k = pc->k; 23141588Seivind if (k > buflen || sizeof(int16_t) > buflen - k) { 23255205Speter#ifdef _KERNEL 2331541Srgrimes int merr; 2341541Srgrimes 2351541Srgrimes if (buflen != 0) 236182455Sjkim return (0); 2371541Srgrimes A = m_xhalf((struct mbuf *)p, k, &merr); 2381541Srgrimes continue; 2391541Srgrimes#else 240182455Sjkim return (0); 2411541Srgrimes#endif 2421541Srgrimes } 2431541Srgrimes A = EXTRACT_SHORT(&p[k]); 2441541Srgrimes continue; 2451541Srgrimes 2461541Srgrimes case BPF_LD|BPF_B|BPF_ABS: 2471541Srgrimes k = pc->k; 2481541Srgrimes if (k >= buflen) { 24955205Speter#ifdef _KERNEL 250177003Srwatson struct mbuf *m; 2511541Srgrimes 2521541Srgrimes if (buflen != 0) 253182455Sjkim return (0); 2541541Srgrimes m = (struct mbuf *)p; 2551541Srgrimes MINDEX(m, k); 2561541Srgrimes A = mtod(m, u_char *)[k]; 2571541Srgrimes continue; 2581541Srgrimes#else 259182455Sjkim return (0); 2601541Srgrimes#endif 2611541Srgrimes } 2621541Srgrimes A = p[k]; 2631541Srgrimes continue; 2641541Srgrimes 2651541Srgrimes case BPF_LD|BPF_W|BPF_LEN: 2661541Srgrimes A = wirelen; 2671541Srgrimes continue; 2681541Srgrimes 2691541Srgrimes case BPF_LDX|BPF_W|BPF_LEN: 2701541Srgrimes X = wirelen; 2711541Srgrimes continue; 2721541Srgrimes 2731541Srgrimes case BPF_LD|BPF_W|BPF_IND: 2741541Srgrimes k = X + pc->k; 27545574Seivind if (pc->k > buflen || X > buflen - pc->k || 27645574Seivind sizeof(int32_t) > buflen - k) { 27755205Speter#ifdef _KERNEL 2781541Srgrimes int merr; 2791541Srgrimes 2801541Srgrimes if (buflen != 0) 281177003Srwatson return (0); 2821541Srgrimes A = m_xword((struct mbuf *)p, k, &merr); 2831541Srgrimes if (merr != 0) 284177003Srwatson return (0); 2851541Srgrimes continue; 2861541Srgrimes#else 287177003Srwatson return (0); 2881541Srgrimes#endif 2891541Srgrimes } 2901541Srgrimes#ifdef BPF_ALIGN 29140779Sdfr if (((intptr_t)(p + k) & 3) != 0) 2921541Srgrimes A = EXTRACT_LONG(&p[k]); 2931541Srgrimes else 2941541Srgrimes#endif 29540779Sdfr A = ntohl(*(int32_t *)(p + k)); 2961541Srgrimes continue; 2971541Srgrimes 2981541Srgrimes case BPF_LD|BPF_H|BPF_IND: 2991541Srgrimes k = X + pc->k; 30045574Seivind if (X > buflen || pc->k > buflen - X || 30145574Seivind sizeof(int16_t) > buflen - k) { 30255205Speter#ifdef _KERNEL 3031541Srgrimes int merr; 3041541Srgrimes 3051541Srgrimes if (buflen != 0) 306182455Sjkim return (0); 3071541Srgrimes A = m_xhalf((struct mbuf *)p, k, &merr); 3081541Srgrimes if (merr != 0) 309177003Srwatson return (0); 3101541Srgrimes continue; 3111541Srgrimes#else 312177003Srwatson return (0); 3131541Srgrimes#endif 3141541Srgrimes } 3151541Srgrimes A = EXTRACT_SHORT(&p[k]); 3161541Srgrimes continue; 3171541Srgrimes 3181541Srgrimes case BPF_LD|BPF_B|BPF_IND: 3191541Srgrimes k = X + pc->k; 32048548Sbde if (pc->k >= buflen || X >= buflen - pc->k) { 32155205Speter#ifdef _KERNEL 322177003Srwatson struct mbuf *m; 3231541Srgrimes 3241541Srgrimes if (buflen != 0) 325182455Sjkim return (0); 3261541Srgrimes m = (struct mbuf *)p; 3271541Srgrimes MINDEX(m, k); 328159018Sdwmalone A = mtod(m, u_char *)[k]; 3291541Srgrimes continue; 3301541Srgrimes#else 331177003Srwatson return (0); 3321541Srgrimes#endif 3331541Srgrimes } 3341541Srgrimes A = p[k]; 3351541Srgrimes continue; 3361541Srgrimes 3371541Srgrimes case BPF_LDX|BPF_MSH|BPF_B: 3381541Srgrimes k = pc->k; 3391541Srgrimes if (k >= buflen) { 34055205Speter#ifdef _KERNEL 3411541Srgrimes register struct mbuf *m; 3421541Srgrimes 3431541Srgrimes if (buflen != 0) 344182455Sjkim return (0); 3451541Srgrimes m = (struct mbuf *)p; 3461541Srgrimes MINDEX(m, k); 347159018Sdwmalone X = (mtod(m, u_char *)[k] & 0xf) << 2; 3481541Srgrimes continue; 3491541Srgrimes#else 350182455Sjkim return (0); 3511541Srgrimes#endif 3521541Srgrimes } 3531541Srgrimes X = (p[pc->k] & 0xf) << 2; 3541541Srgrimes continue; 3551541Srgrimes 3561541Srgrimes case BPF_LD|BPF_IMM: 3571541Srgrimes A = pc->k; 3581541Srgrimes continue; 3591541Srgrimes 3601541Srgrimes case BPF_LDX|BPF_IMM: 3611541Srgrimes X = pc->k; 3621541Srgrimes continue; 3631541Srgrimes 3641541Srgrimes case BPF_LD|BPF_MEM: 3651541Srgrimes A = mem[pc->k]; 3661541Srgrimes continue; 3678876Srgrimes 3681541Srgrimes case BPF_LDX|BPF_MEM: 3691541Srgrimes X = mem[pc->k]; 3701541Srgrimes continue; 3711541Srgrimes 3721541Srgrimes case BPF_ST: 3731541Srgrimes mem[pc->k] = A; 3741541Srgrimes continue; 3751541Srgrimes 3761541Srgrimes case BPF_STX: 3771541Srgrimes mem[pc->k] = X; 3781541Srgrimes continue; 3791541Srgrimes 3801541Srgrimes case BPF_JMP|BPF_JA: 3811541Srgrimes pc += pc->k; 3821541Srgrimes continue; 3831541Srgrimes 3841541Srgrimes case BPF_JMP|BPF_JGT|BPF_K: 3851541Srgrimes pc += (A > pc->k) ? pc->jt : pc->jf; 3861541Srgrimes continue; 3871541Srgrimes 3881541Srgrimes case BPF_JMP|BPF_JGE|BPF_K: 3891541Srgrimes pc += (A >= pc->k) ? pc->jt : pc->jf; 3901541Srgrimes continue; 3911541Srgrimes 3921541Srgrimes case BPF_JMP|BPF_JEQ|BPF_K: 3931541Srgrimes pc += (A == pc->k) ? pc->jt : pc->jf; 3941541Srgrimes continue; 3951541Srgrimes 3961541Srgrimes case BPF_JMP|BPF_JSET|BPF_K: 3971541Srgrimes pc += (A & pc->k) ? pc->jt : pc->jf; 3981541Srgrimes continue; 3991541Srgrimes 4001541Srgrimes case BPF_JMP|BPF_JGT|BPF_X: 4011541Srgrimes pc += (A > X) ? pc->jt : pc->jf; 4021541Srgrimes continue; 4031541Srgrimes 4041541Srgrimes case BPF_JMP|BPF_JGE|BPF_X: 4051541Srgrimes pc += (A >= X) ? pc->jt : pc->jf; 4061541Srgrimes continue; 4071541Srgrimes 4081541Srgrimes case BPF_JMP|BPF_JEQ|BPF_X: 4091541Srgrimes pc += (A == X) ? pc->jt : pc->jf; 4101541Srgrimes continue; 4111541Srgrimes 4121541Srgrimes case BPF_JMP|BPF_JSET|BPF_X: 4131541Srgrimes pc += (A & X) ? pc->jt : pc->jf; 4141541Srgrimes continue; 4151541Srgrimes 4161541Srgrimes case BPF_ALU|BPF_ADD|BPF_X: 4171541Srgrimes A += X; 4181541Srgrimes continue; 4198876Srgrimes 4201541Srgrimes case BPF_ALU|BPF_SUB|BPF_X: 4211541Srgrimes A -= X; 4221541Srgrimes continue; 4238876Srgrimes 4241541Srgrimes case BPF_ALU|BPF_MUL|BPF_X: 4251541Srgrimes A *= X; 4261541Srgrimes continue; 4278876Srgrimes 4281541Srgrimes case BPF_ALU|BPF_DIV|BPF_X: 4291541Srgrimes if (X == 0) 430182455Sjkim return (0); 4311541Srgrimes A /= X; 4321541Srgrimes continue; 4338876Srgrimes 4341541Srgrimes case BPF_ALU|BPF_AND|BPF_X: 4351541Srgrimes A &= X; 4361541Srgrimes continue; 4378876Srgrimes 4381541Srgrimes case BPF_ALU|BPF_OR|BPF_X: 4391541Srgrimes A |= X; 4401541Srgrimes continue; 4411541Srgrimes 4421541Srgrimes case BPF_ALU|BPF_LSH|BPF_X: 4431541Srgrimes A <<= X; 4441541Srgrimes continue; 4451541Srgrimes 4461541Srgrimes case BPF_ALU|BPF_RSH|BPF_X: 4471541Srgrimes A >>= X; 4481541Srgrimes continue; 4491541Srgrimes 4501541Srgrimes case BPF_ALU|BPF_ADD|BPF_K: 4511541Srgrimes A += pc->k; 4521541Srgrimes continue; 4538876Srgrimes 4541541Srgrimes case BPF_ALU|BPF_SUB|BPF_K: 4551541Srgrimes A -= pc->k; 4561541Srgrimes continue; 4578876Srgrimes 4581541Srgrimes case BPF_ALU|BPF_MUL|BPF_K: 4591541Srgrimes A *= pc->k; 4601541Srgrimes continue; 4618876Srgrimes 4621541Srgrimes case BPF_ALU|BPF_DIV|BPF_K: 4631541Srgrimes A /= pc->k; 4641541Srgrimes continue; 4658876Srgrimes 4661541Srgrimes case BPF_ALU|BPF_AND|BPF_K: 4671541Srgrimes A &= pc->k; 4681541Srgrimes continue; 4698876Srgrimes 4701541Srgrimes case BPF_ALU|BPF_OR|BPF_K: 4711541Srgrimes A |= pc->k; 4721541Srgrimes continue; 4731541Srgrimes 4741541Srgrimes case BPF_ALU|BPF_LSH|BPF_K: 4751541Srgrimes A <<= pc->k; 4761541Srgrimes continue; 4771541Srgrimes 4781541Srgrimes case BPF_ALU|BPF_RSH|BPF_K: 4791541Srgrimes A >>= pc->k; 4801541Srgrimes continue; 4811541Srgrimes 4821541Srgrimes case BPF_ALU|BPF_NEG: 4831541Srgrimes A = -A; 4841541Srgrimes continue; 4851541Srgrimes 4861541Srgrimes case BPF_MISC|BPF_TAX: 4871541Srgrimes X = A; 4881541Srgrimes continue; 4891541Srgrimes 4901541Srgrimes case BPF_MISC|BPF_TXA: 4911541Srgrimes A = X; 4921541Srgrimes continue; 4931541Srgrimes } 4941541Srgrimes } 4951541Srgrimes} 4961541Srgrimes 49755205Speter#ifdef _KERNEL 498182454Sjkimstatic const u_short bpf_code_map[] = { 499182412Sjkim 0x10ff, /* 0x00-0x0f: 1111111100001000 */ 500182412Sjkim 0x3070, /* 0x10-0x1f: 0000111000001100 */ 501182412Sjkim 0x3131, /* 0x20-0x2f: 1000110010001100 */ 502182412Sjkim 0x3031, /* 0x30-0x3f: 1000110000001100 */ 503182412Sjkim 0x3131, /* 0x40-0x4f: 1000110010001100 */ 504182412Sjkim 0x1011, /* 0x50-0x5f: 1000100000001000 */ 505182412Sjkim 0x1013, /* 0x60-0x6f: 1100100000001000 */ 506182412Sjkim 0x1010, /* 0x70-0x7f: 0000100000001000 */ 507182412Sjkim 0x0093, /* 0x80-0x8f: 1100100100000000 */ 508182412Sjkim 0x0000, /* 0x90-0x9f: 0000000000000000 */ 509182412Sjkim 0x0000, /* 0xa0-0xaf: 0000000000000000 */ 510182412Sjkim 0x0002, /* 0xb0-0xbf: 0100000000000000 */ 511182412Sjkim 0x0000, /* 0xc0-0xcf: 0000000000000000 */ 512182412Sjkim 0x0000, /* 0xd0-0xdf: 0000000000000000 */ 513182412Sjkim 0x0000, /* 0xe0-0xef: 0000000000000000 */ 514182412Sjkim 0x0000 /* 0xf0-0xff: 0000000000000000 */ 515182412Sjkim}; 516182412Sjkim 517182454Sjkim#define BPF_VALIDATE_CODE(c) \ 518182454Sjkim ((c) <= 0xff && (bpf_code_map[(c) >> 4] & (1 << ((c) & 0xf))) != 0) 519182454Sjkim 5201541Srgrimes/* 5211541Srgrimes * Return true if the 'fcode' is a valid filter program. 5221541Srgrimes * The constraints are that each jump be forward and to a valid 5238876Srgrimes * code. The code must terminate with either an accept or reject. 5241541Srgrimes * 5251541Srgrimes * The kernel needs to be able to verify an application's filter code. 5261541Srgrimes * Otherwise, a bogus program could easily crash the system. 5271541Srgrimes */ 5281541Srgrimesint 529182455Sjkimbpf_validate(const struct bpf_insn *f, int len) 5301541Srgrimes{ 5311541Srgrimes register int i; 53254038Sarchie register const struct bpf_insn *p; 5331541Srgrimes 534153996Sjkim /* Do not accept negative length filter. */ 535153996Sjkim if (len < 0) 536182455Sjkim return (0); 537153996Sjkim 538153996Sjkim /* An empty filter means accept all. */ 539153996Sjkim if (len == 0) 540182455Sjkim return (1); 541153221Sjkim 5421541Srgrimes for (i = 0; i < len; ++i) { 543182412Sjkim p = &f[i]; 5441541Srgrimes /* 545182412Sjkim * Check that the code is valid. 546182412Sjkim */ 547182454Sjkim if (!BPF_VALIDATE_CODE(p->code)) 548182455Sjkim return (0); 549182412Sjkim /* 5508876Srgrimes * Check that that jumps are forward, and within 5511541Srgrimes * the code block. 5521541Srgrimes */ 5531541Srgrimes if (BPF_CLASS(p->code) == BPF_JMP) { 554182425Sjkim register u_int offset; 5551541Srgrimes 556182454Sjkim if (p->code == (BPF_JMP|BPF_JA)) 557182425Sjkim offset = p->k; 558182425Sjkim else 559182425Sjkim offset = p->jt > p->jf ? p->jt : p->jf; 560182425Sjkim if (offset >= (u_int)(len - i) - 1) 561182455Sjkim return (0); 562182454Sjkim continue; 5631541Srgrimes } 5641541Srgrimes /* 5651541Srgrimes * Check that memory operations use valid addresses. 5661541Srgrimes */ 567182454Sjkim if (p->code == BPF_ST || p->code == BPF_STX || 568182454Sjkim p->code == (BPF_LD|BPF_MEM) || 569182454Sjkim p->code == (BPF_LDX|BPF_MEM)) { 570182454Sjkim if (p->k >= BPF_MEMWORDS) 571182455Sjkim return (0); 572182454Sjkim continue; 573182454Sjkim } 5741541Srgrimes /* 5751541Srgrimes * Check for constant division by 0. 5761541Srgrimes */ 5771541Srgrimes if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0) 578182455Sjkim return (0); 5791541Srgrimes } 580182455Sjkim return (BPF_CLASS(f[len - 1].code) == BPF_RET); 5811541Srgrimes} 5821541Srgrimes#endif 583