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 27965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifdef _WIN32 28478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <pcap-stdinc.h> 29965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#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> 40965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif /* _WIN32 */ 41478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 42965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifndef _WIN32 43478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 44478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef __NetBSD__ 45478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/param.h> 46478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 47478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 48478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/in.h> 49511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <arpa/inet.h> 50478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 51965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif /* _WIN32 */ 52478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 53478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdlib.h> 54478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <string.h> 55478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <memory.h> 56478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <setjmp.h> 57478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdarg.h> 58478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 59478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef MSDOS 60478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap-dos.h" 61478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 62478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 63478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap-int.h" 64478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 65478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "ethertype.h" 66478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "nlpid.h" 67478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "llc.h" 68478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "gencode.h" 69511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "ieee80211.h" 70478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "atmuni31.h" 71478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "sunatmpos.h" 72478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "ppp.h" 73511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "pcap/sll.h" 74511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "pcap/ipnet.h" 75478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "arcnet.h" 76965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 77965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#include "grammar.h" 78965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#include "scanner.h" 79965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 80511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#if defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) 81511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <linux/types.h> 82511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <linux/if_packet.h> 83511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <linux/filter.h> 84511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 85965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 86478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_NET_PFVAR_H 87478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/socket.h> 88478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if.h> 89478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/pfvar.h> 90478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if_pflog.h> 91478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 92965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 93478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef offsetof 94478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define offsetof(s, e) ((size_t)&((s *)0)->e) 95478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 96965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 97478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6 98965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifdef _WIN32 99965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF) 100965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes/* IPv6 address */ 101965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstruct in6_addr 102965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes { 103965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes union 104965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes { 105965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int8_t u6_addr8[16]; 106965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int16_t u6_addr16[8]; 107965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int32_t u6_addr32[4]; 108965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes } in6_u; 109965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#define s6_addr in6_u.u6_addr8 110965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#define s6_addr16 in6_u.u6_addr16 111965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#define s6_addr32 in6_u.u6_addr32 112965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#define s6_addr64 in6_u.u6_addr64 113965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes }; 114965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 115965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughestypedef unsigned short sa_family_t; 116965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 117965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#define __SOCKADDR_COMMON(sa_prefix) \ 118965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sa_family_t sa_prefix##family 119965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 120965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes/* Ditto, for IPv6. */ 121965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstruct sockaddr_in6 122965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes { 123965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes __SOCKADDR_COMMON (sin6_); 124965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int16_t sin6_port; /* Transport layer port # */ 125965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int32_t sin6_flowinfo; /* IPv6 flow information */ 126965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes struct in6_addr sin6_addr; /* IPv6 address */ 127965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes }; 128965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 129965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifndef EAI_ADDRFAMILY 130965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstruct addrinfo { 131965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ 132965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int ai_family; /* PF_xxx */ 133965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int ai_socktype; /* SOCK_xxx */ 134965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ 135965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes size_t ai_addrlen; /* length of ai_addr */ 136965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes char *ai_canonname; /* canonical name for hostname */ 137965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes struct sockaddr *ai_addr; /* binary address */ 138965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes struct addrinfo *ai_next; /* next structure in linked list */ 139965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes}; 140965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif /* EAI_ADDRFAMILY */ 141965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif /* defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF) */ 142965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#else /* _WIN32 */ 143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netdb.h> /* for "struct addrinfo" */ 144965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif /* _WIN32 */ 145965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif /* INET6 */ 146511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <pcap/namedb.h> 147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 148965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#include "nametoaddr.h" 149965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define ETHERMTU 1500 151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 152d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#ifndef ETHERTYPE_TEB 153d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#define ETHERTYPE_TEB 0x6558 154d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#endif 155d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 156511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef IPPROTO_HOPOPTS 157511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IPPROTO_HOPOPTS 0 158511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 159511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef IPPROTO_ROUTING 160511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IPPROTO_ROUTING 43 161511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 162511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef IPPROTO_FRAGMENT 163511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IPPROTO_FRAGMENT 44 164511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 165511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef IPPROTO_DSTOPTS 166511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IPPROTO_DSTOPTS 60 167511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_SCTP 169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_SCTP 132 170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 172d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#define GENEVE_PORT 6081 173d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_OS_PROTO_H 175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "os-proto.h" 176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define JMP(c) ((c)|BPF_JMP|BPF_K) 179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 180965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes/* 181965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * "Push" the current value of the link-layer header type and link-layer 182965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * header offset onto a "stack", and set a new value. (It's not a 183965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * full-blown stack; we keep only the top two items.) 184965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 185965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#define PUSH_LINKHDR(cs, new_linktype, new_is_variable, new_constant_part, new_reg) \ 186965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes{ \ 187965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cs)->prevlinktype = (cs)->linktype; \ 188965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cs)->off_prevlinkhdr = (cs)->off_linkhdr; \ 189965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cs)->linktype = (new_linktype); \ 190965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cs)->off_linkhdr.is_variable = (new_is_variable); \ 191965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cs)->off_linkhdr.constant_part = (new_constant_part); \ 192965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cs)->off_linkhdr.reg = (new_reg); \ 193965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cs)->is_geneve = 0; \ 194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 196965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes/* 197965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Offset "not set" value. 198965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 199965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#define OFFSET_NOT_SET 0xffffffffU 200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 202d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Absolute offsets, which are offsets from the beginning of the raw 203d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * packet data, are, in the general case, the sum of a variable value 204d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * and a constant value; the variable value may be absent, in which 205d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * case the offset is only the constant value, and the constant value 206d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * may be zero, in which case the offset is only the variable value. 207d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 208d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * bpf_abs_offset is a structure containing all that information: 209d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 210d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * is_variable is 1 if there's a variable part. 211d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 212d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * constant_part is the constant part of the value, possibly zero; 213d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 214d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * if is_variable is 1, reg is the register number for a register 215d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * containing the variable value if the register has been assigned, 216d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * and -1 otherwise. 217d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 218d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughestypedef struct { 219d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes int is_variable; 220d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes u_int constant_part; 221d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes int reg; 222d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} bpf_abs_offset; 223d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 224d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* 225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Value passed to gen_load_a() to indicate what the offset argument 226d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * is relative to the beginning of. 227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectenum e_offrel { 229d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_PACKET, /* full packet data */ 230d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_LINKHDR, /* link-layer header */ 231d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_PREVLINKHDR, /* previous link-layer header */ 232d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_LLC, /* 802.2 LLC header */ 233d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_PREVMPLSHDR, /* previous MPLS header */ 234d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_LINKTYPE, /* link-layer type */ 235d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_LINKPL, /* link-layer payload */ 236d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_LINKPL_NOSNAP, /* link-layer payload, with no SNAP header at the link layer */ 237d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_TRAN_IPV4, /* transport-layer header, with IPv4 network layer */ 238d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes OR_TRAN_IPV6 /* transport-layer header, with IPv6 network layer */ 239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}; 240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We divy out chunks of memory rather than call malloc each time so 243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we don't have to worry about leaking memory. It's probably 244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * not a big deal if all this memory was wasted but if this ever 245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * goes into a library that would probably not be a good idea. 246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - this *is* in a library.... 248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define NCHUNKS 16 250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define CHUNK0SIZE 1024 251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct chunk { 252965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes size_t n_left; 253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project void *m; 254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}; 255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 256965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes/* Code generator state */ 257965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 258965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstruct _compiler_state { 259965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes jmp_buf top_ctx; 260965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes pcap_t *bpf_pcap; 261965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 262965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes struct icode ic; 263965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 264965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int snaplen; 265965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 266965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int linktype; 267965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int prevlinktype; 268965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int outermostlinktype; 269965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 270965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_u_int32 netmask; 271965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int no_optimize; 272965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 273965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* Hack for handling VLAN and MPLS stacks. */ 274965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int label_stack_depth; 275965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int vlan_stack_depth; 276965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 277965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* XXX */ 278965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int pcap_fddipad; 279965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 280965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifdef INET6 281965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 282965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * As errors are handled by a longjmp, anything allocated must 283965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * be freed in the longjmp handler, so it must be reachable 284965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * from that handler. 285965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 286965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * One thing that's allocated is the result of pcap_nametoaddrinfo(); 287965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * it must be freed with freeaddrinfo(). This variable points to 288965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * any addrinfo structure that would need to be freed. 289965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 290965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes struct addrinfo *ai; 291965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif 292965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 293965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 294965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Various code constructs need to know the layout of the packet. 295965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * These values give the necessary offsets from the beginning 296965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * of the packet data. 297965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 298965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 299965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 300965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Absolute offset of the beginning of the link-layer header. 301965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 302965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_abs_offset off_linkhdr; 303965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 304965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 305965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * If we're checking a link-layer header for a packet encapsulated 306965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * in another protocol layer, this is the equivalent information 307965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * for the previous layers' link-layer header from the beginning 308965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * of the raw packet data. 309965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 310965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_abs_offset off_prevlinkhdr; 311965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 312965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 313965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * This is the equivalent information for the outermost layers' 314965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * link-layer header. 315965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 316965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_abs_offset off_outermostlinkhdr; 317965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 318965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 319965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Absolute offset of the beginning of the link-layer payload. 320965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 321965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_abs_offset off_linkpl; 322965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 323965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 324965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * "off_linktype" is the offset to information in the link-layer 325965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * header giving the packet type. This is an absolute offset 326965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * from the beginning of the packet. 327965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 328965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * For Ethernet, it's the offset of the Ethernet type field; this 329965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * means that it must have a value that skips VLAN tags. 330965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 331965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * For link-layer types that always use 802.2 headers, it's the 332965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * offset of the LLC header; this means that it must have a value 333965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * that skips VLAN tags. 334965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 335965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * For PPP, it's the offset of the PPP type field. 336965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 337965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * For Cisco HDLC, it's the offset of the CHDLC type field. 338965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 339965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * For BSD loopback, it's the offset of the AF_ value. 340965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 341965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * For Linux cooked sockets, it's the offset of the type field. 342965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 343965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * off_linktype.constant_part is set to OFFSET_NOT_SET for no 344965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * encapsulation, in which case, IP is assumed. 345965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 346965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_abs_offset off_linktype; 347965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 348965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 349965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * TRUE if the link layer includes an ATM pseudo-header. 350965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 351965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int is_atm; 352965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 353965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 354965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * TRUE if "geneve" appeared in the filter; it causes us to 355965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * generate code that checks for a Geneve header and assume 356965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * that later filters apply to the encapsulated payload. 357965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 358965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int is_geneve; 359965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 360965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 361965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * These are offsets for the ATM pseudo-header. 362965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 363965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int off_vpi; 364965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int off_vci; 365965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int off_proto; 366965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 367965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 368965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * These are offsets for the MTP2 fields. 369965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 370965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int off_li; 371965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int off_li_hsl; 372965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 373965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 374965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * These are offsets for the MTP3 fields. 375965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 376965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int off_sio; 377965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int off_opc; 378965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int off_dpc; 379965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int off_sls; 380965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 381965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 382965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * This is the offset of the first byte after the ATM pseudo_header, 383965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * or -1 if there is no ATM pseudo-header. 384965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 385965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int off_payload; 386965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 387965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 388965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * These are offsets to the beginning of the network-layer header. 389965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * They are relative to the beginning of the link-layer payload 390965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * (i.e., they don't include off_linkhdr.constant_part or 391965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * off_linkpl.constant_part). 392965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 393965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * If the link layer never uses 802.2 LLC: 394965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 395965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * "off_nl" and "off_nl_nosnap" are the same. 396965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 397965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * If the link layer always uses 802.2 LLC: 398965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 399965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * "off_nl" is the offset if there's a SNAP header following 400965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * the 802.2 header; 401965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 402965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * "off_nl_nosnap" is the offset if there's no SNAP header. 403965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 404965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * If the link layer is Ethernet: 405965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 406965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * "off_nl" is the offset if the packet is an Ethernet II packet 407965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * (we assume no 802.3+802.2+SNAP); 408965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 409965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * "off_nl_nosnap" is the offset if the packet is an 802.3 packet 410965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * with an 802.2 header following it. 411965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 412965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int off_nl; 413965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int off_nl_nosnap; 414965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 415965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 416965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Here we handle simple allocation of the scratch registers. 417965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * If too many registers are alloc'd, the allocator punts. 418965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 419965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int regused[BPF_MEMWORDS]; 420965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int curreg; 421965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 422965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 423965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Memory chunks. 424965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 425965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes struct chunk chunks[NCHUNKS]; 426965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int cur_chunk; 427965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes}; 428965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 429965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesvoid 430965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesbpf_syntax_error(compiler_state_t *cstate, const char *msg) 431965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes{ 432965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "syntax error in filter expression: %s", msg); 433965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* NOTREACHED */ 434965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes} 435965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 436965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes/* VARARGS */ 437965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesvoid 438965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesbpf_error(compiler_state_t *cstate, const char *fmt, ...) 439965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes{ 440965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes va_list ap; 441965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 442965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes va_start(ap, fmt); 443965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->bpf_pcap != NULL) 444965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (void)pcap_vsnprintf(pcap_geterr(cstate->bpf_pcap), 445965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes PCAP_ERRBUF_SIZE, fmt, ap); 446965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes va_end(ap); 447965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes longjmp(cstate->top_ctx, 1); 448965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* NOTREACHED */ 449965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes} 450965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 451965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic void init_linktype(compiler_state_t *, pcap_t *); 452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 453965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic void init_regs(compiler_state_t *); 454965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic int alloc_reg(compiler_state_t *); 455965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic void free_reg(compiler_state_t *, int); 456965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 457965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic void initchunks(compiler_state_t *cstate); 458965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic void *newchunk(compiler_state_t *cstate, size_t); 459965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic void freechunks(compiler_state_t *cstate); 460965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic inline struct block *new_block(compiler_state_t *cstate, int); 461965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic inline struct slist *new_stmt(compiler_state_t *cstate, int); 462965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_retblk(compiler_state_t *cstate, int); 463965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic inline void syntax(compiler_state_t *cstate); 464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void backpatch(struct block *, struct block *); 466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void merge(struct block *, struct block *); 467965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_cmp(compiler_state_t *, enum e_offrel, u_int, 468965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int, bpf_int32); 469965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_cmp_gt(compiler_state_t *, enum e_offrel, u_int, 470965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int, bpf_int32); 471965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_cmp_ge(compiler_state_t *, enum e_offrel, u_int, 472965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int, bpf_int32); 473965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_cmp_lt(compiler_state_t *, enum e_offrel, u_int, 474965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int, bpf_int32); 475965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_cmp_le(compiler_state_t *, enum e_offrel, u_int, 476965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int, bpf_int32); 477965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_mcmp(compiler_state_t *, enum e_offrel, u_int, 478965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int, bpf_int32, bpf_u_int32); 479965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_bcmp(compiler_state_t *, enum e_offrel, u_int, 480965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int, const u_char *); 481965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_ncmp(compiler_state_t *, enum e_offrel, bpf_u_int32, 482965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_u_int32, bpf_u_int32, bpf_u_int32, int, bpf_int32); 483965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct slist *gen_load_absoffsetrel(compiler_state_t *, bpf_abs_offset *, 484965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int, u_int); 485965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct slist *gen_load_a(compiler_state_t *, enum e_offrel, u_int, 486965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int); 487965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct slist *gen_loadx_iphdrlen(compiler_state_t *); 488965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_uncond(compiler_state_t *, int); 489965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic inline struct block *gen_true(compiler_state_t *); 490965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic inline struct block *gen_false(compiler_state_t *); 491965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_ether_linktype(compiler_state_t *, int); 492965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_ipnet_linktype(compiler_state_t *, int); 493965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_linux_sll_linktype(compiler_state_t *, int); 494965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct slist *gen_load_prism_llprefixlen(compiler_state_t *); 495965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct slist *gen_load_avs_llprefixlen(compiler_state_t *); 496965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct slist *gen_load_radiotap_llprefixlen(compiler_state_t *); 497965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct slist *gen_load_ppi_llprefixlen(compiler_state_t *); 498965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic void insert_compute_vloffsets(compiler_state_t *, struct block *); 499965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct slist *gen_abs_offset_varpart(compiler_state_t *, 500965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_abs_offset *); 501511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int ethertype_to_ppptype(int); 502965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_linktype(compiler_state_t *, int); 503965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_snap(compiler_state_t *, bpf_u_int32, bpf_u_int32); 504965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_llc_linktype(compiler_state_t *, int); 505965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_hostop(compiler_state_t *, bpf_u_int32, bpf_u_int32, 506965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int, int, u_int, u_int); 507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6 508965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_hostop6(compiler_state_t *, struct in6_addr *, 509965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes struct in6_addr *, int, int, u_int, u_int); 510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 511965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_ahostop(compiler_state_t *, const u_char *, int); 512965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_ehostop(compiler_state_t *, const u_char *, int); 513965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_fhostop(compiler_state_t *, const u_char *, int); 514965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_thostop(compiler_state_t *, const u_char *, int); 515965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_wlanhostop(compiler_state_t *, const u_char *, int); 516965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_ipfchostop(compiler_state_t *, const u_char *, int); 517965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_dnhostop(compiler_state_t *, bpf_u_int32, int); 518965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_mpls_linktype(compiler_state_t *, int); 519965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_host(compiler_state_t *, bpf_u_int32, bpf_u_int32, 520965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int, int, int); 521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6 522965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_host6(compiler_state_t *, struct in6_addr *, 523965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes struct in6_addr *, int, int, int); 524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef INET6 526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int); 527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 528965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_ipfrag(compiler_state_t *); 529965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_portatom(compiler_state_t *, int, bpf_int32); 530965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_portrangeatom(compiler_state_t *, int, bpf_int32, 531965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_int32); 532965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_portatom6(compiler_state_t *, int, bpf_int32); 533965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_portrangeatom6(compiler_state_t *, int, bpf_int32, 534965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_int32); 535965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstruct block *gen_portop(compiler_state_t *, int, int, int); 536965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_port(compiler_state_t *, int, int, int); 537965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstruct block *gen_portrangeop(compiler_state_t *, int, int, int, int); 538965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_portrange(compiler_state_t *, int, int, int, int); 539965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstruct block *gen_portop6(compiler_state_t *, int, int, int); 540965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_port6(compiler_state_t *, int, int, int); 541965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstruct block *gen_portrangeop6(compiler_state_t *, int, int, int, int); 542965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_portrange6(compiler_state_t *, int, int, int, int); 543965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic int lookup_proto(compiler_state_t *, const char *, int); 544965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_protochain(compiler_state_t *, int, int, int); 545965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_proto(compiler_state_t *, int, int, int); 546965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct slist *xfer_to_x(compiler_state_t *, struct arth *); 547965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct slist *xfer_to_a(compiler_state_t *, struct arth *); 548965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_mac_multicast(compiler_state_t *, int); 549965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_len(compiler_state_t *, int, int); 550965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_check_802_11_data_frame(compiler_state_t *); 551965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_geneve_ll_check(compiler_state_t *cstate); 552965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 553965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_ppi_dlt_check(compiler_state_t *); 554965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block *gen_msg_abbrev(compiler_state_t *, int type); 555965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 556965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic void 557965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesinitchunks(compiler_state_t *cstate) 558965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes{ 559965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int i; 560965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 561965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes for (i = 0; i < NCHUNKS; i++) { 562965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->chunks[i].n_left = 0; 563965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->chunks[i].m = NULL; 564965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes } 565965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->cur_chunk = 0; 566965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes} 567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void * 569965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesnewchunk(compiler_state_t *cstate, size_t n) 570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct chunk *cp; 572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int k; 573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project size_t size; 574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef __NetBSD__ 576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* XXX Round up to nearest long. */ 577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1); 578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* XXX Round up to structure boundary. */ 580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project n = ALIGN(n); 581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 583965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cp = &cstate->chunks[cstate->cur_chunk]; 584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (n > cp->n_left) { 585965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes ++cp, k = ++cstate->cur_chunk; 586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (k >= NCHUNKS) 587965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "out of memory"); 588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project size = CHUNK0SIZE << k; 589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cp->m = (void *)malloc(size); 590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (cp->m == NULL) 591965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "out of memory"); 592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset((char *)cp->m, 0, size); 593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cp->n_left = size; 594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (n > size) 595965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "out of memory"); 596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cp->n_left -= n; 598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (void *)((char *)cp->m + cp->n_left); 599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void 602965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesfreechunks(compiler_state_t *cstate) 603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int i; 605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project for (i = 0; i < NCHUNKS; ++i) 607965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->chunks[i].m != NULL) 608965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes free(cstate->chunks[i].m); 609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * A strdup whose allocations are freed after code generation is over. 613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectchar * 615965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughessdup(compiler_state_t *cstate, const char *s) 616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 617965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes size_t n = strlen(s) + 1; 618965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes char *cp = newchunk(cstate, n); 619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strlcpy(cp, s, n); 621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (cp); 622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct block * 625965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesnew_block(compiler_state_t *cstate, int code) 626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *p; 628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 629965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes p = (struct block *)newchunk(cstate, sizeof(*p)); 630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->s.code = code; 631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->head = p; 632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return p; 634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct slist * 637965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesnew_stmt(compiler_state_t *cstate, int code) 638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *p; 640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 641965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes p = (struct slist *)newchunk(cstate, sizeof(*p)); 642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->s.code = code; 643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return p; 645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 648965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_retblk(compiler_state_t *cstate, int v) 649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 650965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes struct block *b = new_block(cstate, BPF_RET|BPF_K); 651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->s.k = v; 653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline void 657965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughessyntax(compiler_state_t *cstate) 658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 659965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "syntax error in filter expression"); 660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 662511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallint 663511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_compile(pcap_t *p, struct bpf_program *program, 664511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *buf, int optimize, bpf_u_int32 mask) 665511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 666965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes compiler_state_t cstate; 667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project const char * volatile xbuf = buf; 668965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes yyscan_t scanner = NULL; 669965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes YY_BUFFER_STATE in_buffer = NULL; 670511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall u_int len; 671d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes int rc; 672d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 673965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifdef _WIN32 674d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes static int done = 0; 675d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 676d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (!done) 677965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes pcap_wsockinit(); 678d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes done = 1; 679d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#endif 680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 681511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 682511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If this pcap_t hasn't been activated, it doesn't have a 683511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * link-layer type, so we can't use it. 684511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 685511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (!p->activated) { 686965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 687511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "not-yet-activated pcap_t passed to pcap_compile"); 688d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes rc = -1; 689d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes goto quit; 690511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 691965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes initchunks(&cstate); 692965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate.no_optimize = 0; 693965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate.ai = NULL; 694965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate.ic.root = NULL; 695965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate.ic.cur_mark = 0; 696965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate.bpf_pcap = p; 697965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes init_regs(&cstate); 698965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 699965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (setjmp(cstate.top_ctx)) { 700511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef INET6 701965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate.ai != NULL) 702965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes freeaddrinfo(cstate.ai); 703511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 704d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes rc = -1; 705d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes goto quit; 706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 708965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate.netmask = mask; 709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 710965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate.snaplen = pcap_snapshot(p); 711965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate.snaplen == 0) { 712965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "snaplen of 0 rejects all packets"); 714d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes rc = -1; 715d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes goto quit; 716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 718965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (pcap_lex_init(&scanner) != 0) 719965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(&cstate, "can't initialize scanner: %s", pcap_strerror(errno)); 720965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes in_buffer = pcap__scan_string(xbuf ? xbuf : "", scanner); 721965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 722965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 723965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Associate the compiler state with the lexical analyzer 724965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * state. 725965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 726965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes pcap_set_extra(&cstate, scanner); 727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 728965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes init_linktype(&cstate, p); 729965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (void)pcap_parse(scanner, &cstate); 730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 731965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate.ic.root == NULL) 732965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate.ic.root = gen_retblk(&cstate, cstate.snaplen); 733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 734965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (optimize && !cstate.no_optimize) { 735965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_optimize(&cstate, &cstate.ic); 736965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate.ic.root == NULL || 737965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cstate.ic.root->s.code == (BPF_RET|BPF_K) && cstate.ic.root->s.k == 0)) 738965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(&cstate, "expression rejects all packets"); 739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 740965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes program->bf_insns = icode_to_fcode(&cstate, &cstate.ic, cstate.ic.root, &len); 741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project program->bf_len = len; 742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 743d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes rc = 0; /* We're all okay */ 744d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 745d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesquit: 746965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 747965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Clean up everything for the lexical analyzer. 748965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 749965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (in_buffer != NULL) 750965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes pcap__delete_buffer(in_buffer, scanner); 751965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (scanner != NULL) 752965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes pcap_lex_destroy(scanner); 753d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 754965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 755965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Clean up our own allocated memory. 756965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 757965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes freechunks(&cstate); 758d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 759d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return (rc); 760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * entry point for using the compiler with no pcap open 764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * pass in all the stuff that is needed explicitly instead. 765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint 767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_compile_nopcap(int snaplen_arg, int linktype_arg, 768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct bpf_program *program, 769478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project const char *buf, int optimize, bpf_u_int32 mask) 770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_t *p; 772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int ret; 773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p = pcap_open_dead(linktype_arg, snaplen_arg); 775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p == NULL) 776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = pcap_compile(p, program, buf, optimize, mask); 778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_close(p); 779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (ret); 780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Clean up a "struct bpf_program" by freeing all the memory allocated 784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in it. 785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid 787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_freecode(struct bpf_program *program) 788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project program->bf_len = 0; 790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (program->bf_insns != NULL) { 791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free((char *)program->bf_insns); 792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project program->bf_insns = NULL; 793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Backpatch the blocks in 'list' to 'target'. The 'sense' field indicates 798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * which of the jt and jf fields has been resolved and which is a pointer 799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * back to another unresolved block (or nil). At least one of the fields 800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in each block is already resolved. 801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void 803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectbackpatch(list, target) 804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *list, *target; 805478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *next; 807478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (list) { 809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!list->sense) { 810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project next = JT(list); 811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project JT(list) = target; 812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project next = JF(list); 814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project JF(list) = target; 815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project list = next; 817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 818478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Merge the lists in b0 and b1, using the 'sense' field to indicate 822478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * which of jt and jf is the link. 823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void 825478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectmerge(b0, b1) 826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block **p = &b0; 829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Find end of list. */ 831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (*p) 832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p = !((*p)->sense) ? &JT(*p) : &JF(*p); 833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Concatenate the lists. */ 835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *p = b1; 836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid 839965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesfinish_parse(compiler_state_t *cstate, struct block *p) 840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *ppi_dlt_check; 842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 843478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Insert before the statements of the first (root) block any 845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * statements needed to load the lengths of any variable-length 846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * headers into registers. 847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - a fancier strategy would be to insert those before the 849478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * statements of all blocks that use those lengths and that 850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * have no predecessors that use them, so that we only compute 851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the lengths if we need them. There might be even better 852511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * approaches than that. 853511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 854511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * However, those strategies would be more complicated, and 855511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * as we don't generate code to compute a length if the 856511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * program has no tests that use the length, and as most 857511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * tests will probably use those lengths, we would just 858511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * postpone computing the lengths so that it's not done 859511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * for tests that fail early, and it's not clear that's 860511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * worth the effort. 861511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 862965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes insert_compute_vloffsets(cstate, p->head); 863d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 864511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 865511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For DLT_PPI captures, generate a check of the per-packet 866511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * DLT value to make sure it's DLT_IEEE802_11. 867965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 868965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * XXX - TurboCap cards use DLT_PPI for Ethernet. 869965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Can we just define some DLT_ETHERNET_WITH_PHDR pseudo-header 870965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * with appropriate Ethernet information and use that rather 871965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * than using something such as DLT_PPI where you don't know 872965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * the link-layer header type until runtime, which, in the 873965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * general case, would force us to generate both Ethernet *and* 874965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 802.11 code (*and* anything else for which PPI is used) 875965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * and choose between them early in the BPF program? 876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 877965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes ppi_dlt_check = gen_ppi_dlt_check(cstate); 878511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (ppi_dlt_check != NULL) 879511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(ppi_dlt_check, p); 880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 881965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes backpatch(p, gen_retblk(cstate, cstate->snaplen)); 882511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->sense = !p->sense; 883965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes backpatch(p, gen_retblk(cstate, 0)); 884965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->ic.root = p->head; 885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid 888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_and(b0, b1) 889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project backpatch(b0, b1->head); 892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0->sense = !b0->sense; 893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->sense = !b1->sense; 894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project merge(b1, b0); 895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->sense = !b1->sense; 896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->head = b0->head; 897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid 900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_or(b0, b1) 901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0->sense = !b0->sense; 904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project backpatch(b0, b1->head); 905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0->sense = !b0->sense; 906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project merge(b1, b0); 907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->head = b0->head; 908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 910478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid 911478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_not(b) 912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 914478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->sense = !b->sense; 915478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 918965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_cmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset, 919965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int size, bpf_int32 v) 920478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 921965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_ncmp(cstate, offrel, offset, size, 0xffffffff, BPF_JEQ, 0, v); 922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 923478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 924478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 925965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_cmp_gt(compiler_state_t *cstate, enum e_offrel offrel, u_int offset, 926965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int size, bpf_int32 v) 927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 928965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_ncmp(cstate, offrel, offset, size, 0xffffffff, BPF_JGT, 0, v); 929478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 932965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_cmp_ge(compiler_state_t *cstate, enum e_offrel offrel, u_int offset, 933965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int size, bpf_int32 v) 934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 935965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_ncmp(cstate, offrel, offset, size, 0xffffffff, BPF_JGE, 0, v); 936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 939965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_cmp_lt(compiler_state_t *cstate, enum e_offrel offrel, u_int offset, 940965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int size, bpf_int32 v) 941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 942965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_ncmp(cstate, offrel, offset, size, 0xffffffff, BPF_JGE, 1, v); 943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 946965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_cmp_le(compiler_state_t *cstate, enum e_offrel offrel, u_int offset, 947965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int size, bpf_int32 v) 948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 949965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_ncmp(cstate, offrel, offset, size, 0xffffffff, BPF_JGT, 1, v); 950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 953965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_mcmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset, 954965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int size, bpf_int32 v, bpf_u_int32 mask) 955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 956965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_ncmp(cstate, offrel, offset, size, mask, BPF_JEQ, 0, v); 957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 960965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_bcmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset, 961965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int size, const u_char *v) 962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block *b, *tmp; 964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = NULL; 966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (size >= 4) { 967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const u_char *p = &v[size - 4]; 968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 w = ((bpf_int32)p[0] << 24) | 969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ((bpf_int32)p[1] << 16) | ((bpf_int32)p[2] << 8) | p[3]; 970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 971965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_cmp(cstate, offrel, offset + size - 4, BPF_W, w); 972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (b != NULL) 973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b, tmp); 974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = tmp; 975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project size -= 4; 976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (size >= 2) { 978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register const u_char *p = &v[size - 2]; 979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 w = ((bpf_int32)p[0] << 8) | p[1]; 980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 981965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_cmp(cstate, offrel, offset + size - 2, BPF_H, w); 982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (b != NULL) 983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b, tmp); 984478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = tmp; 985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project size -= 2; 986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (size > 0) { 988965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_cmp(cstate, offrel, offset, BPF_B, (bpf_int32)v[0]); 989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (b != NULL) 990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b, tmp); 991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = tmp; 992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * AND the field of size "size" at offset "offset" relative to the header 998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * specified by "offrel" with "mask", and compare it with the value "v" 999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with the test specified by "jtype"; if "reverse" is true, the test 1000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * should test the opposite of "jtype". 1001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 1003965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_ncmp(compiler_state_t *cstate, enum e_offrel offrel, bpf_u_int32 offset, 1004965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_u_int32 size, bpf_u_int32 mask, bpf_u_int32 jtype, int reverse, 1005965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_int32 v) 1006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s, *s2; 1008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 1009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1010965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, offrel, offset, size); 1011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (mask != 0xffffffff) { 1013965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ALU|BPF_AND|BPF_K); 1014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2->s.k = mask; 1015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, s2); 1016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1018965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = new_block(cstate, JMP(jtype)); 1019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->stmts = s; 1020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->s.k = v; 1021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (reverse && (jtype == BPF_JGT || jtype == BPF_JGE)) 1022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b); 1023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 1024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void 1027965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesinit_linktype(compiler_state_t *cstate, pcap_t *p) 1028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1029965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->pcap_fddipad = p->fddipad; 1030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1032d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * We start out with only one link-layer header. 1033d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 1034965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->outermostlinktype = pcap_datalink(p); 1035965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_outermostlinkhdr.constant_part = 0; 1036965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_outermostlinkhdr.is_variable = 0; 1037965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_outermostlinkhdr.reg = -1; 1038d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 1039965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->prevlinktype = cstate->outermostlinktype; 1040965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_prevlinkhdr.constant_part = 0; 1041965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_prevlinkhdr.is_variable = 0; 1042965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_prevlinkhdr.reg = -1; 1043d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 1044965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->linktype = cstate->outermostlinktype; 1045965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkhdr.constant_part = 0; 1046965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkhdr.is_variable = 0; 1047965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkhdr.reg = -1; 1048d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 1049d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 1050d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * XXX 1051d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 1052965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 0; 1053965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.is_variable = 0; 1054965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.reg = -1; 1055d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 1056965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 0; 1057965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.is_variable = 0; 1058965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.reg = -1; 1059d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 1060d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 1061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Assume it's not raw ATM with a pseudo-header, for now. 1062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1063965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->is_atm = 0; 1064965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_vpi = -1; 1065965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_vci = -1; 1066965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_proto = -1; 1067965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_payload = -1; 1068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1070d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * And not Geneve. 1071511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 1072965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->is_geneve = 0; 1073511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1074511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 1075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * And assume we're not doing SS7. 1076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1077965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_li = -1; 1078965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_li_hsl = -1; 1079965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_sio = -1; 1080965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_opc = -1; 1081965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_dpc = -1; 1082965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_sls = -1; 1083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1084965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->label_stack_depth = 0; 1085965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->vlan_stack_depth = 0; 1086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1087965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes switch (cstate->linktype) { 1088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ARCNET: 1090965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 2; 1091965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 6; 1092965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; /* XXX in reality, variable! */ 1093965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; /* no 802.2 LLC */ 1094d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ARCNET_LINUX: 1097965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 4; 1098965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 8; 1099965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; /* XXX in reality, variable! */ 1100965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; /* no 802.2 LLC */ 1101d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_EN10MB: 1104965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 12; 1105965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 14; /* Ethernet header length */ 1106965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; /* Ethernet II */ 1107965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 3; /* 802.3+802.2 */ 1108d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_SLIP: 1111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SLIP doesn't have a link level type. The 16 byte 1113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header is hacked into our SLIP driver. 1114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1115965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = OFFSET_NOT_SET; 1116965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 16; 1117965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1118965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; /* no 802.2 LLC */ 1119d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_SLIP_BSDOS: 1122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* XXX this may be the same as the DLT_PPP_BSDOS case */ 1123965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = OFFSET_NOT_SET; 1124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* XXX end */ 1125965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 24; 1126965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1127965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; /* no 802.2 LLC */ 1128d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_NULL: 1131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_LOOP: 1132965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 0; 1133965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 4; 1134965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1135965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; /* no 802.2 LLC */ 1136d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ENC: 1139965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 0; 1140965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 12; 1141965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1142965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; /* no 802.2 LLC */ 1143d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP: 1146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP_PPPD: 1147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_C_HDLC: /* BSD/OS Cisco HDLC */ 1148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP_SERIAL: /* NetBSD sync/async serial PPP */ 1149965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 2; /* skip HDLC-like framing */ 1150965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 4; /* skip HDLC-like framing and protocol field */ 1151965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1152965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; /* no 802.2 LLC */ 1153d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP_ETHER: 1156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This does no include the Ethernet header, and 1158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * only covers session state. 1159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1160965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 6; 1161965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 8; 1162965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1163965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; /* no 802.2 LLC */ 1164d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP_BSDOS: 1167965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 5; 1168965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 24; 1169965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1170965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; /* no 802.2 LLC */ 1171d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_FDDI: 1174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * FDDI doesn't really have a link-level type field. 1176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We set "off_linktype" to the offset of the LLC header. 1177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * To check for Ethernet types, we assume that SSAP = SNAP 1179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is being used and pick out the encapsulated Ethernet type. 1180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - should we generate code to check for SNAP? 1181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1182965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 13; 1183965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part += cstate->pcap_fddipad; 1184965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 13; /* FDDI MAC header length */ 1185965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part += cstate->pcap_fddipad; 1186965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 8; /* 802.2+SNAP */ 1187965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 3; /* 802.2 */ 1188d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802: 1191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Token Ring doesn't really have a link-level type field. 1193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We set "off_linktype" to the offset of the LLC header. 1194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * To check for Ethernet types, we assume that SSAP = SNAP 1196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is being used and pick out the encapsulated Ethernet type. 1197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - should we generate code to check for SNAP? 1198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - the header is actually variable-length. 1200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Some various Linux patched versions gave 38 1201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as "off_linktype" and 40 as "off_nl"; however, 1202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * if a token ring packet has *no* routing 1203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * information, i.e. is not source-routed, the correct 1204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * values are 20 and 22, as they are in the vanilla code. 1205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * A packet is source-routed iff the uppermost bit 1207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of the first byte of the source address, at an 1208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * offset of 8, has the uppermost bit set. If the 1209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * packet is source-routed, the total number of bytes 1210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of routing information is 2 plus bits 0x1F00 of 1211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the 16-bit value at an offset of 14 (shifted right 1212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 8 - figure out which byte that is). 1213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1214965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 14; 1215965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 14; /* Token Ring MAC header length */ 1216965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 8; /* 802.2+SNAP */ 1217965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 3; /* 802.2 */ 1218d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 1221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO_AVS: 1222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO: 1223965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkhdr.is_variable = 1; 1224d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Fall through, 802.11 doesn't have a variable link 1225d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * prefix but is otherwise the same. */ 1226d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 1227d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_IEEE802_11: 1228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 802.11 doesn't really have a link-level type field. 1230d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * We set "off_linktype.constant_part" to the offset of 1231d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the LLC header. 1232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * To check for Ethernet types, we assume that SSAP = SNAP 1234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is being used and pick out the encapsulated Ethernet type. 1235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - should we generate code to check for SNAP? 1236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1237511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * We also handle variable-length radio headers here. 1238511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * The Prism header is in theory variable-length, but in 1239511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * practice it's always 144 bytes long. However, some 1240511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * drivers on Linux use ARPHRD_IEEE80211_PRISM, but 1241511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * sometimes or always supply an AVS header, so we 1242511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * have to check whether the radio header is a Prism 1243511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * header or an AVS header, so, in practice, it's 1244511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * variable-length. 1245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1246965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 24; 1247965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 0; /* link-layer header is variable-length */ 1248965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.is_variable = 1; 1249965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 8; /* 802.2+SNAP */ 1250965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 3; /* 802.2 */ 1251d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPI: 1254d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 1255511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * At the moment we treat PPI the same way that we treat 1256511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * normal Radiotap encoded packets. The difference is in 1257511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the function that generates the code at the beginning 1258511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * to compute the header length. Since this code generator 1259511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * of PPI supports bare 802.11 encapsulation only (i.e. 1260511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the encapsulated DLT should be DLT_IEEE802_11) we 1261511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * generate code to check for this too. 1262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1263965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 24; 1264965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 0; /* link-layer header is variable-length */ 1265965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.is_variable = 1; 1266965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkhdr.is_variable = 1; 1267965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 8; /* 802.2+SNAP */ 1268965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 3; /* 802.2 */ 1269d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ATM_RFC1483: 1272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ATM_CLIP: /* Linux ATM defines this */ 1273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * assume routed, non-ISO PDUs 1275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00) 1276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - what about ISO PDUs, e.g. CLNP, ISIS, ESIS, 1278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * or PPP with the PPP NLPID (e.g., PPPoA)? The 1279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * latter would presumably be treated the way PPPoE 1280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * should be, so you can do "pppoe and udp port 2049" 1281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * or "pppoa and tcp port 80" and have it check for 1282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * PPPo{A,E} and a PPP protocol of IP and.... 1283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1284965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 0; 1285965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 0; /* packet begins with LLC header */ 1286965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 8; /* 802.2+SNAP */ 1287965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 3; /* 802.2 */ 1288d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_SUNATM: 1291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Full Frontal ATM; you get AALn PDUs with an ATM 1293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * pseudo-header. 1294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1295965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->is_atm = 1; 1296965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_vpi = SUNATM_VPI_POS; 1297965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_vci = SUNATM_VCI_POS; 1298965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_proto = PROTO_POS; 1299965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_payload = SUNATM_PKT_BEGIN_POS; 1300965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = cstate->off_payload; 1301965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = cstate->off_payload; /* if LLC-encapsulated */ 1302965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 8; /* 802.2+SNAP */ 1303965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 3; /* 802.2 */ 1304d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_RAW: 1307511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IPV4: 1308511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IPV6: 1309965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = OFFSET_NOT_SET; 1310965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 0; 1311965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1312965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; /* no 802.2 LLC */ 1313d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_LINUX_SLL: /* fake header for Linux cooked socket */ 1316965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 14; 1317965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 16; 1318965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1319965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; /* no 802.2 LLC */ 1320d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_LTALK: 1323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LocalTalk does have a 1-byte type field in the LLAP header, 1325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * but really it just indicates whether there is a "short" or 1326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "long" DDP packet following. 1327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1328965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = OFFSET_NOT_SET; 1329965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 0; 1330965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1331965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; /* no 802.2 LLC */ 1332d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IP_OVER_FC: 1335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * RFC 2625 IP-over-Fibre-Channel doesn't really have a 1337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * link-level type field. We set "off_linktype" to the 1338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * offset of the LLC header. 1339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * To check for Ethernet types, we assume that SSAP = SNAP 1341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is being used and pick out the encapsulated Ethernet type. 1342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - should we generate code to check for SNAP? RFC 1343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2625 says SNAP should be used. 1344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1345965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 16; 1346965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 16; 1347965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 8; /* 802.2+SNAP */ 1348965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 3; /* 802.2 */ 1349d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_FRELAY: 1352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - we should set this to handle SNAP-encapsulated 1354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames (NLPID of 0x80). 1355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1356965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = OFFSET_NOT_SET; 1357965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 0; 1358965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1359965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; /* no 802.2 LLC */ 1360d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the only BPF-interesting FRF.16 frames are non-control frames; 1364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Frame Relay has a variable length link-layer 1365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * so lets start with offset 4 for now and increments later on (FIXME); 1366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_MFR: 1368965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = OFFSET_NOT_SET; 1369965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 0; 1370965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 4; 1371965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; /* XXX - for now -> no 802.2 LLC */ 1372d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_APPLE_IP_OVER_IEEE1394: 1375965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 16; 1376965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 18; 1377965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1378965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; /* no 802.2 LLC */ 1379d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_SYMANTEC_FIREWALL: 1382965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 6; 1383965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 44; 1384965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; /* Ethernet II */ 1385965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; /* XXX - what does it do with 802.3 packets? */ 1386d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_NET_PFVAR_H 1389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PFLOG: 1390965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 0; 1391965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = PFLOG_HDRLEN; 1392965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1393965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; /* no 802.2 LLC */ 1394d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 1396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MFR: 1398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MLFR: 1399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MLPPP: 1400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_PPP: 1401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_CHDLC: 1402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_FRELAY: 1403965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 4; 1404965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 4; 1405965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1406965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = -1; /* no 802.2 LLC */ 1407d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ATM1: 1410965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 4; /* in reality variable between 4-8 */ 1411965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 4; /* in reality variable between 4-8 */ 1412965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1413965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 10; 1414d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ATM2: 1417965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 8; /* in reality variable between 8-12 */ 1418965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 8; /* in reality variable between 8-12 */ 1419965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1420965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 10; 1421d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* frames captured on a Juniper PPPoE service PIC 1424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * contain raw ethernet frames */ 1425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_PPPOE: 1426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ETHER: 1427965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 14; 1428965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 16; 1429965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 18; /* Ethernet II */ 1430965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 21; /* 802.3+802.2 */ 1431d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_PPPOE_ATM: 1434965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 4; 1435965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 6; 1436965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1437965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = -1; /* no 802.2 LLC */ 1438d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_GGSN: 1441965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 6; 1442965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 12; 1443965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1444965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = -1; /* no 802.2 LLC */ 1445d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ES: 1448965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 6; 1449965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = OFFSET_NOT_SET; /* not really a network layer but raw IP addresses */ 1450965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = -1; /* not really a network layer but raw IP addresses */ 1451965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = -1; /* no 802.2 LLC */ 1452d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MONITOR: 1455965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 12; 1456965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 12; 1457965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; /* raw IP/IP6 header */ 1458965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = -1; /* no 802.2 LLC */ 1459d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1461511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_BACNET_MS_TP: 1462965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = OFFSET_NOT_SET; 1463965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = OFFSET_NOT_SET; 1464965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = -1; 1465965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = -1; 1466d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1467511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_SERVICES: 1469965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 12; 1470965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = OFFSET_NOT_SET; /* L3 proto location dep. on cookie type */ 1471965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = -1; /* L3 proto location dep. on cookie type */ 1472965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = -1; /* no 802.2 LLC */ 1473d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_VP: 1476965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 18; 1477965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = OFFSET_NOT_SET; 1478965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = -1; 1479965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = -1; 1480d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1481511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1482511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_ST: 1483965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 18; 1484965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = OFFSET_NOT_SET; 1485965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = -1; 1486965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = -1; 1487d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1488511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1489511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_ISM: 1490965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 8; 1491965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = OFFSET_NOT_SET; 1492965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = -1; 1493965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = -1; 1494d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1495511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1496511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_VS: 1497511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_SRX_E2E: 1498511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_FIBRECHANNEL: 1499511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_ATM_CEMIC: 1500965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 8; 1501965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = OFFSET_NOT_SET; 1502965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = -1; 1503965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = -1; 1504d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_MTP2: 1507965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_li = 2; 1508965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_li_hsl = 4; 1509965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_sio = 3; 1510965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_opc = 4; 1511965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_dpc = 4; 1512965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_sls = 7; 1513965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = OFFSET_NOT_SET; 1514965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = OFFSET_NOT_SET; 1515965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = -1; 1516965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = -1; 1517d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_MTP2_WITH_PHDR: 1520965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_li = 6; 1521965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_li_hsl = 8; 1522965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_sio = 7; 1523965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_opc = 8; 1524965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_dpc = 8; 1525965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_sls = 11; 1526965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = OFFSET_NOT_SET; 1527965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = OFFSET_NOT_SET; 1528965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = -1; 1529965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = -1; 1530d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1532511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_ERF: 1533965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_li = 22; 1534965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_li_hsl = 24; 1535965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_sio = 23; 1536965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_opc = 24; 1537965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_dpc = 24; 1538965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_sls = 27; 1539965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = OFFSET_NOT_SET; 1540965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = OFFSET_NOT_SET; 1541965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = -1; 1542965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = -1; 1543d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1545511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PFSYNC: 1546965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = OFFSET_NOT_SET; 1547965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 4; 1548965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1549965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; 1550d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1552511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_AX25_KISS: 1553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Currently, only raw "link[N:M]" filtering is supported. 1555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1556965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = OFFSET_NOT_SET; /* variable, min 15, max 71 steps of 7 */ 1557965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = OFFSET_NOT_SET; 1558965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = -1; /* variable, min 16, max 71 steps of 7 */ 1559965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = -1; /* no 802.2 LLC */ 1560d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1561511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1562511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IPNET: 1563965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 1; 1564965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 24; /* ipnet header length */ 1565965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 1566965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = -1; 1567d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1569511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER: 1570965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkhdr.constant_part = 4; /* Ethernet header is past 4-byte pseudo-header */ 1571965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = cstate->off_linkhdr.constant_part + 12; 1572965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = cstate->off_linkhdr.constant_part + 14; /* pseudo-header+Ethernet header length */ 1573965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; /* Ethernet II */ 1574965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 3; /* 802.3+802.2 */ 1575d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1576511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1577511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER_TRANSPARENT: 1578965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkhdr.constant_part = 12; /* MAC header is past 4-byte pseudo-header, preamble, and SFD */ 1579965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = cstate->off_linkhdr.constant_part + 12; 1580965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = cstate->off_linkhdr.constant_part + 14; /* pseudo-header+preamble+SFD+Ethernet header length */ 1581965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; /* Ethernet II */ 1582965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 3; /* 802.3+802.2 */ 1583d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1584511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1585511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 1586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1587511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For values in the range in which we've assigned new 1588511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * DLT_ values, only raw "link[N:M]" filtering is supported. 1589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1590965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->linktype >= DLT_MATCHING_MIN && 1591965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->linktype <= DLT_MATCHING_MAX) { 1592965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = OFFSET_NOT_SET; 1593965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = OFFSET_NOT_SET; 1594965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = -1; 1595965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = -1; 1596d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } else { 1597965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "unknown data link type %d", cstate->linktype); 1598511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 1599d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1602965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_outermostlinkhdr = cstate->off_prevlinkhdr = cstate->off_linkhdr; 1603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1605511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 1606d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Load a value relative to the specified absolute offset. 1607511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 1608511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist * 1609965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_load_absoffsetrel(compiler_state_t *cstate, bpf_abs_offset *abs_offset, 1610965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int offset, u_int size) 1611511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 1612511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *s, *s2; 1613511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1614965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_abs_offset_varpart(cstate, abs_offset); 1615511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1616511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 1617d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * If "s" is non-null, it has code to arrange that the X register 1618d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * contains the variable part of the absolute offset, so we 1619d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * generate a load relative to that, with an offset of 1620d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * abs_offset->constant_part + offset. 1621511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 1622d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Otherwise, we can do an absolute load with an offset of 1623d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * abs_offset->constant_part + offset. 1624511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 1625511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (s != NULL) { 1626511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 1627d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * "s" points to a list of statements that puts the 1628d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * variable part of the absolute offset into the X register. 1629d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Do an indirect load, to use the X register as an offset. 1630511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 1631965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_LD|BPF_IND|size); 1632d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s2->s.k = abs_offset->constant_part + offset; 1633511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 1634511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else { 1635511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 1636d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * There is no variable part of the absolute offset, so 1637d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * just do an absolute load. 1638511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 1639965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_LD|BPF_ABS|size); 1640d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s->s.k = abs_offset->constant_part + offset; 1641511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 1642511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return s; 1643511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 1644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 1646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load a value relative to the beginning of the specified header. 1647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist * 1649965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_load_a(compiler_state_t *cstate, enum e_offrel offrel, u_int offset, 1650965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int size) 1651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s, *s2; 1653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (offrel) { 1655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case OR_PACKET: 1657965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_LD|BPF_ABS|size); 1658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->s.k = offset; 1659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 1660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1661d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case OR_LINKHDR: 1662965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_absoffsetrel(cstate, &cstate->off_linkhdr, offset, size); 1663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 1664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1665d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case OR_PREVLINKHDR: 1666965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_absoffsetrel(cstate, &cstate->off_prevlinkhdr, offset, size); 1667511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 1668511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1669d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case OR_LLC: 1670965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_absoffsetrel(cstate, &cstate->off_linkpl, offset, size); 1671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 1672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1673d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case OR_PREVMPLSHDR: 1674965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_absoffsetrel(cstate, &cstate->off_linkpl, cstate->off_nl - 4 + offset, size); 1675d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1676d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 1677d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case OR_LINKPL: 1678965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_absoffsetrel(cstate, &cstate->off_linkpl, cstate->off_nl + offset, size); 1679d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1680d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 1681d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case OR_LINKPL_NOSNAP: 1682965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_absoffsetrel(cstate, &cstate->off_linkpl, cstate->off_nl_nosnap + offset, size); 1683d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 1684d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 1685d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case OR_LINKTYPE: 1686965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_absoffsetrel(cstate, &cstate->off_linktype, offset, size); 1687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 1688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case OR_TRAN_IPV4: 1690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the X register with the length of the IPv4 header 1692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (plus the offset of the link-layer header, if it's 1693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * preceded by a variable-length header such as a radio 1694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header), in bytes. 1695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1696965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_loadx_iphdrlen(cstate); 1697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1699d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Load the item at {offset of the link-layer payload} + 1700d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * {offset, relative to the start of the link-layer 1701511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * paylod, of the IPv4 header} + {length of the IPv4 header} + 1702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * {specified offset}. 1703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1704d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * If the offset of the link-layer payload is variable, 1705d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the variable part of that offset is included in the 1706d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * value in the X register, and we include the constant 1707d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * part in the offset of the load. 1708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1709965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_LD|BPF_IND|size); 1710965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2->s.k = cstate->off_linkpl.constant_part + cstate->off_nl + offset; 1711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, s2); 1712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 1713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case OR_TRAN_IPV6: 1715965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_absoffsetrel(cstate, &cstate->off_linkpl, cstate->off_nl + 40 + offset, size); 1716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 1717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 1719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 1720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return NULL; 1721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return s; 1723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 1726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to load into the X register the sum of the length of 1727d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the IPv4 header and the variable part of the offset of the link-layer 1728d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * payload. 1729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist * 1731965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_loadx_iphdrlen(compiler_state_t *cstate) 1732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s, *s2; 1734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1735965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_abs_offset_varpart(cstate, &cstate->off_linkpl); 1736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (s != NULL) { 1737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1738d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * The offset of the link-layer payload has a variable 1739d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * part. "s" points to a list of statements that put 1740d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the variable part of that offset into the X register. 1741511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 1742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The 4*([k]&0xf) addressing mode can't be used, as we 1743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * don't have a constant offset, so we have to load the 1744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * value in question into the A register and add to it 1745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the value from the X register. 1746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1747965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_LD|BPF_IND|BPF_B); 1748965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2->s.k = cstate->off_linkpl.constant_part + cstate->off_nl; 1749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, s2); 1750965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ALU|BPF_AND|BPF_K); 1751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2->s.k = 0xf; 1752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, s2); 1753965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ALU|BPF_LSH|BPF_K); 1754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2->s.k = 2; 1755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, s2); 1756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1758d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * The A register now contains the length of the IP header. 1759d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * We need to add to it the variable part of the offset of 1760d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the link-layer payload, which is still in the X 1761511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * register, and move the result into the X register. 1762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1763965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sappend(s, new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_X)); 1764965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sappend(s, new_stmt(cstate, BPF_MISC|BPF_TAX)); 1765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 1766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1767d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * The offset of the link-layer payload is a constant, 1768d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * so no code was generated to load the (non-existent) 1769d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * variable part of that offset. 1770d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 1771d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * This means we can use the 4*([k]&0xf) addressing 1772d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * mode. Load the length of the IPv4 header, which 1773965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * is at an offset of cstate->off_nl from the beginning of 1774d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the link-layer payload, and thus at an offset of 1775965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * cstate->off_linkpl.constant_part + cstate->off_nl from the beginning 1776d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * of the raw packet data, using that addressing mode. 1777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1778965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_LDX|BPF_MSH|BPF_B); 1779965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s->s.k = cstate->off_linkpl.constant_part + cstate->off_nl; 1780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return s; 1782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 1785965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_uncond(compiler_state_t *cstate, int rsense) 1786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 1788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s; 1789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1790965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_LD|BPF_IMM); 1791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->s.k = !rsense; 1792965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = new_block(cstate, JMP(BPF_JEQ)); 1793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->stmts = s; 1794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 1796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct block * 1799965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_true(compiler_state_t *cstate) 1800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1801965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_uncond(cstate, 1); 1802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct block * 1805965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_false(compiler_state_t *cstate) 1806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1807965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_uncond(cstate, 0); 1808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 1811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Byte-swap a 32-bit number. 1812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ("htonl()" or "ntohl()" won't work - we want to byte-swap even on 1813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * big-endian platforms.) 1814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define SWAPLONG(y) \ 1816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) 1817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1818478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 1819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to match a particular packet type. 1820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP 1822478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * value, if <= ETHERMTU. We use that to determine whether to 1823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * match the type/length field or to check the type/length field for 1824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a value <= ETHERMTU to see whether it's a type field and then do 1825478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the appropriate test. 1826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 1828965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_ether_linktype(compiler_state_t *cstate, int proto) 1829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 1830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 1831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 1833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_ISONS: 1835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_IP: 1836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_NETBEUI: 1837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OSI protocols and NetBEUI always use 802.2 encapsulation, 1839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * so we check the DSAP and SSAP. 1840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LLCSAP_IP checks for IP-over-802.2, rather 1842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * than IP-over-Ethernet or IP-over-SNAP. 1843478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - should we check both the DSAP and the 1845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SSAP, like this, or should we check just the 1846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DSAP, as we do for other types <= ETHERMTU 1847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (i.e., other SAP values)? 1848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1849965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp_gt(cstate, OR_LINKTYPE, 0, BPF_H, ETHERMTU); 1850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b0); 1851965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, (bpf_int32) 1852478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ((proto << 8) | proto)); 1853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 1854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 1855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_IPX: 1857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for; 1859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet_II frames, which are Ethernet 1861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames with a frame type of ETHERTYPE_IPX; 1862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet_802.3 frames, which are 802.3 1864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames (i.e., the type/length field is 1865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a length field, <= ETHERMTU, rather than 1866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a type field) with the first two bytes 1867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * after the Ethernet/802.3 header being 1868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 0xFFFF; 1869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet_802.2 frames, which are 802.3 1871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames with an 802.2 LLC header and 1872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with the IPX LSAP as the DSAP in the LLC 1873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header; 1874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet_SNAP frames, which are 802.3 1876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames with an LLC header and a SNAP 1877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header and with an OUI of 0x000000 1878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (encapsulated Ethernet) and a protocol 1879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ID of ETHERTYPE_IPX in the SNAP header. 1880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - should we generate the same code both 1882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * for tests for LLCSAP_IPX and for ETHERTYPE_IPX? 1883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This generates code to check both for the 1887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * IPX LSAP (Ethernet_802.2) and for Ethernet_802.3. 1888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1889965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LLC, 0, BPF_B, (bpf_int32)LLCSAP_IPX); 1890965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, (bpf_int32)0xFFFF); 1891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 1892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now we add code to check for SNAP frames with 1895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ETHERTYPE_IPX, i.e. Ethernet_SNAP. 1896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1897965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_snap(cstate, 0x000000, ETHERTYPE_IPX); 1898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 1899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now we generate code to check for 802.3 1902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames in general. 1903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1904965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp_gt(cstate, OR_LINKTYPE, 0, BPF_H, ETHERMTU); 1905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b0); 1906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now add the check for 802.3 frames before the 1909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * check for Ethernet_802.2 and Ethernet_802.3, 1910478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as those checks should only be done on 802.3 1911478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames, not on Ethernet frames. 1912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 1914478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1915478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now add the check for Ethernet_II frames, and 1917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * do that before checking for the other frame 1918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * types. 1919478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1920965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)ETHERTYPE_IPX); 1921478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 1922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 1923478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1924478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_ATALK: 1925478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_AARP: 1926478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * EtherTalk (AppleTalk protocols on Ethernet link 1928478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * layer) may use 802.2 encapsulation. 1929478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1932478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for 802.2 encapsulation (EtherTalk phase 2?); 1933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we check for an Ethernet type field less than 1934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1500, which means it's an 802.3 length field. 1935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1936965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp_gt(cstate, OR_LINKTYPE, 0, BPF_H, ETHERMTU); 1937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b0); 1938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 802.2-encapsulated ETHERTYPE_ATALK packets are 1941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SNAP packets with an organization code of 1942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 0x080007 (Apple, for Appletalk) and a protocol 1943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * type of ETHERTYPE_ATALK (Appletalk). 1944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 802.2-encapsulated ETHERTYPE_AARP packets are 1946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SNAP packets with an organization code of 1947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 0x000000 (encapsulated Ethernet) and a protocol 1948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * type of ETHERTYPE_AARP (Appletalk ARP). 1949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == ETHERTYPE_ATALK) 1951965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_snap(cstate, 0x080007, ETHERTYPE_ATALK); 1952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else /* proto == ETHERTYPE_AARP */ 1953965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_snap(cstate, 0x000000, ETHERTYPE_AARP); 1954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 1955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for Ethernet encapsulation (Ethertalk 1958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * phase 1?); we just check for the Ethernet 1959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * protocol type. 1960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1961965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto); 1962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 1964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 1965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 1967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto <= ETHERMTU) { 1968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is an LLC SAP value, so the frames 1970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that match would be 802.2 frames. 1971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check that the frame is an 802.2 frame 1972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (i.e., that the length/type field is 1973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a length field, <= ETHERMTU) and 1974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * then check the DSAP. 1975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1976965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp_gt(cstate, OR_LINKTYPE, 0, BPF_H, ETHERMTU); 1977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b0); 1978965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp(cstate, OR_LINKTYPE, 2, BPF_B, (bpf_int32)proto); 1979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 1980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 1981478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 1982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 1983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is an Ethernet type, so compare 1984478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the length/type field with it (if 1985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the frame is an 802.2 frame, the length 1986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * field will be <= ETHERMTU, and, as 1987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto" is > ETHERMTU, this test 1988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * will fail and the frame won't match, 1989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * which is what we want). 1990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 1991965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, 1992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)proto); 1993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 1995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 1996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 1997965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic struct block * 1998965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_loopback_linktype(compiler_state_t *cstate, int proto) 1999965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes{ 2000965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 2001965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * For DLT_NULL, the link-layer header is a 32-bit word 2002965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * containing an AF_ value in *host* byte order, and for 2003965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * DLT_ENC, the link-layer header begins with a 32-bit 2004965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * word containing an AF_ value in host byte order. 2005965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 2006965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * In addition, if we're reading a saved capture file, 2007965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * the host byte order in the capture may not be the 2008965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * same as the host byte order on this machine. 2009965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 2010965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * For DLT_LOOP, the link-layer header is a 32-bit 2011965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * word containing an AF_ value in *network* byte order. 2012965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 2013965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->linktype == DLT_NULL || cstate->linktype == DLT_ENC) { 2014965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 2015965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * The AF_ value is in host byte order, but the BPF 2016965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * interpreter will convert it to network byte order. 2017965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 2018965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * If this is a save file, and it's from a machine 2019965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * with the opposite byte order to ours, we byte-swap 2020965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * the AF_ value. 2021965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 2022965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Then we run it through "htonl()", and generate 2023965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * code to compare against the result. 2024965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 2025965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->bpf_pcap->rfile != NULL && cstate->bpf_pcap->swapped) 2026965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes proto = SWAPLONG(proto); 2027965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes proto = htonl(proto); 2028965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes } 2029965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return (gen_cmp(cstate, OR_LINKHDR, 0, BPF_W, (bpf_int32)proto)); 2030965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes} 2031965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 2032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 2033511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * "proto" is an Ethernet type value and for IPNET, if it is not IPv4 2034511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * or IPv6 then we have an error. 2035511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2036511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct block * 2037965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_ipnet_linktype(compiler_state_t *cstate, int proto) 2038511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 2039511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (proto) { 2040511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2041511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case ETHERTYPE_IP: 2042965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, (bpf_int32)IPH_AF_INET); 2043511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NOTREACHED */ 2044511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2045511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case ETHERTYPE_IPV6: 2046965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, 2047511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (bpf_int32)IPH_AF_INET6); 2048511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NOTREACHED */ 2049511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2050511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 2051511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2052511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 2053511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2054965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_false(cstate); 2055511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 2056511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2057511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 2058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to match a particular packet type. 2059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP 2061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * value, if <= ETHERMTU. We use that to determine whether to 2062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * match the type field or to check the type field for the special 2063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LINUX_SLL_P_802_2 value and then do the appropriate test. 2064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2065478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 2066965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_linux_sll_linktype(compiler_state_t *cstate, int proto) 2067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 2068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 2069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 2071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_ISONS: 2073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_IP: 2074478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_NETBEUI: 2075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OSI protocols and NetBEUI always use 802.2 encapsulation, 2077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * so we check the DSAP and SSAP. 2078478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LLCSAP_IP checks for IP-over-802.2, rather 2080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * than IP-over-Ethernet or IP-over-SNAP. 2081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2082478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - should we check both the DSAP and the 2083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SSAP, like this, or should we check just the 2084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DSAP, as we do for other types <= ETHERMTU 2085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (i.e., other SAP values)? 2086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2087965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, LINUX_SLL_P_802_2); 2088965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, (bpf_int32) 2089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ((proto << 8) | proto)); 2090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 2091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 2092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_IPX: 2094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet_II frames, which are Ethernet 2096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames with a frame type of ETHERTYPE_IPX; 2097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet_802.3 frames, which have a frame 2099478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * type of LINUX_SLL_P_802_3; 2100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet_802.2 frames, which are 802.3 2102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames with an 802.2 LLC header (i.e, have 2103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a frame type of LINUX_SLL_P_802_2) and 2104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with the IPX LSAP as the DSAP in the LLC 2105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header; 2106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet_SNAP frames, which are 802.3 2108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames with an LLC header and a SNAP 2109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header and with an OUI of 0x000000 2110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (encapsulated Ethernet) and a protocol 2111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ID of ETHERTYPE_IPX in the SNAP header. 2112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * First, do the checks on LINUX_SLL_P_802_2 2114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames; generate the check for either 2115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet_802.2 or Ethernet_SNAP frames, and 2116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * then put a check for LINUX_SLL_P_802_2 frames 2117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * before it. 2118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2119965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LLC, 0, BPF_B, (bpf_int32)LLCSAP_IPX); 2120965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_snap(cstate, 0x000000, ETHERTYPE_IPX); 2121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 2122965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, LINUX_SLL_P_802_2); 2123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 2124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now check for 802.3 frames and OR that with 2127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the previous test. 2128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2129965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, LINUX_SLL_P_802_3); 2130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 2131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now add the check for Ethernet_II frames, and 2134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * do that before checking for the other frame 2135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * types. 2136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2137965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)ETHERTYPE_IPX); 2138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 2139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 2140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_ATALK: 2142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_AARP: 2143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * EtherTalk (AppleTalk protocols on Ethernet link 2145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * layer) may use 802.2 encapsulation. 2146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for 802.2 encapsulation (EtherTalk phase 2?); 2150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we check for the 802.2 protocol type in the 2151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "Ethernet type" field. 2152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2153965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, LINUX_SLL_P_802_2); 2154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 802.2-encapsulated ETHERTYPE_ATALK packets are 2157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SNAP packets with an organization code of 2158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 0x080007 (Apple, for Appletalk) and a protocol 2159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * type of ETHERTYPE_ATALK (Appletalk). 2160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 802.2-encapsulated ETHERTYPE_AARP packets are 2162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SNAP packets with an organization code of 2163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 0x000000 (encapsulated Ethernet) and a protocol 2164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * type of ETHERTYPE_AARP (Appletalk ARP). 2165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == ETHERTYPE_ATALK) 2167965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_snap(cstate, 0x080007, ETHERTYPE_ATALK); 2168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else /* proto == ETHERTYPE_AARP */ 2169965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_snap(cstate, 0x000000, ETHERTYPE_AARP); 2170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 2171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for Ethernet encapsulation (Ethertalk 2174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * phase 1?); we just check for the Ethernet 2175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * protocol type. 2176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2177965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto); 2178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 2180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 2181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 2183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto <= ETHERMTU) { 2184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is an LLC SAP value, so the frames 2186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that match would be 802.2 frames. 2187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for the 802.2 protocol type 2188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in the "Ethernet type" field, and 2189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * then check the DSAP. 2190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2191965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, LINUX_SLL_P_802_2); 2192965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp(cstate, OR_LINKHDR, cstate->off_linkpl.constant_part, BPF_B, 2193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)proto); 2194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 2195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 2196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 2197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is an Ethernet type, so compare 2199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the length/type field with it (if 2200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the frame is an 802.2 frame, the length 2201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * field will be <= ETHERMTU, and, as 2202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto" is > ETHERMTU, this test 2203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * will fail and the frame won't match, 2204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * which is what we want). 2205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2206965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto); 2207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 2208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 2209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 2210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2211511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist * 2212965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_load_prism_llprefixlen(compiler_state_t *cstate) 2213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 2214511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *s1, *s2; 2215511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *sjeq_avs_cookie; 2216511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *sjcommon; 2217511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2218511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2219511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * This code is not compatible with the optimizer, as 2220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * we are generating jmp instructions within a normal 2221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * slist of instructions 2222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2223965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->no_optimize = 1; 2224511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2225511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2226511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Generate code to load the length of the radio header into 2227511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the register assigned to hold that length, if one has been 2228511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * assigned. (If one hasn't been assigned, no code we've 2229511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * generated uses that prefix, so we don't need to generate any 2230511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * code to load it.) 2231511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 2232511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Some Linux drivers use ARPHRD_IEEE80211_PRISM but sometimes 2233511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * or always use the AVS header rather than the Prism header. 2234511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * We load a 4-byte big-endian value at the beginning of the 2235511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * raw packet data, and see whether, when masked with 0xFFFFF000, 2236511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * it's equal to 0x80211000. If so, that indicates that it's 2237511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * an AVS header (the masked-out bits are the version number). 2238511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Otherwise, it's a Prism header. 2239511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 2240511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * XXX - the Prism header is also, in theory, variable-length, 2241511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * but no known software generates headers that aren't 144 2242511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * bytes long. 2243511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2244965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_linkhdr.reg != -1) { 2245511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2246511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Load the cookie. 2247511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2248965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_LD|BPF_W|BPF_ABS); 2249511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s1->s.k = 0; 2250511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2251511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2252511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * AND it with 0xFFFFF000. 2253511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2254965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ALU|BPF_AND|BPF_K); 2255511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 0xFFFFF000; 2256511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s1, s2); 2257511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2258511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2259511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Compare with 0x80211000. 2260511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2261965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjeq_avs_cookie = new_stmt(cstate, JMP(BPF_JEQ)); 2262511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjeq_avs_cookie->s.k = 0x80211000; 2263511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s1, sjeq_avs_cookie); 2264511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2265511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2266511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If it's AVS: 2267511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 2268511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * The 4 bytes at an offset of 4 from the beginning of 2269511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the AVS header are the length of the AVS header. 2270511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * That field is big-endian. 2271511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2272965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_LD|BPF_W|BPF_ABS); 2273511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 4; 2274511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s1, s2); 2275511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjeq_avs_cookie->s.jt = s2; 2276511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2277511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2278511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now jump to the code to allocate a register 2279511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * into which to save the header length and 2280511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * store the length there. (The "jump always" 2281511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * instruction needs to have the k field set; 2282511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * it's added to the PC, so, as we're jumping 2283511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * over a single instruction, it should be 1.) 2284511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2285965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjcommon = new_stmt(cstate, JMP(BPF_JA)); 2286511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjcommon->s.k = 1; 2287511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s1, sjcommon); 2288511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2289511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2290511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now for the code that handles the Prism header. 2291511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Just load the length of the Prism header (144) 2292511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * into the A register. Have the test for an AVS 2293511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * header branch here if we don't have an AVS header. 2294511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2295965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_LD|BPF_W|BPF_IMM); 2296511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 144; 2297511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s1, s2); 2298511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjeq_avs_cookie->s.jf = s2; 2299511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2300511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2301511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now allocate a register to hold that value and store 2302511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * it. The code for the AVS header will jump here after 2303511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * loading the length of the AVS header. 2304511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2305965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ST); 2306965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2->s.k = cstate->off_linkhdr.reg; 2307511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s1, s2); 2308511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjcommon->s.jf = s2; 2309511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2310511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2311511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now move it into the X register. 2312511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2313965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_MISC|BPF_TAX); 2314511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s1, s2); 2315511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2316511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (s1); 2317511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else 2318511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (NULL); 2319511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 2320511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2321511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist * 2322965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_load_avs_llprefixlen(compiler_state_t *cstate) 2323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 2324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s1, *s2; 2325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2327511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Generate code to load the length of the AVS header into 2328511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the register assigned to hold that length, if one has been 2329511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * assigned. (If one hasn't been assigned, no code we've 2330511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * generated uses that prefix, so we don't need to generate any 2331511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * code to load it.) 2332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2333965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_linkhdr.reg != -1) { 2334511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2335511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * The 4 bytes at an offset of 4 from the beginning of 2336511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the AVS header are the length of the AVS header. 2337511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * That field is big-endian. 2338511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2339965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_LD|BPF_W|BPF_ABS); 2340511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s1->s.k = 4; 2341511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2342511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2343511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now allocate a register to hold that value and store 2344511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * it. 2345511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2346965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ST); 2347965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2->s.k = cstate->off_linkhdr.reg; 2348511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s1, s2); 2349511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2350511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2351511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now move it into the X register. 2352511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2353965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_MISC|BPF_TAX); 2354511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s1, s2); 2355511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2356511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (s1); 2357511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else 2358511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (NULL); 2359511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 2360511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2361511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist * 2362965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_load_radiotap_llprefixlen(compiler_state_t *cstate) 2363511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 2364511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *s1, *s2; 2365511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2366511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2367511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Generate code to load the length of the radiotap header into 2368511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the register assigned to hold that length, if one has been 2369511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * assigned. (If one hasn't been assigned, no code we've 2370511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * generated uses that prefix, so we don't need to generate any 2371511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * code to load it.) 2372511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2373965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_linkhdr.reg != -1) { 2374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The 2 bytes at offsets of 2 and 3 from the beginning 2376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of the radiotap header are the length of the radiotap 2377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header; unfortunately, it's little-endian, so we have 2378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to load it a byte at a time and construct the value. 2379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the high-order byte, at an offset of 3, shift it 2383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * left a byte, and put the result in the X register. 2384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2385965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS); 2386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s1->s.k = 3; 2387965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ALU|BPF_LSH|BPF_K); 2388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2->s.k = 8; 2390965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_MISC|BPF_TAX); 2391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the next byte, at an offset of 2, and OR the 2395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * value from the X register into it. 2396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2397965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS); 2398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2->s.k = 2; 2400965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ALU|BPF_OR|BPF_X); 2401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now allocate a register to hold that value and store 2405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * it. 2406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2407965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ST); 2408965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2->s.k = cstate->off_linkhdr.reg; 2409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now move it into the X register. 2413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2414965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_MISC|BPF_TAX); 2415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2417511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (s1); 2418511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else 2419511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (NULL); 2420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 2421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2422d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* 2423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * At the moment we treat PPI as normal Radiotap encoded 2424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * packets. The difference is in the function that generates 2425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the code at the beginning to compute the header length. 2426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Since this code generator of PPI supports bare 802.11 2427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * encapsulation only (i.e. the encapsulated DLT should be 2428511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * DLT_IEEE802_11) we generate code to check for this too; 2429511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * that's done in finish_parse(). 2430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2431511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist * 2432965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_load_ppi_llprefixlen(compiler_state_t *cstate) 2433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 2434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s1, *s2; 2435d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2437511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Generate code to load the length of the radiotap header 2438511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * into the register assigned to hold that length, if one has 2439511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * been assigned. 2440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2441965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_linkhdr.reg != -1) { 2442511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The 2 bytes at offsets of 2 and 3 from the beginning 2444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of the radiotap header are the length of the radiotap 2445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header; unfortunately, it's little-endian, so we have 2446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to load it a byte at a time and construct the value. 2447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the high-order byte, at an offset of 3, shift it 2451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * left a byte, and put the result in the X register. 2452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2453965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS); 2454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s1->s.k = 3; 2455965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ALU|BPF_LSH|BPF_K); 2456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2->s.k = 8; 2458965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_MISC|BPF_TAX); 2459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the next byte, at an offset of 2, and OR the 2463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * value from the X register into it. 2464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2465965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS); 2466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s2->s.k = 2; 2468965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ALU|BPF_OR|BPF_X); 2469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now allocate a register to hold that value and store 2473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * it. 2474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2475965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ST); 2476965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2->s.k = cstate->off_linkhdr.reg; 2477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now move it into the X register. 2481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2482965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_MISC|BPF_TAX); 2483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 2484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2485511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (s1); 2486511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else 2487511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (NULL); 2488511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 2489511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2490511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 2491511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Load a value relative to the beginning of the link-layer header after the 802.11 2492511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * header, i.e. LLC_SNAP. 2493511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * The link-layer header doesn't necessarily begin at the beginning 2494511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * of the packet data; there might be a variable-length prefix containing 2495511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * radio information. 2496511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2497511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist * 2498965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_load_802_11_header_len(compiler_state_t *cstate, struct slist *s, struct slist *snext) 2499511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 2500511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *s2; 2501511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *sjset_data_frame_1; 2502511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *sjset_data_frame_2; 2503511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *sjset_qos; 2504965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes struct slist *sjset_radiotap_flags_present; 2505965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes struct slist *sjset_radiotap_ext_present; 2506965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes struct slist *sjset_radiotap_tsft_present; 2507511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *sjset_tsft_datapad, *sjset_notsft_datapad; 2508511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *s_roundup; 2509511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2510965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_linkpl.reg == -1) { 2511511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2512511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * No register has been assigned to the offset of 2513d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the link-layer payload, which means nobody needs 2514511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * it; don't bother computing it - just return 2515511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * what we already have. 2516511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2517511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (s); 2518511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 2519511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2520511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2521511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * This code is not compatible with the optimizer, as 2522511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * we are generating jmp instructions within a normal 2523511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * slist of instructions 2524511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2525965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->no_optimize = 1; 2526d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2527511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2528511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If "s" is non-null, it has code to arrange that the X register 2529511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * contains the length of the prefix preceding the link-layer 2530511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * header. 2531511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 2532511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Otherwise, the length of the prefix preceding the link-layer 2533d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * header is "off_outermostlinkhdr.constant_part". 2534511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2535511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (s == NULL) { 2536511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2537511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * There is no variable-length header preceding the 2538511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * link-layer header. 2539511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 2540511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Load the length of the fixed-length prefix preceding 2541511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the link-layer header (if any) into the X register, 2542965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * and store it in the cstate->off_linkpl.reg register. 2543d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * That length is off_outermostlinkhdr.constant_part. 2544511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2545965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_LDX|BPF_IMM); 2546965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s->s.k = cstate->off_outermostlinkhdr.constant_part; 2547511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 2548511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2549511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2550511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * The X register contains the offset of the beginning of the 2551511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * link-layer header; add 24, which is the minimum length 2552511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * of the MAC header for a data frame, to that, and store it 2553965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * in cstate->off_linkpl.reg, and then load the Frame Control field, 2554511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * which is at the offset in the X register, with an indexed load. 2555511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2556965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_MISC|BPF_TXA); 2557511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2558965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_K); 2559511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 24; 2560511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2561965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ST); 2562965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2->s.k = cstate->off_linkpl.reg; 2563511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2564511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2565965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_LD|BPF_IND|BPF_B); 2566511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 0; 2567511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2568511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2569511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2570511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Check the Frame Control field to see if this is a data frame; 2571511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * a data frame has the 0x08 bit (b3) in that field set and the 2572511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 0x04 bit (b2) clear. 2573511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2574965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_data_frame_1 = new_stmt(cstate, JMP(BPF_JSET)); 2575511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_data_frame_1->s.k = 0x08; 2576511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, sjset_data_frame_1); 2577d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2578511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2579511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If b3 is set, test b2, otherwise go to the first statement of 2580511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the rest of the program. 2581511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2582965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_data_frame_1->s.jt = sjset_data_frame_2 = new_stmt(cstate, JMP(BPF_JSET)); 2583511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_data_frame_2->s.k = 0x04; 2584511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, sjset_data_frame_2); 2585511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_data_frame_1->s.jf = snext; 2586511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2587511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2588511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If b2 is not set, this is a data frame; test the QoS bit. 2589511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Otherwise, go to the first statement of the rest of the 2590511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * program. 2591511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2592511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_data_frame_2->s.jt = snext; 2593965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_data_frame_2->s.jf = sjset_qos = new_stmt(cstate, JMP(BPF_JSET)); 2594511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_qos->s.k = 0x80; /* QoS bit */ 2595511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, sjset_qos); 2596d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2597511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2598965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * If it's set, add 2 to cstate->off_linkpl.reg, to skip the QoS 2599511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * field. 2600511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Otherwise, go to the first statement of the rest of the 2601511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * program. 2602511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2603965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_qos->s.jt = s2 = new_stmt(cstate, BPF_LD|BPF_MEM); 2604965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2->s.k = cstate->off_linkpl.reg; 2605511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2606965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_IMM); 2607511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 2; 2608511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2609965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ST); 2610965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2->s.k = cstate->off_linkpl.reg; 2611511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2612511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2613511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2614511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If we have a radiotap header, look at it to see whether 2615511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * there's Atheros padding between the MAC-layer header 2616511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * and the payload. 2617511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 2618511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Note: all of the fields in the radiotap header are 2619511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * little-endian, so we byte-swap all of the values 2620511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * we test against, as they will be loaded as big-endian 2621511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * values. 2622965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 2623965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * XXX - in the general case, we would have to scan through 2624965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * *all* the presence bits, if there's more than one word of 2625965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * presence bits. That would require a loop, meaning that 2626965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * we wouldn't be able to run the filter in the kernel. 2627965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 2628965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * We assume here that the Atheros adapters that insert the 2629965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * annoying padding don't have multiple antennae and therefore 2630965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * do not generate radiotap headers with multiple presence words. 2631511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2632965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->linktype == DLT_IEEE802_11_RADIO) { 2633511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2634511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Is the IEEE80211_RADIOTAP_FLAGS bit (0x0000002) set 2635965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * in the first presence flag word? 2636511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2637965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_qos->s.jf = s2 = new_stmt(cstate, BPF_LD|BPF_ABS|BPF_W); 2638511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 4; 2639511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2640511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2641965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_radiotap_flags_present = new_stmt(cstate, JMP(BPF_JSET)); 2642965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_radiotap_flags_present->s.k = SWAPLONG(0x00000002); 2643965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sappend(s, sjset_radiotap_flags_present); 2644511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2645511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2646511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If not, skip all of this. 2647511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2648965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_radiotap_flags_present->s.jf = snext; 2649965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 2650965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 2651965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Otherwise, is the "extension" bit set in that word? 2652965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 2653965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_radiotap_ext_present = new_stmt(cstate, JMP(BPF_JSET)); 2654965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_radiotap_ext_present->s.k = SWAPLONG(0x80000000); 2655965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sappend(s, sjset_radiotap_ext_present); 2656965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_radiotap_flags_present->s.jt = sjset_radiotap_ext_present; 2657965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 2658965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 2659965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * If so, skip all of this. 2660965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 2661965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_radiotap_ext_present->s.jt = snext; 2662511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2663511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2664511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Otherwise, is the IEEE80211_RADIOTAP_TSFT bit set? 2665511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2666965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_radiotap_tsft_present = new_stmt(cstate, JMP(BPF_JSET)); 2667965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_radiotap_tsft_present->s.k = SWAPLONG(0x00000001); 2668965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sappend(s, sjset_radiotap_tsft_present); 2669965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_radiotap_ext_present->s.jf = sjset_radiotap_tsft_present; 2670511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2671511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2672511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If IEEE80211_RADIOTAP_TSFT is set, the flags field is 2673511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * at an offset of 16 from the beginning of the raw packet 2674511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * data (8 bytes for the radiotap header and 8 bytes for 2675511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the TSFT field). 2676511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 2677511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Test whether the IEEE80211_RADIOTAP_F_DATAPAD bit (0x20) 2678511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * is set. 2679511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2680965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_LD|BPF_ABS|BPF_B); 2681511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 16; 2682511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2683965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_radiotap_tsft_present->s.jt = s2; 2684511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2685965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_tsft_datapad = new_stmt(cstate, JMP(BPF_JSET)); 2686511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_tsft_datapad->s.k = 0x20; 2687511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, sjset_tsft_datapad); 2688511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2689511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2690511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If IEEE80211_RADIOTAP_TSFT is not set, the flags field is 2691511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * at an offset of 8 from the beginning of the raw packet 2692511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * data (8 bytes for the radiotap header). 2693511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 2694511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Test whether the IEEE80211_RADIOTAP_F_DATAPAD bit (0x20) 2695511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * is set. 2696511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2697965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_LD|BPF_ABS|BPF_B); 2698511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 8; 2699511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2700965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_radiotap_tsft_present->s.jf = s2; 2701511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2702965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sjset_notsft_datapad = new_stmt(cstate, JMP(BPF_JSET)); 2703511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_notsft_datapad->s.k = 0x20; 2704511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, sjset_notsft_datapad); 2705511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 2707511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * In either case, if IEEE80211_RADIOTAP_F_DATAPAD is 2708511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * set, round the length of the 802.11 header to 2709511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * a multiple of 4. Do that by adding 3 and then 2710511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * dividing by and multiplying by 4, which we do by 2711511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * ANDing with ~3. 2712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2713965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s_roundup = new_stmt(cstate, BPF_LD|BPF_MEM); 2714965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s_roundup->s.k = cstate->off_linkpl.reg; 2715511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s_roundup); 2716965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_IMM); 2717511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = 3; 2718511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2719965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ALU|BPF_AND|BPF_IMM); 2720511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s2->s.k = ~3; 2721511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2722965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ST); 2723965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2->s.k = cstate->off_linkpl.reg; 2724511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, s2); 2725511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2726511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_tsft_datapad->s.jt = s_roundup; 2727511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_tsft_datapad->s.jf = snext; 2728511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_notsft_datapad->s.jt = s_roundup; 2729511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_notsft_datapad->s.jf = snext; 2730511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else 2731511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sjset_qos->s.jf = snext; 2732511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2733511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return s; 2734511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 2735511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2736511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void 2737965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesinsert_compute_vloffsets(compiler_state_t *cstate, struct block *b) 2738511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 2739511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *s; 2740511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2741d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* There is an implicit dependency between the link 2742d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * payload and link header since the payload computation 2743d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * includes the variable part of the header. Therefore, 2744d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * if nobody else has allocated a register for the link 2745d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * header and we need it, do it now. */ 2746965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_linkpl.reg != -1 && cstate->off_linkhdr.is_variable && 2747965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkhdr.reg == -1) 2748965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkhdr.reg = alloc_reg(cstate); 2749d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2750511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2751511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For link-layer types that have a variable-length header 2752511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * preceding the link-layer header, generate code to load 2753511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the offset of the link-layer header into the register 2754511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * assigned to that offset, if any. 2755d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 2756d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * XXX - this, and the next switch statement, won't handle 2757d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * encapsulation of 802.11 or 802.11+radio information in 2758d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * some other protocol stack. That's significantly more 2759d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * complicated. 2760511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2761965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes switch (cstate->outermostlinktype) { 2762511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2763511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 2764965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_prism_llprefixlen(cstate); 2765511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2766511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2767511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO_AVS: 2768965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_avs_llprefixlen(cstate); 2769511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2770511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2771511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO: 2772965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_radiotap_llprefixlen(cstate); 2773511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2774511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2775511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PPI: 2776965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_ppi_llprefixlen(cstate); 2777511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2779511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 2780511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s = NULL; 2781511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2782511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 2783511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2784511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2785511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For link-layer types that have a variable-length link-layer 2786d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * header, generate code to load the offset of the link-layer 2787511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * payload into the register assigned to that offset, if any. 2788511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2789965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes switch (cstate->outermostlinktype) { 2790511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2791511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11: 2792511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 2793511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO_AVS: 2794511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO: 2795511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PPI: 2796965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_802_11_header_len(cstate, s, b->stmts); 2797511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2798511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 2799511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2800511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2801511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If we have any offset-loading code, append all the 2802511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * existing statements in the block to those statements, 2803511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * and make the resulting list the list of statements 2804511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * for the block. 2805511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2806511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (s != NULL) { 2807511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sappend(s, b->stmts); 2808511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b->stmts = s; 2809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 2810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 2811511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 2813965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_ppi_dlt_check(compiler_state_t *cstate) 2814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 2815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s_load_dlt; 2816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 2817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2818965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->linktype == DLT_PPI) 2819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project { 2820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Create the statements that check for the DLT 2821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2822965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s_load_dlt = new_stmt(cstate, BPF_LD|BPF_W|BPF_ABS); 2823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s_load_dlt->s.k = 4; 2824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2825965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = new_block(cstate, JMP(BPF_JEQ)); 2826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->stmts = s_load_dlt; 2828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->s.k = SWAPLONG(DLT_IEEE802_11); 2829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 2830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 2831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project { 2832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = NULL; 2833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 2834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 2836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 2837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 2839d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Take an absolute offset, and: 2840d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 2841d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * if it has no variable part, return NULL; 2842d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 2843d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * if it has a variable part, generate code to load the register 2844d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * containing that variable part into the X register, returning 2845d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * a pointer to that code - if no register for that offset has 2846d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * been allocated, allocate it first. 2847d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 2848d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * (The code to set that register will be generated later, but will 2849d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * be placed earlier in the code sequence.) 2850511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2851511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist * 2852965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_abs_offset_varpart(compiler_state_t *cstate, bpf_abs_offset *off) 2853511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 2854511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *s; 2855511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2856d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (off->is_variable) { 2857d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (off->reg == -1) { 2858511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2859d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * We haven't yet assigned a register for the 2860d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * variable part of the offset of the link-layer 2861d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * header; allocate one. 2862511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2863965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes off->reg = alloc_reg(cstate); 2864511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 2865511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2866511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2867d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Load the register containing the variable part of the 2868d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * offset of the link-layer header into the X register. 2869511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2870965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_LDX|BPF_MEM); 2871d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s->s.k = off->reg; 2872511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return s; 2873511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else { 2874511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2875d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * That offset isn't variable, there's no variable part, 2876d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * so we don't need to generate any code. 2877511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2878511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return NULL; 2879511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 2880511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 2881511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2882511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 2883511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Map an Ethernet type to the equivalent PPP type. 2884511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2885511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int 2886511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallethertype_to_ppptype(proto) 2887511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int proto; 2888511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 2889511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (proto) { 2890511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2891511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case ETHERTYPE_IP: 2892511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = PPP_IP; 2893511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2894511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2895511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case ETHERTYPE_IPV6: 2896511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = PPP_IPV6; 2897511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2898511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2899511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case ETHERTYPE_DN: 2900511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = PPP_DECNET; 2901511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2902511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2903511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case ETHERTYPE_ATALK: 2904511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = PPP_APPLE; 2905511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2906511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2907511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case ETHERTYPE_NS: 2908511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = PPP_NS; 2909511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2910511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2911511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case LLCSAP_ISONS: 2912511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = PPP_OSI; 2913511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2914511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2915511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case LLCSAP_8021D: 2916511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 2917511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * I'm assuming the "Bridging PDU"s that go 2918511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * over PPP are Spanning Tree Protocol 2919511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Bridging PDUs. 2920511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 2921511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = PPP_BRPDU; 2922511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2923511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2924511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case LLCSAP_IPX: 2925511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = PPP_IPX; 2926511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 2927511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 2928511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (proto); 2929511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 2930511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 2931511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 2932d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Generate any tests that, for encapsulation of a link-layer packet 2933d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * inside another protocol stack, need to be done to check for those 2934d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * link-layer packets (and that haven't already been done by a check 2935d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * for that encapsulation). 2936d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 2937d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct block * 2938965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_prevlinkhdr_check(compiler_state_t *cstate) 2939d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 2940d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0; 2941d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2942965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->is_geneve) 2943965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_geneve_ll_check(cstate); 2944d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2945965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes switch (cstate->prevlinktype) { 2946d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2947d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_SUNATM: 2948d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 2949d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * This is LANE-encapsulated Ethernet; check that the LANE 2950d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * packet doesn't begin with an LE Control marker, i.e. 2951d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * that it's data, not a control message. 2952d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 2953d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * (We've already generated a test for LANE.) 2954d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 2955965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_PREVLINKHDR, SUNATM_PKT_BEGIN_POS, BPF_H, 0xFF00); 2956d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_not(b0); 2957d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b0; 2958d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2959d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes default: 2960d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 2961d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * No such tests are necessary. 2962d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 2963d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return NULL; 2964d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 2965d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /*NOTREACHED*/ 2966d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 2967d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 2968d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* 2969965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * The three different values we should check for when checking for an 2970965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * IPv6 packet with DLT_NULL. 2971965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 2972965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#define BSD_AFNUM_INET6_BSD 24 /* NetBSD, OpenBSD, BSD/OS, Npcap */ 2973965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#define BSD_AFNUM_INET6_FREEBSD 28 /* FreeBSD */ 2974965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#define BSD_AFNUM_INET6_DARWIN 30 /* OS X, iOS, other Darwin-based OSes */ 2975965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 2976965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes/* 2977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to match a particular packet type by matching the 2978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * link-layer type field or fields in the 802.2 LLC header. 2979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP 2981478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * value, if <= ETHERMTU. 2982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 2983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 2984965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_linktype(compiler_state_t *cstate, int proto) 2985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 2986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *b2; 2987d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes const char *description; 2988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* are we checking MPLS-encapsulated packets? */ 2990965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->label_stack_depth > 0) { 2991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 2992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IP: 2993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case PPP_IP: 2994511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* FIXME add other L3 proto IDs */ 2995965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_mpls_linktype(cstate, Q_IP); 2996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 2997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IPV6: 2998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case PPP_IPV6: 2999511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* FIXME add other L3 proto IDs */ 3000965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_mpls_linktype(cstate, Q_IPV6); 3001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 3003965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "unsupported protocol over mpls"); 3004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 3005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3008965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes switch (cstate->linktype) { 3009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_EN10MB: 3011511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER: 3012511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER_TRANSPARENT: 3013d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Geneve has an EtherType regardless of whether there is an 3014d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * L2 header. */ 3015965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (!cstate->is_geneve) 3016965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_prevlinkhdr_check(cstate); 3017d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes else 3018d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = NULL; 3019d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3020965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_ether_linktype(cstate, proto); 3021d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (b0 != NULL) 3022d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 3023d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 3024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 3025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_C_HDLC: 3028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 3029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_ISONS: 3031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = (proto << 8 | LLCSAP_ISONS); 3032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* fall through */ 3033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 3035965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto); 3036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 3037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802_11: 3042511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 3043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802_11_RADIO_AVS: 3044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802_11_RADIO: 3045511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PPI: 3046511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 3047511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Check that we have a data frame. 3048511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 3049965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_check_802_11_data_frame(cstate); 3050511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3051511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 3052511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now check for the specified link-layer type. 3053511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 3054965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_llc_linktype(cstate, proto); 3055511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b0, b1); 3056511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return b1; 3057511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /*NOTREACHED*/ 3058511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3059511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3060511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_FDDI: 3061511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 3062d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * XXX - check for LLC frames. 3063511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 3064965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_llc_linktype(cstate, proto); 3065511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /*NOTREACHED*/ 3066511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3067511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3068511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802: 3069511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 3070511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * XXX - check for LLC PDUs, as per IEEE 802.5. 3071511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 3072965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_llc_linktype(cstate, proto); 3073511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /*NOTREACHED*/ 3074511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3075511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ATM_RFC1483: 3077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ATM_CLIP: 3078478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IP_OVER_FC: 3079965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_llc_linktype(cstate, proto); 3080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 3081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3082478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_SUNATM: 3084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3085d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Check for an LLC-encapsulated version of this protocol; 3086d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * if we were checking for LANE, linktype would no longer 3087d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * be DLT_SUNATM. 3088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3089d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Check for LLC encapsulation and then check the protocol. 3090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3091965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_atmfield_code(cstate, A_PROTOTYPE, PT_LLC, BPF_JEQ, 0); 3092965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_llc_linktype(cstate, proto); 3093d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 3094d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 3095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 3096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_LINUX_SLL: 3099965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_linux_sll_linktype(cstate, proto); 3100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 3101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_SLIP: 3104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_SLIP_BSDOS: 3105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_RAW: 3106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * These types don't provide any type field; packets 3108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * are always IPv4 or IPv6. 3109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - for IPv4, check for a version number of 4, and, 3111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * for IPv6, check for a version number of 6? 3112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 3114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IP: 3116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Check for a version number of 4. */ 3117965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, 0x40, 0xF0); 3118511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IPV6: 3120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Check for a version number of 6. */ 3121965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, 0x60, 0xF0); 3122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 3124965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_false(cstate); /* always false */ 3125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 3127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3129511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IPV4: 3130511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 3131511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Raw IPv4, so no type field. 3132511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 3133511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (proto == ETHERTYPE_IP) 3134965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_true(cstate); /* always true */ 3135511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3136511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Checking for something other than IPv4; always false */ 3137965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_false(cstate); 3138511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /*NOTREACHED*/ 3139511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3140511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3141511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IPV6: 3142511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 3143511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Raw IPv6, so no type field. 3144511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 3145511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (proto == ETHERTYPE_IPV6) 3146965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_true(cstate); /* always true */ 3147511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3148511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Checking for something other than IPv6; always false */ 3149965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_false(cstate); 3150511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /*NOTREACHED*/ 3151511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3152511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP: 3154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP_PPPD: 3155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP_SERIAL: 3156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP_ETHER: 3157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We use Ethernet protocol types inside libpcap; 3159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * map them to the corresponding PPP protocol types. 3160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3161511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = ethertype_to_ppptype(proto); 3162965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto); 3163511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /*NOTREACHED*/ 3164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP_BSDOS: 3167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We use Ethernet protocol types inside libpcap; 3169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * map them to the corresponding PPP protocol types. 3170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 3172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IP: 3174511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 3175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Also check for Van Jacobson-compressed IP. 3176511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * XXX - do this for other forms of PPP? 3177511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 3178965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, PPP_IP); 3179965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, PPP_VJC); 3180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 3181965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, PPP_VJNC); 3182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, b0); 3183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 3184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3185511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 3186511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = ethertype_to_ppptype(proto); 3187965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, 3188511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (bpf_int32)proto); 3189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3190511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /*NOTREACHED*/ 3191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_NULL: 3194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_LOOP: 3195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ENC: 3196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 3197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IP: 3199965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return (gen_loopback_linktype(cstate, AF_INET)); 3200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IPV6: 3202965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 3203965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * AF_ values may, unfortunately, be platform- 3204965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * dependent; AF_INET isn't, because everybody 3205965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * used 4.2BSD's value, but AF_INET6 is, because 3206965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 4.2BSD didn't have a value for it (given that 3207965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * IPv6 didn't exist back in the early 1980's), 3208965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * and they all picked their own values. 3209965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 3210965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * This means that, if we're reading from a 3211965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * savefile, we need to check for all the 3212965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * possible values. 3213965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * 3214965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * If we're doing a live capture, we only need 3215965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * to check for this platform's value; however, 3216965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Npcap uses 24, which isn't Windows's AF_INET6 3217965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * value. (Given the multiple different values, 3218965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * programs that read pcap files shouldn't be 3219965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * checking for their platform's AF_INET6 value 3220965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * anyway, they should check for all of the 3221965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * possible values. and they might as well do 3222965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * that even for live captures.) 3223965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 3224965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->bpf_pcap->rfile != NULL) { 3225965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 3226965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Savefile - check for all three 3227965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * possible IPv6 values. 3228965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 3229965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_loopback_linktype(cstate, BSD_AFNUM_INET6_BSD); 3230965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_loopback_linktype(cstate, BSD_AFNUM_INET6_FREEBSD); 3231965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes gen_or(b0, b1); 3232965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_loopback_linktype(cstate, BSD_AFNUM_INET6_DARWIN); 3233965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes gen_or(b0, b1); 3234965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return (b1); 3235965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes } else { 3236965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 3237965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Live capture, so we only need to 3238965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * check for the value used on this 3239965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * platform. 3240965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 3241965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifdef _WIN32 3242965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 3243965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Npcap doesn't use Windows's AF_INET6, 3244965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * as that collides with AF_IPX on 3245965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * some BSDs (both have the value 23). 3246965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Instead, it uses 24. 3247965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 3248965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return (gen_loopback_linktype(cstate, 24)); 3249965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#else /* _WIN32 */ 3250965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifdef AF_INET6 3251965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return (gen_loopback_linktype(cstate, AF_INET6)); 3252965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#else /* AF_INET6 */ 3253965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 3254965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * I guess this platform doesn't support 3255965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * IPv6, so we just reject all packets. 3256965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 3257965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_false(cstate); 3258965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif /* AF_INET6 */ 3259965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif /* _WIN32 */ 3260965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes } 3261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 3263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Not a type on which we support filtering. 3265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - support those that have AF_ values 3266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * #defined on this platform, at least? 3267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3268965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_false(cstate); 3269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_NET_PFVAR_H 3272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PFLOG: 3273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * af field is host byte order in contrast to the rest of 3275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the packet. 3276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == ETHERTYPE_IP) 3278965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return (gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, af), 3279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project BPF_B, (bpf_int32)AF_INET)); 3280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (proto == ETHERTYPE_IPV6) 3281965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return (gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, af), 3282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project BPF_B, (bpf_int32)AF_INET6)); 3283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 3284965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_false(cstate); 3285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 3286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_NET_PFVAR_H */ 3288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ARCNET: 3290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_ARCNET_LINUX: 3291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX should we check for first fragment if the protocol 3293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * uses PHDS? 3294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 3296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 3298965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_false(cstate); 3299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IPV6: 3301965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return (gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, 3302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)ARCTYPE_INET6)); 3303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IP: 3305965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, 3306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)ARCTYPE_IP); 3307965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, 3308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)ARCTYPE_IP_OLD); 3309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 3310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b1); 3311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_ARP: 3313965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, 3314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)ARCTYPE_ARP); 3315965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, 3316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)ARCTYPE_ARP_OLD); 3317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 3318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b1); 3319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_REVARP: 3321965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return (gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, 3322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)ARCTYPE_REVARP)); 3323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_ATALK: 3325965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return (gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, 3326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)ARCTYPE_ATALK)); 3327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 3329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_LTALK: 3332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 3333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_ATALK: 3334965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_true(cstate); 3335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 3336965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_false(cstate); 3337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 3339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_FRELAY: 3342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - assumes a 2-byte Frame Relay header with 3344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DLCI and flags. What if the address is longer? 3345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 3347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IP: 3349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for the special NLPID for IP. 3351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3352965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_cmp(cstate, OR_LINKHDR, 2, BPF_H, (0x03<<8) | 0xcc); 3353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_IPV6: 3355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for the special NLPID for IPv6. 3357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3358965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_cmp(cstate, OR_LINKHDR, 2, BPF_H, (0x03<<8) | 0x8e); 3359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_ISONS: 3361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for several OSI protocols. 3363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Frame Relay packets typically have an OSI 3365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * NLPID at the beginning; we check for each 3366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of them. 3367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * What we check for is the NLPID and a frame 3369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * control field of UI, i.e. 0x03 followed 3370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * by the NLPID. 3371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3372965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKHDR, 2, BPF_H, (0x03<<8) | ISO8473_CLNP); 3373965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp(cstate, OR_LINKHDR, 2, BPF_H, (0x03<<8) | ISO9542_ESIS); 3374965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b2 = gen_cmp(cstate, OR_LINKHDR, 2, BPF_H, (0x03<<8) | ISO10589_ISIS); 3375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, b2); 3376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b2); 3377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b2; 3378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 3380965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_false(cstate); 3381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 3383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3385511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_MFR: 3386965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "Multi-link Frame Relay link-layer type filtering not implemented"); 3387511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MFR: 3389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MLFR: 3390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MLPPP: 3391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ATM1: 3392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ATM2: 3393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_PPPOE: 3394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_PPPOE_ATM: 3395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_GGSN: 3396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ES: 3397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MONITOR: 3398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_SERVICES: 3399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ETHER: 3400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_PPP: 3401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_FRELAY: 3402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_CHDLC: 3403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_VP: 3404511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_ST: 3405511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_ISM: 3406511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_VS: 3407511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_SRX_E2E: 3408511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_FIBRECHANNEL: 3409511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_ATM_CEMIC: 3410511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* just lets verify the magic number for now - 3412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * on ATM we may have up to 6 different encapsulations on the wire 3413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and need a lot of heuristics to figure out that the payload 3414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * might be; 3415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * FIXME encapsulation specific BPF_ filters 3417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3418965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_mcmp(cstate, OR_LINKHDR, 0, BPF_W, 0x4d474300, 0xffffff00); /* compare the magic number */ 3419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3420511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_BACNET_MS_TP: 3421965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_mcmp(cstate, OR_LINKHDR, 0, BPF_W, 0x55FF0000, 0xffff0000); 3422511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3423511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IPNET: 3424965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_ipnet_linktype(cstate, proto); 3425511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_LINUX_IRDA: 3427965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "IrDA link-layer type filtering not implemented"); 3428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_DOCSIS: 3430965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "DOCSIS link-layer type filtering not implemented"); 3431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3432511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_MTP2: 3433511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_MTP2_WITH_PHDR: 3434965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "MTP2 link-layer type filtering not implemented"); 3435511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3436511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_ERF: 3437965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "ERF link-layer type filtering not implemented"); 3438511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3439511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PFSYNC: 3440965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "PFSYNC link-layer type filtering not implemented"); 3441511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_LINUX_LAPD: 3443965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "LAPD link-layer type filtering not implemented"); 3444511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3445965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes case DLT_USB_FREEBSD: 3446511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_USB_LINUX: 3447511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_USB_LINUX_MMAPPED: 3448965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes case DLT_USBPCAP: 3449965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "USB link-layer type filtering not implemented"); 3450511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3451511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_BLUETOOTH_HCI_H4: 3452511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_BLUETOOTH_HCI_H4_WITH_PHDR: 3453965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "Bluetooth link-layer type filtering not implemented"); 3454511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3455511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_CAN20B: 3456511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_CAN_SOCKETCAN: 3457965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "CAN link-layer type filtering not implemented"); 3458511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3459511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_15_4: 3460511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_15_4_LINUX: 3461511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_15_4_NONASK_PHY: 3462511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_15_4_NOFCS: 3463965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "IEEE 802.15.4 link-layer type filtering not implemented"); 3464511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3465511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_16_MAC_CPS_RADIO: 3466965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "IEEE 802.16 link-layer type filtering not implemented"); 3467511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3468511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_SITA: 3469965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "SITA link-layer type filtering not implemented"); 3470511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3471511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_RAIF1: 3472965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "RAIF1 link-layer type filtering not implemented"); 3473511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3474511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IPMB: 3475965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "IPMB link-layer type filtering not implemented"); 3476511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3477d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_AX25_KISS: 3478965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "AX.25 link-layer type filtering not implemented"); 3479d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3480d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_NFLOG: 3481d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Using the fixed-size NFLOG header it is possible to tell only 3482d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the address family of the packet, other meaningful data is 3483d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * either missing or behind TLVs. 3484d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3485965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "NFLOG link-layer type filtering not implemented"); 3486d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3487d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes default: 3488d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3489d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Does this link-layer header type have a field 3490d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * indicating the type of the next protocol? If 3491d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * so, off_linktype.constant_part will be the offset of that 3492965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * field in the packet; if not, it will be OFFSET_NOT_SET. 3493d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3494965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_linktype.constant_part != OFFSET_NOT_SET) { 3495d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3496d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Yes; assume it's an Ethernet type. (If 3497d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * it's not, it needs to be handled specially 3498d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * above.) 3499d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3500965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto); 3501d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } else { 3502d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3503d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * No; report an error. 3504d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3505965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes description = pcap_datalink_val_to_description(cstate->linktype); 3506d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (description != NULL) { 3507965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "%s link-layer type filtering not implemented", 3508d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes description); 3509d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } else { 3510965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "DLT %u link-layer type filtering not implemented", 3511965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->linktype); 3512d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 3513d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 3514d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 3515d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 3516d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 3517d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3518d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* 3519d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Check for an LLC SNAP packet with a given organization code and 3520d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * protocol type; we check the entire contents of the 802.2 LLC and 3521d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * snap headers, checking for DSAP and SSAP of SNAP and a control 3522d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * field of 0x03 in the LLC header, and for the specified organization 3523d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * code and protocol type in the SNAP header. 3524d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3525d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct block * 3526965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_snap(compiler_state_t *cstate, bpf_u_int32 orgcode, bpf_u_int32 ptype) 3527d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 3528d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes u_char snapblock[8]; 3529d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3530d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes snapblock[0] = LLCSAP_SNAP; /* DSAP = SNAP */ 3531d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes snapblock[1] = LLCSAP_SNAP; /* SSAP = SNAP */ 3532d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes snapblock[2] = 0x03; /* control = UI */ 3533d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes snapblock[3] = (orgcode >> 16); /* upper 8 bits of organization code */ 3534d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes snapblock[4] = (orgcode >> 8); /* middle 8 bits of organization code */ 3535d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes snapblock[5] = (orgcode >> 0); /* lower 8 bits of organization code */ 3536d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes snapblock[6] = (ptype >> 8); /* upper 8 bits of protocol type */ 3537d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes snapblock[7] = (ptype >> 0); /* lower 8 bits of protocol type */ 3538965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_bcmp(cstate, OR_LLC, 0, 8, snapblock); 3539d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 3540d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3541d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* 3542d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Generate code to match frames with an LLC header. 3543d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3544d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstruct block * 3545965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_llc(compiler_state_t *cstate) 3546d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 3547d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 3548d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3549965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes switch (cstate->linktype) { 3550d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3551d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_EN10MB: 3552d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3553d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * We check for an Ethernet type field less than 3554d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 1500, which means it's an 802.3 length field. 3555d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3556965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp_gt(cstate, OR_LINKTYPE, 0, BPF_H, ETHERMTU); 3557d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_not(b0); 3558d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3559d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3560d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Now check for the purported DSAP and SSAP not being 3561d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 0xFF, to rule out NetWare-over-802.3. 3562d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3563965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, (bpf_int32)0xFFFF); 3564d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_not(b1); 3565d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 3566d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 3567d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3568d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_SUNATM: 3569d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3570d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * We check for LLC traffic. 3571d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3572965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_atmtype_abbrev(cstate, A_LLC); 3573d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b0; 3574d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3575d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_IEEE802: /* Token Ring */ 3576d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3577d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * XXX - check for LLC frames. 3578d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3579965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_true(cstate); 3580d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3581d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_FDDI: 3582d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3583d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * XXX - check for LLC frames. 3584d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3585965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_true(cstate); 3586d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3587d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_ATM_RFC1483: 3588d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3589d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * For LLC encapsulation, these are defined to have an 3590d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 802.2 LLC header. 3591d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 3592d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * For VC encapsulation, they don't, but there's no 3593d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * way to check for that; the protocol used on the VC 3594d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * is negotiated out of band. 3595d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3596965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_true(cstate); 3597d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3598d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_IEEE802_11: 3599d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_PRISM_HEADER: 3600d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_IEEE802_11_RADIO: 3601d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_IEEE802_11_RADIO_AVS: 3602d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_PPI: 3603d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3604d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Check that we have a data frame. 3605d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3606965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_check_802_11_data_frame(cstate); 3607d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b0; 3608d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3609d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes default: 3610965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'llc' not supported for linktype %d", cstate->linktype); 3611d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* NOTREACHED */ 3612d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 3613d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 3614d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3615d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstruct block * 3616965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_llc_i(compiler_state_t *cstate) 3617d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 3618d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 3619d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct slist *s; 3620d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3621d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3622d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Check whether this is an LLC frame. 3623d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3624965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_llc(cstate); 3625d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3626d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3627d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Load the control byte and test the low-order bit; it must 3628d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * be clear for I frames. 3629d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3630965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LLC, 2, BPF_B); 3631965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = new_block(cstate, JMP(BPF_JSET)); 3632d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1->s.k = 0x01; 3633d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1->stmts = s; 3634d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_not(b1); 3635d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 3636d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 3637d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 3638d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3639d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstruct block * 3640965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_llc_s(compiler_state_t *cstate) 3641d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 3642d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 3643d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3644d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3645d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Check whether this is an LLC frame. 3646d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3647965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_llc(cstate); 3648d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3649d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3650d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Now compare the low-order 2 bit of the control byte against 3651d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the appropriate value for S frames. 3652d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3653965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_mcmp(cstate, OR_LLC, 2, BPF_B, LLC_S_FMT, 0x03); 3654d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 3655d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 3656d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 3657d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3658d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstruct block * 3659965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_llc_u(compiler_state_t *cstate) 3660d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 3661d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 3662d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3663d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3664d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Check whether this is an LLC frame. 3665d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3666965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_llc(cstate); 3667d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3668d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3669d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Now compare the low-order 2 bit of the control byte against 3670d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the appropriate value for U frames. 3671d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3672965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_mcmp(cstate, OR_LLC, 2, BPF_B, LLC_U_FMT, 0x03); 3673d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 3674d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 3675d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 3676d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3677d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstruct block * 3678965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_llc_s_subtype(compiler_state_t *cstate, bpf_u_int32 subtype) 3679d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 3680d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 3681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3683d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Check whether this is an LLC frame. 3684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3685965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_llc(cstate); 3686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3688d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Now check for an S frame with the appropriate type. 3689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3690965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_mcmp(cstate, OR_LLC, 2, BPF_B, subtype, LLC_S_CMD_MASK); 3691d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 3692d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 3693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 3694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3695d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstruct block * 3696965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_llc_u_subtype(compiler_state_t *cstate, bpf_u_int32 subtype) 3697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 3698d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 3699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3700d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3701d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Check whether this is an LLC frame. 3702d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3703965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_llc(cstate); 3704d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 3705d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 3706d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Now check for a U frame with the appropriate type. 3707d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 3708965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_mcmp(cstate, OR_LLC, 2, BPF_B, subtype, LLC_U_CMD_MASK); 3709d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 3710d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 3711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 3712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 3714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to match a particular packet type, for link-layer types 3715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * using 802.2 LLC headers. 3716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is *NOT* used for Ethernet; "gen_ether_linktype()" is used 3718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * for that - it handles the D/I/X Ethernet vs. 802.3+802.2 issues. 3719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP 3721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * value, if <= ETHERMTU. We use that to determine whether to 3722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * match the DSAP or both DSAP and LSAP or to check the OUI and 3723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * protocol ID in a SNAP header. 3724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 3726965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_llc_linktype(compiler_state_t *cstate, int proto) 3727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 3728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - handle token-ring variable-length header. 3730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 3732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_IP: 3734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_ISONS: 3735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_NETBEUI: 3736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - should we check both the DSAP and the 3738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SSAP, like this, or should we check just the 3739d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * DSAP, as we do for other SAP values? 3740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3741965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_cmp(cstate, OR_LLC, 0, BPF_H, (bpf_u_int32) 3742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ((proto << 8) | proto)); 3743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case LLCSAP_IPX: 3745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - are there ever SNAP frames for IPX on 3747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * non-Ethernet 802.x networks? 3748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3749965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_cmp(cstate, OR_LLC, 0, BPF_B, 3750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)LLCSAP_IPX); 3751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case ETHERTYPE_ATALK: 3753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 802.2-encapsulated ETHERTYPE_ATALK packets are 3755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SNAP packets with an organization code of 3756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 0x080007 (Apple, for Appletalk) and a protocol 3757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * type of ETHERTYPE_ATALK (Appletalk). 3758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - check for an organization code of 3760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * encapsulated Ethernet as well? 3761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3762965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_snap(cstate, 0x080007, ETHERTYPE_ATALK); 3763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 3765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - we don't have to check for IPX 802.3 3767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * here, but should we check for the IPX Ethertype? 3768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3769478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto <= ETHERMTU) { 3770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is an LLC SAP value, so check 3772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the DSAP. 3773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3774965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_cmp(cstate, OR_LLC, 0, BPF_B, (bpf_int32)proto); 3775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 3776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 3777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is an Ethernet type; we assume that it's 3778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * unlikely that it'll appear in the right place 3779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * at random, and therefore check only the 3780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * location that would hold the Ethernet type 3781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in a SNAP frame with an organization code of 3782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 0x000000 (encapsulated Ethernet). 3783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - if we were to check for the SNAP DSAP and 3785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LSAP, as per XXX, and were also to check for an 3786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * organization code of 0x000000 (encapsulated 3787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet), we'd do 3788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3789965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * return gen_snap(cstate, 0x000000, proto); 3790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * here; for now, we don't, as per the above. 3792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * I don't know whether it's worth the extra CPU 3793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * time to do the right check or not. 3794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3795965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_cmp(cstate, OR_LLC, 6, BPF_H, (bpf_int32)proto); 3796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 3799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 3801965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_hostop(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask, 3802965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int dir, int proto, u_int src_off, u_int dst_off) 3803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 3804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 3805478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int offset; 3806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3807478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 3808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 3810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project offset = src_off; 3811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 3814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project offset = dst_off; 3815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 3818965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_hostop(cstate, addr, mask, Q_SRC, proto, src_off, dst_off); 3819965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_hostop(cstate, addr, mask, Q_DST, proto, src_off, dst_off); 3820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3822478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 3824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 3825965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_hostop(cstate, addr, mask, Q_SRC, proto, src_off, dst_off); 3826965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_hostop(cstate, addr, mask, Q_DST, proto, src_off, dst_off); 3827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 3828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 3831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 3832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3833965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, proto); 3834965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_mcmp(cstate, OR_LINKPL, offset, BPF_W, (bpf_int32)addr, mask); 3835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 3838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6 3840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 3841965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_hostop6(compiler_state_t *cstate, struct in6_addr *addr, 3842965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes struct in6_addr *mask, int dir, int proto, u_int src_off, u_int dst_off) 3843478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 3844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 3845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int offset; 3846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int32_t *a, *m; 3847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 3849478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 3851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project offset = src_off; 3852478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 3855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project offset = dst_off; 3856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 3857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 3859965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_hostop6(cstate, addr, mask, Q_SRC, proto, src_off, dst_off); 3860965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_hostop6(cstate, addr, mask, Q_DST, proto, src_off, dst_off); 3861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 3865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 3866965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_hostop6(cstate, addr, mask, Q_SRC, proto, src_off, dst_off); 3867965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_hostop6(cstate, addr, mask, Q_DST, proto, src_off, dst_off); 3868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 3869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 3872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 3873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* this order is important */ 3875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project a = (u_int32_t *)addr; 3876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project m = (u_int32_t *)mask; 3877965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_mcmp(cstate, OR_LINKPL, offset + 12, BPF_W, ntohl(a[3]), ntohl(m[3])); 3878965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_mcmp(cstate, OR_LINKPL, offset + 8, BPF_W, ntohl(a[2]), ntohl(m[2])); 3879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3880965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_mcmp(cstate, OR_LINKPL, offset + 4, BPF_W, ntohl(a[1]), ntohl(m[1])); 3881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3882965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_mcmp(cstate, OR_LINKPL, offset + 0, BPF_W, ntohl(a[0]), ntohl(m[0])); 3883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3884965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, proto); 3885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 3888511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 3889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 3891965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_ehostop(compiler_state_t *cstate, const u_char *eaddr, int dir) 3892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 3893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block *b0, *b1; 3894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 3896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 3897965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_bcmp(cstate, OR_LINKHDR, 6, 6, eaddr); 3898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 3900965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_bcmp(cstate, OR_LINKHDR, 0, 6, eaddr); 3901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 3903965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ehostop(cstate, eaddr, Q_SRC); 3904965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_ehostop(cstate, eaddr, Q_DST); 3905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 3909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 3910965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ehostop(cstate, eaddr, Q_SRC); 3911965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_ehostop(cstate, eaddr, Q_DST); 3912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 3913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3914511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3915511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR1: 3916965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr1' is only supported on 802.11 with 802.11 headers"); 3917511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3918511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3919511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR2: 3920965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr2' is only supported on 802.11 with 802.11 headers"); 3921511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3922511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3923511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR3: 3924965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr3' is only supported on 802.11 with 802.11 headers"); 3925511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3926511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3927511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR4: 3928965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr4' is only supported on 802.11 with 802.11 headers"); 3929511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3930511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3931511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_RA: 3932965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'ra' is only supported on 802.11 with 802.11 headers"); 3933511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3934511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3935511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_TA: 3936965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'ta' is only supported on 802.11 with 802.11 headers"); 3937511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 3940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 3941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 3942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 3944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Like gen_ehostop, but for DLT_FDDI 3945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 3946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 3947965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_fhostop(compiler_state_t *cstate, const u_char *eaddr, int dir) 3948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 3949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 3950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 3952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 3953965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_bcmp(cstate, OR_LINKHDR, 6 + 1 + cstate->pcap_fddipad, 6, eaddr); 3954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 3956965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_bcmp(cstate, OR_LINKHDR, 0 + 1 + cstate->pcap_fddipad, 6, eaddr); 3957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 3959965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_fhostop(cstate, eaddr, Q_SRC); 3960965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_fhostop(cstate, eaddr, Q_DST); 3961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 3962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 3965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 3966965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_fhostop(cstate, eaddr, Q_SRC); 3967965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_fhostop(cstate, eaddr, Q_DST); 3968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 3969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 3970511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3971511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR1: 3972965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr1' is only supported on 802.11"); 3973511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3974511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3975511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR2: 3976965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr2' is only supported on 802.11"); 3977511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3978511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3979511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR3: 3980965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr3' is only supported on 802.11"); 3981511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3982511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3983511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR4: 3984965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr4' is only supported on 802.11"); 3985511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3986511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3987511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_RA: 3988965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'ra' is only supported on 802.11"); 3989511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3990511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 3991511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_TA: 3992965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'ta' is only supported on 802.11"); 3993511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 3994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 3995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 3996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 3997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 3998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 3999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 4000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Like gen_ehostop, but for DLT_IEEE802 (Token Ring) 4001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 4003965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_thostop(compiler_state_t *cstate, const u_char *eaddr, int dir) 4004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 4005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block *b0, *b1; 4006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 4008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 4009965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_bcmp(cstate, OR_LINKHDR, 8, 6, eaddr); 4010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 4012965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_bcmp(cstate, OR_LINKHDR, 2, 6, eaddr); 4013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 4015965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_thostop(cstate, eaddr, Q_SRC); 4016965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_thostop(cstate, eaddr, Q_DST); 4017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 4018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 4021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 4022965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_thostop(cstate, eaddr, Q_SRC); 4023965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_thostop(cstate, eaddr, Q_DST); 4024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 4025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4026511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4027511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR1: 4028965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr1' is only supported on 802.11"); 4029511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4030511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4031511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR2: 4032965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr2' is only supported on 802.11"); 4033511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4034511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4035511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR3: 4036965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr3' is only supported on 802.11"); 4037511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4038511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4039511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR4: 4040965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr4' is only supported on 802.11"); 4041511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4042511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4043511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_RA: 4044965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'ra' is only supported on 802.11"); 4045511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4046511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4047511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_TA: 4048965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'ta' is only supported on 802.11"); 4049511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 4052478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 4053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 4054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 4056511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Like gen_ehostop, but for DLT_IEEE802_11 (802.11 wireless LAN) and 4057511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * various 802.11 + radio headers. 4058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 4060965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_wlanhostop(compiler_state_t *cstate, const u_char *eaddr, int dir) 4061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 4062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block *b0, *b1, *b2; 4063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct slist *s; 4064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4065511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef ENABLE_WLAN_FILTERING_PATCH 4066511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4067511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * TODO GV 20070613 4068511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * We need to disable the optimizer because the optimizer is buggy 4069511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * and wipes out some LD instructions generated by the below 4070511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * code to validate the Frame Control bits 4071511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4072965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->no_optimize = 1; 4073511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif /* ENABLE_WLAN_FILTERING_PATCH */ 4074511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 4076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 4077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4078478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Oh, yuk. 4079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For control frames, there is no SA. 4081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4082478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For management frames, SA is at an 4083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * offset of 10 from the beginning of 4084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the packet. 4085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For data frames, SA is at an offset 4087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of 10 from the beginning of the packet 4088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * if From DS is clear, at an offset of 4089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 16 from the beginning of the packet 4090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * if From DS is set and To DS is clear, 4091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and an offset of 24 from the beginning 4092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of the packet if From DS is set and To DS 4093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is set. 4094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate the tests to be done for data frames 4098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with From DS set. 4099478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * First, check for To DS set, i.e. check "link[1] & 0x01". 4101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4102965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 1, BPF_B); 4103965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = new_block(cstate, JMP(BPF_JSET)); 4104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->s.k = 0x01; /* To DS */ 4105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->stmts = s; 4106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If To DS is set, the SA is at 24. 4109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4110965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_bcmp(cstate, OR_LINKHDR, 24, 6, eaddr); 4111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b1, b0); 4112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now, check for To DS not set, i.e. check 4115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "!(link[1] & 0x01)". 4116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4117965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 1, BPF_B); 4118965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b2 = new_block(cstate, JMP(BPF_JSET)); 4119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->s.k = 0x01; /* To DS */ 4120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->stmts = s; 4121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b2); 4122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If To DS is not set, the SA is at 16. 4125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4126965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_bcmp(cstate, OR_LINKHDR, 16, 6, eaddr); 4127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b2, b1); 4128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now OR together the last two checks. That gives 4131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the complete set of checks for data frames with 4132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * From DS set. 4133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, b0); 4135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now check for From DS being set, and AND that with 4138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the ORed-together checks. 4139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4140965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 1, BPF_B); 4141965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = new_block(cstate, JMP(BPF_JSET)); 4142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->s.k = 0x02; /* From DS */ 4143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->stmts = s; 4144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b1, b0); 4145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now check for data frames with From DS not set. 4148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4149965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 1, BPF_B); 4150965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b2 = new_block(cstate, JMP(BPF_JSET)); 4151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->s.k = 0x02; /* From DS */ 4152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->stmts = s; 4153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b2); 4154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If From DS isn't set, the SA is at 10. 4157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4158965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_bcmp(cstate, OR_LINKHDR, 10, 6, eaddr); 4159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b2, b1); 4160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now OR together the checks for data frames with 4163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * From DS not set and for data frames with From DS 4164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * set; that gives the checks done for data frames. 4165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, b0); 4167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now check for a data frame. 4170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * I.e, check "link[0] & 0x08". 4171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4172965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 0, BPF_B); 4173965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = new_block(cstate, JMP(BPF_JSET)); 4174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->s.k = 0x08; 4175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->stmts = s; 4176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * AND that with the checks done for data frames. 4179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b1, b0); 4181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If the high-order bit of the type value is 0, this 4184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is a management frame. 4185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * I.e, check "!(link[0] & 0x08)". 4186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4187965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 0, BPF_B); 4188965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b2 = new_block(cstate, JMP(BPF_JSET)); 4189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->s.k = 0x08; 4190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->stmts = s; 4191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b2); 4192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For management frames, the SA is at 10. 4195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4196965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_bcmp(cstate, OR_LINKHDR, 10, 6, eaddr); 4197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b2, b1); 4198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OR that with the checks done for data frames. 4201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * That gives the checks done for management and 4202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * data frames. 4203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, b0); 4205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If the low-order bit of the type value is 1, 4208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * this is either a control frame or a frame 4209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with a reserved type, and thus not a 4210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frame with an SA. 4211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * I.e., check "!(link[0] & 0x04)". 4213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4214965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 0, BPF_B); 4215965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = new_block(cstate, JMP(BPF_JSET)); 4216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->s.k = 0x04; 4217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->stmts = s; 4218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b1); 4219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * AND that with the checks for data and management 4222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames. 4223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b1, b0); 4225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 4226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 4228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Oh, yuk. 4230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For control frames, there is no DA. 4232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For management frames, DA is at an 4234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * offset of 4 from the beginning of 4235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the packet. 4236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For data frames, DA is at an offset 4238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of 4 from the beginning of the packet 4239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * if To DS is clear and at an offset of 4240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 16 from the beginning of the packet 4241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * if To DS is set. 4242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate the tests to be done for data frames. 4246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * First, check for To DS set, i.e. "link[1] & 0x01". 4248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4249965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 1, BPF_B); 4250965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = new_block(cstate, JMP(BPF_JSET)); 4251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->s.k = 0x01; /* To DS */ 4252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->stmts = s; 4253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If To DS is set, the DA is at 16. 4256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4257965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_bcmp(cstate, OR_LINKHDR, 16, 6, eaddr); 4258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b1, b0); 4259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now, check for To DS not set, i.e. check 4262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "!(link[1] & 0x01)". 4263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4264965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 1, BPF_B); 4265965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b2 = new_block(cstate, JMP(BPF_JSET)); 4266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->s.k = 0x01; /* To DS */ 4267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->stmts = s; 4268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b2); 4269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If To DS is not set, the DA is at 4. 4272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4273965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_bcmp(cstate, OR_LINKHDR, 4, 6, eaddr); 4274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b2, b1); 4275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now OR together the last two checks. That gives 4278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the complete set of checks for data frames. 4279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, b0); 4281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Now check for a data frame. 4284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * I.e, check "link[0] & 0x08". 4285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4286965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 0, BPF_B); 4287965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = new_block(cstate, JMP(BPF_JSET)); 4288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->s.k = 0x08; 4289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->stmts = s; 4290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * AND that with the checks done for data frames. 4293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b1, b0); 4295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If the high-order bit of the type value is 0, this 4298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is a management frame. 4299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * I.e, check "!(link[0] & 0x08)". 4300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4301965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 0, BPF_B); 4302965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b2 = new_block(cstate, JMP(BPF_JSET)); 4303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->s.k = 0x08; 4304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b2->stmts = s; 4305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b2); 4306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For management frames, the DA is at 4. 4309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4310965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_bcmp(cstate, OR_LINKHDR, 4, 6, eaddr); 4311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b2, b1); 4312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OR that with the checks done for data frames. 4315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * That gives the checks done for management and 4316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * data frames. 4317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, b0); 4319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If the low-order bit of the type value is 1, 4322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * this is either a control frame or a frame 4323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with a reserved type, and thus not a 4324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frame with an SA. 4325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * I.e., check "!(link[0] & 0x04)". 4327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4328965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 0, BPF_B); 4329965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = new_block(cstate, JMP(BPF_JSET)); 4330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->s.k = 0x04; 4331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1->stmts = s; 4332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b1); 4333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * AND that with the checks for data and management 4336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frames. 4337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b1, b0); 4339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 4340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4341511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_RA: 4342511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4343511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Not present in management frames; addr1 in other 4344511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * frames. 4345511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4346511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4347511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4348511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If the high-order bit of the type value is 0, this 4349511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * is a management frame. 4350511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * I.e, check "(link[0] & 0x08)". 4351511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4352965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 0, BPF_B); 4353965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = new_block(cstate, JMP(BPF_JSET)); 4354511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->s.k = 0x08; 4355511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->stmts = s; 4356511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4357511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4358511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Check addr1. 4359511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4360965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_bcmp(cstate, OR_LINKHDR, 4, 6, eaddr); 4361511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4362511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4363511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * AND that with the check of addr1. 4364511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4365511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b1, b0); 4366511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (b0); 4367511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4368511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_TA: 4369511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4370511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Not present in management frames; addr2, if present, 4371511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * in other frames. 4372511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4373511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4374511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4375511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Not present in CTS or ACK control frames. 4376511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4377965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_TYPE_CTL, 4378511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall IEEE80211_FC0_TYPE_MASK); 4379511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b0); 4380965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_SUBTYPE_CTS, 4381511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall IEEE80211_FC0_SUBTYPE_MASK); 4382511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b1); 4383965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b2 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_SUBTYPE_ACK, 4384511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall IEEE80211_FC0_SUBTYPE_MASK); 4385511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b2); 4386511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b1, b2); 4387511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_or(b0, b2); 4388511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4389511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4390511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If the high-order bit of the type value is 0, this 4391511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * is a management frame. 4392511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * I.e, check "(link[0] & 0x08)". 4393511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4394965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 0, BPF_B); 4395965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = new_block(cstate, JMP(BPF_JSET)); 4396511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->s.k = 0x08; 4397511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->stmts = s; 4398511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4399511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4400511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * AND that with the check for frames other than 4401511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * CTS and ACK frames. 4402511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4403511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b1, b2); 4404511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4405511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4406511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Check addr2. 4407511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4408965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_bcmp(cstate, OR_LINKHDR, 10, 6, eaddr); 4409511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b2, b1); 4410511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return b1; 4411511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4412511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4413511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * XXX - add BSSID keyword? 4414511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4415511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR1: 4416965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return (gen_bcmp(cstate, OR_LINKHDR, 4, 6, eaddr)); 4417511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4418511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR2: 4419511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4420511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Not present in CTS or ACK control frames. 4421511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4422965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_TYPE_CTL, 4423511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall IEEE80211_FC0_TYPE_MASK); 4424511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b0); 4425965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_SUBTYPE_CTS, 4426511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall IEEE80211_FC0_SUBTYPE_MASK); 4427511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b1); 4428965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b2 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_SUBTYPE_ACK, 4429511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall IEEE80211_FC0_SUBTYPE_MASK); 4430511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b2); 4431511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b1, b2); 4432511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_or(b0, b2); 4433965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_bcmp(cstate, OR_LINKHDR, 10, 6, eaddr); 4434511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b2, b1); 4435511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return b1; 4436511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4437511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR3: 4438511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4439511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Not present in control frames. 4440511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4441965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_TYPE_CTL, 4442511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall IEEE80211_FC0_TYPE_MASK); 4443511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b0); 4444965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_bcmp(cstate, OR_LINKHDR, 16, 6, eaddr); 4445511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b0, b1); 4446511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return b1; 4447511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4448511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR4: 4449511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 4450511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Present only if the direction mask has both "From DS" 4451511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * and "To DS" set. Neither control frames nor management 4452511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * frames should have both of those set, so we don't 4453511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * check the frame type. 4454511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 4455965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_mcmp(cstate, OR_LINKHDR, 1, BPF_B, 4456511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall IEEE80211_FC1_DIR_DSTODS, IEEE80211_FC1_DIR_MASK); 4457965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_bcmp(cstate, OR_LINKHDR, 24, 6, eaddr); 4458511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b0, b1); 4459511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return b1; 4460511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 4462965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_wlanhostop(cstate, eaddr, Q_SRC); 4463965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_wlanhostop(cstate, eaddr, Q_DST); 4464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 4465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 4468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 4469965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_wlanhostop(cstate, eaddr, Q_SRC); 4470965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_wlanhostop(cstate, eaddr, Q_DST); 4471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 4472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 4475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 4476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 4477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 4479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Like gen_ehostop, but for RFC 2625 IP-over-Fibre-Channel. 4480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (We assume that the addresses are IEEE 48-bit MAC addresses, 4481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as the RFC states.) 4482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 4484965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_ipfchostop(compiler_state_t *cstate, const u_char *eaddr, int dir) 4485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 4486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block *b0, *b1; 4487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 4489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 4490965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_bcmp(cstate, OR_LINKHDR, 10, 6, eaddr); 4491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 4493965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_bcmp(cstate, OR_LINKHDR, 2, 6, eaddr); 4494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 4496965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ipfchostop(cstate, eaddr, Q_SRC); 4497965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_ipfchostop(cstate, eaddr, Q_DST); 4498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 4499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 4502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 4503965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ipfchostop(cstate, eaddr, Q_SRC); 4504965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_ipfchostop(cstate, eaddr, Q_DST); 4505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 4506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4507511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4508511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR1: 4509965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr1' is only supported on 802.11"); 4510511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4511511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4512511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR2: 4513965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr2' is only supported on 802.11"); 4514511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4515511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4516511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR3: 4517965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr3' is only supported on 802.11"); 4518511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4519511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4520511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR4: 4521965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr4' is only supported on 802.11"); 4522511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4523511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4524511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_RA: 4525965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'ra' is only supported on 802.11"); 4526511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4527511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4528511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_TA: 4529965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'ta' is only supported on 802.11"); 4530511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 4533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 4534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 4535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 4537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is quite tricky because there may be pad bytes in front of the 4538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DECNET header, and then there are two possible data packet formats that 4539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * carry both src and dst addresses, plus 5 packet types in a format that 4540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * carries only the src node, plus 2 types that use a different format and 4541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * also carry just the src node. 4542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Yuck. 4544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Instead of doing those all right, we just look for data packets with 4546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 0 or 1 bytes of padding. If you want to look at other packets, that 4547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * will require a lot more hacking. 4548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * To add support for filtering on DECNET "areas" (network numbers) 4550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * one would want to add a "mask" argument to this routine. That would 4551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * make the filter even more inefficient, although one could be clever 4552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and not generate masking instructions if the mask is 0xFFFF. 4553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 4555965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_dnhostop(compiler_state_t *cstate, bpf_u_int32 addr, int dir) 4556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 4557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *b2, *tmp; 4558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int offset_lh; /* offset if long header is received */ 4559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int offset_sh; /* offset if short header is received */ 4560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 4562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 4564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project offset_sh = 1; /* follows flags */ 4565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project offset_lh = 7; /* flgs,darea,dsubarea,HIORD */ 4566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 4569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project offset_sh = 3; /* follows flags, dstnode */ 4570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project offset_lh = 15; /* flgs,darea,dsubarea,did,sarea,ssub,HIORD */ 4571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 4574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Inefficient because we do our Calvinball dance twice */ 4575965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_dnhostop(cstate, addr, Q_SRC); 4576965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_dnhostop(cstate, addr, Q_DST); 4577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 4578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 4581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 4582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Inefficient because we do our Calvinball dance twice */ 4583965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_dnhostop(cstate, addr, Q_SRC); 4584965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_dnhostop(cstate, addr, Q_DST); 4585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 4586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISO: 4589965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "ISO host filtering not implemented"); 4590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 4592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 4593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4594965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, ETHERTYPE_DN); 4595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Check for pad = 1, long header case */ 4596965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_mcmp(cstate, OR_LINKPL, 2, BPF_H, 4597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF)); 4598965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp(cstate, OR_LINKPL, 2 + 1 + offset_lh, 4599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project BPF_H, (bpf_int32)ntohs((u_short)addr)); 4600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b1); 4601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Check for pad = 0, long header case */ 4602965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_mcmp(cstate, OR_LINKPL, 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7); 4603965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b2 = gen_cmp(cstate, OR_LINKPL, 2 + offset_lh, BPF_H, (bpf_int32)ntohs((u_short)addr)); 4604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b2); 4605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b2, b1); 4606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Check for pad = 1, short header case */ 4607965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_mcmp(cstate, OR_LINKPL, 2, BPF_H, 4608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF)); 4609965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b2 = gen_cmp(cstate, OR_LINKPL, 2 + 1 + offset_sh, BPF_H, (bpf_int32)ntohs((u_short)addr)); 4610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b2); 4611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b2, b1); 4612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Check for pad = 0, short header case */ 4613965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_mcmp(cstate, OR_LINKPL, 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7); 4614965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b2 = gen_cmp(cstate, OR_LINKPL, 2 + offset_sh, BPF_H, (bpf_int32)ntohs((u_short)addr)); 4615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b2); 4616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b2, b1); 4617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4618965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* Combine with test for cstate->linktype */ 4619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 4620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 4622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 4624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate a check for IPv4 or IPv6 for MPLS-encapsulated packets; 4625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * test the bottom-of-stack bit, and then check the version number 4626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * field in the IP header. 4627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 4629965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_mpls_linktype(compiler_state_t *cstate, int proto) 4630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 4631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 4632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 4634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 4636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* match the bottom-of-stack bit */ 4637965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_mcmp(cstate, OR_LINKPL, -2, BPF_B, 0x01, 0x01); 4638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* match the IPv4 version number */ 4639965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_B, 0x40, 0xf0); 4640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 4641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4642d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 4643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 4644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* match the bottom-of-stack bit */ 4645965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_mcmp(cstate, OR_LINKPL, -2, BPF_B, 0x01, 0x01); 4646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* match the IPv4 version number */ 4647965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_B, 0x60, 0xf0); 4648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 4649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4650d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 4651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 4652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 4653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 4655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 4657965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_host(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask, 4658965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int proto, int dir, int type) 4659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 4660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 4661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project const char *typestr; 4662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (type == Q_NET) 4664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project typestr = "net"; 4665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 4666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project typestr = "host"; 4667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 4669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 4671965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_host(cstate, addr, mask, Q_IP, dir, type); 4672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Only check for non-IPv4 addresses if we're not 4674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * checking MPLS-encapsulated packets. 4675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4676965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->label_stack_depth == 0) { 4677965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_host(cstate, addr, mask, Q_ARP, dir, type); 4678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 4679965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_host(cstate, addr, mask, Q_RARP, dir, type); 4680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, b0); 4681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 4683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 4685965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_hostop(cstate, addr, mask, dir, ETHERTYPE_IP, 12, 16); 4686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RARP: 4688965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_hostop(cstate, addr, mask, dir, ETHERTYPE_REVARP, 14, 24); 4689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ARP: 4691965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_hostop(cstate, addr, mask, dir, ETHERTYPE_ARP, 14, 24); 4692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_TCP: 4694965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'tcp' modifier applied to %s", typestr); 4695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCTP: 4697965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'sctp' modifier applied to %s", typestr); 4698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_UDP: 4700965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'udp' modifier applied to %s", typestr); 4701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMP: 4703965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'icmp' modifier applied to %s", typestr); 4704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGMP: 4706965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'igmp' modifier applied to %s", typestr); 4707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGRP: 4709965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'igrp' modifier applied to %s", typestr); 4710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PIM: 4712965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'pim' modifier applied to %s", typestr); 4713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_VRRP: 4715965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'vrrp' modifier applied to %s", typestr); 4716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4717511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_CARP: 4718965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'carp' modifier applied to %s", typestr); 4719511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ATALK: 4721965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "ATALK host filtering not implemented"); 4722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AARP: 4724965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "AARP host filtering not implemented"); 4725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DECNET: 4727965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_dnhostop(cstate, addr, dir); 4728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCA: 4730965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "SCA host filtering not implemented"); 4731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LAT: 4733965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "LAT host filtering not implemented"); 4734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPDL: 4736965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "MOPDL host filtering not implemented"); 4737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPRC: 4739965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "MOPRC host filtering not implemented"); 4740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 4742965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'ip6' modifier applied to ip host"); 4743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMPV6: 4745965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'icmp6' modifier applied to %s", typestr); 4746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AH: 4748965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'ah' modifier applied to %s", typestr); 4749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ESP: 4751965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'esp' modifier applied to %s", typestr); 4752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISO: 4754965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "ISO host filtering not implemented"); 4755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ESIS: 4757965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'esis' modifier applied to %s", typestr); 4758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS: 4760965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'isis' modifier applied to %s", typestr); 4761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_CLNP: 4763965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'clnp' modifier applied to %s", typestr); 4764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_STP: 4766965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'stp' modifier applied to %s", typestr); 4767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPX: 4769965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "IPX host filtering not implemented"); 4770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_NETBEUI: 4772965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'netbeui' modifier applied to %s", typestr); 4773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RADIO: 4775965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'radio' modifier applied to %s", typestr); 4776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 4778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 4779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 4781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 4782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6 4784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 4785965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_host6(compiler_state_t *cstate, struct in6_addr *addr, 4786965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes struct in6_addr *mask, int proto, int dir, int type) 4787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 4788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project const char *typestr; 4789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (type == Q_NET) 4791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project typestr = "net"; 4792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 4793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project typestr = "host"; 4794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 4796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 4798965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_host6(cstate, addr, mask, Q_IPV6, dir, type); 4799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4800511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_LINK: 4801965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "link-layer modifier applied to ip6 %s", typestr); 4802511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 4804965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'ip' modifier applied to ip6 %s", typestr); 4805478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RARP: 4807965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'rarp' modifier applied to ip6 %s", typestr); 4808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ARP: 4810965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'arp' modifier applied to ip6 %s", typestr); 4811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCTP: 4813965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'sctp' modifier applied to %s", typestr); 4814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_TCP: 4816965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'tcp' modifier applied to %s", typestr); 4817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4818478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_UDP: 4819965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'udp' modifier applied to %s", typestr); 4820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMP: 4822965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'icmp' modifier applied to %s", typestr); 4823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGMP: 4825965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'igmp' modifier applied to %s", typestr); 4826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGRP: 4828965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'igrp' modifier applied to %s", typestr); 4829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PIM: 4831965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'pim' modifier applied to %s", typestr); 4832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_VRRP: 4834965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'vrrp' modifier applied to %s", typestr); 4835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4836511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_CARP: 4837965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'carp' modifier applied to %s", typestr); 4838511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 4839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ATALK: 4840965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "ATALK host filtering not implemented"); 4841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AARP: 4843965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "AARP host filtering not implemented"); 4844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DECNET: 4846965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'decnet' modifier applied to ip6 %s", typestr); 4847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCA: 4849965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "SCA host filtering not implemented"); 4850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LAT: 4852965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "LAT host filtering not implemented"); 4853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPDL: 4855965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "MOPDL host filtering not implemented"); 4856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPRC: 4858965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "MOPRC host filtering not implemented"); 4859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 4861965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_hostop6(cstate, addr, mask, dir, ETHERTYPE_IPV6, 8, 24); 4862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMPV6: 4864965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'icmp6' modifier applied to %s", typestr); 4865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AH: 4867965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'ah' modifier applied to %s", typestr); 4868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ESP: 4870965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'esp' modifier applied to %s", typestr); 4871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISO: 4873965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "ISO host filtering not implemented"); 4874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ESIS: 4876965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'esis' modifier applied to %s", typestr); 4877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS: 4879965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'isis' modifier applied to %s", typestr); 4880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_CLNP: 4882965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'clnp' modifier applied to %s", typestr); 4883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_STP: 4885965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'stp' modifier applied to %s", typestr); 4886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPX: 4888965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "IPX host filtering not implemented"); 4889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_NETBEUI: 4891965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'netbeui' modifier applied to %s", typestr); 4892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RADIO: 4894965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'radio' modifier applied to %s", typestr); 4895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 4897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 4898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 4900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 4901511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 4902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef INET6 4904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 4905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_gateway(eaddr, alist, proto, dir) 4906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project const u_char *eaddr; 4907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 **alist; 4908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int proto; 4909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir; 4910478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 4911478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *tmp; 4912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (dir != 0) 4914965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "direction applied to 'gateway'"); 4915478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 4917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 4918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 4919478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ARP: 4920478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RARP: 4921965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes switch (cstate->linktype) { 4922511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_EN10MB: 4923511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER: 4924511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER_TRANSPARENT: 4925965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_prevlinkhdr_check(cstate); 4926965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ehostop(cstate, eaddr, Q_OR); 4927d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (b1 != NULL) 4928d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b1, b0); 4929511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4930511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_FDDI: 4931965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_fhostop(cstate, eaddr, Q_OR); 4932511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802: 4934965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_thostop(cstate, eaddr, Q_OR); 4935511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802_11: 4937511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 4938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802_11_RADIO_AVS: 4939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802_11_RADIO: 4940511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PPI: 4941965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_wlanhostop(cstate, eaddr, Q_OR); 4942511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4943511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_SUNATM: 4944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 4945d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * This is LLC-multiplexed traffic; if it were 4946965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * LANE, cstate->linktype would have been set to 4947d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * DLT_EN10MB. 4948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 4949965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, 4950d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes "'gateway' supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel"); 4951511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IP_OVER_FC: 4953965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ipfchostop(cstate, eaddr, Q_OR); 4954511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 4955511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 4956965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, 4957511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "'gateway' supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel"); 4958511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 4959965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_host(cstate, **alist++, 0xffffffff, proto, Q_OR, Q_HOST); 4960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (*alist) { 4961965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_host(cstate, **alist++, 0xffffffff, proto, Q_OR, 4962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project Q_HOST); 4963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, tmp); 4964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b1 = tmp; 4965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b1); 4967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 4968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 4969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 4970965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "illegal modifier of 'gateway'"); 4971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 4972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 4973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 4974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 4976965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_proto_abbrev(compiler_state_t *cstate, int proto) 4977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 4978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0; 4979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b1; 4980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4981478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 4982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCTP: 4984965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, IPPROTO_SCTP, Q_IP, Q_DEFAULT); 4985965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, IPPROTO_SCTP, Q_IPV6, Q_DEFAULT); 4986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 4987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_TCP: 4990965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, IPPROTO_TCP, Q_IP, Q_DEFAULT); 4991965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, IPPROTO_TCP, Q_IPV6, Q_DEFAULT); 4992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 4993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 4994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 4995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_UDP: 4996965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, IPPROTO_UDP, Q_IP, Q_DEFAULT); 4997965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, IPPROTO_UDP, Q_IPV6, Q_DEFAULT); 4998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 4999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMP: 5002965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, IPPROTO_ICMP, Q_IP, Q_DEFAULT); 5003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_IGMP 5006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_IGMP 2 5007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 5008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGMP: 5010965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, IPPROTO_IGMP, Q_IP, Q_DEFAULT); 5011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_IGRP 5014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_IGRP 9 5015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 5016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGRP: 5017965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, IPPROTO_IGRP, Q_IP, Q_DEFAULT); 5018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_PIM 5021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_PIM 103 5022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 5023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PIM: 5025965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, IPPROTO_PIM, Q_IP, Q_DEFAULT); 5026965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, IPPROTO_PIM, Q_IPV6, Q_DEFAULT); 5027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_VRRP 5031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_VRRP 112 5032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 5033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_VRRP: 5035965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, IPPROTO_VRRP, Q_IP, Q_DEFAULT); 5036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5038511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef IPPROTO_CARP 5039511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IPPROTO_CARP 112 5040511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 5041511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 5042511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_CARP: 5043965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, IPPROTO_CARP, Q_IP, Q_DEFAULT); 5044511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 5045511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 5046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 5047965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_linktype(cstate, ETHERTYPE_IP); 5048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ARP: 5051965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_linktype(cstate, ETHERTYPE_ARP); 5052478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RARP: 5055965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_linktype(cstate, ETHERTYPE_REVARP); 5056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LINK: 5059965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "link layer applied in wrong context"); 5060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ATALK: 5062965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_linktype(cstate, ETHERTYPE_ATALK); 5063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5065478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AARP: 5066965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_linktype(cstate, ETHERTYPE_AARP); 5067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DECNET: 5070965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_linktype(cstate, ETHERTYPE_DN); 5071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCA: 5074965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_linktype(cstate, ETHERTYPE_SCA); 5075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LAT: 5078965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_linktype(cstate, ETHERTYPE_LAT); 5079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPDL: 5082965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_linktype(cstate, ETHERTYPE_MOPDL); 5083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPRC: 5086965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_linktype(cstate, ETHERTYPE_MOPRC); 5087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 5090965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_linktype(cstate, ETHERTYPE_IPV6); 5091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_ICMPV6 5094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_ICMPV6 58 5095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 5096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMPV6: 5097965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, IPPROTO_ICMPV6, Q_IPV6, Q_DEFAULT); 5098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5099478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_AH 5101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_AH 51 5102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 5103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AH: 5104965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, IPPROTO_AH, Q_IP, Q_DEFAULT); 5105965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, IPPROTO_AH, Q_IPV6, Q_DEFAULT); 5106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_ESP 5110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_ESP 50 5111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 5112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ESP: 5113965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, IPPROTO_ESP, Q_IP, Q_DEFAULT); 5114965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, IPPROTO_ESP, Q_IPV6, Q_DEFAULT); 5115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISO: 5119965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_linktype(cstate, LLCSAP_ISONS); 5120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ESIS: 5123965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, ISO9542_ESIS, Q_ISO, Q_DEFAULT); 5124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS: 5127965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, ISO10589_ISIS, Q_ISO, Q_DEFAULT); 5128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS_L1: /* all IS-IS Level1 PDU-Types */ 5131965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT); 5132965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */ 5133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5134965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, ISIS_L1_LSP, Q_ISIS, Q_DEFAULT); 5135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5136965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT); 5137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5138965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT); 5139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS_L2: /* all IS-IS Level2 PDU-Types */ 5143965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT); 5144965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */ 5145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5146965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, ISIS_L2_LSP, Q_ISIS, Q_DEFAULT); 5147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5148965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT); 5149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5150965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT); 5151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS_IIH: /* all IS-IS Hello PDU-Types */ 5155965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT); 5156965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT); 5157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5158965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); 5159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS_LSP: 5163965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, ISIS_L1_LSP, Q_ISIS, Q_DEFAULT); 5164965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, ISIS_L2_LSP, Q_ISIS, Q_DEFAULT); 5165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS_SNP: 5169965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT); 5170965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT); 5171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5172965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT); 5173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5174965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT); 5175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS_CSNP: 5179965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT); 5180965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT); 5181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS_PSNP: 5185965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT); 5186965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT); 5187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_CLNP: 5191965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, ISO8473_CLNP, Q_ISO, Q_DEFAULT); 5192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_STP: 5195965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_linktype(cstate, LLCSAP_8021D); 5196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPX: 5199965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_linktype(cstate, LLCSAP_IPX); 5200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_NETBEUI: 5203965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_linktype(cstate, LLCSAP_NETBEUI); 5204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RADIO: 5207965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'radio' is not a valid protocol type"); 5208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 5211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5216965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_ipfrag(compiler_state_t *cstate) 5217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s; 5219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 5220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* not IPv4 frag other than the first frag */ 5222965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKPL, 6, BPF_H); 5223965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = new_block(cstate, JMP(BPF_JSET)); 5224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->s.k = 0x1fff; 5225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->stmts = s; 5226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b); 5227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 5229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 5232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate a comparison to a port value in the transport-layer header 5233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * at the specified offset from the beginning of that header. 5234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - this handles a variable-length prefix preceding the link-layer 5236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header, such as the radiotap or AVS radio prefix, but doesn't handle 5237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * variable-length link-layer headers (such as Token Ring or 802.11 5238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * headers). 5239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5241965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_portatom(compiler_state_t *cstate, int off, bpf_int32 v) 5242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5243965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_cmp(cstate, OR_TRAN_IPV4, off, BPF_H, v); 5244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5247965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_portatom6(compiler_state_t *cstate, int off, bpf_int32 v) 5248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5249965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_cmp(cstate, OR_TRAN_IPV6, off, BPF_H, v); 5250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 5253965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_portop(compiler_state_t *cstate, int port, int proto, int dir) 5254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *tmp; 5256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5257511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* ip proto 'proto' and not a fragment other than the first fragment */ 5258965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_cmp(cstate, OR_LINKPL, 9, BPF_B, (bpf_int32)proto); 5259965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ipfrag(cstate); 5260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b0); 5261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 5263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 5264965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portatom(cstate, 0, (bpf_int32)port); 5265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 5268965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portatom(cstate, 2, (bpf_int32)port); 5269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 5272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 5273965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_portatom(cstate, 0, (bpf_int32)port); 5274965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portatom(cstate, 2, (bpf_int32)port); 5275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 5279965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_portatom(cstate, 0, (bpf_int32)port); 5280965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portatom(cstate, 2, (bpf_int32)port); 5281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b1); 5282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 5286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5293965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_port(compiler_state_t *cstate, int port, int ip_proto, int dir) 5294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *tmp; 5296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ether proto ip 5299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For FDDI, RFC 1188 says that SNAP encapsulation is used, 5301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * not LLC encapsulation with LLCSAP_IP. 5302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For IEEE 802 networks - which includes 802.5 token ring 5304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (which is what DLT_IEEE802 means) and 802.11 - RFC 1042 5305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * says that SNAP encapsulation is used, not LLC encapsulation 5306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with LLCSAP_IP. 5307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For LLC-encapsulated ATM/"Classical IP", RFC 1483 and 5309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * RFC 2225 say that SNAP encapsulation is used, not LLC 5310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * encapsulation with LLCSAP_IP. 5311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * So we always check for ETHERTYPE_IP. 5313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5314965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, ETHERTYPE_IP); 5315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (ip_proto) { 5317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_UDP: 5318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_TCP: 5319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_SCTP: 5320965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portop(cstate, port, ip_proto, dir); 5321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case PROTO_UNDEF: 5324965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_portop(cstate, port, IPPROTO_TCP, dir); 5325965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portop(cstate, port, IPPROTO_UDP, dir); 5326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5327965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_portop(cstate, port, IPPROTO_SCTP, dir); 5328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 5333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 5339965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_portop6(compiler_state_t *cstate, int port, int proto, int dir) 5340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *tmp; 5342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* ip6 proto 'proto' */ 5344511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* XXX - catch the first fragment of a fragmented packet? */ 5345965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, (bpf_int32)proto); 5346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 5348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 5349965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portatom6(cstate, 0, (bpf_int32)port); 5350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 5353965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portatom6(cstate, 2, (bpf_int32)port); 5354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 5357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 5358965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_portatom6(cstate, 0, (bpf_int32)port); 5359965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portatom6(cstate, 2, (bpf_int32)port); 5360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 5364965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_portatom6(cstate, 0, (bpf_int32)port); 5365965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portatom6(cstate, 2, (bpf_int32)port); 5366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b1); 5367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 5371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5378965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_port6(compiler_state_t *cstate, int port, int ip_proto, int dir) 5379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *tmp; 5381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* link proto ip6 */ 5383965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, ETHERTYPE_IPV6); 5384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (ip_proto) { 5386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_UDP: 5387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_TCP: 5388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_SCTP: 5389965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portop6(cstate, port, ip_proto, dir); 5390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case PROTO_UNDEF: 5393965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_portop6(cstate, port, IPPROTO_TCP, dir); 5394965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portop6(cstate, port, IPPROTO_UDP, dir); 5395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5396965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_portop6(cstate, port, IPPROTO_SCTP, dir); 5397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 5402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* gen_portrange code */ 5408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5409965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_portrangeatom(compiler_state_t *cstate, int off, bpf_int32 v1, 5410965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_int32 v2) 5411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b1, *b2; 5413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (v1 > v2) { 5415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Reverse the order of the ports, so v1 is the lower one. 5417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 vtemp; 5419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project vtemp = v1; 5421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v1 = v2; 5422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v2 = vtemp; 5423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5425965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp_ge(cstate, OR_TRAN_IPV4, off, BPF_H, v1); 5426965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b2 = gen_cmp_le(cstate, OR_TRAN_IPV4, off, BPF_H, v2); 5427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5428d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b1, b2); 5429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b2; 5431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 5434965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_portrangeop(compiler_state_t *cstate, int port1, int port2, int proto, 5435965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int dir) 5436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *tmp; 5438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5439511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* ip proto 'proto' and not a fragment other than the first fragment */ 5440965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_cmp(cstate, OR_LINKPL, 9, BPF_B, (bpf_int32)proto); 5441965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ipfrag(cstate); 5442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b0); 5443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 5445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 5446965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portrangeatom(cstate, 0, (bpf_int32)port1, (bpf_int32)port2); 5447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 5450965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portrangeatom(cstate, 2, (bpf_int32)port1, (bpf_int32)port2); 5451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 5454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 5455965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_portrangeatom(cstate, 0, (bpf_int32)port1, (bpf_int32)port2); 5456965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portrangeatom(cstate, 2, (bpf_int32)port1, (bpf_int32)port2); 5457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 5461965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_portrangeatom(cstate, 0, (bpf_int32)port1, (bpf_int32)port2); 5462965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portrangeatom(cstate, 2, (bpf_int32)port1, (bpf_int32)port2); 5463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b1); 5464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 5468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5475965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_portrange(compiler_state_t *cstate, int port1, int port2, int ip_proto, 5476965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int dir) 5477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *tmp; 5479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* link proto ip */ 5481965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, ETHERTYPE_IP); 5482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (ip_proto) { 5484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_UDP: 5485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_TCP: 5486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_SCTP: 5487965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portrangeop(cstate, port1, port2, ip_proto, dir); 5488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case PROTO_UNDEF: 5491965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_portrangeop(cstate, port1, port2, IPPROTO_TCP, dir); 5492965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portrangeop(cstate, port1, port2, IPPROTO_UDP, dir); 5493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5494965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_portrangeop(cstate, port1, port2, IPPROTO_SCTP, dir); 5495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 5500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5506965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_portrangeatom6(compiler_state_t *cstate, int off, bpf_int32 v1, 5507965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_int32 v2) 5508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b1, *b2; 5510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (v1 > v2) { 5512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Reverse the order of the ports, so v1 is the lower one. 5514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_int32 vtemp; 5516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project vtemp = v1; 5518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v1 = v2; 5519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v2 = vtemp; 5520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5522965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp_ge(cstate, OR_TRAN_IPV6, off, BPF_H, v1); 5523965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b2 = gen_cmp_le(cstate, OR_TRAN_IPV6, off, BPF_H, v2); 5524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5525d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b1, b2); 5526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b2; 5528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 5531965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_portrangeop6(compiler_state_t *cstate, int port1, int port2, int proto, 5532965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int dir) 5533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *tmp; 5535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* ip6 proto 'proto' */ 5537511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* XXX - catch the first fragment of a fragmented packet? */ 5538965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, (bpf_int32)proto); 5539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 5541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 5542965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portrangeatom6(cstate, 0, (bpf_int32)port1, (bpf_int32)port2); 5543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 5546965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portrangeatom6(cstate, 2, (bpf_int32)port1, (bpf_int32)port2); 5547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 5550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 5551965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_portrangeatom6(cstate, 0, (bpf_int32)port1, (bpf_int32)port2); 5552965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portrangeatom6(cstate, 2, (bpf_int32)port1, (bpf_int32)port2); 5553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 5557965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_portrangeatom6(cstate, 0, (bpf_int32)port1, (bpf_int32)port2); 5558965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portrangeatom6(cstate, 2, (bpf_int32)port1, (bpf_int32)port2); 5559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b1); 5560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 5564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5571965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_portrange6(compiler_state_t *cstate, int port1, int port2, int ip_proto, 5572965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int dir) 5573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *tmp; 5575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* link proto ip6 */ 5577965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, ETHERTYPE_IPV6); 5578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (ip_proto) { 5580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_UDP: 5581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_TCP: 5582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case IPPROTO_SCTP: 5583965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portrangeop6(cstate, port1, port2, ip_proto, dir); 5584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case PROTO_UNDEF: 5587965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_portrangeop6(cstate, port1, port2, IPPROTO_TCP, dir); 5588965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_portrangeop6(cstate, port1, port2, IPPROTO_UDP, dir); 5589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5590965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_portrangeop6(cstate, port1, port2, IPPROTO_SCTP, dir); 5591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(tmp, b1); 5592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 5596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 5598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 5602965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hugheslookup_proto(compiler_state_t *cstate, const char *name, int proto) 5603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int v; 5605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 5607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 5609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 5610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 5611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = pcap_nametoproto(name); 5612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (v == PROTO_UNDEF) 5613965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "unknown ip proto '%s'", name); 5614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LINK: 5617965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* XXX should look up h/w protocol type based on cstate->linktype */ 5618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = pcap_nametoeproto(name); 5619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (v == PROTO_UNDEF) { 5620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = pcap_nametollc(name); 5621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (v == PROTO_UNDEF) 5622965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "unknown ether proto '%s'", name); 5623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISO: 5627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (strcmp(name, "esis") == 0) 5628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = ISO9542_ESIS; 5629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (strcmp(name, "isis") == 0) 5630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = ISO10589_ISIS; 5631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (strcmp(name, "clnp") == 0) 5632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = ISO8473_CLNP; 5633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 5634965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "unknown osi proto '%s'", name); 5635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = PROTO_UNDEF; 5639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return v; 5642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if 0 5645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct stmt * 5646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_joinsp(s, n) 5647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct stmt **s; 5648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int n; 5649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return NULL; 5651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 5653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5655965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_protochain(compiler_state_t *cstate, int v, int proto, int dir) 5656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef NO_PROTOCHAIN 5658965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_proto(cstate, v, proto, dir); 5659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 5660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b; 5661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s[100]; 5662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int fix2, fix3, fix4, fix5; 5663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int ahcheck, again, end; 5664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int i, max; 5665965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int reg2 = alloc_reg(cstate); 5666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(s, 0, sizeof(s)); 5668965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes fix3 = fix4 = fix5 = 0; 5669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 5671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 5672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 5673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 5675965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_protochain(cstate, v, Q_IP, dir); 5676965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = gen_protochain(cstate, v, Q_IPV6, dir); 5677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b); 5678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 5679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5680965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "bad protocol applied for 'protochain'"); 5681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 5682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5685511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * We don't handle variable-length prefixes before the link-layer 5686511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * header, or variable-length link-layer headers, here yet. 5687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We might want to add BPF instructions to do the protochain 5688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * work, to simplify that and, on platforms that have a BPF 5689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * interpreter with the new instructions, let the filtering 5690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * be done in the kernel. (We already require a modified BPF 5691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * engine to do the protochain stuff, to support backward 5692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * branches, and backward branch support is unlikely to appear 5693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in kernel BPF engines.) 5694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5695965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_linkpl.is_variable) 5696965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'protochain' not supported with variable length headers"); 5697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5698965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->no_optimize = 1; /*this code is not compatible with optimzer yet */ 5699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * s[0] is a dummy entry to protect other BPF insn from damage 5702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * by s[fix] = foo with uninitialized variable "fix". It is somewhat 5703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * hard to find interdependency made by jump table fixup. 5704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i = 0; 5706965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, 0); /*dummy*/ 5707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 5710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 5711965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, ETHERTYPE_IP); 5712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A = ip->ip_p */ 5714965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_LD|BPF_ABS|BPF_B); 5715965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i]->s.k = cstate->off_linkpl.constant_part + cstate->off_nl + 9; 5716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* X = ip->ip_hl << 2 */ 5718965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_LDX|BPF_MSH|BPF_B); 5719965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i]->s.k = cstate->off_linkpl.constant_part + cstate->off_nl; 5720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5722511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 5723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 5724965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, ETHERTYPE_IPV6); 5725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A = ip6->ip_nxt */ 5727965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_LD|BPF_ABS|BPF_B); 5728965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i]->s.k = cstate->off_linkpl.constant_part + cstate->off_nl + 6; 5729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* X = sizeof(struct ip6_hdr) */ 5731965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_LDX|BPF_IMM); 5732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = 40; 5733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 5735511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 5736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 5737965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "unsupported proto to gen_protochain"); 5738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 5739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* again: if (A == v) goto end; else fall through; */ 5742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project again = i; 5743965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_JMP|BPF_JEQ|BPF_K); 5744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = v; 5745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jt = NULL; /*later*/ 5746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jf = NULL; /*update in next stmt*/ 5747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fix5 = i; 5748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_NONE 5751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_NONE 59 5752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 5753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* if (A == IPPROTO_NONE) goto end */ 5754965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_JMP|BPF_JEQ|BPF_K); 5755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jt = NULL; /*later*/ 5756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jf = NULL; /*update in next stmt*/ 5757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = IPPROTO_NONE; 5758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[fix5]->s.jf = s[i]; 5759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fix2 = i; 5760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_IPV6) { 5763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int v6start, v6end, v6advance, j; 5764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v6start = i; 5766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* if (A == IPPROTO_HOPOPTS) goto v6advance */ 5767965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_JMP|BPF_JEQ|BPF_K); 5768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jt = NULL; /*later*/ 5769478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jf = NULL; /*update in next stmt*/ 5770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = IPPROTO_HOPOPTS; 5771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[fix2]->s.jf = s[i]; 5772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* if (A == IPPROTO_DSTOPTS) goto v6advance */ 5774965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i - 1]->s.jf = s[i] = new_stmt(cstate, BPF_JMP|BPF_JEQ|BPF_K); 5775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jt = NULL; /*later*/ 5776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jf = NULL; /*update in next stmt*/ 5777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = IPPROTO_DSTOPTS; 5778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* if (A == IPPROTO_ROUTING) goto v6advance */ 5780965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i - 1]->s.jf = s[i] = new_stmt(cstate, BPF_JMP|BPF_JEQ|BPF_K); 5781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jt = NULL; /*later*/ 5782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jf = NULL; /*update in next stmt*/ 5783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = IPPROTO_ROUTING; 5784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* if (A == IPPROTO_FRAGMENT) goto v6advance; else goto ahcheck; */ 5786965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i - 1]->s.jf = s[i] = new_stmt(cstate, BPF_JMP|BPF_JEQ|BPF_K); 5787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jt = NULL; /*later*/ 5788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jf = NULL; /*later*/ 5789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = IPPROTO_FRAGMENT; 5790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fix3 = i; 5791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v6end = i; 5792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* v6advance: */ 5795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v6advance = i; 5796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in short, 5799511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * A = P[X + packet head]; 5800511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * X = X + (P[X + packet head + 1] + 1) * 8; 5801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A = P[X + packet head] */ 5803965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_LD|BPF_IND|BPF_B); 5804965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i]->s.k = cstate->off_linkpl.constant_part + cstate->off_nl; 5805478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* MEM[reg2] = A */ 5807965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_ST); 5808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = reg2; 5809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5810511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* A = P[X + packet head + 1]; */ 5811965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_LD|BPF_IND|BPF_B); 5812965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i]->s.k = cstate->off_linkpl.constant_part + cstate->off_nl + 1; 5813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A += 1 */ 5815965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_K); 5816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = 1; 5817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5818478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A *= 8 */ 5819965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_ALU|BPF_MUL|BPF_K); 5820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = 8; 5821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5822511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* A += X */ 5823965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_X); 5824511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s[i]->s.k = 0; 5825511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall i++; 5826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* X = A; */ 5827965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_MISC|BPF_TAX); 5828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A = MEM[reg2] */ 5830965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_LD|BPF_MEM); 5831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = reg2; 5832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* goto again; (must use BPF_JA for backward jump) */ 5835965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_JMP|BPF_JA); 5836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = again - i - 1; 5837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i - 1]->s.jf = s[i]; 5838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* fixup */ 5841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project for (j = v6start; j <= v6end; j++) 5842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[j]->s.jt = s[v6advance]; 5843511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else { 5844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* nop */ 5845965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_K); 5846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = 0; 5847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[fix2]->s.jf = s[i]; 5848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5849478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 5850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* ahcheck: */ 5852478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ahcheck = i; 5853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* if (A == IPPROTO_AH) then fall through; else goto end; */ 5854965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_JMP|BPF_JEQ|BPF_K); 5855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jt = NULL; /*later*/ 5856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.jf = NULL; /*later*/ 5857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = IPPROTO_AH; 5858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (fix3) 5859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[fix3]->s.jf = s[ahcheck]; 5860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fix4 = i; 5861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in short, 5865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * A = P[X]; 5866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * X = X + (P[X + 1] + 2) * 4; 5867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A = X */ 5869965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i - 1]->s.jt = s[i] = new_stmt(cstate, BPF_MISC|BPF_TXA); 5870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A = P[X + packet head]; */ 5872965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_LD|BPF_IND|BPF_B); 5873965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i]->s.k = cstate->off_linkpl.constant_part + cstate->off_nl; 5874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* MEM[reg2] = A */ 5876965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_ST); 5877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = reg2; 5878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A = X */ 5880965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i - 1]->s.jt = s[i] = new_stmt(cstate, BPF_MISC|BPF_TXA); 5881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A += 1 */ 5883965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_K); 5884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = 1; 5885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* X = A */ 5887965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_MISC|BPF_TAX); 5888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A = P[X + packet head] */ 5890965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_LD|BPF_IND|BPF_B); 5891965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i]->s.k = cstate->off_linkpl.constant_part + cstate->off_nl; 5892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A += 2 */ 5894965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_K); 5895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = 2; 5896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A *= 4 */ 5898965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_ALU|BPF_MUL|BPF_K); 5899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = 4; 5900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* X = A; */ 5902965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_MISC|BPF_TAX); 5903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* A = MEM[reg2] */ 5905965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_LD|BPF_MEM); 5906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = reg2; 5907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* goto again; (must use BPF_JA for backward jump) */ 5910965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_JMP|BPF_JA); 5911478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = again - i - 1; 5912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5914478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* end: nop */ 5915478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project end = i; 5916965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s[i] = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_K); 5917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->s.k = 0; 5918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[fix2]->s.jt = s[end]; 5919478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[fix4]->s.jf = s[end]; 5920478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[fix5]->s.jt = s[end]; 5921478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project i++; 5922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5923478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5924478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * make slist chain 5925478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5926478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project max = i; 5927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project for (i = 0; i < max - 1; i++) 5928478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[i]->next = s[i + 1]; 5929478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s[max - 1]->next = NULL; 5930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 5932478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * emit final check 5933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5934965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = new_block(cstate, JMP(BPF_JEQ)); 5935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->stmts = s[1]; /*remember, s[0] is dummy*/ 5936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->s.k = v; 5937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5938965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes free_reg(cstate, reg2); 5939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b); 5941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 5942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 5943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 5944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5945511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct block * 5946965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_check_802_11_data_frame(compiler_state_t *cstate) 5947511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 5948511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct slist *s; 5949511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct block *b0, *b1; 5950511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 5951511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 5952511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * A data frame has the 0x08 bit (b3) in the frame control field set 5953511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * and the 0x04 bit (b2) clear. 5954511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 5955965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 0, BPF_B); 5956965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = new_block(cstate, JMP(BPF_JSET)); 5957511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0->s.k = 0x08; 5958511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0->stmts = s; 5959d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 5960965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 0, BPF_B); 5961965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = new_block(cstate, JMP(BPF_JSET)); 5962511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->s.k = 0x04; 5963511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->stmts = s; 5964511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b1); 5965511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 5966511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b1, b0); 5967511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 5968511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return b0; 5969511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 5970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 5972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code that checks whether the packet is a packet for protocol 5973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * <proto> and whether the type field in that protocol's header has 5974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the value <v>, e.g. if <proto> is Q_IP, it checks whether it's an 5975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * IP packet and checks the protocol number in the IP header against <v>. 5976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If <proto> is Q_DEFAULT, i.e. just "proto" was specified, it checks 5978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * against Q_IP and Q_IPV6. 5979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 5980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 5981965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_proto(compiler_state_t *cstate, int v, int proto, int dir) 5982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 5983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 5984511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef CHASE_CHAIN 5985511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct block *b2; 5986511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 5987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (dir != Q_DEFAULT) 5989965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "direction applied to 'proto'"); 5990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 5991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 5992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 5993965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, v, Q_IP, dir); 5994965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_proto(cstate, v, Q_IPV6, dir); 5995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 5996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 5997511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 5998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 5999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For FDDI, RFC 1188 says that SNAP encapsulation is used, 6001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * not LLC encapsulation with LLCSAP_IP. 6002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 6003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For IEEE 802 networks - which includes 802.5 token ring 6004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (which is what DLT_IEEE802 means) and 802.11 - RFC 1042 6005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * says that SNAP encapsulation is used, not LLC encapsulation 6006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with LLCSAP_IP. 6007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 6008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For LLC-encapsulated ATM/"Classical IP", RFC 1483 and 6009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * RFC 2225 say that SNAP encapsulation is used, not LLC 6010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * encapsulation with LLCSAP_IP. 6011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 6012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * So we always check for ETHERTYPE_IP. 6013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6014965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, ETHERTYPE_IP); 6015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef CHASE_CHAIN 6016965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp(cstate, OR_LINKPL, 9, BPF_B, (bpf_int32)v); 6017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 6018965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_protochain(cstate, v, Q_IP); 6019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 6020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 6021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 6022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISO: 6024965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes switch (cstate->linktype) { 6025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_FRELAY: 6027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Frame Relay packets typically have an OSI 6029965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * NLPID at the beginning; "gen_linktype(cstate, LLCSAP_ISONS)" 6030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * generates code to check for all the OSI 6031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * NLPIDs, so calling it and then adding a check 6032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * for the particular NLPID for which we're 6033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * looking is bogus, as we can just check for 6034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the NLPID. 6035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 6036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * What we check for is the NLPID and a frame 6037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * control field value of UI, i.e. 0x03 followed 6038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * by the NLPID. 6039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 6040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - assumes a 2-byte Frame Relay header with 6041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DLCI and flags. What if the address is longer? 6042478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 6043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - what about SNAP-encapsulated frames? 6044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6045965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_cmp(cstate, OR_LINKHDR, 2, BPF_H, (0x03<<8) | v); 6046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 6047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 6048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_C_HDLC: 6050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Cisco uses an Ethertype lookalike - for OSI, 6052478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * it's 0xfefe. 6053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6054965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, LLCSAP_ISONS<<8 | LLCSAP_ISONS); 6055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* OSI in C-HDLC is stuffed with a fudge byte */ 6056965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 1, BPF_B, (long)v); 6057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 6058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 6059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 6061965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, LLCSAP_ISONS); 6062965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 0, BPF_B, (long)v); 6063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 6064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 6065478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6066478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ISIS: 6068965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_proto(cstate, ISO10589_ISIS, Q_ISO, Q_DEFAULT); 6069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4 is the offset of the PDU type relative to the IS-IS 6071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header. 6072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6073965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 4, BPF_B, (long)v); 6074478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 6075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 6076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ARP: 6078965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "arp does not encapsulate another protocol"); 6079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RARP: 6082965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "rarp does not encapsulate another protocol"); 6083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ATALK: 6086965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "atalk encapsulation is not specifiable"); 6087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DECNET: 6090965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "decnet encapsulation is not specifiable"); 6091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCA: 6094965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "sca does not encapsulate another protocol"); 6095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LAT: 6098965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "lat does not encapsulate another protocol"); 6099478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPRC: 6102965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "moprc does not encapsulate another protocol"); 6103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPDL: 6106965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "mopdl does not encapsulate another protocol"); 6107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LINK: 6110965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_linktype(cstate, v); 6111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_UDP: 6113965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'udp proto' is bogus"); 6114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_TCP: 6117965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'tcp proto' is bogus"); 6118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCTP: 6121965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'sctp proto' is bogus"); 6122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMP: 6125965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'icmp proto' is bogus"); 6126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGMP: 6129965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'igmp proto' is bogus"); 6130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGRP: 6133965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'igrp proto' is bogus"); 6134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PIM: 6137965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'pim proto' is bogus"); 6138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_VRRP: 6141965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'vrrp proto' is bogus"); 6142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6144511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_CARP: 6145965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'carp proto' is bogus"); 6146511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NOTREACHED */ 6147511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 6148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 6149965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, ETHERTYPE_IPV6); 6150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef CHASE_CHAIN 6151511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 6152511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Also check for a fragment header before the final 6153511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * header. 6154511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 6155965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b2 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, IPPROTO_FRAGMENT); 6156965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp(cstate, OR_LINKPL, 40, BPF_B, (bpf_int32)v); 6157511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b2, b1); 6158965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b2 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, (bpf_int32)v); 6159511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_or(b2, b1); 6160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 6161965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_protochain(cstate, v, Q_IPV6); 6162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 6163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 6164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 6165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMPV6: 6167965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'icmp6 proto' is bogus"); 6168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AH: 6170965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'ah proto' is bogus"); 6171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ESP: 6173965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'ah proto' is bogus"); 6174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_STP: 6176965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'stp proto' is bogus"); 6177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPX: 6179965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'ipx proto' is bogus"); 6180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_NETBEUI: 6182965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'netbeui proto' is bogus"); 6183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RADIO: 6185965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'radio proto' is bogus"); 6186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 6188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 6189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 6195965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_scode(compiler_state_t *cstate, const char *name, struct qual q) 6196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int proto = q.proto; 6198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir = q.dir; 6199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int tproto; 6200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_char *eaddr; 6201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 mask, addr; 6202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef INET6 6203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 **alist; 6204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 6205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int tproto6; 6206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct sockaddr_in *sin4; 6207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct sockaddr_in6 *sin6; 6208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct addrinfo *res, *res0; 6209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct in6_addr mask128; 6210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /*INET6*/ 6211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b, *tmp; 6212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int port, real_proto; 6213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int port1, port2; 6214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (q.addr) { 6216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_NET: 6218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project addr = pcap_nametonetaddr(name); 6219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (addr == 0) 6220965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "unknown network '%s'", name); 6221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Left justify network addr and calculate its network mask */ 6222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project mask = 0xffffffff; 6223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (addr && (addr & 0xff000000) == 0) { 6224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project addr <<= 8; 6225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project mask <<= 8; 6226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6227965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_host(cstate, addr, mask, proto, dir, q.addr); 6228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 6230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_HOST: 6231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_LINK) { 6232965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes switch (cstate->linktype) { 6233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_EN10MB: 6235511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER: 6236511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER_TRANSPARENT: 6237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project eaddr = pcap_ether_hostton(name); 6238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (eaddr == NULL) 6239965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, 6240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "unknown ether host '%s'", name); 6241965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_prevlinkhdr_check(cstate); 6242965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = gen_ehostop(cstate, eaddr, dir); 6243d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (tmp != NULL) 6244d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(tmp, b); 6245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(eaddr); 6246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_FDDI: 6249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project eaddr = pcap_ether_hostton(name); 6250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (eaddr == NULL) 6251965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, 6252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "unknown FDDI host '%s'", name); 6253965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = gen_fhostop(cstate, eaddr, dir); 6254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(eaddr); 6255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802: 6258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project eaddr = pcap_ether_hostton(name); 6259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (eaddr == NULL) 6260965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, 6261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "unknown token ring host '%s'", name); 6262965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = gen_thostop(cstate, eaddr, dir); 6263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(eaddr); 6264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802_11: 6267511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 6268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802_11_RADIO_AVS: 6269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IEEE802_11_RADIO: 6270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPI: 6271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project eaddr = pcap_ether_hostton(name); 6272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (eaddr == NULL) 6273965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, 6274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "unknown 802.11 host '%s'", name); 6275965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = gen_wlanhostop(cstate, eaddr, dir); 6276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(eaddr); 6277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_IP_OVER_FC: 6280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project eaddr = pcap_ether_hostton(name); 6281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (eaddr == NULL) 6282965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, 6283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "unknown Fibre Channel host '%s'", name); 6284965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = gen_ipfchostop(cstate, eaddr, dir); 6285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(eaddr); 6286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6289965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "only ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel supports link-level host name"); 6290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else if (proto == Q_DECNET) { 6291965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes unsigned short dn_addr; 6292965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 6293965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (!__pcap_nametodnaddr(name, &dn_addr)) { 6294965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifdef DECNETLIB 6295965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "unknown decnet host name '%s'\n", name); 6296965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#else 6297965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "decnet name support not included, '%s' cannot be translated\n", 6298965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes name); 6299965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif 6300965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes } 6301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * I don't think DECNET hosts can be multihomed, so 6303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * there is no need to build up a list of addresses 6304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6305965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return (gen_host(cstate, dn_addr, 0, proto, dir, q.addr)); 6306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 6307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef INET6 6308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project alist = pcap_nametoaddr(name); 6309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (alist == NULL || *alist == NULL) 6310965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "unknown host '%s'", name); 6311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tproto = proto; 6312965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_linktype.constant_part == OFFSET_NOT_SET && 6313d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes tproto == Q_DEFAULT) 6314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tproto = Q_IP; 6315965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = gen_host(cstate, **alist++, 0xffffffff, tproto, dir, q.addr); 6316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (*alist) { 6317965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_host(cstate, **alist++, 0xffffffff, 6318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tproto, dir, q.addr); 6319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b, tmp); 6320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = tmp; 6321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 6324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(&mask128, 0xff, sizeof(mask128)); 6325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project res0 = res = pcap_nametoaddrinfo(name); 6326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (res == NULL) 6327965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "unknown host '%s'", name); 6328965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->ai = res; 6329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = tmp = NULL; 6330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tproto = tproto6 = proto; 6331965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_linktype.constant_part == OFFSET_NOT_SET && 6332d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes tproto == Q_DEFAULT) { 6333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tproto = Q_IP; 6334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tproto6 = Q_IPV6; 6335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project for (res = res0; res; res = res->ai_next) { 6337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (res->ai_family) { 6338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case AF_INET: 6339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (tproto == Q_IPV6) 6340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 6341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sin4 = (struct sockaddr_in *) 6343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project res->ai_addr; 6344965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_host(cstate, ntohl(sin4->sin_addr.s_addr), 6345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 0xffffffff, tproto, dir, q.addr); 6346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 6347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case AF_INET6: 6348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (tproto6 == Q_IP) 6349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 6350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sin6 = (struct sockaddr_in6 *) 6352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project res->ai_addr; 6353965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_host6(cstate, &sin6->sin6_addr, 6354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project &mask128, tproto6, dir, q.addr); 6355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 6356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 6357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 6358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (b) 6360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b, tmp); 6361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = tmp; 6362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6363965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->ai = NULL; 6364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project freeaddrinfo(res0); 6365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (b == NULL) { 6366965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "unknown host '%s'%s", name, 6367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (proto == Q_DEFAULT) 6368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ? "" 6369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project : " for specified address family"); 6370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /*INET6*/ 6373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PORT: 6376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto != Q_DEFAULT && 6377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto != Q_UDP && proto != Q_TCP && proto != Q_SCTP) 6378965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "illegal qualifier of 'port'"); 6379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (pcap_nametoport(name, &port, &real_proto) == 0) 6380965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "unknown port '%s'", name); 6381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_UDP) { 6382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (real_proto == IPPROTO_TCP) 6383965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "port '%s' is tcp", name); 6384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (real_proto == IPPROTO_SCTP) 6385965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "port '%s' is sctp", name); 6386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* override PROTO_UNDEF */ 6388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project real_proto = IPPROTO_UDP; 6389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_TCP) { 6391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (real_proto == IPPROTO_UDP) 6392965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "port '%s' is udp", name); 6393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (real_proto == IPPROTO_SCTP) 6395965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "port '%s' is sctp", name); 6396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* override PROTO_UNDEF */ 6398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project real_proto = IPPROTO_TCP; 6399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_SCTP) { 6401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (real_proto == IPPROTO_UDP) 6402965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "port '%s' is udp", name); 6403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (real_proto == IPPROTO_TCP) 6405965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "port '%s' is tcp", name); 6406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* override PROTO_UNDEF */ 6408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project real_proto = IPPROTO_SCTP; 6409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6410511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (port < 0) 6411965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "illegal port number %d < 0", port); 6412511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (port > 65535) 6413965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "illegal port number %d > 65535", port); 6414965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = gen_port(cstate, port, real_proto, dir); 6415965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes gen_or(gen_port6(cstate, port, real_proto, dir), b); 6416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PORTRANGE: 6419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto != Q_DEFAULT && 6420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto != Q_UDP && proto != Q_TCP && proto != Q_SCTP) 6421965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "illegal qualifier of 'portrange'"); 6422d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (pcap_nametoportrange(name, &port1, &port2, &real_proto) == 0) 6423965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "unknown port in range '%s'", name); 6424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_UDP) { 6425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (real_proto == IPPROTO_TCP) 6426965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "port in range '%s' is tcp", name); 6427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (real_proto == IPPROTO_SCTP) 6428965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "port in range '%s' is sctp", name); 6429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* override PROTO_UNDEF */ 6431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project real_proto = IPPROTO_UDP; 6432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_TCP) { 6434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (real_proto == IPPROTO_UDP) 6435965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "port in range '%s' is udp", name); 6436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (real_proto == IPPROTO_SCTP) 6437965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "port in range '%s' is sctp", name); 6438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* override PROTO_UNDEF */ 6440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project real_proto = IPPROTO_TCP; 6441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_SCTP) { 6443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (real_proto == IPPROTO_UDP) 6444965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "port in range '%s' is udp", name); 6445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (real_proto == IPPROTO_TCP) 6446965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "port in range '%s' is tcp", name); 6447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* override PROTO_UNDEF */ 6449d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes real_proto = IPPROTO_SCTP; 6450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6451511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (port1 < 0) 6452965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "illegal port number %d < 0", port1); 6453511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (port1 > 65535) 6454965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "illegal port number %d > 65535", port1); 6455511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (port2 < 0) 6456965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "illegal port number %d < 0", port2); 6457511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (port2 > 65535) 6458965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "illegal port number %d > 65535", port2); 6459511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 6460965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = gen_portrange(cstate, port1, port2, real_proto, dir); 6461965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes gen_or(gen_portrange6(cstate, port1, port2, real_proto, dir), b); 6462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_GATEWAY: 6465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef INET6 6466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project eaddr = pcap_ether_hostton(name); 6467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (eaddr == NULL) 6468965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "unknown ether host: %s", name); 6469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project alist = pcap_nametoaddr(name); 6471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (alist == NULL || *alist == NULL) 6472965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "unknown host '%s'", name); 6473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b = gen_gateway(eaddr, alist, proto, dir); 6474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(eaddr); 6475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else 6477965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'gateway' not supported in this configuration"); 6478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /*INET6*/ 6479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PROTO: 6481965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes real_proto = lookup_proto(cstate, name, proto); 6482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (real_proto >= 0) 6483965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_proto(cstate, real_proto, proto, dir); 6484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6485965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "unknown protocol: %s", name); 6486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PROTOCHAIN: 6488965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes real_proto = lookup_proto(cstate, name, proto); 6489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (real_proto >= 0) 6490965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_protochain(cstate, real_proto, proto, dir); 6491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6492965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "unknown protocol: %s", name); 6493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_UNDEF: 6495965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes syntax(cstate); 6496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 6499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 6503965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_mcode(compiler_state_t *cstate, const char *s1, const char *s2, 6504965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes unsigned int masklen, struct qual q) 6505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int nlen, mlen; 6507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 n, m; 6508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project nlen = __pcap_atoin(s1, &n); 6510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Promote short ipaddr */ 6511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project n <<= 32 - nlen; 6512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (s2 != NULL) { 6514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project mlen = __pcap_atoin(s2, &m); 6515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Promote short ipaddr */ 6516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project m <<= 32 - mlen; 6517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ((n & ~m) != 0) 6518965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "non-network bits set in \"%s mask %s\"", 6519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s1, s2); 6520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 6521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Convert mask len to mask */ 6522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (masklen > 32) 6523965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "mask length must be <= 32"); 6524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (masklen == 0) { 6525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * X << 32 is not guaranteed by C to be 0; it's 6527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * undefined. 6528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project m = 0; 6530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 6531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project m = 0xffffffff << (32 - masklen); 6532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ((n & ~m) != 0) 6533965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "non-network bits set in \"%s/%d\"", 6534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s1, masklen); 6535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (q.addr) { 6538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_NET: 6540965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_host(cstate, n, m, q.proto, q.dir, q.addr); 6541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 6543965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "Mask syntax for networks only"); 6544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return NULL; 6548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 6551965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_ncode(compiler_state_t *cstate, const char *s, bpf_u_int32 v, struct qual q) 6552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 mask; 6554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int proto = q.proto; 6555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int dir = q.dir; 6556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int vlen; 6557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (s == NULL) 6559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project vlen = 32; 6560965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes else if (q.proto == Q_DECNET) { 6561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project vlen = __pcap_atodn(s, &v); 6562965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (vlen == 0) 6563965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "malformed decnet address '%s'", s); 6564965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes } else 6565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project vlen = __pcap_atoin(s, &v); 6566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (q.addr) { 6568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 6570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_HOST: 6571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_NET: 6572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_DECNET) 6573965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_host(cstate, v, 0, proto, dir, q.addr); 6574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (proto == Q_LINK) { 6575965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "illegal link layer address"); 6576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 6577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project mask = 0xffffffff; 6578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (s == NULL && q.addr == Q_NET) { 6579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Promote short net number */ 6580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (v && (v & 0xff000000) == 0) { 6581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v <<= 8; 6582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project mask <<= 8; 6583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 6585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Promote short ipaddr */ 6586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v <<= 32 - vlen; 6587965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes mask <<= 32 - vlen ; 6588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6589965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_host(cstate, v, mask, proto, dir, q.addr); 6590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PORT: 6593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_UDP) 6594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = IPPROTO_UDP; 6595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (proto == Q_TCP) 6596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = IPPROTO_TCP; 6597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (proto == Q_SCTP) 6598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = IPPROTO_SCTP; 6599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (proto == Q_DEFAULT) 6600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = PROTO_UNDEF; 6601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6602965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "illegal qualifier of 'port'"); 6603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6604511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (v > 65535) 6605965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "illegal port number %u > 65535", v); 6606511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 6607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project { 6608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 6609965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = gen_port(cstate, (int)v, proto, dir); 6610965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes gen_or(gen_port6(cstate, (int)v, proto, dir), b); 6611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PORTRANGE: 6615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proto == Q_UDP) 6616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = IPPROTO_UDP; 6617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (proto == Q_TCP) 6618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = IPPROTO_TCP; 6619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (proto == Q_SCTP) 6620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = IPPROTO_SCTP; 6621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else if (proto == Q_DEFAULT) 6622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proto = PROTO_UNDEF; 6623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 6624965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "illegal qualifier of 'portrange'"); 6625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6626511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (v > 65535) 6627965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "illegal port number %u > 65535", v); 6628511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 6629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project { 6630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 6631965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = gen_portrange(cstate, (int)v, (int)v, proto, dir); 6632965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes gen_or(gen_portrange6(cstate, (int)v, (int)v, proto, dir), b); 6633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_GATEWAY: 6637965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'gateway' requires a name"); 6638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PROTO: 6641965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_proto(cstate, (int)v, proto, dir); 6642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PROTOCHAIN: 6644965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_protochain(cstate, (int)v, proto, dir); 6645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_UNDEF: 6647965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes syntax(cstate); 6648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 6651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 6652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6 6658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 6659965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_mcode6(compiler_state_t *cstate, const char *s1, const char *s2, 6660965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes unsigned int masklen, struct qual q) 6661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct addrinfo *res; 6663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct in6_addr *addr; 6664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct in6_addr mask; 6665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 6666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int32_t *a, *m; 6667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (s2) 6669965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "no mask %s supported", s2); 6670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project res = pcap_nametoaddrinfo(s1); 6672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!res) 6673965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "invalid ip6 address %s", s1); 6674965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->ai = res; 6675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (res->ai_next) 6676965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "%s resolved to multiple address", s1); 6677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project addr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; 6678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (sizeof(mask) * 8 < masklen) 6680965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "mask length must be <= %u", (unsigned int)(sizeof(mask) * 8)); 6681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(&mask, 0, sizeof(mask)); 6682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(&mask, 0xff, masklen / 8); 6683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (masklen % 8) { 6684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project mask.s6_addr[masklen / 8] = 6685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (0xff << (8 - masklen % 8)) & 0xff; 6686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project a = (u_int32_t *)addr; 6689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project m = (u_int32_t *)&mask; 6690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ((a[0] & ~m[0]) || (a[1] & ~m[1]) 6691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project || (a[2] & ~m[2]) || (a[3] & ~m[3])) { 6692965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "non-network bits set in \"%s/%d\"", s1, masklen); 6693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (q.addr) { 6696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 6698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_HOST: 6699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (masklen != 128) 6700965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "Mask syntax for networks only"); 6701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* FALLTHROUGH */ 6702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_NET: 6704965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = gen_host6(cstate, addr, &mask, q.proto, q.dir, q.addr); 6705965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->ai = NULL; 6706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project freeaddrinfo(res); 6707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 6708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 6710965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "invalid qualifier against IPv6 address"); 6711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return NULL; 6714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /*INET6*/ 6716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 6718965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_ecode(compiler_state_t *cstate, const u_char *eaddr, struct qual q) 6719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b, *tmp; 6721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) { 6723965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes switch (cstate->linktype) { 6724511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_EN10MB: 6725511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER: 6726511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER_TRANSPARENT: 6727965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = gen_prevlinkhdr_check(cstate); 6728965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = gen_ehostop(cstate, eaddr, (int)q.dir); 6729d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (tmp != NULL) 6730d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(tmp, b); 6731d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b; 6732511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_FDDI: 6733965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_fhostop(cstate, eaddr, (int)q.dir); 6734511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802: 6735965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_thostop(cstate, eaddr, (int)q.dir); 6736511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11: 6737511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 6738511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO_AVS: 6739511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO: 6740511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PPI: 6741965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_wlanhostop(cstate, eaddr, (int)q.dir); 6742511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IP_OVER_FC: 6743965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_ipfchostop(cstate, eaddr, (int)q.dir); 6744511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 6745965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "ethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel"); 6746511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 6747511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 6748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6749965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "ethernet address used in non-ether expression"); 6750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 6751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return NULL; 6752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid 6755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectsappend(s0, s1) 6756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s0, *s1; 6757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is definitely not the best way to do this, but the 6760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * lists will rarely get long. 6761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (s0->next) 6763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s0 = s0->next; 6764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s0->next = s1; 6765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist * 6768965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesxfer_to_x(compiler_state_t *cstate, struct arth *a) 6769478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s; 6771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6772965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_LDX|BPF_MEM); 6773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->s.k = a->regno; 6774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return s; 6775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist * 6778965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesxfer_to_a(compiler_state_t *cstate, struct arth *a) 6779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s; 6781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6782965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_LD|BPF_MEM); 6783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->s.k = a->regno; 6784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return s; 6785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 6786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 6788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Modify "index" to use the value stored into its register as an 6789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * offset relative to the beginning of the header for the protocol 6790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto", and allocate a register and put an item "size" bytes long 6791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (1, 2, or 4) at that offset into that register, making it the register 6792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * for "index". 6793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct arth * 6795965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size) 6796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 6797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s, *tmp; 6798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 6799965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int regno = alloc_reg(cstate); 6800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6801965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes free_reg(cstate, inst->regno); 6802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (size) { 6803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 6805965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "data size must be 1, 2, or 4"); 6806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6807478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case 1: 6808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project size = BPF_B; 6809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 6810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case 2: 6812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project size = BPF_H; 6813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 6814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case 4: 6816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project size = BPF_W; 6817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 6818478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 6819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 6820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 6821965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "unsupported index operation"); 6822478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RADIO: 6824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6825478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The offset is relative to the beginning of the packet 6826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * data, if we have a radio header. (If we don't, this 6827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is an error.) 6828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6829965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->linktype != DLT_IEEE802_11_RADIO_AVS && 6830965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->linktype != DLT_IEEE802_11_RADIO && 6831965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->linktype != DLT_PRISM_HEADER) 6832965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "radio information not present in capture"); 6833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load into the X register the offset computed into the 6836511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * register specified by "index". 6837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6838965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = xfer_to_x(cstate, inst); 6839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the item at that offset. 6842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6843965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = new_stmt(cstate, BPF_LD|BPF_IND|size); 6844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, tmp); 6845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(inst->s, s); 6846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 6847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LINK: 6849478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The offset is relative to the beginning of 6851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the link-layer header. 6852478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 6853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - what about ATM LANE? Should the index be 6854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * relative to the beginning of the AAL5 frame, so 6855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that 0 refers to the beginning of the LE Control 6856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * field, or relative to the beginning of the LAN 6857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * frame, so that 0 refers, for Ethernet LANE, to 6858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the beginning of the destination address? 6859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6860965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_abs_offset_varpart(cstate, &cstate->off_linkhdr); 6861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If "s" is non-null, it has code to arrange that the 6864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * X register contains the length of the prefix preceding 6865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the link-layer header. Add to it the offset computed 6866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * into the register specified by "index", and move that 6867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * into the X register. Otherwise, just load into the X 6868511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * register the offset computed into the register specified 6869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * by "index". 6870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (s != NULL) { 6872965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sappend(s, xfer_to_a(cstate, inst)); 6873965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sappend(s, new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_X)); 6874965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sappend(s, new_stmt(cstate, BPF_MISC|BPF_TAX)); 6875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 6876965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = xfer_to_x(cstate, inst); 6877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the item at the sum of the offset we've put in the 6880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * X register and the offset of the start of the link 6881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * layer header (which is 0 if the radio header is 6882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * variable-length; that header length is what we put 6883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * into the X register and then added to the index). 6884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6885965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = new_stmt(cstate, BPF_LD|BPF_IND|size); 6886965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp->s.k = cstate->off_linkhdr.constant_part; 6887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, tmp); 6888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(inst->s, s); 6889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 6890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 6892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ARP: 6893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_RARP: 6894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ATALK: 6895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DECNET: 6896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCA: 6897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LAT: 6898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPRC: 6899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_MOPDL: 6900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 6901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The offset is relative to the beginning of 6903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the network-layer header. 6904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - are there any cases where we want 6905965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * cstate->off_nl_nosnap? 6906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6907965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_abs_offset_varpart(cstate, &cstate->off_linkpl); 6908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6910478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If "s" is non-null, it has code to arrange that the 6911d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * X register contains the variable part of the offset 6912d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * of the link-layer payload. Add to it the offset 6913d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * computed into the register specified by "index", 6914d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * and move that into the X register. Otherwise, just 6915d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * load into the X register the offset computed into 6916d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the register specified by "index". 6917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (s != NULL) { 6919965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sappend(s, xfer_to_a(cstate, inst)); 6920965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sappend(s, new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_X)); 6921965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sappend(s, new_stmt(cstate, BPF_MISC|BPF_TAX)); 6922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 6923965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = xfer_to_x(cstate, inst); 6924478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6925478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6926478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the item at the sum of the offset we've put in the 6927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * X register, the offset of the start of the network 6928d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * layer header from the beginning of the link-layer 6929d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * payload, and the constant part of the offset of the 6930d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * start of the link-layer payload. 6931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6932965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp = new_stmt(cstate, BPF_LD|BPF_IND|size); 6933965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp->s.k = cstate->off_linkpl.constant_part + cstate->off_nl; 6934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s, tmp); 6935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(inst->s, s); 6936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Do the computation only if the packet contains 6939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the protocol in question. 6940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6941965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = gen_proto_abbrev(cstate, proto); 6942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (inst->b) 6943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(inst->b, b); 6944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project inst->b = b; 6945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 6946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SCTP: 6948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_TCP: 6949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_UDP: 6950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMP: 6951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGMP: 6952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IGRP: 6953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_PIM: 6954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_VRRP: 6955511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_CARP: 6956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The offset is relative to the beginning of 6958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the transport-layer header. 6959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 6960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load the X register with the length of the IPv4 header 6961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (plus the offset of the link-layer header, if it's 6962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a variable-length header), in bytes. 6963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 6964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - are there any cases where we want 6965965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * cstate->off_nl_nosnap? 6966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - we should, if we're built with 6967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * IPv6 support, generate code to load either 6968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * IPv4, IPv6, or both, as appropriate. 6969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6970965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_loadx_iphdrlen(cstate); 6971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6973d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * The X register now contains the sum of the variable 6974d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * part of the offset of the link-layer payload and the 6975511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * length of the network-layer header. 6976511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 6977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load into the A register the offset relative to 6978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the beginning of the transport layer header, 6979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * add the X register to that, move that to the 6980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * X register, and load with an offset from the 6981d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * X register equal to the sum of the constant part of 6982d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the offset of the link-layer payload and the offset, 6983d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * relative to the beginning of the link-layer payload, 6984d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * of the network-layer header. 6985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6986965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sappend(s, xfer_to_a(cstate, inst)); 6987965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sappend(s, new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_X)); 6988965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sappend(s, new_stmt(cstate, BPF_MISC|BPF_TAX)); 6989965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes sappend(s, tmp = new_stmt(cstate, BPF_LD|BPF_IND|size)); 6990965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes tmp->s.k = cstate->off_linkpl.constant_part + cstate->off_nl; 6991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(inst->s, s); 6992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 6993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 6994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Do the computation only if the packet contains 6995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the protocol in question - which is true only 6996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * if this is an IP datagram and is the first or 6997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * only fragment of that datagram. 6998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 6999965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes gen_and(gen_proto_abbrev(cstate, proto), b = gen_ipfrag(cstate)); 7000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (inst->b) 7001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(inst->b, b); 7002965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes gen_and(gen_proto_abbrev(cstate, Q_IP), b); 7003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project inst->b = b; 7004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 7005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_ICMPV6: 7006965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "IPv6 upper-layer protocol is not supported by proto[x]"); 7007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 7008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project inst->regno = regno; 7010965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_ST); 7011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->s.k = regno; 7012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(inst->s, s); 7013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return inst; 7015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7018965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_relation(compiler_state_t *cstate, int code, struct arth *a0, 7019965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes struct arth *a1, int reversed) 7020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s0, *s1, *s2; 7022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b, *tmp; 7023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7024965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s0 = xfer_to_x(cstate, a1); 7025965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = xfer_to_a(cstate, a0); 7026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (code == BPF_JEQ) { 7027965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ALU|BPF_SUB|BPF_X); 7028965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = new_block(cstate, JMP(code)); 7029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 7030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 7032965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = new_block(cstate, BPF_JMP|code|BPF_X); 7033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (reversed) 7034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b); 7035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s0, s1); 7037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(a1->s, s0); 7038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(a0->s, a1->s); 7039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->stmts = a0->s; 7041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7042965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes free_reg(cstate, a0->regno); 7043965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes free_reg(cstate, a1->regno); 7044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7045478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 'and' together protocol checks */ 7046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (a0->b) { 7047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (a1->b) { 7048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(a0->b, tmp = a1->b); 7049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 7051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = a0->b; 7052478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 7053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project tmp = a1->b; 7054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (tmp) 7056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(tmp, b); 7057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 7059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct arth * 7062965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_loadlen(compiler_state_t *cstate) 7063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7064965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes int regno = alloc_reg(cstate); 7065965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes struct arth *a = (struct arth *)newchunk(cstate, sizeof(*a)); 7066478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s; 7067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7068965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_LD|BPF_LEN); 7069965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s->next = new_stmt(cstate, BPF_ST); 7070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->next->s.k = regno; 7071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project a->s = s; 7072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project a->regno = regno; 7073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7074478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return a; 7075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct arth * 7078965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_loadi(compiler_state_t *cstate, int val) 7079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct arth *a; 7081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s; 7082478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int reg; 7083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7084965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes a = (struct arth *)newchunk(cstate, sizeof(*a)); 7085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7086965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes reg = alloc_reg(cstate); 7087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7088965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_LD|BPF_IMM); 7089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->s.k = val; 7090965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s->next = new_stmt(cstate, BPF_ST); 7091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->next->s.k = reg; 7092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project a->s = s; 7093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project a->regno = reg; 7094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return a; 7096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct arth * 7099965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_neg(compiler_state_t *cstate, struct arth *a) 7100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s; 7102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7103965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = xfer_to_a(cstate, a); 7104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(a->s, s); 7105965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_ALU|BPF_NEG); 7106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->s.k = 0; 7107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(a->s, s); 7108965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_ST); 7109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->s.k = a->regno; 7110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(a->s, s); 7111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return a; 7113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct arth * 7116965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_arth(compiler_state_t *cstate, int code, struct arth *a0, 7117965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes struct arth *a1) 7118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s0, *s1, *s2; 7120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7121965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* 7122965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Disallow division by, or modulus by, zero; we do this here 7123965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * so that it gets done even if the optimizer is disabled. 7124965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */ 7125965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (code == BPF_DIV) { 7126965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (a1->s->s.code == (BPF_LD|BPF_IMM) && a1->s->s.k == 0) 7127965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "division by zero"); 7128965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes } else if (code == BPF_MOD) { 7129965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (a1->s->s.code == (BPF_LD|BPF_IMM) && a1->s->s.k == 0) 7130965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "modulus by zero"); 7131965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes } 7132965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s0 = xfer_to_x(cstate, a1); 7133965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = xfer_to_a(cstate, a0); 7134965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s2 = new_stmt(cstate, BPF_ALU|BPF_X|code); 7135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s1, s2); 7137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(s0, s1); 7138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(a1->s, s0); 7139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(a0->s, a1->s); 7140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7141965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes free_reg(cstate, a0->regno); 7142965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes free_reg(cstate, a1->regno); 7143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7144965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s0 = new_stmt(cstate, BPF_ST); 7145965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes a0->regno = s0->s.k = alloc_reg(cstate); 7146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sappend(a0->s, s0); 7147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return a0; 7149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 7152511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Initialize the table of used registers and the current register. 7153511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7154511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void 7155965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesinit_regs(compiler_state_t *cstate) 7156511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 7157965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->curreg = 0; 7158965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes memset(cstate->regused, 0, sizeof cstate->regused); 7159511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 7160511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7161511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 7162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Return the next free register. 7163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 7165965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesalloc_reg(compiler_state_t *cstate) 7166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int n = BPF_MEMWORDS; 7168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (--n >= 0) { 7170965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->regused[cstate->curreg]) 7171965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->curreg = (cstate->curreg + 1) % BPF_MEMWORDS; 7172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else { 7173965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->regused[cstate->curreg] = 1; 7174965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return cstate->curreg; 7175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7177965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "too many registers needed to evaluate expression"); 7178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return 0; 7180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 7183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Return a register to the table so it can 7184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * be used later. 7185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void 7187965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesfree_reg(compiler_state_t *cstate, int n) 7188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7189965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->regused[n] = 0; 7190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 7193965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_len(compiler_state_t *cstate, int jmp, int n) 7194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s; 7196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 7197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7198965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_LD|BPF_LEN); 7199965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = new_block(cstate, JMP(jmp)); 7200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->stmts = s; 7201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->s.k = n; 7202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 7204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7207965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_greater(compiler_state_t *cstate, int n) 7208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7209965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_len(cstate, BPF_JGE, n); 7210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 7213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Actually, this is less than or equal. 7214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7216965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_less(compiler_state_t *cstate, int n) 7217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 7219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7220965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = gen_len(cstate, BPF_JGT, n); 7221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b); 7222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 7224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 7227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is for "byte {idx} {op} {val}"; "idx" is treated as relative to 7228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the beginning of the link-layer header. 7229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - that means you can't test values in the radiotap header, but 7230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as that header is difficult if not impossible to parse generally 7231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * without a loop, that might not be a severe problem. A new keyword 7232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "radio" could be added for that, although what you'd really want 7233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * would be a way of testing particular radio header values, which 7234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * would generate code appropriate to the radio header in question. 7235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7237965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_byteop(compiler_state_t *cstate, int op, int idx, int val) 7238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b; 7240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct slist *s; 7241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (op) { 7243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 7244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 7245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case '=': 7247965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_cmp(cstate, OR_LINKHDR, (u_int)idx, BPF_B, (bpf_int32)val); 7248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case '<': 7250965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = gen_cmp_lt(cstate, OR_LINKHDR, (u_int)idx, BPF_B, (bpf_int32)val); 7251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 7252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case '>': 7254965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = gen_cmp_gt(cstate, OR_LINKHDR, (u_int)idx, BPF_B, (bpf_int32)val); 7255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 7256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case '|': 7258965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_ALU|BPF_OR|BPF_K); 7259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 7260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case '&': 7262965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_ALU|BPF_AND|BPF_K); 7263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 7264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project s->s.k = val; 7266965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b = new_block(cstate, JMP(BPF_JEQ)); 7267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b->stmts = s; 7268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b); 7269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b; 7271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7273965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic const u_char abroadcast[] = { 0x0 }; 7274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7276965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_broadcast(compiler_state_t *cstate, int proto) 7277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 hostmask; 7279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1, *b2; 7280965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes static const u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 7281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 7283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 7285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LINK: 7286965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes switch (cstate->linktype) { 7287511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_ARCNET: 7288511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_ARCNET_LINUX: 7289965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_ahostop(cstate, abroadcast, Q_DST); 7290511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_EN10MB: 7291511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER: 7292511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER_TRANSPARENT: 7293965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_prevlinkhdr_check(cstate); 7294965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ehostop(cstate, ebroadcast, Q_DST); 7295d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (b1 != NULL) 7296d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b1, b0); 7297d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b0; 7298511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_FDDI: 7299965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_fhostop(cstate, ebroadcast, Q_DST); 7300511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802: 7301965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_thostop(cstate, ebroadcast, Q_DST); 7302511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11: 7303511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 7304511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO_AVS: 7305511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO: 7306511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PPI: 7307965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_wlanhostop(cstate, ebroadcast, Q_DST); 7308511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IP_OVER_FC: 7309965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_ipfchostop(cstate, ebroadcast, Q_DST); 7310511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 7311965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "not a broadcast link"); 7312511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 7313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 7314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 7316511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7317511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * We treat a netmask of PCAP_NETMASK_UNKNOWN (0xffffffff) 7318511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * as an indication that we don't know the netmask, and fail 7319511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * in that case. 7320511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7321965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->netmask == PCAP_NETMASK_UNKNOWN) 7322965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "netmask not known, so 'ip broadcast' not supported"); 7323965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, ETHERTYPE_IP); 7324965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes hostmask = ~cstate->netmask; 7325965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_mcmp(cstate, OR_LINKPL, 16, BPF_W, (bpf_int32)0, hostmask); 7326965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b2 = gen_mcmp(cstate, OR_LINKPL, 16, BPF_W, 7327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)(~0 & hostmask), hostmask); 7328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b1, b2); 7329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b2); 7330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b2; 7331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7332965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "only link-layer/IP broadcast filters supported"); 7333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return NULL; 7335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 7338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to test the low-order bit of a MAC address (that's 7339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the bottom bit of the *first* byte). 7340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 7342965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_mac_multicast(compiler_state_t *cstate, int offset) 7343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block *b0; 7345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct slist *s; 7346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* link[offset] & 1 != 0 */ 7348965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, offset, BPF_B); 7349965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = new_block(cstate, JMP(BPF_JSET)); 7350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0->s.k = 1; 7351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0->stmts = s; 7352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 7353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7356965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_multicast(compiler_state_t *cstate, int proto) 7357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block *b0, *b1, *b2; 7359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct slist *s; 7360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (proto) { 7362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 7364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_LINK: 7365965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes switch (cstate->linktype) { 7366511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_ARCNET: 7367511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_ARCNET_LINUX: 7368511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* all ARCnet multicasts use the same address */ 7369965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_ahostop(cstate, abroadcast, Q_DST); 7370511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_EN10MB: 7371511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER: 7372511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER_TRANSPARENT: 7373965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_prevlinkhdr_check(cstate); 7374511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* ether[0] & 1 != 0 */ 7375965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_mac_multicast(cstate, 0); 7376d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (b1 != NULL) 7377d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b1, b0); 7378d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b0; 7379511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_FDDI: 7380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 7381511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX 7382511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 7383511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * XXX - was that referring to bit-order issues? 7384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7385511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* fddi[1] & 1 != 0 */ 7386965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_mac_multicast(cstate, 1); 7387511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802: 7388511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* tr[2] & 1 != 0 */ 7389965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_mac_multicast(cstate, 2); 7390511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11: 7391511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 7392511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO_AVS: 7393511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO: 7394511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PPI: 7395511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7396511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Oh, yuk. 7397511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 7398511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For control frames, there is no DA. 7399511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 7400511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For management frames, DA is at an 7401511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * offset of 4 from the beginning of 7402511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the packet. 7403511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 7404511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For data frames, DA is at an offset 7405511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * of 4 from the beginning of the packet 7406511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * if To DS is clear and at an offset of 7407511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 16 from the beginning of the packet 7408511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * if To DS is set. 7409511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7410511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7411511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7412511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Generate the tests to be done for data frames. 7413511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 7414511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * First, check for To DS set, i.e. "link[1] & 0x01". 7415511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7416965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 1, BPF_B); 7417965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = new_block(cstate, JMP(BPF_JSET)); 7418511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->s.k = 0x01; /* To DS */ 7419511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->stmts = s; 7420511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7421511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7422511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If To DS is set, the DA is at 16. 7423511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7424965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_mac_multicast(cstate, 16); 7425511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b1, b0); 7426511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7427511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7428511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now, check for To DS not set, i.e. check 7429511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * "!(link[1] & 0x01)". 7430511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7431965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 1, BPF_B); 7432965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b2 = new_block(cstate, JMP(BPF_JSET)); 7433511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b2->s.k = 0x01; /* To DS */ 7434511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b2->stmts = s; 7435511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b2); 7436511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7437511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7438511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If To DS is not set, the DA is at 4. 7439511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7440965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_mac_multicast(cstate, 4); 7441511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b2, b1); 7442511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7443511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7444511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now OR together the last two checks. That gives 7445511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the complete set of checks for data frames. 7446511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7447511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_or(b1, b0); 7448511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7449511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7450511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Now check for a data frame. 7451511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * I.e, check "link[0] & 0x08". 7452511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7453965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 0, BPF_B); 7454965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = new_block(cstate, JMP(BPF_JSET)); 7455511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->s.k = 0x08; 7456511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->stmts = s; 7457511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7458511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7459511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * AND that with the checks done for data frames. 7460511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7461511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b1, b0); 7462511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7463511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7464511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If the high-order bit of the type value is 0, this 7465511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * is a management frame. 7466511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * I.e, check "!(link[0] & 0x08)". 7467511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7468965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 0, BPF_B); 7469965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b2 = new_block(cstate, JMP(BPF_JSET)); 7470511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b2->s.k = 0x08; 7471511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b2->stmts = s; 7472511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b2); 7473511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7474511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7475511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For management frames, the DA is at 4. 7476511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7477965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_mac_multicast(cstate, 4); 7478511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b2, b1); 7479511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7480511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7481511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * OR that with the checks done for data frames. 7482511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * That gives the checks done for management and 7483511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * data frames. 7484511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7485511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_or(b1, b0); 7486511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7487511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7488511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If the low-order bit of the type value is 1, 7489511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * this is either a control frame or a frame 7490511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * with a reserved type, and thus not a 7491511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * frame with an SA. 7492511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 7493511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * I.e., check "!(link[0] & 0x04)". 7494511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7495965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_load_a(cstate, OR_LINKHDR, 0, BPF_B); 7496965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = new_block(cstate, JMP(BPF_JSET)); 7497511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->s.k = 0x04; 7498511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b1->stmts = s; 7499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_not(b1); 7500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7501511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7502511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * AND that with the checks for data and management 7503511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * frames. 7504511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b1, b0); 7506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 7507511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IP_OVER_FC: 7508965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_mac_multicast(cstate, 2); 7509511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return b0; 7510511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 7511511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7512511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 7513511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Link not known to support multicasts */ 7514511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IP: 7517965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, ETHERTYPE_IP); 7518965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp_ge(cstate, OR_LINKPL, 16, BPF_B, (bpf_int32)224); 7519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 7520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 7521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_IPV6: 7523965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, ETHERTYPE_IPV6); 7524965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_cmp(cstate, OR_LINKPL, 24, BPF_B, (bpf_int32)255); 7525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 7526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 7527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7528965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel"); 7529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return NULL; 7531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 7534511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Filter on inbound (dir == 0) or outbound (dir == 1) traffic. 7535511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Outbound traffic is sent by this machine, while inbound traffic is 7536511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * sent by a remote machine (and may include packets destined for a 7537511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * unicast or multicast link-layer address we are not subscribing to). 7538511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * These are the same definitions implemented by pcap_setdirection(). 7539511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Capturing only unicast traffic destined for this host is probably 7540511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * better accomplished using a higher-layer filter. 7541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7543965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_inbound(compiler_state_t *cstate, int dir) 7544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block *b0; 7546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 7548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Only some data link types support inbound/outbound qualifiers. 7549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 7550965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes switch (cstate->linktype) { 7551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_SLIP: 7552965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_relation(cstate, BPF_JEQ, 7553965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes gen_load(cstate, Q_LINK, gen_loadi(cstate, 0), 1), 7554965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes gen_loadi(cstate, 0), 7555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project dir); 7556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 7557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7558511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IPNET: 7559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (dir) { 7560511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* match outgoing packets */ 7561965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKHDR, 2, BPF_H, IPNET_OUTBOUND); 7562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 7563511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* match incoming packets */ 7564965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKHDR, 2, BPF_H, IPNET_INBOUND); 7565511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 7566511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7567511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7568511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_LINUX_SLL: 7569511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* match outgoing packets */ 7570965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKHDR, 0, BPF_H, LINUX_SLL_OUTGOING); 7571511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (!dir) { 7572511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* to filter on inbound traffic, invert the match */ 7573511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b0); 7574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 7576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_NET_PFVAR_H 7578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PFLOG: 7579965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, dir), BPF_B, 7580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)((dir == 0) ? PF_IN : PF_OUT)); 7581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 7582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 7583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP_PPPD: 7585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (dir) { 7586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* match outgoing packets */ 7587965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKHDR, 0, BPF_B, PPP_PPPD_OUT); 7588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 7589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* match incoming packets */ 7590965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKHDR, 0, BPF_B, PPP_PPPD_IN); 7591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 7593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MFR: 7595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MLFR: 7596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MLPPP: 7597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ATM1: 7598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ATM2: 7599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_PPPOE: 7600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_PPPOE_ATM: 7601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_GGSN: 7602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ES: 7603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_MONITOR: 7604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_SERVICES: 7605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_ETHER: 7606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_PPP: 7607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_FRELAY: 7608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_CHDLC: 7609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_JUNIPER_VP: 7610511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_ST: 7611511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_ISM: 7612511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_VS: 7613511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_SRX_E2E: 7614511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_FIBRECHANNEL: 7615511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_JUNIPER_ATM_CEMIC: 7616511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* juniper flags (including direction) are stored 7618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the byte after the 3-byte magic number */ 7619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (dir) { 7620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* match outgoing packets */ 7621965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_mcmp(cstate, OR_LINKHDR, 3, BPF_B, 0, 0x01); 7622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 7623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* match incoming packets */ 7624965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_mcmp(cstate, OR_LINKHDR, 3, BPF_B, 1, 0x01); 7625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7626511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 7629511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7630511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If we have packet meta-data indicating a direction, 7631511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * check it, otherwise give up as this link-layer type 7632511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * has nothing in the packet data. 7633511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7634511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#if defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) 7635511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 7636511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * This is Linux with PF_PACKET support. 7637511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If this is a *live* capture, we can look at 7638511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * special meta-data in the filter expression; 7639511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * if it's a savefile, we can't. 7640511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 7641965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->bpf_pcap->rfile != NULL) { 7642511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* We have a FILE *, so this is a savefile */ 7643965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "inbound/outbound not supported on linktype %d when reading savefiles", 7644965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->linktype); 7645511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall b0 = NULL; 7646511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NOTREACHED */ 7647511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 7648511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* match outgoing packets */ 7649965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKHDR, SKF_AD_OFF + SKF_AD_PKTTYPE, BPF_H, 7650511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall PACKET_OUTGOING); 7651511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (!dir) { 7652511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* to filter on inbound traffic, invert the match */ 7653511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_not(b0); 7654511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 7655511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else /* defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */ 7656965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "inbound/outbound not supported on linktype %d", 7657965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->linktype); 7658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = NULL; 7659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7660511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif /* defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */ 7661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b0); 7663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_NET_PFVAR_H 7666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* PF firewall log matched interface */ 7667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7668965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_pf_ifname(compiler_state_t *cstate, const char *ifname) 7669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0; 7671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int len, off; 7672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7673965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->linktype != DLT_PFLOG) { 7674965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "ifname supported only on PF linktype"); 7675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7677511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall len = sizeof(((struct pfloghdr *)0)->ifname); 7678511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall off = offsetof(struct pfloghdr, ifname); 7679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (strlen(ifname) >= len) { 7680965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "ifname interface names can only be %d characters", 7681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project len-1); 7682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7684965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_bcmp(cstate, OR_LINKHDR, off, strlen(ifname), (const u_char *)ifname); 7685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b0); 7686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* PF firewall log ruleset name */ 7689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7690965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_pf_ruleset(compiler_state_t *cstate, char *ruleset) 7691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0; 7693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7694965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->linktype != DLT_PFLOG) { 7695965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "ruleset supported only on PF linktype"); 7696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7698511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (strlen(ruleset) >= sizeof(((struct pfloghdr *)0)->ruleset)) { 7700965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "ruleset names can only be %ld characters", 7701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (long)(sizeof(((struct pfloghdr *)0)->ruleset) - 1)); 7702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7704511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7705965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_bcmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, ruleset), 7706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strlen(ruleset), (const u_char *)ruleset); 7707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b0); 7708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* PF firewall log rule number */ 7711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7712965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_pf_rnr(compiler_state_t *cstate, int rnr) 7713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0; 7715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7716965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->linktype != DLT_PFLOG) { 7717965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "rnr supported only on PF linktype"); 7718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7721965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, rulenr), BPF_W, 7722511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (bpf_int32)rnr); 7723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b0); 7724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* PF firewall log sub-rule number */ 7727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7728965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_pf_srnr(compiler_state_t *cstate, int srnr) 7729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0; 7731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7732965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->linktype != DLT_PFLOG) { 7733965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "srnr supported only on PF linktype"); 7734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7737965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, subrulenr), BPF_W, 7738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (bpf_int32)srnr); 7739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b0); 7740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* PF firewall log reason code */ 7743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7744965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_pf_reason(compiler_state_t *cstate, int reason) 7745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0; 7747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7748965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->linktype != DLT_PFLOG) { 7749965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "reason supported only on PF linktype"); 7750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7753965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, reason), BPF_B, 7754511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (bpf_int32)reason); 7755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b0); 7756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* PF firewall log action */ 7759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7760965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_pf_action(compiler_state_t *cstate, int action) 7761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0; 7763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7764965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->linktype != DLT_PFLOG) { 7765965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "action supported only on PF linktype"); 7766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7769965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, action), BPF_B, 7770511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (bpf_int32)action); 7771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b0); 7772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else /* !HAVE_NET_PFVAR_H */ 7774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7775965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_pf_ifname(compiler_state_t *cstate, const char *ifname) 7776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7777965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "libpcap was compiled without pf support"); 7778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 7780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7783965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_pf_ruleset(compiler_state_t *cstate, char *ruleset) 7784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7785965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "libpcap was compiled on a machine without pf support"); 7786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 7788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7791965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_pf_rnr(compiler_state_t *cstate, int rnr) 7792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7793965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "libpcap was compiled on a machine without pf support"); 7794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 7796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7799965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_pf_srnr(compiler_state_t *cstate, int srnr) 7800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7801965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "libpcap was compiled on a machine without pf support"); 7802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 7804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7805478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7807965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_pf_reason(compiler_state_t *cstate, int reason) 7808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7809965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "libpcap was compiled on a machine without pf support"); 7810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 7812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7815965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_pf_action(compiler_state_t *cstate, int action) 7816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7817965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "libpcap was compiled on a machine without pf support"); 7818478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 7820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_NET_PFVAR_H */ 7822478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7823511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* IEEE 802.11 wireless header */ 7824511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct block * 7825965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_p80211_type(compiler_state_t *cstate, int type, int mask) 7826511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 7827511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct block *b0; 7828511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7829965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes switch (cstate->linktype) { 7830511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7831511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11: 7832511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 7833511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO_AVS: 7834511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO: 7835965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, (bpf_int32)type, 7836511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (bpf_int32)mask); 7837511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7838511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7839511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 7840965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "802.11 link-layer types supported only on 802.11"); 7841511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NOTREACHED */ 7842511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 7843511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7844511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (b0); 7845511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 7846511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7847511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct block * 7848965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_p80211_fcdir(compiler_state_t *cstate, int fcdir) 7849511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 7850511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct block *b0; 7851511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7852965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes switch (cstate->linktype) { 7853511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7854511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11: 7855511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_PRISM_HEADER: 7856511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO_AVS: 7857511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_IEEE802_11_RADIO: 7858511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7859511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7860511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 7861965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "frame direction supported only with 802.11 headers"); 7862511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NOTREACHED */ 7863511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 7864511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7865965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_mcmp(cstate, OR_LINKHDR, 1, BPF_B, (bpf_int32)fcdir, 7866511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (bpf_u_int32)IEEE80211_FC1_DIR_MASK); 7867511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7868511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (b0); 7869511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 7870511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 7872965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_acode(compiler_state_t *cstate, const u_char *eaddr, struct qual q) 7873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7874965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes switch (cstate->linktype) { 7875511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7876511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_ARCNET: 7877511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_ARCNET_LINUX: 7878511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && 7879511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall q.proto == Q_LINK) 7880965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return (gen_ahostop(cstate, eaddr, (int)q.dir)); 7881511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall else { 7882965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "ARCnet address used in non-arc expression"); 7883511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NOTREACHED */ 7884511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 7885511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7886511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7887511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 7888965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "aid supported only on ARCnet"); 7889511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NOTREACHED */ 7890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7891965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "ARCnet address used in non-arc expression"); 7892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return NULL; 7894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 7897965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_ahostop(compiler_state_t *cstate, const u_char *eaddr, int dir) 7898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 7899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct block *b0, *b1; 7900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (dir) { 7902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* src comes first, different from Ethernet */ 7903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_SRC: 7904965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_bcmp(cstate, OR_LINKHDR, 0, 1, eaddr); 7905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DST: 7907965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_bcmp(cstate, OR_LINKHDR, 1, 1, eaddr); 7908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_AND: 7910965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ahostop(cstate, eaddr, Q_SRC); 7911965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_ahostop(cstate, eaddr, Q_DST); 7912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 7913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 7914478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7915478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_DEFAULT: 7916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case Q_OR: 7917965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ahostop(cstate, eaddr, Q_SRC); 7918965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_ahostop(cstate, eaddr, Q_DST); 7919478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 7920478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 7921511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7922511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR1: 7923965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr1' is only supported on 802.11"); 7924511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7925511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7926511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR2: 7927965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr2' is only supported on 802.11"); 7928511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7929511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7930511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR3: 7931965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr3' is only supported on 802.11"); 7932511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7933511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7934511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_ADDR4: 7935965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'addr4' is only supported on 802.11"); 7936511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7937511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7938511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_RA: 7939965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'ra' is only supported on 802.11"); 7940511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7941511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 7942511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case Q_TA: 7943965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'ta' is only supported on 802.11"); 7944511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 7945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 7946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 7947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* NOTREACHED */ 7948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 7949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 7950d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT) 7951d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct block * 7952965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_vlan_bpf_extensions(compiler_state_t *cstate, int vlan_num) 7953d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 7954d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 7955d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct slist *s; 7956d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7957d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* generate new filter code based on extracting packet 7958d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * metadata */ 7959965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS); 7960d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT; 7961d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7962965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = new_block(cstate, JMP(BPF_JEQ)); 7963d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0->stmts = s; 7964d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0->s.k = 1; 7965d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7966d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (vlan_num >= 0) { 7967965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS); 7968d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG; 7969d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7970965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = new_block(cstate, JMP(BPF_JEQ)); 7971d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1->stmts = s; 7972d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1->s.k = (bpf_int32) vlan_num; 7973d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7974d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0,b1); 7975d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = b1; 7976d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 7977d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7978d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b0; 7979d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 7980d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#endif 7981d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7982d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct block * 7983965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_vlan_no_bpf_extensions(compiler_state_t *cstate, int vlan_num) 7984d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 7985d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 7986d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7987d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* check for VLAN, including QinQ */ 7988965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, ETHERTYPE_8021Q); 7989965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_linktype(cstate, ETHERTYPE_8021AD); 7990965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes gen_or(b0,b1); 7991965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = b1; 7992965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_linktype(cstate, ETHERTYPE_8021QINQ); 7993d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_or(b0,b1); 7994d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = b1; 7995d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 7996d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* If a specific VLAN is requested, check VLAN id */ 7997d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (vlan_num >= 0) { 7998965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_H, 7999d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes (bpf_int32)vlan_num, 0x0fff); 8000d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 8001d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = b1; 8002d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 8003d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8004d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 8005d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * The payload follows the full header, including the 8006d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * VLAN tags, so skip past this VLAN tag. 8007d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 8008965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part += 4; 8009d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8010d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 8011d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * The link-layer type information follows the VLAN tags, so 8012d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * skip past this VLAN tag. 8013d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 8014965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part += 4; 8015d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8016d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b0; 8017d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 8018d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 8020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * support IEEE 802.1Q VLAN trunk over ethernet 8021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 8022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 8023965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_vlan(compiler_state_t *cstate, int vlan_num) 8024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8025d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0; 8026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* can't check for VLAN-encapsulated packets inside MPLS */ 8028965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->label_stack_depth > 0) 8029965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "no VLAN match after MPLS"); 8030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 8032511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Check for a VLAN packet, and then change the offsets to point 8033511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * to the type and data fields within the VLAN packet. Just 8034511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * increment the offsets, so that we can support a hierarchy, e.g. 8035511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * "vlan 300 && vlan 200" to capture VLAN 200 encapsulated within 8036511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * VLAN 100. 8037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 8038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - this is a bit of a kludge. If we were to split the 8039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * compiler into a parser that parses an expression and 8040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * generates an expression tree, and a code generator that 8041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * takes an expression tree (which could come from our 8042478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * parser or from some other parser) and generates BPF code, 8043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we could perhaps make the offsets parameters of routines 8044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and, in the handler for an "AND" node, pass to subnodes 8045478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * other than the VLAN node the adjusted offsets. 8046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 8047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This would mean that "vlan" would, instead of changing the 8048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * behavior of *all* tests after it, change only the behavior 8049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of tests ANDed with it. That would change the documented 8050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * semantics of "vlan", which might break some expressions. 8051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * However, it would mean that "(vlan and ip) or ip" would check 8052478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * both for VLAN-encapsulated IP and IP-over-Ethernet, rather than 8053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * checking only for VLAN-encapsulated IP, so that could still 8054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * be considered worth doing; it wouldn't break expressions 8055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that are of the form "vlan and ..." or "vlan N and ...", 8056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * which I suspect are the most common expressions involving 8057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "vlan". "vlan or ..." doesn't necessarily do what the user 8058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * would really want, now, as all the "or ..." tests would 8059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * be done assuming a VLAN, even though the "or" could be viewed 8060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as meaning "or, if this isn't a VLAN packet...". 8061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 8062965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes switch (cstate->linktype) { 8063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_EN10MB: 8065511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER: 8066511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER_TRANSPARENT: 8067d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT) 8068d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Verify that this is the outer part of the packet and 8069d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * not encapsulated somehow. */ 8070965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->vlan_stack_depth == 0 && !cstate->off_linkhdr.is_variable && 8071965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkhdr.constant_part == 8072965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_outermostlinkhdr.constant_part) { 8073d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 8074d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Do we need special VLAN handling? 8075d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 8076965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->bpf_pcap->bpf_codegen_flags & BPF_SPECIAL_VLAN_HANDLING) 8077965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_vlan_bpf_extensions(cstate, vlan_num); 8078d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes else 8079965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_vlan_no_bpf_extensions(cstate, vlan_num); 8080d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } else 8081511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 8082965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_vlan_no_bpf_extensions(cstate, vlan_num); 8083d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes break; 8084d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8085d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_IEEE802_11: 8086d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_PRISM_HEADER: 8087d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_IEEE802_11_RADIO_AVS: 8088d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes case DLT_IEEE802_11_RADIO: 8089965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_vlan_no_bpf_extensions(cstate, vlan_num); 8090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 8093965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "no VLAN support for data link type %d", 8094965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->linktype); 8095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 8096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8098965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->vlan_stack_depth++; 8099d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b0); 8101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 8104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * support for MPLS 8105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 8106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 8107965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_mpls(compiler_state_t *cstate, int label_num) 8108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8109d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 8110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8111965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->label_stack_depth > 0) { 8112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* just match the bottom-of-stack bit clear */ 8113965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_mcmp(cstate, OR_PREVMPLSHDR, 2, BPF_B, 0, 0x01); 8114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 8115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 8116d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * We're not in an MPLS stack yet, so check the link-layer 8117d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * type against MPLS. 8118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 8119965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes switch (cstate->linktype) { 8120d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_C_HDLC: /* fall through */ 8122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_EN10MB: 8123511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER: 8124511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DLT_NETANALYZER_TRANSPARENT: 8125965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, ETHERTYPE_MPLS); 8126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8127d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case DLT_PPP: 8129965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, PPP_MPLS_UCAST); 8130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8131d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* FIXME add other DLT_s ... 8133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * for Frame-Relay/and ATM this may get messy due to SNAP headers 8134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * leave it for now */ 8135d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 8137965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "no MPLS support for data link type %d", 8138965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->linktype); 8139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = NULL; 8140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /*NOTREACHED*/ 8141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* If a specific MPLS label is requested, check it */ 8146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (label_num >= 0) { 8147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project label_num = label_num << 12; /* label is shifted 12 bits on the wire */ 8148965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_W, (bpf_int32)label_num, 8149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 0xfffff000); /* only compare the first 20 bits */ 8150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project b0 = b1; 8152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8154d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* 8155d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Change the offsets to point to the type and data fields within 8156d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the MPLS packet. Just increment the offsets, so that we 8157d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * can support a hierarchy, e.g. "mpls 100000 && mpls 1024" to 8158d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * capture packets with an outer label of 100000 and an inner 8159d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * label of 1024. 8160d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 8161d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Increment the MPLS stack depth as well; this indicates that 8162d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * we're checking MPLS-encapsulated headers, to make sure higher 8163d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * level code generators don't try to match against IP-related 8164d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * protocols such as Q_ARP, Q_RARP etc. 8165d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 8166d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * XXX - this is a bit of a kludge. See comments in gen_vlan(). 8167d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 8168965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap += 4; 8169965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl += 4; 8170965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->label_stack_depth++; 8171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (b0); 8172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 8175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Support PPPOE discovery and session. 8176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 8177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 8178965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_pppoed(compiler_state_t *cstate) 8179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* check for PPPoE discovery */ 8181965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes return gen_linktype(cstate, (bpf_int32)ETHERTYPE_PPPOED); 8182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 8185965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_pppoes(compiler_state_t *cstate, int sess_num) 8186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8187511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct block *b0, *b1; 8188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 8190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Test against the PPPoE session link-layer type. 8191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 8192965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_linktype(cstate, (bpf_int32)ETHERTYPE_PPPOES); 8193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8194d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* If a specific session is requested, check PPPoE session id */ 8195d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (sess_num >= 0) { 8196965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_W, 8197d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes (bpf_int32)sess_num, 0x0000ffff); 8198d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 8199d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = b1; 8200d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 8201d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 8203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Change the offsets to point to the type and data fields within 8204511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the PPP packet, and note that this is PPPoE rather than 8205511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * raw PPP. 8206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 8207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - this is a bit of a kludge. If we were to split the 8208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * compiler into a parser that parses an expression and 8209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * generates an expression tree, and a code generator that 8210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * takes an expression tree (which could come from our 8211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * parser or from some other parser) and generates BPF code, 8212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we could perhaps make the offsets parameters of routines 8213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and, in the handler for an "AND" node, pass to subnodes 8214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * other than the PPPoE node the adjusted offsets. 8215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 8216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This would mean that "pppoes" would, instead of changing the 8217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * behavior of *all* tests after it, change only the behavior 8218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of tests ANDed with it. That would change the documented 8219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * semantics of "pppoes", which might break some expressions. 8220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * However, it would mean that "(pppoes and ip) or ip" would check 8221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * both for VLAN-encapsulated IP and IP-over-Ethernet, rather than 8222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * checking only for VLAN-encapsulated IP, so that could still 8223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * be considered worth doing; it wouldn't break expressions 8224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that are of the form "pppoes and ..." which I suspect are the 8225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * most common expressions involving "pppoes". "pppoes or ..." 8226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * doesn't necessarily do what the user would really want, now, 8227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as all the "or ..." tests would be done assuming PPPoE, even 8228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * though the "or" could be viewed as meaning "or, if this isn't 8229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a PPPoE packet...". 8230d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 8231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The "network-layer" protocol is PPPoE, which has a 6-byte 8232511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * PPPoE header, followed by a PPP packet. 8233511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 8234511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * There is no HDLC encapsulation for the PPP packet (it's 8235511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * encapsulated in PPPoES instead), so the link-layer type 8236511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * starts at the first byte of the PPP packet. For PPPoE, 8237511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * that offset is relative to the beginning of the total 8238511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * link-layer payload, including any 802.2 LLC header, so 8239965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * it's 6 bytes past cstate->off_nl. 8240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 8241965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes PUSH_LINKHDR(cstate, DLT_PPP, cstate->off_linkpl.is_variable, 8242965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part + cstate->off_nl + 6, /* 6 bytes past the PPPoE header */ 8243965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.reg); 8244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8245965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype = cstate->off_linkhdr; 8246965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = cstate->off_linkhdr.constant_part + 2; 8247d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8248965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 8249965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 0; /* no 802.2 LLC */ 8250d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8251d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b0; 8252d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 8253d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8254d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* Check that this is Geneve and the VNI is correct if 8255d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * specified. Parameterized to handle both IPv4 and IPv6. */ 8256d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct block * 8257965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_geneve_check(compiler_state_t *cstate, 8258965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes struct block *(*gen_portfn)(compiler_state_t *, int, int, int), 8259965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes enum e_offrel offrel, int vni) 8260d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 8261d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 8262d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8263965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_portfn(cstate, GENEVE_PORT, IPPROTO_UDP, Q_DST); 8264d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8265d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Check that we are operating on version 0. Otherwise, we 8266d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * can't decode the rest of the fields. The version is 2 bits 8267d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * in the first byte of the Geneve header. */ 8268965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_mcmp(cstate, offrel, 8, BPF_B, (bpf_int32)0, 0xc0); 8269d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 8270d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = b1; 8271d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8272d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (vni >= 0) { 8273d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes vni <<= 8; /* VNI is in the upper 3 bytes */ 8274965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_mcmp(cstate, offrel, 12, BPF_W, (bpf_int32)vni, 8275d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 0xffffff00); 8276d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 8277d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = b1; 8278d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 8279d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8280d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b0; 8281d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 8282d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8283d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* The IPv4 and IPv6 Geneve checks need to do two things: 8284d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * - Verify that this actually is Geneve with the right VNI. 8285d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * - Place the IP header length (plus variable link prefix if 8286d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * needed) into register A to be used later to compute 8287d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the inner packet offsets. */ 8288d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct block * 8289965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_geneve4(compiler_state_t *cstate, int vni) 8290d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 8291d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 8292d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct slist *s, *s1; 8293d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8294965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_geneve_check(cstate, gen_port, OR_TRAN_IPV4, vni); 8295d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8296d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Load the IP header length into A. */ 8297965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_loadx_iphdrlen(cstate); 8298d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8299965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_MISC|BPF_TXA); 8300d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8301d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8302d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Forcibly append these statements to the true condition 8303d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * of the protocol check by creating a new block that is 8304d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * always true and ANDing them. */ 8305965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = new_block(cstate, BPF_JMP|BPF_JEQ|BPF_X); 8306d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1->stmts = s; 8307d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1->s.k = 0; 8308d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8309d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 8310d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8311d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 8312d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 8313d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8314d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct block * 8315965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_geneve6(compiler_state_t *cstate, int vni) 8316d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 8317d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 8318d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct slist *s, *s1; 8319d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8320965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_geneve_check(cstate, gen_port6, OR_TRAN_IPV6, vni); 8321d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8322d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Load the IP header length. We need to account for a 8323d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * variable length link prefix if there is one. */ 8324965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_abs_offset_varpart(cstate, &cstate->off_linkpl); 8325d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes if (s) { 8326965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_LD|BPF_IMM); 8327d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 40; 8328d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8329d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8330965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_X); 8331d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 0; 8332d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8333d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } else { 8334965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_LD|BPF_IMM); 8335965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s->s.k = 40; 8336d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes } 8337d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8338d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Forcibly append these statements to the true condition 8339d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * of the protocol check by creating a new block that is 8340d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * always true and ANDing them. */ 8341965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_MISC|BPF_TAX); 8342d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8343d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8344965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = new_block(cstate, BPF_JMP|BPF_JEQ|BPF_X); 8345d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1->stmts = s; 8346d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1->s.k = 0; 8347d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8348d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 8349d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8350d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 8351d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 8352d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8353d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* We need to store three values based on the Geneve header:: 8354d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * - The offset of the linktype. 8355d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * - The offset of the end of the Geneve header. 8356d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * - The offset of the end of the encapsulated MAC header. */ 8357d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct slist * 8358965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_geneve_offsets(compiler_state_t *cstate) 8359d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 8360d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct slist *s, *s1, *s_proto; 8361d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8362d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* First we need to calculate the offset of the Geneve header 8363d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * itself. This is composed of the IP header previously calculated 8364d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * (include any variable link prefix) and stored in A plus the 8365d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * fixed sized headers (fixed link prefix, MAC length, and UDP 8366d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * header). */ 8367965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_K); 8368965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s->s.k = cstate->off_linkpl.constant_part + cstate->off_nl + 8; 8369d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8370d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Stash this in X since we'll need it later. */ 8371965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_MISC|BPF_TAX); 8372d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8373d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8374d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* The EtherType in Geneve is 2 bytes in. Calculate this and 8375d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * store it. */ 8376965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_K); 8377d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 2; 8378d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8379d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8380965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.reg = alloc_reg(cstate); 8381965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.is_variable = 1; 8382965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = 0; 8383d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8384965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_ST); 8385965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1->s.k = cstate->off_linktype.reg; 8386d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8387d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8388d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Load the Geneve option length and mask and shift to get the 8389d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * number of bytes. It is stored in the first byte of the Geneve 8390d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * header. */ 8391965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_LD|BPF_IND|BPF_B); 8392d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 0; 8393d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8394d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8395965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_ALU|BPF_AND|BPF_K); 8396d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 0x3f; 8397d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8398d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8399965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_ALU|BPF_MUL|BPF_K); 8400d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 4; 8401d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8402d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8403d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Add in the rest of the Geneve base header. */ 8404965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_K); 8405d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 8; 8406d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8407d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8408d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Add the Geneve header length to its offset and store. */ 8409965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_X); 8410d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 0; 8411d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8412d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8413d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Set the encapsulated type as Ethernet. Even though we may 8414d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * not actually have Ethernet inside there are two reasons this 8415d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * is useful: 8416d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * - The linktype field is always in EtherType format regardless 8417d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * of whether it is in Geneve or an inner Ethernet frame. 8418d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * - The only link layer that we have specific support for is 8419d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Ethernet. We will confirm that the packet actually is 8420d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * Ethernet at runtime before executing these checks. */ 8421965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes PUSH_LINKHDR(cstate, DLT_EN10MB, 1, 0, alloc_reg(cstate)); 8422d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8423965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_ST); 8424965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1->s.k = cstate->off_linkhdr.reg; 8425d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8426d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8427d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Calculate whether we have an Ethernet header or just raw IP/ 8428d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * MPLS/etc. If we have Ethernet, advance the end of the MAC offset 8429d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * and linktype by 14 bytes so that the network header can be found 8430d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * seamlessly. Otherwise, keep what we've calculated already. */ 8431d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8432d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* We have a bare jmp so we can't use the optimizer. */ 8433965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->no_optimize = 1; 8434d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8435d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Load the EtherType in the Geneve header, 2 bytes in. */ 8436965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_LD|BPF_IND|BPF_H); 8437d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 2; 8438d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8439d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8440d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Load X with the end of the Geneve header. */ 8441965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_LDX|BPF_MEM); 8442965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1->s.k = cstate->off_linkhdr.reg; 8443d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8444d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8445d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Check if the EtherType is Transparent Ethernet Bridging. At the 8446d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * end of this check, we should have the total length in X. In 8447d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the non-Ethernet case, it's already there. */ 8448965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s_proto = new_stmt(cstate, JMP(BPF_JEQ)); 8449d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s_proto->s.k = ETHERTYPE_TEB; 8450d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s_proto); 8451d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8452965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_MISC|BPF_TXA); 8453d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8454d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s_proto->s.jt = s1; 8455d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8456d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Since this is Ethernet, use the EtherType of the payload 8457d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * directly as the linktype. Overwrite what we already have. */ 8458965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_K); 8459d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 12; 8460d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8461d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8462965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_ST); 8463965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1->s.k = cstate->off_linktype.reg; 8464d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8465d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8466d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Advance two bytes further to get the end of the Ethernet 8467d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * header. */ 8468965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_K); 8469d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s1->s.k = 2; 8470d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8471d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8472d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Move the result to X. */ 8473965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_MISC|BPF_TAX); 8474d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8475d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8476d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Store the final result of our linkpl calculation. */ 8477965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.reg = alloc_reg(cstate); 8478965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.is_variable = 1; 8479965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = 0; 8480d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8481965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_STX); 8482965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1->s.k = cstate->off_linkpl.reg; 8483d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8484d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes s_proto->s.jf = s1; 8485d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8486965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; 8487d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8488d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return s; 8489d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 8490d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8491d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* Check to see if this is a Geneve packet. */ 8492d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstruct block * 8493965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_geneve(compiler_state_t *cstate, int vni) 8494d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 8495d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0, *b1; 8496d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct slist *s; 8497d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8498965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_geneve4(cstate, vni); 8499965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_geneve6(cstate, vni); 8500d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8501d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_or(b0, b1); 8502d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0 = b1; 8503d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8504d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Later filters should act on the payload of the Geneve frame, 8505d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * update all of the header pointers. Attach this code so that 8506d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * it gets executed in the event that the Geneve filter matches. */ 8507965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = gen_geneve_offsets(cstate); 8508d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8509965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_true(cstate); 8510d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, b1->stmts); 8511d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b1->stmts = s; 8512d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8513d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_and(b0, b1); 8514d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8515965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->is_geneve = 1; 8516d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8517d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes return b1; 8518d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes} 8519d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8520d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* Check that the encapsulated frame has a link layer header 8521d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * for Ethernet filters. */ 8522d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic struct block * 8523965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_geneve_ll_check(compiler_state_t *cstate) 8524d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{ 8525d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct block *b0; 8526d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes struct slist *s, *s1; 8527d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8528d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* The easiest way to see if there is a link layer present 8529d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * is to check if the link layer header and payload are not 8530d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * the same. */ 8531d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8532d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes /* Geneve always generates pure variable offsets so we can 8533d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * compare only the registers. */ 8534965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s = new_stmt(cstate, BPF_LD|BPF_MEM); 8535965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s->s.k = cstate->off_linkhdr.reg; 8536d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8537965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1 = new_stmt(cstate, BPF_LDX|BPF_MEM); 8538965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes s1->s.k = cstate->off_linkpl.reg; 8539d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes sappend(s, s1); 8540d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes 8541965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = new_block(cstate, BPF_JMP|BPF_JEQ|BPF_X); 8542d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0->stmts = s; 8543d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes b0->s.k = 0; 8544d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes gen_not(b0); 8545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 8547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 8550965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_atmfield_code(compiler_state_t *cstate, int atmfield, bpf_int32 jvalue, 8551965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_u_int32 jtype, int reverse) 8552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0; 8554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (atmfield) { 8556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_VPI: 8558965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (!cstate->is_atm) 8559965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'vpi' supported only on raw ATM"); 8560965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_vpi == (u_int)-1) 8561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8562965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_vpi, BPF_B, 0xffffffff, jtype, 8563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project reverse, jvalue); 8564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_VCI: 8567965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (!cstate->is_atm) 8568965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'vci' supported only on raw ATM"); 8569965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_vci == (u_int)-1) 8570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8571965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_vci, BPF_H, 0xffffffff, jtype, 8572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project reverse, jvalue); 8573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_PROTOTYPE: 8576965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_proto == (u_int)-1) 8577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); /* XXX - this isn't on FreeBSD */ 8578965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_proto, BPF_B, 0x0f, jtype, 8579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project reverse, jvalue); 8580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_MSGTYPE: 8583965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_payload == (u_int)-1) 8584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8585965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_payload + MSG_TYPE_POS, BPF_B, 8586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 0xffffffff, jtype, reverse, jvalue); 8587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_CALLREFTYPE: 8590965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (!cstate->is_atm) 8591965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'callref' supported only on raw ATM"); 8592965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_proto == (u_int)-1) 8593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8594965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_proto, BPF_B, 0xffffffff, 8595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project jtype, reverse, jvalue); 8596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 8599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 8602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 8605965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_atmtype_abbrev(compiler_state_t *cstate, int type) 8606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 8608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (type) { 8610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_METAC: 8612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Get all packets in Meta signalling Circuit */ 8613965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (!cstate->is_atm) 8614965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'metac' supported only on raw ATM"); 8615965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0); 8616965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_atmfield_code(cstate, A_VCI, 1, BPF_JEQ, 0); 8617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_BCC: 8621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Get all packets in Broadcast Circuit*/ 8622965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (!cstate->is_atm) 8623965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'bcc' supported only on raw ATM"); 8624965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0); 8625965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_atmfield_code(cstate, A_VCI, 2, BPF_JEQ, 0); 8626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_OAMF4SC: 8630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Get all cells in Segment OAM F4 circuit*/ 8631965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (!cstate->is_atm) 8632965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'oam4sc' supported only on raw ATM"); 8633965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0); 8634965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_atmfield_code(cstate, A_VCI, 3, BPF_JEQ, 0); 8635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_OAMF4EC: 8639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Get all cells in End-to-End OAM F4 Circuit*/ 8640965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (!cstate->is_atm) 8641965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'oam4ec' supported only on raw ATM"); 8642965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0); 8643965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_atmfield_code(cstate, A_VCI, 4, BPF_JEQ, 0); 8644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_SC: 8648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Get all packets in connection Signalling Circuit */ 8649965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (!cstate->is_atm) 8650965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'sc' supported only on raw ATM"); 8651965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0); 8652965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_atmfield_code(cstate, A_VCI, 5, BPF_JEQ, 0); 8653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_ILMIC: 8657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Get all packets in ILMI Circuit */ 8658965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (!cstate->is_atm) 8659965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'ilmic' supported only on raw ATM"); 8660965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0); 8661965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_atmfield_code(cstate, A_VCI, 16, BPF_JEQ, 0); 8662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_LANE: 8666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Get all LANE packets */ 8667965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (!cstate->is_atm) 8668965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'lane' supported only on raw ATM"); 8669965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_atmfield_code(cstate, A_PROTOTYPE, PT_LANE, BPF_JEQ, 0); 8670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 8672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Arrange that all subsequent tests assume LANE 8673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * rather than LLC-encapsulated packets, and set 8674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the offsets appropriately for LANE-encapsulated 8675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet. 8676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 8677d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * We assume LANE means Ethernet, not Token Ring. 8678d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes */ 8679965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes PUSH_LINKHDR(cstate, DLT_EN10MB, 0, 8680965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_payload + 2, /* Ethernet header */ 8681d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes -1); 8682965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linktype.constant_part = cstate->off_linkhdr.constant_part + 12; 8683965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_linkpl.constant_part = cstate->off_linkhdr.constant_part + 14; /* Ethernet */ 8684965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl = 0; /* Ethernet II */ 8685965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->off_nl_nosnap = 3; /* 802.3+802.2 */ 8686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_LLC: 8689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Get all LLC-encapsulated packets */ 8690965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (!cstate->is_atm) 8691965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'llc' supported only on raw ATM"); 8692965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_atmfield_code(cstate, A_PROTOTYPE, PT_LLC, BPF_JEQ, 0); 8693965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes cstate->linktype = cstate->prevlinktype; 8694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 8697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 8700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8702d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes/* 8703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Filtering for MTP2 messages based on li value 8704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * FISU, length is null 8705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LSSU, length is 1 or 2 8706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * MSU, length is 3 or more 8707511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For MTP2_HSL, sequences are on 2 bytes, and length on 9 bits 8708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 8709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 8710965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_mtp2type_abbrev(compiler_state_t *cstate, int type) 8711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 8713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (type) { 8715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case M_FISU: 8717965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if ( (cstate->linktype != DLT_MTP2) && 8718965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cstate->linktype != DLT_ERF) && 8719965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cstate->linktype != DLT_MTP2_WITH_PHDR) ) 8720965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'fisu' supported only on MTP2"); 8721965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* gen_ncmp(cstate, offrel, offset, size, mask, jtype, reverse, value) */ 8722965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li, BPF_B, 0x3f, BPF_JEQ, 0, 0); 8723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case M_LSSU: 8726965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if ( (cstate->linktype != DLT_MTP2) && 8727965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cstate->linktype != DLT_ERF) && 8728965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cstate->linktype != DLT_MTP2_WITH_PHDR) ) 8729965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'lssu' supported only on MTP2"); 8730965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li, BPF_B, 0x3f, BPF_JGT, 1, 2); 8731965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_ncmp(cstate, OR_PACKET, cstate->off_li, BPF_B, 0x3f, BPF_JGT, 0, 0); 8732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b1, b0); 8733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case M_MSU: 8736965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if ( (cstate->linktype != DLT_MTP2) && 8737965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cstate->linktype != DLT_ERF) && 8738965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cstate->linktype != DLT_MTP2_WITH_PHDR) ) 8739965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'msu' supported only on MTP2"); 8740965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li, BPF_B, 0x3f, BPF_JGT, 0, 2); 8741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8743511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case MH_FISU: 8744965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if ( (cstate->linktype != DLT_MTP2) && 8745965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cstate->linktype != DLT_ERF) && 8746965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cstate->linktype != DLT_MTP2_WITH_PHDR) ) 8747965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'hfisu' supported only on MTP2_HSL"); 8748965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes /* gen_ncmp(cstate, offrel, offset, size, mask, jtype, reverse, value) */ 8749965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li_hsl, BPF_H, 0xff80, BPF_JEQ, 0, 0); 8750511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 8751511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 8752511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case MH_LSSU: 8753965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if ( (cstate->linktype != DLT_MTP2) && 8754965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cstate->linktype != DLT_ERF) && 8755965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cstate->linktype != DLT_MTP2_WITH_PHDR) ) 8756965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'hlssu' supported only on MTP2_HSL"); 8757965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li_hsl, BPF_H, 0xff80, BPF_JGT, 1, 0x0100); 8758965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_ncmp(cstate, OR_PACKET, cstate->off_li_hsl, BPF_H, 0xff80, BPF_JGT, 0, 0); 8759511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall gen_and(b1, b0); 8760511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 8761511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 8762511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case MH_MSU: 8763965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if ( (cstate->linktype != DLT_MTP2) && 8764965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cstate->linktype != DLT_ERF) && 8765965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes (cstate->linktype != DLT_MTP2_WITH_PHDR) ) 8766965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'hmsu' supported only on MTP2_HSL"); 8767965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li_hsl, BPF_H, 0xff80, BPF_JGT, 0, 0x0100); 8768511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 8769511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 8770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 8771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 8774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 8777965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_mtp3field_code(compiler_state_t *cstate, int mtp3field, bpf_u_int32 jvalue, 8778965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_u_int32 jtype, int reverse) 8779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0; 8781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 val1 , val2 , val3; 8782965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int newoff_sio = cstate->off_sio; 8783965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int newoff_opc = cstate->off_opc; 8784965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int newoff_dpc = cstate->off_dpc; 8785965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes u_int newoff_sls = cstate->off_sls; 8786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (mtp3field) { 8788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8789511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case MH_SIO: 8790511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall newoff_sio += 3; /* offset for MTP2_HSL */ 8791511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* FALLTHROUGH */ 8792511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 8793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case M_SIO: 8794965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_sio == (u_int)-1) 8795965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'sio' supported only on SS7"); 8796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* sio coded on 1 byte so max value 255 */ 8797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if(jvalue > 255) 8798965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "sio value %u too big; max value = 255", 8799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project jvalue); 8800965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ncmp(cstate, OR_PACKET, newoff_sio, BPF_B, 0xffffffff, 8801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (u_int)jtype, reverse, (u_int)jvalue); 8802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8804511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case MH_OPC: 8805511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall newoff_opc+=3; 8806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case M_OPC: 8807965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_opc == (u_int)-1) 8808965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'opc' supported only on SS7"); 8809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* opc coded on 14 bits so max value 16383 */ 8810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (jvalue > 16383) 8811965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "opc value %u too big; max value = 16383", 8812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project jvalue); 8813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* the following instructions are made to convert jvalue 8814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to the form used to write opc in an ss7 message*/ 8815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val1 = jvalue & 0x00003c00; 8816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val1 = val1 >>10; 8817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val2 = jvalue & 0x000003fc; 8818478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val2 = val2 <<6; 8819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val3 = jvalue & 0x00000003; 8820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val3 = val3 <<22; 8821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project jvalue = val1 + val2 + val3; 8822965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ncmp(cstate, OR_PACKET, newoff_opc, BPF_W, 0x00c0ff0f, 8823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (u_int)jtype, reverse, (u_int)jvalue); 8824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8825478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8826511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case MH_DPC: 8827511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall newoff_dpc += 3; 8828511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* FALLTHROUGH */ 8829511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 8830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case M_DPC: 8831965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_dpc == (u_int)-1) 8832965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'dpc' supported only on SS7"); 8833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* dpc coded on 14 bits so max value 16383 */ 8834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (jvalue > 16383) 8835965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "dpc value %u too big; max value = 16383", 8836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project jvalue); 8837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* the following instructions are made to convert jvalue 8838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to the forme used to write dpc in an ss7 message*/ 8839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val1 = jvalue & 0x000000ff; 8840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val1 = val1 << 24; 8841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val2 = jvalue & 0x00003f00; 8842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project val2 = val2 << 8; 8843478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project jvalue = val1 + val2; 8844965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ncmp(cstate, OR_PACKET, newoff_dpc, BPF_W, 0xff3f0000, 8845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (u_int)jtype, reverse, (u_int)jvalue); 8846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8848511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case MH_SLS: 8849511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall newoff_sls+=3; 8850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case M_SLS: 8851965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (cstate->off_sls == (u_int)-1) 8852965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'sls' supported only on SS7"); 8853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* sls coded on 4 bits so max value 15 */ 8854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (jvalue > 15) 8855965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "sls value %u too big; max value = 15", 8856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project jvalue); 8857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* the following instruction is made to convert jvalue 8858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to the forme used to write sls in an ss7 message*/ 8859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project jvalue = jvalue << 4; 8860965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_ncmp(cstate, OR_PACKET, newoff_sls, BPF_B, 0xf0, 8861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (u_int)jtype,reverse, (u_int)jvalue); 8862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 8865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b0; 8868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block * 8871965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_msg_abbrev(compiler_state_t *cstate, int type) 8872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b1; 8874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 8876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Q.2931 signalling protocol messages for handling virtual circuits 8877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * establishment and teardown 8878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 8879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (type) { 8880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_SETUP: 8882965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_atmfield_code(cstate, A_MSGTYPE, SETUP, BPF_JEQ, 0); 8883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_CALLPROCEED: 8886965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_atmfield_code(cstate, A_MSGTYPE, CALL_PROCEED, BPF_JEQ, 0); 8887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_CONNECT: 8890965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_atmfield_code(cstate, A_MSGTYPE, CONNECT, BPF_JEQ, 0); 8891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_CONNECTACK: 8894965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_atmfield_code(cstate, A_MSGTYPE, CONNECT_ACK, BPF_JEQ, 0); 8895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_RELEASE: 8898965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_atmfield_code(cstate, A_MSGTYPE, RELEASE, BPF_JEQ, 0); 8899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_RELEASE_DONE: 8902965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_atmfield_code(cstate, A_MSGTYPE, RELEASE_DONE, BPF_JEQ, 0); 8903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 8906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 8909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8910478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8911478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block * 8912965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesgen_atmmulti_abbrev(compiler_state_t *cstate, int type) 8913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 8914478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct block *b0, *b1; 8915478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (type) { 8917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_OAM: 8919965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (!cstate->is_atm) 8920965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'oam' supported only on raw ATM"); 8921965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_atmmulti_abbrev(cstate, A_OAMF4); 8922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8923478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8924478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_OAMF4: 8925965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (!cstate->is_atm) 8926965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'oamf4' supported only on raw ATM"); 8927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* OAM F4 type */ 8928965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_atmfield_code(cstate, A_VCI, 3, BPF_JEQ, 0); 8929965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_atmfield_code(cstate, A_VCI, 4, BPF_JEQ, 0); 8930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8931965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0); 8932478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_CONNECTMSG: 8936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 8937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Get Q.2931 signalling messages for switched 8938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * virtual connection 8939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 8940965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (!cstate->is_atm) 8941965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'connectmsg' supported only on raw ATM"); 8942965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_msg_abbrev(cstate, A_SETUP); 8943965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_msg_abbrev(cstate, A_CALLPROCEED); 8944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8945965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_msg_abbrev(cstate, A_CONNECT); 8946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8947965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_msg_abbrev(cstate, A_CONNECTACK); 8948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8949965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_msg_abbrev(cstate, A_RELEASE); 8950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8951965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_msg_abbrev(cstate, A_RELEASE_DONE); 8952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8953965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_atmtype_abbrev(cstate, A_SC); 8954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case A_METACONNECT: 8958965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (!cstate->is_atm) 8959965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes bpf_error(cstate, "'metaconnect' supported only on raw ATM"); 8960965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_msg_abbrev(cstate, A_SETUP); 8961965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b1 = gen_msg_abbrev(cstate, A_CALLPROCEED); 8962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8963965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_msg_abbrev(cstate, A_CONNECT); 8964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8965965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_msg_abbrev(cstate, A_RELEASE); 8966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8967965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_msg_abbrev(cstate, A_RELEASE_DONE); 8968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_or(b0, b1); 8969965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes b0 = gen_atmtype_abbrev(cstate, A_METAC); 8970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project gen_and(b0, b1); 8971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 8972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 8973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 8974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project abort(); 8975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 8976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return b1; 8977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 8978