1478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*#define CHASE_CHAIN*/ 2478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 3478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 4478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The Regents of the University of California. All rights reserved. 5478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 6478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Redistribution and use in source and binary forms, with or without 7478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * modification, are permitted provided that: (1) source code distributions 8478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * retain the above copyright notice and this paragraph in its entirety, (2) 9478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * distributions including binary code include the above copyright notice and 10478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * this paragraph in its entirety in the documentation or other materials 11478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * provided with the distribution, and (3) all advertising materials mentioning 12478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * features or use of this software display the following acknowledgement: 13478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ``This product includes software developed by the University of California, 14478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 15478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the University nor the names of its contributors may be used to endorse 16478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * or promote products derived from this software without specific prior 17478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * written permission. 18478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 19478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 20478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 21478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 22478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 23478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_CONFIG_H 24478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "config.h" 25478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 26478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 27478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef WIN32 28478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <pcap-stdinc.h> 29478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else /* WIN32 */ 30511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#if HAVE_INTTYPES_H 31511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <inttypes.h> 32511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#elif HAVE_STDINT_H 33511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stdint.h> 34511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 35511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_SYS_BITYPES_H 36511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/bitypes.h> 37511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 38478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/types.h> 39478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/socket.h> 40478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* WIN32 */ 41478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 42478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 43478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - why was this included even on UNIX? 44478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 45478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef __MINGW32__ 46511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "ip6_misc.h" 47478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 48478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 49478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef WIN32 50478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 51478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef __NetBSD__ 52478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/param.h> 53478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 54478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 55478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/in.h> 56511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <arpa/inet.h> 57478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 58478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* WIN32 */ 59478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 60478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdlib.h> 61478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <string.h> 62478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <memory.h> 63478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <setjmp.h> 64478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdarg.h> 65478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 66478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef MSDOS 67478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap-dos.h" 68478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 69478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 70478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap-int.h" 71478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 72478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "ethertype.h" 73478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "nlpid.h" 74478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "llc.h" 75478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "gencode.h" 76511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "ieee80211.h" 77478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "atmuni31.h" 78478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "sunatmpos.h" 79478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "ppp.h" 80511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "pcap/sll.h" 81511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "pcap/ipnet.h" 82478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "arcnet.h" 83511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#if defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) 84511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <linux/types.h> 85511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <linux/if_packet.h> 86511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <linux/filter.h> 87511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 88478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_NET_PFVAR_H 89478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/socket.h> 90478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if.h> 91478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/pfvar.h> 92478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if_pflog.h> 93478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 94478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef offsetof 95478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define offsetof(s, e) ((size_t)&((s *)0)->e) 96478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 97478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6 98478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef WIN32 99478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netdb.h> /* for "struct addrinfo" */ 100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* WIN32 */ 101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /*INET6*/ 102511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <pcap/namedb.h> 103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define ETHERMTU 1500 105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 106d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#ifndef ETHERTYPE_TEB 107d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#define ETHERTYPE_TEB 0x6558 108d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#endif 109d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 110511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef IPPROTO_HOPOPTS 111511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IPPROTO_HOPOPTS 0 112511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 113511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef IPPROTO_ROUTING 114511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IPPROTO_ROUTING 43 115511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 116511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef IPPROTO_FRAGMENT 117511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IPPROTO_FRAGMENT 44 118511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 119511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef IPPROTO_DSTOPTS 120511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IPPROTO_DSTOPTS 60 121511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_SCTP 123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_SCTP 132 124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 126d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#define GENEVE_PORT 6081 127d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_OS_PROTO_H 129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "os-proto.h" 130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define JMP(c) ((c)|BPF_JMP|BPF_K) 133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* Locals */ 135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic jmp_buf top_ctx; 136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic pcap_t *bpf_pcap; 137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 138d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* Hack for handling VLAN and MPLS stacks. */ 139511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef WIN32 140d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic u_int label_stack_depth = (u_int)-1, vlan_stack_depth = (u_int)-1; 141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 142d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic u_int label_stack_depth = -1U, vlan_stack_depth = -1U; 143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* XXX */ 146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pcap_fddipad; 147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* VARARGS */ 149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid 150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectbpf_error(const char *fmt, ...) 151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project va_list ap; 153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project va_start(ap, fmt); 155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (bpf_pcap != NULL) 156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)vsnprintf(pcap_geterr(bpf_pcap), PCAP_ERRBUF_SIZE, 157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fmt, ap); 158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project va_end(ap); 159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project longjmp(top_ctx, 1); 160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void init_linktype(pcap_t *); 164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 165511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void init_regs(void); 166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int alloc_reg(void); 167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void free_reg(int); 168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *root; 170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 172d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Absolute offsets, which are offsets from the beginning of the raw 173d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * packet data, are, in the general case, the sum of a variable value 174d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * and a constant value; the variable value may be absent, in which 175d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * case the offset is only the constant value, and the constant value 176d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * may be zero, in which case the offset is only the variable value. 177d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 178d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * bpf_abs_offset is a structure containing all that information: 179d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 180d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * is_variable is 1 if there's a variable part. 181d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 182d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * constant_part is the constant part of the value, possibly zero; 183d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 184d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * if is_variable is 1, reg is the register number for a register 185d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * containing the variable value if the register has been assigned, 186d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * and -1 otherwise. 187d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 188d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughestypedef struct { 189d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes int is_variable; 190d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes u_int constant_part; 191d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes int reg; 192d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} bpf_abs_offset; 193d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 194d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* 195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Value passed to gen_load_a() to indicate what the offset argument 196d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * is relative to the beginning of. 197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectenum e_offrel { 199d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_PACKET, /* full packet data */ 200d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_LINKHDR, /* link-layer header */ 201d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_PREVLINKHDR, /* previous link-layer header */ 202d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_LLC, /* 802.2 LLC header */ 203d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_PREVMPLSHDR, /* previous MPLS header */ 204d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_LINKTYPE, /* link-layer type */ 205d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_LINKPL, /* link-layer payload */ 206d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_LINKPL_NOSNAP, /* link-layer payload, with no SNAP header at the link layer */ 207d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_TRAN_IPV4, /* transport-layer header, with IPv4 network layer */ 208d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_TRAN_IPV6 /* transport-layer header, with IPv6 network layer */ 209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}; 210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 211511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef INET6 212511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * As errors are handled by a longjmp, anything allocated must be freed 214511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * in the longjmp handler, so it must be reachable from that handler. 215511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * One thing that's allocated is the result of pcap_nametoaddrinfo(); 216511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * it must be freed with freeaddrinfo(). This variable points to any 217511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * addrinfo structure that would need to be freed. 218511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 219511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct addrinfo *ai; 220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We divy out chunks of memory rather than call malloc each time so 224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we don't have to worry about leaking memory. It's probably 225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * not a big deal if all this memory was wasted but if this ever 226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * goes into a library that would probably not be a good idea. 227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - this *is* in a library.... 229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define NCHUNKS 16 231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define CHUNK0SIZE 1024 232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct chunk { 233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int n_left; 234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project void *m; 235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}; 236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct chunk chunks[NCHUNKS]; 238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int cur_chunk; 239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void *newchunk(u_int); 241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void freechunks(void); 242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct block *new_block(int); 243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct slist *new_stmt(int); 244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_retblk(int); 245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline void syntax(void); 246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void backpatch(struct block *, struct block *); 248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void merge(struct block *, struct block *); 249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_cmp(enum e_offrel, u_int, u_int, bpf_int32); 250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_cmp_gt(enum e_offrel, u_int, u_int, bpf_int32); 251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_cmp_ge(enum e_offrel, u_int, u_int, bpf_int32); 252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_cmp_lt(enum e_offrel, u_int, u_int, bpf_int32); 253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_cmp_le(enum e_offrel, u_int, u_int, bpf_int32); 254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_mcmp(enum e_offrel, u_int, u_int, bpf_int32, 255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32); 256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_bcmp(enum e_offrel, u_int, u_int, const u_char *); 257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_ncmp(enum e_offrel, bpf_u_int32, bpf_u_int32, 258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32, bpf_u_int32, int, bpf_int32); 259d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct slist *gen_load_absoffsetrel(bpf_abs_offset *, u_int, u_int); 260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist *gen_load_a(enum e_offrel, u_int, u_int); 261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist *gen_loadx_iphdrlen(void); 262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_uncond(int); 263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct block *gen_true(void); 264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct block *gen_false(void); 265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_ether_linktype(int); 266511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct block *gen_ipnet_linktype(int); 267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_linux_sll_linktype(int); 268511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *gen_load_prism_llprefixlen(void); 269511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *gen_load_avs_llprefixlen(void); 270511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *gen_load_radiotap_llprefixlen(void); 271511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *gen_load_ppi_llprefixlen(void); 272511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void insert_compute_vloffsets(struct block *); 273d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct slist *gen_abs_offset_varpart(bpf_abs_offset *); 274511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int ethertype_to_ppptype(int); 275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_linktype(int); 276511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct block *gen_snap(bpf_u_int32, bpf_u_int32); 277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_llc_linktype(int); 278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int); 279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6 280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_hostop6(struct in6_addr *, struct in6_addr *, int, int, u_int, u_int); 281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_ahostop(const u_char *, int); 283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_ehostop(const u_char *, int); 284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_fhostop(const u_char *, int); 285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_thostop(const u_char *, int); 286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_wlanhostop(const u_char *, int); 287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_ipfchostop(const u_char *, int); 288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_dnhostop(bpf_u_int32, int); 289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_mpls_linktype(int); 290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int, int); 291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6 292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_host6(struct in6_addr *, struct in6_addr *, int, int, int); 293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef INET6 295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int); 296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_ipfrag(void); 298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_portatom(int, bpf_int32); 299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_portrangeatom(int, bpf_int32, bpf_int32); 300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_portatom6(int, bpf_int32); 301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_portrangeatom6(int, bpf_int32, bpf_int32); 302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *gen_portop(int, int, int); 303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_port(int, int, int); 304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *gen_portrangeop(int, int, int, int); 305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_portrange(int, int, int, int); 306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *gen_portop6(int, int, int); 307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_port6(int, int, int); 308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *gen_portrangeop6(int, int, int, int); 309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_portrange6(int, int, int, int); 310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int lookup_proto(const char *, int); 311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_protochain(int, int, int); 312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_proto(int, int, int); 313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist *xfer_to_x(struct arth *); 314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist *xfer_to_a(struct arth *); 315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_mac_multicast(int); 316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_len(int, int); 317511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct block *gen_check_802_11_data_frame(void); 318d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct block *gen_geneve_ll_check(void); 319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_ppi_dlt_check(void); 321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_msg_abbrev(int type); 322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void * 324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectnewchunk(n) 325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int n; 326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct chunk *cp; 328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int k; 329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project size_t size; 330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef __NetBSD__ 332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* XXX Round up to nearest long. */ 333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1); 334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* XXX Round up to structure boundary. */ 336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project n = ALIGN(n); 337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cp = &chunks[cur_chunk]; 340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (n > cp->n_left) { 341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ++cp, k = ++cur_chunk; 342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (k >= NCHUNKS) 343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("out of memory"); 344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project size = CHUNK0SIZE << k; 345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cp->m = (void *)malloc(size); 346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (cp->m == NULL) 347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("out of memory"); 348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset((char *)cp->m, 0, size); 349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cp->n_left = size; 350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (n > size) 351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("out of memory"); 352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cp->n_left -= n; 354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (void *)((char *)cp->m + cp->n_left); 355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void 358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectfreechunks() 359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int i; 361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cur_chunk = 0; 363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project for (i = 0; i < NCHUNKS; ++i) 364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (chunks[i].m != NULL) { 365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(chunks[i].m); 366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project chunks[i].m = NULL; 367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * A strdup whose allocations are freed after code generation is over. 372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectchar * 374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectsdup(s) 375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const char *s; 376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int n = strlen(s) + 1; 378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project char *cp = newchunk(n); 379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strlcpy(cp, s, n); 381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (cp); 382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct block * 385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectnew_block(code) 386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int code; 387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *p; 389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p = (struct block *)newchunk(sizeof(*p)); 391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->s.code = code; 392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->head = p; 393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return p; 395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct slist * 398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectnew_stmt(code) 399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int code; 400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *p; 402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p = (struct slist *)newchunk(sizeof(*p)); 404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->s.code = code; 405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return p; 407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_retblk(v) 411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int v; 412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b = new_block(BPF_RET|BPF_K); 414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->s.k = v; 416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline void 420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectsyntax() 421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("syntax error in filter expression"); 423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic bpf_u_int32 netmask; 426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int snaplen; 427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint no_optimize; 428511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 429511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallint 430511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_compile(pcap_t *p, struct bpf_program *program, 431511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *buf, int optimize, bpf_u_int32 mask) 432511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project extern int n_errors; 434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project const char * volatile xbuf = buf; 435511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall u_int len; 436d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes int rc; 437d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 438d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 439d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * XXX - single-thread this code path with pthread calls on 440d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * UN*X, if the platform supports pthreads? If that requires 441d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * a separate -lpthread, we might not want to do that. 442d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 443d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#ifdef WIN32 444d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes extern int wsockinit (void); 445d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes static int done = 0; 446d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 447d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (!done) 448d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes wsockinit(); 449d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes done = 1; 450d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes EnterCriticalSection(&g_PcapCompileCriticalSection); 451d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#endif 452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 453511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 454511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If this pcap_t hasn't been activated, it doesn't have a 455511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * link-layer type, so we can't use it. 456511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 457511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (!p->activated) { 458511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 459511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "not-yet-activated pcap_t passed to pcap_compile"); 460d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes rc = -1; 461d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes goto quit; 462511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project no_optimize = 0; 464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project n_errors = 0; 465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project root = NULL; 466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_pcap = p; 467511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall init_regs(); 468d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (setjmp(top_ctx)) { 470511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef INET6 471511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (ai != NULL) { 472511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall freeaddrinfo(ai); 473511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ai = NULL; 474511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 475511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project lex_cleanup(); 477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project freechunks(); 478d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes rc = -1; 479d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes goto quit; 480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project netmask = mask; 483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snaplen = pcap_snapshot(p); 485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (snaplen == 0) { 486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "snaplen of 0 rejects all packets"); 488d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes rc = -1; 489d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes goto quit; 490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project lex_init(xbuf ? xbuf : ""); 493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project init_linktype(p); 494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)pcap_parse(); 495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (n_errors) 497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project syntax(); 498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (root == NULL) 500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project root = gen_retblk(snaplen); 501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (optimize && !no_optimize) { 503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_optimize(&root); 504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (root == NULL || 505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0)) 506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("expression rejects all packets"); 507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project program->bf_insns = icode_to_fcode(root, &len); 509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project program->bf_len = len; 510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project lex_cleanup(); 512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project freechunks(); 513d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 514d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes rc = 0; /* We're all okay */ 515d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 516d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesquit: 517d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 518d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#ifdef WIN32 519d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes LeaveCriticalSection(&g_PcapCompileCriticalSection); 520d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#endif 521d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 522d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return (rc); 523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * entry point for using the compiler with no pcap open 527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * pass in all the stuff that is needed explicitly instead. 528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint 530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_compile_nopcap(int snaplen_arg, int linktype_arg, 531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct bpf_program *program, 532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project const char *buf, int optimize, bpf_u_int32 mask) 533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_t *p; 535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int ret; 536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p = pcap_open_dead(linktype_arg, snaplen_arg); 538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p == NULL) 539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = pcap_compile(p, program, buf, optimize, mask); 541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_close(p); 542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (ret); 543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Clean up a "struct bpf_program" by freeing all the memory allocated 547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in it. 548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid 550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_freecode(struct bpf_program *program) 551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project program->bf_len = 0; 553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (program->bf_insns != NULL) { 554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free((char *)program->bf_insns); 555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project program->bf_insns = NULL; 556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Backpatch the blocks in 'list' to 'target'. The 'sense' field indicates 561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * which of the jt and jf fields has been resolved and which is a pointer 562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * back to another unresolved block (or nil). At least one of the fields 563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in each block is already resolved. 564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void 566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectbackpatch(list, target) 567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *list, *target; 568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *next; 570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (list) { 572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!list->sense) { 573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project next = JT(list); 574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project JT(list) = target; 575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project next = JF(list); 577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project JF(list) = target; 578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project list = next; 580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Merge the lists in b0 and b1, using the 'sense' field to indicate 585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * which of jt and jf is the link. 586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void 588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectmerge(b0, b1) 589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block **p = &b0; 592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Find end of list. */ 594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (*p) 595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p = !((*p)->sense) ? &JT(*p) : &JF(*p); 596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Concatenate the lists. */ 598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *p = b1; 599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid 602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectfinish_parse(p) 603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *p; 604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *ppi_dlt_check; 606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Insert before the statements of the first (root) block any 609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * statements needed to load the lengths of any variable-length 610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * headers into registers. 611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - a fancier strategy would be to insert those before the 613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * statements of all blocks that use those lengths and that 614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * have no predecessors that use them, so that we only compute 615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the lengths if we need them. There might be even better 616511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * approaches than that. 617511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 618511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * However, those strategies would be more complicated, and 619511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * as we don't generate code to compute a length if the 620511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * program has no tests that use the length, and as most 621511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * tests will probably use those lengths, we would just 622511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * postpone computing the lengths so that it's not done 623511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * for tests that fail early, and it's not clear that's 624511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * worth the effort. 625511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 626511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall insert_compute_vloffsets(p->head); 627d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 628511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 629511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For DLT_PPI captures, generate a check of the per-packet 630511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * DLT value to make sure it's DLT_IEEE802_11. 631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 632511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ppi_dlt_check = gen_ppi_dlt_check(); 633511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (ppi_dlt_check != NULL) 634511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(ppi_dlt_check, p); 635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 636511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall backpatch(p, gen_retblk(snaplen)); 637511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->sense = !p->sense; 638511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall backpatch(p, gen_retblk(0)); 639511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall root = p->head; 640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid 643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_and(b0, b1) 644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project backpatch(b0, b1->head); 647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0->sense = !b0->sense; 648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->sense = !b1->sense; 649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project merge(b1, b0); 650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->sense = !b1->sense; 651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->head = b0->head; 652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid 655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_or(b0, b1) 656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0->sense = !b0->sense; 659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project backpatch(b0, b1->head); 660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0->sense = !b0->sense; 661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project merge(b1, b0); 662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->head = b0->head; 663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid 666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_not(b) 667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->sense = !b->sense; 670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_cmp(offrel, offset, size, v) 674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project enum e_offrel offrel; 675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int offset, size; 676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 v; 677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JEQ, 0, v); 679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_cmp_gt(offrel, offset, size, v) 683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project enum e_offrel offrel; 684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int offset, size; 685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 v; 686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGT, 0, v); 688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_cmp_ge(offrel, offset, size, v) 692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project enum e_offrel offrel; 693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int offset, size; 694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 v; 695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGE, 0, v); 697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_cmp_lt(offrel, offset, size, v) 701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project enum e_offrel offrel; 702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int offset, size; 703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 v; 704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGE, 1, v); 706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_cmp_le(offrel, offset, size, v) 710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project enum e_offrel offrel; 711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int offset, size; 712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 v; 713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGT, 1, v); 715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_mcmp(offrel, offset, size, v, mask) 719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project enum e_offrel offrel; 720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int offset, size; 721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 v; 722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 mask; 723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_ncmp(offrel, offset, size, mask, BPF_JEQ, 0, v); 725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_bcmp(offrel, offset, size, v) 729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project enum e_offrel offrel; 730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register u_int offset, size; 731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const u_char *v; 732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block *b, *tmp; 734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = NULL; 736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (size >= 4) { 737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const u_char *p = &v[size - 4]; 738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 w = ((bpf_int32)p[0] << 24) | 739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ((bpf_int32)p[1] << 16) | ((bpf_int32)p[2] << 8) | p[3]; 740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_cmp(offrel, offset + size - 4, BPF_W, w); 742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (b != NULL) 743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b, tmp); 744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = tmp; 745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project size -= 4; 746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (size >= 2) { 748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const u_char *p = &v[size - 2]; 749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 w = ((bpf_int32)p[0] << 8) | p[1]; 750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_cmp(offrel, offset + size - 2, BPF_H, w); 752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (b != NULL) 753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b, tmp); 754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = tmp; 755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project size -= 2; 756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (size > 0) { 758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_cmp(offrel, offset, BPF_B, (bpf_int32)v[0]); 759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (b != NULL) 760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b, tmp); 761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = tmp; 762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * AND the field of size "size" at offset "offset" relative to the header 768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * specified by "offrel" with "mask", and compare it with the value "v" 769478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with the test specified by "jtype"; if "reverse" is true, the test 770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * should test the opposite of "jtype". 771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ncmp(offrel, offset, size, mask, jtype, reverse, v) 774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project enum e_offrel offrel; 775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 v; 776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 offset, size, mask, jtype; 777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int reverse; 778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s, *s2; 780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = gen_load_a(offrel, offset, size); 783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (mask != 0xffffffff) { 785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_ALU|BPF_AND|BPF_K); 786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2->s.k = mask; 787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, s2); 788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = new_block(JMP(jtype)); 791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->stmts = s; 792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->s.k = v; 793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (reverse && (jtype == BPF_JGT || jtype == BPF_JGE)) 794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b); 795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 799d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Various code constructs need to know the layout of the packet. 800d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * These variables give the necessary offsets from the beginning 801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of the packet data. 802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 805d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Absolute offset of the beginning of the link-layer header. 806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 807d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic bpf_abs_offset off_linkhdr; 808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 810d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * If we're checking a link-layer header for a packet encapsulated in 811d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * another protocol layer, this is the equivalent information for the 812d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * previous layers' link-layer header from the beginning of the raw 813d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * packet data. 814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 815d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic bpf_abs_offset off_prevlinkhdr; 816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 818d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * This is the equivalent information for the outermost layers' link-layer 819d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * header. 820511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 821d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic bpf_abs_offset off_outermostlinkhdr; 822511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 823511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 824d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * "Push" the current value of the link-layer header type and link-layer 825d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * header offset onto a "stack", and set a new value. (It's not a 826d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * full-blown stack; we keep only the top two items.) 827511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 828d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#define PUSH_LINKHDR(new_linktype, new_is_variable, new_constant_part, new_reg) \ 829d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ \ 830d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes prevlinktype = new_linktype; \ 831d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_prevlinkhdr = off_linkhdr; \ 832d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes linktype = new_linktype; \ 833d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkhdr.is_variable = new_is_variable; \ 834d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkhdr.constant_part = new_constant_part; \ 835d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkhdr.reg = new_reg; \ 836d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes is_geneve = 0; \ 837d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 838511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 839511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 840d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Absolute offset of the beginning of the link-layer payload. 841511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 842d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic bpf_abs_offset off_linkpl; 843511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 844511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "off_linktype" is the offset to information in the link-layer header 846d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * giving the packet type. This is an absolute offset from the beginning 847d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * of the packet. 848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 849d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * For Ethernet, it's the offset of the Ethernet type field; this 850d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * means that it must have a value that skips VLAN tags. 851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 852478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For link-layer types that always use 802.2 headers, it's the 853d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * offset of the LLC header; this means that it must have a value 854d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * that skips VLAN tags. 855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For PPP, it's the offset of the PPP type field. 857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For Cisco HDLC, it's the offset of the CHDLC type field. 859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For BSD loopback, it's the offset of the AF_ value. 861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For Linux cooked sockets, it's the offset of the type field. 863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 864d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * off_linktype.constant_part is set to -1 for no encapsulation, 865d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * in which case, IP is assumed. 866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 867d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic bpf_abs_offset off_linktype; 868511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 869511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * TRUE if the link layer includes an ATM pseudo-header. 871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int is_atm = 0; 873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 875d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * TRUE if "geneve" appeared in the filter; it causes us to generate 876d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * code that checks for a Geneve header and assume that later filters 877d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * apply to the encapsulated payload. 878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 879d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic int is_geneve = 0; 880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * These are offsets for the ATM pseudo-header. 883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_vpi; 885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_vci; 886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_proto; 887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * These are offsets for the MTP2 fields. 890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_li; 892511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic u_int off_li_hsl; 893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * These are offsets for the MTP3 fields. 896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_sio; 898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_opc; 899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_dpc; 900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_sls; 901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is the offset of the first byte after the ATM pseudo_header, 904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * or -1 if there is no ATM pseudo-header. 905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_payload; 907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * These are offsets to the beginning of the network-layer header. 910d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * They are relative to the beginning of the link-layer payload (i.e., 911d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * they don't include off_linkhdr.constant_part or off_linkpl.constant_part). 912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If the link layer never uses 802.2 LLC: 914478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 915478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "off_nl" and "off_nl_nosnap" are the same. 916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If the link layer always uses 802.2 LLC: 918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 919478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "off_nl" is the offset if there's a SNAP header following 920478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the 802.2 header; 921478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "off_nl_nosnap" is the offset if there's no SNAP header. 923478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 924478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If the link layer is Ethernet: 925478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 926478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "off_nl" is the offset if the packet is an Ethernet II packet 927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (we assume no 802.3+802.2+SNAP); 928478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 929478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "off_nl_nosnap" is the offset if the packet is an 802.3 packet 930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with an 802.2 header following it. 931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 932478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_nl; 933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_nl_nosnap; 934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int linktype; 936d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic int prevlinktype; 937d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic int outermostlinktype; 938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void 940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectinit_linktype(p) 941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_t *p; 942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_fddipad = p->fddipad; 944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 946d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * We start out with only one link-layer header. 947d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 948d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes outermostlinktype = pcap_datalink(p); 949d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_outermostlinkhdr.constant_part = 0; 950d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_outermostlinkhdr.is_variable = 0; 951d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_outermostlinkhdr.reg = -1; 952d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 953d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes prevlinktype = outermostlinktype; 954d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_prevlinkhdr.constant_part = 0; 955d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_prevlinkhdr.is_variable = 0; 956d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_prevlinkhdr.reg = -1; 957d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 958d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes linktype = outermostlinktype; 959d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkhdr.constant_part = 0; 960d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkhdr.is_variable = 0; 961d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkhdr.reg = -1; 962d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 963d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 964d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * XXX 965d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 966d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 0; 967d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.is_variable = 0; 968d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.reg = -1; 969d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 970d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 0; 971d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.is_variable = 0; 972d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.reg = -1; 973d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 974d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Assume it's not raw ATM with a pseudo-header, for now. 976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project is_atm = 0; 978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_vpi = -1; 979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_vci = -1; 980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_proto = -1; 981478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_payload = -1; 982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 984d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * And not Geneve. 985511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 986d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes is_geneve = 0; 987511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 988511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * And assume we're not doing SS7. 990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_li = -1; 992511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_li_hsl = -1; 993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_sio = -1; 994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_opc = -1; 995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_dpc = -1; 996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_sls = -1; 997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project label_stack_depth = 0; 999d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes vlan_stack_depth = 0; 1000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (linktype) { 1002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ARCNET: 1004d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 2; 1005d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 6; 1006511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; /* XXX in reality, variable! */ 1007511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 0; /* no 802.2 LLC */ 1008d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ARCNET_LINUX: 1011d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 4; 1012d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 8; 1013511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; /* XXX in reality, variable! */ 1014511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 0; /* no 802.2 LLC */ 1015d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_EN10MB: 1018d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 12; 1019d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 14; /* Ethernet header length */ 1020511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; /* Ethernet II */ 1021511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 3; /* 802.3+802.2 */ 1022d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_SLIP: 1025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SLIP doesn't have a link level type. The 16 byte 1027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header is hacked into our SLIP driver. 1028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1029d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = -1; 1030d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 16; 1031511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; 1032511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 0; /* no 802.2 LLC */ 1033d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_SLIP_BSDOS: 1036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* XXX this may be the same as the DLT_PPP_BSDOS case */ 1037d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = -1; 1038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* XXX end */ 1039d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 24; 1040511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; 1041511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 0; /* no 802.2 LLC */ 1042d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_NULL: 1045478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_LOOP: 1046d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 0; 1047d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 4; 1048511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; 1049511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 0; /* no 802.2 LLC */ 1050d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1052478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ENC: 1053d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 0; 1054d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 12; 1055511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; 1056511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 0; /* no 802.2 LLC */ 1057d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP: 1060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP_PPPD: 1061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_C_HDLC: /* BSD/OS Cisco HDLC */ 1062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP_SERIAL: /* NetBSD sync/async serial PPP */ 1063d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 2; /* skip HDLC-like framing */ 1064d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 4; /* skip HDLC-like framing and protocol field */ 1065511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; 1066511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 0; /* no 802.2 LLC */ 1067d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP_ETHER: 1070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This does no include the Ethernet header, and 1072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * only covers session state. 1073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1074d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 6; 1075d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 8; 1076511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; 1077511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 0; /* no 802.2 LLC */ 1078d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP_BSDOS: 1081d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 5; 1082d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 24; 1083511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; 1084511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 0; /* no 802.2 LLC */ 1085d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_FDDI: 1088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * FDDI doesn't really have a link-level type field. 1090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We set "off_linktype" to the offset of the LLC header. 1091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * To check for Ethernet types, we assume that SSAP = SNAP 1093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is being used and pick out the encapsulated Ethernet type. 1094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - should we generate code to check for SNAP? 1095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1096d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 13; 1097d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part += pcap_fddipad; 1098d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 13; /* FDDI MAC header length */ 1099d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part += pcap_fddipad; 1100511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 8; /* 802.2+SNAP */ 1101511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 3; /* 802.2 */ 1102d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802: 1105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Token Ring doesn't really have a link-level type field. 1107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We set "off_linktype" to the offset of the LLC header. 1108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * To check for Ethernet types, we assume that SSAP = SNAP 1110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is being used and pick out the encapsulated Ethernet type. 1111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - should we generate code to check for SNAP? 1112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - the header is actually variable-length. 1114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Some various Linux patched versions gave 38 1115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as "off_linktype" and 40 as "off_nl"; however, 1116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * if a token ring packet has *no* routing 1117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * information, i.e. is not source-routed, the correct 1118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * values are 20 and 22, as they are in the vanilla code. 1119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * A packet is source-routed iff the uppermost bit 1121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of the first byte of the source address, at an 1122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * offset of 8, has the uppermost bit set. If the 1123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * packet is source-routed, the total number of bytes 1124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of routing information is 2 plus bits 0x1F00 of 1125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the 16-bit value at an offset of 14 (shifted right 1126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 8 - figure out which byte that is). 1127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1128d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 14; 1129d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 14; /* Token Ring MAC header length */ 1130511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 8; /* 802.2+SNAP */ 1131511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 3; /* 802.2 */ 1132d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1134511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 1135511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO_AVS: 1136511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO: 1137d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkhdr.is_variable = 1; 1138d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Fall through, 802.11 doesn't have a variable link 1139d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * prefix but is otherwise the same. */ 1140d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 1141d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_IEEE802_11: 1142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 802.11 doesn't really have a link-level type field. 1144d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * We set "off_linktype.constant_part" to the offset of 1145d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the LLC header. 1146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * To check for Ethernet types, we assume that SSAP = SNAP 1148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is being used and pick out the encapsulated Ethernet type. 1149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - should we generate code to check for SNAP? 1150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1151511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * We also handle variable-length radio headers here. 1152511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * The Prism header is in theory variable-length, but in 1153511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * practice it's always 144 bytes long. However, some 1154511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * drivers on Linux use ARPHRD_IEEE80211_PRISM, but 1155511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * sometimes or always supply an AVS header, so we 1156511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * have to check whether the radio header is a Prism 1157511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * header or an AVS header, so, in practice, it's 1158511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * variable-length. 1159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1160d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 24; 1161d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 0; /* link-layer header is variable-length */ 1162d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.is_variable = 1; 1163511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 8; /* 802.2+SNAP */ 1164511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 3; /* 802.2 */ 1165d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPI: 1168d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 1169511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * At the moment we treat PPI the same way that we treat 1170511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * normal Radiotap encoded packets. The difference is in 1171511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the function that generates the code at the beginning 1172511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * to compute the header length. Since this code generator 1173511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * of PPI supports bare 802.11 encapsulation only (i.e. 1174511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the encapsulated DLT should be DLT_IEEE802_11) we 1175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * generate code to check for this too. 1176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1177d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 24; 1178d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 0; /* link-layer header is variable-length */ 1179d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.is_variable = 1; 1180d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkhdr.is_variable = 1; 1181511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 8; /* 802.2+SNAP */ 1182511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 3; /* 802.2 */ 1183d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ATM_RFC1483: 1186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ATM_CLIP: /* Linux ATM defines this */ 1187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * assume routed, non-ISO PDUs 1189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00) 1190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - what about ISO PDUs, e.g. CLNP, ISIS, ESIS, 1192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * or PPP with the PPP NLPID (e.g., PPPoA)? The 1193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * latter would presumably be treated the way PPPoE 1194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * should be, so you can do "pppoe and udp port 2049" 1195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * or "pppoa and tcp port 80" and have it check for 1196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * PPPo{A,E} and a PPP protocol of IP and.... 1197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1198d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 0; 1199d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 0; /* packet begins with LLC header */ 1200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl = 8; /* 802.2+SNAP */ 1201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl_nosnap = 3; /* 802.2 */ 1202d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_SUNATM: 1205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Full Frontal ATM; you get AALn PDUs with an ATM 1207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * pseudo-header. 1208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project is_atm = 1; 1210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_vpi = SUNATM_VPI_POS; 1211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_vci = SUNATM_VCI_POS; 1212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_proto = PROTO_POS; 1213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_payload = SUNATM_PKT_BEGIN_POS; 1214d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = off_payload; 1215d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = off_payload; /* if LLC-encapsulated */ 1216511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 8; /* 802.2+SNAP */ 1217511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 3; /* 802.2 */ 1218d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_RAW: 1221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IPV4: 1222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IPV6: 1223d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = -1; 1224d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 0; 1225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl = 0; 1226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl_nosnap = 0; /* no 802.2 LLC */ 1227d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_LINUX_SLL: /* fake header for Linux cooked socket */ 1230d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 14; 1231d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 16; 1232511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; 1233511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 0; /* no 802.2 LLC */ 1234d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_LTALK: 1237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LocalTalk does have a 1-byte type field in the LLAP header, 1239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * but really it just indicates whether there is a "short" or 1240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "long" DDP packet following. 1241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1242d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = -1; 1243d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 0; 1244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl = 0; 1245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl_nosnap = 0; /* no 802.2 LLC */ 1246d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IP_OVER_FC: 1249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * RFC 2625 IP-over-Fibre-Channel doesn't really have a 1251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * link-level type field. We set "off_linktype" to the 1252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * offset of the LLC header. 1253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * To check for Ethernet types, we assume that SSAP = SNAP 1255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is being used and pick out the encapsulated Ethernet type. 1256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - should we generate code to check for SNAP? RFC 1257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2625 says SNAP should be used. 1258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1259d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 16; 1260d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 16; 1261511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 8; /* 802.2+SNAP */ 1262511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 3; /* 802.2 */ 1263d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_FRELAY: 1266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - we should set this to handle SNAP-encapsulated 1268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames (NLPID of 0x80). 1269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1270d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = -1; 1271d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 0; 1272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl = 0; 1273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl_nosnap = 0; /* no 802.2 LLC */ 1274d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the only BPF-interesting FRF.16 frames are non-control frames; 1278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Frame Relay has a variable length link-layer 1279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * so lets start with offset 4 for now and increments later on (FIXME); 1280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_MFR: 1282d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = -1; 1283d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 0; 1284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl = 4; 1285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl_nosnap = 0; /* XXX - for now -> no 802.2 LLC */ 1286d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_APPLE_IP_OVER_IEEE1394: 1289d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 16; 1290d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 18; 1291511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; 1292511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 0; /* no 802.2 LLC */ 1293d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_SYMANTEC_FIREWALL: 1296d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 6; 1297d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 44; 1298511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; /* Ethernet II */ 1299511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 0; /* XXX - what does it do with 802.3 packets? */ 1300d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_NET_PFVAR_H 1303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PFLOG: 1304d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 0; 1305d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = PFLOG_HDRLEN; 1306511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; 1307511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 0; /* no 802.2 LLC */ 1308d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 1310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MFR: 1312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MLFR: 1313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MLPPP: 1314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_PPP: 1315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_CHDLC: 1316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_FRELAY: 1317d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 4; 1318d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 4; 1319511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; 1320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl_nosnap = -1; /* no 802.2 LLC */ 1321d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ATM1: 1324d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 4; /* in reality variable between 4-8 */ 1325d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 4; /* in reality variable between 4-8 */ 1326511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; 1327511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 10; 1328d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ATM2: 1331d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 8; /* in reality variable between 8-12 */ 1332d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 8; /* in reality variable between 8-12 */ 1333511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; 1334511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 10; 1335d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* frames captured on a Juniper PPPoE service PIC 1338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * contain raw ethernet frames */ 1339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_PPPOE: 1340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ETHER: 1341d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 14; 1342d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 16; 1343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl = 18; /* Ethernet II */ 1344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl_nosnap = 21; /* 802.3+802.2 */ 1345d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_PPPOE_ATM: 1348d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 4; 1349d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 6; 1350511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; 1351511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = -1; /* no 802.2 LLC */ 1352d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_GGSN: 1355d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 6; 1356d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 12; 1357511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; 1358511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = -1; /* no 802.2 LLC */ 1359d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ES: 1362d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 6; 1363d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = -1; /* not really a network layer but raw IP addresses */ 1364511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = -1; /* not really a network layer but raw IP addresses */ 1365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl_nosnap = -1; /* no 802.2 LLC */ 1366d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MONITOR: 1369d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 12; 1370d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 12; 1371511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; /* raw IP/IP6 header */ 1372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl_nosnap = -1; /* no 802.2 LLC */ 1373d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1375511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_BACNET_MS_TP: 1376d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = -1; 1377d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = -1; 1378511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = -1; 1379511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = -1; 1380d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1381511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_SERVICES: 1383d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 12; 1384d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = -1; /* L3 proto location dep. on cookie type */ 1385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl = -1; /* L3 proto location dep. on cookie type */ 1386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl_nosnap = -1; /* no 802.2 LLC */ 1387d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_VP: 1390d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 18; 1391d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = -1; 1392511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = -1; 1393511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = -1; 1394d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1395511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1396511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_ST: 1397d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 18; 1398d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = -1; 1399511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = -1; 1400511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = -1; 1401d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1402511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1403511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_ISM: 1404d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 8; 1405d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = -1; 1406511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = -1; 1407511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = -1; 1408d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1409511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1410511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_VS: 1411511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_SRX_E2E: 1412511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_FIBRECHANNEL: 1413511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_ATM_CEMIC: 1414d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 8; 1415d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = -1; 1416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl = -1; 1417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl_nosnap = -1; 1418d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_MTP2: 1421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_li = 2; 1422511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_li_hsl = 4; 1423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_sio = 3; 1424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_opc = 4; 1425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_dpc = 4; 1426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_sls = 7; 1427d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = -1; 1428d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = -1; 1429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl = -1; 1430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl_nosnap = -1; 1431d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_MTP2_WITH_PHDR: 1434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_li = 6; 1435511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_li_hsl = 8; 1436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_sio = 7; 1437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_opc = 8; 1438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_dpc = 8; 1439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_sls = 11; 1440d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = -1; 1441d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = -1; 1442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl = -1; 1443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl_nosnap = -1; 1444d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1446511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_ERF: 1447511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_li = 22; 1448511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_li_hsl = 24; 1449511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_sio = 23; 1450511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_opc = 24; 1451511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_dpc = 24; 1452511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_sls = 27; 1453d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = -1; 1454d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = -1; 1455511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = -1; 1456511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = -1; 1457d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1459511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PFSYNC: 1460d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = -1; 1461d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 4; 1462511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; 1463511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 0; 1464d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1466511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_AX25_KISS: 1467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Currently, only raw "link[N:M]" filtering is supported. 1469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1470d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = -1; /* variable, min 15, max 71 steps of 7 */ 1471d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = -1; 1472511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = -1; /* variable, min 16, max 71 steps of 7 */ 1473511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = -1; /* no 802.2 LLC */ 1474d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1475511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1476511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IPNET: 1477d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 1; 1478d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 24; /* ipnet header length */ 1479511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; 1480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl_nosnap = -1; 1481d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1483511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER: 1484d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkhdr.constant_part = 4; /* Ethernet header is past 4-byte pseudo-header */ 1485d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = off_linkhdr.constant_part + 12; 1486d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = off_linkhdr.constant_part + 14; /* pseudo-header+Ethernet header length */ 1487511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; /* Ethernet II */ 1488511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 3; /* 802.3+802.2 */ 1489d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1490511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1491511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER_TRANSPARENT: 1492d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkhdr.constant_part = 12; /* MAC header is past 4-byte pseudo-header, preamble, and SFD */ 1493d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = off_linkhdr.constant_part + 12; 1494d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = off_linkhdr.constant_part + 14; /* pseudo-header+preamble+SFD+Ethernet header length */ 1495511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; /* Ethernet II */ 1496511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 3; /* 802.3+802.2 */ 1497d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1498511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1499511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 1500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1501511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For values in the range in which we've assigned new 1502511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * DLT_ values, only raw "link[N:M]" filtering is supported. 1503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1504511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (linktype >= DLT_MATCHING_MIN && 1505511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall linktype <= DLT_MATCHING_MAX) { 1506d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = -1; 1507d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = -1; 1508511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = -1; 1509511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = -1; 1510d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } else { 1511d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes bpf_error("unknown data link type %d", linktype); 1512511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 1513d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1516d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_outermostlinkhdr = off_prevlinkhdr = off_linkhdr; 1517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1519511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 1520d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Load a value relative to the specified absolute offset. 1521511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 1522511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist * 1523d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesgen_load_absoffsetrel(bpf_abs_offset *abs_offset, u_int offset, u_int size) 1524511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 1525511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *s, *s2; 1526511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1527d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_abs_offset_varpart(abs_offset); 1528511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1529511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 1530d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * If "s" is non-null, it has code to arrange that the X register 1531d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * contains the variable part of the absolute offset, so we 1532d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * generate a load relative to that, with an offset of 1533d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * abs_offset->constant_part + offset. 1534511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 1535d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Otherwise, we can do an absolute load with an offset of 1536d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * abs_offset->constant_part + offset. 1537511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 1538511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (s != NULL) { 1539511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 1540d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * "s" points to a list of statements that puts the 1541d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * variable part of the absolute offset into the X register. 1542d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Do an indirect load, to use the X register as an offset. 1543511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 1544511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2 = new_stmt(BPF_LD|BPF_IND|size); 1545d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s2->s.k = abs_offset->constant_part + offset; 1546511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 1547511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else { 1548511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 1549d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * There is no variable part of the absolute offset, so 1550d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * just do an absolute load. 1551511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 1552511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s = new_stmt(BPF_LD|BPF_ABS|size); 1553d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s->s.k = abs_offset->constant_part + offset; 1554511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 1555511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return s; 1556511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 1557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 1559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load a value relative to the beginning of the specified header. 1560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist * 1562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_load_a(offrel, offset, size) 1563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project enum e_offrel offrel; 1564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int offset, size; 1565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s, *s2; 1567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (offrel) { 1569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case OR_PACKET: 1571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = new_stmt(BPF_LD|BPF_ABS|size); 1572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->s.k = offset; 1573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 1574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1575d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case OR_LINKHDR: 1576d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_absoffsetrel(&off_linkhdr, offset, size); 1577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 1578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1579d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case OR_PREVLINKHDR: 1580d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_absoffsetrel(&off_prevlinkhdr, offset, size); 1581511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 1582511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1583d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case OR_LLC: 1584d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_absoffsetrel(&off_linkpl, offset, size); 1585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 1586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1587d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case OR_PREVMPLSHDR: 1588d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_absoffsetrel(&off_linkpl, off_nl - 4 + offset, size); 1589d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1590d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 1591d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case OR_LINKPL: 1592d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_absoffsetrel(&off_linkpl, off_nl + offset, size); 1593d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1594d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 1595d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case OR_LINKPL_NOSNAP: 1596d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_absoffsetrel(&off_linkpl, off_nl_nosnap + offset, size); 1597d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1598d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 1599d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case OR_LINKTYPE: 1600d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_absoffsetrel(&off_linktype, offset, size); 1601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 1602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case OR_TRAN_IPV4: 1604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the X register with the length of the IPv4 header 1606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (plus the offset of the link-layer header, if it's 1607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * preceded by a variable-length header such as a radio 1608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header), in bytes. 1609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = gen_loadx_iphdrlen(); 1611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1613d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Load the item at {offset of the link-layer payload} + 1614d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * {offset, relative to the start of the link-layer 1615511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * paylod, of the IPv4 header} + {length of the IPv4 header} + 1616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * {specified offset}. 1617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1618d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * If the offset of the link-layer payload is variable, 1619d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the variable part of that offset is included in the 1620d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * value in the X register, and we include the constant 1621d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * part in the offset of the load. 1622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_LD|BPF_IND|size); 1624d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s2->s.k = off_linkpl.constant_part + off_nl + offset; 1625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, s2); 1626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 1627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case OR_TRAN_IPV6: 1629d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_absoffsetrel(&off_linkpl, off_nl + 40 + offset, size); 1630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 1631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 1633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 1634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return NULL; 1635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return s; 1637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 1640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to load into the X register the sum of the length of 1641d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the IPv4 header and the variable part of the offset of the link-layer 1642d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * payload. 1643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist * 1645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_loadx_iphdrlen() 1646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s, *s2; 1648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1649d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_abs_offset_varpart(&off_linkpl); 1650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (s != NULL) { 1651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1652d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * The offset of the link-layer payload has a variable 1653d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * part. "s" points to a list of statements that put 1654d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the variable part of that offset into the X register. 1655511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 1656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The 4*([k]&0xf) addressing mode can't be used, as we 1657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * don't have a constant offset, so we have to load the 1658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * value in question into the A register and add to it 1659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the value from the X register. 1660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_LD|BPF_IND|BPF_B); 1662d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s2->s.k = off_linkpl.constant_part + off_nl; 1663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, s2); 1664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_ALU|BPF_AND|BPF_K); 1665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2->s.k = 0xf; 1666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, s2); 1667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_ALU|BPF_LSH|BPF_K); 1668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2->s.k = 2; 1669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, s2); 1670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1672d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * The A register now contains the length of the IP header. 1673d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * We need to add to it the variable part of the offset of 1674d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the link-layer payload, which is still in the X 1675511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * register, and move the result into the X register. 1676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); 1678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, new_stmt(BPF_MISC|BPF_TAX)); 1679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 1680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1681d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * The offset of the link-layer payload is a constant, 1682d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * so no code was generated to load the (non-existent) 1683d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * variable part of that offset. 1684d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 1685d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * This means we can use the 4*([k]&0xf) addressing 1686d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * mode. Load the length of the IPv4 header, which 1687d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * is at an offset of off_nl from the beginning of 1688d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the link-layer payload, and thus at an offset of 1689d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * off_linkpl.constant_part + off_nl from the beginning 1690d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * of the raw packet data, using that addressing mode. 1691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = new_stmt(BPF_LDX|BPF_MSH|BPF_B); 1693d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s->s.k = off_linkpl.constant_part + off_nl; 1694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return s; 1696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 1699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_uncond(rsense) 1700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int rsense; 1701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 1703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s; 1704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = new_stmt(BPF_LD|BPF_IMM); 1706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->s.k = !rsense; 1707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = new_block(JMP(BPF_JEQ)); 1708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->stmts = s; 1709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 1711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct block * 1714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_true() 1715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_uncond(1); 1717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct block * 1720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_false() 1721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_uncond(0); 1723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 1726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Byte-swap a 32-bit number. 1727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ("htonl()" or "ntohl()" won't work - we want to byte-swap even on 1728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * big-endian platforms.) 1729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define SWAPLONG(y) \ 1731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) 1732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 1734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to match a particular packet type. 1735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP 1737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * value, if <= ETHERMTU. We use that to determine whether to 1738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * match the type/length field or to check the type/length field for 1739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a value <= ETHERMTU to see whether it's a type field and then do 1740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the appropriate test. 1741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 1743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ether_linktype(proto) 1744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int proto; 1745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 1747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 1749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_ISONS: 1751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_IP: 1752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_NETBEUI: 1753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OSI protocols and NetBEUI always use 802.2 encapsulation, 1755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * so we check the DSAP and SSAP. 1756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LLCSAP_IP checks for IP-over-802.2, rather 1758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * than IP-over-Ethernet or IP-over-SNAP. 1759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - should we check both the DSAP and the 1761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SSAP, like this, or should we check just the 1762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DSAP, as we do for other types <= ETHERMTU 1763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (i.e., other SAP values)? 1764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1765d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp_gt(OR_LINKTYPE, 0, BPF_H, ETHERMTU); 1766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b0); 1767d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_cmp(OR_LLC, 0, BPF_H, (bpf_int32) 1768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ((proto << 8) | proto)); 1769478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 1770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 1771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_IPX: 1773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for; 1775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet_II frames, which are Ethernet 1777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames with a frame type of ETHERTYPE_IPX; 1778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet_802.3 frames, which are 802.3 1780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames (i.e., the type/length field is 1781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a length field, <= ETHERMTU, rather than 1782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a type field) with the first two bytes 1783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * after the Ethernet/802.3 header being 1784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 0xFFFF; 1785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet_802.2 frames, which are 802.3 1787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames with an 802.2 LLC header and 1788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with the IPX LSAP as the DSAP in the LLC 1789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header; 1790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet_SNAP frames, which are 802.3 1792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames with an LLC header and a SNAP 1793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header and with an OUI of 0x000000 1794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (encapsulated Ethernet) and a protocol 1795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ID of ETHERTYPE_IPX in the SNAP header. 1796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - should we generate the same code both 1798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * for tests for LLCSAP_IPX and for ETHERTYPE_IPX? 1799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This generates code to check both for the 1803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * IPX LSAP (Ethernet_802.2) and for Ethernet_802.3. 1804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1805d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LLC, 0, BPF_B, (bpf_int32)LLCSAP_IPX); 1806d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_cmp(OR_LLC, 0, BPF_H, (bpf_int32)0xFFFF); 1807478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 1808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now we add code to check for SNAP frames with 1811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ETHERTYPE_IPX, i.e. Ethernet_SNAP. 1812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1813511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = gen_snap(0x000000, ETHERTYPE_IPX); 1814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 1815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now we generate code to check for 802.3 1818478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames in general. 1819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1820d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp_gt(OR_LINKTYPE, 0, BPF_H, ETHERMTU); 1821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b0); 1822478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now add the check for 802.3 frames before the 1825478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * check for Ethernet_802.2 and Ethernet_802.3, 1826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as those checks should only be done on 802.3 1827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames, not on Ethernet frames. 1828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 1830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now add the check for Ethernet_II frames, and 1833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * do that before checking for the other frame 1834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * types. 1835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1836d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKTYPE, 0, BPF_H, (bpf_int32)ETHERTYPE_IPX); 1837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 1838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 1839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_ATALK: 1841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_AARP: 1842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1843478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * EtherTalk (AppleTalk protocols on Ethernet link 1844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * layer) may use 802.2 encapsulation. 1845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for 802.2 encapsulation (EtherTalk phase 2?); 1849478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we check for an Ethernet type field less than 1850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1500, which means it's an 802.3 length field. 1851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1852d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp_gt(OR_LINKTYPE, 0, BPF_H, ETHERMTU); 1853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b0); 1854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 802.2-encapsulated ETHERTYPE_ATALK packets are 1857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SNAP packets with an organization code of 1858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 0x080007 (Apple, for Appletalk) and a protocol 1859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * type of ETHERTYPE_ATALK (Appletalk). 1860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 802.2-encapsulated ETHERTYPE_AARP packets are 1862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SNAP packets with an organization code of 1863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 0x000000 (encapsulated Ethernet) and a protocol 1864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * type of ETHERTYPE_AARP (Appletalk ARP). 1865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == ETHERTYPE_ATALK) 1867511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1 = gen_snap(0x080007, ETHERTYPE_ATALK); 1868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else /* proto == ETHERTYPE_AARP */ 1869511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1 = gen_snap(0x000000, ETHERTYPE_AARP); 1870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 1871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for Ethernet encapsulation (Ethertalk 1874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * phase 1?); we just check for the Ethernet 1875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * protocol type. 1876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1877d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto); 1878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 1880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 1881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 1883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto <= ETHERMTU) { 1884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is an LLC SAP value, so the frames 1886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that match would be 802.2 frames. 1887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check that the frame is an 802.2 frame 1888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (i.e., that the length/type field is 1889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a length field, <= ETHERMTU) and 1890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * then check the DSAP. 1891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1892d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp_gt(OR_LINKTYPE, 0, BPF_H, ETHERMTU); 1893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b0); 1894d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_cmp(OR_LINKTYPE, 2, BPF_B, (bpf_int32)proto); 1895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 1896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 1897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 1898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is an Ethernet type, so compare 1900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the length/type field with it (if 1901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the frame is an 802.2 frame, the length 1902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * field will be <= ETHERMTU, and, as 1903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto" is > ETHERMTU, this test 1904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * will fail and the frame won't match, 1905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * which is what we want). 1906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1907d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_cmp(OR_LINKTYPE, 0, BPF_H, 1908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)proto); 1909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1910478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1911478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 1914511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * "proto" is an Ethernet type value and for IPNET, if it is not IPv4 1915511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * or IPv6 then we have an error. 1916511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 1917511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct block * 1918511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_ipnet_linktype(proto) 1919511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall register int proto; 1920511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 1921511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (proto) { 1922511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1923511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case ETHERTYPE_IP: 1924d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_cmp(OR_LINKTYPE, 0, BPF_B, (bpf_int32)IPH_AF_INET); 1925511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NOTREACHED */ 1926511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1927511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case ETHERTYPE_IPV6: 1928d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_cmp(OR_LINKTYPE, 0, BPF_B, 1929511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (bpf_int32)IPH_AF_INET6); 1930511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NOTREACHED */ 1931511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1932511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 1933511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 1934511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 1935511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1936511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_false(); 1937511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 1938511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1939511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 1940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to match a particular packet type. 1941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP 1943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * value, if <= ETHERMTU. We use that to determine whether to 1944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * match the type field or to check the type field for the special 1945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LINUX_SLL_P_802_2 value and then do the appropriate test. 1946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 1948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_linux_sll_linktype(proto) 1949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int proto; 1950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 1952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 1954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_ISONS: 1956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_IP: 1957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_NETBEUI: 1958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OSI protocols and NetBEUI always use 802.2 encapsulation, 1960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * so we check the DSAP and SSAP. 1961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LLCSAP_IP checks for IP-over-802.2, rather 1963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * than IP-over-Ethernet or IP-over-SNAP. 1964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - should we check both the DSAP and the 1966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SSAP, like this, or should we check just the 1967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DSAP, as we do for other types <= ETHERMTU 1968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (i.e., other SAP values)? 1969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1970d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKTYPE, 0, BPF_H, LINUX_SLL_P_802_2); 1971d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_cmp(OR_LLC, 0, BPF_H, (bpf_int32) 1972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ((proto << 8) | proto)); 1973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 1974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 1975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_IPX: 1977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet_II frames, which are Ethernet 1979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames with a frame type of ETHERTYPE_IPX; 1980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1981478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet_802.3 frames, which have a frame 1982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * type of LINUX_SLL_P_802_3; 1983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1984478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet_802.2 frames, which are 802.3 1985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames with an 802.2 LLC header (i.e, have 1986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a frame type of LINUX_SLL_P_802_2) and 1987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with the IPX LSAP as the DSAP in the LLC 1988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header; 1989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet_SNAP frames, which are 802.3 1991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames with an LLC header and a SNAP 1992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header and with an OUI of 0x000000 1993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (encapsulated Ethernet) and a protocol 1994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ID of ETHERTYPE_IPX in the SNAP header. 1995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * First, do the checks on LINUX_SLL_P_802_2 1997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames; generate the check for either 1998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet_802.2 or Ethernet_SNAP frames, and 1999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * then put a check for LINUX_SLL_P_802_2 frames 2000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * before it. 2001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2002d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LLC, 0, BPF_B, (bpf_int32)LLCSAP_IPX); 2003511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1 = gen_snap(0x000000, ETHERTYPE_IPX); 2004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 2005d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKTYPE, 0, BPF_H, LINUX_SLL_P_802_2); 2006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 2007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now check for 802.3 frames and OR that with 2010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the previous test. 2011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2012d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKTYPE, 0, BPF_H, LINUX_SLL_P_802_3); 2013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 2014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now add the check for Ethernet_II frames, and 2017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * do that before checking for the other frame 2018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * types. 2019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2020d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKTYPE, 0, BPF_H, (bpf_int32)ETHERTYPE_IPX); 2021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 2022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 2023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_ATALK: 2025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_AARP: 2026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * EtherTalk (AppleTalk protocols on Ethernet link 2028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * layer) may use 802.2 encapsulation. 2029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for 802.2 encapsulation (EtherTalk phase 2?); 2033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we check for the 802.2 protocol type in the 2034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "Ethernet type" field. 2035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2036d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKTYPE, 0, BPF_H, LINUX_SLL_P_802_2); 2037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 802.2-encapsulated ETHERTYPE_ATALK packets are 2040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SNAP packets with an organization code of 2041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 0x080007 (Apple, for Appletalk) and a protocol 2042478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * type of ETHERTYPE_ATALK (Appletalk). 2043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 802.2-encapsulated ETHERTYPE_AARP packets are 2045478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SNAP packets with an organization code of 2046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 0x000000 (encapsulated Ethernet) and a protocol 2047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * type of ETHERTYPE_AARP (Appletalk ARP). 2048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == ETHERTYPE_ATALK) 2050511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1 = gen_snap(0x080007, ETHERTYPE_ATALK); 2051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else /* proto == ETHERTYPE_AARP */ 2052511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1 = gen_snap(0x000000, ETHERTYPE_AARP); 2053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 2054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for Ethernet encapsulation (Ethertalk 2057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * phase 1?); we just check for the Ethernet 2058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * protocol type. 2059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2060d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto); 2061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 2063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 2064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2065478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 2066478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto <= ETHERMTU) { 2067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is an LLC SAP value, so the frames 2069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that match would be 802.2 frames. 2070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for the 802.2 protocol type 2071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in the "Ethernet type" field, and 2072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * then check the DSAP. 2073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2074d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKTYPE, 0, BPF_H, LINUX_SLL_P_802_2); 2075d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_cmp(OR_LINKHDR, off_linkpl.constant_part, BPF_B, 2076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)proto); 2077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 2078478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 2079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 2080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is an Ethernet type, so compare 2082478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the length/type field with it (if 2083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the frame is an 802.2 frame, the length 2084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * field will be <= ETHERMTU, and, as 2085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto" is > ETHERMTU, this test 2086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * will fail and the frame won't match, 2087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * which is what we want). 2088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2089d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_cmp(OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto); 2090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 2091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 2092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 2093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2094511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist * 2095511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_load_prism_llprefixlen() 2096511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 2097511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *s1, *s2; 2098511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *sjeq_avs_cookie; 2099511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *sjcommon; 2100511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2101511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2102511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * This code is not compatible with the optimizer, as 2103511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * we are generating jmp instructions within a normal 2104511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * slist of instructions 2105511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2106511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall no_optimize = 1; 2107511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2108511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2109511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Generate code to load the length of the radio header into 2110511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the register assigned to hold that length, if one has been 2111511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * assigned. (If one hasn't been assigned, no code we've 2112511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * generated uses that prefix, so we don't need to generate any 2113511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * code to load it.) 2114511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 2115511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Some Linux drivers use ARPHRD_IEEE80211_PRISM but sometimes 2116511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * or always use the AVS header rather than the Prism header. 2117511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * We load a 4-byte big-endian value at the beginning of the 2118511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * raw packet data, and see whether, when masked with 0xFFFFF000, 2119511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * it's equal to 0x80211000. If so, that indicates that it's 2120511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * an AVS header (the masked-out bits are the version number). 2121511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Otherwise, it's a Prism header. 2122511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 2123511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * XXX - the Prism header is also, in theory, variable-length, 2124511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * but no known software generates headers that aren't 144 2125511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * bytes long. 2126511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2127d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (off_linkhdr.reg != -1) { 2128511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2129511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Load the cookie. 2130511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2131511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s1 = new_stmt(BPF_LD|BPF_W|BPF_ABS); 2132511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s1->s.k = 0; 2133511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2134511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2135511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * AND it with 0xFFFFF000. 2136511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2137511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2 = new_stmt(BPF_ALU|BPF_AND|BPF_K); 2138511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 0xFFFFF000; 2139511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s1, s2); 2140511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2141511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2142511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Compare with 0x80211000. 2143511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2144511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjeq_avs_cookie = new_stmt(JMP(BPF_JEQ)); 2145511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjeq_avs_cookie->s.k = 0x80211000; 2146511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s1, sjeq_avs_cookie); 2147511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2148511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2149511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If it's AVS: 2150511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 2151511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * The 4 bytes at an offset of 4 from the beginning of 2152511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the AVS header are the length of the AVS header. 2153511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * That field is big-endian. 2154511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2155511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2 = new_stmt(BPF_LD|BPF_W|BPF_ABS); 2156511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 4; 2157511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s1, s2); 2158511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjeq_avs_cookie->s.jt = s2; 2159511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2160511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2161511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now jump to the code to allocate a register 2162511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * into which to save the header length and 2163511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * store the length there. (The "jump always" 2164511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * instruction needs to have the k field set; 2165511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * it's added to the PC, so, as we're jumping 2166511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * over a single instruction, it should be 1.) 2167511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2168511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjcommon = new_stmt(JMP(BPF_JA)); 2169511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjcommon->s.k = 1; 2170511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s1, sjcommon); 2171511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2172511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2173511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now for the code that handles the Prism header. 2174511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Just load the length of the Prism header (144) 2175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * into the A register. Have the test for an AVS 2176511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * header branch here if we don't have an AVS header. 2177511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2178511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2 = new_stmt(BPF_LD|BPF_W|BPF_IMM); 2179511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 144; 2180511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s1, s2); 2181511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjeq_avs_cookie->s.jf = s2; 2182511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2183511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2184511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now allocate a register to hold that value and store 2185511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * it. The code for the AVS header will jump here after 2186511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * loading the length of the AVS header. 2187511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2188511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2 = new_stmt(BPF_ST); 2189d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s2->s.k = off_linkhdr.reg; 2190511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s1, s2); 2191511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjcommon->s.jf = s2; 2192511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2193511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2194511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now move it into the X register. 2195511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2196511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2 = new_stmt(BPF_MISC|BPF_TAX); 2197511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s1, s2); 2198511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2199511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (s1); 2200511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else 2201511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (NULL); 2202511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 2203511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2204511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist * 2205511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_load_avs_llprefixlen() 2206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 2207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s1, *s2; 2208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2210511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Generate code to load the length of the AVS header into 2211511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the register assigned to hold that length, if one has been 2212511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * assigned. (If one hasn't been assigned, no code we've 2213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * generated uses that prefix, so we don't need to generate any 2214511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * code to load it.) 2215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2216d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (off_linkhdr.reg != -1) { 2217511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2218511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * The 4 bytes at an offset of 4 from the beginning of 2219511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the AVS header are the length of the AVS header. 2220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * That field is big-endian. 2221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s1 = new_stmt(BPF_LD|BPF_W|BPF_ABS); 2223511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s1->s.k = 4; 2224511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2225511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2226511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now allocate a register to hold that value and store 2227511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * it. 2228511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2229511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2 = new_stmt(BPF_ST); 2230d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s2->s.k = off_linkhdr.reg; 2231511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s1, s2); 2232511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2233511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2234511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now move it into the X register. 2235511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2236511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2 = new_stmt(BPF_MISC|BPF_TAX); 2237511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s1, s2); 2238511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2239511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (s1); 2240511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else 2241511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (NULL); 2242511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 2243511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2244511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist * 2245511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_load_radiotap_llprefixlen() 2246511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 2247511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *s1, *s2; 2248511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2249511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2250511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Generate code to load the length of the radiotap header into 2251511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the register assigned to hold that length, if one has been 2252511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * assigned. (If one hasn't been assigned, no code we've 2253511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * generated uses that prefix, so we don't need to generate any 2254511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * code to load it.) 2255511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2256d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (off_linkhdr.reg != -1) { 2257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The 2 bytes at offsets of 2 and 3 from the beginning 2259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of the radiotap header are the length of the radiotap 2260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header; unfortunately, it's little-endian, so we have 2261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to load it a byte at a time and construct the value. 2262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the high-order byte, at an offset of 3, shift it 2266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * left a byte, and put the result in the X register. 2267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s1 = new_stmt(BPF_LD|BPF_B|BPF_ABS); 2269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s1->s.k = 3; 2270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_ALU|BPF_LSH|BPF_K); 2271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2->s.k = 8; 2273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_MISC|BPF_TAX); 2274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the next byte, at an offset of 2, and OR the 2278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * value from the X register into it. 2279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_LD|BPF_B|BPF_ABS); 2281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2->s.k = 2; 2283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_ALU|BPF_OR|BPF_X); 2284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now allocate a register to hold that value and store 2288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * it. 2289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_ST); 2291d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s2->s.k = off_linkhdr.reg; 2292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now move it into the X register. 2296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_MISC|BPF_TAX); 2298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2300511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (s1); 2301511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else 2302511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (NULL); 2303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 2304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2305d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* 2306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * At the moment we treat PPI as normal Radiotap encoded 2307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * packets. The difference is in the function that generates 2308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the code at the beginning to compute the header length. 2309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Since this code generator of PPI supports bare 802.11 2310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * encapsulation only (i.e. the encapsulated DLT should be 2311511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * DLT_IEEE802_11) we generate code to check for this too; 2312511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * that's done in finish_parse(). 2313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2314511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist * 2315511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_load_ppi_llprefixlen() 2316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 2317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s1, *s2; 2318d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2320511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Generate code to load the length of the radiotap header 2321511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * into the register assigned to hold that length, if one has 2322511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * been assigned. 2323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2324d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (off_linkhdr.reg != -1) { 2325511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The 2 bytes at offsets of 2 and 3 from the beginning 2327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of the radiotap header are the length of the radiotap 2328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header; unfortunately, it's little-endian, so we have 2329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to load it a byte at a time and construct the value. 2330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the high-order byte, at an offset of 3, shift it 2334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * left a byte, and put the result in the X register. 2335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s1 = new_stmt(BPF_LD|BPF_B|BPF_ABS); 2337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s1->s.k = 3; 2338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_ALU|BPF_LSH|BPF_K); 2339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2->s.k = 8; 2341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_MISC|BPF_TAX); 2342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the next byte, at an offset of 2, and OR the 2346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * value from the X register into it. 2347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_LD|BPF_B|BPF_ABS); 2349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2->s.k = 2; 2351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_ALU|BPF_OR|BPF_X); 2352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now allocate a register to hold that value and store 2356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * it. 2357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_ST); 2359d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s2->s.k = off_linkhdr.reg; 2360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now move it into the X register. 2364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_MISC|BPF_TAX); 2366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2368511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (s1); 2369511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else 2370511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (NULL); 2371511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 2372511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2373511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 2374511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Load a value relative to the beginning of the link-layer header after the 802.11 2375511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * header, i.e. LLC_SNAP. 2376511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * The link-layer header doesn't necessarily begin at the beginning 2377511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * of the packet data; there might be a variable-length prefix containing 2378511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * radio information. 2379511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2380511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist * 2381511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_load_802_11_header_len(struct slist *s, struct slist *snext) 2382511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 2383511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *s2; 2384511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *sjset_data_frame_1; 2385511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *sjset_data_frame_2; 2386511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *sjset_qos; 2387511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *sjset_radiotap_flags; 2388511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *sjset_radiotap_tsft; 2389511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *sjset_tsft_datapad, *sjset_notsft_datapad; 2390511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *s_roundup; 2391511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2392d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (off_linkpl.reg == -1) { 2393511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2394511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * No register has been assigned to the offset of 2395d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the link-layer payload, which means nobody needs 2396511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * it; don't bother computing it - just return 2397511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * what we already have. 2398511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2399511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (s); 2400511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 2401511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2402511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2403511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * This code is not compatible with the optimizer, as 2404511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * we are generating jmp instructions within a normal 2405511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * slist of instructions 2406511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2407511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall no_optimize = 1; 2408d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2409511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2410511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If "s" is non-null, it has code to arrange that the X register 2411511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * contains the length of the prefix preceding the link-layer 2412511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * header. 2413511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 2414511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Otherwise, the length of the prefix preceding the link-layer 2415d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * header is "off_outermostlinkhdr.constant_part". 2416511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2417511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (s == NULL) { 2418511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2419511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * There is no variable-length header preceding the 2420511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * link-layer header. 2421511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 2422511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Load the length of the fixed-length prefix preceding 2423511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the link-layer header (if any) into the X register, 2424d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * and store it in the off_linkpl.reg register. 2425d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * That length is off_outermostlinkhdr.constant_part. 2426511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2427511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s = new_stmt(BPF_LDX|BPF_IMM); 2428d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s->s.k = off_outermostlinkhdr.constant_part; 2429511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 2430511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2431511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2432511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * The X register contains the offset of the beginning of the 2433511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * link-layer header; add 24, which is the minimum length 2434511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * of the MAC header for a data frame, to that, and store it 2435d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * in off_linkpl.reg, and then load the Frame Control field, 2436511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * which is at the offset in the X register, with an indexed load. 2437511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2438511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2 = new_stmt(BPF_MISC|BPF_TXA); 2439511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2440511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2 = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 2441511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 24; 2442511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2443511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2 = new_stmt(BPF_ST); 2444d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s2->s.k = off_linkpl.reg; 2445511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2446511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2447511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2 = new_stmt(BPF_LD|BPF_IND|BPF_B); 2448511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 0; 2449511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2450511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2451511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2452511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Check the Frame Control field to see if this is a data frame; 2453511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * a data frame has the 0x08 bit (b3) in that field set and the 2454511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 0x04 bit (b2) clear. 2455511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2456511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_data_frame_1 = new_stmt(JMP(BPF_JSET)); 2457511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_data_frame_1->s.k = 0x08; 2458511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, sjset_data_frame_1); 2459d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2460511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2461511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If b3 is set, test b2, otherwise go to the first statement of 2462511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the rest of the program. 2463511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2464511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_data_frame_1->s.jt = sjset_data_frame_2 = new_stmt(JMP(BPF_JSET)); 2465511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_data_frame_2->s.k = 0x04; 2466511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, sjset_data_frame_2); 2467511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_data_frame_1->s.jf = snext; 2468511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2469511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2470511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If b2 is not set, this is a data frame; test the QoS bit. 2471511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Otherwise, go to the first statement of the rest of the 2472511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * program. 2473511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2474511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_data_frame_2->s.jt = snext; 2475511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_data_frame_2->s.jf = sjset_qos = new_stmt(JMP(BPF_JSET)); 2476511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_qos->s.k = 0x80; /* QoS bit */ 2477511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, sjset_qos); 2478d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2479511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2480d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * If it's set, add 2 to off_linkpl.reg, to skip the QoS 2481511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * field. 2482511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Otherwise, go to the first statement of the rest of the 2483511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * program. 2484511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2485511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_qos->s.jt = s2 = new_stmt(BPF_LD|BPF_MEM); 2486d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s2->s.k = off_linkpl.reg; 2487511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2488511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2 = new_stmt(BPF_ALU|BPF_ADD|BPF_IMM); 2489511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 2; 2490511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2491511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2 = new_stmt(BPF_ST); 2492d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s2->s.k = off_linkpl.reg; 2493511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2494511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2495511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2496511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If we have a radiotap header, look at it to see whether 2497511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * there's Atheros padding between the MAC-layer header 2498511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * and the payload. 2499511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 2500511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Note: all of the fields in the radiotap header are 2501511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * little-endian, so we byte-swap all of the values 2502511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * we test against, as they will be loaded as big-endian 2503511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * values. 2504511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2505511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (linktype == DLT_IEEE802_11_RADIO) { 2506511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2507511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Is the IEEE80211_RADIOTAP_FLAGS bit (0x0000002) set 2508511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * in the presence flag? 2509511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2510511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_qos->s.jf = s2 = new_stmt(BPF_LD|BPF_ABS|BPF_W); 2511511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 4; 2512511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2513511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2514511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_radiotap_flags = new_stmt(JMP(BPF_JSET)); 2515511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_radiotap_flags->s.k = SWAPLONG(0x00000002); 2516511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, sjset_radiotap_flags); 2517511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2518511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2519511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If not, skip all of this. 2520511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2521511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_radiotap_flags->s.jf = snext; 2522511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2523511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2524511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Otherwise, is the IEEE80211_RADIOTAP_TSFT bit set? 2525511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2526511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_radiotap_tsft = sjset_radiotap_flags->s.jt = 2527511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall new_stmt(JMP(BPF_JSET)); 2528511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_radiotap_tsft->s.k = SWAPLONG(0x00000001); 2529511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, sjset_radiotap_tsft); 2530511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2531511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2532511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If IEEE80211_RADIOTAP_TSFT is set, the flags field is 2533511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * at an offset of 16 from the beginning of the raw packet 2534511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * data (8 bytes for the radiotap header and 8 bytes for 2535511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the TSFT field). 2536511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 2537511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Test whether the IEEE80211_RADIOTAP_F_DATAPAD bit (0x20) 2538511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * is set. 2539511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2540511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_radiotap_tsft->s.jt = s2 = new_stmt(BPF_LD|BPF_ABS|BPF_B); 2541511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 16; 2542511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2543511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2544511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_tsft_datapad = new_stmt(JMP(BPF_JSET)); 2545511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_tsft_datapad->s.k = 0x20; 2546511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, sjset_tsft_datapad); 2547511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2548511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2549511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If IEEE80211_RADIOTAP_TSFT is not set, the flags field is 2550511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * at an offset of 8 from the beginning of the raw packet 2551511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * data (8 bytes for the radiotap header). 2552511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 2553511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Test whether the IEEE80211_RADIOTAP_F_DATAPAD bit (0x20) 2554511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * is set. 2555511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2556511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_radiotap_tsft->s.jf = s2 = new_stmt(BPF_LD|BPF_ABS|BPF_B); 2557511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 8; 2558511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2559511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2560511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_notsft_datapad = new_stmt(JMP(BPF_JSET)); 2561511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_notsft_datapad->s.k = 0x20; 2562511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, sjset_notsft_datapad); 2563511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2565511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * In either case, if IEEE80211_RADIOTAP_F_DATAPAD is 2566511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * set, round the length of the 802.11 header to 2567511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * a multiple of 4. Do that by adding 3 and then 2568511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * dividing by and multiplying by 4, which we do by 2569511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * ANDing with ~3. 2570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2571511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s_roundup = new_stmt(BPF_LD|BPF_MEM); 2572d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s_roundup->s.k = off_linkpl.reg; 2573511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s_roundup); 2574511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2 = new_stmt(BPF_ALU|BPF_ADD|BPF_IMM); 2575511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 3; 2576511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2577511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2 = new_stmt(BPF_ALU|BPF_AND|BPF_IMM); 2578511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = ~3; 2579511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2580511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2 = new_stmt(BPF_ST); 2581d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s2->s.k = off_linkpl.reg; 2582511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2583511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2584511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_tsft_datapad->s.jt = s_roundup; 2585511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_tsft_datapad->s.jf = snext; 2586511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_notsft_datapad->s.jt = s_roundup; 2587511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_notsft_datapad->s.jf = snext; 2588511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else 2589511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_qos->s.jf = snext; 2590511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2591511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return s; 2592511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 2593511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2594511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void 2595511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallinsert_compute_vloffsets(b) 2596511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct block *b; 2597511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 2598511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *s; 2599511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2600d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* There is an implicit dependency between the link 2601d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * payload and link header since the payload computation 2602d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * includes the variable part of the header. Therefore, 2603d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * if nobody else has allocated a register for the link 2604d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * header and we need it, do it now. */ 2605d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (off_linkpl.reg != -1 && off_linkhdr.is_variable && 2606d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkhdr.reg == -1) 2607d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkhdr.reg = alloc_reg(); 2608d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2609511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2610511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For link-layer types that have a variable-length header 2611511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * preceding the link-layer header, generate code to load 2612511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the offset of the link-layer header into the register 2613511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * assigned to that offset, if any. 2614d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 2615d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * XXX - this, and the next switch statement, won't handle 2616d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * encapsulation of 802.11 or 802.11+radio information in 2617d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * some other protocol stack. That's significantly more 2618d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * complicated. 2619511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2620d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes switch (outermostlinktype) { 2621511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2622511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 2623511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s = gen_load_prism_llprefixlen(); 2624511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2625511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2626511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO_AVS: 2627511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s = gen_load_avs_llprefixlen(); 2628511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2629511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2630511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO: 2631511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s = gen_load_radiotap_llprefixlen(); 2632511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2633511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2634511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PPI: 2635511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s = gen_load_ppi_llprefixlen(); 2636511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2638511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 2639511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s = NULL; 2640511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2641511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 2642511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2643511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2644511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For link-layer types that have a variable-length link-layer 2645d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * header, generate code to load the offset of the link-layer 2646511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * payload into the register assigned to that offset, if any. 2647511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2648d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes switch (outermostlinktype) { 2649511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2650511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11: 2651511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 2652511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO_AVS: 2653511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO: 2654511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PPI: 2655511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s = gen_load_802_11_header_len(s, b->stmts); 2656511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2657511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 2658511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2659511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2660511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If we have any offset-loading code, append all the 2661511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * existing statements in the block to those statements, 2662511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * and make the resulting list the list of statements 2663511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * for the block. 2664511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2665511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (s != NULL) { 2666511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, b->stmts); 2667511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b->stmts = s; 2668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 2669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 2670511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 2672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ppi_dlt_check(void) 2673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 2674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s_load_dlt; 2675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 2676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (linktype == DLT_PPI) 2678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project { 2679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Create the statements that check for the DLT 2680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s_load_dlt = new_stmt(BPF_LD|BPF_W|BPF_ABS); 2682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s_load_dlt->s.k = 4; 2683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = new_block(JMP(BPF_JEQ)); 2685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->stmts = s_load_dlt; 2687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->s.k = SWAPLONG(DLT_IEEE802_11); 2688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 2689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 2690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project { 2691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = NULL; 2692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 2693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 2695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 2696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 2698d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Take an absolute offset, and: 2699d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 2700d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * if it has no variable part, return NULL; 2701d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 2702d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * if it has a variable part, generate code to load the register 2703d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * containing that variable part into the X register, returning 2704d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * a pointer to that code - if no register for that offset has 2705d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * been allocated, allocate it first. 2706d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 2707d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * (The code to set that register will be generated later, but will 2708d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * be placed earlier in the code sequence.) 2709511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2710511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist * 2711d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesgen_abs_offset_varpart(bpf_abs_offset *off) 2712511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 2713511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *s; 2714511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2715d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (off->is_variable) { 2716d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (off->reg == -1) { 2717511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2718d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * We haven't yet assigned a register for the 2719d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * variable part of the offset of the link-layer 2720d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * header; allocate one. 2721511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2722d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off->reg = alloc_reg(); 2723511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 2724511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2725511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2726d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Load the register containing the variable part of the 2727d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * offset of the link-layer header into the X register. 2728511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2729511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s = new_stmt(BPF_LDX|BPF_MEM); 2730d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s->s.k = off->reg; 2731511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return s; 2732511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else { 2733511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2734d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * That offset isn't variable, there's no variable part, 2735d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * so we don't need to generate any code. 2736511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2737511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return NULL; 2738511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 2739511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 2740511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2741511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 2742511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Map an Ethernet type to the equivalent PPP type. 2743511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2744511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int 2745511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallethertype_to_ppptype(proto) 2746511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int proto; 2747511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 2748511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (proto) { 2749511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2750511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case ETHERTYPE_IP: 2751511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = PPP_IP; 2752511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2753511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2754511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case ETHERTYPE_IPV6: 2755511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = PPP_IPV6; 2756511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2757511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2758511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case ETHERTYPE_DN: 2759511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = PPP_DECNET; 2760511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2761511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2762511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case ETHERTYPE_ATALK: 2763511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = PPP_APPLE; 2764511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2765511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2766511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case ETHERTYPE_NS: 2767511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = PPP_NS; 2768511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2769511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2770511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case LLCSAP_ISONS: 2771511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = PPP_OSI; 2772511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2773511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2774511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case LLCSAP_8021D: 2775511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2776511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * I'm assuming the "Bridging PDU"s that go 2777511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * over PPP are Spanning Tree Protocol 2778511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Bridging PDUs. 2779511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2780511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = PPP_BRPDU; 2781511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2782511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2783511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case LLCSAP_IPX: 2784511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = PPP_IPX; 2785511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2786511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 2787511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (proto); 2788511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 2789511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2790511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 2791d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Generate any tests that, for encapsulation of a link-layer packet 2792d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * inside another protocol stack, need to be done to check for those 2793d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * link-layer packets (and that haven't already been done by a check 2794d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * for that encapsulation). 2795d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 2796d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct block * 2797d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesgen_prevlinkhdr_check(void) 2798d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 2799d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0; 2800d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2801d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (is_geneve) 2802d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_geneve_ll_check(); 2803d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2804d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes switch (prevlinktype) { 2805d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2806d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_SUNATM: 2807d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 2808d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * This is LANE-encapsulated Ethernet; check that the LANE 2809d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * packet doesn't begin with an LE Control marker, i.e. 2810d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * that it's data, not a control message. 2811d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 2812d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * (We've already generated a test for LANE.) 2813d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 2814d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_PREVLINKHDR, SUNATM_PKT_BEGIN_POS, BPF_H, 0xFF00); 2815d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_not(b0); 2816d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b0; 2817d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2818d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes default: 2819d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 2820d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * No such tests are necessary. 2821d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 2822d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return NULL; 2823d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 2824d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /*NOTREACHED*/ 2825d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 2826d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2827d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* 2828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to match a particular packet type by matching the 2829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * link-layer type field or fields in the 802.2 LLC header. 2830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP 2832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * value, if <= ETHERMTU. 2833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 2835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_linktype(proto) 2836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int proto; 2837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 2838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *b2; 2839d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes const char *description; 2840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* are we checking MPLS-encapsulated packets? */ 2842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (label_stack_depth > 0) { 2843478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 2844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IP: 2845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case PPP_IP: 2846511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* FIXME add other L3 proto IDs */ 2847d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_mpls_linktype(Q_IP); 2848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2849478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IPV6: 2850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case PPP_IPV6: 2851511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* FIXME add other L3 proto IDs */ 2852d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_mpls_linktype(Q_IPV6); 2853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 2855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("unsupported protocol over mpls"); 2856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 2857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 2858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 2859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (linktype) { 2861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_EN10MB: 2863511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER: 2864511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER_TRANSPARENT: 2865d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Geneve has an EtherType regardless of whether there is an 2866d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * L2 header. */ 2867d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (!is_geneve) 2868d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_prevlinkhdr_check(); 2869d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes else 2870d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = NULL; 2871d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2872d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_ether_linktype(proto); 2873d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (b0 != NULL) 2874d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 2875d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 2876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 2877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 2878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_C_HDLC: 2880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 2881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_ISONS: 2883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = (proto << 8 | LLCSAP_ISONS); 2884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* fall through */ 2885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 2887d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_cmp(OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto); 2888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 2889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 2890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 2891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 2892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802_11: 2894511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 2895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802_11_RADIO_AVS: 2896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802_11_RADIO: 2897511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PPI: 2898511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2899511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Check that we have a data frame. 2900511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2901511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = gen_check_802_11_data_frame(); 2902511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2903511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2904511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now check for the specified link-layer type. 2905511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2906511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1 = gen_llc_linktype(proto); 2907511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b0, b1); 2908511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return b1; 2909511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /*NOTREACHED*/ 2910511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2911511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2912511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_FDDI: 2913511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2914d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * XXX - check for LLC frames. 2915511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2916511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_llc_linktype(proto); 2917511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /*NOTREACHED*/ 2918511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2919511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2920511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802: 2921511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2922511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * XXX - check for LLC PDUs, as per IEEE 802.5. 2923511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2924511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_llc_linktype(proto); 2925511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /*NOTREACHED*/ 2926511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2927511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2928478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ATM_RFC1483: 2929478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ATM_CLIP: 2930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IP_OVER_FC: 2931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_llc_linktype(proto); 2932478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 2933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 2934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_SUNATM: 2936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2937d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Check for an LLC-encapsulated version of this protocol; 2938d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * if we were checking for LANE, linktype would no longer 2939d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * be DLT_SUNATM. 2940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2941d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Check for LLC encapsulation and then check the protocol. 2942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2943d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_atmfield_code(A_PROTOTYPE, PT_LLC, BPF_JEQ, 0); 2944d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_llc_linktype(proto); 2945d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 2946d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 2947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 2948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 2949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_LINUX_SLL: 2951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_linux_sll_linktype(proto); 2952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 2953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 2954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_SLIP: 2956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_SLIP_BSDOS: 2957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_RAW: 2958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * These types don't provide any type field; packets 2960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * are always IPv4 or IPv6. 2961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - for IPv4, check for a version number of 4, and, 2963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * for IPv6, check for a version number of 6? 2964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 2966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IP: 2968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Check for a version number of 4. */ 2969d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_mcmp(OR_LINKHDR, 0, BPF_B, 0x40, 0xF0); 2970511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IPV6: 2972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Check for a version number of 6. */ 2973d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_mcmp(OR_LINKHDR, 0, BPF_B, 0x60, 0xF0); 2974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 2976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_false(); /* always false */ 2977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 2978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 2979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 2980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2981511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IPV4: 2982511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2983511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Raw IPv4, so no type field. 2984511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2985511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (proto == ETHERTYPE_IP) 2986511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_true(); /* always true */ 2987511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2988511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Checking for something other than IPv4; always false */ 2989511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_false(); 2990511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /*NOTREACHED*/ 2991511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2992511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2993511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IPV6: 2994511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2995511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Raw IPv6, so no type field. 2996511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2997511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (proto == ETHERTYPE_IPV6) 2998511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_true(); /* always true */ 2999511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3000511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Checking for something other than IPv6; always false */ 3001511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_false(); 3002511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /*NOTREACHED*/ 3003511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3004511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP: 3006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP_PPPD: 3007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP_SERIAL: 3008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP_ETHER: 3009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We use Ethernet protocol types inside libpcap; 3011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * map them to the corresponding PPP protocol types. 3012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3013511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = ethertype_to_ppptype(proto); 3014d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_cmp(OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto); 3015511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /*NOTREACHED*/ 3016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP_BSDOS: 3019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We use Ethernet protocol types inside libpcap; 3021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * map them to the corresponding PPP protocol types. 3022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 3024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IP: 3026511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 3027511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Also check for Van Jacobson-compressed IP. 3028511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * XXX - do this for other forms of PPP? 3029511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 3030d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKTYPE, 0, BPF_H, PPP_IP); 3031d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_cmp(OR_LINKTYPE, 0, BPF_H, PPP_VJC); 3032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 3033d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKTYPE, 0, BPF_H, PPP_VJNC); 3034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, b0); 3035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 3036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3037511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 3038511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = ethertype_to_ppptype(proto); 3039d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_cmp(OR_LINKTYPE, 0, BPF_H, 3040511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (bpf_int32)proto); 3041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3042511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /*NOTREACHED*/ 3043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3045478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_NULL: 3046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_LOOP: 3047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ENC: 3048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For DLT_NULL, the link-layer header is a 32-bit 3050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * word containing an AF_ value in *host* byte order, 3051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and for DLT_ENC, the link-layer header begins 3052478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with a 32-bit work containing an AF_ value in 3053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * host byte order. 3054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * In addition, if we're reading a saved capture file, 3056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the host byte order in the capture may not be the 3057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * same as the host byte order on this machine. 3058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For DLT_LOOP, the link-layer header is a 32-bit 3060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * word containing an AF_ value in *network* byte order. 3061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - AF_ values may, unfortunately, be platform- 3063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * dependent; for example, FreeBSD's AF_INET6 is 24 3064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * whilst NetBSD's and OpenBSD's is 26. 3065478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3066478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This means that, when reading a capture file, just 3067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * checking for our AF_INET6 value won't work if the 3068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * capture file came from another OS. 3069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 3071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IP: 3073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = AF_INET; 3074478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6 3077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IPV6: 3078478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = AF_INET6; 3079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 3081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3082478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 3083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Not a type on which we support filtering. 3085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - support those that have AF_ values 3086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * #defined on this platform, at least? 3087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_false(); 3089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (linktype == DLT_NULL || linktype == DLT_ENC) { 3092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The AF_ value is in host byte order, but 3094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the BPF interpreter will convert it to 3095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * network byte order. 3096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If this is a save file, and it's from a 3098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * machine with the opposite byte order to 3099478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ours, we byte-swap the AF_ value. 3100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Then we run it through "htonl()", and 3102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * generate code to compare against the result. 3103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3104511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (bpf_pcap->rfile != NULL && bpf_pcap->swapped) 3105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = SWAPLONG(proto); 3106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = htonl(proto); 3107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3108d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return (gen_cmp(OR_LINKHDR, 0, BPF_W, (bpf_int32)proto)); 3109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_NET_PFVAR_H 3111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PFLOG: 3112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * af field is host byte order in contrast to the rest of 3114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the packet. 3115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == ETHERTYPE_IP) 3117d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return (gen_cmp(OR_LINKHDR, offsetof(struct pfloghdr, af), 3118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project BPF_B, (bpf_int32)AF_INET)); 3119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (proto == ETHERTYPE_IPV6) 3120d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return (gen_cmp(OR_LINKHDR, offsetof(struct pfloghdr, af), 3121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project BPF_B, (bpf_int32)AF_INET6)); 3122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 3123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_false(); 3124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 3125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_NET_PFVAR_H */ 3127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ARCNET: 3129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ARCNET_LINUX: 3130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX should we check for first fragment if the protocol 3132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * uses PHDS? 3133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 3135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 3137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_false(); 3138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IPV6: 3140d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return (gen_cmp(OR_LINKTYPE, 0, BPF_B, 3141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)ARCTYPE_INET6)); 3142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IP: 3144d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKTYPE, 0, BPF_B, 3145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)ARCTYPE_IP); 3146d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_cmp(OR_LINKTYPE, 0, BPF_B, 3147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)ARCTYPE_IP_OLD); 3148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 3149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b1); 3150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_ARP: 3152d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKTYPE, 0, BPF_B, 3153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)ARCTYPE_ARP); 3154d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_cmp(OR_LINKTYPE, 0, BPF_B, 3155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)ARCTYPE_ARP_OLD); 3156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 3157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b1); 3158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_REVARP: 3160d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return (gen_cmp(OR_LINKTYPE, 0, BPF_B, 3161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)ARCTYPE_REVARP)); 3162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_ATALK: 3164d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return (gen_cmp(OR_LINKTYPE, 0, BPF_B, 3165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)ARCTYPE_ATALK)); 3166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 3168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_LTALK: 3171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 3172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_ATALK: 3173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_true(); 3174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 3175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_false(); 3176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 3178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_FRELAY: 3181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - assumes a 2-byte Frame Relay header with 3183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DLCI and flags. What if the address is longer? 3184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 3186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IP: 3188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for the special NLPID for IP. 3190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3191d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_cmp(OR_LINKHDR, 2, BPF_H, (0x03<<8) | 0xcc); 3192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IPV6: 3194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for the special NLPID for IPv6. 3196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3197d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_cmp(OR_LINKHDR, 2, BPF_H, (0x03<<8) | 0x8e); 3198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_ISONS: 3200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for several OSI protocols. 3202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Frame Relay packets typically have an OSI 3204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * NLPID at the beginning; we check for each 3205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of them. 3206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * What we check for is the NLPID and a frame 3208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * control field of UI, i.e. 0x03 followed 3209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * by the NLPID. 3210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3211d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKHDR, 2, BPF_H, (0x03<<8) | ISO8473_CLNP); 3212d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_cmp(OR_LINKHDR, 2, BPF_H, (0x03<<8) | ISO9542_ESIS); 3213d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b2 = gen_cmp(OR_LINKHDR, 2, BPF_H, (0x03<<8) | ISO10589_ISIS); 3214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, b2); 3215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b2); 3216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b2; 3217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 3219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_false(); 3220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 3222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3224511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_MFR: 3225511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("Multi-link Frame Relay link-layer type filtering not implemented"); 3226511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MFR: 3228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MLFR: 3229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MLPPP: 3230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ATM1: 3231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ATM2: 3232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_PPPOE: 3233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_PPPOE_ATM: 3234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_GGSN: 3235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ES: 3236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MONITOR: 3237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_SERVICES: 3238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ETHER: 3239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_PPP: 3240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_FRELAY: 3241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_CHDLC: 3242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_VP: 3243511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_ST: 3244511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_ISM: 3245511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_VS: 3246511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_SRX_E2E: 3247511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_FIBRECHANNEL: 3248511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_ATM_CEMIC: 3249511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* just lets verify the magic number for now - 3251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * on ATM we may have up to 6 different encapsulations on the wire 3252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and need a lot of heuristics to figure out that the payload 3253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * might be; 3254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * FIXME encapsulation specific BPF_ filters 3256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3257d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_mcmp(OR_LINKHDR, 0, BPF_W, 0x4d474300, 0xffffff00); /* compare the magic number */ 3258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3259511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_BACNET_MS_TP: 3260d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_mcmp(OR_LINKHDR, 0, BPF_W, 0x55FF0000, 0xffff0000); 3261511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3262511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IPNET: 3263511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_ipnet_linktype(proto); 3264511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_LINUX_IRDA: 3266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("IrDA link-layer type filtering not implemented"); 3267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_DOCSIS: 3269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("DOCSIS link-layer type filtering not implemented"); 3270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3271511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_MTP2: 3272511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_MTP2_WITH_PHDR: 3273511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("MTP2 link-layer type filtering not implemented"); 3274511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3275511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_ERF: 3276511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("ERF link-layer type filtering not implemented"); 3277511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3278511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PFSYNC: 3279511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("PFSYNC link-layer type filtering not implemented"); 3280511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_LINUX_LAPD: 3282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("LAPD link-layer type filtering not implemented"); 3283511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3284511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_USB: 3285511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_USB_LINUX: 3286511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_USB_LINUX_MMAPPED: 3287511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("USB link-layer type filtering not implemented"); 3288511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3289511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_BLUETOOTH_HCI_H4: 3290511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_BLUETOOTH_HCI_H4_WITH_PHDR: 3291511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("Bluetooth link-layer type filtering not implemented"); 3292511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3293511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_CAN20B: 3294511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_CAN_SOCKETCAN: 3295511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("CAN link-layer type filtering not implemented"); 3296511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3297511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_15_4: 3298511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_15_4_LINUX: 3299511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_15_4_NONASK_PHY: 3300511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_15_4_NOFCS: 3301511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("IEEE 802.15.4 link-layer type filtering not implemented"); 3302511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3303511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_16_MAC_CPS_RADIO: 3304511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("IEEE 802.16 link-layer type filtering not implemented"); 3305511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3306511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_SITA: 3307511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("SITA link-layer type filtering not implemented"); 3308511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3309511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_RAIF1: 3310511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("RAIF1 link-layer type filtering not implemented"); 3311511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3312511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IPMB: 3313511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("IPMB link-layer type filtering not implemented"); 3314511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3315d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_AX25_KISS: 3316d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes bpf_error("AX.25 link-layer type filtering not implemented"); 3317d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3318d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_NFLOG: 3319d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Using the fixed-size NFLOG header it is possible to tell only 3320d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the address family of the packet, other meaningful data is 3321d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * either missing or behind TLVs. 3322d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3323d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes bpf_error("NFLOG link-layer type filtering not implemented"); 3324d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3325d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes default: 3326d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3327d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Does this link-layer header type have a field 3328d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * indicating the type of the next protocol? If 3329d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * so, off_linktype.constant_part will be the offset of that 3330d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * field in the packet; if not, it will be -1. 3331d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3332d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (off_linktype.constant_part != (u_int)-1) { 3333d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3334d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Yes; assume it's an Ethernet type. (If 3335d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * it's not, it needs to be handled specially 3336d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * above.) 3337d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3338d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_cmp(OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto); 3339d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } else { 3340d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3341d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * No; report an error. 3342d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3343d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes description = pcap_datalink_val_to_description(linktype); 3344d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (description != NULL) { 3345d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes bpf_error("%s link-layer type filtering not implemented", 3346d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes description); 3347d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } else { 3348d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes bpf_error("DLT %u link-layer type filtering not implemented", 3349d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes linktype); 3350d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 3351d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 3352d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 3353d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 3354d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 3355d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3356d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* 3357d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Check for an LLC SNAP packet with a given organization code and 3358d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * protocol type; we check the entire contents of the 802.2 LLC and 3359d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * snap headers, checking for DSAP and SSAP of SNAP and a control 3360d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * field of 0x03 in the LLC header, and for the specified organization 3361d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * code and protocol type in the SNAP header. 3362d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3363d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct block * 3364d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesgen_snap(orgcode, ptype) 3365d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes bpf_u_int32 orgcode; 3366d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes bpf_u_int32 ptype; 3367d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 3368d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes u_char snapblock[8]; 3369d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3370d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes snapblock[0] = LLCSAP_SNAP; /* DSAP = SNAP */ 3371d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes snapblock[1] = LLCSAP_SNAP; /* SSAP = SNAP */ 3372d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes snapblock[2] = 0x03; /* control = UI */ 3373d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes snapblock[3] = (orgcode >> 16); /* upper 8 bits of organization code */ 3374d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes snapblock[4] = (orgcode >> 8); /* middle 8 bits of organization code */ 3375d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes snapblock[5] = (orgcode >> 0); /* lower 8 bits of organization code */ 3376d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes snapblock[6] = (ptype >> 8); /* upper 8 bits of protocol type */ 3377d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes snapblock[7] = (ptype >> 0); /* lower 8 bits of protocol type */ 3378d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_bcmp(OR_LLC, 0, 8, snapblock); 3379d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 3380d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3381d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* 3382d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Generate code to match frames with an LLC header. 3383d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3384d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstruct block * 3385d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesgen_llc(void) 3386d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 3387d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 3388d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3389d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes switch (linktype) { 3390d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3391d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_EN10MB: 3392d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3393d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * We check for an Ethernet type field less than 3394d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 1500, which means it's an 802.3 length field. 3395d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3396d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp_gt(OR_LINKTYPE, 0, BPF_H, ETHERMTU); 3397d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_not(b0); 3398d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3399d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3400d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Now check for the purported DSAP and SSAP not being 3401d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 0xFF, to rule out NetWare-over-802.3. 3402d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3403d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_cmp(OR_LLC, 0, BPF_H, (bpf_int32)0xFFFF); 3404d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_not(b1); 3405d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 3406d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 3407d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3408d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_SUNATM: 3409d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3410d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * We check for LLC traffic. 3411d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3412d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_atmtype_abbrev(A_LLC); 3413d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b0; 3414d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3415d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_IEEE802: /* Token Ring */ 3416d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3417d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * XXX - check for LLC frames. 3418d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3419d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_true(); 3420d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3421d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_FDDI: 3422d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3423d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * XXX - check for LLC frames. 3424d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3425d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_true(); 3426d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3427d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_ATM_RFC1483: 3428d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3429d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * For LLC encapsulation, these are defined to have an 3430d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 802.2 LLC header. 3431d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 3432d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * For VC encapsulation, they don't, but there's no 3433d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * way to check for that; the protocol used on the VC 3434d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * is negotiated out of band. 3435d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3436d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_true(); 3437d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3438d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_IEEE802_11: 3439d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_PRISM_HEADER: 3440d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_IEEE802_11_RADIO: 3441d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_IEEE802_11_RADIO_AVS: 3442d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_PPI: 3443d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3444d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Check that we have a data frame. 3445d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3446d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_check_802_11_data_frame(); 3447d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b0; 3448d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3449d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes default: 3450d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes bpf_error("'llc' not supported for linktype %d", linktype); 3451d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* NOTREACHED */ 3452d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 3453d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 3454d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3455d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstruct block * 3456d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesgen_llc_i(void) 3457d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 3458d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 3459d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct slist *s; 3460d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3461d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3462d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Check whether this is an LLC frame. 3463d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3464d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_llc(); 3465d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3466d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3467d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Load the control byte and test the low-order bit; it must 3468d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * be clear for I frames. 3469d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3470d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LLC, 2, BPF_B); 3471d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = new_block(JMP(BPF_JSET)); 3472d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1->s.k = 0x01; 3473d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1->stmts = s; 3474d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_not(b1); 3475d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 3476d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 3477d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 3478d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3479d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstruct block * 3480d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesgen_llc_s(void) 3481d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 3482d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 3483d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3484d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3485d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Check whether this is an LLC frame. 3486d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3487d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_llc(); 3488d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3489d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3490d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Now compare the low-order 2 bit of the control byte against 3491d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the appropriate value for S frames. 3492d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3493d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_mcmp(OR_LLC, 2, BPF_B, LLC_S_FMT, 0x03); 3494d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 3495d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 3496d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 3497d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3498d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstruct block * 3499d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesgen_llc_u(void) 3500d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 3501d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 3502d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3503d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3504d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Check whether this is an LLC frame. 3505d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3506d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_llc(); 3507d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3508d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3509d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Now compare the low-order 2 bit of the control byte against 3510d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the appropriate value for U frames. 3511d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3512d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_mcmp(OR_LLC, 2, BPF_B, LLC_U_FMT, 0x03); 3513d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 3514d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 3515d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 3516d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3517d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstruct block * 3518d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesgen_llc_s_subtype(bpf_u_int32 subtype) 3519d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 3520d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 3521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3523d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Check whether this is an LLC frame. 3524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3525d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_llc(); 3526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3528d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Now check for an S frame with the appropriate type. 3529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3530d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_mcmp(OR_LLC, 2, BPF_B, subtype, LLC_S_CMD_MASK); 3531d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 3532d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 3533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 3534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3535d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstruct block * 3536d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesgen_llc_u_subtype(bpf_u_int32 subtype) 3537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 3538d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 3539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3540d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3541d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Check whether this is an LLC frame. 3542d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3543d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_llc(); 3544d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3545d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3546d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Now check for a U frame with the appropriate type. 3547d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3548d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_mcmp(OR_LLC, 2, BPF_B, subtype, LLC_U_CMD_MASK); 3549d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 3550d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 3551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 3552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 3554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to match a particular packet type, for link-layer types 3555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * using 802.2 LLC headers. 3556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is *NOT* used for Ethernet; "gen_ether_linktype()" is used 3558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * for that - it handles the D/I/X Ethernet vs. 802.3+802.2 issues. 3559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP 3561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * value, if <= ETHERMTU. We use that to determine whether to 3562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * match the DSAP or both DSAP and LSAP or to check the OUI and 3563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * protocol ID in a SNAP header. 3564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 3566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_llc_linktype(proto) 3567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int proto; 3568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 3569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - handle token-ring variable-length header. 3571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 3573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_IP: 3575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_ISONS: 3576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_NETBEUI: 3577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - should we check both the DSAP and the 3579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SSAP, like this, or should we check just the 3580d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * DSAP, as we do for other SAP values? 3581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3582d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_cmp(OR_LLC, 0, BPF_H, (bpf_u_int32) 3583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ((proto << 8) | proto)); 3584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_IPX: 3586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - are there ever SNAP frames for IPX on 3588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * non-Ethernet 802.x networks? 3589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3590d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_cmp(OR_LLC, 0, BPF_B, 3591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)LLCSAP_IPX); 3592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_ATALK: 3594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 802.2-encapsulated ETHERTYPE_ATALK packets are 3596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SNAP packets with an organization code of 3597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 0x080007 (Apple, for Appletalk) and a protocol 3598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * type of ETHERTYPE_ATALK (Appletalk). 3599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - check for an organization code of 3601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * encapsulated Ethernet as well? 3602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3603511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_snap(0x080007, ETHERTYPE_ATALK); 3604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 3606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - we don't have to check for IPX 802.3 3608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * here, but should we check for the IPX Ethertype? 3609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto <= ETHERMTU) { 3611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is an LLC SAP value, so check 3613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the DSAP. 3614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3615d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_cmp(OR_LLC, 0, BPF_B, (bpf_int32)proto); 3616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 3617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is an Ethernet type; we assume that it's 3619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * unlikely that it'll appear in the right place 3620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * at random, and therefore check only the 3621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * location that would hold the Ethernet type 3622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in a SNAP frame with an organization code of 3623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 0x000000 (encapsulated Ethernet). 3624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - if we were to check for the SNAP DSAP and 3626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LSAP, as per XXX, and were also to check for an 3627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * organization code of 0x000000 (encapsulated 3628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet), we'd do 3629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3630511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * return gen_snap(0x000000, proto); 3631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * here; for now, we don't, as per the above. 3633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * I don't know whether it's worth the extra CPU 3634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * time to do the right check or not. 3635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3636d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_cmp(OR_LLC, 6, BPF_H, (bpf_int32)proto); 3637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 3640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 3642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_hostop(addr, mask, dir, proto, src_off, dst_off) 3643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 addr; 3644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 mask; 3645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir, proto; 3646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int src_off, dst_off; 3647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 3648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 3649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int offset; 3650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 3652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 3654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project offset = src_off; 3655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 3658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project offset = dst_off; 3659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 3662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off); 3663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off); 3664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 3668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 3669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off); 3670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off); 3671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 3672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 3675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 3676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype(proto); 3678d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_mcmp(OR_LINKPL, offset, BPF_W, (bpf_int32)addr, mask); 3679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 3682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6 3684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 3685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_hostop6(addr, mask, dir, proto, src_off, dst_off) 3686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct in6_addr *addr; 3687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct in6_addr *mask; 3688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir, proto; 3689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int src_off, dst_off; 3690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 3691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 3692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int offset; 3693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int32_t *a, *m; 3694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 3696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 3698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project offset = src_off; 3699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 3702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project offset = dst_off; 3703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 3706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off); 3707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off); 3708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 3712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 3713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off); 3714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off); 3715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 3716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 3719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 3720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* this order is important */ 3722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project a = (u_int32_t *)addr; 3723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project m = (u_int32_t *)mask; 3724d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_mcmp(OR_LINKPL, offset + 12, BPF_W, ntohl(a[3]), ntohl(m[3])); 3725d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_mcmp(OR_LINKPL, offset + 8, BPF_W, ntohl(a[2]), ntohl(m[2])); 3726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3727d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_mcmp(OR_LINKPL, offset + 4, BPF_W, ntohl(a[1]), ntohl(m[1])); 3728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3729d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_mcmp(OR_LINKPL, offset + 0, BPF_W, ntohl(a[0]), ntohl(m[0])); 3730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype(proto); 3732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 3735511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 3736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 3738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ehostop(eaddr, dir) 3739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const u_char *eaddr; 3740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int dir; 3741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 3742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block *b0, *b1; 3743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 3745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 3746d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_bcmp(OR_LINKHDR, 6, 6, eaddr); 3747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 3749d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_bcmp(OR_LINKHDR, 0, 6, eaddr); 3750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 3752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_ehostop(eaddr, Q_SRC); 3753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_ehostop(eaddr, Q_DST); 3754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 3758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 3759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_ehostop(eaddr, Q_SRC); 3760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_ehostop(eaddr, Q_DST); 3761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 3762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3763511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3764511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR1: 3765511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr1' is only supported on 802.11 with 802.11 headers"); 3766511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3767511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3768511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR2: 3769511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr2' is only supported on 802.11 with 802.11 headers"); 3770511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3771511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3772511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR3: 3773511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr3' is only supported on 802.11 with 802.11 headers"); 3774511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3775511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3776511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR4: 3777511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr4' is only supported on 802.11 with 802.11 headers"); 3778511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3779511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3780511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_RA: 3781511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'ra' is only supported on 802.11 with 802.11 headers"); 3782511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3783511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3784511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_TA: 3785511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'ta' is only supported on 802.11 with 802.11 headers"); 3786511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 3789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 3790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 3791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 3793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Like gen_ehostop, but for DLT_FDDI 3794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 3796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_fhostop(eaddr, dir) 3797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const u_char *eaddr; 3798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int dir; 3799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 3800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 3801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 3803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 3804d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_bcmp(OR_LINKHDR, 6 + 1 + pcap_fddipad, 6, eaddr); 3805478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 3807d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_bcmp(OR_LINKHDR, 0 + 1 + pcap_fddipad, 6, eaddr); 3808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 3810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_fhostop(eaddr, Q_SRC); 3811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_fhostop(eaddr, Q_DST); 3812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 3816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 3817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_fhostop(eaddr, Q_SRC); 3818478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_fhostop(eaddr, Q_DST); 3819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 3820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3821511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3822511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR1: 3823511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr1' is only supported on 802.11"); 3824511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3825511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3826511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR2: 3827511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr2' is only supported on 802.11"); 3828511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3829511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3830511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR3: 3831511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr3' is only supported on 802.11"); 3832511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3833511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3834511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR4: 3835511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr4' is only supported on 802.11"); 3836511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3837511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3838511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_RA: 3839511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'ra' is only supported on 802.11"); 3840511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3841511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3842511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_TA: 3843511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'ta' is only supported on 802.11"); 3844511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 3847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 3848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 3849478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 3851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Like gen_ehostop, but for DLT_IEEE802 (Token Ring) 3852478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 3854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_thostop(eaddr, dir) 3855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const u_char *eaddr; 3856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int dir; 3857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 3858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block *b0, *b1; 3859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 3861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 3862d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_bcmp(OR_LINKHDR, 8, 6, eaddr); 3863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 3865d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_bcmp(OR_LINKHDR, 2, 6, eaddr); 3866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 3868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_thostop(eaddr, Q_SRC); 3869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_thostop(eaddr, Q_DST); 3870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 3874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 3875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_thostop(eaddr, Q_SRC); 3876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_thostop(eaddr, Q_DST); 3877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 3878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3879511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3880511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR1: 3881511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr1' is only supported on 802.11"); 3882511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3883511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3884511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR2: 3885511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr2' is only supported on 802.11"); 3886511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3887511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3888511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR3: 3889511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr3' is only supported on 802.11"); 3890511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3891511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3892511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR4: 3893511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr4' is only supported on 802.11"); 3894511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3895511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3896511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_RA: 3897511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'ra' is only supported on 802.11"); 3898511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3899511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3900511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_TA: 3901511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'ta' is only supported on 802.11"); 3902511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 3905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 3906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 3907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 3909511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Like gen_ehostop, but for DLT_IEEE802_11 (802.11 wireless LAN) and 3910511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * various 802.11 + radio headers. 3911478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 3913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_wlanhostop(eaddr, dir) 3914478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const u_char *eaddr; 3915478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int dir; 3916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 3917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block *b0, *b1, *b2; 3918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct slist *s; 3919478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3920511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef ENABLE_WLAN_FILTERING_PATCH 3921511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 3922511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * TODO GV 20070613 3923511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * We need to disable the optimizer because the optimizer is buggy 3924511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * and wipes out some LD instructions generated by the below 3925511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * code to validate the Frame Control bits 3926511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 3927511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall no_optimize = 1; 3928511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif /* ENABLE_WLAN_FILTERING_PATCH */ 3929511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 3931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 3932478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Oh, yuk. 3934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For control frames, there is no SA. 3936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For management frames, SA is at an 3938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * offset of 10 from the beginning of 3939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the packet. 3940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For data frames, SA is at an offset 3942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of 10 from the beginning of the packet 3943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * if From DS is clear, at an offset of 3944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 16 from the beginning of the packet 3945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * if From DS is set and To DS is clear, 3946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and an offset of 24 from the beginning 3947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of the packet if From DS is set and To DS 3948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is set. 3949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate the tests to be done for data frames 3953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with From DS set. 3954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * First, check for To DS set, i.e. check "link[1] & 0x01". 3956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3957d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 1, BPF_B); 3958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = new_block(JMP(BPF_JSET)); 3959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->s.k = 0x01; /* To DS */ 3960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->stmts = s; 3961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If To DS is set, the SA is at 24. 3964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3965d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_bcmp(OR_LINKHDR, 24, 6, eaddr); 3966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b1, b0); 3967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now, check for To DS not set, i.e. check 3970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "!(link[1] & 0x01)". 3971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3972d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 1, BPF_B); 3973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2 = new_block(JMP(BPF_JSET)); 3974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->s.k = 0x01; /* To DS */ 3975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->stmts = s; 3976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b2); 3977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If To DS is not set, the SA is at 16. 3980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3981d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_bcmp(OR_LINKHDR, 16, 6, eaddr); 3982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b2, b1); 3983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3984478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now OR together the last two checks. That gives 3986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the complete set of checks for data frames with 3987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * From DS set. 3988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, b0); 3990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now check for From DS being set, and AND that with 3993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the ORed-together checks. 3994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3995d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 1, BPF_B); 3996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = new_block(JMP(BPF_JSET)); 3997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->s.k = 0x02; /* From DS */ 3998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->stmts = s; 3999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b1, b0); 4000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now check for data frames with From DS not set. 4003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4004d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 1, BPF_B); 4005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2 = new_block(JMP(BPF_JSET)); 4006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->s.k = 0x02; /* From DS */ 4007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->stmts = s; 4008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b2); 4009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If From DS isn't set, the SA is at 10. 4012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4013d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_bcmp(OR_LINKHDR, 10, 6, eaddr); 4014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b2, b1); 4015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now OR together the checks for data frames with 4018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * From DS not set and for data frames with From DS 4019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * set; that gives the checks done for data frames. 4020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, b0); 4022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now check for a data frame. 4025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * I.e, check "link[0] & 0x08". 4026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4027d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 0, BPF_B); 4028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = new_block(JMP(BPF_JSET)); 4029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->s.k = 0x08; 4030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->stmts = s; 4031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * AND that with the checks done for data frames. 4034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b1, b0); 4036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If the high-order bit of the type value is 0, this 4039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is a management frame. 4040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * I.e, check "!(link[0] & 0x08)". 4041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4042d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 0, BPF_B); 4043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2 = new_block(JMP(BPF_JSET)); 4044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->s.k = 0x08; 4045478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->stmts = s; 4046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b2); 4047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For management frames, the SA is at 10. 4050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4051d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_bcmp(OR_LINKHDR, 10, 6, eaddr); 4052478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b2, b1); 4053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OR that with the checks done for data frames. 4056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * That gives the checks done for management and 4057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * data frames. 4058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, b0); 4060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If the low-order bit of the type value is 1, 4063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * this is either a control frame or a frame 4064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with a reserved type, and thus not a 4065478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frame with an SA. 4066478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * I.e., check "!(link[0] & 0x04)". 4068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4069d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 0, BPF_B); 4070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = new_block(JMP(BPF_JSET)); 4071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->s.k = 0x04; 4072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->stmts = s; 4073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b1); 4074478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * AND that with the checks for data and management 4077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames. 4078478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b1, b0); 4080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 4081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4082478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 4083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Oh, yuk. 4085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For control frames, there is no DA. 4087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For management frames, DA is at an 4089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * offset of 4 from the beginning of 4090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the packet. 4091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For data frames, DA is at an offset 4093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of 4 from the beginning of the packet 4094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * if To DS is clear and at an offset of 4095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 16 from the beginning of the packet 4096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * if To DS is set. 4097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4099478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate the tests to be done for data frames. 4101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * First, check for To DS set, i.e. "link[1] & 0x01". 4103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4104d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 1, BPF_B); 4105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = new_block(JMP(BPF_JSET)); 4106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->s.k = 0x01; /* To DS */ 4107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->stmts = s; 4108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If To DS is set, the DA is at 16. 4111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4112d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_bcmp(OR_LINKHDR, 16, 6, eaddr); 4113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b1, b0); 4114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now, check for To DS not set, i.e. check 4117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "!(link[1] & 0x01)". 4118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4119d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 1, BPF_B); 4120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2 = new_block(JMP(BPF_JSET)); 4121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->s.k = 0x01; /* To DS */ 4122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->stmts = s; 4123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b2); 4124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If To DS is not set, the DA is at 4. 4127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4128d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_bcmp(OR_LINKHDR, 4, 6, eaddr); 4129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b2, b1); 4130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now OR together the last two checks. That gives 4133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the complete set of checks for data frames. 4134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, b0); 4136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now check for a data frame. 4139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * I.e, check "link[0] & 0x08". 4140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4141d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 0, BPF_B); 4142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = new_block(JMP(BPF_JSET)); 4143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->s.k = 0x08; 4144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->stmts = s; 4145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * AND that with the checks done for data frames. 4148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b1, b0); 4150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If the high-order bit of the type value is 0, this 4153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is a management frame. 4154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * I.e, check "!(link[0] & 0x08)". 4155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4156d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 0, BPF_B); 4157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2 = new_block(JMP(BPF_JSET)); 4158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->s.k = 0x08; 4159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->stmts = s; 4160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b2); 4161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For management frames, the DA is at 4. 4164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4165d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_bcmp(OR_LINKHDR, 4, 6, eaddr); 4166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b2, b1); 4167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OR that with the checks done for data frames. 4170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * That gives the checks done for management and 4171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * data frames. 4172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, b0); 4174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If the low-order bit of the type value is 1, 4177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * this is either a control frame or a frame 4178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with a reserved type, and thus not a 4179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frame with an SA. 4180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * I.e., check "!(link[0] & 0x04)". 4182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4183d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 0, BPF_B); 4184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = new_block(JMP(BPF_JSET)); 4185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->s.k = 0x04; 4186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->stmts = s; 4187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b1); 4188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * AND that with the checks for data and management 4191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames. 4192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b1, b0); 4194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 4195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4196511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_RA: 4197511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4198511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Not present in management frames; addr1 in other 4199511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * frames. 4200511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4201511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4202511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4203511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If the high-order bit of the type value is 0, this 4204511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * is a management frame. 4205511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * I.e, check "(link[0] & 0x08)". 4206511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4207d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 0, BPF_B); 4208511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1 = new_block(JMP(BPF_JSET)); 4209511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->s.k = 0x08; 4210511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->stmts = s; 4211511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4212511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Check addr1. 4214511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4215d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_bcmp(OR_LINKHDR, 4, 6, eaddr); 4216511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4217511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4218511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * AND that with the check of addr1. 4219511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b1, b0); 4221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (b0); 4222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4223511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_TA: 4224511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4225511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Not present in management frames; addr2, if present, 4226511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * in other frames. 4227511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4228511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4229511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4230511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Not present in CTS or ACK control frames. 4231511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4232d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_mcmp(OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_TYPE_CTL, 4233511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall IEEE80211_FC0_TYPE_MASK); 4234511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b0); 4235d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_mcmp(OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_SUBTYPE_CTS, 4236511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall IEEE80211_FC0_SUBTYPE_MASK); 4237511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b1); 4238d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b2 = gen_mcmp(OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_SUBTYPE_ACK, 4239511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall IEEE80211_FC0_SUBTYPE_MASK); 4240511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b2); 4241511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b1, b2); 4242511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_or(b0, b2); 4243511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4244511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4245511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If the high-order bit of the type value is 0, this 4246511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * is a management frame. 4247511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * I.e, check "(link[0] & 0x08)". 4248511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4249d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 0, BPF_B); 4250511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1 = new_block(JMP(BPF_JSET)); 4251511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->s.k = 0x08; 4252511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->stmts = s; 4253511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4254511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4255511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * AND that with the check for frames other than 4256511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * CTS and ACK frames. 4257511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4258511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b1, b2); 4259511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4260511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4261511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Check addr2. 4262511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4263d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_bcmp(OR_LINKHDR, 10, 6, eaddr); 4264511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b2, b1); 4265511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return b1; 4266511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4267511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4268511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * XXX - add BSSID keyword? 4269511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4270511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR1: 4271d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return (gen_bcmp(OR_LINKHDR, 4, 6, eaddr)); 4272511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4273511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR2: 4274511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4275511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Not present in CTS or ACK control frames. 4276511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4277d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_mcmp(OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_TYPE_CTL, 4278511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall IEEE80211_FC0_TYPE_MASK); 4279511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b0); 4280d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_mcmp(OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_SUBTYPE_CTS, 4281511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall IEEE80211_FC0_SUBTYPE_MASK); 4282511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b1); 4283d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b2 = gen_mcmp(OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_SUBTYPE_ACK, 4284511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall IEEE80211_FC0_SUBTYPE_MASK); 4285511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b2); 4286511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b1, b2); 4287511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_or(b0, b2); 4288d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_bcmp(OR_LINKHDR, 10, 6, eaddr); 4289511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b2, b1); 4290511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return b1; 4291511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4292511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR3: 4293511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4294511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Not present in control frames. 4295511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4296d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_mcmp(OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_TYPE_CTL, 4297511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall IEEE80211_FC0_TYPE_MASK); 4298511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b0); 4299d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_bcmp(OR_LINKHDR, 16, 6, eaddr); 4300511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b0, b1); 4301511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return b1; 4302511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4303511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR4: 4304511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4305511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Present only if the direction mask has both "From DS" 4306511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * and "To DS" set. Neither control frames nor management 4307511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * frames should have both of those set, so we don't 4308511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * check the frame type. 4309511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4310d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_mcmp(OR_LINKHDR, 1, BPF_B, 4311511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall IEEE80211_FC1_DIR_DSTODS, IEEE80211_FC1_DIR_MASK); 4312d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_bcmp(OR_LINKHDR, 24, 6, eaddr); 4313511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b0, b1); 4314511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return b1; 4315511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 4317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_wlanhostop(eaddr, Q_SRC); 4318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_wlanhostop(eaddr, Q_DST); 4319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 4320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 4323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 4324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_wlanhostop(eaddr, Q_SRC); 4325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_wlanhostop(eaddr, Q_DST); 4326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 4327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 4330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 4331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 4332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 4334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Like gen_ehostop, but for RFC 2625 IP-over-Fibre-Channel. 4335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (We assume that the addresses are IEEE 48-bit MAC addresses, 4336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as the RFC states.) 4337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 4339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ipfchostop(eaddr, dir) 4340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const u_char *eaddr; 4341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int dir; 4342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 4343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block *b0, *b1; 4344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 4346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 4347d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_bcmp(OR_LINKHDR, 10, 6, eaddr); 4348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 4350d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_bcmp(OR_LINKHDR, 2, 6, eaddr); 4351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 4353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_ipfchostop(eaddr, Q_SRC); 4354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_ipfchostop(eaddr, Q_DST); 4355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 4356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 4359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 4360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_ipfchostop(eaddr, Q_SRC); 4361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_ipfchostop(eaddr, Q_DST); 4362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 4363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4364511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4365511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR1: 4366511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr1' is only supported on 802.11"); 4367511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4368511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4369511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR2: 4370511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr2' is only supported on 802.11"); 4371511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4372511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4373511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR3: 4374511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr3' is only supported on 802.11"); 4375511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4376511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4377511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR4: 4378511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr4' is only supported on 802.11"); 4379511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4380511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4381511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_RA: 4382511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'ra' is only supported on 802.11"); 4383511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4384511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4385511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_TA: 4386511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'ta' is only supported on 802.11"); 4387511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 4390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 4391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 4392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 4394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is quite tricky because there may be pad bytes in front of the 4395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DECNET header, and then there are two possible data packet formats that 4396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * carry both src and dst addresses, plus 5 packet types in a format that 4397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * carries only the src node, plus 2 types that use a different format and 4398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * also carry just the src node. 4399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Yuck. 4401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Instead of doing those all right, we just look for data packets with 4403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 0 or 1 bytes of padding. If you want to look at other packets, that 4404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * will require a lot more hacking. 4405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * To add support for filtering on DECNET "areas" (network numbers) 4407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * one would want to add a "mask" argument to this routine. That would 4408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * make the filter even more inefficient, although one could be clever 4409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and not generate masking instructions if the mask is 0xFFFF. 4410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 4412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_dnhostop(addr, dir) 4413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 addr; 4414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir; 4415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 4416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *b2, *tmp; 4417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int offset_lh; /* offset if long header is received */ 4418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int offset_sh; /* offset if short header is received */ 4419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 4421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 4423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project offset_sh = 1; /* follows flags */ 4424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project offset_lh = 7; /* flgs,darea,dsubarea,HIORD */ 4425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 4428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project offset_sh = 3; /* follows flags, dstnode */ 4429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project offset_lh = 15; /* flgs,darea,dsubarea,did,sarea,ssub,HIORD */ 4430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 4433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Inefficient because we do our Calvinball dance twice */ 4434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_dnhostop(addr, Q_SRC); 4435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_dnhostop(addr, Q_DST); 4436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 4437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 4440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 4441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Inefficient because we do our Calvinball dance twice */ 4442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_dnhostop(addr, Q_SRC); 4443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_dnhostop(addr, Q_DST); 4444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 4445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISO: 4448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("ISO host filtering not implemented"); 4449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 4451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 4452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype(ETHERTYPE_DN); 4454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Check for pad = 1, long header case */ 4455d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes tmp = gen_mcmp(OR_LINKPL, 2, BPF_H, 4456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF)); 4457d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_cmp(OR_LINKPL, 2 + 1 + offset_lh, 4458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project BPF_H, (bpf_int32)ntohs((u_short)addr)); 4459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b1); 4460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Check for pad = 0, long header case */ 4461d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes tmp = gen_mcmp(OR_LINKPL, 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7); 4462d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b2 = gen_cmp(OR_LINKPL, 2 + offset_lh, BPF_H, (bpf_int32)ntohs((u_short)addr)); 4463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b2); 4464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b2, b1); 4465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Check for pad = 1, short header case */ 4466d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes tmp = gen_mcmp(OR_LINKPL, 2, BPF_H, 4467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF)); 4468d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b2 = gen_cmp(OR_LINKPL, 2 + 1 + offset_sh, BPF_H, (bpf_int32)ntohs((u_short)addr)); 4469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b2); 4470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b2, b1); 4471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Check for pad = 0, short header case */ 4472d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes tmp = gen_mcmp(OR_LINKPL, 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7); 4473d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b2 = gen_cmp(OR_LINKPL, 2 + offset_sh, BPF_H, (bpf_int32)ntohs((u_short)addr)); 4474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b2); 4475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b2, b1); 4476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Combine with test for linktype */ 4478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 4479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 4481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 4483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate a check for IPv4 or IPv6 for MPLS-encapsulated packets; 4484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * test the bottom-of-stack bit, and then check the version number 4485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * field in the IP header. 4486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 4488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_mpls_linktype(proto) 4489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int proto; 4490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 4491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 4492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 4494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 4496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* match the bottom-of-stack bit */ 4497d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_mcmp(OR_LINKPL, -2, BPF_B, 0x01, 0x01); 4498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* match the IPv4 version number */ 4499d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_mcmp(OR_LINKPL, 0, BPF_B, 0x40, 0xf0); 4500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 4501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4502d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 4503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 4504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* match the bottom-of-stack bit */ 4505d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_mcmp(OR_LINKPL, -2, BPF_B, 0x01, 0x01); 4506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* match the IPv4 version number */ 4507d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_mcmp(OR_LINKPL, 0, BPF_B, 0x60, 0xf0); 4508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 4509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4510d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 4511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 4512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 4513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 4515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 4517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_host(addr, mask, proto, dir, type) 4518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 addr; 4519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 mask; 4520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int proto; 4521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir; 4522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int type; 4523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 4524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 4525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project const char *typestr; 4526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (type == Q_NET) 4528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project typestr = "net"; 4529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 4530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project typestr = "host"; 4531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 4533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 4535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_host(addr, mask, Q_IP, dir, type); 4536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Only check for non-IPv4 addresses if we're not 4538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * checking MPLS-encapsulated packets. 4539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (label_stack_depth == 0) { 4541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_host(addr, mask, Q_ARP, dir, type); 4542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 4543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_host(addr, mask, Q_RARP, dir, type); 4544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, b0); 4545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 4547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 4549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_hostop(addr, mask, dir, ETHERTYPE_IP, 12, 16); 4550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RARP: 4552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_hostop(addr, mask, dir, ETHERTYPE_REVARP, 14, 24); 4553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ARP: 4555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_hostop(addr, mask, dir, ETHERTYPE_ARP, 14, 24); 4556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_TCP: 4558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'tcp' modifier applied to %s", typestr); 4559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCTP: 4561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'sctp' modifier applied to %s", typestr); 4562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_UDP: 4564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'udp' modifier applied to %s", typestr); 4565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMP: 4567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'icmp' modifier applied to %s", typestr); 4568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGMP: 4570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'igmp' modifier applied to %s", typestr); 4571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGRP: 4573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'igrp' modifier applied to %s", typestr); 4574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PIM: 4576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'pim' modifier applied to %s", typestr); 4577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_VRRP: 4579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'vrrp' modifier applied to %s", typestr); 4580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4581511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_CARP: 4582511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'carp' modifier applied to %s", typestr); 4583511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ATALK: 4585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("ATALK host filtering not implemented"); 4586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AARP: 4588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("AARP host filtering not implemented"); 4589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DECNET: 4591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_dnhostop(addr, dir); 4592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCA: 4594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("SCA host filtering not implemented"); 4595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LAT: 4597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("LAT host filtering not implemented"); 4598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPDL: 4600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("MOPDL host filtering not implemented"); 4601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPRC: 4603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("MOPRC host filtering not implemented"); 4604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 4606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'ip6' modifier applied to ip host"); 4607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMPV6: 4609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'icmp6' modifier applied to %s", typestr); 4610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AH: 4612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'ah' modifier applied to %s", typestr); 4613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ESP: 4615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'esp' modifier applied to %s", typestr); 4616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISO: 4618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("ISO host filtering not implemented"); 4619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ESIS: 4621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'esis' modifier applied to %s", typestr); 4622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS: 4624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'isis' modifier applied to %s", typestr); 4625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_CLNP: 4627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'clnp' modifier applied to %s", typestr); 4628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_STP: 4630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'stp' modifier applied to %s", typestr); 4631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPX: 4633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("IPX host filtering not implemented"); 4634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_NETBEUI: 4636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'netbeui' modifier applied to %s", typestr); 4637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RADIO: 4639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'radio' modifier applied to %s", typestr); 4640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 4642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 4643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 4645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 4646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6 4648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 4649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_host6(addr, mask, proto, dir, type) 4650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct in6_addr *addr; 4651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct in6_addr *mask; 4652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int proto; 4653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir; 4654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int type; 4655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 4656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project const char *typestr; 4657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (type == Q_NET) 4659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project typestr = "net"; 4660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 4661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project typestr = "host"; 4662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 4664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 4666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_host6(addr, mask, Q_IPV6, dir, type); 4667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4668511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_LINK: 4669511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("link-layer modifier applied to ip6 %s", typestr); 4670511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 4672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'ip' modifier applied to ip6 %s", typestr); 4673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RARP: 4675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'rarp' modifier applied to ip6 %s", typestr); 4676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ARP: 4678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'arp' modifier applied to ip6 %s", typestr); 4679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCTP: 4681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'sctp' modifier applied to %s", typestr); 4682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_TCP: 4684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'tcp' modifier applied to %s", typestr); 4685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_UDP: 4687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'udp' modifier applied to %s", typestr); 4688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMP: 4690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'icmp' modifier applied to %s", typestr); 4691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGMP: 4693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'igmp' modifier applied to %s", typestr); 4694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGRP: 4696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'igrp' modifier applied to %s", typestr); 4697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PIM: 4699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'pim' modifier applied to %s", typestr); 4700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_VRRP: 4702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'vrrp' modifier applied to %s", typestr); 4703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4704511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_CARP: 4705511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'carp' modifier applied to %s", typestr); 4706511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ATALK: 4708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("ATALK host filtering not implemented"); 4709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AARP: 4711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("AARP host filtering not implemented"); 4712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DECNET: 4714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'decnet' modifier applied to ip6 %s", typestr); 4715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCA: 4717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("SCA host filtering not implemented"); 4718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LAT: 4720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("LAT host filtering not implemented"); 4721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPDL: 4723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("MOPDL host filtering not implemented"); 4724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPRC: 4726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("MOPRC host filtering not implemented"); 4727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 4729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_hostop6(addr, mask, dir, ETHERTYPE_IPV6, 8, 24); 4730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMPV6: 4732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'icmp6' modifier applied to %s", typestr); 4733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AH: 4735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'ah' modifier applied to %s", typestr); 4736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ESP: 4738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'esp' modifier applied to %s", typestr); 4739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISO: 4741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("ISO host filtering not implemented"); 4742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ESIS: 4744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'esis' modifier applied to %s", typestr); 4745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS: 4747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'isis' modifier applied to %s", typestr); 4748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_CLNP: 4750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'clnp' modifier applied to %s", typestr); 4751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_STP: 4753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'stp' modifier applied to %s", typestr); 4754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPX: 4756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("IPX host filtering not implemented"); 4757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_NETBEUI: 4759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'netbeui' modifier applied to %s", typestr); 4760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RADIO: 4762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'radio' modifier applied to %s", typestr); 4763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 4765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 4766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 4768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 4769511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 4770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef INET6 4772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 4773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_gateway(eaddr, alist, proto, dir) 4774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project const u_char *eaddr; 4775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 **alist; 4776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int proto; 4777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir; 4778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 4779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *tmp; 4780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (dir != 0) 4782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("direction applied to 'gateway'"); 4783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 4785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 4786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 4787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ARP: 4788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RARP: 4789511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (linktype) { 4790511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_EN10MB: 4791511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER: 4792511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER_TRANSPARENT: 4793d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_prevlinkhdr_check(); 4794511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = gen_ehostop(eaddr, Q_OR); 4795d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (b1 != NULL) 4796d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b1, b0); 4797511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4798511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_FDDI: 4799511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = gen_fhostop(eaddr, Q_OR); 4800511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802: 4802511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = gen_thostop(eaddr, Q_OR); 4803511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802_11: 4805511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 4806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802_11_RADIO_AVS: 4807478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802_11_RADIO: 4808511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PPI: 4809511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = gen_wlanhostop(eaddr, Q_OR); 4810511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4811511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_SUNATM: 4812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4813d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * This is LLC-multiplexed traffic; if it were 4814d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * LANE, linktype would have been set to 4815d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * DLT_EN10MB. 4816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4817d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes bpf_error( 4818d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes "'gateway' supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel"); 4819511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IP_OVER_FC: 4821511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = gen_ipfchostop(eaddr, Q_OR); 4822511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4823511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 4824511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error( 4825511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "'gateway' supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel"); 4826511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 4827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR, Q_HOST); 4828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (*alist) { 4829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_host(**alist++, 0xffffffff, proto, Q_OR, 4830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project Q_HOST); 4831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, tmp); 4832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = tmp; 4833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b1); 4835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 4836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("illegal modifier of 'gateway'"); 4839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 4840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 4841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 4842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4843478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 4844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_proto_abbrev(proto) 4845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int proto; 4846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 4847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0; 4848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b1; 4849478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 4851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4852478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCTP: 4853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(IPPROTO_SCTP, Q_IP, Q_DEFAULT); 4854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(IPPROTO_SCTP, Q_IPV6, Q_DEFAULT); 4855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 4856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_TCP: 4859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(IPPROTO_TCP, Q_IP, Q_DEFAULT); 4860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(IPPROTO_TCP, Q_IPV6, Q_DEFAULT); 4861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 4862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_UDP: 4865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(IPPROTO_UDP, Q_IP, Q_DEFAULT); 4866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(IPPROTO_UDP, Q_IPV6, Q_DEFAULT); 4867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 4868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMP: 4871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(IPPROTO_ICMP, Q_IP, Q_DEFAULT); 4872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_IGMP 4875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_IGMP 2 4876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 4877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGMP: 4879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(IPPROTO_IGMP, Q_IP, Q_DEFAULT); 4880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_IGRP 4883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_IGRP 9 4884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 4885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGRP: 4886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(IPPROTO_IGRP, Q_IP, Q_DEFAULT); 4887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_PIM 4890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_PIM 103 4891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 4892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PIM: 4894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(IPPROTO_PIM, Q_IP, Q_DEFAULT); 4895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(IPPROTO_PIM, Q_IPV6, Q_DEFAULT); 4896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 4897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_VRRP 4900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_VRRP 112 4901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 4902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_VRRP: 4904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(IPPROTO_VRRP, Q_IP, Q_DEFAULT); 4905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4907511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef IPPROTO_CARP 4908511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IPPROTO_CARP 112 4909511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 4910511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4911511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_CARP: 4912511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1 = gen_proto(IPPROTO_CARP, Q_IP, Q_DEFAULT); 4913511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4914511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4915478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 4916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_linktype(ETHERTYPE_IP); 4917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4919478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ARP: 4920478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_linktype(ETHERTYPE_ARP); 4921478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4923478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RARP: 4924478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_linktype(ETHERTYPE_REVARP); 4925478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4926478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LINK: 4928478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("link layer applied in wrong context"); 4929478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ATALK: 4931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_linktype(ETHERTYPE_ATALK); 4932478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AARP: 4935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_linktype(ETHERTYPE_AARP); 4936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DECNET: 4939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_linktype(ETHERTYPE_DN); 4940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCA: 4943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_linktype(ETHERTYPE_SCA); 4944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LAT: 4947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_linktype(ETHERTYPE_LAT); 4948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPDL: 4951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_linktype(ETHERTYPE_MOPDL); 4952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPRC: 4955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_linktype(ETHERTYPE_MOPRC); 4956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 4959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_linktype(ETHERTYPE_IPV6); 4960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_ICMPV6 4963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_ICMPV6 58 4964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 4965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMPV6: 4966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(IPPROTO_ICMPV6, Q_IPV6, Q_DEFAULT); 4967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_AH 4970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_AH 51 4971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 4972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AH: 4973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(IPPROTO_AH, Q_IP, Q_DEFAULT); 4974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(IPPROTO_AH, Q_IPV6, Q_DEFAULT); 4975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 4976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_ESP 4979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_ESP 50 4980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 4981478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ESP: 4982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(IPPROTO_ESP, Q_IP, Q_DEFAULT); 4983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(IPPROTO_ESP, Q_IPV6, Q_DEFAULT); 4984478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 4985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISO: 4988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_linktype(LLCSAP_ISONS); 4989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ESIS: 4992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(ISO9542_ESIS, Q_ISO, Q_DEFAULT); 4993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS: 4996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT); 4997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS_L1: /* all IS-IS Level1 PDU-Types */ 5000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT); 5001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */ 5002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT); 5004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT); 5006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT); 5008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS_L2: /* all IS-IS Level2 PDU-Types */ 5012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT); 5013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */ 5014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT); 5016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT); 5018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT); 5020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS_IIH: /* all IS-IS Hello PDU-Types */ 5024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT); 5025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT); 5026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); 5028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS_LSP: 5032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT); 5033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT); 5034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS_SNP: 5038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT); 5039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT); 5040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT); 5042478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT); 5044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5045478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS_CSNP: 5048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT); 5049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT); 5050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5052478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS_PSNP: 5054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT); 5055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT); 5056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_CLNP: 5060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(ISO8473_CLNP, Q_ISO, Q_DEFAULT); 5061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_STP: 5064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_linktype(LLCSAP_8021D); 5065478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5066478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPX: 5068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_linktype(LLCSAP_IPX); 5069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_NETBEUI: 5072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_linktype(LLCSAP_NETBEUI); 5073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5074478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RADIO: 5076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'radio' is not a valid protocol type"); 5077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5078478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 5080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5082478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ipfrag() 5086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s; 5088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 5089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5090511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* not IPv4 frag other than the first frag */ 5091d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKPL, 6, BPF_H); 5092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = new_block(JMP(BPF_JSET)); 5093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->s.k = 0x1fff; 5094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->stmts = s; 5095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b); 5096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 5098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5099478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 5101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate a comparison to a port value in the transport-layer header 5102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * at the specified offset from the beginning of that header. 5103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - this handles a variable-length prefix preceding the link-layer 5105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header, such as the radiotap or AVS radio prefix, but doesn't handle 5106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * variable-length link-layer headers (such as Token Ring or 802.11 5107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * headers). 5108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portatom(off, v) 5111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int off; 5112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 v; 5113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_cmp(OR_TRAN_IPV4, off, BPF_H, v); 5115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portatom6(off, v) 5119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int off; 5120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 v; 5121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_cmp(OR_TRAN_IPV6, off, BPF_H, v); 5123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 5126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portop(port, proto, dir) 5127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int port, proto, dir; 5128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *tmp; 5130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5131511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* ip proto 'proto' and not a fragment other than the first fragment */ 5132d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes tmp = gen_cmp(OR_LINKPL, 9, BPF_B, (bpf_int32)proto); 5133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_ipfrag(); 5134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b0); 5135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 5137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 5138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portatom(0, (bpf_int32)port); 5139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 5142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portatom(2, (bpf_int32)port); 5143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 5146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 5147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_portatom(0, (bpf_int32)port); 5148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portatom(2, (bpf_int32)port); 5149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 5153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_portatom(0, (bpf_int32)port); 5154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portatom(2, (bpf_int32)port); 5155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b1); 5156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 5160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_port(port, ip_proto, dir) 5168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int port; 5169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int ip_proto; 5170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir; 5171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *tmp; 5173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ether proto ip 5176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For FDDI, RFC 1188 says that SNAP encapsulation is used, 5178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * not LLC encapsulation with LLCSAP_IP. 5179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For IEEE 802 networks - which includes 802.5 token ring 5181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (which is what DLT_IEEE802 means) and 802.11 - RFC 1042 5182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * says that SNAP encapsulation is used, not LLC encapsulation 5183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with LLCSAP_IP. 5184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For LLC-encapsulated ATM/"Classical IP", RFC 1483 and 5186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * RFC 2225 say that SNAP encapsulation is used, not LLC 5187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * encapsulation with LLCSAP_IP. 5188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * So we always check for ETHERTYPE_IP. 5190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype(ETHERTYPE_IP); 5192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (ip_proto) { 5194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_UDP: 5195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_TCP: 5196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_SCTP: 5197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portop(port, ip_proto, dir); 5198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case PROTO_UNDEF: 5201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_portop(port, IPPROTO_TCP, dir); 5202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portop(port, IPPROTO_UDP, dir); 5203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_portop(port, IPPROTO_SCTP, dir); 5205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 5210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 5216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portop6(port, proto, dir) 5217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int port, proto, dir; 5218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *tmp; 5220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* ip6 proto 'proto' */ 5222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* XXX - catch the first fragment of a fragmented packet? */ 5223d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKPL, 6, BPF_B, (bpf_int32)proto); 5224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 5226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 5227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portatom6(0, (bpf_int32)port); 5228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 5231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portatom6(2, (bpf_int32)port); 5232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 5235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 5236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_portatom6(0, (bpf_int32)port); 5237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portatom6(2, (bpf_int32)port); 5238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 5242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_portatom6(0, (bpf_int32)port); 5243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portatom6(2, (bpf_int32)port); 5244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b1); 5245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 5249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_port6(port, ip_proto, dir) 5257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int port; 5258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int ip_proto; 5259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir; 5260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *tmp; 5262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* link proto ip6 */ 5264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype(ETHERTYPE_IPV6); 5265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (ip_proto) { 5267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_UDP: 5268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_TCP: 5269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_SCTP: 5270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portop6(port, ip_proto, dir); 5271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case PROTO_UNDEF: 5274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_portop6(port, IPPROTO_TCP, dir); 5275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portop6(port, IPPROTO_UDP, dir); 5276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_portop6(port, IPPROTO_SCTP, dir); 5278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 5283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* gen_portrange code */ 5289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portrangeatom(off, v1, v2) 5291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int off; 5292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 v1, v2; 5293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b1, *b2; 5295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (v1 > v2) { 5297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Reverse the order of the ports, so v1 is the lower one. 5299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 vtemp; 5301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project vtemp = v1; 5303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v1 = v2; 5304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v2 = vtemp; 5305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_cmp_ge(OR_TRAN_IPV4, off, BPF_H, v1); 5308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2 = gen_cmp_le(OR_TRAN_IPV4, off, BPF_H, v2); 5309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5310d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b1, b2); 5311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b2; 5313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 5316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portrangeop(port1, port2, proto, dir) 5317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int port1, port2; 5318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int proto; 5319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir; 5320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *tmp; 5322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5323511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* ip proto 'proto' and not a fragment other than the first fragment */ 5324d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes tmp = gen_cmp(OR_LINKPL, 9, BPF_B, (bpf_int32)proto); 5325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_ipfrag(); 5326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b0); 5327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 5329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 5330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portrangeatom(0, (bpf_int32)port1, (bpf_int32)port2); 5331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 5334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portrangeatom(2, (bpf_int32)port1, (bpf_int32)port2); 5335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 5338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 5339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_portrangeatom(0, (bpf_int32)port1, (bpf_int32)port2); 5340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portrangeatom(2, (bpf_int32)port1, (bpf_int32)port2); 5341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 5345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_portrangeatom(0, (bpf_int32)port1, (bpf_int32)port2); 5346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portrangeatom(2, (bpf_int32)port1, (bpf_int32)port2); 5347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b1); 5348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 5352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portrange(port1, port2, ip_proto, dir) 5360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int port1, port2; 5361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int ip_proto; 5362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir; 5363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *tmp; 5365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* link proto ip */ 5367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype(ETHERTYPE_IP); 5368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (ip_proto) { 5370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_UDP: 5371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_TCP: 5372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_SCTP: 5373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portrangeop(port1, port2, ip_proto, dir); 5374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case PROTO_UNDEF: 5377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_portrangeop(port1, port2, IPPROTO_TCP, dir); 5378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portrangeop(port1, port2, IPPROTO_UDP, dir); 5379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_portrangeop(port1, port2, IPPROTO_SCTP, dir); 5381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 5386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portrangeatom6(off, v1, v2) 5393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int off; 5394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 v1, v2; 5395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b1, *b2; 5397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (v1 > v2) { 5399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Reverse the order of the ports, so v1 is the lower one. 5401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 vtemp; 5403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project vtemp = v1; 5405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v1 = v2; 5406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v2 = vtemp; 5407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_cmp_ge(OR_TRAN_IPV6, off, BPF_H, v1); 5410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2 = gen_cmp_le(OR_TRAN_IPV6, off, BPF_H, v2); 5411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5412d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b1, b2); 5413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b2; 5415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 5418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portrangeop6(port1, port2, proto, dir) 5419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int port1, port2; 5420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int proto; 5421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir; 5422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *tmp; 5424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* ip6 proto 'proto' */ 5426511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* XXX - catch the first fragment of a fragmented packet? */ 5427d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKPL, 6, BPF_B, (bpf_int32)proto); 5428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 5430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 5431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portrangeatom6(0, (bpf_int32)port1, (bpf_int32)port2); 5432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 5435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portrangeatom6(2, (bpf_int32)port1, (bpf_int32)port2); 5436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 5439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 5440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_portrangeatom6(0, (bpf_int32)port1, (bpf_int32)port2); 5441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portrangeatom6(2, (bpf_int32)port1, (bpf_int32)port2); 5442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 5446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_portrangeatom6(0, (bpf_int32)port1, (bpf_int32)port2); 5447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portrangeatom6(2, (bpf_int32)port1, (bpf_int32)port2); 5448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b1); 5449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 5453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portrange6(port1, port2, ip_proto, dir) 5461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int port1, port2; 5462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int ip_proto; 5463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir; 5464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *tmp; 5466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* link proto ip6 */ 5468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype(ETHERTYPE_IPV6); 5469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (ip_proto) { 5471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_UDP: 5472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_TCP: 5473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_SCTP: 5474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portrangeop6(port1, port2, ip_proto, dir); 5475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case PROTO_UNDEF: 5478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_portrangeop6(port1, port2, IPPROTO_TCP, dir); 5479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_portrangeop6(port1, port2, IPPROTO_UDP, dir); 5480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_portrangeop6(port1, port2, IPPROTO_SCTP, dir); 5482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 5487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 5493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectlookup_proto(name, proto) 5494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const char *name; 5495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int proto; 5496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int v; 5498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 5500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 5502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 5503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 5504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = pcap_nametoproto(name); 5505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (v == PROTO_UNDEF) 5506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("unknown ip proto '%s'", name); 5507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LINK: 5510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* XXX should look up h/w protocol type based on linktype */ 5511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = pcap_nametoeproto(name); 5512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (v == PROTO_UNDEF) { 5513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = pcap_nametollc(name); 5514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (v == PROTO_UNDEF) 5515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("unknown ether proto '%s'", name); 5516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISO: 5520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (strcmp(name, "esis") == 0) 5521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = ISO9542_ESIS; 5522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (strcmp(name, "isis") == 0) 5523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = ISO10589_ISIS; 5524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (strcmp(name, "clnp") == 0) 5525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = ISO8473_CLNP; 5526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 5527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("unknown osi proto '%s'", name); 5528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = PROTO_UNDEF; 5532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return v; 5535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if 0 5538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct stmt * 5539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_joinsp(s, n) 5540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct stmt **s; 5541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int n; 5542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return NULL; 5544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 5546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_protochain(v, proto, dir) 5549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int v; 5550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int proto; 5551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir; 5552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef NO_PROTOCHAIN 5554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_proto(v, proto, dir); 5555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 5556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b; 5557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s[100]; 5558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int fix2, fix3, fix4, fix5; 5559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int ahcheck, again, end; 5560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int i, max; 5561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int reg2 = alloc_reg(); 5562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(s, 0, sizeof(s)); 5564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fix2 = fix3 = fix4 = fix5 = 0; 5565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 5567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 5568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 5569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 5571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_protochain(v, Q_IP, dir); 5572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = gen_protochain(v, Q_IPV6, dir); 5573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b); 5574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 5575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("bad protocol applied for 'protochain'"); 5577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 5578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5581511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * We don't handle variable-length prefixes before the link-layer 5582511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * header, or variable-length link-layer headers, here yet. 5583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We might want to add BPF instructions to do the protochain 5584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * work, to simplify that and, on platforms that have a BPF 5585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * interpreter with the new instructions, let the filtering 5586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * be done in the kernel. (We already require a modified BPF 5587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * engine to do the protochain stuff, to support backward 5588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * branches, and backward branch support is unlikely to appear 5589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in kernel BPF engines.) 5590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5591d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (off_linkpl.is_variable) 5592d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes bpf_error("'protochain' not supported with variable length headers"); 5593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project no_optimize = 1; /*this code is not compatible with optimzer yet */ 5595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * s[0] is a dummy entry to protect other BPF insn from damage 5598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * by s[fix] = foo with uninitialized variable "fix". It is somewhat 5599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * hard to find interdependency made by jump table fixup. 5600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i = 0; 5602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(0); /*dummy*/ 5603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 5606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 5607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype(ETHERTYPE_IP); 5608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A = ip->ip_p */ 5610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B); 5611d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s[i]->s.k = off_linkpl.constant_part + off_nl + 9; 5612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* X = ip->ip_hl << 2 */ 5614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_LDX|BPF_MSH|BPF_B); 5615d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s[i]->s.k = off_linkpl.constant_part + off_nl; 5616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5618511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 5619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 5620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype(ETHERTYPE_IPV6); 5621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A = ip6->ip_nxt */ 5623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B); 5624d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s[i]->s.k = off_linkpl.constant_part + off_nl + 6; 5625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* X = sizeof(struct ip6_hdr) */ 5627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_LDX|BPF_IMM); 5628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = 40; 5629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5631511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 5632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("unsupported proto to gen_protochain"); 5634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 5635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* again: if (A == v) goto end; else fall through; */ 5638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project again = i; 5639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 5640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = v; 5641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jt = NULL; /*later*/ 5642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jf = NULL; /*update in next stmt*/ 5643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fix5 = i; 5644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_NONE 5647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_NONE 59 5648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 5649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* if (A == IPPROTO_NONE) goto end */ 5650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 5651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jt = NULL; /*later*/ 5652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jf = NULL; /*update in next stmt*/ 5653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = IPPROTO_NONE; 5654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[fix5]->s.jf = s[i]; 5655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fix2 = i; 5656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_IPV6) { 5659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int v6start, v6end, v6advance, j; 5660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v6start = i; 5662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* if (A == IPPROTO_HOPOPTS) goto v6advance */ 5663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 5664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jt = NULL; /*later*/ 5665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jf = NULL; /*update in next stmt*/ 5666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = IPPROTO_HOPOPTS; 5667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[fix2]->s.jf = s[i]; 5668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* if (A == IPPROTO_DSTOPTS) goto v6advance */ 5670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 5671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jt = NULL; /*later*/ 5672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jf = NULL; /*update in next stmt*/ 5673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = IPPROTO_DSTOPTS; 5674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* if (A == IPPROTO_ROUTING) goto v6advance */ 5676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 5677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jt = NULL; /*later*/ 5678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jf = NULL; /*update in next stmt*/ 5679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = IPPROTO_ROUTING; 5680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* if (A == IPPROTO_FRAGMENT) goto v6advance; else goto ahcheck; */ 5682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 5683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jt = NULL; /*later*/ 5684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jf = NULL; /*later*/ 5685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = IPPROTO_FRAGMENT; 5686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fix3 = i; 5687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v6end = i; 5688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* v6advance: */ 5691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v6advance = i; 5692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in short, 5695511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * A = P[X + packet head]; 5696511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * X = X + (P[X + packet head + 1] + 1) * 8; 5697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A = P[X + packet head] */ 5699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); 5700d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s[i]->s.k = off_linkpl.constant_part + off_nl; 5701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* MEM[reg2] = A */ 5703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_ST); 5704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = reg2; 5705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5706511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* A = P[X + packet head + 1]; */ 5707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); 5708d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s[i]->s.k = off_linkpl.constant_part + off_nl + 1; 5709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A += 1 */ 5711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 5712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = 1; 5713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A *= 8 */ 5715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K); 5716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = 8; 5717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5718511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* A += X */ 5719511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_X); 5720511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s[i]->s.k = 0; 5721511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall i++; 5722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* X = A; */ 5723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_MISC|BPF_TAX); 5724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A = MEM[reg2] */ 5726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_LD|BPF_MEM); 5727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = reg2; 5728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* goto again; (must use BPF_JA for backward jump) */ 5731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_JMP|BPF_JA); 5732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = again - i - 1; 5733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i - 1]->s.jf = s[i]; 5734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* fixup */ 5737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project for (j = v6start; j <= v6end; j++) 5738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[j]->s.jt = s[v6advance]; 5739511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else { 5740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* nop */ 5741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 5742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = 0; 5743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[fix2]->s.jf = s[i]; 5744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* ahcheck: */ 5748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ahcheck = i; 5749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* if (A == IPPROTO_AH) then fall through; else goto end; */ 5750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 5751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jt = NULL; /*later*/ 5752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jf = NULL; /*later*/ 5753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = IPPROTO_AH; 5754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (fix3) 5755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[fix3]->s.jf = s[ahcheck]; 5756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fix4 = i; 5757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in short, 5761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * A = P[X]; 5762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * X = X + (P[X + 1] + 2) * 4; 5763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A = X */ 5765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i - 1]->s.jt = s[i] = new_stmt(BPF_MISC|BPF_TXA); 5766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A = P[X + packet head]; */ 5768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); 5769d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s[i]->s.k = off_linkpl.constant_part + off_nl; 5770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* MEM[reg2] = A */ 5772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_ST); 5773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = reg2; 5774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A = X */ 5776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i - 1]->s.jt = s[i] = new_stmt(BPF_MISC|BPF_TXA); 5777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A += 1 */ 5779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 5780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = 1; 5781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* X = A */ 5783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_MISC|BPF_TAX); 5784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A = P[X + packet head] */ 5786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); 5787d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s[i]->s.k = off_linkpl.constant_part + off_nl; 5788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A += 2 */ 5790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 5791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = 2; 5792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A *= 4 */ 5794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K); 5795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = 4; 5796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* X = A; */ 5798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_MISC|BPF_TAX); 5799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A = MEM[reg2] */ 5801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_LD|BPF_MEM); 5802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = reg2; 5803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5805478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* goto again; (must use BPF_JA for backward jump) */ 5806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_JMP|BPF_JA); 5807478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = again - i - 1; 5808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* end: nop */ 5811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project end = i; 5812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 5813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = 0; 5814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[fix2]->s.jt = s[end]; 5815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[fix4]->s.jf = s[end]; 5816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[fix5]->s.jt = s[end]; 5817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5818478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * make slist chain 5821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5822478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project max = i; 5823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project for (i = 0; i < max - 1; i++) 5824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->next = s[i + 1]; 5825478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[max - 1]->next = NULL; 5826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * emit final check 5829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = new_block(JMP(BPF_JEQ)); 5831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->stmts = s[1]; /*remember, s[0] is dummy*/ 5832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->s.k = v; 5833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free_reg(reg2); 5835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b); 5837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 5838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 5839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5841511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct block * 5842511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_check_802_11_data_frame() 5843511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 5844511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *s; 5845511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct block *b0, *b1; 5846511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 5847511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 5848511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * A data frame has the 0x08 bit (b3) in the frame control field set 5849511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * and the 0x04 bit (b2) clear. 5850511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 5851d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 0, BPF_B); 5852511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = new_block(JMP(BPF_JSET)); 5853511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0->s.k = 0x08; 5854511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0->stmts = s; 5855d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 5856d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 0, BPF_B); 5857511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1 = new_block(JMP(BPF_JSET)); 5858511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->s.k = 0x04; 5859511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->stmts = s; 5860511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b1); 5861511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 5862511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b1, b0); 5863511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 5864511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return b0; 5865511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 5866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 5868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code that checks whether the packet is a packet for protocol 5869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * <proto> and whether the type field in that protocol's header has 5870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the value <v>, e.g. if <proto> is Q_IP, it checks whether it's an 5871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * IP packet and checks the protocol number in the IP header against <v>. 5872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If <proto> is Q_DEFAULT, i.e. just "proto" was specified, it checks 5874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * against Q_IP and Q_IPV6. 5875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_proto(v, proto, dir) 5878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int v; 5879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int proto; 5880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir; 5881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 5883511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef CHASE_CHAIN 5884511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct block *b2; 5885511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 5886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (dir != Q_DEFAULT) 5888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("direction applied to 'proto'"); 5889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 5891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 5892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(v, Q_IP, dir); 5893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_proto(v, Q_IPV6, dir); 5894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5896511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 5897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 5898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For FDDI, RFC 1188 says that SNAP encapsulation is used, 5900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * not LLC encapsulation with LLCSAP_IP. 5901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For IEEE 802 networks - which includes 802.5 token ring 5903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (which is what DLT_IEEE802 means) and 802.11 - RFC 1042 5904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * says that SNAP encapsulation is used, not LLC encapsulation 5905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with LLCSAP_IP. 5906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For LLC-encapsulated ATM/"Classical IP", RFC 1483 and 5908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * RFC 2225 say that SNAP encapsulation is used, not LLC 5909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * encapsulation with LLCSAP_IP. 5910478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5911478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * So we always check for ETHERTYPE_IP. 5912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype(ETHERTYPE_IP); 5914478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef CHASE_CHAIN 5915d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_cmp(OR_LINKPL, 9, BPF_B, (bpf_int32)v); 5916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 5917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_protochain(v, Q_IP); 5918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 5919478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5920478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5921478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISO: 5923478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (linktype) { 5924478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5925478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_FRELAY: 5926478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Frame Relay packets typically have an OSI 5928478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * NLPID at the beginning; "gen_linktype(LLCSAP_ISONS)" 5929478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * generates code to check for all the OSI 5930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * NLPIDs, so calling it and then adding a check 5931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * for the particular NLPID for which we're 5932478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * looking is bogus, as we can just check for 5933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the NLPID. 5934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * What we check for is the NLPID and a frame 5936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * control field value of UI, i.e. 0x03 followed 5937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * by the NLPID. 5938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - assumes a 2-byte Frame Relay header with 5940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DLCI and flags. What if the address is longer? 5941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - what about SNAP-encapsulated frames? 5943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5944d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_cmp(OR_LINKHDR, 2, BPF_H, (0x03<<8) | v); 5945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 5946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_C_HDLC: 5949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Cisco uses an Ethertype lookalike - for OSI, 5951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * it's 0xfefe. 5952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype(LLCSAP_ISONS<<8 | LLCSAP_ISONS); 5954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* OSI in C-HDLC is stuffed with a fudge byte */ 5955d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_cmp(OR_LINKPL_NOSNAP, 1, BPF_B, (long)v); 5956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype(LLCSAP_ISONS); 5961d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_cmp(OR_LINKPL_NOSNAP, 0, BPF_B, (long)v); 5962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS: 5967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT); 5968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4 is the offset of the PDU type relative to the IS-IS 5970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header. 5971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5972d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_cmp(OR_LINKPL_NOSNAP, 4, BPF_B, (long)v); 5973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ARP: 5977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("arp does not encapsulate another protocol"); 5978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 5979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RARP: 5981478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("rarp does not encapsulate another protocol"); 5982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 5983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5984478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ATALK: 5985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("atalk encapsulation is not specifiable"); 5986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 5987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DECNET: 5989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("decnet encapsulation is not specifiable"); 5990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 5991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCA: 5993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("sca does not encapsulate another protocol"); 5994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 5995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LAT: 5997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("lat does not encapsulate another protocol"); 5998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 5999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPRC: 6001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("moprc does not encapsulate another protocol"); 6002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPDL: 6005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("mopdl does not encapsulate another protocol"); 6006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LINK: 6009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_linktype(v); 6010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_UDP: 6012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'udp proto' is bogus"); 6013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_TCP: 6016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'tcp proto' is bogus"); 6017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCTP: 6020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'sctp proto' is bogus"); 6021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMP: 6024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'icmp proto' is bogus"); 6025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGMP: 6028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'igmp proto' is bogus"); 6029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGRP: 6032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'igrp proto' is bogus"); 6033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PIM: 6036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'pim proto' is bogus"); 6037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_VRRP: 6040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'vrrp proto' is bogus"); 6041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6042478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6043511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_CARP: 6044511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'carp proto' is bogus"); 6045511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NOTREACHED */ 6046511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 6047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 6048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype(ETHERTYPE_IPV6); 6049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef CHASE_CHAIN 6050511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 6051511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Also check for a fragment header before the final 6052511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * header. 6053511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 6054d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b2 = gen_cmp(OR_LINKPL, 6, BPF_B, IPPROTO_FRAGMENT); 6055d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_cmp(OR_LINKPL, 40, BPF_B, (bpf_int32)v); 6056511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b2, b1); 6057d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b2 = gen_cmp(OR_LINKPL, 6, BPF_B, (bpf_int32)v); 6058511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_or(b2, b1); 6059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 6060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_protochain(v, Q_IPV6); 6061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 6062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 6063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 6064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6065478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMPV6: 6066478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'icmp6 proto' is bogus"); 6067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AH: 6069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'ah proto' is bogus"); 6070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ESP: 6072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'ah proto' is bogus"); 6073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6074478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_STP: 6075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'stp proto' is bogus"); 6076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPX: 6078478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'ipx proto' is bogus"); 6079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_NETBEUI: 6081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'netbeui proto' is bogus"); 6082478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RADIO: 6084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'radio proto' is bogus"); 6085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 6087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 6088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 6094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_scode(name, q) 6095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const char *name; 6096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct qual q; 6097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int proto = q.proto; 6099478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir = q.dir; 6100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int tproto; 6101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_char *eaddr; 6102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 mask, addr; 6103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef INET6 6104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 **alist; 6105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 6106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int tproto6; 6107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct sockaddr_in *sin4; 6108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct sockaddr_in6 *sin6; 6109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct addrinfo *res, *res0; 6110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct in6_addr mask128; 6111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /*INET6*/ 6112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b, *tmp; 6113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int port, real_proto; 6114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int port1, port2; 6115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (q.addr) { 6117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_NET: 6119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project addr = pcap_nametonetaddr(name); 6120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (addr == 0) 6121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("unknown network '%s'", name); 6122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Left justify network addr and calculate its network mask */ 6123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project mask = 0xffffffff; 6124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (addr && (addr & 0xff000000) == 0) { 6125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project addr <<= 8; 6126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project mask <<= 8; 6127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_host(addr, mask, proto, dir, q.addr); 6129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 6131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_HOST: 6132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_LINK) { 6133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (linktype) { 6134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_EN10MB: 6136511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER: 6137511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER_TRANSPARENT: 6138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project eaddr = pcap_ether_hostton(name); 6139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (eaddr == NULL) 6140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error( 6141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "unknown ether host '%s'", name); 6142d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes tmp = gen_prevlinkhdr_check(); 6143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = gen_ehostop(eaddr, dir); 6144d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (tmp != NULL) 6145d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(tmp, b); 6146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(eaddr); 6147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_FDDI: 6150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project eaddr = pcap_ether_hostton(name); 6151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (eaddr == NULL) 6152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error( 6153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "unknown FDDI host '%s'", name); 6154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = gen_fhostop(eaddr, dir); 6155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(eaddr); 6156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802: 6159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project eaddr = pcap_ether_hostton(name); 6160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (eaddr == NULL) 6161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error( 6162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "unknown token ring host '%s'", name); 6163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = gen_thostop(eaddr, dir); 6164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(eaddr); 6165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802_11: 6168511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 6169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802_11_RADIO_AVS: 6170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802_11_RADIO: 6171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPI: 6172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project eaddr = pcap_ether_hostton(name); 6173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (eaddr == NULL) 6174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error( 6175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "unknown 802.11 host '%s'", name); 6176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = gen_wlanhostop(eaddr, dir); 6177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(eaddr); 6178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IP_OVER_FC: 6181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project eaddr = pcap_ether_hostton(name); 6182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (eaddr == NULL) 6183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error( 6184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "unknown Fibre Channel host '%s'", name); 6185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = gen_ipfchostop(eaddr, dir); 6186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(eaddr); 6187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("only ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel supports link-level host name"); 6191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else if (proto == Q_DECNET) { 6192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project unsigned short dn_addr = __pcap_nametodnaddr(name); 6193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * I don't think DECNET hosts can be multihomed, so 6195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * there is no need to build up a list of addresses 6196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (gen_host(dn_addr, 0, proto, dir, q.addr)); 6198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 6199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef INET6 6200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project alist = pcap_nametoaddr(name); 6201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (alist == NULL || *alist == NULL) 6202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("unknown host '%s'", name); 6203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tproto = proto; 6204d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (off_linktype.constant_part == (u_int)-1 && 6205d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes tproto == Q_DEFAULT) 6206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tproto = Q_IP; 6207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = gen_host(**alist++, 0xffffffff, tproto, dir, q.addr); 6208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (*alist) { 6209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_host(**alist++, 0xffffffff, 6210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tproto, dir, q.addr); 6211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b, tmp); 6212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = tmp; 6213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 6216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(&mask128, 0xff, sizeof(mask128)); 6217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project res0 = res = pcap_nametoaddrinfo(name); 6218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (res == NULL) 6219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("unknown host '%s'", name); 6220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ai = res; 6221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = tmp = NULL; 6222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tproto = tproto6 = proto; 6223d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (off_linktype.constant_part == -1 && 6224d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes tproto == Q_DEFAULT) { 6225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tproto = Q_IP; 6226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tproto6 = Q_IPV6; 6227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project for (res = res0; res; res = res->ai_next) { 6229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (res->ai_family) { 6230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case AF_INET: 6231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (tproto == Q_IPV6) 6232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 6233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sin4 = (struct sockaddr_in *) 6235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project res->ai_addr; 6236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_host(ntohl(sin4->sin_addr.s_addr), 6237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 0xffffffff, tproto, dir, q.addr); 6238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 6239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case AF_INET6: 6240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (tproto6 == Q_IP) 6241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 6242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sin6 = (struct sockaddr_in6 *) 6244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project res->ai_addr; 6245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = gen_host6(&sin6->sin6_addr, 6246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project &mask128, tproto6, dir, q.addr); 6247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 6248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 6249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 6250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (b) 6252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b, tmp); 6253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = tmp; 6254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6255511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ai = NULL; 6256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project freeaddrinfo(res0); 6257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (b == NULL) { 6258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("unknown host '%s'%s", name, 6259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (proto == Q_DEFAULT) 6260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ? "" 6261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project : " for specified address family"); 6262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /*INET6*/ 6265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PORT: 6268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto != Q_DEFAULT && 6269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto != Q_UDP && proto != Q_TCP && proto != Q_SCTP) 6270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("illegal qualifier of 'port'"); 6271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (pcap_nametoport(name, &port, &real_proto) == 0) 6272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("unknown port '%s'", name); 6273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_UDP) { 6274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (real_proto == IPPROTO_TCP) 6275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("port '%s' is tcp", name); 6276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (real_proto == IPPROTO_SCTP) 6277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("port '%s' is sctp", name); 6278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* override PROTO_UNDEF */ 6280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project real_proto = IPPROTO_UDP; 6281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_TCP) { 6283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (real_proto == IPPROTO_UDP) 6284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("port '%s' is udp", name); 6285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (real_proto == IPPROTO_SCTP) 6287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("port '%s' is sctp", name); 6288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* override PROTO_UNDEF */ 6290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project real_proto = IPPROTO_TCP; 6291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_SCTP) { 6293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (real_proto == IPPROTO_UDP) 6294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("port '%s' is udp", name); 6295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (real_proto == IPPROTO_TCP) 6297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("port '%s' is tcp", name); 6298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* override PROTO_UNDEF */ 6300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project real_proto = IPPROTO_SCTP; 6301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6302511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (port < 0) 6303511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("illegal port number %d < 0", port); 6304511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (port > 65535) 6305511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("illegal port number %d > 65535", port); 6306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = gen_port(port, real_proto, dir); 6307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(gen_port6(port, real_proto, dir), b); 6308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PORTRANGE: 6311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto != Q_DEFAULT && 6312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto != Q_UDP && proto != Q_TCP && proto != Q_SCTP) 6313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("illegal qualifier of 'portrange'"); 6314d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (pcap_nametoportrange(name, &port1, &port2, &real_proto) == 0) 6315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("unknown port in range '%s'", name); 6316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_UDP) { 6317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (real_proto == IPPROTO_TCP) 6318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("port in range '%s' is tcp", name); 6319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (real_proto == IPPROTO_SCTP) 6320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("port in range '%s' is sctp", name); 6321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* override PROTO_UNDEF */ 6323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project real_proto = IPPROTO_UDP; 6324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_TCP) { 6326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (real_proto == IPPROTO_UDP) 6327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("port in range '%s' is udp", name); 6328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (real_proto == IPPROTO_SCTP) 6329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("port in range '%s' is sctp", name); 6330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* override PROTO_UNDEF */ 6332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project real_proto = IPPROTO_TCP; 6333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_SCTP) { 6335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (real_proto == IPPROTO_UDP) 6336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("port in range '%s' is udp", name); 6337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (real_proto == IPPROTO_TCP) 6338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("port in range '%s' is tcp", name); 6339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* override PROTO_UNDEF */ 6341d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes real_proto = IPPROTO_SCTP; 6342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6343511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (port1 < 0) 6344511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("illegal port number %d < 0", port1); 6345511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (port1 > 65535) 6346511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("illegal port number %d > 65535", port1); 6347511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (port2 < 0) 6348511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("illegal port number %d < 0", port2); 6349511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (port2 > 65535) 6350511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("illegal port number %d > 65535", port2); 6351511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 6352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = gen_portrange(port1, port2, real_proto, dir); 6353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(gen_portrange6(port1, port2, real_proto, dir), b); 6354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_GATEWAY: 6357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef INET6 6358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project eaddr = pcap_ether_hostton(name); 6359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (eaddr == NULL) 6360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("unknown ether host: %s", name); 6361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project alist = pcap_nametoaddr(name); 6363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (alist == NULL || *alist == NULL) 6364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("unknown host '%s'", name); 6365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = gen_gateway(eaddr, alist, proto, dir); 6366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(eaddr); 6367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 6369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'gateway' not supported in this configuration"); 6370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /*INET6*/ 6371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PROTO: 6373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project real_proto = lookup_proto(name, proto); 6374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (real_proto >= 0) 6375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_proto(real_proto, proto, dir); 6376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("unknown protocol: %s", name); 6378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PROTOCHAIN: 6380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project real_proto = lookup_proto(name, proto); 6381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (real_proto >= 0) 6382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_protochain(real_proto, proto, dir); 6383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("unknown protocol: %s", name); 6385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_UNDEF: 6387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project syntax(); 6388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 6391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 6395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_mcode(s1, s2, masklen, q) 6396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const char *s1, *s2; 6397d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes register unsigned int masklen; 6398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct qual q; 6399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int nlen, mlen; 6401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 n, m; 6402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project nlen = __pcap_atoin(s1, &n); 6404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Promote short ipaddr */ 6405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project n <<= 32 - nlen; 6406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (s2 != NULL) { 6408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project mlen = __pcap_atoin(s2, &m); 6409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Promote short ipaddr */ 6410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project m <<= 32 - mlen; 6411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ((n & ~m) != 0) 6412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("non-network bits set in \"%s mask %s\"", 6413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s1, s2); 6414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 6415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Convert mask len to mask */ 6416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (masklen > 32) 6417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("mask length must be <= 32"); 6418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (masklen == 0) { 6419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * X << 32 is not guaranteed by C to be 0; it's 6421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * undefined. 6422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project m = 0; 6424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 6425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project m = 0xffffffff << (32 - masklen); 6426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ((n & ~m) != 0) 6427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("non-network bits set in \"%s/%d\"", 6428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s1, masklen); 6429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (q.addr) { 6432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_NET: 6434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_host(n, m, q.proto, q.dir, q.addr); 6435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 6437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("Mask syntax for networks only"); 6438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return NULL; 6442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 6445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ncode(s, v, q) 6446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const char *s; 6447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 v; 6448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct qual q; 6449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 mask; 6451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int proto = q.proto; 6452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir = q.dir; 6453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int vlen; 6454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (s == NULL) 6456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project vlen = 32; 6457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (q.proto == Q_DECNET) 6458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project vlen = __pcap_atodn(s, &v); 6459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project vlen = __pcap_atoin(s, &v); 6461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (q.addr) { 6463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 6465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_HOST: 6466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_NET: 6467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_DECNET) 6468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_host(v, 0, proto, dir, q.addr); 6469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (proto == Q_LINK) { 6470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("illegal link layer address"); 6471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 6472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project mask = 0xffffffff; 6473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (s == NULL && q.addr == Q_NET) { 6474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Promote short net number */ 6475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (v && (v & 0xff000000) == 0) { 6476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v <<= 8; 6477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project mask <<= 8; 6478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 6480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Promote short ipaddr */ 6481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v <<= 32 - vlen; 6482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project mask <<= 32 - vlen; 6483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_host(v, mask, proto, dir, q.addr); 6485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PORT: 6488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_UDP) 6489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = IPPROTO_UDP; 6490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (proto == Q_TCP) 6491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = IPPROTO_TCP; 6492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (proto == Q_SCTP) 6493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = IPPROTO_SCTP; 6494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (proto == Q_DEFAULT) 6495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = PROTO_UNDEF; 6496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("illegal qualifier of 'port'"); 6498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6499511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (v > 65535) 6500511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("illegal port number %u > 65535", v); 6501511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 6502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project { 6503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 6504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = gen_port((int)v, proto, dir); 6505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(gen_port6((int)v, proto, dir), b); 6506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PORTRANGE: 6510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_UDP) 6511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = IPPROTO_UDP; 6512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (proto == Q_TCP) 6513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = IPPROTO_TCP; 6514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (proto == Q_SCTP) 6515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = IPPROTO_SCTP; 6516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (proto == Q_DEFAULT) 6517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = PROTO_UNDEF; 6518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("illegal qualifier of 'portrange'"); 6520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6521511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (v > 65535) 6522511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("illegal port number %u > 65535", v); 6523511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 6524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project { 6525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 6526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = gen_portrange((int)v, (int)v, proto, dir); 6527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(gen_portrange6((int)v, (int)v, proto, dir), b); 6528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_GATEWAY: 6532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'gateway' requires a name"); 6533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PROTO: 6536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_proto((int)v, proto, dir); 6537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PROTOCHAIN: 6539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_protochain((int)v, proto, dir); 6540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_UNDEF: 6542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project syntax(); 6543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 6546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 6547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6 6553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 6554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_mcode6(s1, s2, masklen, q) 6555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const char *s1, *s2; 6556d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes register unsigned int masklen; 6557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct qual q; 6558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct addrinfo *res; 6560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct in6_addr *addr; 6561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct in6_addr mask; 6562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 6563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int32_t *a, *m; 6564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (s2) 6566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("no mask %s supported", s2); 6567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project res = pcap_nametoaddrinfo(s1); 6569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!res) 6570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("invalid ip6 address %s", s1); 6571511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ai = res; 6572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (res->ai_next) 6573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("%s resolved to multiple address", s1); 6574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project addr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; 6575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (sizeof(mask) * 8 < masklen) 6577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("mask length must be <= %u", (unsigned int)(sizeof(mask) * 8)); 6578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(&mask, 0, sizeof(mask)); 6579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(&mask, 0xff, masklen / 8); 6580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (masklen % 8) { 6581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project mask.s6_addr[masklen / 8] = 6582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (0xff << (8 - masklen % 8)) & 0xff; 6583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project a = (u_int32_t *)addr; 6586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project m = (u_int32_t *)&mask; 6587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ((a[0] & ~m[0]) || (a[1] & ~m[1]) 6588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project || (a[2] & ~m[2]) || (a[3] & ~m[3])) { 6589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("non-network bits set in \"%s/%d\"", s1, masklen); 6590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (q.addr) { 6593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 6595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_HOST: 6596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (masklen != 128) 6597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("Mask syntax for networks only"); 6598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* FALLTHROUGH */ 6599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_NET: 6601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = gen_host6(addr, &mask, q.proto, q.dir, q.addr); 6602511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ai = NULL; 6603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project freeaddrinfo(res); 6604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 6607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("invalid qualifier against IPv6 address"); 6608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return NULL; 6611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /*INET6*/ 6613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 6615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ecode(eaddr, q) 6616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const u_char *eaddr; 6617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct qual q; 6618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b, *tmp; 6620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) { 6622511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (linktype) { 6623511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_EN10MB: 6624511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER: 6625511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER_TRANSPARENT: 6626d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes tmp = gen_prevlinkhdr_check(); 6627d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b = gen_ehostop(eaddr, (int)q.dir); 6628d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (tmp != NULL) 6629d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(tmp, b); 6630d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b; 6631511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_FDDI: 6632511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_fhostop(eaddr, (int)q.dir); 6633511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802: 6634511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_thostop(eaddr, (int)q.dir); 6635511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11: 6636511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 6637511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO_AVS: 6638511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO: 6639511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PPI: 6640511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_wlanhostop(eaddr, (int)q.dir); 6641511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IP_OVER_FC: 6642511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_ipfchostop(eaddr, (int)q.dir); 6643511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 6644511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("ethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel"); 6645511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 6646511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 6647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("ethernet address used in non-ether expression"); 6649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return NULL; 6651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid 6654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectsappend(s0, s1) 6655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s0, *s1; 6656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is definitely not the best way to do this, but the 6659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * lists will rarely get long. 6660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (s0->next) 6662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s0 = s0->next; 6663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s0->next = s1; 6664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist * 6667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectxfer_to_x(a) 6668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct arth *a; 6669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s; 6671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = new_stmt(BPF_LDX|BPF_MEM); 6673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->s.k = a->regno; 6674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return s; 6675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist * 6678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectxfer_to_a(a) 6679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct arth *a; 6680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s; 6682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = new_stmt(BPF_LD|BPF_MEM); 6684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->s.k = a->regno; 6685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return s; 6686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 6689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Modify "index" to use the value stored into its register as an 6690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * offset relative to the beginning of the header for the protocol 6691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto", and allocate a register and put an item "size" bytes long 6692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (1, 2, or 4) at that offset into that register, making it the register 6693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * for "index". 6694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct arth * 6696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_load(proto, inst, size) 6697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int proto; 6698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct arth *inst; 6699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int size; 6700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s, *tmp; 6702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 6703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int regno = alloc_reg(); 6704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free_reg(inst->regno); 6706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (size) { 6707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 6709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("data size must be 1, 2, or 4"); 6710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case 1: 6712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project size = BPF_B; 6713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 6714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case 2: 6716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project size = BPF_H; 6717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 6718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case 4: 6720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project size = BPF_W; 6721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 6722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 6724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 6725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("unsupported index operation"); 6726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RADIO: 6728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The offset is relative to the beginning of the packet 6730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * data, if we have a radio header. (If we don't, this 6731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is an error.) 6732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (linktype != DLT_IEEE802_11_RADIO_AVS && 6734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project linktype != DLT_IEEE802_11_RADIO && 6735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project linktype != DLT_PRISM_HEADER) 6736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("radio information not present in capture"); 6737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load into the X register the offset computed into the 6740511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * register specified by "index". 6741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = xfer_to_x(inst); 6743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the item at that offset. 6746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = new_stmt(BPF_LD|BPF_IND|size); 6748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, tmp); 6749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(inst->s, s); 6750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 6751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LINK: 6753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The offset is relative to the beginning of 6755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the link-layer header. 6756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 6757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - what about ATM LANE? Should the index be 6758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * relative to the beginning of the AAL5 frame, so 6759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that 0 refers to the beginning of the LE Control 6760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * field, or relative to the beginning of the LAN 6761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frame, so that 0 refers, for Ethernet LANE, to 6762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the beginning of the destination address? 6763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6764d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_abs_offset_varpart(&off_linkhdr); 6765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If "s" is non-null, it has code to arrange that the 6768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * X register contains the length of the prefix preceding 6769478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the link-layer header. Add to it the offset computed 6770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * into the register specified by "index", and move that 6771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * into the X register. Otherwise, just load into the X 6772511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * register the offset computed into the register specified 6773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * by "index". 6774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (s != NULL) { 6776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, xfer_to_a(inst)); 6777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); 6778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, new_stmt(BPF_MISC|BPF_TAX)); 6779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 6780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = xfer_to_x(inst); 6781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the item at the sum of the offset we've put in the 6784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * X register and the offset of the start of the link 6785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * layer header (which is 0 if the radio header is 6786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * variable-length; that header length is what we put 6787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * into the X register and then added to the index). 6788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = new_stmt(BPF_LD|BPF_IND|size); 6790d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes tmp->s.k = off_linkhdr.constant_part; 6791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, tmp); 6792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(inst->s, s); 6793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 6794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 6796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ARP: 6797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RARP: 6798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ATALK: 6799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DECNET: 6800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCA: 6801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LAT: 6802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPRC: 6803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPDL: 6804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 6805478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The offset is relative to the beginning of 6807478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the network-layer header. 6808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - are there any cases where we want 6809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * off_nl_nosnap? 6810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6811d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_abs_offset_varpart(&off_linkpl); 6812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If "s" is non-null, it has code to arrange that the 6815d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * X register contains the variable part of the offset 6816d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * of the link-layer payload. Add to it the offset 6817d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * computed into the register specified by "index", 6818d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * and move that into the X register. Otherwise, just 6819d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * load into the X register the offset computed into 6820d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the register specified by "index". 6821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6822478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (s != NULL) { 6823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, xfer_to_a(inst)); 6824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); 6825478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, new_stmt(BPF_MISC|BPF_TAX)); 6826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 6827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = xfer_to_x(inst); 6828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the item at the sum of the offset we've put in the 6831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * X register, the offset of the start of the network 6832d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * layer header from the beginning of the link-layer 6833d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * payload, and the constant part of the offset of the 6834d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * start of the link-layer payload. 6835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = new_stmt(BPF_LD|BPF_IND|size); 6837d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes tmp->s.k = off_linkpl.constant_part + off_nl; 6838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, tmp); 6839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(inst->s, s); 6840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Do the computation only if the packet contains 6843478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the protocol in question. 6844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = gen_proto_abbrev(proto); 6846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (inst->b) 6847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(inst->b, b); 6848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project inst->b = b; 6849478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 6850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCTP: 6852478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_TCP: 6853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_UDP: 6854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMP: 6855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGMP: 6856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGRP: 6857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PIM: 6858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_VRRP: 6859511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_CARP: 6860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The offset is relative to the beginning of 6862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the transport-layer header. 6863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 6864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the X register with the length of the IPv4 header 6865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (plus the offset of the link-layer header, if it's 6866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a variable-length header), in bytes. 6867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 6868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - are there any cases where we want 6869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * off_nl_nosnap? 6870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - we should, if we're built with 6871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * IPv6 support, generate code to load either 6872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * IPv4, IPv6, or both, as appropriate. 6873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = gen_loadx_iphdrlen(); 6875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6877d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * The X register now contains the sum of the variable 6878d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * part of the offset of the link-layer payload and the 6879511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * length of the network-layer header. 6880511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 6881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load into the A register the offset relative to 6882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the beginning of the transport layer header, 6883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * add the X register to that, move that to the 6884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * X register, and load with an offset from the 6885d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * X register equal to the sum of the constant part of 6886d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the offset of the link-layer payload and the offset, 6887d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * relative to the beginning of the link-layer payload, 6888d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * of the network-layer header. 6889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, xfer_to_a(inst)); 6891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); 6892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, new_stmt(BPF_MISC|BPF_TAX)); 6893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size)); 6894d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes tmp->s.k = off_linkpl.constant_part + off_nl; 6895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(inst->s, s); 6896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Do the computation only if the packet contains 6899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the protocol in question - which is true only 6900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * if this is an IP datagram and is the first or 6901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * only fragment of that datagram. 6902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(gen_proto_abbrev(proto), b = gen_ipfrag()); 6904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (inst->b) 6905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(inst->b, b); 6906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(gen_proto_abbrev(Q_IP), b); 6907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project inst->b = b; 6908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 6909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMPV6: 6910478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("IPv6 upper-layer protocol is not supported by proto[x]"); 6911478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 6912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project inst->regno = regno; 6914478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = new_stmt(BPF_ST); 6915478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->s.k = regno; 6916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(inst->s, s); 6917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return inst; 6919478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6920478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6921478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 6922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_relation(code, a0, a1, reversed) 6923478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int code; 6924478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct arth *a0, *a1; 6925478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int reversed; 6926478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s0, *s1, *s2; 6928478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b, *tmp; 6929478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s0 = xfer_to_x(a1); 6931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s1 = xfer_to_a(a0); 6932478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (code == BPF_JEQ) { 6933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X); 6934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = new_block(JMP(code)); 6935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 6936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = new_block(BPF_JMP|code|BPF_X); 6939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (reversed) 6940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b); 6941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s0, s1); 6943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(a1->s, s0); 6944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(a0->s, a1->s); 6945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->stmts = a0->s; 6947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free_reg(a0->regno); 6949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free_reg(a1->regno); 6950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 'and' together protocol checks */ 6952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (a0->b) { 6953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (a1->b) { 6954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(a0->b, tmp = a1->b); 6955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = a0->b; 6958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 6959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = a1->b; 6960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (tmp) 6962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b); 6963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct arth * 6968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_loadlen() 6969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int regno = alloc_reg(); 6971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct arth *a = (struct arth *)newchunk(sizeof(*a)); 6972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s; 6973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = new_stmt(BPF_LD|BPF_LEN); 6975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->next = new_stmt(BPF_ST); 6976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->next->s.k = regno; 6977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project a->s = s; 6978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project a->regno = regno; 6979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return a; 6981478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct arth * 6984478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_loadi(val) 6985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int val; 6986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct arth *a; 6988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s; 6989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int reg; 6990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project a = (struct arth *)newchunk(sizeof(*a)); 6992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project reg = alloc_reg(); 6994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = new_stmt(BPF_LD|BPF_IMM); 6996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->s.k = val; 6997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->next = new_stmt(BPF_ST); 6998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->next->s.k = reg; 6999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project a->s = s; 7000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project a->regno = reg; 7001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return a; 7003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct arth * 7006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_neg(a) 7007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct arth *a; 7008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s; 7010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = xfer_to_a(a); 7012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(a->s, s); 7013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = new_stmt(BPF_ALU|BPF_NEG); 7014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->s.k = 0; 7015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(a->s, s); 7016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = new_stmt(BPF_ST); 7017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->s.k = a->regno; 7018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(a->s, s); 7019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return a; 7021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct arth * 7024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_arth(code, a0, a1) 7025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int code; 7026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct arth *a0, *a1; 7027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s0, *s1, *s2; 7029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s0 = xfer_to_x(a1); 7031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s1 = xfer_to_a(a0); 7032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2 = new_stmt(BPF_ALU|BPF_X|code); 7033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 7035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s0, s1); 7036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(a1->s, s0); 7037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(a0->s, a1->s); 7038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free_reg(a0->regno); 7040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free_reg(a1->regno); 7041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7042478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s0 = new_stmt(BPF_ST); 7043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project a0->regno = s0->s.k = alloc_reg(); 7044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(a0->s, s0); 7045478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return a0; 7047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 7050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Here we handle simple allocation of the scratch registers. 7051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If too many registers are alloc'd, the allocator punts. 7052478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int regused[BPF_MEMWORDS]; 7054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int curreg; 7055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 7057511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Initialize the table of used registers and the current register. 7058511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7059511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void 7060511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallinit_regs() 7061511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 7062511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall curreg = 0; 7063511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall memset(regused, 0, sizeof regused); 7064511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 7065511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7066511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 7067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Return the next free register. 7068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 7070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectalloc_reg() 7071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int n = BPF_MEMWORDS; 7073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7074478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (--n >= 0) { 7075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (regused[curreg]) 7076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project curreg = (curreg + 1) % BPF_MEMWORDS; 7077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else { 7078478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project regused[curreg] = 1; 7079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return curreg; 7080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7082478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("too many registers needed to evaluate expression"); 7083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 7085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 7088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Return a register to the table so it can 7089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * be used later. 7090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void 7092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectfree_reg(n) 7093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int n; 7094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project regused[n] = 0; 7096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 7099478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_len(jmp, n) 7100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int jmp, n; 7101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s; 7103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 7104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = new_stmt(BPF_LD|BPF_LEN); 7106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = new_block(JMP(jmp)); 7107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->stmts = s; 7108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->s.k = n; 7109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 7111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_greater(n) 7115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int n; 7116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_len(BPF_JGE, n); 7118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 7121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Actually, this is less than or equal. 7122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_less(n) 7125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int n; 7126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 7128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = gen_len(BPF_JGT, n); 7130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b); 7131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 7133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 7136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is for "byte {idx} {op} {val}"; "idx" is treated as relative to 7137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the beginning of the link-layer header. 7138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - that means you can't test values in the radiotap header, but 7139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as that header is difficult if not impossible to parse generally 7140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * without a loop, that might not be a severe problem. A new keyword 7141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "radio" could be added for that, although what you'd really want 7142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * would be a way of testing particular radio header values, which 7143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * would generate code appropriate to the radio header in question. 7144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_byteop(op, idx, val) 7147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int op, idx, val; 7148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 7150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s; 7151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (op) { 7153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 7154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 7155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case '=': 7157d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_cmp(OR_LINKHDR, (u_int)idx, BPF_B, (bpf_int32)val); 7158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case '<': 7160d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b = gen_cmp_lt(OR_LINKHDR, (u_int)idx, BPF_B, (bpf_int32)val); 7161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 7162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case '>': 7164d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b = gen_cmp_gt(OR_LINKHDR, (u_int)idx, BPF_B, (bpf_int32)val); 7165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 7166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case '|': 7168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = new_stmt(BPF_ALU|BPF_OR|BPF_K); 7169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 7170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case '&': 7172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s = new_stmt(BPF_ALU|BPF_AND|BPF_K); 7173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 7174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->s.k = val; 7176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = new_block(JMP(BPF_JEQ)); 7177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->stmts = s; 7178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b); 7179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 7181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_char abroadcast[] = { 0x0 }; 7184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_broadcast(proto) 7187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int proto; 7188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 hostmask; 7190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *b2; 7191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project static u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 7192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 7194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 7196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LINK: 7197511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (linktype) { 7198511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_ARCNET: 7199511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_ARCNET_LINUX: 7200511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_ahostop(abroadcast, Q_DST); 7201511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_EN10MB: 7202511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER: 7203511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER_TRANSPARENT: 7204d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_prevlinkhdr_check(); 7205d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_ehostop(ebroadcast, Q_DST); 7206d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (b1 != NULL) 7207d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b1, b0); 7208d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b0; 7209511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_FDDI: 7210511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_fhostop(ebroadcast, Q_DST); 7211511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802: 7212511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_thostop(ebroadcast, Q_DST); 7213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11: 7214511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 7215511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO_AVS: 7216511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO: 7217511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PPI: 7218511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_wlanhostop(ebroadcast, Q_DST); 7219511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IP_OVER_FC: 7220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_ipfchostop(ebroadcast, Q_DST); 7221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 7222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("not a broadcast link"); 7223511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 7224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 7225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 7227511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7228511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * We treat a netmask of PCAP_NETMASK_UNKNOWN (0xffffffff) 7229511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * as an indication that we don't know the netmask, and fail 7230511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * in that case. 7231511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7232511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (netmask == PCAP_NETMASK_UNKNOWN) 7233511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("netmask not known, so 'ip broadcast' not supported"); 7234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype(ETHERTYPE_IP); 7235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project hostmask = ~netmask; 7236d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_mcmp(OR_LINKPL, 16, BPF_W, (bpf_int32)0, hostmask); 7237d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b2 = gen_mcmp(OR_LINKPL, 16, BPF_W, 7238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)(~0 & hostmask), hostmask); 7239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, b2); 7240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b2); 7241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b2; 7242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("only link-layer/IP broadcast filters supported"); 7244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return NULL; 7246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 7249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to test the low-order bit of a MAC address (that's 7250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the bottom bit of the *first* byte). 7251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 7253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_mac_multicast(offset) 7254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int offset; 7255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block *b0; 7257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct slist *s; 7258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* link[offset] & 1 != 0 */ 7260d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, offset, BPF_B); 7261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = new_block(JMP(BPF_JSET)); 7262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0->s.k = 1; 7263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0->stmts = s; 7264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 7265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_multicast(proto) 7269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int proto; 7270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block *b0, *b1, *b2; 7272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct slist *s; 7273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 7275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 7277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LINK: 7278511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (linktype) { 7279511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_ARCNET: 7280511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_ARCNET_LINUX: 7281511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* all ARCnet multicasts use the same address */ 7282511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_ahostop(abroadcast, Q_DST); 7283511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_EN10MB: 7284511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER: 7285511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER_TRANSPARENT: 7286d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_prevlinkhdr_check(); 7287511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* ether[0] & 1 != 0 */ 7288d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_mac_multicast(0); 7289d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (b1 != NULL) 7290d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b1, b0); 7291d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b0; 7292511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_FDDI: 7293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 7294511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX 7295511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 7296511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * XXX - was that referring to bit-order issues? 7297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7298511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* fddi[1] & 1 != 0 */ 7299511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_mac_multicast(1); 7300511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802: 7301511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* tr[2] & 1 != 0 */ 7302511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return gen_mac_multicast(2); 7303511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11: 7304511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 7305511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO_AVS: 7306511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO: 7307511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PPI: 7308511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7309511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Oh, yuk. 7310511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 7311511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For control frames, there is no DA. 7312511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 7313511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For management frames, DA is at an 7314511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * offset of 4 from the beginning of 7315511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the packet. 7316511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 7317511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For data frames, DA is at an offset 7318511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * of 4 from the beginning of the packet 7319511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * if To DS is clear and at an offset of 7320511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 16 from the beginning of the packet 7321511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * if To DS is set. 7322511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7323511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7324511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7325511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Generate the tests to be done for data frames. 7326511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 7327511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * First, check for To DS set, i.e. "link[1] & 0x01". 7328511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7329d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 1, BPF_B); 7330511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1 = new_block(JMP(BPF_JSET)); 7331511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->s.k = 0x01; /* To DS */ 7332511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->stmts = s; 7333511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7334511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7335511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If To DS is set, the DA is at 16. 7336511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7337511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = gen_mac_multicast(16); 7338511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b1, b0); 7339511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7340511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7341511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now, check for To DS not set, i.e. check 7342511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * "!(link[1] & 0x01)". 7343511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7344d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 1, BPF_B); 7345511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b2 = new_block(JMP(BPF_JSET)); 7346511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b2->s.k = 0x01; /* To DS */ 7347511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b2->stmts = s; 7348511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b2); 7349511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7350511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7351511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If To DS is not set, the DA is at 4. 7352511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7353511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1 = gen_mac_multicast(4); 7354511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b2, b1); 7355511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7356511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7357511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now OR together the last two checks. That gives 7358511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the complete set of checks for data frames. 7359511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7360511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_or(b1, b0); 7361511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7362511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7363511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now check for a data frame. 7364511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * I.e, check "link[0] & 0x08". 7365511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7366d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 0, BPF_B); 7367511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1 = new_block(JMP(BPF_JSET)); 7368511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->s.k = 0x08; 7369511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->stmts = s; 7370511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7371511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7372511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * AND that with the checks done for data frames. 7373511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7374511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b1, b0); 7375511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7376511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7377511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If the high-order bit of the type value is 0, this 7378511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * is a management frame. 7379511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * I.e, check "!(link[0] & 0x08)". 7380511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7381d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 0, BPF_B); 7382511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b2 = new_block(JMP(BPF_JSET)); 7383511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b2->s.k = 0x08; 7384511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b2->stmts = s; 7385511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b2); 7386511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7387511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7388511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For management frames, the DA is at 4. 7389511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7390511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1 = gen_mac_multicast(4); 7391511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b2, b1); 7392511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7393511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7394511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * OR that with the checks done for data frames. 7395511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * That gives the checks done for management and 7396511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * data frames. 7397511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7398511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_or(b1, b0); 7399511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7400511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7401511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If the low-order bit of the type value is 1, 7402511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * this is either a control frame or a frame 7403511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * with a reserved type, and thus not a 7404511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * frame with an SA. 7405511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 7406511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * I.e., check "!(link[0] & 0x04)". 7407511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7408d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_load_a(OR_LINKHDR, 0, BPF_B); 7409511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1 = new_block(JMP(BPF_JSET)); 7410511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->s.k = 0x04; 7411511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->stmts = s; 7412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b1); 7413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7414511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7415511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * AND that with the checks for data and management 7416511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * frames. 7417511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b1, b0); 7419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 7420511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IP_OVER_FC: 7421511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = gen_mac_multicast(2); 7422511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return b0; 7423511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 7424511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7425511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 7426511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Link not known to support multicasts */ 7427511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 7430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype(ETHERTYPE_IP); 7431d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_cmp_ge(OR_LINKPL, 16, BPF_B, (bpf_int32)224); 7432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 7433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 7434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 7436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype(ETHERTYPE_IPV6); 7437d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_cmp(OR_LINKPL, 24, BPF_B, (bpf_int32)255); 7438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 7439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 7440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel"); 7442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return NULL; 7444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 7447511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Filter on inbound (dir == 0) or outbound (dir == 1) traffic. 7448511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Outbound traffic is sent by this machine, while inbound traffic is 7449511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * sent by a remote machine (and may include packets destined for a 7450511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * unicast or multicast link-layer address we are not subscribing to). 7451511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * These are the same definitions implemented by pcap_setdirection(). 7452511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Capturing only unicast traffic destined for this host is probably 7453511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * better accomplished using a higher-layer filter. 7454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_inbound(dir) 7457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir; 7458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block *b0; 7460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 7462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Only some data link types support inbound/outbound qualifiers. 7463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (linktype) { 7465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_SLIP: 7466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_relation(BPF_JEQ, 7467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_load(Q_LINK, gen_loadi(0), 1), 7468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_loadi(0), 7469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project dir); 7470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 7471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7472511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IPNET: 7473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (dir) { 7474511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* match outgoing packets */ 7475d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKHDR, 2, BPF_H, IPNET_OUTBOUND); 7476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 7477511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* match incoming packets */ 7478d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKHDR, 2, BPF_H, IPNET_INBOUND); 7479511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 7480511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7481511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7482511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_LINUX_SLL: 7483511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* match outgoing packets */ 7484d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKHDR, 0, BPF_H, LINUX_SLL_OUTGOING); 7485511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (!dir) { 7486511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* to filter on inbound traffic, invert the match */ 7487511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b0); 7488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 7490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_NET_PFVAR_H 7492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PFLOG: 7493d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKHDR, offsetof(struct pfloghdr, dir), BPF_B, 7494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)((dir == 0) ? PF_IN : PF_OUT)); 7495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 7496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 7497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP_PPPD: 7499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (dir) { 7500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* match outgoing packets */ 7501d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKHDR, 0, BPF_B, PPP_PPPD_OUT); 7502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 7503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* match incoming packets */ 7504d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKHDR, 0, BPF_B, PPP_PPPD_IN); 7505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 7507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MFR: 7509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MLFR: 7510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MLPPP: 7511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ATM1: 7512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ATM2: 7513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_PPPOE: 7514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_PPPOE_ATM: 7515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_GGSN: 7516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ES: 7517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MONITOR: 7518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_SERVICES: 7519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ETHER: 7520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_PPP: 7521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_FRELAY: 7522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_CHDLC: 7523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_VP: 7524511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_ST: 7525511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_ISM: 7526511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_VS: 7527511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_SRX_E2E: 7528511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_FIBRECHANNEL: 7529511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_ATM_CEMIC: 7530511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* juniper flags (including direction) are stored 7532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the byte after the 3-byte magic number */ 7533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (dir) { 7534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* match outgoing packets */ 7535d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_mcmp(OR_LINKHDR, 3, BPF_B, 0, 0x01); 7536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 7537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* match incoming packets */ 7538d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_mcmp(OR_LINKHDR, 3, BPF_B, 1, 0x01); 7539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7540511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 7543511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7544511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If we have packet meta-data indicating a direction, 7545511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * check it, otherwise give up as this link-layer type 7546511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * has nothing in the packet data. 7547511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7548511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#if defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) 7549511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7550511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * This is Linux with PF_PACKET support. 7551511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If this is a *live* capture, we can look at 7552511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * special meta-data in the filter expression; 7553511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * if it's a savefile, we can't. 7554511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7555511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (bpf_pcap->rfile != NULL) { 7556511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* We have a FILE *, so this is a savefile */ 7557511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("inbound/outbound not supported on linktype %d when reading savefiles", 7558511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall linktype); 7559511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = NULL; 7560511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NOTREACHED */ 7561511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 7562511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* match outgoing packets */ 7563d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKHDR, SKF_AD_OFF + SKF_AD_PKTTYPE, BPF_H, 7564511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall PACKET_OUTGOING); 7565511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (!dir) { 7566511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* to filter on inbound traffic, invert the match */ 7567511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b0); 7568511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 7569511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else /* defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */ 7570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("inbound/outbound not supported on linktype %d", 7571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project linktype); 7572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = NULL; 7573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7574511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif /* defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */ 7575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b0); 7577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_NET_PFVAR_H 7580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* PF firewall log matched interface */ 7581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_ifname(const char *ifname) 7583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0; 7585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int len, off; 7586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7587511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (linktype != DLT_PFLOG) { 7588511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("ifname supported only on PF linktype"); 7589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7591511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall len = sizeof(((struct pfloghdr *)0)->ifname); 7592511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off = offsetof(struct pfloghdr, ifname); 7593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (strlen(ifname) >= len) { 7594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("ifname interface names can only be %d characters", 7595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project len-1); 7596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7598d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_bcmp(OR_LINKHDR, off, strlen(ifname), (const u_char *)ifname); 7599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b0); 7600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* PF firewall log ruleset name */ 7603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_ruleset(char *ruleset) 7605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0; 7607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (linktype != DLT_PFLOG) { 7609511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("ruleset supported only on PF linktype"); 7610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7612511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (strlen(ruleset) >= sizeof(((struct pfloghdr *)0)->ruleset)) { 7614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("ruleset names can only be %ld characters", 7615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (long)(sizeof(((struct pfloghdr *)0)->ruleset) - 1)); 7616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7618511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7619d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_bcmp(OR_LINKHDR, offsetof(struct pfloghdr, ruleset), 7620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strlen(ruleset), (const u_char *)ruleset); 7621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b0); 7622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* PF firewall log rule number */ 7625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_rnr(int rnr) 7627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0; 7629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7630511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (linktype != DLT_PFLOG) { 7631511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("rnr supported only on PF linktype"); 7632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7635d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKHDR, offsetof(struct pfloghdr, rulenr), BPF_W, 7636511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (bpf_int32)rnr); 7637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b0); 7638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* PF firewall log sub-rule number */ 7641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_srnr(int srnr) 7643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0; 7645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (linktype != DLT_PFLOG) { 7647511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("srnr supported only on PF linktype"); 7648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7651d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKHDR, offsetof(struct pfloghdr, subrulenr), BPF_W, 7652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)srnr); 7653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b0); 7654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* PF firewall log reason code */ 7657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_reason(int reason) 7659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0; 7661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7662511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (linktype != DLT_PFLOG) { 7663511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("reason supported only on PF linktype"); 7664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7667d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKHDR, offsetof(struct pfloghdr, reason), BPF_B, 7668511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (bpf_int32)reason); 7669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b0); 7670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* PF firewall log action */ 7673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_action(int action) 7675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0; 7677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7678511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (linktype != DLT_PFLOG) { 7679511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("action supported only on PF linktype"); 7680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7683d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_cmp(OR_LINKHDR, offsetof(struct pfloghdr, action), BPF_B, 7684511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (bpf_int32)action); 7685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b0); 7686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else /* !HAVE_NET_PFVAR_H */ 7688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_ifname(const char *ifname) 7690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("libpcap was compiled without pf support"); 7692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 7694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_ruleset(char *ruleset) 7698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("libpcap was compiled on a machine without pf support"); 7700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 7702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_rnr(int rnr) 7706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("libpcap was compiled on a machine without pf support"); 7708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 7710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_srnr(int srnr) 7714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("libpcap was compiled on a machine without pf support"); 7716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 7718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_reason(int reason) 7722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("libpcap was compiled on a machine without pf support"); 7724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 7726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_action(int action) 7730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("libpcap was compiled on a machine without pf support"); 7732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 7734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_NET_PFVAR_H */ 7736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7737511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* IEEE 802.11 wireless header */ 7738511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct block * 7739511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_p80211_type(int type, int mask) 7740511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 7741511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct block *b0; 7742511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7743511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (linktype) { 7744511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7745511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11: 7746511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 7747511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO_AVS: 7748511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO: 7749d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_mcmp(OR_LINKHDR, 0, BPF_B, (bpf_int32)type, 7750511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (bpf_int32)mask); 7751511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7752511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7753511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 7754511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("802.11 link-layer types supported only on 802.11"); 7755511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NOTREACHED */ 7756511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 7757511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7758511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (b0); 7759511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 7760511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7761511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct block * 7762511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_p80211_fcdir(int fcdir) 7763511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 7764511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct block *b0; 7765511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7766511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (linktype) { 7767511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7768511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11: 7769511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 7770511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO_AVS: 7771511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO: 7772511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7773511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7774511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 7775511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("frame direction supported only with 802.11 headers"); 7776511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NOTREACHED */ 7777511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 7778511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7779d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_mcmp(OR_LINKHDR, 1, BPF_B, (bpf_int32)fcdir, 7780511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (bpf_u_int32)IEEE80211_FC1_DIR_MASK); 7781511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7782511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (b0); 7783511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 7784511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_acode(eaddr, q) 7787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const u_char *eaddr; 7788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct qual q; 7789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7790511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (linktype) { 7791511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7792511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_ARCNET: 7793511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_ARCNET_LINUX: 7794511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && 7795511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall q.proto == Q_LINK) 7796511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (gen_ahostop(eaddr, (int)q.dir)); 7797511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall else { 7798511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("ARCnet address used in non-arc expression"); 7799511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NOTREACHED */ 7800511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 7801511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7802511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7803511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 7804511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("aid supported only on ARCnet"); 7805511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NOTREACHED */ 7806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7807478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("ARCnet address used in non-arc expression"); 7808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return NULL; 7810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 7813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ahostop(eaddr, dir) 7814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const u_char *eaddr; 7815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int dir; 7816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block *b0, *b1; 7818478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 7820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* src comes first, different from Ethernet */ 7821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 7822d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_bcmp(OR_LINKHDR, 0, 1, eaddr); 7823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 7825d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return gen_bcmp(OR_LINKHDR, 1, 1, eaddr); 7826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 7828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_ahostop(eaddr, Q_SRC); 7829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_ahostop(eaddr, Q_DST); 7830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 7831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 7832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 7834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 7835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_ahostop(eaddr, Q_SRC); 7836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_ahostop(eaddr, Q_DST); 7837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 7838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 7839511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7840511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR1: 7841511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr1' is only supported on 802.11"); 7842511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7843511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7844511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR2: 7845511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr2' is only supported on 802.11"); 7846511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7847511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7848511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR3: 7849511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr3' is only supported on 802.11"); 7850511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7851511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7852511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR4: 7853511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'addr4' is only supported on 802.11"); 7854511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7855511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7856511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_RA: 7857511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'ra' is only supported on 802.11"); 7858511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7859511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7860511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_TA: 7861511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'ta' is only supported on 802.11"); 7862511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 7865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7868d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT) 7869d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct block * 7870d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesgen_vlan_bpf_extensions(int vlan_num) 7871d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 7872d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 7873d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct slist *s; 7874d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7875d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* generate new filter code based on extracting packet 7876d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * metadata */ 7877d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = new_stmt(BPF_LD|BPF_B|BPF_ABS); 7878d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT; 7879d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7880d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = new_block(JMP(BPF_JEQ)); 7881d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0->stmts = s; 7882d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0->s.k = 1; 7883d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7884d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (vlan_num >= 0) { 7885d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = new_stmt(BPF_LD|BPF_B|BPF_ABS); 7886d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG; 7887d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7888d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = new_block(JMP(BPF_JEQ)); 7889d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1->stmts = s; 7890d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1->s.k = (bpf_int32) vlan_num; 7891d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7892d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0,b1); 7893d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = b1; 7894d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 7895d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7896d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b0; 7897d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 7898d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#endif 7899d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7900d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct block * 7901d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesgen_vlan_no_bpf_extensions(int vlan_num) 7902d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 7903d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 7904d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7905d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* check for VLAN, including QinQ */ 7906d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_linktype(ETHERTYPE_8021Q); 7907d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_linktype(ETHERTYPE_8021QINQ); 7908d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_or(b0,b1); 7909d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = b1; 7910d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7911d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* If a specific VLAN is requested, check VLAN id */ 7912d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (vlan_num >= 0) { 7913d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_mcmp(OR_LINKPL, 0, BPF_H, 7914d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes (bpf_int32)vlan_num, 0x0fff); 7915d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 7916d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = b1; 7917d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 7918d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7919d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 7920d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * The payload follows the full header, including the 7921d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * VLAN tags, so skip past this VLAN tag. 7922d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 7923d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part += 4; 7924d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7925d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 7926d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * The link-layer type information follows the VLAN tags, so 7927d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * skip past this VLAN tag. 7928d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 7929d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part += 4; 7930d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7931d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b0; 7932d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 7933d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 7935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * support IEEE 802.1Q VLAN trunk over ethernet 7936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_vlan(vlan_num) 7939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int vlan_num; 7940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7941d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0; 7942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* can't check for VLAN-encapsulated packets inside MPLS */ 7944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (label_stack_depth > 0) 7945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("no VLAN match after MPLS"); 7946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 7948511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Check for a VLAN packet, and then change the offsets to point 7949511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * to the type and data fields within the VLAN packet. Just 7950511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * increment the offsets, so that we can support a hierarchy, e.g. 7951511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * "vlan 300 && vlan 200" to capture VLAN 200 encapsulated within 7952511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * VLAN 100. 7953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 7954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - this is a bit of a kludge. If we were to split the 7955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * compiler into a parser that parses an expression and 7956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * generates an expression tree, and a code generator that 7957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * takes an expression tree (which could come from our 7958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * parser or from some other parser) and generates BPF code, 7959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we could perhaps make the offsets parameters of routines 7960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and, in the handler for an "AND" node, pass to subnodes 7961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * other than the VLAN node the adjusted offsets. 7962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 7963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This would mean that "vlan" would, instead of changing the 7964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * behavior of *all* tests after it, change only the behavior 7965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of tests ANDed with it. That would change the documented 7966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * semantics of "vlan", which might break some expressions. 7967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * However, it would mean that "(vlan and ip) or ip" would check 7968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * both for VLAN-encapsulated IP and IP-over-Ethernet, rather than 7969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * checking only for VLAN-encapsulated IP, so that could still 7970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * be considered worth doing; it wouldn't break expressions 7971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that are of the form "vlan and ..." or "vlan N and ...", 7972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * which I suspect are the most common expressions involving 7973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "vlan". "vlan or ..." doesn't necessarily do what the user 7974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * would really want, now, as all the "or ..." tests would 7975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * be done assuming a VLAN, even though the "or" could be viewed 7976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as meaning "or, if this isn't a VLAN packet...". 7977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (linktype) { 7979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_EN10MB: 7981511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER: 7982511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER_TRANSPARENT: 7983d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT) 7984d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Verify that this is the outer part of the packet and 7985d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * not encapsulated somehow. */ 7986d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (vlan_stack_depth == 0 && !off_linkhdr.is_variable && 7987d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkhdr.constant_part == 7988d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_outermostlinkhdr.constant_part) { 7989d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 7990d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Do we need special VLAN handling? 7991d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 7992d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (bpf_pcap->bpf_codegen_flags & BPF_SPECIAL_VLAN_HANDLING) 7993d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_vlan_bpf_extensions(vlan_num); 7994d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes else 7995d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_vlan_no_bpf_extensions(vlan_num); 7996d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } else 7997511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 7998d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_vlan_no_bpf_extensions(vlan_num); 7999d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 8000d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8001d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_IEEE802_11: 8002d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_PRISM_HEADER: 8003d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_IEEE802_11_RADIO_AVS: 8004d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_IEEE802_11_RADIO: 8005d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_vlan_no_bpf_extensions(vlan_num); 8006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 8009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("no VLAN support for data link type %d", 8010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project linktype); 8011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 8012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8014d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes vlan_stack_depth++; 8015d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b0); 8017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 8020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * support for MPLS 8021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 8022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 8023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_mpls(label_num) 8024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int label_num; 8025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8026d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 8027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (label_stack_depth > 0) { 8029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* just match the bottom-of-stack bit clear */ 8030d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_mcmp(OR_PREVMPLSHDR, 2, BPF_B, 0, 0x01); 8031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 8032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 8033d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * We're not in an MPLS stack yet, so check the link-layer 8034d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * type against MPLS. 8035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 8036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (linktype) { 8037d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_C_HDLC: /* fall through */ 8039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_EN10MB: 8040511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER: 8041511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER_TRANSPARENT: 8042478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype(ETHERTYPE_MPLS); 8043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8044d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8045478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP: 8046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype(PPP_MPLS_UCAST); 8047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8048d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* FIXME add other DLT_s ... 8050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * for Frame-Relay/and ATM this may get messy due to SNAP headers 8051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * leave it for now */ 8052d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 8054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("no MPLS support for data link type %d", 8055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project linktype); 8056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = NULL; 8057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 8058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* If a specific MPLS label is requested, check it */ 8063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (label_num >= 0) { 8064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project label_num = label_num << 12; /* label is shifted 12 bits on the wire */ 8065d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_mcmp(OR_LINKPL, 0, BPF_W, (bpf_int32)label_num, 8066478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 0xfffff000); /* only compare the first 20 bits */ 8067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = b1; 8069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8071d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 8072d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Change the offsets to point to the type and data fields within 8073d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the MPLS packet. Just increment the offsets, so that we 8074d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * can support a hierarchy, e.g. "mpls 100000 && mpls 1024" to 8075d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * capture packets with an outer label of 100000 and an inner 8076d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * label of 1024. 8077d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 8078d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Increment the MPLS stack depth as well; this indicates that 8079d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * we're checking MPLS-encapsulated headers, to make sure higher 8080d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * level code generators don't try to match against IP-related 8081d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * protocols such as Q_ARP, Q_RARP etc. 8082d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 8083d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * XXX - this is a bit of a kludge. See comments in gen_vlan(). 8084d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 8085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl_nosnap += 4; 8086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project off_nl += 4; 8087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project label_stack_depth++; 8088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b0); 8089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 8092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Support PPPOE discovery and session. 8093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 8094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 8095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pppoed() 8096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* check for PPPoE discovery */ 8098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return gen_linktype((bpf_int32)ETHERTYPE_PPPOED); 8099478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 8102511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_pppoes(sess_num) 8103511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int sess_num; 8104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8105511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct block *b0, *b1; 8106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 8108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Test against the PPPoE session link-layer type. 8109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 8110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_linktype((bpf_int32)ETHERTYPE_PPPOES); 8111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8112d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* If a specific session is requested, check PPPoE session id */ 8113d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (sess_num >= 0) { 8114d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_mcmp(OR_LINKPL, 0, BPF_W, 8115d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes (bpf_int32)sess_num, 0x0000ffff); 8116d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 8117d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = b1; 8118d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 8119d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 8121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Change the offsets to point to the type and data fields within 8122511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the PPP packet, and note that this is PPPoE rather than 8123511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * raw PPP. 8124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 8125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - this is a bit of a kludge. If we were to split the 8126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * compiler into a parser that parses an expression and 8127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * generates an expression tree, and a code generator that 8128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * takes an expression tree (which could come from our 8129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * parser or from some other parser) and generates BPF code, 8130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we could perhaps make the offsets parameters of routines 8131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and, in the handler for an "AND" node, pass to subnodes 8132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * other than the PPPoE node the adjusted offsets. 8133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 8134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This would mean that "pppoes" would, instead of changing the 8135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * behavior of *all* tests after it, change only the behavior 8136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of tests ANDed with it. That would change the documented 8137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * semantics of "pppoes", which might break some expressions. 8138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * However, it would mean that "(pppoes and ip) or ip" would check 8139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * both for VLAN-encapsulated IP and IP-over-Ethernet, rather than 8140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * checking only for VLAN-encapsulated IP, so that could still 8141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * be considered worth doing; it wouldn't break expressions 8142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that are of the form "pppoes and ..." which I suspect are the 8143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * most common expressions involving "pppoes". "pppoes or ..." 8144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * doesn't necessarily do what the user would really want, now, 8145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as all the "or ..." tests would be done assuming PPPoE, even 8146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * though the "or" could be viewed as meaning "or, if this isn't 8147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a PPPoE packet...". 8148d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 8149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The "network-layer" protocol is PPPoE, which has a 6-byte 8150511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * PPPoE header, followed by a PPP packet. 8151511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 8152511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * There is no HDLC encapsulation for the PPP packet (it's 8153511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * encapsulated in PPPoES instead), so the link-layer type 8154511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * starts at the first byte of the PPP packet. For PPPoE, 8155511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * that offset is relative to the beginning of the total 8156511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * link-layer payload, including any 802.2 LLC header, so 8157511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * it's 6 bytes past off_nl. 8158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 8159d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes PUSH_LINKHDR(DLT_PPP, off_linkpl.is_variable, 8160d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part + off_nl + 6, /* 6 bytes past the PPPoE header */ 8161d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.reg); 8162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8163d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype = off_linkhdr; 8164d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = off_linkhdr.constant_part + 2; 8165d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8166d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_nl = 0; 8167d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_nl_nosnap = 0; /* no 802.2 LLC */ 8168d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8169d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b0; 8170d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 8171d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8172d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* Check that this is Geneve and the VNI is correct if 8173d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * specified. Parameterized to handle both IPv4 and IPv6. */ 8174d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct block * 8175d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesgen_geneve_check(struct block *(*gen_portfn)(int, int, int), 8176d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes enum e_offrel offrel, int vni) 8177d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 8178d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 8179d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8180d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_portfn(GENEVE_PORT, IPPROTO_UDP, Q_DST); 8181d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8182d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Check that we are operating on version 0. Otherwise, we 8183d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * can't decode the rest of the fields. The version is 2 bits 8184d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * in the first byte of the Geneve header. */ 8185d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_mcmp(offrel, 8, BPF_B, (bpf_int32)0, 0xc0); 8186d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 8187d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = b1; 8188d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8189d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (vni >= 0) { 8190d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes vni <<= 8; /* VNI is in the upper 3 bytes */ 8191d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_mcmp(offrel, 12, BPF_W, (bpf_int32)vni, 8192d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 0xffffff00); 8193d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 8194d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = b1; 8195d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 8196d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8197d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b0; 8198d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 8199d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8200d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* The IPv4 and IPv6 Geneve checks need to do two things: 8201d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * - Verify that this actually is Geneve with the right VNI. 8202d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * - Place the IP header length (plus variable link prefix if 8203d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * needed) into register A to be used later to compute 8204d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the inner packet offsets. */ 8205d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct block * 8206d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesgen_geneve4(int vni) 8207d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 8208d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 8209d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct slist *s, *s1; 8210d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8211d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_geneve_check(gen_port, OR_TRAN_IPV4, vni); 8212d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8213d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Load the IP header length into A. */ 8214d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_loadx_iphdrlen(); 8215d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8216d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_MISC|BPF_TXA); 8217d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8218d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8219d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Forcibly append these statements to the true condition 8220d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * of the protocol check by creating a new block that is 8221d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * always true and ANDing them. */ 8222d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = new_block(BPF_JMP|BPF_JEQ|BPF_X); 8223d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1->stmts = s; 8224d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1->s.k = 0; 8225d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8226d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 8227d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8228d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 8229d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 8230d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8231d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct block * 8232d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesgen_geneve6(int vni) 8233d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 8234d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 8235d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct slist *s, *s1; 8236d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8237d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_geneve_check(gen_port6, OR_TRAN_IPV6, vni); 8238d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8239d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Load the IP header length. We need to account for a 8240d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * variable length link prefix if there is one. */ 8241d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_abs_offset_varpart(&off_linkpl); 8242d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (s) { 8243d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_LD|BPF_IMM); 8244d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 40; 8245d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8246d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8247d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_ALU|BPF_ADD|BPF_X); 8248d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 0; 8249d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8250d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } else { 8251d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = new_stmt(BPF_LD|BPF_IMM); 8252d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s->s.k = 40;; 8253d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 8254d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8255d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Forcibly append these statements to the true condition 8256d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * of the protocol check by creating a new block that is 8257d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * always true and ANDing them. */ 8258d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_MISC|BPF_TAX); 8259d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8260d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8261d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = new_block(BPF_JMP|BPF_JEQ|BPF_X); 8262d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1->stmts = s; 8263d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1->s.k = 0; 8264d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8265d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 8266d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8267d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 8268d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 8269d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8270d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* We need to store three values based on the Geneve header:: 8271d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * - The offset of the linktype. 8272d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * - The offset of the end of the Geneve header. 8273d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * - The offset of the end of the encapsulated MAC header. */ 8274d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct slist * 8275d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesgen_geneve_offsets(void) 8276d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 8277d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct slist *s, *s1, *s_proto; 8278d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8279d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* First we need to calculate the offset of the Geneve header 8280d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * itself. This is composed of the IP header previously calculated 8281d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * (include any variable link prefix) and stored in A plus the 8282d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * fixed sized headers (fixed link prefix, MAC length, and UDP 8283d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * header). */ 8284d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 8285d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s->s.k = off_linkpl.constant_part + off_nl + 8; 8286d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8287d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Stash this in X since we'll need it later. */ 8288d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_MISC|BPF_TAX); 8289d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8290d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8291d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* The EtherType in Geneve is 2 bytes in. Calculate this and 8292d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * store it. */ 8293d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 8294d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 2; 8295d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8296d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8297d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.reg = alloc_reg(); 8298d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.is_variable = 1; 8299d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = 0; 8300d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8301d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_ST); 8302d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = off_linktype.reg; 8303d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8304d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8305d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Load the Geneve option length and mask and shift to get the 8306d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * number of bytes. It is stored in the first byte of the Geneve 8307d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * header. */ 8308d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_LD|BPF_IND|BPF_B); 8309d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 0; 8310d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8311d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8312d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_ALU|BPF_AND|BPF_K); 8313d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 0x3f; 8314d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8315d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8316d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_ALU|BPF_MUL|BPF_K); 8317d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 4; 8318d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8319d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8320d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Add in the rest of the Geneve base header. */ 8321d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 8322d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 8; 8323d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8324d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8325d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Add the Geneve header length to its offset and store. */ 8326d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_ALU|BPF_ADD|BPF_X); 8327d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 0; 8328d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8329d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8330d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Set the encapsulated type as Ethernet. Even though we may 8331d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * not actually have Ethernet inside there are two reasons this 8332d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * is useful: 8333d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * - The linktype field is always in EtherType format regardless 8334d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * of whether it is in Geneve or an inner Ethernet frame. 8335d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * - The only link layer that we have specific support for is 8336d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Ethernet. We will confirm that the packet actually is 8337d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Ethernet at runtime before executing these checks. */ 8338d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes PUSH_LINKHDR(DLT_EN10MB, 1, 0, alloc_reg()); 8339d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8340d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_ST); 8341d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = off_linkhdr.reg; 8342d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8343d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8344d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Calculate whether we have an Ethernet header or just raw IP/ 8345d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * MPLS/etc. If we have Ethernet, advance the end of the MAC offset 8346d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * and linktype by 14 bytes so that the network header can be found 8347d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * seamlessly. Otherwise, keep what we've calculated already. */ 8348d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8349d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* We have a bare jmp so we can't use the optimizer. */ 8350d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes no_optimize = 1; 8351d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8352d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Load the EtherType in the Geneve header, 2 bytes in. */ 8353d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_LD|BPF_IND|BPF_H); 8354d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 2; 8355d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8356d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8357d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Load X with the end of the Geneve header. */ 8358d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_LDX|BPF_MEM); 8359d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = off_linkhdr.reg; 8360d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8361d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8362d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Check if the EtherType is Transparent Ethernet Bridging. At the 8363d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * end of this check, we should have the total length in X. In 8364d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the non-Ethernet case, it's already there. */ 8365d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s_proto = new_stmt(JMP(BPF_JEQ)); 8366d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s_proto->s.k = ETHERTYPE_TEB; 8367d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s_proto); 8368d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8369d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_MISC|BPF_TXA); 8370d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8371d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s_proto->s.jt = s1; 8372d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8373d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Since this is Ethernet, use the EtherType of the payload 8374d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * directly as the linktype. Overwrite what we already have. */ 8375d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 8376d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 12; 8377d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8378d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8379d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_ST); 8380d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = off_linktype.reg; 8381d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8382d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8383d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Advance two bytes further to get the end of the Ethernet 8384d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * header. */ 8385d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 8386d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 2; 8387d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8388d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8389d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Move the result to X. */ 8390d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_MISC|BPF_TAX); 8391d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8392d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8393d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Store the final result of our linkpl calculation. */ 8394d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.reg = alloc_reg(); 8395d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.is_variable = 1; 8396d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = 0; 8397d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8398d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_STX); 8399d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = off_linkpl.reg; 8400d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8401d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s_proto->s.jf = s1; 8402d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8403d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_nl = 0; 8404d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8405d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return s; 8406d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 8407d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8408d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* Check to see if this is a Geneve packet. */ 8409d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstruct block * 8410d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesgen_geneve(int vni) 8411d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 8412d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 8413d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct slist *s; 8414d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8415d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_geneve4(vni); 8416d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_geneve6(vni); 8417d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8418d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_or(b0, b1); 8419d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = b1; 8420d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8421d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Later filters should act on the payload of the Geneve frame, 8422d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * update all of the header pointers. Attach this code so that 8423d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * it gets executed in the event that the Geneve filter matches. */ 8424d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = gen_geneve_offsets(); 8425d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8426d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1 = gen_true(); 8427d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, b1->stmts); 8428d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1->stmts = s; 8429d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8430d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 8431d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8432d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes is_geneve = 1; 8433d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8434d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 8435d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 8436d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8437d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* Check that the encapsulated frame has a link layer header 8438d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * for Ethernet filters. */ 8439d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct block * 8440d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesgen_geneve_ll_check() 8441d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 8442d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0; 8443d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct slist *s, *s1; 8444d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8445d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* The easiest way to see if there is a link layer present 8446d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * is to check if the link layer header and payload are not 8447d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the same. */ 8448d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8449d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Geneve always generates pure variable offsets so we can 8450d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * compare only the registers. */ 8451d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s = new_stmt(BPF_LD|BPF_MEM); 8452d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s->s.k = off_linkhdr.reg; 8453d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8454d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1 = new_stmt(BPF_LDX|BPF_MEM); 8455d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = off_linkpl.reg; 8456d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8457d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8458d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = new_block(BPF_JMP|BPF_JEQ|BPF_X); 8459d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0->stmts = s; 8460d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0->s.k = 0; 8461d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_not(b0); 8462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 8464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 8467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_atmfield_code(atmfield, jvalue, jtype, reverse) 8468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int atmfield; 8469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 jvalue; 8470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 jtype; 8471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int reverse; 8472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0; 8474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (atmfield) { 8476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_VPI: 8478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!is_atm) 8479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'vpi' supported only on raw ATM"); 8480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (off_vpi == (u_int)-1) 8481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8482d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_ncmp(OR_LINKHDR, off_vpi, BPF_B, 0xffffffff, jtype, 8483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project reverse, jvalue); 8484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_VCI: 8487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!is_atm) 8488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'vci' supported only on raw ATM"); 8489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (off_vci == (u_int)-1) 8490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8491d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_ncmp(OR_LINKHDR, off_vci, BPF_H, 0xffffffff, jtype, 8492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project reverse, jvalue); 8493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_PROTOTYPE: 8496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (off_proto == (u_int)-1) 8497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); /* XXX - this isn't on FreeBSD */ 8498d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_ncmp(OR_LINKHDR, off_proto, BPF_B, 0x0f, jtype, 8499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project reverse, jvalue); 8500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_MSGTYPE: 8503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (off_payload == (u_int)-1) 8504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8505d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_ncmp(OR_LINKHDR, off_payload + MSG_TYPE_POS, BPF_B, 8506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 0xffffffff, jtype, reverse, jvalue); 8507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_CALLREFTYPE: 8510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!is_atm) 8511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'callref' supported only on raw ATM"); 8512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (off_proto == (u_int)-1) 8513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8514d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = gen_ncmp(OR_LINKHDR, off_proto, BPF_B, 0xffffffff, 8515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project jtype, reverse, jvalue); 8516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 8519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 8522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 8525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_atmtype_abbrev(type) 8526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int type; 8527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 8529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (type) { 8531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_METAC: 8533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Get all packets in Meta signalling Circuit */ 8534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!is_atm) 8535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'metac' supported only on raw ATM"); 8536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0); 8537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_atmfield_code(A_VCI, 1, BPF_JEQ, 0); 8538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_BCC: 8542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Get all packets in Broadcast Circuit*/ 8543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!is_atm) 8544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'bcc' supported only on raw ATM"); 8545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0); 8546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_atmfield_code(A_VCI, 2, BPF_JEQ, 0); 8547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_OAMF4SC: 8551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Get all cells in Segment OAM F4 circuit*/ 8552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!is_atm) 8553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'oam4sc' supported only on raw ATM"); 8554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0); 8555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_atmfield_code(A_VCI, 3, BPF_JEQ, 0); 8556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_OAMF4EC: 8560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Get all cells in End-to-End OAM F4 Circuit*/ 8561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!is_atm) 8562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'oam4ec' supported only on raw ATM"); 8563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0); 8564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_atmfield_code(A_VCI, 4, BPF_JEQ, 0); 8565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_SC: 8569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Get all packets in connection Signalling Circuit */ 8570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!is_atm) 8571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'sc' supported only on raw ATM"); 8572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0); 8573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_atmfield_code(A_VCI, 5, BPF_JEQ, 0); 8574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_ILMIC: 8578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Get all packets in ILMI Circuit */ 8579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!is_atm) 8580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'ilmic' supported only on raw ATM"); 8581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0); 8582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_atmfield_code(A_VCI, 16, BPF_JEQ, 0); 8583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_LANE: 8587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Get all LANE packets */ 8588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!is_atm) 8589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'lane' supported only on raw ATM"); 8590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_atmfield_code(A_PROTOTYPE, PT_LANE, BPF_JEQ, 0); 8591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 8593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Arrange that all subsequent tests assume LANE 8594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * rather than LLC-encapsulated packets, and set 8595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the offsets appropriately for LANE-encapsulated 8596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet. 8597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 8598d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * We assume LANE means Ethernet, not Token Ring. 8599d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 8600d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes PUSH_LINKHDR(DLT_EN10MB, 0, 8601d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_payload + 2, /* Ethernet header */ 8602d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes -1); 8603d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linktype.constant_part = off_linkhdr.constant_part + 12; 8604d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes off_linkpl.constant_part = off_linkhdr.constant_part + 14; /* Ethernet */ 8605511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl = 0; /* Ethernet II */ 8606511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off_nl_nosnap = 3; /* 802.3+802.2 */ 8607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_LLC: 8610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Get all LLC-encapsulated packets */ 8611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!is_atm) 8612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'llc' supported only on raw ATM"); 8613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_atmfield_code(A_PROTOTYPE, PT_LLC, BPF_JEQ, 0); 8614d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes linktype = prevlinktype; 8615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 8618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 8621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8623d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* 8624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Filtering for MTP2 messages based on li value 8625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * FISU, length is null 8626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LSSU, length is 1 or 2 8627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * MSU, length is 3 or more 8628511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For MTP2_HSL, sequences are on 2 bytes, and length on 9 bits 8629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 8630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 8631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_mtp2type_abbrev(type) 8632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int type; 8633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 8635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (type) { 8637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case M_FISU: 8639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ( (linktype != DLT_MTP2) && 8640511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (linktype != DLT_ERF) && 8641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (linktype != DLT_MTP2_WITH_PHDR) ) 8642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'fisu' supported only on MTP2"); 8643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* gen_ncmp(offrel, offset, size, mask, jtype, reverse, value) */ 8644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JEQ, 0, 0); 8645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case M_LSSU: 8648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ( (linktype != DLT_MTP2) && 8649511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (linktype != DLT_ERF) && 8650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (linktype != DLT_MTP2_WITH_PHDR) ) 8651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'lssu' supported only on MTP2"); 8652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 1, 2); 8653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 0, 0); 8654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b1, b0); 8655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case M_MSU: 8658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ( (linktype != DLT_MTP2) && 8659511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (linktype != DLT_ERF) && 8660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (linktype != DLT_MTP2_WITH_PHDR) ) 8661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'msu' supported only on MTP2"); 8662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 0, 2); 8663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8665511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case MH_FISU: 8666511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if ( (linktype != DLT_MTP2) && 8667511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (linktype != DLT_ERF) && 8668511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (linktype != DLT_MTP2_WITH_PHDR) ) 8669511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'hfisu' supported only on MTP2_HSL"); 8670511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* gen_ncmp(offrel, offset, size, mask, jtype, reverse, value) */ 8671511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = gen_ncmp(OR_PACKET, off_li_hsl, BPF_H, 0xff80, BPF_JEQ, 0, 0); 8672511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 8673511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 8674511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case MH_LSSU: 8675511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if ( (linktype != DLT_MTP2) && 8676511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (linktype != DLT_ERF) && 8677511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (linktype != DLT_MTP2_WITH_PHDR) ) 8678511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'hlssu' supported only on MTP2_HSL"); 8679511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = gen_ncmp(OR_PACKET, off_li_hsl, BPF_H, 0xff80, BPF_JGT, 1, 0x0100); 8680511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1 = gen_ncmp(OR_PACKET, off_li_hsl, BPF_H, 0xff80, BPF_JGT, 0, 0); 8681511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b1, b0); 8682511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 8683511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 8684511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case MH_MSU: 8685511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if ( (linktype != DLT_MTP2) && 8686511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (linktype != DLT_ERF) && 8687511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (linktype != DLT_MTP2_WITH_PHDR) ) 8688511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_error("'hmsu' supported only on MTP2_HSL"); 8689511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = gen_ncmp(OR_PACKET, off_li_hsl, BPF_H, 0xff80, BPF_JGT, 0, 0x0100); 8690511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 8691511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 8692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 8693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 8696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 8699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_mtp3field_code(mtp3field, jvalue, jtype, reverse) 8700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int mtp3field; 8701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 jvalue; 8702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 jtype; 8703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int reverse; 8704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0; 8706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 val1 , val2 , val3; 8707511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall u_int newoff_sio=off_sio; 8708511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall u_int newoff_opc=off_opc; 8709511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall u_int newoff_dpc=off_dpc; 8710511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall u_int newoff_sls=off_sls; 8711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (mtp3field) { 8713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8714511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case MH_SIO: 8715511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall newoff_sio += 3; /* offset for MTP2_HSL */ 8716511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* FALLTHROUGH */ 8717511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 8718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case M_SIO: 8719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (off_sio == (u_int)-1) 8720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'sio' supported only on SS7"); 8721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* sio coded on 1 byte so max value 255 */ 8722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if(jvalue > 255) 8723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("sio value %u too big; max value = 255", 8724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project jvalue); 8725511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = gen_ncmp(OR_PACKET, newoff_sio, BPF_B, 0xffffffff, 8726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (u_int)jtype, reverse, (u_int)jvalue); 8727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8729511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case MH_OPC: 8730511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall newoff_opc+=3; 8731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case M_OPC: 8732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (off_opc == (u_int)-1) 8733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'opc' supported only on SS7"); 8734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* opc coded on 14 bits so max value 16383 */ 8735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (jvalue > 16383) 8736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("opc value %u too big; max value = 16383", 8737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project jvalue); 8738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* the following instructions are made to convert jvalue 8739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to the form used to write opc in an ss7 message*/ 8740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val1 = jvalue & 0x00003c00; 8741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val1 = val1 >>10; 8742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val2 = jvalue & 0x000003fc; 8743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val2 = val2 <<6; 8744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val3 = jvalue & 0x00000003; 8745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val3 = val3 <<22; 8746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project jvalue = val1 + val2 + val3; 8747511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = gen_ncmp(OR_PACKET, newoff_opc, BPF_W, 0x00c0ff0f, 8748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (u_int)jtype, reverse, (u_int)jvalue); 8749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8751511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case MH_DPC: 8752511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall newoff_dpc += 3; 8753511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* FALLTHROUGH */ 8754511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 8755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case M_DPC: 8756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (off_dpc == (u_int)-1) 8757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'dpc' supported only on SS7"); 8758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* dpc coded on 14 bits so max value 16383 */ 8759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (jvalue > 16383) 8760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("dpc value %u too big; max value = 16383", 8761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project jvalue); 8762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* the following instructions are made to convert jvalue 8763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to the forme used to write dpc in an ss7 message*/ 8764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val1 = jvalue & 0x000000ff; 8765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val1 = val1 << 24; 8766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val2 = jvalue & 0x00003f00; 8767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val2 = val2 << 8; 8768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project jvalue = val1 + val2; 8769511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = gen_ncmp(OR_PACKET, newoff_dpc, BPF_W, 0xff3f0000, 8770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (u_int)jtype, reverse, (u_int)jvalue); 8771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8773511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case MH_SLS: 8774511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall newoff_sls+=3; 8775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case M_SLS: 8776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (off_sls == (u_int)-1) 8777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'sls' supported only on SS7"); 8778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* sls coded on 4 bits so max value 15 */ 8779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (jvalue > 15) 8780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("sls value %u too big; max value = 15", 8781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project jvalue); 8782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* the following instruction is made to convert jvalue 8783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to the forme used to write sls in an ss7 message*/ 8784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project jvalue = jvalue << 4; 8785511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = gen_ncmp(OR_PACKET, newoff_sls, BPF_B, 0xf0, 8786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (u_int)jtype,reverse, (u_int)jvalue); 8787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 8790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 8793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 8796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_msg_abbrev(type) 8797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int type; 8798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b1; 8800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 8802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Q.2931 signalling protocol messages for handling virtual circuits 8803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * establishment and teardown 8804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 8805478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (type) { 8806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8807478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_SETUP: 8808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_atmfield_code(A_MSGTYPE, SETUP, BPF_JEQ, 0); 8809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_CALLPROCEED: 8812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_atmfield_code(A_MSGTYPE, CALL_PROCEED, BPF_JEQ, 0); 8813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_CONNECT: 8816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_atmfield_code(A_MSGTYPE, CONNECT, BPF_JEQ, 0); 8817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8818478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_CONNECTACK: 8820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_atmfield_code(A_MSGTYPE, CONNECT_ACK, BPF_JEQ, 0); 8821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8822478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_RELEASE: 8824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_atmfield_code(A_MSGTYPE, RELEASE, BPF_JEQ, 0); 8825478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_RELEASE_DONE: 8828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_atmfield_code(A_MSGTYPE, RELEASE_DONE, BPF_JEQ, 0); 8829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 8832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 8835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 8838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_atmmulti_abbrev(type) 8839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int type; 8840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 8842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8843478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (type) { 8844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_OAM: 8846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!is_atm) 8847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'oam' supported only on raw ATM"); 8848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_atmmulti_abbrev(A_OAMF4); 8849478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_OAMF4: 8852478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!is_atm) 8853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'oamf4' supported only on raw ATM"); 8854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* OAM F4 type */ 8855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_atmfield_code(A_VCI, 3, BPF_JEQ, 0); 8856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_atmfield_code(A_VCI, 4, BPF_JEQ, 0); 8857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0); 8859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_CONNECTMSG: 8863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 8864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Get Q.2931 signalling messages for switched 8865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * virtual connection 8866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 8867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!is_atm) 8868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'connectmsg' supported only on raw ATM"); 8869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_msg_abbrev(A_SETUP); 8870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_msg_abbrev(A_CALLPROCEED); 8871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_msg_abbrev(A_CONNECT); 8873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_msg_abbrev(A_CONNECTACK); 8875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_msg_abbrev(A_RELEASE); 8877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_msg_abbrev(A_RELEASE_DONE); 8879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_atmtype_abbrev(A_SC); 8881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_METACONNECT: 8885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!is_atm) 8886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_error("'metaconnect' supported only on raw ATM"); 8887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_msg_abbrev(A_SETUP); 8888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = gen_msg_abbrev(A_CALLPROCEED); 8889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_msg_abbrev(A_CONNECT); 8891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_msg_abbrev(A_RELEASE); 8893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_msg_abbrev(A_RELEASE_DONE); 8895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = gen_atmtype_abbrev(A_METAC); 8897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 8901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 8904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8905