gencode.c revision 511eca30a483e912c274e1d8ba3a0f8f081e2227
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#ifndef lint
23478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic const char rcsid[] _U_ =
24511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.309 2008-12-23 20:13:29 guy Exp $ (LBL)";
25478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
26478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
27478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_CONFIG_H
28478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "config.h"
29478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
30478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
31478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef WIN32
32478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <pcap-stdinc.h>
33478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else /* WIN32 */
34511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#if HAVE_INTTYPES_H
35511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <inttypes.h>
36511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#elif HAVE_STDINT_H
37511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stdint.h>
38511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
39511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_SYS_BITYPES_H
40511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/bitypes.h>
41511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
42478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/types.h>
43478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/socket.h>
44478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* WIN32 */
45478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
46478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
47478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - why was this included even on UNIX?
48478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
49478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef __MINGW32__
50511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "ip6_misc.h"
51478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
52478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
53478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef WIN32
54478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
55478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef __NetBSD__
56478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/param.h>
57478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
58478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
59478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/in.h>
60511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <arpa/inet.h>
61478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
62478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* WIN32 */
63478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
64478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdlib.h>
65478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <string.h>
66478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <memory.h>
67478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <setjmp.h>
68478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdarg.h>
69478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
70478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef MSDOS
71478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap-dos.h"
72478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
73478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
74478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap-int.h"
75478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
76478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "ethertype.h"
77478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "nlpid.h"
78478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "llc.h"
79478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "gencode.h"
80511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "ieee80211.h"
81478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "atmuni31.h"
82478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "sunatmpos.h"
83478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "ppp.h"
84511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "pcap/sll.h"
85511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "pcap/ipnet.h"
86478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "arcnet.h"
87511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#if defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
88511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <linux/types.h>
89511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <linux/if_packet.h>
90511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <linux/filter.h>
91511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
92478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_NET_PFVAR_H
93478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/socket.h>
94478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if.h>
95478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/pfvar.h>
96478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if_pflog.h>
97478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
98478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef offsetof
99478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define offsetof(s, e) ((size_t)&((s *)0)->e)
100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6
102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef WIN32
103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netdb.h>	/* for "struct addrinfo" */
104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* WIN32 */
105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /*INET6*/
106511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <pcap/namedb.h>
107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define ETHERMTU	1500
109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
110511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef IPPROTO_HOPOPTS
111511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IPPROTO_HOPOPTS 0
112511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
113511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef IPPROTO_ROUTING
114511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IPPROTO_ROUTING 43
115511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
116511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef IPPROTO_FRAGMENT
117511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IPPROTO_FRAGMENT 44
118511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
119511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef IPPROTO_DSTOPTS
120511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IPPROTO_DSTOPTS 60
121511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_SCTP
123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_SCTP 132
124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_OS_PROTO_H
127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "os-proto.h"
128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define JMP(c) ((c)|BPF_JMP|BPF_K)
131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* Locals */
133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic jmp_buf top_ctx;
134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic pcap_t *bpf_pcap;
135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* Hack for updating VLAN, MPLS, and PPPoE offsets. */
137511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef WIN32
138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int	orig_linktype = (u_int)-1, orig_nl = (u_int)-1, label_stack_depth = (u_int)-1;
139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int	orig_linktype = -1U, orig_nl = -1U, label_stack_depth = -1U;
141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* XXX */
144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int	pcap_fddipad;
145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* VARARGS */
147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid
148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectbpf_error(const char *fmt, ...)
149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	va_list ap;
151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	va_start(ap, fmt);
153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (bpf_pcap != NULL)
154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)vsnprintf(pcap_geterr(bpf_pcap), PCAP_ERRBUF_SIZE,
155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    fmt, ap);
156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	va_end(ap);
157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	longjmp(top_ctx, 1);
158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void init_linktype(pcap_t *);
162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
163511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void init_regs(void);
164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int alloc_reg(void);
165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void free_reg(int);
166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *root;
168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Value passed to gen_load_a() to indicate what the offset argument
171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is relative to.
172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectenum e_offrel {
174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	OR_PACKET,	/* relative to the beginning of the packet */
175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	OR_LINK,	/* relative to the beginning of the link-layer header */
176511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	OR_MACPL,	/* relative to the end of the MAC-layer header */
177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	OR_NET,		/* relative to the network-layer header */
178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	OR_NET_NOSNAP,	/* relative to the network-layer header, with no SNAP header at the link layer */
179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	OR_TRAN_IPV4,	/* relative to the transport-layer header, with IPv4 network layer */
180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	OR_TRAN_IPV6	/* relative to the transport-layer header, with IPv6 network layer */
181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project};
182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
183511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef INET6
184511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
185511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * As errors are handled by a longjmp, anything allocated must be freed
186511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * in the longjmp handler, so it must be reachable from that handler.
187511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * One thing that's allocated is the result of pcap_nametoaddrinfo();
188511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * it must be freed with freeaddrinfo().  This variable points to any
189511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * addrinfo structure that would need to be freed.
190511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
191511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct addrinfo *ai;
192511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
193511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We divy out chunks of memory rather than call malloc each time so
196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we don't have to worry about leaking memory.  It's probably
197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * not a big deal if all this memory was wasted but if this ever
198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * goes into a library that would probably not be a good idea.
199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - this *is* in a library....
201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define NCHUNKS 16
203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define CHUNK0SIZE 1024
204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct chunk {
205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int n_left;
206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	void *m;
207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project};
208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct chunk chunks[NCHUNKS];
210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int cur_chunk;
211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void *newchunk(u_int);
213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void freechunks(void);
214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct block *new_block(int);
215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct slist *new_stmt(int);
216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_retblk(int);
217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline void syntax(void);
218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void backpatch(struct block *, struct block *);
220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void merge(struct block *, struct block *);
221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_cmp(enum e_offrel, u_int, u_int, bpf_int32);
222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_cmp_gt(enum e_offrel, u_int, u_int, bpf_int32);
223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_cmp_ge(enum e_offrel, u_int, u_int, bpf_int32);
224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_cmp_lt(enum e_offrel, u_int, u_int, bpf_int32);
225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_cmp_le(enum e_offrel, u_int, u_int, bpf_int32);
226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_mcmp(enum e_offrel, u_int, u_int, bpf_int32,
227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    bpf_u_int32);
228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_bcmp(enum e_offrel, u_int, u_int, const u_char *);
229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_ncmp(enum e_offrel, bpf_u_int32, bpf_u_int32,
230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    bpf_u_int32, bpf_u_int32, int, bpf_int32);
231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist *gen_load_llrel(u_int, u_int);
232511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *gen_load_macplrel(u_int, u_int);
233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist *gen_load_a(enum e_offrel, u_int, u_int);
234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist *gen_loadx_iphdrlen(void);
235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_uncond(int);
236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct block *gen_true(void);
237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct block *gen_false(void);
238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_ether_linktype(int);
239511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct block *gen_ipnet_linktype(int);
240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_linux_sll_linktype(int);
241511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *gen_load_prism_llprefixlen(void);
242511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *gen_load_avs_llprefixlen(void);
243511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *gen_load_radiotap_llprefixlen(void);
244511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *gen_load_ppi_llprefixlen(void);
245511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void insert_compute_vloffsets(struct block *);
246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist *gen_llprefixlen(void);
247511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *gen_off_macpl(void);
248511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int ethertype_to_ppptype(int);
249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_linktype(int);
250511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct block *gen_snap(bpf_u_int32, bpf_u_int32);
251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_llc_linktype(int);
252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int);
253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6
254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_hostop6(struct in6_addr *, struct in6_addr *, int, int, u_int, u_int);
255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_ahostop(const u_char *, int);
257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_ehostop(const u_char *, int);
258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_fhostop(const u_char *, int);
259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_thostop(const u_char *, int);
260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_wlanhostop(const u_char *, int);
261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_ipfchostop(const u_char *, int);
262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_dnhostop(bpf_u_int32, int);
263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_mpls_linktype(int);
264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int, int);
265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6
266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_host6(struct in6_addr *, struct in6_addr *, int, int, int);
267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef INET6
269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int);
270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_ipfrag(void);
272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_portatom(int, bpf_int32);
273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_portrangeatom(int, bpf_int32, bpf_int32);
274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_portatom6(int, bpf_int32);
275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_portrangeatom6(int, bpf_int32, bpf_int32);
276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *gen_portop(int, int, int);
277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_port(int, int, int);
278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *gen_portrangeop(int, int, int, int);
279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_portrange(int, int, int, int);
280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *gen_portop6(int, int, int);
281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_port6(int, int, int);
282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *gen_portrangeop6(int, int, int, int);
283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_portrange6(int, int, int, int);
284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int lookup_proto(const char *, int);
285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_protochain(int, int, int);
286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_proto(int, int, int);
287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist *xfer_to_x(struct arth *);
288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist *xfer_to_a(struct arth *);
289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_mac_multicast(int);
290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_len(int, int);
291511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct block *gen_check_802_11_data_frame(void);
292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_ppi_dlt_check(void);
294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *gen_msg_abbrev(int type);
295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void *
297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectnewchunk(n)
298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int n;
299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct chunk *cp;
301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int k;
302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	size_t size;
303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef __NetBSD__
305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* XXX Round up to nearest long. */
306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1);
307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* XXX Round up to structure boundary. */
309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	n = ALIGN(n);
310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	cp = &chunks[cur_chunk];
313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (n > cp->n_left) {
314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		++cp, k = ++cur_chunk;
315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (k >= NCHUNKS)
316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("out of memory");
317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		size = CHUNK0SIZE << k;
318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		cp->m = (void *)malloc(size);
319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (cp->m == NULL)
320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("out of memory");
321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		memset((char *)cp->m, 0, size);
322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		cp->n_left = size;
323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (n > size)
324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("out of memory");
325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	cp->n_left -= n;
327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (void *)((char *)cp->m + cp->n_left);
328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void
331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectfreechunks()
332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int i;
334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	cur_chunk = 0;
336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	for (i = 0; i < NCHUNKS; ++i)
337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (chunks[i].m != NULL) {
338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			free(chunks[i].m);
339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			chunks[i].m = NULL;
340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * A strdup whose allocations are freed after code generation is over.
345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectchar *
347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectsdup(s)
348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register const char *s;
349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int n = strlen(s) + 1;
351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	char *cp = newchunk(n);
352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	strlcpy(cp, s, n);
354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (cp);
355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct block *
358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectnew_block(code)
359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int code;
360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *p;
362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p = (struct block *)newchunk(sizeof(*p));
364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->s.code = code;
365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->head = p;
366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return p;
368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct slist *
371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectnew_stmt(code)
372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int code;
373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *p;
375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p = (struct slist *)newchunk(sizeof(*p));
377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->s.code = code;
378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return p;
380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_retblk(v)
384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int v;
385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b = new_block(BPF_RET|BPF_K);
387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b->s.k = v;
389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b;
390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline void
393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectsyntax()
394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_error("syntax error in filter expression");
396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic bpf_u_int32 netmask;
399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int snaplen;
400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint no_optimize;
401511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef WIN32
402511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
403511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_compile_unsafe(pcap_t *p, struct bpf_program *program,
404511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	     const char *buf, int optimize, bpf_u_int32 mask);
405511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
406511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallint
407511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_compile(pcap_t *p, struct bpf_program *program,
408511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	     const char *buf, int optimize, bpf_u_int32 mask)
409511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
410511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int result;
411511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
412511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	EnterCriticalSection(&g_PcapCompileCriticalSection);
413511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
414511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	result = pcap_compile_unsafe(p, program, buf, optimize, mask);
415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
416511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	LeaveCriticalSection(&g_PcapCompileCriticalSection);
417511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
418511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return result;
419511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
420511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
421511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
422511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_compile_unsafe(pcap_t *p, struct bpf_program *program,
423511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	     const char *buf, int optimize, bpf_u_int32 mask)
424511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else /* WIN32 */
425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint
426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_compile(pcap_t *p, struct bpf_program *program,
427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	     const char *buf, int optimize, bpf_u_int32 mask)
428511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif /* WIN32 */
429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	extern int n_errors;
431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	const char * volatile xbuf = buf;
432511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_int len;
433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
434511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
435511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * If this pcap_t hasn't been activated, it doesn't have a
436511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * link-layer type, so we can't use it.
437511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
438511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (!p->activated) {
439511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
440511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    "not-yet-activated pcap_t passed to pcap_compile");
441511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (-1);
442511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	no_optimize = 0;
444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	n_errors = 0;
445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	root = NULL;
446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_pcap = p;
447511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	init_regs();
448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (setjmp(top_ctx)) {
449511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef INET6
450511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (ai != NULL) {
451511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			freeaddrinfo(ai);
452511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			ai = NULL;
453511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
454511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		lex_cleanup();
456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		freechunks();
457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (-1);
458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	netmask = mask;
461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	snaplen = pcap_snapshot(p);
463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (snaplen == 0) {
464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 "snaplen of 0 rejects all packets");
466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return -1;
467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	lex_init(xbuf ? xbuf : "");
470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	init_linktype(p);
471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	(void)pcap_parse();
472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (n_errors)
474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		syntax();
475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (root == NULL)
477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		root = gen_retblk(snaplen);
478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (optimize && !no_optimize) {
480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_optimize(&root);
481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (root == NULL ||
482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0))
483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("expression rejects all packets");
484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	program->bf_insns = icode_to_fcode(root, &len);
486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	program->bf_len = len;
487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	lex_cleanup();
489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	freechunks();
490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (0);
491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * entry point for using the compiler with no pcap open
495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * pass in all the stuff that is needed explicitly instead.
496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint
498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_compile_nopcap(int snaplen_arg, int linktype_arg,
499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    struct bpf_program *program,
500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	     const char *buf, int optimize, bpf_u_int32 mask)
501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	pcap_t *p;
503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int ret;
504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p = pcap_open_dead(linktype_arg, snaplen_arg);
506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (p == NULL)
507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (-1);
508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ret = pcap_compile(p, program, buf, optimize, mask);
509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	pcap_close(p);
510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (ret);
511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Clean up a "struct bpf_program" by freeing all the memory allocated
515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in it.
516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid
518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_freecode(struct bpf_program *program)
519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	program->bf_len = 0;
521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (program->bf_insns != NULL) {
522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		free((char *)program->bf_insns);
523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		program->bf_insns = NULL;
524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Backpatch the blocks in 'list' to 'target'.  The 'sense' field indicates
529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * which of the jt and jf fields has been resolved and which is a pointer
530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * back to another unresolved block (or nil).  At least one of the fields
531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in each block is already resolved.
532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void
534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectbackpatch(list, target)
535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *list, *target;
536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *next;
538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	while (list) {
540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (!list->sense) {
541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			next = JT(list);
542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			JT(list) = target;
543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else {
544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			next = JF(list);
545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			JF(list) = target;
546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		list = next;
548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Merge the lists in b0 and b1, using the 'sense' field to indicate
553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * which of jt and jf is the link.
554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void
556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectmerge(b0, b1)
557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1;
558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register struct block **p = &b0;
560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Find end of list. */
562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	while (*p)
563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p = !((*p)->sense) ? &JT(*p) : &JF(*p);
564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Concatenate the lists. */
566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	*p = b1;
567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid
570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectfinish_parse(p)
571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *p;
572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *ppi_dlt_check;
574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Insert before the statements of the first (root) block any
577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * statements needed to load the lengths of any variable-length
578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * headers into registers.
579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 *
580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * XXX - a fancier strategy would be to insert those before the
581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * statements of all blocks that use those lengths and that
582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * have no predecessors that use them, so that we only compute
583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * the lengths if we need them.  There might be even better
584511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * approaches than that.
585511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 *
586511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * However, those strategies would be more complicated, and
587511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * as we don't generate code to compute a length if the
588511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * program has no tests that use the length, and as most
589511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * tests will probably use those lengths, we would just
590511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * postpone computing the lengths so that it's not done
591511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * for tests that fail early, and it's not clear that's
592511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * worth the effort.
593511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
594511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	insert_compute_vloffsets(p->head);
595511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
596511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
597511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * For DLT_PPI captures, generate a check of the per-packet
598511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * DLT value to make sure it's DLT_IEEE802_11.
599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
600511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	ppi_dlt_check = gen_ppi_dlt_check();
601511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (ppi_dlt_check != NULL)
602511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_and(ppi_dlt_check, p);
603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
604511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	backpatch(p, gen_retblk(snaplen));
605511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->sense = !p->sense;
606511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	backpatch(p, gen_retblk(0));
607511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	root = p->head;
608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid
611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_and(b0, b1)
612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1;
613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	backpatch(b0, b1->head);
615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0->sense = !b0->sense;
616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b1->sense = !b1->sense;
617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	merge(b1, b0);
618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b1->sense = !b1->sense;
619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b1->head = b0->head;
620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid
623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_or(b0, b1)
624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1;
625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0->sense = !b0->sense;
627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	backpatch(b0, b1->head);
628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0->sense = !b0->sense;
629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	merge(b1, b0);
630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b1->head = b0->head;
631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid
634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_not(b)
635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b;
636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b->sense = !b->sense;
638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_cmp(offrel, offset, size, v)
642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	enum e_offrel offrel;
643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int offset, size;
644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_int32 v;
645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JEQ, 0, v);
647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_cmp_gt(offrel, offset, size, v)
651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	enum e_offrel offrel;
652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int offset, size;
653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_int32 v;
654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGT, 0, v);
656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_cmp_ge(offrel, offset, size, v)
660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	enum e_offrel offrel;
661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int offset, size;
662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_int32 v;
663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGE, 0, v);
665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_cmp_lt(offrel, offset, size, v)
669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	enum e_offrel offrel;
670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int offset, size;
671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_int32 v;
672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGE, 1, v);
674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_cmp_le(offrel, offset, size, v)
678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	enum e_offrel offrel;
679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int offset, size;
680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_int32 v;
681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGT, 1, v);
683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_mcmp(offrel, offset, size, v, mask)
687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	enum e_offrel offrel;
688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int offset, size;
689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_int32 v;
690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 mask;
691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return gen_ncmp(offrel, offset, size, mask, BPF_JEQ, 0, v);
693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_bcmp(offrel, offset, size, v)
697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	enum e_offrel offrel;
698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register u_int offset, size;
699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register const u_char *v;
700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register struct block *b, *tmp;
702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b = NULL;
704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	while (size >= 4) {
705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		register const u_char *p = &v[size - 4];
706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_int32 w = ((bpf_int32)p[0] << 24) |
707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    ((bpf_int32)p[1] << 16) | ((bpf_int32)p[2] << 8) | p[3];
708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_cmp(offrel, offset + size - 4, BPF_W, w);
710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (b != NULL)
711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_and(b, tmp);
712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b = tmp;
713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		size -= 4;
714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	while (size >= 2) {
716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		register const u_char *p = &v[size - 2];
717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_int32 w = ((bpf_int32)p[0] << 8) | p[1];
718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_cmp(offrel, offset + size - 2, BPF_H, w);
720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (b != NULL)
721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_and(b, tmp);
722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b = tmp;
723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		size -= 2;
724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (size > 0) {
726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_cmp(offrel, offset, BPF_B, (bpf_int32)v[0]);
727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (b != NULL)
728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_and(b, tmp);
729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b = tmp;
730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b;
732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * AND the field of size "size" at offset "offset" relative to the header
736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * specified by "offrel" with "mask", and compare it with the value "v"
737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with the test specified by "jtype"; if "reverse" is true, the test
738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * should test the opposite of "jtype".
739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ncmp(offrel, offset, size, mask, jtype, reverse, v)
742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	enum e_offrel offrel;
743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_int32 v;
744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 offset, size, mask, jtype;
745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int reverse;
746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s, *s2;
748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b;
749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s = gen_load_a(offrel, offset, size);
751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (mask != 0xffffffff) {
753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_ALU|BPF_AND|BPF_K);
754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2->s.k = mask;
755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s, s2);
756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b = new_block(JMP(jtype));
759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b->stmts = s;
760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b->s.k = v;
761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (reverse && (jtype == BPF_JGT || jtype == BPF_JGE))
762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_not(b);
763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b;
764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Various code constructs need to know the layout of the data link
768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * layer.  These variables give the necessary offsets from the beginning
769478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of the packet data.
770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is the offset of the beginning of the link-layer header from
774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the beginning of the raw packet data.
775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * It's usually 0, except for 802.11 with a fixed-length radio header.
777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (For 802.11 with a variable-length radio header, we have to generate
778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * code to compute that offset; off_ll is 0 in that case.)
779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_ll;
781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
783511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If there's a variable-length header preceding the link-layer header,
784511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * "reg_off_ll" is the register number for a register containing the
785511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * length of that header, and therefore the offset of the link-layer
786511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * header from the beginning of the raw packet data.  Otherwise,
787511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * "reg_off_ll" is -1.
788511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
789511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int reg_off_ll;
790511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
791511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
792511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * This is the offset of the beginning of the MAC-layer header from
793511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the beginning of the link-layer header.
794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * It's usually 0, except for ATM LANE, where it's the offset, relative
795511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * to the beginning of the raw packet data, of the Ethernet header, and
796511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * for Ethernet with various additional information.
797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_mac;
799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
801511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * This is the offset of the beginning of the MAC-layer payload,
802511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * from the beginning of the raw packet data.
803511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *
804511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * I.e., it's the sum of the length of the link-layer header (without,
805511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * for example, any 802.2 LLC header, so it's the MAC-layer
806511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * portion of that header), plus any prefix preceding the
807511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * link-layer header.
808511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
809511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic u_int off_macpl;
810511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
811511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
812511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * This is 1 if the offset of the beginning of the MAC-layer payload
813511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * from the beginning of the link-layer header is variable-length.
814511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
815511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int off_macpl_is_variable;
816511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
817511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
818511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If the link layer has variable_length headers, "reg_off_macpl"
819511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * is the register number for a register containing the length of the
820511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * link-layer header plus the length of any variable-length header
821511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * preceding the link-layer header.  Otherwise, "reg_off_macpl"
822511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * is -1.
823511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
824511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int reg_off_macpl;
825511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
826511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "off_linktype" is the offset to information in the link-layer header
828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * giving the packet type.  This offset is relative to the beginning
829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of the link-layer header (i.e., it doesn't include off_ll).
830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For Ethernet, it's the offset of the Ethernet type field.
832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For link-layer types that always use 802.2 headers, it's the
834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * offset of the LLC header.
835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For PPP, it's the offset of the PPP type field.
837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For Cisco HDLC, it's the offset of the CHDLC type field.
839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For BSD loopback, it's the offset of the AF_ value.
841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For Linux cooked sockets, it's the offset of the type field.
843478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * It's set to -1 for no encapsulation, in which case, IP is assumed.
845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_linktype;
847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
849511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * TRUE if "pppoes" appeared in the filter; it causes link-layer type
850511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * checks to check the PPP header, assumed to follow a LAN-style link-
851511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * layer header and a PPPoE session header.
852511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
853511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int is_pppoes = 0;
854511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
855511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * TRUE if the link layer includes an ATM pseudo-header.
857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int is_atm = 0;
859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * TRUE if "lane" appeared in the filter; it causes us to generate
862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * code that assumes LANE rather than LLC-encapsulated traffic in SunATM.
863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int is_lane = 0;
865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * These are offsets for the ATM pseudo-header.
868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_vpi;
870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_vci;
871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_proto;
872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * These are offsets for the MTP2 fields.
875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_li;
877511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic u_int off_li_hsl;
878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * These are offsets for the MTP3 fields.
881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_sio;
883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_opc;
884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_dpc;
885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_sls;
886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is the offset of the first byte after the ATM pseudo_header,
889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * or -1 if there is no ATM pseudo-header.
890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_payload;
892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * These are offsets to the beginning of the network-layer header.
895511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * They are relative to the beginning of the MAC-layer payload (i.e.,
896511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * they don't include off_ll or off_macpl).
897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If the link layer never uses 802.2 LLC:
899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *	"off_nl" and "off_nl_nosnap" are the same.
901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If the link layer always uses 802.2 LLC:
903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *	"off_nl" is the offset if there's a SNAP header following
905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *	the 802.2 header;
906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *	"off_nl_nosnap" is the offset if there's no SNAP header.
908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If the link layer is Ethernet:
910478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
911478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *	"off_nl" is the offset if the packet is an Ethernet II packet
912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *	(we assume no 802.3+802.2+SNAP);
913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
914478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *	"off_nl_nosnap" is the offset if the packet is an 802.3 packet
915478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *	with an 802.2 header following it.
916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_nl;
918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_int off_nl_nosnap;
919478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
920478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int linktype;
921478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void
923478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectinit_linktype(p)
924478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	pcap_t *p;
925478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
926478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	linktype = pcap_datalink(p);
927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	pcap_fddipad = p->fddipad;
928478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
929478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Assume it's not raw ATM with a pseudo-header, for now.
931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
932478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	off_mac = 0;
933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	is_atm = 0;
934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	is_lane = 0;
935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	off_vpi = -1;
936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	off_vci = -1;
937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	off_proto = -1;
938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	off_payload = -1;
939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
941511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * And that we're not doing PPPoE.
942511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
943511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	is_pppoes = 0;
944511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
945511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * And assume we're not doing SS7.
947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	off_li = -1;
949511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	off_li_hsl = -1;
950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	off_sio = -1;
951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	off_opc = -1;
952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	off_dpc = -1;
953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	off_sls = -1;
954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
956511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Also assume it's not 802.11.
957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	off_ll = 0;
959511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	off_macpl = 0;
960511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	off_macpl_is_variable = 0;
961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	orig_linktype = -1;
963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	orig_nl = -1;
964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        label_stack_depth = 0;
965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
966511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	reg_off_ll = -1;
967511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	reg_off_macpl = -1;
968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (linktype) {
970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_ARCNET:
972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 2;
973511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 6;
974511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;		/* XXX in reality, variable! */
975511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 0;	/* no 802.2 LLC */
976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_ARCNET_LINUX:
979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 4;
980511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 8;
981511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;		/* XXX in reality, variable! */
982511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 0;	/* no 802.2 LLC */
983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
984478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_EN10MB:
986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 12;
987511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 14;		/* Ethernet header length */
988511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;		/* Ethernet II */
989511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 3;	/* 802.3+802.2 */
990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_SLIP:
993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * SLIP doesn't have a link level type.  The 16 byte
995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * header is hacked into our SLIP driver.
996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = -1;
998511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 16;
999511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;
1000511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 0;	/* no 802.2 LLC */
1001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_SLIP_BSDOS:
1004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* XXX this may be the same as the DLT_PPP_BSDOS case */
1005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = -1;
1006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* XXX end */
1007511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 24;
1008511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;
1009511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 0;	/* no 802.2 LLC */
1010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_NULL:
1013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_LOOP:
1014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 0;
1015511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 4;
1016511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;
1017511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 0;	/* no 802.2 LLC */
1018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_ENC:
1021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 0;
1022511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 12;
1023511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;
1024511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 0;	/* no 802.2 LLC */
1025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_PPP:
1028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_PPP_PPPD:
1029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_C_HDLC:		/* BSD/OS Cisco HDLC */
1030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_PPP_SERIAL:		/* NetBSD sync/async serial PPP */
1031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 2;
1032511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 4;
1033511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;
1034511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 0;	/* no 802.2 LLC */
1035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_PPP_ETHER:
1038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * This does no include the Ethernet header, and
1040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * only covers session state.
1041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1042478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 6;
1043511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 8;
1044511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;
1045511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 0;	/* no 802.2 LLC */
1046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_PPP_BSDOS:
1049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 5;
1050511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 24;
1051511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;
1052511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 0;	/* no 802.2 LLC */
1053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_FDDI:
1056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * FDDI doesn't really have a link-level type field.
1058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * We set "off_linktype" to the offset of the LLC header.
1059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * To check for Ethernet types, we assume that SSAP = SNAP
1061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * is being used and pick out the encapsulated Ethernet type.
1062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - should we generate code to check for SNAP?
1063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 13;
1065478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype += pcap_fddipad;
1066511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 13;		/* FDDI MAC header length */
1067511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl += pcap_fddipad;
1068511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 8;		/* 802.2+SNAP */
1069511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 3;	/* 802.2 */
1070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_IEEE802:
1073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1074478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Token Ring doesn't really have a link-level type field.
1075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * We set "off_linktype" to the offset of the LLC header.
1076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * To check for Ethernet types, we assume that SSAP = SNAP
1078478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * is being used and pick out the encapsulated Ethernet type.
1079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - should we generate code to check for SNAP?
1080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - the header is actually variable-length.
1082478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Some various Linux patched versions gave 38
1083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * as "off_linktype" and 40 as "off_nl"; however,
1084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * if a token ring packet has *no* routing
1085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * information, i.e. is not source-routed, the correct
1086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * values are 20 and 22, as they are in the vanilla code.
1087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * A packet is source-routed iff the uppermost bit
1089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * of the first byte of the source address, at an
1090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * offset of 8, has the uppermost bit set.  If the
1091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * packet is source-routed, the total number of bytes
1092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * of routing information is 2 plus bits 0x1F00 of
1093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the 16-bit value at an offset of 14 (shifted right
1094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * 8 - figure out which byte that is).
1095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 14;
1097511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 14;		/* Token Ring MAC header length */
1098511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 8;		/* 802.2+SNAP */
1099511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 3;	/* 802.2 */
1100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_IEEE802_11:
1103511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_PRISM_HEADER:
1104511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_11_RADIO_AVS:
1105511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_11_RADIO:
1106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * 802.11 doesn't really have a link-level type field.
1108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * We set "off_linktype" to the offset of the LLC header.
1109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * To check for Ethernet types, we assume that SSAP = SNAP
1111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * is being used and pick out the encapsulated Ethernet type.
1112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - should we generate code to check for SNAP?
1113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1114511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * We also handle variable-length radio headers here.
1115511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * The Prism header is in theory variable-length, but in
1116511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * practice it's always 144 bytes long.  However, some
1117511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * drivers on Linux use ARPHRD_IEEE80211_PRISM, but
1118511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * sometimes or always supply an AVS header, so we
1119511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * have to check whether the radio header is a Prism
1120511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * header or an AVS header, so, in practice, it's
1121511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * variable-length.
1122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 24;
1124511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 0;		/* link-layer header is variable-length */
1125511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl_is_variable = 1;
1126511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 8;		/* 802.2+SNAP */
1127511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 3;	/* 802.2 */
1128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_PPI:
1131511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
1132511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * At the moment we treat PPI the same way that we treat
1133511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * normal Radiotap encoded packets. The difference is in
1134511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * the function that generates the code at the beginning
1135511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * to compute the header length.  Since this code generator
1136511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * of PPI supports bare 802.11 encapsulation only (i.e.
1137511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * the encapsulated DLT should be DLT_IEEE802_11) we
1138511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * generate code to check for this too.
1139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 24;
1141511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 0;		/* link-layer header is variable-length */
1142511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl_is_variable = 1;
1143511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 8;		/* 802.2+SNAP */
1144511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 3;	/* 802.2 */
1145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_ATM_RFC1483:
1148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_ATM_CLIP:	/* Linux ATM defines this */
1149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * assume routed, non-ISO PDUs
1151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00)
1152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - what about ISO PDUs, e.g. CLNP, ISIS, ESIS,
1154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * or PPP with the PPP NLPID (e.g., PPPoA)?  The
1155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * latter would presumably be treated the way PPPoE
1156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * should be, so you can do "pppoe and udp port 2049"
1157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * or "pppoa and tcp port 80" and have it check for
1158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * PPPo{A,E} and a PPP protocol of IP and....
1159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 0;
1161511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 0;		/* packet begins with LLC header */
1162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl = 8;		/* 802.2+SNAP */
1163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl_nosnap = 3;	/* 802.2 */
1164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_SUNATM:
1167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Full Frontal ATM; you get AALn PDUs with an ATM
1169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * pseudo-header.
1170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		is_atm = 1;
1172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_vpi = SUNATM_VPI_POS;
1173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_vci = SUNATM_VCI_POS;
1174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_proto = PROTO_POS;
1175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_mac = -1;	/* assume LLC-encapsulated, so no MAC-layer header */
1176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_payload = SUNATM_PKT_BEGIN_POS;
1177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = off_payload;
1178511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = off_payload;	/* if LLC-encapsulated */
1179511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 8;		/* 802.2+SNAP */
1180511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 3;	/* 802.2 */
1181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_RAW:
1184511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IPV4:
1185511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IPV6:
1186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = -1;
1187511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 0;
1188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl = 0;
1189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl_nosnap = 0;	/* no 802.2 LLC */
1190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_LINUX_SLL:	/* fake header for Linux cooked socket */
1193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 14;
1194511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 16;
1195511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;
1196511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 0;	/* no 802.2 LLC */
1197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_LTALK:
1200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * LocalTalk does have a 1-byte type field in the LLAP header,
1202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * but really it just indicates whether there is a "short" or
1203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * "long" DDP packet following.
1204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = -1;
1206511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 0;
1207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl = 0;
1208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl_nosnap = 0;	/* no 802.2 LLC */
1209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_IP_OVER_FC:
1212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * RFC 2625 IP-over-Fibre-Channel doesn't really have a
1214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * link-level type field.  We set "off_linktype" to the
1215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * offset of the LLC header.
1216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * To check for Ethernet types, we assume that SSAP = SNAP
1218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * is being used and pick out the encapsulated Ethernet type.
1219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - should we generate code to check for SNAP? RFC
1220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * 2625 says SNAP should be used.
1221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 16;
1223511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 16;
1224511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 8;		/* 802.2+SNAP */
1225511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 3;	/* 802.2 */
1226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_FRELAY:
1229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - we should set this to handle SNAP-encapsulated
1231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * frames (NLPID of 0x80).
1232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = -1;
1234511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 0;
1235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl = 0;
1236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl_nosnap = 0;	/* no 802.2 LLC */
1237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                /*
1240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                 * the only BPF-interesting FRF.16 frames are non-control frames;
1241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                 * Frame Relay has a variable length link-layer
1242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                 * so lets start with offset 4 for now and increments later on (FIXME);
1243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                 */
1244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_MFR:
1245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = -1;
1246511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 0;
1247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl = 4;
1248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl_nosnap = 0;	/* XXX - for now -> no 802.2 LLC */
1249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_APPLE_IP_OVER_IEEE1394:
1252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 16;
1253511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 18;
1254511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;
1255511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 0;	/* no 802.2 LLC */
1256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_SYMANTEC_FIREWALL:
1259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 6;
1260511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 44;
1261511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;		/* Ethernet II */
1262511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 0;	/* XXX - what does it do with 802.3 packets? */
1263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_NET_PFVAR_H
1266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_PFLOG:
1267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 0;
1268511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = PFLOG_HDRLEN;
1269511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;
1270511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 0;	/* no 802.2 LLC */
1271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
1273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_MFR:
1275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_MLFR:
1276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_MLPPP:
1277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_PPP:
1278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_CHDLC:
1279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_FRELAY:
1280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                off_linktype = 4;
1281511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 4;
1282511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;
1283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl_nosnap = -1;	/* no 802.2 LLC */
1284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                return;
1285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_JUNIPER_ATM1:
1287511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_linktype = 4;	/* in reality variable between 4-8 */
1288511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 4;	/* in reality variable between 4-8 */
1289511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;
1290511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 10;
1291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_JUNIPER_ATM2:
1294511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_linktype = 8;	/* in reality variable between 8-12 */
1295511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 8;	/* in reality variable between 8-12 */
1296511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;
1297511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 10;
1298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* frames captured on a Juniper PPPoE service PIC
1301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * contain raw ethernet frames */
1302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_JUNIPER_PPPOE:
1303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_ETHER:
1304511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        	off_macpl = 14;
1305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 16;
1306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl = 18;		/* Ethernet II */
1307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl_nosnap = 21;	/* 802.3+802.2 */
1308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_JUNIPER_PPPOE_ATM:
1311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 4;
1312511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 6;
1313511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;
1314511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = -1;	/* no 802.2 LLC */
1315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_JUNIPER_GGSN:
1318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 6;
1319511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 12;
1320511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;
1321511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = -1;	/* no 802.2 LLC */
1322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_JUNIPER_ES:
1325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 6;
1326511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = -1;		/* not really a network layer but raw IP addresses */
1327511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = -1;		/* not really a network layer but raw IP addresses */
1328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl_nosnap = -1;	/* no 802.2 LLC */
1329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_JUNIPER_MONITOR:
1332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 12;
1333511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 12;
1334511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;		/* raw IP/IP6 header */
1335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl_nosnap = -1;	/* no 802.2 LLC */
1336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1338511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_BACNET_MS_TP:
1339511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_linktype = -1;
1340511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = -1;
1341511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = -1;
1342511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = -1;
1343511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return;
1344511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_JUNIPER_SERVICES:
1346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 12;
1347511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = -1;		/* L3 proto location dep. on cookie type */
1348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl = -1;		/* L3 proto location dep. on cookie type */
1349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl_nosnap = -1;	/* no 802.2 LLC */
1350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_JUNIPER_VP:
1353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = 18;
1354511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = -1;
1355511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = -1;
1356511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = -1;
1357511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return;
1358511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1359511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_JUNIPER_ST:
1360511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_linktype = 18;
1361511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = -1;
1362511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = -1;
1363511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = -1;
1364511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return;
1365511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1366511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_JUNIPER_ISM:
1367511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_linktype = 8;
1368511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = -1;
1369511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = -1;
1370511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = -1;
1371511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return;
1372511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1373511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_JUNIPER_VS:
1374511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_JUNIPER_SRX_E2E:
1375511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_JUNIPER_FIBRECHANNEL:
1376511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_JUNIPER_ATM_CEMIC:
1377511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_linktype = 8;
1378511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = -1;
1379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl = -1;
1380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl_nosnap = -1;
1381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_MTP2:
1384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_li = 2;
1385511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_li_hsl = 4;
1386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_sio = 3;
1387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_opc = 4;
1388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_dpc = 4;
1389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_sls = 7;
1390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = -1;
1391511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = -1;
1392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl = -1;
1393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl_nosnap = -1;
1394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_MTP2_WITH_PHDR:
1397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_li = 6;
1398511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_li_hsl = 8;
1399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_sio = 7;
1400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_opc = 8;
1401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_dpc = 8;
1402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_sls = 11;
1403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = -1;
1404511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = -1;
1405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl = -1;
1406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl_nosnap = -1;
1407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1409511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_ERF:
1410511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_li = 22;
1411511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_li_hsl = 24;
1412511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_sio = 23;
1413511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_opc = 24;
1414511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_dpc = 24;
1415511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_sls = 27;
1416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = -1;
1417511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = -1;
1418511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = -1;
1419511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = -1;
1420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1422511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_PFSYNC:
1423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = -1;
1424511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 4;
1425511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;
1426511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 0;
1427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1429511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_AX25_KISS:
1430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Currently, only raw "link[N:M]" filtering is supported.
1432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1433511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_linktype = -1;	/* variable, min 15, max 71 steps of 7 */
1434511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = -1;
1435511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = -1;		/* variable, min 16, max 71 steps of 7 */
1436511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = -1;	/* no 802.2 LLC */
1437511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_mac = 1;		/* step over the kiss length byte */
1438511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return;
1439511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1440511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IPNET:
1441511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_linktype = 1;
1442511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 24;		/* ipnet header length */
1443511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;
1444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl_nosnap = -1;
1445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return;
1446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1447511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_NETANALYZER:
1448511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_mac = 4;		/* MAC header is past 4-byte pseudo-header */
1449511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_linktype = 16;	/* includes 4-byte pseudo-header */
1450511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 18;		/* pseudo-header+Ethernet header length */
1451511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;		/* Ethernet II */
1452511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 3;	/* 802.3+802.2 */
1453511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return;
1454511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1455511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_NETANALYZER_TRANSPARENT:
1456511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_mac = 12;		/* MAC header is past 4-byte pseudo-header, preamble, and SFD */
1457511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_linktype = 24;	/* includes 4-byte pseudo-header+preamble+SFD */
1458511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = 26;		/* pseudo-header+preamble+SFD+Ethernet header length */
1459511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;		/* Ethernet II */
1460511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 3;	/* 802.3+802.2 */
1461511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return;
1462511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1463511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	default:
1464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1465511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * For values in the range in which we've assigned new
1466511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * DLT_ values, only raw "link[N:M]" filtering is supported.
1467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1468511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (linktype >= DLT_MATCHING_MIN &&
1469511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    linktype <= DLT_MATCHING_MAX) {
1470511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			off_linktype = -1;
1471511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			off_macpl = -1;
1472511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			off_nl = -1;
1473511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			off_nl_nosnap = -1;
1474511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return;
1475511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
1476511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
1478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_error("unknown data link type %d", linktype);
1479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
1480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load a value relative to the beginning of the link-layer header.
1484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The link-layer header doesn't necessarily begin at the beginning
1485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of the packet data; there might be a variable-length prefix containing
1486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * radio information.
1487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist *
1489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_load_llrel(offset, size)
1490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int offset, size;
1491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s, *s2;
1493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s = gen_llprefixlen();
1495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
1497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * If "s" is non-null, it has code to arrange that the X register
1498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * contains the length of the prefix preceding the link-layer
1499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * header.
1500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 *
1501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Otherwise, the length of the prefix preceding the link-layer
1502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * header is "off_ll".
1503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
1504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (s != NULL) {
1505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * There's a variable-length prefix preceding the
1507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * link-layer header.  "s" points to a list of statements
1508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * that put the length of that prefix into the X register.
1509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * do an indirect load, to use the X register as an offset.
1510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_LD|BPF_IND|size);
1512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2->s.k = offset;
1513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s, s2);
1514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	} else {
1515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * There is no variable-length header preceding the
1517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * link-layer header; add in off_ll, which, if there's
1518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * a fixed-length header preceding the link-layer header,
1519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * is the length of that header.
1520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = new_stmt(BPF_LD|BPF_ABS|size);
1522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s->s.k = offset + off_ll;
1523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
1524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return s;
1525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1527511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
1528511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Load a value relative to the beginning of the MAC-layer payload.
1529511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
1530511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *
1531511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_load_macplrel(offset, size)
1532511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_int offset, size;
1533511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
1534511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct slist *s, *s2;
1535511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1536511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s = gen_off_macpl();
1537511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1538511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
1539511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * If s is non-null, the offset of the MAC-layer payload is
1540511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * variable, and s points to a list of instructions that
1541511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * arrange that the X register contains that offset.
1542511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 *
1543511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Otherwise, the offset of the MAC-layer payload is constant,
1544511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * and is in off_macpl.
1545511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
1546511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (s != NULL) {
1547511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
1548511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * The offset of the MAC-layer payload is in the X
1549511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * register.  Do an indirect load, to use the X register
1550511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * as an offset.
1551511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
1552511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2 = new_stmt(BPF_LD|BPF_IND|size);
1553511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2->s.k = offset;
1554511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s, s2);
1555511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	} else {
1556511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
1557511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * The offset of the MAC-layer payload is constant,
1558511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * and is in off_macpl; load the value at that offset
1559511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * plus the specified offset.
1560511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
1561511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s = new_stmt(BPF_LD|BPF_ABS|size);
1562511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s->s.k = off_macpl + offset;
1563511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
1564511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return s;
1565511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
1566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Load a value relative to the beginning of the specified header.
1569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist *
1571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_load_a(offrel, offset, size)
1572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	enum e_offrel offrel;
1573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int offset, size;
1574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s, *s2;
1576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (offrel) {
1578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case OR_PACKET:
1580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                s = new_stmt(BPF_LD|BPF_ABS|size);
1581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                s->s.k = offset;
1582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
1583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case OR_LINK:
1585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = gen_load_llrel(offset, size);
1586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
1587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1588511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case OR_MACPL:
1589511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s = gen_load_macplrel(offset, size);
1590511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
1591511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1592511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case OR_NET:
1593511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s = gen_load_macplrel(off_nl + offset, size);
1594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
1595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case OR_NET_NOSNAP:
1597511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s = gen_load_macplrel(off_nl_nosnap + offset, size);
1598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
1599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case OR_TRAN_IPV4:
1601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Load the X register with the length of the IPv4 header
1603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * (plus the offset of the link-layer header, if it's
1604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * preceded by a variable-length header such as a radio
1605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * header), in bytes.
1606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = gen_loadx_iphdrlen();
1608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1610511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Load the item at {offset of the MAC-layer payload} +
1611511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * {offset, relative to the start of the MAC-layer
1612511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * paylod, of the IPv4 header} + {length of the IPv4 header} +
1613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * {specified offset}.
1614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1615511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * (If the offset of the MAC-layer payload is variable,
1616511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * it's included in the value in the X register, and
1617511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * off_macpl is 0.)
1618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_LD|BPF_IND|size);
1620511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2->s.k = off_macpl + off_nl + offset;
1621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s, s2);
1622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
1623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case OR_TRAN_IPV6:
1625511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s = gen_load_macplrel(off_nl + 40 + offset, size);
1626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
1627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
1629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
1630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return NULL;
1631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
1632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return s;
1633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to load into the X register the sum of the length of
1637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the IPv4 header and any variable-length header preceding the link-layer
1638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header.
1639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist *
1641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_loadx_iphdrlen()
1642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s, *s2;
1644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1645511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s = gen_off_macpl();
1646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (s != NULL) {
1647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * There's a variable-length prefix preceding the
1649511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * link-layer header, or the link-layer header is itself
1650511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * variable-length.  "s" points to a list of statements
1651511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * that put the offset of the MAC-layer payload into
1652511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * the X register.
1653511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 *
1654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * The 4*([k]&0xf) addressing mode can't be used, as we
1655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * don't have a constant offset, so we have to load the
1656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * value in question into the A register and add to it
1657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the value from the X register.
1658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_LD|BPF_IND|BPF_B);
1660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2->s.k = off_nl;
1661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s, s2);
1662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_ALU|BPF_AND|BPF_K);
1663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2->s.k = 0xf;
1664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s, s2);
1665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_ALU|BPF_LSH|BPF_K);
1666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2->s.k = 2;
1667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s, s2);
1668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * The A register now contains the length of the
1671511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * IP header.  We need to add to it the offset of
1672511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * the MAC-layer payload, which is still in the X
1673511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * register, and move the result into the X register.
1674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
1676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s, new_stmt(BPF_MISC|BPF_TAX));
1677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	} else {
1678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * There is no variable-length header preceding the
1680511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * link-layer header, and the link-layer header is
1681511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * fixed-length; load the length of the IPv4 header,
1682511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * which is at an offset of off_nl from the beginning
1683511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * of the MAC-layer payload, and thus at an offset
1684511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * of off_mac_pl + off_nl from the beginning of the
1685511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * raw packet data.
1686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
1688511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s->s.k = off_macpl + off_nl;
1689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
1690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return s;
1691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
1694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_uncond(rsense)
1695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int rsense;
1696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b;
1698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s;
1699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s = new_stmt(BPF_LD|BPF_IMM);
1701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s->s.k = !rsense;
1702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b = new_block(JMP(BPF_JEQ));
1703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b->stmts = s;
1704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b;
1706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct block *
1709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_true()
1710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return gen_uncond(1);
1712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic inline struct block *
1715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_false()
1716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return gen_uncond(0);
1718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Byte-swap a 32-bit number.
1722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ("htonl()" or "ntohl()" won't work - we want to byte-swap even on
1723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * big-endian platforms.)
1724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define	SWAPLONG(y) \
1726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
1727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to match a particular packet type.
1730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
1731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP
1732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * value, if <= ETHERMTU.  We use that to determine whether to
1733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * match the type/length field or to check the type/length field for
1734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * a value <= ETHERMTU to see whether it's a type field and then do
1735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the appropriate test.
1736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
1738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ether_linktype(proto)
1739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register int proto;
1740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1;
1742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (proto) {
1744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case LLCSAP_ISONS:
1746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case LLCSAP_IP:
1747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case LLCSAP_NETBEUI:
1748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * OSI protocols and NetBEUI always use 802.2 encapsulation,
1750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * so we check the DSAP and SSAP.
1751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * LLCSAP_IP checks for IP-over-802.2, rather
1753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * than IP-over-Ethernet or IP-over-SNAP.
1754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - should we check both the DSAP and the
1756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * SSAP, like this, or should we check just the
1757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * DSAP, as we do for other types <= ETHERMTU
1758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * (i.e., other SAP values)?
1759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU);
1761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_not(b0);
1762511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = gen_cmp(OR_MACPL, 0, BPF_H, (bpf_int32)
1763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			     ((proto << 8) | proto));
1764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
1765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
1766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case LLCSAP_IPX:
1768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1769478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Check for;
1770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	Ethernet_II frames, which are Ethernet
1772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	frames with a frame type of ETHERTYPE_IPX;
1773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	Ethernet_802.3 frames, which are 802.3
1775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	frames (i.e., the type/length field is
1776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	a length field, <= ETHERMTU, rather than
1777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	a type field) with the first two bytes
1778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	after the Ethernet/802.3 header being
1779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	0xFFFF;
1780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	Ethernet_802.2 frames, which are 802.3
1782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	frames with an 802.2 LLC header and
1783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	with the IPX LSAP as the DSAP in the LLC
1784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	header;
1785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	Ethernet_SNAP frames, which are 802.3
1787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	frames with an LLC header and a SNAP
1788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	header and with an OUI of 0x000000
1789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	(encapsulated Ethernet) and a protocol
1790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	ID of ETHERTYPE_IPX in the SNAP header.
1791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - should we generate the same code both
1793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * for tests for LLCSAP_IPX and for ETHERTYPE_IPX?
1794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * This generates code to check both for the
1798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * IPX LSAP (Ethernet_802.2) and for Ethernet_802.3.
1799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1800511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_cmp(OR_MACPL, 0, BPF_B, (bpf_int32)LLCSAP_IPX);
1801511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = gen_cmp(OR_MACPL, 0, BPF_H, (bpf_int32)0xFFFF);
1802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
1803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1805478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now we add code to check for SNAP frames with
1806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * ETHERTYPE_IPX, i.e. Ethernet_SNAP.
1807478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1808511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_snap(0x000000, ETHERTYPE_IPX);
1809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
1810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now we generate code to check for 802.3
1813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * frames in general.
1814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU);
1816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_not(b0);
1817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1818478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now add the check for 802.3 frames before the
1820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * check for Ethernet_802.2 and Ethernet_802.3,
1821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * as those checks should only be done on 802.3
1822478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * frames, not on Ethernet frames.
1823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
1825478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now add the check for Ethernet_II frames, and
1828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * do that before checking for the other frame
1829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * types.
1830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
1832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    (bpf_int32)ETHERTYPE_IPX);
1833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
1834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
1835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case ETHERTYPE_ATALK:
1837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case ETHERTYPE_AARP:
1838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * EtherTalk (AppleTalk protocols on Ethernet link
1840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * layer) may use 802.2 encapsulation.
1841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1843478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Check for 802.2 encapsulation (EtherTalk phase 2?);
1845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * we check for an Ethernet type field less than
1846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * 1500, which means it's an 802.3 length field.
1847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU);
1849478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_not(b0);
1850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1852478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * 802.2-encapsulated ETHERTYPE_ATALK packets are
1853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * SNAP packets with an organization code of
1854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * 0x080007 (Apple, for Appletalk) and a protocol
1855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * type of ETHERTYPE_ATALK (Appletalk).
1856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * 802.2-encapsulated ETHERTYPE_AARP packets are
1858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * SNAP packets with an organization code of
1859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * 0x000000 (encapsulated Ethernet) and a protocol
1860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * type of ETHERTYPE_AARP (Appletalk ARP).
1861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (proto == ETHERTYPE_ATALK)
1863511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b1 = gen_snap(0x080007, ETHERTYPE_ATALK);
1864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else	/* proto == ETHERTYPE_AARP */
1865511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b1 = gen_snap(0x000000, ETHERTYPE_AARP);
1866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
1867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Check for Ethernet encapsulation (Ethertalk
1870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * phase 1?); we just check for the Ethernet
1871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * protocol type.
1872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);
1874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
1876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
1877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
1879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (proto <= ETHERMTU) {
1880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
1881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * This is an LLC SAP value, so the frames
1882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * that match would be 802.2 frames.
1883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Check that the frame is an 802.2 frame
1884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * (i.e., that the length/type field is
1885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * a length field, <= ETHERMTU) and
1886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * then check the DSAP.
1887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
1888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU);
1889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_not(b0);
1890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_B,
1891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    (bpf_int32)proto);
1892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_and(b0, b1);
1893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return b1;
1894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else {
1895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
1896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * This is an Ethernet type, so compare
1897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * the length/type field with it (if
1898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * the frame is an 802.2 frame, the length
1899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * field will be <= ETHERMTU, and, as
1900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * "proto" is > ETHERMTU, this test
1901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * will fail and the frame won't match,
1902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * which is what we want).
1903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
1904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_cmp(OR_LINK, off_linktype, BPF_H,
1905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    (bpf_int32)proto);
1906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
1907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
1908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1910478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1911511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * "proto" is an Ethernet type value and for IPNET, if it is not IPv4
1912511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * or IPv6 then we have an error.
1913511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
1914511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct block *
1915511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_ipnet_linktype(proto)
1916511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	register int proto;
1917511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
1918511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	switch (proto) {
1919511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1920511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case ETHERTYPE_IP:
1921511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return gen_cmp(OR_LINK, off_linktype, BPF_B,
1922511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    (bpf_int32)IPH_AF_INET);
1923511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* NOTREACHED */
1924511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1925511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case ETHERTYPE_IPV6:
1926511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return gen_cmp(OR_LINK, off_linktype, BPF_B,
1927511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    (bpf_int32)IPH_AF_INET6);
1928511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* NOTREACHED */
1929511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1930511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	default:
1931511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
1932511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
1933511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1934511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return gen_false();
1935511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
1936511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1937511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
1938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to match a particular packet type.
1939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
1940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP
1941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * value, if <= ETHERMTU.  We use that to determine whether to
1942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * match the type field or to check the type field for the special
1943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LINUX_SLL_P_802_2 value and then do the appropriate test.
1944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
1946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_linux_sll_linktype(proto)
1947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register int proto;
1948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1;
1950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (proto) {
1952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case LLCSAP_ISONS:
1954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case LLCSAP_IP:
1955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case LLCSAP_NETBEUI:
1956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * OSI protocols and NetBEUI always use 802.2 encapsulation,
1958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * so we check the DSAP and SSAP.
1959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * LLCSAP_IP checks for IP-over-802.2, rather
1961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * than IP-over-Ethernet or IP-over-SNAP.
1962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - should we check both the DSAP and the
1964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * SSAP, like this, or should we check just the
1965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * DSAP, as we do for other types <= ETHERMTU
1966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * (i.e., other SAP values)?
1967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2);
1969511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = gen_cmp(OR_MACPL, 0, BPF_H, (bpf_int32)
1970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			     ((proto << 8) | proto));
1971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
1972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
1973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case LLCSAP_IPX:
1975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	Ethernet_II frames, which are Ethernet
1977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	frames with a frame type of ETHERTYPE_IPX;
1978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	Ethernet_802.3 frames, which have a frame
1980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	type of LINUX_SLL_P_802_3;
1981478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	Ethernet_802.2 frames, which are 802.3
1983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	frames with an 802.2 LLC header (i.e, have
1984478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	a frame type of LINUX_SLL_P_802_2) and
1985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	with the IPX LSAP as the DSAP in the LLC
1986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	header;
1987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	Ethernet_SNAP frames, which are 802.3
1989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	frames with an LLC header and a SNAP
1990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	header and with an OUI of 0x000000
1991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	(encapsulated Ethernet) and a protocol
1992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	ID of ETHERTYPE_IPX in the SNAP header.
1993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
1994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * First, do the checks on LINUX_SLL_P_802_2
1995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * frames; generate the check for either
1996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Ethernet_802.2 or Ethernet_SNAP frames, and
1997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * then put a check for LINUX_SLL_P_802_2 frames
1998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * before it.
1999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2000511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_cmp(OR_MACPL, 0, BPF_B, (bpf_int32)LLCSAP_IPX);
2001511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = gen_snap(0x000000, ETHERTYPE_IPX);
2002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
2003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2);
2004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
2005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
2007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now check for 802.3 frames and OR that with
2008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the previous test.
2009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_3);
2011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
2012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
2014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now add the check for Ethernet_II frames, and
2015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * do that before checking for the other frame
2016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * types.
2017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
2019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    (bpf_int32)ETHERTYPE_IPX);
2020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
2021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
2022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case ETHERTYPE_ATALK:
2024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case ETHERTYPE_AARP:
2025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
2026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * EtherTalk (AppleTalk protocols on Ethernet link
2027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * layer) may use 802.2 encapsulation.
2028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
2031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Check for 802.2 encapsulation (EtherTalk phase 2?);
2032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * we check for the 802.2 protocol type in the
2033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * "Ethernet type" field.
2034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2);
2036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
2038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * 802.2-encapsulated ETHERTYPE_ATALK packets are
2039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * SNAP packets with an organization code of
2040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * 0x080007 (Apple, for Appletalk) and a protocol
2041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * type of ETHERTYPE_ATALK (Appletalk).
2042478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
2043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * 802.2-encapsulated ETHERTYPE_AARP packets are
2044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * SNAP packets with an organization code of
2045478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * 0x000000 (encapsulated Ethernet) and a protocol
2046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * type of ETHERTYPE_AARP (Appletalk ARP).
2047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (proto == ETHERTYPE_ATALK)
2049511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b1 = gen_snap(0x080007, ETHERTYPE_ATALK);
2050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else	/* proto == ETHERTYPE_AARP */
2051511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b1 = gen_snap(0x000000, ETHERTYPE_AARP);
2052478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
2053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
2055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Check for Ethernet encapsulation (Ethertalk
2056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * phase 1?); we just check for the Ethernet
2057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * protocol type.
2058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);
2060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
2062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
2063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
2065478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (proto <= ETHERMTU) {
2066478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
2067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * This is an LLC SAP value, so the frames
2068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * that match would be 802.2 frames.
2069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Check for the 802.2 protocol type
2070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * in the "Ethernet type" field, and
2071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * then check the DSAP.
2072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
2073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
2074478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    LINUX_SLL_P_802_2);
2075511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b1 = gen_cmp(OR_LINK, off_macpl, BPF_B,
2076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			     (bpf_int32)proto);
2077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_and(b0, b1);
2078478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return b1;
2079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else {
2080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
2081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * This is an Ethernet type, so compare
2082478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * the length/type field with it (if
2083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * the frame is an 802.2 frame, the length
2084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * field will be <= ETHERMTU, and, as
2085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * "proto" is > ETHERMTU, this test
2086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * will fail and the frame won't match,
2087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * which is what we want).
2088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
2089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_cmp(OR_LINK, off_linktype, BPF_H,
2090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    (bpf_int32)proto);
2091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
2092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
2093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
2094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2095511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *
2096511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_load_prism_llprefixlen()
2097511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
2098511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct slist *s1, *s2;
2099511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct slist *sjeq_avs_cookie;
2100511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct slist *sjcommon;
2101511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2102511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
2103511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * This code is not compatible with the optimizer, as
2104511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * we are generating jmp instructions within a normal
2105511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * slist of instructions
2106511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
2107511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	no_optimize = 1;
2108511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2109511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
2110511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Generate code to load the length of the radio header into
2111511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * the register assigned to hold that length, if one has been
2112511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * assigned.  (If one hasn't been assigned, no code we've
2113511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * generated uses that prefix, so we don't need to generate any
2114511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * code to load it.)
2115511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 *
2116511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Some Linux drivers use ARPHRD_IEEE80211_PRISM but sometimes
2117511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * or always use the AVS header rather than the Prism header.
2118511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * We load a 4-byte big-endian value at the beginning of the
2119511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * raw packet data, and see whether, when masked with 0xFFFFF000,
2120511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * it's equal to 0x80211000.  If so, that indicates that it's
2121511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * an AVS header (the masked-out bits are the version number).
2122511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Otherwise, it's a Prism header.
2123511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 *
2124511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * XXX - the Prism header is also, in theory, variable-length,
2125511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * but no known software generates headers that aren't 144
2126511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * bytes long.
2127511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
2128511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (reg_off_ll != -1) {
2129511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2130511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Load the cookie.
2131511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2132511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s1 = new_stmt(BPF_LD|BPF_W|BPF_ABS);
2133511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s1->s.k = 0;
2134511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2135511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2136511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * AND it with 0xFFFFF000.
2137511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2138511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2 = new_stmt(BPF_ALU|BPF_AND|BPF_K);
2139511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2->s.k = 0xFFFFF000;
2140511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s1, s2);
2141511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2142511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2143511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Compare with 0x80211000.
2144511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2145511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjeq_avs_cookie = new_stmt(JMP(BPF_JEQ));
2146511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjeq_avs_cookie->s.k = 0x80211000;
2147511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s1, sjeq_avs_cookie);
2148511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2149511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2150511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * If it's AVS:
2151511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 *
2152511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * The 4 bytes at an offset of 4 from the beginning of
2153511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * the AVS header are the length of the AVS header.
2154511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * That field is big-endian.
2155511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2156511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2 = new_stmt(BPF_LD|BPF_W|BPF_ABS);
2157511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2->s.k = 4;
2158511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s1, s2);
2159511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjeq_avs_cookie->s.jt = s2;
2160511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2161511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2162511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Now jump to the code to allocate a register
2163511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * into which to save the header length and
2164511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * store the length there.  (The "jump always"
2165511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * instruction needs to have the k field set;
2166511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * it's added to the PC, so, as we're jumping
2167511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * over a single instruction, it should be 1.)
2168511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2169511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjcommon = new_stmt(JMP(BPF_JA));
2170511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjcommon->s.k = 1;
2171511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s1, sjcommon);
2172511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2173511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2174511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Now for the code that handles the Prism header.
2175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Just load the length of the Prism header (144)
2176511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * into the A register.  Have the test for an AVS
2177511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * header branch here if we don't have an AVS header.
2178511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2179511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2 = new_stmt(BPF_LD|BPF_W|BPF_IMM);
2180511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2->s.k = 144;
2181511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s1, s2);
2182511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjeq_avs_cookie->s.jf = s2;
2183511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2184511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2185511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Now allocate a register to hold that value and store
2186511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * it.  The code for the AVS header will jump here after
2187511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * loading the length of the AVS header.
2188511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2189511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2 = new_stmt(BPF_ST);
2190511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2->s.k = reg_off_ll;
2191511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s1, s2);
2192511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjcommon->s.jf = s2;
2193511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2194511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2195511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Now move it into the X register.
2196511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2197511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2 = new_stmt(BPF_MISC|BPF_TAX);
2198511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s1, s2);
2199511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2200511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (s1);
2201511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	} else
2202511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (NULL);
2203511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
2204511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2205511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *
2206511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_load_avs_llprefixlen()
2207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
2208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s1, *s2;
2209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
2211511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Generate code to load the length of the AVS header into
2212511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * the register assigned to hold that length, if one has been
2213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * assigned.  (If one hasn't been assigned, no code we've
2214511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * generated uses that prefix, so we don't need to generate any
2215511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * code to load it.)
2216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
2217511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (reg_off_ll != -1) {
2218511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2219511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * The 4 bytes at an offset of 4 from the beginning of
2220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * the AVS header are the length of the AVS header.
2221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * That field is big-endian.
2222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2223511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s1 = new_stmt(BPF_LD|BPF_W|BPF_ABS);
2224511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s1->s.k = 4;
2225511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2226511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2227511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Now allocate a register to hold that value and store
2228511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * it.
2229511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2230511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2 = new_stmt(BPF_ST);
2231511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2->s.k = reg_off_ll;
2232511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s1, s2);
2233511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2234511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2235511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Now move it into the X register.
2236511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2237511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2 = new_stmt(BPF_MISC|BPF_TAX);
2238511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s1, s2);
2239511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2240511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (s1);
2241511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	} else
2242511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (NULL);
2243511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
2244511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2245511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *
2246511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_load_radiotap_llprefixlen()
2247511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
2248511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct slist *s1, *s2;
2249511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2250511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
2251511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Generate code to load the length of the radiotap header into
2252511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * the register assigned to hold that length, if one has been
2253511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * assigned.  (If one hasn't been assigned, no code we've
2254511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * generated uses that prefix, so we don't need to generate any
2255511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * code to load it.)
2256511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
2257511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (reg_off_ll != -1) {
2258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
2259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * The 2 bytes at offsets of 2 and 3 from the beginning
2260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * of the radiotap header are the length of the radiotap
2261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * header; unfortunately, it's little-endian, so we have
2262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * to load it a byte at a time and construct the value.
2263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
2266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Load the high-order byte, at an offset of 3, shift it
2267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * left a byte, and put the result in the X register.
2268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s1 = new_stmt(BPF_LD|BPF_B|BPF_ABS);
2270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s1->s.k = 3;
2271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_ALU|BPF_LSH|BPF_K);
2272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s1, s2);
2273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2->s.k = 8;
2274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_MISC|BPF_TAX);
2275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s1, s2);
2276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
2278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Load the next byte, at an offset of 2, and OR the
2279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * value from the X register into it.
2280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_LD|BPF_B|BPF_ABS);
2282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s1, s2);
2283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2->s.k = 2;
2284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_ALU|BPF_OR|BPF_X);
2285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s1, s2);
2286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
2288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now allocate a register to hold that value and store
2289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * it.
2290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_ST);
2292511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2->s.k = reg_off_ll;
2293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s1, s2);
2294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
2296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now move it into the X register.
2297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_MISC|BPF_TAX);
2299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s1, s2);
2300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2301511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (s1);
2302511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	} else
2303511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (NULL);
2304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
2305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
2307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * At the moment we treat PPI as normal Radiotap encoded
2308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * packets. The difference is in the function that generates
2309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the code at the beginning to compute the header length.
2310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Since this code generator of PPI supports bare 802.11
2311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * encapsulation only (i.e. the encapsulated DLT should be
2312511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * DLT_IEEE802_11) we generate code to check for this too;
2313511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * that's done in finish_parse().
2314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
2315511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *
2316511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_load_ppi_llprefixlen()
2317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
2318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s1, *s2;
2319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
2321511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Generate code to load the length of the radiotap header
2322511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * into the register assigned to hold that length, if one has
2323511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * been assigned.
2324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
2325511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (reg_off_ll != -1) {
2326511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * The 2 bytes at offsets of 2 and 3 from the beginning
2328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * of the radiotap header are the length of the radiotap
2329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * header; unfortunately, it's little-endian, so we have
2330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * to load it a byte at a time and construct the value.
2331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
2334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Load the high-order byte, at an offset of 3, shift it
2335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * left a byte, and put the result in the X register.
2336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s1 = new_stmt(BPF_LD|BPF_B|BPF_ABS);
2338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s1->s.k = 3;
2339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_ALU|BPF_LSH|BPF_K);
2340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s1, s2);
2341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2->s.k = 8;
2342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_MISC|BPF_TAX);
2343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s1, s2);
2344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
2346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Load the next byte, at an offset of 2, and OR the
2347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * value from the X register into it.
2348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_LD|BPF_B|BPF_ABS);
2350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s1, s2);
2351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2->s.k = 2;
2352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_ALU|BPF_OR|BPF_X);
2353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s1, s2);
2354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
2356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now allocate a register to hold that value and store
2357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * it.
2358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_ST);
2360511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2->s.k = reg_off_ll;
2361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s1, s2);
2362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
2364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now move it into the X register.
2365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_MISC|BPF_TAX);
2367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s1, s2);
2368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2369511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (s1);
2370511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	} else
2371511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (NULL);
2372511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
2373511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2374511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
2375511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Load a value relative to the beginning of the link-layer header after the 802.11
2376511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * header, i.e. LLC_SNAP.
2377511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * The link-layer header doesn't necessarily begin at the beginning
2378511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * of the packet data; there might be a variable-length prefix containing
2379511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * radio information.
2380511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
2381511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *
2382511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_load_802_11_header_len(struct slist *s, struct slist *snext)
2383511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
2384511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct slist *s2;
2385511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct slist *sjset_data_frame_1;
2386511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct slist *sjset_data_frame_2;
2387511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct slist *sjset_qos;
2388511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct slist *sjset_radiotap_flags;
2389511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct slist *sjset_radiotap_tsft;
2390511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct slist *sjset_tsft_datapad, *sjset_notsft_datapad;
2391511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct slist *s_roundup;
2392511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2393511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (reg_off_macpl == -1) {
2394511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2395511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * No register has been assigned to the offset of
2396511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * the MAC-layer payload, which means nobody needs
2397511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * it; don't bother computing it - just return
2398511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * what we already have.
2399511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2400511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (s);
2401511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
2402511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2403511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
2404511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * This code is not compatible with the optimizer, as
2405511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * we are generating jmp instructions within a normal
2406511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * slist of instructions
2407511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
2408511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	no_optimize = 1;
2409511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2410511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
2411511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * If "s" is non-null, it has code to arrange that the X register
2412511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * contains the length of the prefix preceding the link-layer
2413511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * header.
2414511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 *
2415511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Otherwise, the length of the prefix preceding the link-layer
2416511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * header is "off_ll".
2417511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
2418511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (s == NULL) {
2419511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2420511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * There is no variable-length header preceding the
2421511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * link-layer header.
2422511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 *
2423511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Load the length of the fixed-length prefix preceding
2424511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * the link-layer header (if any) into the X register,
2425511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * and store it in the reg_off_macpl register.
2426511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * That length is off_ll.
2427511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2428511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s = new_stmt(BPF_LDX|BPF_IMM);
2429511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s->s.k = off_ll;
2430511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
2431511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2432511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
2433511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * The X register contains the offset of the beginning of the
2434511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * link-layer header; add 24, which is the minimum length
2435511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * of the MAC header for a data frame, to that, and store it
2436511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * in reg_off_macpl, and then load the Frame Control field,
2437511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * which is at the offset in the X register, with an indexed load.
2438511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
2439511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s2 = new_stmt(BPF_MISC|BPF_TXA);
2440511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sappend(s, s2);
2441511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s2 = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
2442511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s2->s.k = 24;
2443511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sappend(s, s2);
2444511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s2 = new_stmt(BPF_ST);
2445511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s2->s.k = reg_off_macpl;
2446511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sappend(s, s2);
2447511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2448511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s2 = new_stmt(BPF_LD|BPF_IND|BPF_B);
2449511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s2->s.k = 0;
2450511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sappend(s, s2);
2451511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2452511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
2453511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Check the Frame Control field to see if this is a data frame;
2454511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * a data frame has the 0x08 bit (b3) in that field set and the
2455511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * 0x04 bit (b2) clear.
2456511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
2457511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sjset_data_frame_1 = new_stmt(JMP(BPF_JSET));
2458511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sjset_data_frame_1->s.k = 0x08;
2459511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sappend(s, sjset_data_frame_1);
2460511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2461511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
2462511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * If b3 is set, test b2, otherwise go to the first statement of
2463511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * the rest of the program.
2464511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
2465511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sjset_data_frame_1->s.jt = sjset_data_frame_2 = new_stmt(JMP(BPF_JSET));
2466511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sjset_data_frame_2->s.k = 0x04;
2467511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sappend(s, sjset_data_frame_2);
2468511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sjset_data_frame_1->s.jf = snext;
2469511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2470511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
2471511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * If b2 is not set, this is a data frame; test the QoS bit.
2472511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Otherwise, go to the first statement of the rest of the
2473511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * program.
2474511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
2475511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sjset_data_frame_2->s.jt = snext;
2476511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sjset_data_frame_2->s.jf = sjset_qos = new_stmt(JMP(BPF_JSET));
2477511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sjset_qos->s.k = 0x80;	/* QoS bit */
2478511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sappend(s, sjset_qos);
2479511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2480511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
2481511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * If it's set, add 2 to reg_off_macpl, to skip the QoS
2482511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * field.
2483511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Otherwise, go to the first statement of the rest of the
2484511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * program.
2485511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
2486511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sjset_qos->s.jt = s2 = new_stmt(BPF_LD|BPF_MEM);
2487511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s2->s.k = reg_off_macpl;
2488511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sappend(s, s2);
2489511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s2 = new_stmt(BPF_ALU|BPF_ADD|BPF_IMM);
2490511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s2->s.k = 2;
2491511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sappend(s, s2);
2492511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s2 = new_stmt(BPF_ST);
2493511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s2->s.k = reg_off_macpl;
2494511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sappend(s, s2);
2495511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2496511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
2497511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * If we have a radiotap header, look at it to see whether
2498511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * there's Atheros padding between the MAC-layer header
2499511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * and the payload.
2500511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 *
2501511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Note: all of the fields in the radiotap header are
2502511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * little-endian, so we byte-swap all of the values
2503511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * we test against, as they will be loaded as big-endian
2504511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * values.
2505511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
2506511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (linktype == DLT_IEEE802_11_RADIO) {
2507511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2508511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Is the IEEE80211_RADIOTAP_FLAGS bit (0x0000002) set
2509511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * in the presence flag?
2510511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2511511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjset_qos->s.jf = s2 = new_stmt(BPF_LD|BPF_ABS|BPF_W);
2512511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2->s.k = 4;
2513511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s, s2);
2514511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2515511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjset_radiotap_flags = new_stmt(JMP(BPF_JSET));
2516511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjset_radiotap_flags->s.k = SWAPLONG(0x00000002);
2517511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s, sjset_radiotap_flags);
2518511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2519511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2520511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * If not, skip all of this.
2521511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2522511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjset_radiotap_flags->s.jf = snext;
2523511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2524511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2525511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Otherwise, is the IEEE80211_RADIOTAP_TSFT bit set?
2526511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2527511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjset_radiotap_tsft = sjset_radiotap_flags->s.jt =
2528511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    new_stmt(JMP(BPF_JSET));
2529511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjset_radiotap_tsft->s.k = SWAPLONG(0x00000001);
2530511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s, sjset_radiotap_tsft);
2531511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2532511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2533511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * If IEEE80211_RADIOTAP_TSFT is set, the flags field is
2534511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * at an offset of 16 from the beginning of the raw packet
2535511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * data (8 bytes for the radiotap header and 8 bytes for
2536511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * the TSFT field).
2537511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 *
2538511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Test whether the IEEE80211_RADIOTAP_F_DATAPAD bit (0x20)
2539511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * is set.
2540511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2541511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjset_radiotap_tsft->s.jt = s2 = new_stmt(BPF_LD|BPF_ABS|BPF_B);
2542511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2->s.k = 16;
2543511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s, s2);
2544511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2545511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjset_tsft_datapad = new_stmt(JMP(BPF_JSET));
2546511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjset_tsft_datapad->s.k = 0x20;
2547511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s, sjset_tsft_datapad);
2548511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2549511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2550511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * If IEEE80211_RADIOTAP_TSFT is not set, the flags field is
2551511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * at an offset of 8 from the beginning of the raw packet
2552511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * data (8 bytes for the radiotap header).
2553511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 *
2554511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Test whether the IEEE80211_RADIOTAP_F_DATAPAD bit (0x20)
2555511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * is set.
2556511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2557511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjset_radiotap_tsft->s.jf = s2 = new_stmt(BPF_LD|BPF_ABS|BPF_B);
2558511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2->s.k = 8;
2559511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s, s2);
2560511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2561511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjset_notsft_datapad = new_stmt(JMP(BPF_JSET));
2562511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjset_notsft_datapad->s.k = 0x20;
2563511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s, sjset_notsft_datapad);
2564511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
2566511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * In either case, if IEEE80211_RADIOTAP_F_DATAPAD is
2567511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * set, round the length of the 802.11 header to
2568511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * a multiple of 4.  Do that by adding 3 and then
2569511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * dividing by and multiplying by 4, which we do by
2570511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * ANDing with ~3.
2571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2572511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s_roundup = new_stmt(BPF_LD|BPF_MEM);
2573511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s_roundup->s.k = reg_off_macpl;
2574511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s, s_roundup);
2575511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2 = new_stmt(BPF_ALU|BPF_ADD|BPF_IMM);
2576511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2->s.k = 3;
2577511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s, s2);
2578511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2 = new_stmt(BPF_ALU|BPF_AND|BPF_IMM);
2579511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2->s.k = ~3;
2580511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s, s2);
2581511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2 = new_stmt(BPF_ST);
2582511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s2->s.k = reg_off_macpl;
2583511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s, s2);
2584511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2585511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjset_tsft_datapad->s.jt = s_roundup;
2586511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjset_tsft_datapad->s.jf = snext;
2587511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjset_notsft_datapad->s.jt = s_roundup;
2588511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjset_notsft_datapad->s.jf = snext;
2589511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	} else
2590511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sjset_qos->s.jf = snext;
2591511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2592511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return s;
2593511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
2594511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2595511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void
2596511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallinsert_compute_vloffsets(b)
2597511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct block *b;
2598511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
2599511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct slist *s;
2600511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2601511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
2602511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * For link-layer types that have a variable-length header
2603511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * preceding the link-layer header, generate code to load
2604511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * the offset of the link-layer header into the register
2605511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * assigned to that offset, if any.
2606511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
2607511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	switch (linktype) {
2608511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2609511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_PRISM_HEADER:
2610511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s = gen_load_prism_llprefixlen();
2611511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
2612511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2613511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_11_RADIO_AVS:
2614511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s = gen_load_avs_llprefixlen();
2615511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
2616511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2617511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_11_RADIO:
2618511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s = gen_load_radiotap_llprefixlen();
2619511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
2620511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2621511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_PPI:
2622511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s = gen_load_ppi_llprefixlen();
2623511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
2624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2625511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	default:
2626511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s = NULL;
2627511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
2628511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
2629511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2630511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
2631511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * For link-layer types that have a variable-length link-layer
2632511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * header, generate code to load the offset of the MAC-layer
2633511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * payload into the register assigned to that offset, if any.
2634511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
2635511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	switch (linktype) {
2636511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2637511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_11:
2638511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_PRISM_HEADER:
2639511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_11_RADIO_AVS:
2640511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_11_RADIO:
2641511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_PPI:
2642511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s = gen_load_802_11_header_len(s, b->stmts);
2643511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
2644511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
2645511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2646511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
2647511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * If we have any offset-loading code, append all the
2648511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * existing statements in the block to those statements,
2649511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * and make the resulting list the list of statements
2650511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * for the block.
2651511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
2652511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (s != NULL) {
2653511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		sappend(s, b->stmts);
2654511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b->stmts = s;
2655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
2656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
2657511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
2659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ppi_dlt_check(void)
2660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
2661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s_load_dlt;
2662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b;
2663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (linktype == DLT_PPI)
2665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
2666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Create the statements that check for the DLT
2667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s_load_dlt = new_stmt(BPF_LD|BPF_W|BPF_ABS);
2669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s_load_dlt->s.k = 4;
2670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b = new_block(JMP(BPF_JEQ));
2672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b->stmts = s_load_dlt;
2674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b->s.k = SWAPLONG(DLT_IEEE802_11);
2675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
2676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else
2677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
2678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b = NULL;
2679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
2680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b;
2682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
2683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2684511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *
2685511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_prism_llprefixlen(void)
2686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
2687511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct slist *s;
2688511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2689511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (reg_off_ll == -1) {
2690511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2691511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * We haven't yet assigned a register for the length
2692511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * of the radio header; allocate one.
2693511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2694511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		reg_off_ll = alloc_reg();
2695511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
2696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2697511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
2698511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Load the register containing the radio length
2699511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * into the X register.
2700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
2701511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s = new_stmt(BPF_LDX|BPF_MEM);
2702511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s->s.k = reg_off_ll;
2703511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return s;
2704511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
2705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2706511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *
2707511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_avs_llprefixlen(void)
2708511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
2709511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct slist *s;
2710511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2711511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (reg_off_ll == -1) {
2712511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2713511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * We haven't yet assigned a register for the length
2714511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * of the AVS header; allocate one.
2715511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2716511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		reg_off_ll = alloc_reg();
2717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
2718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2719511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
2720511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Load the register containing the AVS length
2721511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * into the X register.
2722511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
2723511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s = new_stmt(BPF_LDX|BPF_MEM);
2724511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s->s.k = reg_off_ll;
2725511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return s;
2726511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
2727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist *
2729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_radiotap_llprefixlen(void)
2730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
2731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s;
2732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2733511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (reg_off_ll == -1) {
2734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
2735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * We haven't yet assigned a register for the length
2736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * of the radiotap header; allocate one.
2737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2738511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		reg_off_ll = alloc_reg();
2739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
2740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
2742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Load the register containing the radiotap length
2743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * into the X register.
2744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
2745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s = new_stmt(BPF_LDX|BPF_MEM);
2746511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s->s.k = reg_off_ll;
2747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return s;
2748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
2749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
2751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * At the moment we treat PPI as normal Radiotap encoded
2752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * packets. The difference is in the function that generates
2753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the code at the beginning to compute the header length.
2754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Since this code generator of PPI supports bare 802.11
2755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * encapsulation only (i.e. the encapsulated DLT should be
2756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DLT_IEEE802_11) we generate code to check for this too.
2757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
2758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist *
2759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ppi_llprefixlen(void)
2760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
2761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s;
2762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2763511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (reg_off_ll == -1) {
2764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
2765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * We haven't yet assigned a register for the length
2766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * of the radiotap header; allocate one.
2767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
2768511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		reg_off_ll = alloc_reg();
2769478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
2770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
2772511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Load the register containing the PPI length
2773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * into the X register.
2774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
2775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s = new_stmt(BPF_LDX|BPF_MEM);
2776511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s->s.k = reg_off_ll;
2777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return s;
2778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
2779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
2781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to compute the link-layer header length, if necessary,
2782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * putting it into the X register, and to return either a pointer to a
2783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "struct slist" for the list of statements in that code, or NULL if
2784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * no code is necessary.
2785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
2786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist *
2787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_llprefixlen(void)
2788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
2789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (linktype) {
2790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2791511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_PRISM_HEADER:
2792511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return gen_prism_llprefixlen();
2793511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2794511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_11_RADIO_AVS:
2795511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return gen_avs_llprefixlen();
2796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_IEEE802_11_RADIO:
2798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_radiotap_llprefixlen();
2799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2800511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_PPI:
2801511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return gen_ppi_llprefixlen();
2802511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
2804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return NULL;
2805478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
2806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
2807478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
2809511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Generate code to load the register containing the offset of the
2810511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * MAC-layer payload into the X register; if no register for that offset
2811511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * has been allocated, allocate it first.
2812511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
2813511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct slist *
2814511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_off_macpl(void)
2815511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
2816511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct slist *s;
2817511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2818511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (off_macpl_is_variable) {
2819511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (reg_off_macpl == -1) {
2820511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
2821511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * We haven't yet assigned a register for the offset
2822511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * of the MAC-layer payload; allocate one.
2823511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
2824511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			reg_off_macpl = alloc_reg();
2825511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
2826511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2827511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2828511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Load the register containing the offset of the MAC-layer
2829511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * payload into the X register.
2830511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2831511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s = new_stmt(BPF_LDX|BPF_MEM);
2832511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s->s.k = reg_off_macpl;
2833511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return s;
2834511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	} else {
2835511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2836511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * That offset isn't variable, so we don't need to
2837511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * generate any code.
2838511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2839511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return NULL;
2840511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
2841511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
2842511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2843511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
2844511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Map an Ethernet type to the equivalent PPP type.
2845511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
2846511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
2847511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallethertype_to_ppptype(proto)
2848511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int proto;
2849511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
2850511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	switch (proto) {
2851511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2852511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case ETHERTYPE_IP:
2853511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		proto = PPP_IP;
2854511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
2855511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2856511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case ETHERTYPE_IPV6:
2857511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		proto = PPP_IPV6;
2858511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
2859511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2860511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case ETHERTYPE_DN:
2861511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		proto = PPP_DECNET;
2862511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
2863511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2864511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case ETHERTYPE_ATALK:
2865511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		proto = PPP_APPLE;
2866511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
2867511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2868511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case ETHERTYPE_NS:
2869511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		proto = PPP_NS;
2870511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
2871511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2872511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case LLCSAP_ISONS:
2873511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		proto = PPP_OSI;
2874511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
2875511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2876511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case LLCSAP_8021D:
2877511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2878511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * I'm assuming the "Bridging PDU"s that go
2879511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * over PPP are Spanning Tree Protocol
2880511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Bridging PDUs.
2881511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2882511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		proto = PPP_BRPDU;
2883511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
2884511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2885511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case LLCSAP_IPX:
2886511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		proto = PPP_IPX;
2887511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
2888511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
2889511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return (proto);
2890511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
2891511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2892511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
2893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to match a particular packet type by matching the
2894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * link-layer type field or fields in the 802.2 LLC header.
2895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
2896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP
2897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * value, if <= ETHERMTU.
2898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
2899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
2900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_linktype(proto)
2901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register int proto;
2902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
2903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1, *b2;
2904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* are we checking MPLS-encapsulated packets? */
2906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (label_stack_depth > 0) {
2907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		switch (proto) {
2908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case ETHERTYPE_IP:
2909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case PPP_IP:
2910511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* FIXME add other L3 proto IDs */
2911478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_mpls_linktype(Q_IP);
2912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case ETHERTYPE_IPV6:
2914478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case PPP_IPV6:
2915511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* FIXME add other L3 proto IDs */
2916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_mpls_linktype(Q_IPV6);
2917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		default:
2919478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("unsupported protocol over mpls");
2920478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* NOTREACHED */
2921478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
2922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
2923478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2924511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
2925511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Are we testing PPPoE packets?
2926511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
2927511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (is_pppoes) {
2928511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2929511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * The PPPoE session header is part of the
2930511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * MAC-layer payload, so all references
2931511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * should be relative to the beginning of
2932511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * that payload.
2933511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2934511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2935511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2936511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * We use Ethernet protocol types inside libpcap;
2937511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * map them to the corresponding PPP protocol types.
2938511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2939511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		proto = ethertype_to_ppptype(proto);
2940511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return gen_cmp(OR_MACPL, off_linktype, BPF_H, (bpf_int32)proto);
2941511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
2942511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (linktype) {
2944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_EN10MB:
2946511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_NETANALYZER:
2947511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_NETANALYZER_TRANSPARENT:
2948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_ether_linktype(proto);
2949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*NOTREACHED*/
2950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
2951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_C_HDLC:
2953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		switch (proto) {
2954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case LLCSAP_ISONS:
2956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			proto = (proto << 8 | LLCSAP_ISONS);
2957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* fall through */
2958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		default:
2960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_cmp(OR_LINK, off_linktype, BPF_H,
2961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    (bpf_int32)proto);
2962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*NOTREACHED*/
2963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
2964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
2965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
2966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
2967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_IEEE802_11:
2968511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_PRISM_HEADER:
2969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_IEEE802_11_RADIO_AVS:
2970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_IEEE802_11_RADIO:
2971511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_PPI:
2972511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2973511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Check that we have a data frame.
2974511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2975511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_check_802_11_data_frame();
2976511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2977511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2978511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Now check for the specified link-layer type.
2979511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2980511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = gen_llc_linktype(proto);
2981511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_and(b0, b1);
2982511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return b1;
2983511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*NOTREACHED*/
2984511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
2985511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2986511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_FDDI:
2987511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2988511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * XXX - check for asynchronous frames, as per RFC 1103.
2989511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2990511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return gen_llc_linktype(proto);
2991511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*NOTREACHED*/
2992511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
2993511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
2994511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802:
2995511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
2996511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * XXX - check for LLC PDUs, as per IEEE 802.5.
2997511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
2998511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return gen_llc_linktype(proto);
2999511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*NOTREACHED*/
3000511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3001511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_ATM_RFC1483:
3003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_ATM_CLIP:
3004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_IP_OVER_FC:
3005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_llc_linktype(proto);
3006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*NOTREACHED*/
3007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
3008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_SUNATM:
3010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If "is_lane" is set, check for a LANE-encapsulated
3012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * version of this protocol, otherwise check for an
3013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * LLC-encapsulated version of this protocol.
3014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
3015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * We assume LANE means Ethernet, not Token Ring.
3016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (is_lane) {
3018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
3019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Check that the packet doesn't begin with an
3020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * LE Control marker.  (We've already generated
3021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * a test for LANE.)
3022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
3023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b0 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H,
3024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    0xFF00);
3025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_not(b0);
3026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
3028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Now generate an Ethernet test.
3029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
3030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b1 = gen_ether_linktype(proto);
3031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_and(b0, b1);
3032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return b1;
3033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else {
3034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
3035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Check for LLC encapsulation and then check the
3036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * protocol.
3037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
3038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b0 = gen_atmfield_code(A_PROTOTYPE, PT_LLC, BPF_JEQ, 0);
3039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b1 = gen_llc_linktype(proto);
3040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_and(b0, b1);
3041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return b1;
3042478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
3043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*NOTREACHED*/
3044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
3045478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_LINUX_SLL:
3047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_linux_sll_linktype(proto);
3048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*NOTREACHED*/
3049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
3050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_SLIP:
3052478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_SLIP_BSDOS:
3053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_RAW:
3054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * These types don't provide any type field; packets
3056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * are always IPv4 or IPv6.
3057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
3058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - for IPv4, check for a version number of 4, and,
3059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * for IPv6, check for a version number of 6?
3060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		switch (proto) {
3062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case ETHERTYPE_IP:
3064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* Check for a version number of 4. */
3065478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_mcmp(OR_LINK, 0, BPF_B, 0x40, 0xF0);
3066511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case ETHERTYPE_IPV6:
3068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* Check for a version number of 6. */
3069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_mcmp(OR_LINK, 0, BPF_B, 0x60, 0xF0);
3070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		default:
3072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_false();		/* always false */
3073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
3074478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*NOTREACHED*/
3075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
3076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3077511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IPV4:
3078511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
3079511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Raw IPv4, so no type field.
3080511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
3081511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (proto == ETHERTYPE_IP)
3082511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_true();		/* always true */
3083511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3084511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* Checking for something other than IPv4; always false */
3085511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return gen_false();
3086511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*NOTREACHED*/
3087511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3088511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3089511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IPV6:
3090511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
3091511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Raw IPv6, so no type field.
3092511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
3093511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (proto == ETHERTYPE_IPV6)
3094511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_true();		/* always true */
3095511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3096511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* Checking for something other than IPv6; always false */
3097511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return gen_false();
3098511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*NOTREACHED*/
3099511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3100511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_PPP:
3102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_PPP_PPPD:
3103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_PPP_SERIAL:
3104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_PPP_ETHER:
3105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * We use Ethernet protocol types inside libpcap;
3107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * map them to the corresponding PPP protocol types.
3108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3109511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		proto = ethertype_to_ppptype(proto);
3110511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);
3111511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*NOTREACHED*/
3112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
3113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_PPP_BSDOS:
3115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * We use Ethernet protocol types inside libpcap;
3117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * map them to the corresponding PPP protocol types.
3118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		switch (proto) {
3120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case ETHERTYPE_IP:
3122511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
3123511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Also check for Van Jacobson-compressed IP.
3124511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * XXX - do this for other forms of PPP?
3125511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
3126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_IP);
3127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b1 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_VJC);
3128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_or(b0, b1);
3129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_VJNC);
3130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_or(b1, b0);
3131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return b0;
3132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3133511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		default:
3134511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			proto = ethertype_to_ppptype(proto);
3135511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_cmp(OR_LINK, off_linktype, BPF_H,
3136511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				(bpf_int32)proto);
3137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
3138511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*NOTREACHED*/
3139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
3140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_NULL:
3142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_LOOP:
3143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_ENC:
3144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * For DLT_NULL, the link-layer header is a 32-bit
3146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * word containing an AF_ value in *host* byte order,
3147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * and for DLT_ENC, the link-layer header begins
3148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * with a 32-bit work containing an AF_ value in
3149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * host byte order.
3150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
3151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * In addition, if we're reading a saved capture file,
3152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the host byte order in the capture may not be the
3153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * same as the host byte order on this machine.
3154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
3155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * For DLT_LOOP, the link-layer header is a 32-bit
3156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * word containing an AF_ value in *network* byte order.
3157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
3158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - AF_ values may, unfortunately, be platform-
3159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * dependent; for example, FreeBSD's AF_INET6 is 24
3160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * whilst NetBSD's and OpenBSD's is 26.
3161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
3162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * This means that, when reading a capture file, just
3163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * checking for our AF_INET6 value won't work if the
3164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * capture file came from another OS.
3165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		switch (proto) {
3167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case ETHERTYPE_IP:
3169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			proto = AF_INET;
3170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
3171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6
3173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case ETHERTYPE_IPV6:
3174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			proto = AF_INET6;
3175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
3176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
3177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		default:
3179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
3180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Not a type on which we support filtering.
3181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * XXX - support those that have AF_ values
3182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * #defined on this platform, at least?
3183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
3184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_false();
3185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
3186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (linktype == DLT_NULL || linktype == DLT_ENC) {
3188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
3189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * The AF_ value is in host byte order, but
3190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * the BPF interpreter will convert it to
3191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * network byte order.
3192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 *
3193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * If this is a save file, and it's from a
3194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * machine with the opposite byte order to
3195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * ours, we byte-swap the AF_ value.
3196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 *
3197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Then we run it through "htonl()", and
3198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * generate code to compare against the result.
3199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
3200511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (bpf_pcap->rfile != NULL && bpf_pcap->swapped)
3201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				proto = SWAPLONG(proto);
3202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			proto = htonl(proto);
3203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
3204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (gen_cmp(OR_LINK, 0, BPF_W, (bpf_int32)proto));
3205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_NET_PFVAR_H
3207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_PFLOG:
3208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * af field is host byte order in contrast to the rest of
3210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the packet.
3211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (proto == ETHERTYPE_IP)
3213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return (gen_cmp(OR_LINK, offsetof(struct pfloghdr, af),
3214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    BPF_B, (bpf_int32)AF_INET));
3215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else if (proto == ETHERTYPE_IPV6)
3216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return (gen_cmp(OR_LINK, offsetof(struct pfloghdr, af),
3217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    BPF_B, (bpf_int32)AF_INET6));
3218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else
3219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_false();
3220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*NOTREACHED*/
3221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
3222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_NET_PFVAR_H */
3223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_ARCNET:
3225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_ARCNET_LINUX:
3226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX should we check for first fragment if the protocol
3228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * uses PHDS?
3229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		switch (proto) {
3231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		default:
3233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_false();
3234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case ETHERTYPE_IPV6:
3236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return (gen_cmp(OR_LINK, off_linktype, BPF_B,
3237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				(bpf_int32)ARCTYPE_INET6));
3238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case ETHERTYPE_IP:
3240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b0 = gen_cmp(OR_LINK, off_linktype, BPF_B,
3241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				     (bpf_int32)ARCTYPE_IP);
3242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b1 = gen_cmp(OR_LINK, off_linktype, BPF_B,
3243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				     (bpf_int32)ARCTYPE_IP_OLD);
3244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_or(b0, b1);
3245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return (b1);
3246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case ETHERTYPE_ARP:
3248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b0 = gen_cmp(OR_LINK, off_linktype, BPF_B,
3249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				     (bpf_int32)ARCTYPE_ARP);
3250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b1 = gen_cmp(OR_LINK, off_linktype, BPF_B,
3251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				     (bpf_int32)ARCTYPE_ARP_OLD);
3252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_or(b0, b1);
3253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return (b1);
3254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case ETHERTYPE_REVARP:
3256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return (gen_cmp(OR_LINK, off_linktype, BPF_B,
3257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					(bpf_int32)ARCTYPE_REVARP));
3258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case ETHERTYPE_ATALK:
3260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return (gen_cmp(OR_LINK, off_linktype, BPF_B,
3261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					(bpf_int32)ARCTYPE_ATALK));
3262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
3263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*NOTREACHED*/
3264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
3265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_LTALK:
3267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		switch (proto) {
3268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case ETHERTYPE_ATALK:
3269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_true();
3270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		default:
3271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_false();
3272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
3273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*NOTREACHED*/
3274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
3275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_FRELAY:
3277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - assumes a 2-byte Frame Relay header with
3279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * DLCI and flags.  What if the address is longer?
3280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		switch (proto) {
3282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case ETHERTYPE_IP:
3284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
3285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Check for the special NLPID for IP.
3286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
3287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | 0xcc);
3288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case ETHERTYPE_IPV6:
3290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
3291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Check for the special NLPID for IPv6.
3292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
3293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | 0x8e);
3294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case LLCSAP_ISONS:
3296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
3297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Check for several OSI protocols.
3298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 *
3299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Frame Relay packets typically have an OSI
3300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * NLPID at the beginning; we check for each
3301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * of them.
3302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 *
3303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * What we check for is the NLPID and a frame
3304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * control field of UI, i.e. 0x03 followed
3305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * by the NLPID.
3306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
3307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b0 = gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | ISO8473_CLNP);
3308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b1 = gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | ISO9542_ESIS);
3309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b2 = gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | ISO10589_ISIS);
3310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_or(b1, b2);
3311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_or(b0, b2);
3312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return b2;
3313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		default:
3315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_false();
3316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
3317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*NOTREACHED*/
3318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
3319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3320511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_MFR:
3321511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("Multi-link Frame Relay link-layer type filtering not implemented");
3322511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_MFR:
3324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_MLFR:
3325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_MLPPP:
3326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_JUNIPER_ATM1:
3327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_JUNIPER_ATM2:
3328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_JUNIPER_PPPOE:
3329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_JUNIPER_PPPOE_ATM:
3330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_GGSN:
3331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_ES:
3332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_MONITOR:
3333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_SERVICES:
3334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_ETHER:
3335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_PPP:
3336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_FRELAY:
3337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_CHDLC:
3338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_VP:
3339511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        case DLT_JUNIPER_ST:
3340511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        case DLT_JUNIPER_ISM:
3341511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        case DLT_JUNIPER_VS:
3342511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        case DLT_JUNIPER_SRX_E2E:
3343511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        case DLT_JUNIPER_FIBRECHANNEL:
3344511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_JUNIPER_ATM_CEMIC:
3345511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* just lets verify the magic number for now -
3347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * on ATM we may have up to 6 different encapsulations on the wire
3348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * and need a lot of heuristics to figure out that the payload
3349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * might be;
3350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
3351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * FIXME encapsulation specific BPF_ filters
3352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_mcmp(OR_LINK, 0, BPF_W, 0x4d474300, 0xffffff00); /* compare the magic number */
3354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3355511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_BACNET_MS_TP:
3356511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return gen_mcmp(OR_LINK, 0, BPF_W, 0x55FF0000, 0xffff0000);
3357511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3358511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IPNET:
3359511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return gen_ipnet_linktype(proto);
3360511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_LINUX_IRDA:
3362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("IrDA link-layer type filtering not implemented");
3363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_DOCSIS:
3365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("DOCSIS link-layer type filtering not implemented");
3366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3367511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_MTP2:
3368511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_MTP2_WITH_PHDR:
3369511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("MTP2 link-layer type filtering not implemented");
3370511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3371511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_ERF:
3372511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("ERF link-layer type filtering not implemented");
3373511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3374511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_PFSYNC:
3375511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("PFSYNC link-layer type filtering not implemented");
3376511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_LINUX_LAPD:
3378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("LAPD link-layer type filtering not implemented");
3379511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3380511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_USB:
3381511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_USB_LINUX:
3382511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_USB_LINUX_MMAPPED:
3383511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("USB link-layer type filtering not implemented");
3384511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3385511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_BLUETOOTH_HCI_H4:
3386511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_BLUETOOTH_HCI_H4_WITH_PHDR:
3387511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("Bluetooth link-layer type filtering not implemented");
3388511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3389511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_CAN20B:
3390511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_CAN_SOCKETCAN:
3391511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("CAN link-layer type filtering not implemented");
3392511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3393511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_15_4:
3394511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_15_4_LINUX:
3395511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_15_4_NONASK_PHY:
3396511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_15_4_NOFCS:
3397511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("IEEE 802.15.4 link-layer type filtering not implemented");
3398511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3399511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_16_MAC_CPS_RADIO:
3400511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("IEEE 802.16 link-layer type filtering not implemented");
3401511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3402511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_SITA:
3403511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("SITA link-layer type filtering not implemented");
3404511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3405511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_RAIF1:
3406511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("RAIF1 link-layer type filtering not implemented");
3407511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3408511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IPMB:
3409511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("IPMB link-layer type filtering not implemented");
3410511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3411511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_AX25_KISS:
3412511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("AX.25 link-layer type filtering not implemented");
3413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
3414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
3416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * All the types that have no encapsulation should either be
3417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * handled as DLT_SLIP, DLT_SLIP_BSDOS, and DLT_RAW are, if
3418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * all packets are IP packets, or should be handled in some
3419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * special case, if none of them are (if some are and some
3420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * aren't, the lack of encapsulation is a problem, as we'd
3421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * have to find some other way of determining the packet type).
3422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 *
3423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Therefore, if "off_linktype" is -1, there's an error.
3424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
3425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (off_linktype == (u_int)-1)
3426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
3427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
3429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Any type not handled above should always have an Ethernet
3430511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * type at an offset of "off_linktype".
3431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
3432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);
3433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
3434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
3436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for an LLC SNAP packet with a given organization code and
3437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * protocol type; we check the entire contents of the 802.2 LLC and
3438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * snap headers, checking for DSAP and SSAP of SNAP and a control
3439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * field of 0x03 in the LLC header, and for the specified organization
3440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * code and protocol type in the SNAP header.
3441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
3442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
3443511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_snap(orgcode, ptype)
3444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 orgcode;
3445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 ptype;
3446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
3447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_char snapblock[8];
3448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	snapblock[0] = LLCSAP_SNAP;	/* DSAP = SNAP */
3450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	snapblock[1] = LLCSAP_SNAP;	/* SSAP = SNAP */
3451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	snapblock[2] = 0x03;		/* control = UI */
3452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	snapblock[3] = (orgcode >> 16);	/* upper 8 bits of organization code */
3453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	snapblock[4] = (orgcode >> 8);	/* middle 8 bits of organization code */
3454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	snapblock[5] = (orgcode >> 0);	/* lower 8 bits of organization code */
3455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	snapblock[6] = (ptype >> 8);	/* upper 8 bits of protocol type */
3456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	snapblock[7] = (ptype >> 0);	/* lower 8 bits of protocol type */
3457511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return gen_bcmp(OR_MACPL, 0, 8, snapblock);
3458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
3459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
3461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to match a particular packet type, for link-layer types
3462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * using 802.2 LLC headers.
3463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
3464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is *NOT* used for Ethernet; "gen_ether_linktype()" is used
3465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * for that - it handles the D/I/X Ethernet vs. 802.3+802.2 issues.
3466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
3467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP
3468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * value, if <= ETHERMTU.  We use that to determine whether to
3469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * match the DSAP or both DSAP and LSAP or to check the OUI and
3470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * protocol ID in a SNAP header.
3471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
3472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
3473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_llc_linktype(proto)
3474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int proto;
3475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
3476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
3477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * XXX - handle token-ring variable-length header.
3478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
3479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (proto) {
3480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case LLCSAP_IP:
3482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case LLCSAP_ISONS:
3483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case LLCSAP_NETBEUI:
3484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - should we check both the DSAP and the
3486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * SSAP, like this, or should we check just the
3487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * DSAP, as we do for other types <= ETHERMTU
3488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * (i.e., other SAP values)?
3489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3490511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return gen_cmp(OR_MACPL, 0, BPF_H, (bpf_u_int32)
3491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			     ((proto << 8) | proto));
3492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case LLCSAP_IPX:
3494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - are there ever SNAP frames for IPX on
3496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * non-Ethernet 802.x networks?
3497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3498511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return gen_cmp(OR_MACPL, 0, BPF_B,
3499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    (bpf_int32)LLCSAP_IPX);
3500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case ETHERTYPE_ATALK:
3502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * 802.2-encapsulated ETHERTYPE_ATALK packets are
3504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * SNAP packets with an organization code of
3505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * 0x080007 (Apple, for Appletalk) and a protocol
3506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * type of ETHERTYPE_ATALK (Appletalk).
3507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
3508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - check for an organization code of
3509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * encapsulated Ethernet as well?
3510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3511511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return gen_snap(0x080007, ETHERTYPE_ATALK);
3512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
3514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - we don't have to check for IPX 802.3
3516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * here, but should we check for the IPX Ethertype?
3517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (proto <= ETHERMTU) {
3519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
3520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * This is an LLC SAP value, so check
3521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * the DSAP.
3522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
3523511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_cmp(OR_MACPL, 0, BPF_B, (bpf_int32)proto);
3524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else {
3525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
3526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * This is an Ethernet type; we assume that it's
3527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * unlikely that it'll appear in the right place
3528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * at random, and therefore check only the
3529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * location that would hold the Ethernet type
3530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * in a SNAP frame with an organization code of
3531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * 0x000000 (encapsulated Ethernet).
3532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 *
3533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * XXX - if we were to check for the SNAP DSAP and
3534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * LSAP, as per XXX, and were also to check for an
3535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * organization code of 0x000000 (encapsulated
3536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Ethernet), we'd do
3537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 *
3538511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 *	return gen_snap(0x000000, proto);
3539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 *
3540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * here; for now, we don't, as per the above.
3541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * I don't know whether it's worth the extra CPU
3542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * time to do the right check or not.
3543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
3544511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_cmp(OR_MACPL, 6, BPF_H, (bpf_int32)proto);
3545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
3546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
3547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
3548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
3550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_hostop(addr, mask, dir, proto, src_off, dst_off)
3551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 addr;
3552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 mask;
3553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int dir, proto;
3554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int src_off, dst_off;
3555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
3556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1;
3557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int offset;
3558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (dir) {
3560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SRC:
3562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		offset = src_off;
3563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
3564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DST:
3566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		offset = dst_off;
3567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
3568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AND:
3570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off);
3571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off);
3572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
3573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
3574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_OR:
3576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
3577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off);
3578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off);
3579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
3580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
3581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
3583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
3584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
3585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 = gen_linktype(proto);
3586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b1 = gen_mcmp(OR_NET, offset, BPF_W, (bpf_int32)addr, mask);
3587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(b0, b1);
3588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b1;
3589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
3590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6
3592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
3593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_hostop6(addr, mask, dir, proto, src_off, dst_off)
3594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct in6_addr *addr;
3595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct in6_addr *mask;
3596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int dir, proto;
3597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int src_off, dst_off;
3598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
3599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1;
3600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int offset;
3601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int32_t *a, *m;
3602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (dir) {
3604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SRC:
3606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		offset = src_off;
3607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
3608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DST:
3610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		offset = dst_off;
3611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
3612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AND:
3614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off);
3615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off);
3616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
3617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
3618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_OR:
3620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
3621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off);
3622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off);
3623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
3624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
3625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
3627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
3628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
3629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* this order is important */
3630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	a = (u_int32_t *)addr;
3631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	m = (u_int32_t *)mask;
3632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b1 = gen_mcmp(OR_NET, offset + 12, BPF_W, ntohl(a[3]), ntohl(m[3]));
3633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 = gen_mcmp(OR_NET, offset + 8, BPF_W, ntohl(a[2]), ntohl(m[2]));
3634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(b0, b1);
3635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 = gen_mcmp(OR_NET, offset + 4, BPF_W, ntohl(a[1]), ntohl(m[1]));
3636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(b0, b1);
3637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 = gen_mcmp(OR_NET, offset + 0, BPF_W, ntohl(a[0]), ntohl(m[0]));
3638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(b0, b1);
3639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 = gen_linktype(proto);
3640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(b0, b1);
3641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b1;
3642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
3643511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
3644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
3646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ehostop(eaddr, dir)
3647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register const u_char *eaddr;
3648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register int dir;
3649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
3650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register struct block *b0, *b1;
3651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (dir) {
3653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SRC:
3654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_bcmp(OR_LINK, off_mac + 6, 6, eaddr);
3655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DST:
3657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_bcmp(OR_LINK, off_mac + 0, 6, eaddr);
3658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AND:
3660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_ehostop(eaddr, Q_SRC);
3661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_ehostop(eaddr, Q_DST);
3662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
3663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
3664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
3666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_OR:
3667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_ehostop(eaddr, Q_SRC);
3668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_ehostop(eaddr, Q_DST);
3669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
3670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
3671511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3672511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR1:
3673511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr1' is only supported on 802.11 with 802.11 headers");
3674511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3675511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3676511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR2:
3677511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr2' is only supported on 802.11 with 802.11 headers");
3678511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3679511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3680511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR3:
3681511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr3' is only supported on 802.11 with 802.11 headers");
3682511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3683511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3684511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR4:
3685511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr4' is only supported on 802.11 with 802.11 headers");
3686511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3687511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3688511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_RA:
3689511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'ra' is only supported on 802.11 with 802.11 headers");
3690511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3691511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3692511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_TA:
3693511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'ta' is only supported on 802.11 with 802.11 headers");
3694511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
3696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	abort();
3697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
3698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
3699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
3701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Like gen_ehostop, but for DLT_FDDI
3702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
3703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
3704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_fhostop(eaddr, dir)
3705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register const u_char *eaddr;
3706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register int dir;
3707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
3708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1;
3709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (dir) {
3711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SRC:
3712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_bcmp(OR_LINK, 6 + 1 + pcap_fddipad, 6, eaddr);
3713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DST:
3715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_bcmp(OR_LINK, 0 + 1 + pcap_fddipad, 6, eaddr);
3716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AND:
3718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_fhostop(eaddr, Q_SRC);
3719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_fhostop(eaddr, Q_DST);
3720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
3721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
3722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
3724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_OR:
3725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_fhostop(eaddr, Q_SRC);
3726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_fhostop(eaddr, Q_DST);
3727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
3728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
3729511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3730511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR1:
3731511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr1' is only supported on 802.11");
3732511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3733511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3734511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR2:
3735511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr2' is only supported on 802.11");
3736511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3737511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3738511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR3:
3739511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr3' is only supported on 802.11");
3740511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3741511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3742511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR4:
3743511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr4' is only supported on 802.11");
3744511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3745511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3746511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_RA:
3747511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'ra' is only supported on 802.11");
3748511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3749511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3750511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_TA:
3751511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'ta' is only supported on 802.11");
3752511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
3754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	abort();
3755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
3756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
3757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
3759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Like gen_ehostop, but for DLT_IEEE802 (Token Ring)
3760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
3761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
3762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_thostop(eaddr, dir)
3763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register const u_char *eaddr;
3764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register int dir;
3765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
3766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register struct block *b0, *b1;
3767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (dir) {
3769478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SRC:
3770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_bcmp(OR_LINK, 8, 6, eaddr);
3771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DST:
3773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_bcmp(OR_LINK, 2, 6, eaddr);
3774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AND:
3776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_thostop(eaddr, Q_SRC);
3777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_thostop(eaddr, Q_DST);
3778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
3779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
3780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
3782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_OR:
3783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_thostop(eaddr, Q_SRC);
3784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_thostop(eaddr, Q_DST);
3785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
3786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
3787511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3788511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR1:
3789511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr1' is only supported on 802.11");
3790511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3791511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3792511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR2:
3793511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr2' is only supported on 802.11");
3794511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3795511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3796511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR3:
3797511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr3' is only supported on 802.11");
3798511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3799511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3800511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR4:
3801511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr4' is only supported on 802.11");
3802511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3803511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3804511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_RA:
3805511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'ra' is only supported on 802.11");
3806511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3807511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3808511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_TA:
3809511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'ta' is only supported on 802.11");
3810511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
3811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
3812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	abort();
3813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
3814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
3815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
3817511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Like gen_ehostop, but for DLT_IEEE802_11 (802.11 wireless LAN) and
3818511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * various 802.11 + radio headers.
3819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
3820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
3821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_wlanhostop(eaddr, dir)
3822478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register const u_char *eaddr;
3823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register int dir;
3824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
3825478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register struct block *b0, *b1, *b2;
3826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register struct slist *s;
3827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3828511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef ENABLE_WLAN_FILTERING_PATCH
3829511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
3830511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * TODO GV 20070613
3831511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * We need to disable the optimizer because the optimizer is buggy
3832511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * and wipes out some LD instructions generated by the below
3833511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * code to validate the Frame Control bits
3834511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
3835511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	no_optimize = 1;
3836511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif /* ENABLE_WLAN_FILTERING_PATCH */
3837511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
3838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (dir) {
3839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SRC:
3840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Oh, yuk.
3842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
3843478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	For control frames, there is no SA.
3844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
3845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	For management frames, SA is at an
3846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	offset of 10 from the beginning of
3847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	the packet.
3848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
3849478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	For data frames, SA is at an offset
3850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	of 10 from the beginning of the packet
3851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	if From DS is clear, at an offset of
3852478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	16 from the beginning of the packet
3853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	if From DS is set and To DS is clear,
3854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	and an offset of 24 from the beginning
3855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	of the packet if From DS is set and To DS
3856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	is set.
3857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Generate the tests to be done for data frames
3861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * with From DS set.
3862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
3863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * First, check for To DS set, i.e. check "link[1] & 0x01".
3864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = gen_load_a(OR_LINK, 1, BPF_B);
3866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = new_block(JMP(BPF_JSET));
3867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1->s.k = 0x01;	/* To DS */
3868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1->stmts = s;
3869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If To DS is set, the SA is at 24.
3872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_bcmp(OR_LINK, 24, 6, eaddr);
3874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b1, b0);
3875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now, check for To DS not set, i.e. check
3878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * "!(link[1] & 0x01)".
3879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = gen_load_a(OR_LINK, 1, BPF_B);
3881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b2 = new_block(JMP(BPF_JSET));
3882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b2->s.k = 0x01;	/* To DS */
3883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b2->stmts = s;
3884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_not(b2);
3885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If To DS is not set, the SA is at 16.
3888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_bcmp(OR_LINK, 16, 6, eaddr);
3890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b2, b1);
3891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now OR together the last two checks.  That gives
3894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the complete set of checks for data frames with
3895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * From DS set.
3896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b1, b0);
3898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now check for From DS being set, and AND that with
3901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the ORed-together checks.
3902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = gen_load_a(OR_LINK, 1, BPF_B);
3904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = new_block(JMP(BPF_JSET));
3905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1->s.k = 0x02;	/* From DS */
3906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1->stmts = s;
3907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b1, b0);
3908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3910478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now check for data frames with From DS not set.
3911478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = gen_load_a(OR_LINK, 1, BPF_B);
3913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b2 = new_block(JMP(BPF_JSET));
3914478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b2->s.k = 0x02;	/* From DS */
3915478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b2->stmts = s;
3916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_not(b2);
3917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3919478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If From DS isn't set, the SA is at 10.
3920478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3921478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_bcmp(OR_LINK, 10, 6, eaddr);
3922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b2, b1);
3923478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3924478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3925478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now OR together the checks for data frames with
3926478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * From DS not set and for data frames with From DS
3927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * set; that gives the checks done for data frames.
3928478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3929478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b1, b0);
3930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3932478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now check for a data frame.
3933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * I.e, check "link[0] & 0x08".
3934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3935511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s = gen_load_a(OR_LINK, 0, BPF_B);
3936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = new_block(JMP(BPF_JSET));
3937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1->s.k = 0x08;
3938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1->stmts = s;
3939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * AND that with the checks done for data frames.
3942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b1, b0);
3944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If the high-order bit of the type value is 0, this
3947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * is a management frame.
3948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * I.e, check "!(link[0] & 0x08)".
3949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = gen_load_a(OR_LINK, 0, BPF_B);
3951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b2 = new_block(JMP(BPF_JSET));
3952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b2->s.k = 0x08;
3953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b2->stmts = s;
3954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_not(b2);
3955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * For management frames, the SA is at 10.
3958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_bcmp(OR_LINK, 10, 6, eaddr);
3960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b2, b1);
3961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * OR that with the checks done for data frames.
3964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * That gives the checks done for management and
3965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * data frames.
3966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b1, b0);
3968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If the low-order bit of the type value is 1,
3971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * this is either a control frame or a frame
3972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * with a reserved type, and thus not a
3973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * frame with an SA.
3974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
3975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * I.e., check "!(link[0] & 0x04)".
3976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = gen_load_a(OR_LINK, 0, BPF_B);
3978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = new_block(JMP(BPF_JSET));
3979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1->s.k = 0x04;
3980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1->stmts = s;
3981478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_not(b1);
3982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3984478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * AND that with the checks for data and management
3985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * frames.
3986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
3987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b1, b0);
3988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b0;
3989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
3990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DST:
3991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
3992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Oh, yuk.
3993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
3994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	For control frames, there is no DA.
3995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
3996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	For management frames, DA is at an
3997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	offset of 4 from the beginning of
3998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	the packet.
3999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
4000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	For data frames, DA is at an offset
4001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	of 4 from the beginning of the packet
4002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	if To DS is clear and at an offset of
4003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	16 from the beginning of the packet
4004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *	if To DS is set.
4005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
4006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
4008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Generate the tests to be done for data frames.
4009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
4010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * First, check for To DS set, i.e. "link[1] & 0x01".
4011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
4012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = gen_load_a(OR_LINK, 1, BPF_B);
4013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = new_block(JMP(BPF_JSET));
4014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1->s.k = 0x01;	/* To DS */
4015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1->stmts = s;
4016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
4018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If To DS is set, the DA is at 16.
4019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
4020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_bcmp(OR_LINK, 16, 6, eaddr);
4021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b1, b0);
4022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
4024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now, check for To DS not set, i.e. check
4025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * "!(link[1] & 0x01)".
4026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
4027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = gen_load_a(OR_LINK, 1, BPF_B);
4028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b2 = new_block(JMP(BPF_JSET));
4029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b2->s.k = 0x01;	/* To DS */
4030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b2->stmts = s;
4031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_not(b2);
4032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
4034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If To DS is not set, the DA is at 4.
4035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
4036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_bcmp(OR_LINK, 4, 6, eaddr);
4037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b2, b1);
4038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
4040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now OR together the last two checks.  That gives
4041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the complete set of checks for data frames.
4042478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
4043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b1, b0);
4044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4045478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
4046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Now check for a data frame.
4047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * I.e, check "link[0] & 0x08".
4048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
4049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = gen_load_a(OR_LINK, 0, BPF_B);
4050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = new_block(JMP(BPF_JSET));
4051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1->s.k = 0x08;
4052478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1->stmts = s;
4053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
4055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * AND that with the checks done for data frames.
4056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
4057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b1, b0);
4058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
4060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If the high-order bit of the type value is 0, this
4061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * is a management frame.
4062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * I.e, check "!(link[0] & 0x08)".
4063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
4064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = gen_load_a(OR_LINK, 0, BPF_B);
4065478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b2 = new_block(JMP(BPF_JSET));
4066478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b2->s.k = 0x08;
4067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b2->stmts = s;
4068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_not(b2);
4069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
4071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * For management frames, the DA is at 4.
4072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
4073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_bcmp(OR_LINK, 4, 6, eaddr);
4074478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b2, b1);
4075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
4077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * OR that with the checks done for data frames.
4078478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * That gives the checks done for management and
4079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * data frames.
4080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
4081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b1, b0);
4082478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
4084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If the low-order bit of the type value is 1,
4085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * this is either a control frame or a frame
4086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * with a reserved type, and thus not a
4087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * frame with an SA.
4088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
4089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * I.e., check "!(link[0] & 0x04)".
4090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
4091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = gen_load_a(OR_LINK, 0, BPF_B);
4092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = new_block(JMP(BPF_JSET));
4093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1->s.k = 0x04;
4094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1->stmts = s;
4095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_not(b1);
4096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
4098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * AND that with the checks for data and management
4099478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * frames.
4100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
4101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b1, b0);
4102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b0;
4103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4104511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_RA:
4105511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
4106511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Not present in management frames; addr1 in other
4107511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * frames.
4108511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
4109511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4110511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
4111511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * If the high-order bit of the type value is 0, this
4112511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * is a management frame.
4113511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * I.e, check "(link[0] & 0x08)".
4114511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
4115511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s = gen_load_a(OR_LINK, 0, BPF_B);
4116511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = new_block(JMP(BPF_JSET));
4117511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1->s.k = 0x08;
4118511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1->stmts = s;
4119511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4120511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
4121511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Check addr1.
4122511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
4123511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_bcmp(OR_LINK, 4, 6, eaddr);
4124511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4125511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
4126511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * AND that with the check of addr1.
4127511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
4128511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_and(b1, b0);
4129511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (b0);
4130511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4131511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_TA:
4132511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
4133511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Not present in management frames; addr2, if present,
4134511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * in other frames.
4135511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
4136511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4137511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
4138511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Not present in CTS or ACK control frames.
4139511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
4140511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
4141511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			IEEE80211_FC0_TYPE_MASK);
4142511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_not(b0);
4143511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_CTS,
4144511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			IEEE80211_FC0_SUBTYPE_MASK);
4145511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_not(b1);
4146511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b2 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_ACK,
4147511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			IEEE80211_FC0_SUBTYPE_MASK);
4148511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_not(b2);
4149511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_and(b1, b2);
4150511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_or(b0, b2);
4151511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4152511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
4153511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * If the high-order bit of the type value is 0, this
4154511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * is a management frame.
4155511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * I.e, check "(link[0] & 0x08)".
4156511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
4157511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s = gen_load_a(OR_LINK, 0, BPF_B);
4158511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = new_block(JMP(BPF_JSET));
4159511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1->s.k = 0x08;
4160511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1->stmts = s;
4161511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4162511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
4163511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * AND that with the check for frames other than
4164511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * CTS and ACK frames.
4165511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
4166511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_and(b1, b2);
4167511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4168511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
4169511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Check addr2.
4170511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
4171511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = gen_bcmp(OR_LINK, 10, 6, eaddr);
4172511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_and(b2, b1);
4173511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return b1;
4174511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
4176511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * XXX - add BSSID keyword?
4177511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
4178511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR1:
4179511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (gen_bcmp(OR_LINK, 4, 6, eaddr));
4180511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4181511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR2:
4182511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
4183511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Not present in CTS or ACK control frames.
4184511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
4185511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
4186511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			IEEE80211_FC0_TYPE_MASK);
4187511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_not(b0);
4188511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_CTS,
4189511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			IEEE80211_FC0_SUBTYPE_MASK);
4190511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_not(b1);
4191511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b2 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_ACK,
4192511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			IEEE80211_FC0_SUBTYPE_MASK);
4193511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_not(b2);
4194511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_and(b1, b2);
4195511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_or(b0, b2);
4196511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = gen_bcmp(OR_LINK, 10, 6, eaddr);
4197511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_and(b2, b1);
4198511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return b1;
4199511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4200511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR3:
4201511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
4202511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Not present in control frames.
4203511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
4204511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
4205511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			IEEE80211_FC0_TYPE_MASK);
4206511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_not(b0);
4207511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = gen_bcmp(OR_LINK, 16, 6, eaddr);
4208511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_and(b0, b1);
4209511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return b1;
4210511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4211511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR4:
4212511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
4213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Present only if the direction mask has both "From DS"
4214511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * and "To DS" set.  Neither control frames nor management
4215511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * frames should have both of those set, so we don't
4216511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * check the frame type.
4217511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
4218511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_mcmp(OR_LINK, 1, BPF_B,
4219511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			IEEE80211_FC1_DIR_DSTODS, IEEE80211_FC1_DIR_MASK);
4220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = gen_bcmp(OR_LINK, 24, 6, eaddr);
4221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_and(b0, b1);
4222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return b1;
4223511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AND:
4225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_wlanhostop(eaddr, Q_SRC);
4226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_wlanhostop(eaddr, Q_DST);
4227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
4228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
4229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
4231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_OR:
4232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_wlanhostop(eaddr, Q_SRC);
4233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_wlanhostop(eaddr, Q_DST);
4234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
4236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
4237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	abort();
4238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
4239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
4240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
4242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Like gen_ehostop, but for RFC 2625 IP-over-Fibre-Channel.
4243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (We assume that the addresses are IEEE 48-bit MAC addresses,
4244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as the RFC states.)
4245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
4246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
4247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ipfchostop(eaddr, dir)
4248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register const u_char *eaddr;
4249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register int dir;
4250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
4251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register struct block *b0, *b1;
4252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (dir) {
4254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SRC:
4255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_bcmp(OR_LINK, 10, 6, eaddr);
4256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DST:
4258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_bcmp(OR_LINK, 2, 6, eaddr);
4259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AND:
4261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_ipfchostop(eaddr, Q_SRC);
4262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_ipfchostop(eaddr, Q_DST);
4263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
4264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
4265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
4267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_OR:
4268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_ipfchostop(eaddr, Q_SRC);
4269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_ipfchostop(eaddr, Q_DST);
4270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
4272511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4273511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR1:
4274511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr1' is only supported on 802.11");
4275511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
4276511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4277511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR2:
4278511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr2' is only supported on 802.11");
4279511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
4280511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4281511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR3:
4282511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr3' is only supported on 802.11");
4283511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
4284511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4285511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR4:
4286511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr4' is only supported on 802.11");
4287511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
4288511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4289511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_RA:
4290511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'ra' is only supported on 802.11");
4291511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
4292511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4293511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_TA:
4294511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'ta' is only supported on 802.11");
4295511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
4296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
4297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	abort();
4298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
4299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
4300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
4302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is quite tricky because there may be pad bytes in front of the
4303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DECNET header, and then there are two possible data packet formats that
4304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * carry both src and dst addresses, plus 5 packet types in a format that
4305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * carries only the src node, plus 2 types that use a different format and
4306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * also carry just the src node.
4307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
4308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Yuck.
4309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
4310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Instead of doing those all right, we just look for data packets with
4311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 0 or 1 bytes of padding.  If you want to look at other packets, that
4312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * will require a lot more hacking.
4313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
4314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * To add support for filtering on DECNET "areas" (network numbers)
4315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * one would want to add a "mask" argument to this routine.  That would
4316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * make the filter even more inefficient, although one could be clever
4317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and not generate masking instructions if the mask is 0xFFFF.
4318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
4319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
4320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_dnhostop(addr, dir)
4321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 addr;
4322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int dir;
4323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
4324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1, *b2, *tmp;
4325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int offset_lh;	/* offset if long header is received */
4326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int offset_sh;	/* offset if short header is received */
4327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (dir) {
4329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DST:
4331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		offset_sh = 1;	/* follows flags */
4332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		offset_lh = 7;	/* flgs,darea,dsubarea,HIORD */
4333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SRC:
4336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		offset_sh = 3;	/* follows flags, dstnode */
4337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		offset_lh = 15;	/* flgs,darea,dsubarea,did,sarea,ssub,HIORD */
4338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AND:
4341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Inefficient because we do our Calvinball dance twice */
4342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_dnhostop(addr, Q_SRC);
4343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_dnhostop(addr, Q_DST);
4344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
4345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
4346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_OR:
4348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
4349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Inefficient because we do our Calvinball dance twice */
4350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_dnhostop(addr, Q_SRC);
4351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_dnhostop(addr, Q_DST);
4352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
4354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ISO:
4356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("ISO host filtering not implemented");
4357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
4359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
4360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
4361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 = gen_linktype(ETHERTYPE_DN);
4362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Check for pad = 1, long header case */
4363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	tmp = gen_mcmp(OR_NET, 2, BPF_H,
4364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF));
4365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b1 = gen_cmp(OR_NET, 2 + 1 + offset_lh,
4366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    BPF_H, (bpf_int32)ntohs((u_short)addr));
4367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(tmp, b1);
4368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Check for pad = 0, long header case */
4369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	tmp = gen_mcmp(OR_NET, 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7);
4370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b2 = gen_cmp(OR_NET, 2 + offset_lh, BPF_H, (bpf_int32)ntohs((u_short)addr));
4371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(tmp, b2);
4372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_or(b2, b1);
4373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Check for pad = 1, short header case */
4374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	tmp = gen_mcmp(OR_NET, 2, BPF_H,
4375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF));
4376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b2 = gen_cmp(OR_NET, 2 + 1 + offset_sh, BPF_H, (bpf_int32)ntohs((u_short)addr));
4377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(tmp, b2);
4378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_or(b2, b1);
4379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Check for pad = 0, short header case */
4380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	tmp = gen_mcmp(OR_NET, 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7);
4381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b2 = gen_cmp(OR_NET, 2 + offset_sh, BPF_H, (bpf_int32)ntohs((u_short)addr));
4382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(tmp, b2);
4383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_or(b2, b1);
4384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Combine with test for linktype */
4386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(b0, b1);
4387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b1;
4388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
4389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
4391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate a check for IPv4 or IPv6 for MPLS-encapsulated packets;
4392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * test the bottom-of-stack bit, and then check the version number
4393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * field in the IP header.
4394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
4395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
4396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_mpls_linktype(proto)
4397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int proto;
4398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
4399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1;
4400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        switch (proto) {
4402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case Q_IP:
4404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                /* match the bottom-of-stack bit */
4405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                b0 = gen_mcmp(OR_NET, -2, BPF_B, 0x01, 0x01);
4406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                /* match the IPv4 version number */
4407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                b1 = gen_mcmp(OR_NET, 0, BPF_B, 0x40, 0xf0);
4408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                gen_and(b0, b1);
4409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                return b1;
4410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       case Q_IPV6:
4412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                /* match the bottom-of-stack bit */
4413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                b0 = gen_mcmp(OR_NET, -2, BPF_B, 0x01, 0x01);
4414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                /* match the IPv4 version number */
4415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                b1 = gen_mcmp(OR_NET, 0, BPF_B, 0x60, 0xf0);
4416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                gen_and(b0, b1);
4417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                return b1;
4418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       default:
4420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                abort();
4421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        }
4422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
4423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
4425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_host(addr, mask, proto, dir, type)
4426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 addr;
4427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 mask;
4428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int proto;
4429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int dir;
4430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int type;
4431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
4432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1;
4433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	const char *typestr;
4434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (type == Q_NET)
4436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		typestr = "net";
4437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else
4438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		typestr = "host";
4439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (proto) {
4441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
4443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_host(addr, mask, Q_IP, dir, type);
4444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
4445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Only check for non-IPv4 addresses if we're not
4446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * checking MPLS-encapsulated packets.
4447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
4448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (label_stack_depth == 0) {
4449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b1 = gen_host(addr, mask, Q_ARP, dir, type);
4450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_or(b0, b1);
4451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b0 = gen_host(addr, mask, Q_RARP, dir, type);
4452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_or(b1, b0);
4453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
4454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b0;
4455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IP:
4457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_hostop(addr, mask, dir, ETHERTYPE_IP, 12, 16);
4458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_RARP:
4460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_hostop(addr, mask, dir, ETHERTYPE_REVARP, 14, 24);
4461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ARP:
4463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_hostop(addr, mask, dir, ETHERTYPE_ARP, 14, 24);
4464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_TCP:
4466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'tcp' modifier applied to %s", typestr);
4467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SCTP:
4469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'sctp' modifier applied to %s", typestr);
4470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_UDP:
4472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'udp' modifier applied to %s", typestr);
4473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ICMP:
4475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'icmp' modifier applied to %s", typestr);
4476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IGMP:
4478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'igmp' modifier applied to %s", typestr);
4479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IGRP:
4481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'igrp' modifier applied to %s", typestr);
4482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_PIM:
4484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'pim' modifier applied to %s", typestr);
4485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_VRRP:
4487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'vrrp' modifier applied to %s", typestr);
4488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4489511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_CARP:
4490511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'carp' modifier applied to %s", typestr);
4491511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ATALK:
4493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("ATALK host filtering not implemented");
4494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AARP:
4496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("AARP host filtering not implemented");
4497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DECNET:
4499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_dnhostop(addr, dir);
4500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SCA:
4502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("SCA host filtering not implemented");
4503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_LAT:
4505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("LAT host filtering not implemented");
4506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_MOPDL:
4508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("MOPDL host filtering not implemented");
4509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_MOPRC:
4511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("MOPRC host filtering not implemented");
4512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IPV6:
4514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'ip6' modifier applied to ip host");
4515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ICMPV6:
4517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'icmp6' modifier applied to %s", typestr);
4518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AH:
4520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'ah' modifier applied to %s", typestr);
4521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ESP:
4523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'esp' modifier applied to %s", typestr);
4524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ISO:
4526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("ISO host filtering not implemented");
4527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ESIS:
4529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'esis' modifier applied to %s", typestr);
4530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ISIS:
4532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'isis' modifier applied to %s", typestr);
4533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_CLNP:
4535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'clnp' modifier applied to %s", typestr);
4536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_STP:
4538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'stp' modifier applied to %s", typestr);
4539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IPX:
4541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("IPX host filtering not implemented");
4542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_NETBEUI:
4544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'netbeui' modifier applied to %s", typestr);
4545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_RADIO:
4547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'radio' modifier applied to %s", typestr);
4548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
4550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
4551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
4552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
4553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
4554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6
4556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
4557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_host6(addr, mask, proto, dir, type)
4558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct in6_addr *addr;
4559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct in6_addr *mask;
4560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int proto;
4561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int dir;
4562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int type;
4563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
4564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	const char *typestr;
4565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (type == Q_NET)
4567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		typestr = "net";
4568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else
4569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		typestr = "host";
4570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (proto) {
4572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
4574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_host6(addr, mask, Q_IPV6, dir, type);
4575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4576511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_LINK:
4577511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("link-layer modifier applied to ip6 %s", typestr);
4578511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IP:
4580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'ip' modifier applied to ip6 %s", typestr);
4581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_RARP:
4583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'rarp' modifier applied to ip6 %s", typestr);
4584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ARP:
4586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'arp' modifier applied to ip6 %s", typestr);
4587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SCTP:
4589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'sctp' modifier applied to %s", typestr);
4590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_TCP:
4592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'tcp' modifier applied to %s", typestr);
4593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_UDP:
4595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'udp' modifier applied to %s", typestr);
4596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ICMP:
4598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'icmp' modifier applied to %s", typestr);
4599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IGMP:
4601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'igmp' modifier applied to %s", typestr);
4602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IGRP:
4604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'igrp' modifier applied to %s", typestr);
4605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_PIM:
4607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'pim' modifier applied to %s", typestr);
4608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_VRRP:
4610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'vrrp' modifier applied to %s", typestr);
4611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4612511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_CARP:
4613511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'carp' modifier applied to %s", typestr);
4614511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ATALK:
4616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("ATALK host filtering not implemented");
4617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AARP:
4619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("AARP host filtering not implemented");
4620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DECNET:
4622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'decnet' modifier applied to ip6 %s", typestr);
4623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SCA:
4625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("SCA host filtering not implemented");
4626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_LAT:
4628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("LAT host filtering not implemented");
4629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_MOPDL:
4631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("MOPDL host filtering not implemented");
4632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_MOPRC:
4634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("MOPRC host filtering not implemented");
4635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IPV6:
4637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_hostop6(addr, mask, dir, ETHERTYPE_IPV6, 8, 24);
4638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ICMPV6:
4640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'icmp6' modifier applied to %s", typestr);
4641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AH:
4643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'ah' modifier applied to %s", typestr);
4644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ESP:
4646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'esp' modifier applied to %s", typestr);
4647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ISO:
4649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("ISO host filtering not implemented");
4650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ESIS:
4652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'esis' modifier applied to %s", typestr);
4653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ISIS:
4655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'isis' modifier applied to %s", typestr);
4656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_CLNP:
4658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'clnp' modifier applied to %s", typestr);
4659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_STP:
4661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'stp' modifier applied to %s", typestr);
4662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IPX:
4664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("IPX host filtering not implemented");
4665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_NETBEUI:
4667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'netbeui' modifier applied to %s", typestr);
4668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_RADIO:
4670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'radio' modifier applied to %s", typestr);
4671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
4673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
4674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
4675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
4676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
4677511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
4678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef INET6
4680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
4681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_gateway(eaddr, alist, proto, dir)
4682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	const u_char *eaddr;
4683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 **alist;
4684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int proto;
4685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int dir;
4686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
4687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1, *tmp;
4688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (dir != 0)
4690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("direction applied to 'gateway'");
4691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (proto) {
4693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
4694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IP:
4695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ARP:
4696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_RARP:
4697511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		switch (linktype) {
4698511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_EN10MB:
4699511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_NETANALYZER:
4700511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_NETANALYZER_TRANSPARENT:
4701511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b0 = gen_ehostop(eaddr, Q_OR);
4702511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
4703511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_FDDI:
4704511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b0 = gen_fhostop(eaddr, Q_OR);
4705511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
4706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case DLT_IEEE802:
4707511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b0 = gen_thostop(eaddr, Q_OR);
4708511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
4709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case DLT_IEEE802_11:
4710511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_PRISM_HEADER:
4711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case DLT_IEEE802_11_RADIO_AVS:
4712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case DLT_IEEE802_11_RADIO:
4713511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_PPI:
4714511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b0 = gen_wlanhostop(eaddr, Q_OR);
4715511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
4716511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_SUNATM:
4717511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (!is_lane)
4718511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				bpf_error(
4719511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    "'gateway' supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
4720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
4721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Check that the packet doesn't begin with an
4722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * LE Control marker.  (We've already generated
4723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * a test for LANE.)
4724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
4725511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS,
4726511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    BPF_H, 0xFF00);
4727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_not(b1);
4728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
4730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Now check the MAC address.
4731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
4732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b0 = gen_ehostop(eaddr, Q_OR);
4733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_and(b1, b0);
4734511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
4735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case DLT_IP_OVER_FC:
4736511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b0 = gen_ipfchostop(eaddr, Q_OR);
4737511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
4738511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		default:
4739511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			bpf_error(
4740511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    "'gateway' supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
4741511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
4742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR, Q_HOST);
4743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		while (*alist) {
4744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			tmp = gen_host(**alist++, 0xffffffff, proto, Q_OR,
4745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    Q_HOST);
4746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_or(b1, tmp);
4747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b1 = tmp;
4748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
4749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_not(b1);
4750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
4751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
4752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
4753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_error("illegal modifier of 'gateway'");
4754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
4755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
4756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
4757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
4759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_proto_abbrev(proto)
4760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int proto;
4761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
4762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0;
4763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b1;
4764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (proto) {
4766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SCTP:
4768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(IPPROTO_SCTP, Q_IP, Q_DEFAULT);
4769478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(IPPROTO_SCTP, Q_IPV6, Q_DEFAULT);
4770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_TCP:
4774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(IPPROTO_TCP, Q_IP, Q_DEFAULT);
4775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(IPPROTO_TCP, Q_IPV6, Q_DEFAULT);
4776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_UDP:
4780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(IPPROTO_UDP, Q_IP, Q_DEFAULT);
4781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(IPPROTO_UDP, Q_IPV6, Q_DEFAULT);
4782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ICMP:
4786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(IPPROTO_ICMP, Q_IP, Q_DEFAULT);
4787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef	IPPROTO_IGMP
4790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define	IPPROTO_IGMP	2
4791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
4792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IGMP:
4794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(IPPROTO_IGMP, Q_IP, Q_DEFAULT);
4795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef	IPPROTO_IGRP
4798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define	IPPROTO_IGRP	9
4799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
4800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IGRP:
4801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(IPPROTO_IGRP, Q_IP, Q_DEFAULT);
4802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_PIM
4805478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_PIM	103
4806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
4807478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_PIM:
4809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(IPPROTO_PIM, Q_IP, Q_DEFAULT);
4810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(IPPROTO_PIM, Q_IPV6, Q_DEFAULT);
4811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_VRRP
4815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_VRRP	112
4816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
4817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4818478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_VRRP:
4819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(IPPROTO_VRRP, Q_IP, Q_DEFAULT);
4820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4822511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef IPPROTO_CARP
4823511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IPPROTO_CARP	112
4824511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
4825511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4826511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_CARP:
4827511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = gen_proto(IPPROTO_CARP, Q_IP, Q_DEFAULT);
4828511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
4829511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
4830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IP:
4831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 =  gen_linktype(ETHERTYPE_IP);
4832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ARP:
4835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 =  gen_linktype(ETHERTYPE_ARP);
4836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_RARP:
4839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 =  gen_linktype(ETHERTYPE_REVARP);
4840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_LINK:
4843478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("link layer applied in wrong context");
4844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ATALK:
4846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 =  gen_linktype(ETHERTYPE_ATALK);
4847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4849478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AARP:
4850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 =  gen_linktype(ETHERTYPE_AARP);
4851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4852478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DECNET:
4854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 =  gen_linktype(ETHERTYPE_DN);
4855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SCA:
4858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 =  gen_linktype(ETHERTYPE_SCA);
4859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_LAT:
4862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 =  gen_linktype(ETHERTYPE_LAT);
4863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_MOPDL:
4866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 =  gen_linktype(ETHERTYPE_MOPDL);
4867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_MOPRC:
4870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 =  gen_linktype(ETHERTYPE_MOPRC);
4871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IPV6:
4874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_linktype(ETHERTYPE_IPV6);
4875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_ICMPV6
4878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_ICMPV6	58
4879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
4880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ICMPV6:
4881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(IPPROTO_ICMPV6, Q_IPV6, Q_DEFAULT);
4882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_AH
4885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_AH	51
4886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
4887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AH:
4888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(IPPROTO_AH, Q_IP, Q_DEFAULT);
4889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(IPPROTO_AH, Q_IPV6, Q_DEFAULT);
4890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_ESP
4894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_ESP	50
4895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
4896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ESP:
4897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(IPPROTO_ESP, Q_IP, Q_DEFAULT);
4898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(IPPROTO_ESP, Q_IPV6, Q_DEFAULT);
4899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ISO:
4903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_linktype(LLCSAP_ISONS);
4904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ESIS:
4907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(ISO9542_ESIS, Q_ISO, Q_DEFAULT);
4908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4910478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ISIS:
4911478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT);
4912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4914478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ISIS_L1: /* all IS-IS Level1 PDU-Types */
4915478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT);
4916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */
4917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT);
4919478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4920478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
4921478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
4923478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4924478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4925478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4926478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ISIS_L2: /* all IS-IS Level2 PDU-Types */
4927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT);
4928478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */
4929478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT);
4931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4932478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
4933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
4935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ISIS_IIH: /* all IS-IS Hello PDU-Types */
4939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT);
4940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT);
4941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT);
4943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ISIS_LSP:
4947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT);
4948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT);
4949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ISIS_SNP:
4953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
4954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
4955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
4957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
4959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ISIS_CSNP:
4963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
4964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
4965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ISIS_PSNP:
4969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
4970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
4971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
4972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_CLNP:
4975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(ISO8473_CLNP, Q_ISO, Q_DEFAULT);
4976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_STP:
4979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_linktype(LLCSAP_8021D);
4980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4981478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IPX:
4983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_linktype(LLCSAP_IPX);
4984478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_NETBEUI:
4987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_linktype(LLCSAP_NETBEUI);
4988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
4989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_RADIO:
4991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'radio' is not a valid protocol type");
4992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
4994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
4995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
4996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b1;
4997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
4998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
4999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
5000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ipfrag()
5001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
5002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s;
5003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b;
5004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5005511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/* not IPv4 frag other than the first frag */
5006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s = gen_load_a(OR_NET, 6, BPF_H);
5007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b = new_block(JMP(BPF_JSET));
5008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b->s.k = 0x1fff;
5009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b->stmts = s;
5010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_not(b);
5011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b;
5013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
5014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
5016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate a comparison to a port value in the transport-layer header
5017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * at the specified offset from the beginning of that header.
5018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
5019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - this handles a variable-length prefix preceding the link-layer
5020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header, such as the radiotap or AVS radio prefix, but doesn't handle
5021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * variable-length link-layer headers (such as Token Ring or 802.11
5022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * headers).
5023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
5024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
5025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portatom(off, v)
5026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int off;
5027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_int32 v;
5028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
5029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return gen_cmp(OR_TRAN_IPV4, off, BPF_H, v);
5030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
5031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
5033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portatom6(off, v)
5034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int off;
5035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_int32 v;
5036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
5037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return gen_cmp(OR_TRAN_IPV6, off, BPF_H, v);
5038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
5039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
5041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portop(port, proto, dir)
5042478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int port, proto, dir;
5043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
5044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1, *tmp;
5045478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5046511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/* ip proto 'proto' and not a fragment other than the first fragment */
5047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	tmp = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)proto);
5048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 = gen_ipfrag();
5049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(tmp, b0);
5050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (dir) {
5052478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SRC:
5053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portatom(0, (bpf_int32)port);
5054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DST:
5057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portatom(2, (bpf_int32)port);
5058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_OR:
5061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
5062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_portatom(0, (bpf_int32)port);
5063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portatom(2, (bpf_int32)port);
5064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(tmp, b1);
5065478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5066478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AND:
5068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_portatom(0, (bpf_int32)port);
5069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portatom(2, (bpf_int32)port);
5070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(tmp, b1);
5071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
5074478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
5075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
5076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(b0, b1);
5077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5078478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b1;
5079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
5080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
5082478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_port(port, ip_proto, dir)
5083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int port;
5084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int ip_proto;
5085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int dir;
5086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
5087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1, *tmp;
5088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
5090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * ether proto ip
5091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 *
5092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * For FDDI, RFC 1188 says that SNAP encapsulation is used,
5093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * not LLC encapsulation with LLCSAP_IP.
5094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 *
5095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * For IEEE 802 networks - which includes 802.5 token ring
5096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * (which is what DLT_IEEE802 means) and 802.11 - RFC 1042
5097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * says that SNAP encapsulation is used, not LLC encapsulation
5098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * with LLCSAP_IP.
5099478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 *
5100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * For LLC-encapsulated ATM/"Classical IP", RFC 1483 and
5101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * RFC 2225 say that SNAP encapsulation is used, not LLC
5102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * encapsulation with LLCSAP_IP.
5103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 *
5104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * So we always check for ETHERTYPE_IP.
5105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
5106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 =  gen_linktype(ETHERTYPE_IP);
5107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (ip_proto) {
5109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case IPPROTO_UDP:
5110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case IPPROTO_TCP:
5111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case IPPROTO_SCTP:
5112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portop(port, ip_proto, dir);
5113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case PROTO_UNDEF:
5116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_portop(port, IPPROTO_TCP, dir);
5117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portop(port, IPPROTO_UDP, dir);
5118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(tmp, b1);
5119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_portop(port, IPPROTO_SCTP, dir);
5120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(tmp, b1);
5121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
5124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
5125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
5126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(b0, b1);
5127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b1;
5128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
5129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
5131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portop6(port, proto, dir)
5132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int port, proto, dir;
5133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
5134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1, *tmp;
5135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* ip6 proto 'proto' */
5137511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/* XXX - catch the first fragment of a fragmented packet? */
5138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)proto);
5139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (dir) {
5141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SRC:
5142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portatom6(0, (bpf_int32)port);
5143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DST:
5146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portatom6(2, (bpf_int32)port);
5147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_OR:
5150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
5151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_portatom6(0, (bpf_int32)port);
5152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portatom6(2, (bpf_int32)port);
5153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(tmp, b1);
5154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AND:
5157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_portatom6(0, (bpf_int32)port);
5158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portatom6(2, (bpf_int32)port);
5159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(tmp, b1);
5160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
5163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
5164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
5165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(b0, b1);
5166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b1;
5168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
5169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
5171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_port6(port, ip_proto, dir)
5172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int port;
5173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int ip_proto;
5174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int dir;
5175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
5176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1, *tmp;
5177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* link proto ip6 */
5179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 =  gen_linktype(ETHERTYPE_IPV6);
5180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (ip_proto) {
5182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case IPPROTO_UDP:
5183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case IPPROTO_TCP:
5184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case IPPROTO_SCTP:
5185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portop6(port, ip_proto, dir);
5186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case PROTO_UNDEF:
5189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_portop6(port, IPPROTO_TCP, dir);
5190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portop6(port, IPPROTO_UDP, dir);
5191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(tmp, b1);
5192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_portop6(port, IPPROTO_SCTP, dir);
5193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(tmp, b1);
5194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
5197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
5198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
5199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(b0, b1);
5200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b1;
5201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
5202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* gen_portrange code */
5204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
5205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portrangeatom(off, v1, v2)
5206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int off;
5207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_int32 v1, v2;
5208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
5209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b1, *b2;
5210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (v1 > v2) {
5212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
5213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Reverse the order of the ports, so v1 is the lower one.
5214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
5215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_int32 vtemp;
5216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		vtemp = v1;
5218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		v1 = v2;
5219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		v2 = vtemp;
5220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
5221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b1 = gen_cmp_ge(OR_TRAN_IPV4, off, BPF_H, v1);
5223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b2 = gen_cmp_le(OR_TRAN_IPV4, off, BPF_H, v2);
5224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(b1, b2);
5226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b2;
5228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
5229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
5231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portrangeop(port1, port2, proto, dir)
5232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int port1, port2;
5233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int proto;
5234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int dir;
5235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
5236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1, *tmp;
5237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5238511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/* ip proto 'proto' and not a fragment other than the first fragment */
5239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	tmp = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)proto);
5240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 = gen_ipfrag();
5241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(tmp, b0);
5242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (dir) {
5244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SRC:
5245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portrangeatom(0, (bpf_int32)port1, (bpf_int32)port2);
5246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DST:
5249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portrangeatom(2, (bpf_int32)port1, (bpf_int32)port2);
5250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_OR:
5253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
5254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_portrangeatom(0, (bpf_int32)port1, (bpf_int32)port2);
5255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portrangeatom(2, (bpf_int32)port1, (bpf_int32)port2);
5256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(tmp, b1);
5257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AND:
5260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_portrangeatom(0, (bpf_int32)port1, (bpf_int32)port2);
5261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portrangeatom(2, (bpf_int32)port1, (bpf_int32)port2);
5262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(tmp, b1);
5263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
5266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
5267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
5268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(b0, b1);
5269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b1;
5271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
5272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
5274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portrange(port1, port2, ip_proto, dir)
5275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int port1, port2;
5276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int ip_proto;
5277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int dir;
5278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
5279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1, *tmp;
5280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* link proto ip */
5282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 =  gen_linktype(ETHERTYPE_IP);
5283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (ip_proto) {
5285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case IPPROTO_UDP:
5286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case IPPROTO_TCP:
5287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case IPPROTO_SCTP:
5288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portrangeop(port1, port2, ip_proto, dir);
5289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case PROTO_UNDEF:
5292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_portrangeop(port1, port2, IPPROTO_TCP, dir);
5293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portrangeop(port1, port2, IPPROTO_UDP, dir);
5294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(tmp, b1);
5295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_portrangeop(port1, port2, IPPROTO_SCTP, dir);
5296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(tmp, b1);
5297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
5300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
5301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
5302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(b0, b1);
5303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b1;
5304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
5305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
5307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portrangeatom6(off, v1, v2)
5308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int off;
5309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_int32 v1, v2;
5310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
5311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b1, *b2;
5312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (v1 > v2) {
5314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
5315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Reverse the order of the ports, so v1 is the lower one.
5316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
5317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_int32 vtemp;
5318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		vtemp = v1;
5320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		v1 = v2;
5321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		v2 = vtemp;
5322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
5323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b1 = gen_cmp_ge(OR_TRAN_IPV6, off, BPF_H, v1);
5325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b2 = gen_cmp_le(OR_TRAN_IPV6, off, BPF_H, v2);
5326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(b1, b2);
5328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b2;
5330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
5331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
5333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portrangeop6(port1, port2, proto, dir)
5334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int port1, port2;
5335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int proto;
5336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int dir;
5337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
5338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1, *tmp;
5339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* ip6 proto 'proto' */
5341511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/* XXX - catch the first fragment of a fragmented packet? */
5342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)proto);
5343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (dir) {
5345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SRC:
5346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portrangeatom6(0, (bpf_int32)port1, (bpf_int32)port2);
5347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DST:
5350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portrangeatom6(2, (bpf_int32)port1, (bpf_int32)port2);
5351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_OR:
5354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
5355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_portrangeatom6(0, (bpf_int32)port1, (bpf_int32)port2);
5356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portrangeatom6(2, (bpf_int32)port1, (bpf_int32)port2);
5357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(tmp, b1);
5358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AND:
5361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_portrangeatom6(0, (bpf_int32)port1, (bpf_int32)port2);
5362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portrangeatom6(2, (bpf_int32)port1, (bpf_int32)port2);
5363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(tmp, b1);
5364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
5367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
5368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
5369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(b0, b1);
5370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b1;
5372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
5373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
5375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_portrange6(port1, port2, ip_proto, dir)
5376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int port1, port2;
5377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int ip_proto;
5378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	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 */
5383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 =  gen_linktype(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:
5389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portrangeop6(port1, port2, ip_proto, dir);
5390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case PROTO_UNDEF:
5393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_portrangeop6(port1, port2, IPPROTO_TCP, dir);
5394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_portrangeop6(port1, port2, IPPROTO_UDP, dir);
5395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(tmp, b1);
5396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = gen_portrangeop6(port1, port2, 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 Projectstatic int
5408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectlookup_proto(name, proto)
5409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register const char *name;
5410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register int proto;
5411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
5412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register int v;
5413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (proto) {
5415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
5417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IP:
5418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IPV6:
5419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		v = pcap_nametoproto(name);
5420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (v == PROTO_UNDEF)
5421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("unknown ip proto '%s'", name);
5422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_LINK:
5425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* XXX should look up h/w protocol type based on linktype */
5426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		v = pcap_nametoeproto(name);
5427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (v == PROTO_UNDEF) {
5428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			v = pcap_nametollc(name);
5429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (v == PROTO_UNDEF)
5430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				bpf_error("unknown ether proto '%s'", name);
5431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
5432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ISO:
5435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (strcmp(name, "esis") == 0)
5436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			v = ISO9542_ESIS;
5437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else if (strcmp(name, "isis") == 0)
5438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			v = ISO10589_ISIS;
5439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else if (strcmp(name, "clnp") == 0)
5440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			v = ISO8473_CLNP;
5441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else
5442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("unknown osi proto '%s'", name);
5443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
5446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		v = PROTO_UNDEF;
5447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
5449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return v;
5450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
5451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if 0
5453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct stmt *
5454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_joinsp(s, n)
5455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct stmt **s;
5456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int n;
5457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
5458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return NULL;
5459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
5460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
5461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
5463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_protochain(v, proto, dir)
5464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int v;
5465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int proto;
5466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int dir;
5467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
5468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef NO_PROTOCHAIN
5469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return gen_proto(v, proto, dir);
5470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
5471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b;
5472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s[100];
5473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int fix2, fix3, fix4, fix5;
5474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int ahcheck, again, end;
5475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int i, max;
5476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int reg2 = alloc_reg();
5477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	memset(s, 0, sizeof(s));
5479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	fix2 = fix3 = fix4 = fix5 = 0;
5480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (proto) {
5482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IP:
5483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IPV6:
5484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
5486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_protochain(v, Q_IP, dir);
5487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b = gen_protochain(v, Q_IPV6, dir);
5488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b);
5489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b;
5490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
5491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("bad protocol applied for 'protochain'");
5492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*NOTREACHED*/
5493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
5494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
5496511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * We don't handle variable-length prefixes before the link-layer
5497511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * header, or variable-length link-layer headers, here yet.
5498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * We might want to add BPF instructions to do the protochain
5499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * work, to simplify that and, on platforms that have a BPF
5500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * interpreter with the new instructions, let the filtering
5501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * be done in the kernel.  (We already require a modified BPF
5502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * engine to do the protochain stuff, to support backward
5503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * branches, and backward branch support is unlikely to appear
5504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * in kernel BPF engines.)
5505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
5506511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	switch (linktype) {
5507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5508511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_11:
5509511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_PRISM_HEADER:
5510511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_11_RADIO_AVS:
5511511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_11_RADIO:
5512511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_PPI:
5513511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'protochain' not supported with 802.11");
5514511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
5515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	no_optimize = 1; /*this code is not compatible with optimzer yet */
5517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
5519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * s[0] is a dummy entry to protect other BPF insn from damage
5520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * by s[fix] = foo with uninitialized variable "fix".  It is somewhat
5521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * hard to find interdependency made by jump table fixup.
5522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
5523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	i = 0;
5524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i] = new_stmt(0);	/*dummy*/
5525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	i++;
5526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (proto) {
5528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IP:
5529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_linktype(ETHERTYPE_IP);
5530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* A = ip->ip_p */
5532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B);
5533511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s[i]->s.k = off_macpl + off_nl + 9;
5534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		i++;
5535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* X = ip->ip_hl << 2 */
5536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i] = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
5537511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s[i]->s.k = off_macpl + off_nl;
5538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		i++;
5539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5540511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
5541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IPV6:
5542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_linktype(ETHERTYPE_IPV6);
5543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* A = ip6->ip_nxt */
5545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B);
5546511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s[i]->s.k = off_macpl + off_nl + 6;
5547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		i++;
5548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* X = sizeof(struct ip6_hdr) */
5549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i] = new_stmt(BPF_LDX|BPF_IMM);
5550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.k = 40;
5551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		i++;
5552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
5553511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
5554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
5555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("unsupported proto to gen_protochain");
5556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*NOTREACHED*/
5557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
5558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* again: if (A == v) goto end; else fall through; */
5560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	again = i;
5561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
5562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i]->s.k = v;
5563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i]->s.jt = NULL;		/*later*/
5564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i]->s.jf = NULL;		/*update in next stmt*/
5565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	fix5 = i;
5566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	i++;
5567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef IPPROTO_NONE
5569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IPPROTO_NONE	59
5570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
5571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* if (A == IPPROTO_NONE) goto end */
5572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
5573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i]->s.jt = NULL;	/*later*/
5574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i]->s.jf = NULL;	/*update in next stmt*/
5575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i]->s.k = IPPROTO_NONE;
5576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[fix5]->s.jf = s[i];
5577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	fix2 = i;
5578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	i++;
5579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (proto == Q_IPV6) {
5581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		int v6start, v6end, v6advance, j;
5582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		v6start = i;
5584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* if (A == IPPROTO_HOPOPTS) goto v6advance */
5585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
5586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.jt = NULL;	/*later*/
5587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.jf = NULL;	/*update in next stmt*/
5588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.k = IPPROTO_HOPOPTS;
5589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[fix2]->s.jf = s[i];
5590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		i++;
5591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* if (A == IPPROTO_DSTOPTS) goto v6advance */
5592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
5593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.jt = NULL;	/*later*/
5594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.jf = NULL;	/*update in next stmt*/
5595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.k = IPPROTO_DSTOPTS;
5596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		i++;
5597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* if (A == IPPROTO_ROUTING) goto v6advance */
5598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
5599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.jt = NULL;	/*later*/
5600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.jf = NULL;	/*update in next stmt*/
5601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.k = IPPROTO_ROUTING;
5602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		i++;
5603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* if (A == IPPROTO_FRAGMENT) goto v6advance; else goto ahcheck; */
5604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
5605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.jt = NULL;	/*later*/
5606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.jf = NULL;	/*later*/
5607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.k = IPPROTO_FRAGMENT;
5608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		fix3 = i;
5609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		v6end = i;
5610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		i++;
5611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* v6advance: */
5613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		v6advance = i;
5614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
5616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * in short,
5617511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * A = P[X + packet head];
5618511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * X = X + (P[X + packet head + 1] + 1) * 8;
5619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
5620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* A = P[X + packet head] */
5621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
5622511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s[i]->s.k = off_macpl + off_nl;
5623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		i++;
5624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* MEM[reg2] = A */
5625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i] = new_stmt(BPF_ST);
5626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.k = reg2;
5627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		i++;
5628511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* A = P[X + packet head + 1]; */
5629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
5630511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s[i]->s.k = off_macpl + off_nl + 1;
5631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		i++;
5632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* A += 1 */
5633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
5634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.k = 1;
5635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		i++;
5636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* A *= 8 */
5637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K);
5638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.k = 8;
5639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		i++;
5640511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* A += X */
5641511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_X);
5642511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s[i]->s.k = 0;
5643511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		i++;
5644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* X = A; */
5645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i] = new_stmt(BPF_MISC|BPF_TAX);
5646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		i++;
5647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* A = MEM[reg2] */
5648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i] = new_stmt(BPF_LD|BPF_MEM);
5649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.k = reg2;
5650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		i++;
5651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* goto again; (must use BPF_JA for backward jump) */
5653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i] = new_stmt(BPF_JMP|BPF_JA);
5654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.k = again - i - 1;
5655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i - 1]->s.jf = s[i];
5656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		i++;
5657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* fixup */
5659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		for (j = v6start; j <= v6end; j++)
5660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			s[j]->s.jt = s[v6advance];
5661511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	} else {
5662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* nop */
5663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
5664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->s.k = 0;
5665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[fix2]->s.jf = s[i];
5666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		i++;
5667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
5668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* ahcheck: */
5670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ahcheck = i;
5671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* if (A == IPPROTO_AH) then fall through; else goto end; */
5672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
5673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i]->s.jt = NULL;	/*later*/
5674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i]->s.jf = NULL;	/*later*/
5675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i]->s.k = IPPROTO_AH;
5676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (fix3)
5677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[fix3]->s.jf = s[ahcheck];
5678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	fix4 = i;
5679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	i++;
5680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
5682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * in short,
5683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * A = P[X];
5684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * X = X + (P[X + 1] + 2) * 4;
5685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
5686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* A = X */
5687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i - 1]->s.jt = s[i] = new_stmt(BPF_MISC|BPF_TXA);
5688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	i++;
5689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* A = P[X + packet head]; */
5690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
5691511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s[i]->s.k = off_macpl + off_nl;
5692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	i++;
5693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* MEM[reg2] = A */
5694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i] = new_stmt(BPF_ST);
5695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i]->s.k = reg2;
5696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	i++;
5697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* A = X */
5698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i - 1]->s.jt = s[i] = new_stmt(BPF_MISC|BPF_TXA);
5699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	i++;
5700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* A += 1 */
5701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
5702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i]->s.k = 1;
5703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	i++;
5704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* X = A */
5705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i] = new_stmt(BPF_MISC|BPF_TAX);
5706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	i++;
5707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* A = P[X + packet head] */
5708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
5709511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s[i]->s.k = off_macpl + off_nl;
5710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	i++;
5711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* A += 2 */
5712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
5713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i]->s.k = 2;
5714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	i++;
5715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* A *= 4 */
5716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K);
5717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i]->s.k = 4;
5718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	i++;
5719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* X = A; */
5720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i] = new_stmt(BPF_MISC|BPF_TAX);
5721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	i++;
5722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* A = MEM[reg2] */
5723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i] = new_stmt(BPF_LD|BPF_MEM);
5724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i]->s.k = reg2;
5725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	i++;
5726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* goto again; (must use BPF_JA for backward jump) */
5728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i] = new_stmt(BPF_JMP|BPF_JA);
5729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i]->s.k = again - i - 1;
5730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	i++;
5731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* end: nop */
5733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	end = i;
5734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
5735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[i]->s.k = 0;
5736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[fix2]->s.jt = s[end];
5737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[fix4]->s.jf = s[end];
5738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[fix5]->s.jt = s[end];
5739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	i++;
5740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
5742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * make slist chain
5743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
5744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	max = i;
5745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	for (i = 0; i < max - 1; i++)
5746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s[i]->next = s[i + 1];
5747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s[max - 1]->next = NULL;
5748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
5750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * emit final check
5751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
5752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b = new_block(JMP(BPF_JEQ));
5753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b->stmts = s[1];	/*remember, s[0] is dummy*/
5754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b->s.k = v;
5755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	free_reg(reg2);
5757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_and(b0, b);
5759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b;
5760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
5761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
5762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5763511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct block *
5764511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_check_802_11_data_frame()
5765511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
5766511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct slist *s;
5767511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct block *b0, *b1;
5768511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
5769511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
5770511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * A data frame has the 0x08 bit (b3) in the frame control field set
5771511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * and the 0x04 bit (b2) clear.
5772511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
5773511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s = gen_load_a(OR_LINK, 0, BPF_B);
5774511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	b0 = new_block(JMP(BPF_JSET));
5775511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	b0->s.k = 0x08;
5776511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	b0->stmts = s;
5777511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
5778511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	s = gen_load_a(OR_LINK, 0, BPF_B);
5779511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	b1 = new_block(JMP(BPF_JSET));
5780511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	b1->s.k = 0x04;
5781511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	b1->stmts = s;
5782511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	gen_not(b1);
5783511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
5784511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	gen_and(b1, b0);
5785511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
5786511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return b0;
5787511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
5788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
5790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code that checks whether the packet is a packet for protocol
5791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * <proto> and whether the type field in that protocol's header has
5792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the value <v>, e.g. if <proto> is Q_IP, it checks whether it's an
5793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * IP packet and checks the protocol number in the IP header against <v>.
5794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
5795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If <proto> is Q_DEFAULT, i.e. just "proto" was specified, it checks
5796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * against Q_IP and Q_IPV6.
5797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
5798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
5799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_proto(v, proto, dir)
5800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int v;
5801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int proto;
5802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int dir;
5803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
5804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1;
5805511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef CHASE_CHAIN
5806511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct block *b2;
5807511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
5808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (dir != Q_DEFAULT)
5810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("direction applied to 'proto'");
5811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (proto) {
5813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
5814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(v, Q_IP, dir);
5815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_proto(v, Q_IPV6, dir);
5816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
5817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
5818511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
5819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IP:
5820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
5821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * For FDDI, RFC 1188 says that SNAP encapsulation is used,
5822478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * not LLC encapsulation with LLCSAP_IP.
5823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
5824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * For IEEE 802 networks - which includes 802.5 token ring
5825478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * (which is what DLT_IEEE802 means) and 802.11 - RFC 1042
5826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * says that SNAP encapsulation is used, not LLC encapsulation
5827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * with LLCSAP_IP.
5828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
5829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * For LLC-encapsulated ATM/"Classical IP", RFC 1483 and
5830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * RFC 2225 say that SNAP encapsulation is used, not LLC
5831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * encapsulation with LLCSAP_IP.
5832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
5833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * So we always check for ETHERTYPE_IP.
5834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
5835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_linktype(ETHERTYPE_IP);
5836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef CHASE_CHAIN
5837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)v);
5838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
5839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_protochain(v, Q_IP);
5840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
5841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
5842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
5843478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ISO:
5845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		switch (linktype) {
5846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case DLT_FRELAY:
5848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
5849478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Frame Relay packets typically have an OSI
5850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * NLPID at the beginning; "gen_linktype(LLCSAP_ISONS)"
5851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * generates code to check for all the OSI
5852478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * NLPIDs, so calling it and then adding a check
5853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * for the particular NLPID for which we're
5854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * looking is bogus, as we can just check for
5855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * the NLPID.
5856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 *
5857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * What we check for is the NLPID and a frame
5858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * control field value of UI, i.e. 0x03 followed
5859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * by the NLPID.
5860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 *
5861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * XXX - assumes a 2-byte Frame Relay header with
5862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * DLCI and flags.  What if the address is longer?
5863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 *
5864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * XXX - what about SNAP-encapsulated frames?
5865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
5866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | v);
5867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*NOTREACHED*/
5868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
5869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case DLT_C_HDLC:
5871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
5872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Cisco uses an Ethertype lookalike - for OSI,
5873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * it's 0xfefe.
5874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
5875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b0 = gen_linktype(LLCSAP_ISONS<<8 | LLCSAP_ISONS);
5876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* OSI in C-HDLC is stuffed with a fudge byte */
5877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b1 = gen_cmp(OR_NET_NOSNAP, 1, BPF_B, (long)v);
5878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_and(b0, b1);
5879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return b1;
5880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		default:
5882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b0 = gen_linktype(LLCSAP_ISONS);
5883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b1 = gen_cmp(OR_NET_NOSNAP, 0, BPF_B, (long)v);
5884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_and(b0, b1);
5885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return b1;
5886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
5887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ISIS:
5889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT);
5890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
5891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * 4 is the offset of the PDU type relative to the IS-IS
5892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * header.
5893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
5894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_cmp(OR_NET_NOSNAP, 4, BPF_B, (long)v);
5895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
5896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
5897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ARP:
5899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("arp does not encapsulate another protocol");
5900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
5901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_RARP:
5903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("rarp does not encapsulate another protocol");
5904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
5905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ATALK:
5907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("atalk encapsulation is not specifiable");
5908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
5909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5910478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DECNET:
5911478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("decnet encapsulation is not specifiable");
5912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
5913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5914478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SCA:
5915478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("sca does not encapsulate another protocol");
5916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
5917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_LAT:
5919478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("lat does not encapsulate another protocol");
5920478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
5921478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_MOPRC:
5923478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("moprc does not encapsulate another protocol");
5924478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
5925478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5926478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_MOPDL:
5927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("mopdl does not encapsulate another protocol");
5928478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
5929478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_LINK:
5931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_linktype(v);
5932478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_UDP:
5934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'udp proto' is bogus");
5935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
5936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_TCP:
5938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'tcp proto' is bogus");
5939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
5940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SCTP:
5942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'sctp proto' is bogus");
5943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
5944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ICMP:
5946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'icmp proto' is bogus");
5947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
5948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IGMP:
5950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'igmp proto' is bogus");
5951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
5952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IGRP:
5954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'igrp proto' is bogus");
5955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
5956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_PIM:
5958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'pim proto' is bogus");
5959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
5960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_VRRP:
5962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'vrrp proto' is bogus");
5963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
5964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5965511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_CARP:
5966511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'carp proto' is bogus");
5967511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* NOTREACHED */
5968511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
5969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IPV6:
5970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_linktype(ETHERTYPE_IPV6);
5971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef CHASE_CHAIN
5972511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
5973511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Also check for a fragment header before the final
5974511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * header.
5975511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
5976511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b2 = gen_cmp(OR_NET, 6, BPF_B, IPPROTO_FRAGMENT);
5977511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = gen_cmp(OR_NET, 40, BPF_B, (bpf_int32)v);
5978511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_and(b2, b1);
5979511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b2 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)v);
5980511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_or(b2, b1);
5981478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
5982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_protochain(v, Q_IPV6);
5983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
5984478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
5985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
5986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ICMPV6:
5988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'icmp6 proto' is bogus");
5989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AH:
5991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'ah proto' is bogus");
5992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ESP:
5994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'ah proto' is bogus");
5995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_STP:
5997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'stp proto' is bogus");
5998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
5999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IPX:
6000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'ipx proto' is bogus");
6001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_NETBEUI:
6003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'netbeui proto' is bogus");
6004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_RADIO:
6006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'radio proto' is bogus");
6007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
6009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
6010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
6011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
6012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
6013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
6014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
6016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_scode(name, q)
6017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register const char *name;
6018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct qual q;
6019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
6020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int proto = q.proto;
6021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int dir = q.dir;
6022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int tproto;
6023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_char *eaddr;
6024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 mask, addr;
6025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef INET6
6026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 **alist;
6027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
6028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int tproto6;
6029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct sockaddr_in *sin4;
6030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct sockaddr_in6 *sin6;
6031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct addrinfo *res, *res0;
6032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct in6_addr mask128;
6033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /*INET6*/
6034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b, *tmp;
6035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int port, real_proto;
6036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int port1, port2;
6037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (q.addr) {
6039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_NET:
6041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		addr = pcap_nametonetaddr(name);
6042478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (addr == 0)
6043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("unknown network '%s'", name);
6044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Left justify network addr and calculate its network mask */
6045478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		mask = 0xffffffff;
6046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		while (addr && (addr & 0xff000000) == 0) {
6047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			addr <<= 8;
6048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			mask <<= 8;
6049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
6050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_host(addr, mask, proto, dir, q.addr);
6051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6052478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
6053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_HOST:
6054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (proto == Q_LINK) {
6055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			switch (linktype) {
6056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			case DLT_EN10MB:
6058511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			case DLT_NETANALYZER:
6059511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			case DLT_NETANALYZER_TRANSPARENT:
6060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				eaddr = pcap_ether_hostton(name);
6061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				if (eaddr == NULL)
6062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					bpf_error(
6063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    "unknown ether host '%s'", name);
6064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				b = gen_ehostop(eaddr, dir);
6065478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				free(eaddr);
6066478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				return b;
6067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			case DLT_FDDI:
6069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				eaddr = pcap_ether_hostton(name);
6070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				if (eaddr == NULL)
6071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					bpf_error(
6072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    "unknown FDDI host '%s'", name);
6073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				b = gen_fhostop(eaddr, dir);
6074478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				free(eaddr);
6075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				return b;
6076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			case DLT_IEEE802:
6078478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				eaddr = pcap_ether_hostton(name);
6079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				if (eaddr == NULL)
6080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					bpf_error(
6081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    "unknown token ring host '%s'", name);
6082478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				b = gen_thostop(eaddr, dir);
6083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				free(eaddr);
6084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				return b;
6085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			case DLT_IEEE802_11:
6087511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			case DLT_PRISM_HEADER:
6088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			case DLT_IEEE802_11_RADIO_AVS:
6089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			case DLT_IEEE802_11_RADIO:
6090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			case DLT_PPI:
6091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				eaddr = pcap_ether_hostton(name);
6092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				if (eaddr == NULL)
6093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					bpf_error(
6094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    "unknown 802.11 host '%s'", name);
6095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				b = gen_wlanhostop(eaddr, dir);
6096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				free(eaddr);
6097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				return b;
6098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6099478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			case DLT_IP_OVER_FC:
6100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				eaddr = pcap_ether_hostton(name);
6101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				if (eaddr == NULL)
6102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					bpf_error(
6103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    "unknown Fibre Channel host '%s'", name);
6104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				b = gen_ipfchostop(eaddr, dir);
6105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				free(eaddr);
6106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				return b;
6107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			case DLT_SUNATM:
6109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				if (!is_lane)
6110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					break;
6111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/*
6113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 * Check that the packet doesn't begin
6114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 * with an LE Control marker.  (We've
6115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 * already generated a test for LANE.)
6116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 */
6117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				tmp = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS,
6118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				    BPF_H, 0xFF00);
6119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				gen_not(tmp);
6120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				eaddr = pcap_ether_hostton(name);
6122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				if (eaddr == NULL)
6123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					bpf_error(
6124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    "unknown ether host '%s'", name);
6125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				b = gen_ehostop(eaddr, dir);
6126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				gen_and(tmp, b);
6127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				free(eaddr);
6128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				return b;
6129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
6130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("only ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel supports link-level host name");
6132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else if (proto == Q_DECNET) {
6133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			unsigned short dn_addr = __pcap_nametodnaddr(name);
6134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
6135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * I don't think DECNET hosts can be multihomed, so
6136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * there is no need to build up a list of addresses
6137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
6138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return (gen_host(dn_addr, 0, proto, dir, q.addr));
6139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else {
6140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef INET6
6141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			alist = pcap_nametoaddr(name);
6142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (alist == NULL || *alist == NULL)
6143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				bpf_error("unknown host '%s'", name);
6144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			tproto = proto;
6145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (off_linktype == (u_int)-1 && tproto == Q_DEFAULT)
6146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				tproto = Q_IP;
6147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b = gen_host(**alist++, 0xffffffff, tproto, dir, q.addr);
6148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			while (*alist) {
6149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				tmp = gen_host(**alist++, 0xffffffff,
6150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					       tproto, dir, q.addr);
6151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				gen_or(b, tmp);
6152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				b = tmp;
6153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
6154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return b;
6155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
6156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			memset(&mask128, 0xff, sizeof(mask128));
6157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			res0 = res = pcap_nametoaddrinfo(name);
6158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (res == NULL)
6159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				bpf_error("unknown host '%s'", name);
6160511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			ai = res;
6161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b = tmp = NULL;
6162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			tproto = tproto6 = proto;
6163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (off_linktype == -1 && tproto == Q_DEFAULT) {
6164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				tproto = Q_IP;
6165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				tproto6 = Q_IPV6;
6166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
6167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			for (res = res0; res; res = res->ai_next) {
6168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				switch (res->ai_family) {
6169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				case AF_INET:
6170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					if (tproto == Q_IPV6)
6171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project						continue;
6172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					sin4 = (struct sockaddr_in *)
6174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project						res->ai_addr;
6175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					tmp = gen_host(ntohl(sin4->sin_addr.s_addr),
6176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project						0xffffffff, tproto, dir, q.addr);
6177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					break;
6178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				case AF_INET6:
6179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					if (tproto6 == Q_IP)
6180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project						continue;
6181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					sin6 = (struct sockaddr_in6 *)
6183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project						res->ai_addr;
6184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					tmp = gen_host6(&sin6->sin6_addr,
6185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project						&mask128, tproto6, dir, q.addr);
6186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					break;
6187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				default:
6188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					continue;
6189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				}
6190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				if (b)
6191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					gen_or(b, tmp);
6192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				b = tmp;
6193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
6194511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			ai = NULL;
6195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			freeaddrinfo(res0);
6196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (b == NULL) {
6197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				bpf_error("unknown host '%s'%s", name,
6198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				    (proto == Q_DEFAULT)
6199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					? ""
6200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					: " for specified address family");
6201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
6202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return b;
6203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /*INET6*/
6204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
6205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_PORT:
6207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (proto != Q_DEFAULT &&
6208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    proto != Q_UDP && proto != Q_TCP && proto != Q_SCTP)
6209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("illegal qualifier of 'port'");
6210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (pcap_nametoport(name, &port, &real_proto) == 0)
6211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("unknown port '%s'", name);
6212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (proto == Q_UDP) {
6213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (real_proto == IPPROTO_TCP)
6214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				bpf_error("port '%s' is tcp", name);
6215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			else if (real_proto == IPPROTO_SCTP)
6216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				bpf_error("port '%s' is sctp", name);
6217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			else
6218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/* override PROTO_UNDEF */
6219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				real_proto = IPPROTO_UDP;
6220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
6221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (proto == Q_TCP) {
6222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (real_proto == IPPROTO_UDP)
6223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				bpf_error("port '%s' is udp", name);
6224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			else if (real_proto == IPPROTO_SCTP)
6226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				bpf_error("port '%s' is sctp", name);
6227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			else
6228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/* override PROTO_UNDEF */
6229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				real_proto = IPPROTO_TCP;
6230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
6231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (proto == Q_SCTP) {
6232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (real_proto == IPPROTO_UDP)
6233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				bpf_error("port '%s' is udp", name);
6234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			else if (real_proto == IPPROTO_TCP)
6236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				bpf_error("port '%s' is tcp", name);
6237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			else
6238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/* override PROTO_UNDEF */
6239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				real_proto = IPPROTO_SCTP;
6240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
6241511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (port < 0)
6242511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			bpf_error("illegal port number %d < 0", port);
6243511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (port > 65535)
6244511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			bpf_error("illegal port number %d > 65535", port);
6245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b = gen_port(port, real_proto, dir);
6246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(gen_port6(port, real_proto, dir), b);
6247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b;
6248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_PORTRANGE:
6250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (proto != Q_DEFAULT &&
6251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    proto != Q_UDP && proto != Q_TCP && proto != Q_SCTP)
6252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("illegal qualifier of 'portrange'");
6253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (pcap_nametoportrange(name, &port1, &port2, &real_proto) == 0)
6254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("unknown port in range '%s'", name);
6255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (proto == Q_UDP) {
6256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (real_proto == IPPROTO_TCP)
6257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				bpf_error("port in range '%s' is tcp", name);
6258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			else if (real_proto == IPPROTO_SCTP)
6259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				bpf_error("port in range '%s' is sctp", name);
6260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			else
6261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/* override PROTO_UNDEF */
6262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				real_proto = IPPROTO_UDP;
6263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
6264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (proto == Q_TCP) {
6265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (real_proto == IPPROTO_UDP)
6266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				bpf_error("port in range '%s' is udp", name);
6267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			else if (real_proto == IPPROTO_SCTP)
6268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				bpf_error("port in range '%s' is sctp", name);
6269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			else
6270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/* override PROTO_UNDEF */
6271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				real_proto = IPPROTO_TCP;
6272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
6273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (proto == Q_SCTP) {
6274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (real_proto == IPPROTO_UDP)
6275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				bpf_error("port in range '%s' is udp", name);
6276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			else if (real_proto == IPPROTO_TCP)
6277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				bpf_error("port in range '%s' is tcp", name);
6278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			else
6279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/* override PROTO_UNDEF */
6280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				real_proto = IPPROTO_SCTP;
6281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
6282511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (port1 < 0)
6283511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			bpf_error("illegal port number %d < 0", port1);
6284511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (port1 > 65535)
6285511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			bpf_error("illegal port number %d > 65535", port1);
6286511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (port2 < 0)
6287511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			bpf_error("illegal port number %d < 0", port2);
6288511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (port2 > 65535)
6289511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			bpf_error("illegal port number %d > 65535", port2);
6290511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
6291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b = gen_portrange(port1, port2, real_proto, dir);
6292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(gen_portrange6(port1, port2, real_proto, dir), b);
6293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b;
6294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_GATEWAY:
6296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef INET6
6297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		eaddr = pcap_ether_hostton(name);
6298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (eaddr == NULL)
6299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("unknown ether host: %s", name);
6300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		alist = pcap_nametoaddr(name);
6302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (alist == NULL || *alist == NULL)
6303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("unknown host '%s'", name);
6304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b = gen_gateway(eaddr, alist, proto, dir);
6305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		free(eaddr);
6306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b;
6307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
6308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'gateway' not supported in this configuration");
6309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /*INET6*/
6310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_PROTO:
6312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		real_proto = lookup_proto(name, proto);
6313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (real_proto >= 0)
6314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_proto(real_proto, proto, dir);
6315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else
6316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("unknown protocol: %s", name);
6317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_PROTOCHAIN:
6319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		real_proto = lookup_proto(name, proto);
6320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (real_proto >= 0)
6321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_protochain(real_proto, proto, dir);
6322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else
6323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("unknown protocol: %s", name);
6324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_UNDEF:
6326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		syntax();
6327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
6328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
6329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	abort();
6330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
6331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
6332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
6334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_mcode(s1, s2, masklen, q)
6335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register const char *s1, *s2;
6336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register int masklen;
6337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct qual q;
6338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
6339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register int nlen, mlen;
6340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 n, m;
6341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	nlen = __pcap_atoin(s1, &n);
6343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Promote short ipaddr */
6344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	n <<= 32 - nlen;
6345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (s2 != NULL) {
6347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		mlen = __pcap_atoin(s2, &m);
6348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Promote short ipaddr */
6349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		m <<= 32 - mlen;
6350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if ((n & ~m) != 0)
6351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("non-network bits set in \"%s mask %s\"",
6352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    s1, s2);
6353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	} else {
6354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Convert mask len to mask */
6355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (masklen > 32)
6356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("mask length must be <= 32");
6357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (masklen == 0) {
6358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
6359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * X << 32 is not guaranteed by C to be 0; it's
6360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * undefined.
6361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
6362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			m = 0;
6363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else
6364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			m = 0xffffffff << (32 - masklen);
6365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if ((n & ~m) != 0)
6366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("non-network bits set in \"%s/%d\"",
6367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    s1, masklen);
6368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
6369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (q.addr) {
6371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_NET:
6373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_host(n, m, q.proto, q.dir, q.addr);
6374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
6376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("Mask syntax for networks only");
6377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
6378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
6379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
6380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return NULL;
6381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
6382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
6384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ncode(s, v, q)
6385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register const char *s;
6386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 v;
6387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct qual q;
6388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
6389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 mask;
6390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int proto = q.proto;
6391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int dir = q.dir;
6392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register int vlen;
6393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (s == NULL)
6395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		vlen = 32;
6396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else if (q.proto == Q_DECNET)
6397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		vlen = __pcap_atodn(s, &v);
6398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else
6399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		vlen = __pcap_atoin(s, &v);
6400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (q.addr) {
6402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
6404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_HOST:
6405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_NET:
6406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (proto == Q_DECNET)
6407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_host(v, 0, proto, dir, q.addr);
6408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else if (proto == Q_LINK) {
6409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("illegal link layer address");
6410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else {
6411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			mask = 0xffffffff;
6412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (s == NULL && q.addr == Q_NET) {
6413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/* Promote short net number */
6414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				while (v && (v & 0xff000000) == 0) {
6415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					v <<= 8;
6416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					mask <<= 8;
6417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				}
6418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			} else {
6419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/* Promote short ipaddr */
6420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				v <<= 32 - vlen;
6421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				mask <<= 32 - vlen;
6422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
6423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return gen_host(v, mask, proto, dir, q.addr);
6424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
6425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_PORT:
6427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (proto == Q_UDP)
6428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			proto = IPPROTO_UDP;
6429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else if (proto == Q_TCP)
6430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			proto = IPPROTO_TCP;
6431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else if (proto == Q_SCTP)
6432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			proto = IPPROTO_SCTP;
6433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else if (proto == Q_DEFAULT)
6434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			proto = PROTO_UNDEF;
6435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else
6436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("illegal qualifier of 'port'");
6437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6438511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (v > 65535)
6439511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			bpf_error("illegal port number %u > 65535", v);
6440511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
6441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    {
6442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		struct block *b;
6443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b = gen_port((int)v, proto, dir);
6444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(gen_port6((int)v, proto, dir), b);
6445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b;
6446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    }
6447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_PORTRANGE:
6449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (proto == Q_UDP)
6450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			proto = IPPROTO_UDP;
6451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else if (proto == Q_TCP)
6452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			proto = IPPROTO_TCP;
6453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else if (proto == Q_SCTP)
6454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			proto = IPPROTO_SCTP;
6455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else if (proto == Q_DEFAULT)
6456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			proto = PROTO_UNDEF;
6457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else
6458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("illegal qualifier of 'portrange'");
6459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6460511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (v > 65535)
6461511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			bpf_error("illegal port number %u > 65535", v);
6462511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
6463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    {
6464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		struct block *b;
6465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b = gen_portrange((int)v, (int)v, proto, dir);
6466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(gen_portrange6((int)v, (int)v, proto, dir), b);
6467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b;
6468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    }
6469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_GATEWAY:
6471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("'gateway' requires a name");
6472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
6473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_PROTO:
6475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_proto((int)v, proto, dir);
6476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_PROTOCHAIN:
6478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_protochain((int)v, proto, dir);
6479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_UNDEF:
6481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		syntax();
6482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
6483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
6485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
6486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
6487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
6488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
6489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
6490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef INET6
6492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
6493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_mcode6(s1, s2, masklen, q)
6494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register const char *s1, *s2;
6495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register int masklen;
6496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct qual q;
6497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
6498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct addrinfo *res;
6499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct in6_addr *addr;
6500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct in6_addr mask;
6501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b;
6502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int32_t *a, *m;
6503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (s2)
6505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("no mask %s supported", s2);
6506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	res = pcap_nametoaddrinfo(s1);
6508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (!res)
6509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("invalid ip6 address %s", s1);
6510511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	ai = res;
6511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (res->ai_next)
6512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("%s resolved to multiple address", s1);
6513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	addr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
6514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (sizeof(mask) * 8 < masklen)
6516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("mask length must be <= %u", (unsigned int)(sizeof(mask) * 8));
6517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	memset(&mask, 0, sizeof(mask));
6518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	memset(&mask, 0xff, masklen / 8);
6519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (masklen % 8) {
6520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		mask.s6_addr[masklen / 8] =
6521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			(0xff << (8 - masklen % 8)) & 0xff;
6522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
6523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	a = (u_int32_t *)addr;
6525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	m = (u_int32_t *)&mask;
6526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if ((a[0] & ~m[0]) || (a[1] & ~m[1])
6527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 || (a[2] & ~m[2]) || (a[3] & ~m[3])) {
6528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("non-network bits set in \"%s/%d\"", s1, masklen);
6529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
6530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (q.addr) {
6532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
6534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_HOST:
6535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (masklen != 128)
6536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("Mask syntax for networks only");
6537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* FALLTHROUGH */
6538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_NET:
6540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b = gen_host6(addr, &mask, q.proto, q.dir, q.addr);
6541511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		ai = NULL;
6542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		freeaddrinfo(res);
6543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b;
6544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
6546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("invalid qualifier against IPv6 address");
6547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
6548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
6549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return NULL;
6550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
6551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /*INET6*/
6552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
6554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ecode(eaddr, q)
6555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register const u_char *eaddr;
6556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct qual q;
6557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
6558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b, *tmp;
6559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
6561511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		switch (linktype) {
6562511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_EN10MB:
6563511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_NETANALYZER:
6564511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_NETANALYZER_TRANSPARENT:
6565511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_ehostop(eaddr, (int)q.dir);
6566511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_FDDI:
6567511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_fhostop(eaddr, (int)q.dir);
6568511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_IEEE802:
6569511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_thostop(eaddr, (int)q.dir);
6570511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_IEEE802_11:
6571511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_PRISM_HEADER:
6572511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_IEEE802_11_RADIO_AVS:
6573511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_IEEE802_11_RADIO:
6574511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_PPI:
6575511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_wlanhostop(eaddr, (int)q.dir);
6576511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_SUNATM:
6577511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (is_lane) {
6578511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				/*
6579511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 * Check that the packet doesn't begin with an
6580511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 * LE Control marker.  (We've already generated
6581511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 * a test for LANE.)
6582511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 */
6583511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				tmp = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H,
6584511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					0xFF00);
6585511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				gen_not(tmp);
6586511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
6587511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				/*
6588511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 * Now check the MAC address.
6589511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 */
6590511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				b = gen_ehostop(eaddr, (int)q.dir);
6591511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				gen_and(tmp, b);
6592511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return b;
6593511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
6594511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
6595511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_IP_OVER_FC:
6596511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_ipfchostop(eaddr, (int)q.dir);
6597511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		default:
6598511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			bpf_error("ethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
6599511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
6600511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
6601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
6602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_error("ethernet address used in non-ether expression");
6603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
6604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return NULL;
6605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
6606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid
6608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectsappend(s0, s1)
6609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s0, *s1;
6610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
6611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
6612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * This is definitely not the best way to do this, but the
6613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * lists will rarely get long.
6614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
6615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	while (s0->next)
6616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s0 = s0->next;
6617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s0->next = s1;
6618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
6619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist *
6621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectxfer_to_x(a)
6622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct arth *a;
6623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
6624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s;
6625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s = new_stmt(BPF_LDX|BPF_MEM);
6627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s->s.k = a->regno;
6628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return s;
6629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
6630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct slist *
6632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectxfer_to_a(a)
6633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct arth *a;
6634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
6635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s;
6636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s = new_stmt(BPF_LD|BPF_MEM);
6638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s->s.k = a->regno;
6639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return s;
6640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
6641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
6643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Modify "index" to use the value stored into its register as an
6644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * offset relative to the beginning of the header for the protocol
6645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "proto", and allocate a register and put an item "size" bytes long
6646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (1, 2, or 4) at that offset into that register, making it the register
6647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * for "index".
6648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
6649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct arth *
6650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_load(proto, inst, size)
6651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int proto;
6652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct arth *inst;
6653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int size;
6654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
6655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s, *tmp;
6656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b;
6657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int regno = alloc_reg();
6658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	free_reg(inst->regno);
6660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (size) {
6661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
6663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("data size must be 1, 2, or 4");
6664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case 1:
6666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		size = BPF_B;
6667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
6668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case 2:
6670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		size = BPF_H;
6671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
6672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case 4:
6674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		size = BPF_W;
6675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
6676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
6677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (proto) {
6678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
6679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("unsupported index operation");
6680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_RADIO:
6682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
6683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * The offset is relative to the beginning of the packet
6684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * data, if we have a radio header.  (If we don't, this
6685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * is an error.)
6686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
6687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (linktype != DLT_IEEE802_11_RADIO_AVS &&
6688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    linktype != DLT_IEEE802_11_RADIO &&
6689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    linktype != DLT_PRISM_HEADER)
6690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("radio information not present in capture");
6691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
6693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Load into the X register the offset computed into the
6694511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * register specified by "index".
6695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
6696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = xfer_to_x(inst);
6697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
6699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Load the item at that offset.
6700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
6701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = new_stmt(BPF_LD|BPF_IND|size);
6702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s, tmp);
6703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(inst->s, s);
6704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
6705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_LINK:
6707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
6708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * The offset is relative to the beginning of
6709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the link-layer header.
6710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
6711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - what about ATM LANE?  Should the index be
6712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * relative to the beginning of the AAL5 frame, so
6713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * that 0 refers to the beginning of the LE Control
6714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * field, or relative to the beginning of the LAN
6715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * frame, so that 0 refers, for Ethernet LANE, to
6716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the beginning of the destination address?
6717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
6718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = gen_llprefixlen();
6719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
6721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If "s" is non-null, it has code to arrange that the
6722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * X register contains the length of the prefix preceding
6723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the link-layer header.  Add to it the offset computed
6724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * into the register specified by "index", and move that
6725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * into the X register.  Otherwise, just load into the X
6726511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * register the offset computed into the register specified
6727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * by "index".
6728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
6729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (s != NULL) {
6730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			sappend(s, xfer_to_a(inst));
6731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
6732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			sappend(s, new_stmt(BPF_MISC|BPF_TAX));
6733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else
6734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			s = xfer_to_x(inst);
6735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
6737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Load the item at the sum of the offset we've put in the
6738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * X register and the offset of the start of the link
6739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * layer header (which is 0 if the radio header is
6740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * variable-length; that header length is what we put
6741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * into the X register and then added to the index).
6742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
6743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = new_stmt(BPF_LD|BPF_IND|size);
6744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp->s.k = off_ll;
6745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s, tmp);
6746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(inst->s, s);
6747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
6748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IP:
6750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ARP:
6751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_RARP:
6752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ATALK:
6753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DECNET:
6754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SCA:
6755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_LAT:
6756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_MOPRC:
6757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_MOPDL:
6758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IPV6:
6759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
6760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * The offset is relative to the beginning of
6761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the network-layer header.
6762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - are there any cases where we want
6763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * off_nl_nosnap?
6764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
6765511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		s = gen_off_macpl();
6766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
6768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If "s" is non-null, it has code to arrange that the
6769511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * X register contains the offset of the MAC-layer
6770511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * payload.  Add to it the offset computed into the
6771511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * register specified by "index", and move that into
6772511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * the X register.  Otherwise, just load into the X
6773511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * register the offset computed into the register specified
6774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * by "index".
6775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
6776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (s != NULL) {
6777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			sappend(s, xfer_to_a(inst));
6778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
6779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			sappend(s, new_stmt(BPF_MISC|BPF_TAX));
6780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else
6781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			s = xfer_to_x(inst);
6782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
6784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Load the item at the sum of the offset we've put in the
6785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * X register, the offset of the start of the network
6786511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * layer header from the beginning of the MAC-layer
6787511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * payload, and the purported offset of the start of the
6788511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * MAC-layer payload (which might be 0 if there's a
6789511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * variable-length prefix before the link-layer header
6790511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * or the link-layer header itself is variable-length;
6791511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * the variable-length offset of the start of the
6792511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * MAC-layer payload is what we put into the X register
6793511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * and then added to the index).
6794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
6795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = new_stmt(BPF_LD|BPF_IND|size);
6796511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		tmp->s.k = off_macpl + off_nl;
6797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s, tmp);
6798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(inst->s, s);
6799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
6801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Do the computation only if the packet contains
6802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the protocol in question.
6803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
6804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b = gen_proto_abbrev(proto);
6805478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (inst->b)
6806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_and(inst->b, b);
6807478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		inst->b = b;
6808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
6809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SCTP:
6811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_TCP:
6812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_UDP:
6813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ICMP:
6814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IGMP:
6815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IGRP:
6816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_PIM:
6817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_VRRP:
6818511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_CARP:
6819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
6820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * The offset is relative to the beginning of
6821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the transport-layer header.
6822478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
6823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Load the X register with the length of the IPv4 header
6824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * (plus the offset of the link-layer header, if it's
6825478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * a variable-length header), in bytes.
6826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
6827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - are there any cases where we want
6828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * off_nl_nosnap?
6829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - we should, if we're built with
6830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * IPv6 support, generate code to load either
6831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * IPv4, IPv6, or both, as appropriate.
6832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
6833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = gen_loadx_iphdrlen();
6834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
6836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * The X register now contains the sum of the length
6837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * of any variable-length header preceding the link-layer
6838511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * header, any variable-length link-layer header, and the
6839511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * length of the network-layer header.
6840511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 *
6841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Load into the A register the offset relative to
6842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the beginning of the transport layer header,
6843478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * add the X register to that, move that to the
6844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * X register, and load with an offset from the
6845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * X register equal to the offset of the network
6846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * layer header relative to the beginning of
6847511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * the MAC-layer payload plus the fixed-length
6848511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * portion of the offset of the MAC-layer payload
6849511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * from the beginning of the raw packet data.
6850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
6851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s, xfer_to_a(inst));
6852478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
6853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s, new_stmt(BPF_MISC|BPF_TAX));
6854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size));
6855511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		tmp->s.k = off_macpl + off_nl;
6856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(inst->s, s);
6857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
6859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Do the computation only if the packet contains
6860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the protocol in question - which is true only
6861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * if this is an IP datagram and is the first or
6862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * only fragment of that datagram.
6863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
6864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(gen_proto_abbrev(proto), b = gen_ipfrag());
6865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (inst->b)
6866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_and(inst->b, b);
6867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(gen_proto_abbrev(Q_IP), b);
6868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		inst->b = b;
6869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
6870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_ICMPV6:
6871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("IPv6 upper-layer protocol is not supported by proto[x]");
6872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*NOTREACHED*/
6873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
6874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	inst->regno = regno;
6875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s = new_stmt(BPF_ST);
6876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s->s.k = regno;
6877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	sappend(inst->s, s);
6878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return inst;
6880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
6881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
6883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_relation(code, a0, a1, reversed)
6884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int code;
6885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct arth *a0, *a1;
6886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int reversed;
6887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
6888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s0, *s1, *s2;
6889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b, *tmp;
6890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s0 = xfer_to_x(a1);
6892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s1 = xfer_to_a(a0);
6893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (code == BPF_JEQ) {
6894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X);
6895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b = new_block(JMP(code));
6896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		sappend(s1, s2);
6897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
6898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else
6899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b = new_block(BPF_JMP|code|BPF_X);
6900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (reversed)
6901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_not(b);
6902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	sappend(s0, s1);
6904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	sappend(a1->s, s0);
6905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	sappend(a0->s, a1->s);
6906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b->stmts = a0->s;
6908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	free_reg(a0->regno);
6910478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	free_reg(a1->regno);
6911478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* 'and' together protocol checks */
6913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (a0->b) {
6914478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (a1->b) {
6915478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_and(a0->b, tmp = a1->b);
6916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
6917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else
6918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			tmp = a0->b;
6919478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	} else
6920478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		tmp = a1->b;
6921478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (tmp)
6923478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(tmp, b);
6924478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6925478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b;
6926478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
6927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6928478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct arth *
6929478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_loadlen()
6930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
6931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int regno = alloc_reg();
6932478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct arth *a = (struct arth *)newchunk(sizeof(*a));
6933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s;
6934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s = new_stmt(BPF_LD|BPF_LEN);
6936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s->next = new_stmt(BPF_ST);
6937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s->next->s.k = regno;
6938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	a->s = s;
6939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	a->regno = regno;
6940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return a;
6942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
6943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct arth *
6945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_loadi(val)
6946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int val;
6947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
6948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct arth *a;
6949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s;
6950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int reg;
6951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	a = (struct arth *)newchunk(sizeof(*a));
6953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	reg = alloc_reg();
6955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s = new_stmt(BPF_LD|BPF_IMM);
6957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s->s.k = val;
6958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s->next = new_stmt(BPF_ST);
6959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s->next->s.k = reg;
6960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	a->s = s;
6961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	a->regno = reg;
6962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return a;
6964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
6965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct arth *
6967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_neg(a)
6968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct arth *a;
6969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
6970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s;
6971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s = xfer_to_a(a);
6973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	sappend(a->s, s);
6974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s = new_stmt(BPF_ALU|BPF_NEG);
6975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s->s.k = 0;
6976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	sappend(a->s, s);
6977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s = new_stmt(BPF_ST);
6978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s->s.k = a->regno;
6979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	sappend(a->s, s);
6980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6981478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return a;
6982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
6983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6984478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct arth *
6985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_arth(code, a0, a1)
6986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int code;
6987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct arth *a0, *a1;
6988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
6989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s0, *s1, *s2;
6990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s0 = xfer_to_x(a1);
6992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s1 = xfer_to_a(a0);
6993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s2 = new_stmt(BPF_ALU|BPF_X|code);
6994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
6995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	sappend(s1, s2);
6996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	sappend(s0, s1);
6997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	sappend(a1->s, s0);
6998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	sappend(a0->s, a1->s);
6999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	free_reg(a0->regno);
7001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	free_reg(a1->regno);
7002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s0 = new_stmt(BPF_ST);
7004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	a0->regno = s0->s.k = alloc_reg();
7005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	sappend(a0->s, s0);
7006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return a0;
7008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
7011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Here we handle simple allocation of the scratch registers.
7012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If too many registers are alloc'd, the allocator punts.
7013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
7014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int regused[BPF_MEMWORDS];
7015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int curreg;
7016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
7018511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Initialize the table of used registers and the current register.
7019511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
7020511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void
7021511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallinit_regs()
7022511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
7023511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	curreg = 0;
7024511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	memset(regused, 0, sizeof regused);
7025511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
7026511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7027511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
7028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Return the next free register.
7029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
7030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
7031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectalloc_reg()
7032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int n = BPF_MEMWORDS;
7034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	while (--n >= 0) {
7036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (regused[curreg])
7037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			curreg = (curreg + 1) % BPF_MEMWORDS;
7038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else {
7039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			regused[curreg] = 1;
7040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return curreg;
7041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
7042478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
7043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_error("too many registers needed to evaluate expression");
7044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
7045478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return 0;
7046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
7049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Return a register to the table so it can
7050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * be used later.
7051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
7052478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void
7053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectfree_reg(n)
7054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int n;
7055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	regused[n] = 0;
7057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
7060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_len(jmp, n)
7061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int jmp, n;
7062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s;
7064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b;
7065478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7066478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s = new_stmt(BPF_LD|BPF_LEN);
7067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b = new_block(JMP(jmp));
7068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b->stmts = s;
7069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b->s.k = n;
7070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b;
7072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7074478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_greater(n)
7076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int n;
7077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7078478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return gen_len(BPF_JGE, n);
7079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
7082478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Actually, this is less than or equal.
7083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
7084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_less(n)
7086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int n;
7087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b;
7089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b = gen_len(BPF_JGT, n);
7091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_not(b);
7092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b;
7094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
7097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is for "byte {idx} {op} {val}"; "idx" is treated as relative to
7098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the beginning of the link-layer header.
7099478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - that means you can't test values in the radiotap header, but
7100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as that header is difficult if not impossible to parse generally
7101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * without a loop, that might not be a severe problem.  A new keyword
7102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "radio" could be added for that, although what you'd really want
7103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * would be a way of testing particular radio header values, which
7104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * would generate code appropriate to the radio header in question.
7105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
7106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_byteop(op, idx, val)
7108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int op, idx, val;
7109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b;
7111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct slist *s;
7112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (op) {
7114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
7115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
7116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case '=':
7118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_cmp(OR_LINK, (u_int)idx, BPF_B, (bpf_int32)val);
7119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case '<':
7121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b = gen_cmp_lt(OR_LINK, (u_int)idx, BPF_B, (bpf_int32)val);
7122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b;
7123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case '>':
7125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b = gen_cmp_gt(OR_LINK, (u_int)idx, BPF_B, (bpf_int32)val);
7126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b;
7127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case '|':
7129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = new_stmt(BPF_ALU|BPF_OR|BPF_K);
7130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
7131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case '&':
7133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		s = new_stmt(BPF_ALU|BPF_AND|BPF_K);
7134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
7135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
7136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s->s.k = val;
7137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b = new_block(JMP(BPF_JEQ));
7138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b->stmts = s;
7139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	gen_not(b);
7140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b;
7142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_char abroadcast[] = { 0x0 };
7145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_broadcast(proto)
7148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int proto;
7149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 hostmask;
7151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1, *b2;
7152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	static u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
7153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (proto) {
7155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
7157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_LINK:
7158511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		switch (linktype) {
7159511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_ARCNET:
7160511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_ARCNET_LINUX:
7161511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_ahostop(abroadcast, Q_DST);
7162511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_EN10MB:
7163511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_NETANALYZER:
7164511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_NETANALYZER_TRANSPARENT:
7165511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_ehostop(ebroadcast, Q_DST);
7166511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_FDDI:
7167511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_fhostop(ebroadcast, Q_DST);
7168511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_IEEE802:
7169511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_thostop(ebroadcast, Q_DST);
7170511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_IEEE802_11:
7171511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_PRISM_HEADER:
7172511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_IEEE802_11_RADIO_AVS:
7173511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_IEEE802_11_RADIO:
7174511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_PPI:
7175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_wlanhostop(ebroadcast, Q_DST);
7176511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_IP_OVER_FC:
7177511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_ipfchostop(ebroadcast, Q_DST);
7178511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_SUNATM:
7179511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (is_lane) {
7180511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				/*
7181511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 * Check that the packet doesn't begin with an
7182511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 * LE Control marker.  (We've already generated
7183511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 * a test for LANE.)
7184511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 */
7185511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS,
7186511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    BPF_H, 0xFF00);
7187511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				gen_not(b1);
7188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7189511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				/*
7190511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 * Now check the MAC address.
7191511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 */
7192511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				b0 = gen_ehostop(ebroadcast, Q_DST);
7193511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				gen_and(b1, b0);
7194511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return b0;
7195511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
7196511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
7197511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		default:
7198511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			bpf_error("not a broadcast link");
7199511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
7200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
7201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IP:
7203511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
7204511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * We treat a netmask of PCAP_NETMASK_UNKNOWN (0xffffffff)
7205511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * as an indication that we don't know the netmask, and fail
7206511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * in that case.
7207511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
7208511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (netmask == PCAP_NETMASK_UNKNOWN)
7209511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			bpf_error("netmask not known, so 'ip broadcast' not supported");
7210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_linktype(ETHERTYPE_IP);
7211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		hostmask = ~netmask;
7212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_mcmp(OR_NET, 16, BPF_W, (bpf_int32)0, hostmask);
7213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b2 = gen_mcmp(OR_NET, 16, BPF_W,
7214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			      (bpf_int32)(~0 & hostmask), hostmask);
7215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b1, b2);
7216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b2);
7217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b2;
7218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
7219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_error("only link-layer/IP broadcast filters supported");
7220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
7221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return NULL;
7222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
7225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Generate code to test the low-order bit of a MAC address (that's
7226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the bottom bit of the *first* byte).
7227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
7228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
7229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_mac_multicast(offset)
7230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int offset;
7231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register struct block *b0;
7233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register struct slist *s;
7234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* link[offset] & 1 != 0 */
7236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	s = gen_load_a(OR_LINK, offset, BPF_B);
7237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 = new_block(JMP(BPF_JSET));
7238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0->s.k = 1;
7239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0->stmts = s;
7240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b0;
7241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_multicast(proto)
7245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int proto;
7246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register struct block *b0, *b1, *b2;
7248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register struct slist *s;
7249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (proto) {
7251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
7253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_LINK:
7254511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		switch (linktype) {
7255511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_ARCNET:
7256511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_ARCNET_LINUX:
7257511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* all ARCnet multicasts use the same address */
7258511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_ahostop(abroadcast, Q_DST);
7259511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_EN10MB:
7260511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_NETANALYZER:
7261511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_NETANALYZER_TRANSPARENT:
7262511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* ether[0] & 1 != 0 */
7263511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_mac_multicast(0);
7264511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_FDDI:
7265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
7266511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX
7267511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 *
7268511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * XXX - was that referring to bit-order issues?
7269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
7270511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* fddi[1] & 1 != 0 */
7271511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_mac_multicast(1);
7272511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_IEEE802:
7273511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* tr[2] & 1 != 0 */
7274511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return gen_mac_multicast(2);
7275511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_IEEE802_11:
7276511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_PRISM_HEADER:
7277511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_IEEE802_11_RADIO_AVS:
7278511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_IEEE802_11_RADIO:
7279511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_PPI:
7280511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
7281511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Oh, yuk.
7282511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 *
7283511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 *	For control frames, there is no DA.
7284511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 *
7285511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 *	For management frames, DA is at an
7286511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 *	offset of 4 from the beginning of
7287511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 *	the packet.
7288511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 *
7289511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 *	For data frames, DA is at an offset
7290511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 *	of 4 from the beginning of the packet
7291511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 *	if To DS is clear and at an offset of
7292511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 *	16 from the beginning of the packet
7293511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 *	if To DS is set.
7294511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
7295511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7296511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
7297511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Generate the tests to be done for data frames.
7298511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 *
7299511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * First, check for To DS set, i.e. "link[1] & 0x01".
7300511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
7301511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			s = gen_load_a(OR_LINK, 1, BPF_B);
7302511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b1 = new_block(JMP(BPF_JSET));
7303511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b1->s.k = 0x01;	/* To DS */
7304511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b1->stmts = s;
7305511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7306511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
7307511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * If To DS is set, the DA is at 16.
7308511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
7309511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b0 = gen_mac_multicast(16);
7310511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			gen_and(b1, b0);
7311511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7312511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
7313511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Now, check for To DS not set, i.e. check
7314511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * "!(link[1] & 0x01)".
7315511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
7316511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			s = gen_load_a(OR_LINK, 1, BPF_B);
7317511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b2 = new_block(JMP(BPF_JSET));
7318511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b2->s.k = 0x01;	/* To DS */
7319511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b2->stmts = s;
7320511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			gen_not(b2);
7321511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7322511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
7323511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * If To DS is not set, the DA is at 4.
7324511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
7325511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b1 = gen_mac_multicast(4);
7326511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			gen_and(b2, b1);
7327511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7328511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
7329511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Now OR together the last two checks.  That gives
7330511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * the complete set of checks for data frames.
7331511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
7332511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			gen_or(b1, b0);
7333511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7334511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
7335511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Now check for a data frame.
7336511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * I.e, check "link[0] & 0x08".
7337511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
7338511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			s = gen_load_a(OR_LINK, 0, BPF_B);
7339511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b1 = new_block(JMP(BPF_JSET));
7340511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b1->s.k = 0x08;
7341511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b1->stmts = s;
7342511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7343511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
7344511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * AND that with the checks done for data frames.
7345511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
7346511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			gen_and(b1, b0);
7347511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7348511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
7349511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * If the high-order bit of the type value is 0, this
7350511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * is a management frame.
7351511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * I.e, check "!(link[0] & 0x08)".
7352511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
7353511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			s = gen_load_a(OR_LINK, 0, BPF_B);
7354511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b2 = new_block(JMP(BPF_JSET));
7355511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b2->s.k = 0x08;
7356511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b2->stmts = s;
7357511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			gen_not(b2);
7358511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7359511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
7360511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * For management frames, the DA is at 4.
7361511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
7362511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b1 = gen_mac_multicast(4);
7363511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			gen_and(b2, b1);
7364511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7365511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
7366511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * OR that with the checks done for data frames.
7367511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * That gives the checks done for management and
7368511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * data frames.
7369511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
7370511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			gen_or(b1, b0);
7371511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7372511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
7373511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * If the low-order bit of the type value is 1,
7374511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * this is either a control frame or a frame
7375511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * with a reserved type, and thus not a
7376511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * frame with an SA.
7377511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 *
7378511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * I.e., check "!(link[0] & 0x04)".
7379511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
7380511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			s = gen_load_a(OR_LINK, 0, BPF_B);
7381511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b1 = new_block(JMP(BPF_JSET));
7382511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b1->s.k = 0x04;
7383511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b1->stmts = s;
7384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_not(b1);
7385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7386511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
7387511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * AND that with the checks for data and management
7388511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * frames.
7389511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
7390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			gen_and(b1, b0);
7391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return b0;
7392511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_IP_OVER_FC:
7393511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b0 = gen_mac_multicast(2);
7394511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return b0;
7395511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case DLT_SUNATM:
7396511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (is_lane) {
7397511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				/*
7398511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 * Check that the packet doesn't begin with an
7399511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 * LE Control marker.  (We've already generated
7400511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 * a test for LANE.)
7401511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 */
7402511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS,
7403511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    BPF_H, 0xFF00);
7404511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				gen_not(b1);
7405511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7406511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				/* ether[off_mac] & 1 != 0 */
7407511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				b0 = gen_mac_multicast(off_mac);
7408511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				gen_and(b1, b0);
7409511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return b0;
7410511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
7411511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
7412511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		default:
7413511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
7414511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
7415511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* Link not known to support multicasts */
7416511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
7417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IP:
7419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_linktype(ETHERTYPE_IP);
7420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_cmp_ge(OR_NET, 16, BPF_B, (bpf_int32)224);
7421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
7422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
7423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_IPV6:
7425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_linktype(ETHERTYPE_IPV6);
7426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_cmp(OR_NET, 24, BPF_B, (bpf_int32)255);
7427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
7428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
7429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
7430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_error("link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel");
7431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
7432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return NULL;
7433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
7436511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Filter on inbound (dir == 0) or outbound (dir == 1) traffic.
7437511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Outbound traffic is sent by this machine, while inbound traffic is
7438511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * sent by a remote machine (and may include packets destined for a
7439511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * unicast or multicast link-layer address we are not subscribing to).
7440511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * These are the same definitions implemented by pcap_setdirection().
7441511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Capturing only unicast traffic destined for this host is probably
7442511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * better accomplished using a higher-layer filter.
7443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
7444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_inbound(dir)
7446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int dir;
7447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register struct block *b0;
7449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
7451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Only some data link types support inbound/outbound qualifiers.
7452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
7453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (linktype) {
7454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_SLIP:
7455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_relation(BPF_JEQ,
7456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			  gen_load(Q_LINK, gen_loadi(0), 1),
7457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			  gen_loadi(0),
7458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			  dir);
7459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
7460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7461511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IPNET:
7462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (dir) {
7463511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* match outgoing packets */
7464511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b0 = gen_cmp(OR_LINK, 2, BPF_H, IPNET_OUTBOUND);
7465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else {
7466511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* match incoming packets */
7467511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b0 = gen_cmp(OR_LINK, 2, BPF_H, IPNET_INBOUND);
7468511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
7469511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
7470511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7471511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_LINUX_SLL:
7472511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* match outgoing packets */
7473511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_cmp(OR_LINK, 0, BPF_H, LINUX_SLL_OUTGOING);
7474511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (!dir) {
7475511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* to filter on inbound traffic, invert the match */
7476511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			gen_not(b0);
7477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
7478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
7479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_NET_PFVAR_H
7481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_PFLOG:
7482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, dir), BPF_B,
7483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    (bpf_int32)((dir == 0) ? PF_IN : PF_OUT));
7484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
7485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
7486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_PPP_PPPD:
7488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (dir) {
7489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* match outgoing packets */
7490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b0 = gen_cmp(OR_LINK, 0, BPF_B, PPP_PPPD_OUT);
7491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else {
7492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* match incoming packets */
7493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b0 = gen_cmp(OR_LINK, 0, BPF_B, PPP_PPPD_IN);
7494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
7495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
7496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_MFR:
7498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_MLFR:
7499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_MLPPP:
7500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_JUNIPER_ATM1:
7501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_JUNIPER_ATM2:
7502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_JUNIPER_PPPOE:
7503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_JUNIPER_PPPOE_ATM:
7504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_GGSN:
7505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_ES:
7506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_MONITOR:
7507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_SERVICES:
7508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_ETHER:
7509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_PPP:
7510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_FRELAY:
7511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_CHDLC:
7512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case DLT_JUNIPER_VP:
7513511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        case DLT_JUNIPER_ST:
7514511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        case DLT_JUNIPER_ISM:
7515511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        case DLT_JUNIPER_VS:
7516511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        case DLT_JUNIPER_SRX_E2E:
7517511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        case DLT_JUNIPER_FIBRECHANNEL:
7518511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_JUNIPER_ATM_CEMIC:
7519511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* juniper flags (including direction) are stored
7521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the byte after the 3-byte magic number */
7522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (dir) {
7523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* match outgoing packets */
7524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b0 = gen_mcmp(OR_LINK, 3, BPF_B, 0, 0x01);
7525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else {
7526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* match incoming packets */
7527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			b0 = gen_mcmp(OR_LINK, 3, BPF_B, 1, 0x01);
7528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
7529511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
7530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
7532511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
7533511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * If we have packet meta-data indicating a direction,
7534511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * check it, otherwise give up as this link-layer type
7535511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * has nothing in the packet data.
7536511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
7537511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#if defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
7538511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
7539511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * This is Linux with PF_PACKET support.
7540511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * If this is a *live* capture, we can look at
7541511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * special meta-data in the filter expression;
7542511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * if it's a savefile, we can't.
7543511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
7544511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (bpf_pcap->rfile != NULL) {
7545511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* We have a FILE *, so this is a savefile */
7546511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			bpf_error("inbound/outbound not supported on linktype %d when reading savefiles",
7547511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    linktype);
7548511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b0 = NULL;
7549511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* NOTREACHED */
7550511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
7551511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* match outgoing packets */
7552511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_cmp(OR_LINK, SKF_AD_OFF + SKF_AD_PKTTYPE, BPF_H,
7553511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		             PACKET_OUTGOING);
7554511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (!dir) {
7555511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* to filter on inbound traffic, invert the match */
7556511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			gen_not(b0);
7557511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
7558511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else /* defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
7559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("inbound/outbound not supported on linktype %d",
7560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    linktype);
7561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = NULL;
7562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
7563511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif /* defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
7564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
7565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (b0);
7566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_NET_PFVAR_H
7569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* PF firewall log matched interface */
7570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_ifname(const char *ifname)
7572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0;
7574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_int len, off;
7575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7576511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (linktype != DLT_PFLOG) {
7577511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("ifname supported only on PF linktype");
7578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
7579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
7580511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	len = sizeof(((struct pfloghdr *)0)->ifname);
7581511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	off = offsetof(struct pfloghdr, ifname);
7582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (strlen(ifname) >= len) {
7583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("ifname interface names can only be %d characters",
7584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    len-1);
7585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
7586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
7587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 = gen_bcmp(OR_LINK, off, strlen(ifname), (const u_char *)ifname);
7588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (b0);
7589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* PF firewall log ruleset name */
7592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_ruleset(char *ruleset)
7594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0;
7596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (linktype != DLT_PFLOG) {
7598511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("ruleset supported only on PF linktype");
7599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
7600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
7601511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (strlen(ruleset) >= sizeof(((struct pfloghdr *)0)->ruleset)) {
7603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("ruleset names can only be %ld characters",
7604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    (long)(sizeof(((struct pfloghdr *)0)->ruleset) - 1));
7605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
7606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
7607511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 = gen_bcmp(OR_LINK, offsetof(struct pfloghdr, ruleset),
7609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    strlen(ruleset), (const u_char *)ruleset);
7610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (b0);
7611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* PF firewall log rule number */
7614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_rnr(int rnr)
7616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0;
7618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7619511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (linktype != DLT_PFLOG) {
7620511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("rnr supported only on PF linktype");
7621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
7622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
7623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7624511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, rulenr), BPF_W,
7625511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 (bpf_int32)rnr);
7626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (b0);
7627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* PF firewall log sub-rule number */
7630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_srnr(int srnr)
7632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0;
7634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (linktype != DLT_PFLOG) {
7636511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("srnr supported only on PF linktype");
7637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
7638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
7639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, subrulenr), BPF_W,
7641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    (bpf_int32)srnr);
7642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (b0);
7643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* PF firewall log reason code */
7646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_reason(int reason)
7648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0;
7650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7651511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (linktype != DLT_PFLOG) {
7652511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("reason supported only on PF linktype");
7653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
7654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
7655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7656511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, reason), BPF_B,
7657511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	    (bpf_int32)reason);
7658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (b0);
7659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* PF firewall log action */
7662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_action(int action)
7664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0;
7666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7667511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (linktype != DLT_PFLOG) {
7668511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("action supported only on PF linktype");
7669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* NOTREACHED */
7670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
7671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7672511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, action), BPF_B,
7673511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	    (bpf_int32)action);
7674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (b0);
7675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else /* !HAVE_NET_PFVAR_H */
7677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_ifname(const char *ifname)
7679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_error("libpcap was compiled without pf support");
7681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
7682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (NULL);
7683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_ruleset(char *ruleset)
7687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_error("libpcap was compiled on a machine without pf support");
7689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
7690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (NULL);
7691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_rnr(int rnr)
7695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_error("libpcap was compiled on a machine without pf support");
7697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
7698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (NULL);
7699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_srnr(int srnr)
7703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_error("libpcap was compiled on a machine without pf support");
7705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
7706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (NULL);
7707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_reason(int reason)
7711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_error("libpcap was compiled on a machine without pf support");
7713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
7714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (NULL);
7715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pf_action(int action)
7719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_error("libpcap was compiled on a machine without pf support");
7721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
7722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (NULL);
7723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_NET_PFVAR_H */
7725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7726511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* IEEE 802.11 wireless header */
7727511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct block *
7728511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_p80211_type(int type, int mask)
7729511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
7730511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct block *b0;
7731511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7732511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	switch (linktype) {
7733511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7734511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_11:
7735511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_PRISM_HEADER:
7736511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_11_RADIO_AVS:
7737511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_11_RADIO:
7738511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_mcmp(OR_LINK, 0, BPF_B, (bpf_int32)type,
7739511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    (bpf_int32)mask);
7740511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
7741511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7742511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	default:
7743511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("802.11 link-layer types supported only on 802.11");
7744511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* NOTREACHED */
7745511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
7746511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7747511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return (b0);
7748511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
7749511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7750511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct block *
7751511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_p80211_fcdir(int fcdir)
7752511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
7753511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct block *b0;
7754511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7755511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	switch (linktype) {
7756511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7757511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_11:
7758511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_PRISM_HEADER:
7759511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_11_RADIO_AVS:
7760511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_IEEE802_11_RADIO:
7761511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
7762511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7763511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	default:
7764511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("frame direction supported only with 802.11 headers");
7765511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* NOTREACHED */
7766511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
7767511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7768511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	b0 = gen_mcmp(OR_LINK, 1, BPF_B, (bpf_int32)fcdir,
7769511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		(bpf_u_int32)IEEE80211_FC1_DIR_MASK);
7770511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7771511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return (b0);
7772511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
7773511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_acode(eaddr, q)
7776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register const u_char *eaddr;
7777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct qual q;
7778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7779511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	switch (linktype) {
7780511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7781511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_ARCNET:
7782511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_ARCNET_LINUX:
7783511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) &&
7784511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    q.proto == Q_LINK)
7785511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return (gen_ahostop(eaddr, (int)q.dir));
7786511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		else {
7787511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			bpf_error("ARCnet address used in non-arc expression");
7788511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* NOTREACHED */
7789511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
7790511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
7791511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7792511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	default:
7793511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("aid supported only on ARCnet");
7794511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* NOTREACHED */
7795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
7796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_error("ARCnet address used in non-arc expression");
7797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
7798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return NULL;
7799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
7802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_ahostop(eaddr, dir)
7803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register const u_char *eaddr;
7804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register int dir;
7805478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register struct block *b0, *b1;
7807478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (dir) {
7809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* src comes first, different from Ethernet */
7810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_SRC:
7811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_bcmp(OR_LINK, 0, 1, eaddr);
7812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DST:
7814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return gen_bcmp(OR_LINK, 1, 1, eaddr);
7815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_AND:
7817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_ahostop(eaddr, Q_SRC);
7818478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_ahostop(eaddr, Q_DST);
7819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
7820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
7821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7822478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_DEFAULT:
7823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case Q_OR:
7824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_ahostop(eaddr, Q_SRC);
7825478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_ahostop(eaddr, Q_DST);
7826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
7827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return b1;
7828511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7829511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR1:
7830511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr1' is only supported on 802.11");
7831511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
7832511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7833511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR2:
7834511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr2' is only supported on 802.11");
7835511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
7836511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7837511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR3:
7838511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr3' is only supported on 802.11");
7839511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
7840511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7841511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_ADDR4:
7842511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'addr4' is only supported on 802.11");
7843511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
7844511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7845511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_RA:
7846511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'ra' is only supported on 802.11");
7847511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
7848511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7849511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case Q_TA:
7850511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bpf_error("'ta' is only supported on 802.11");
7851511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
7852478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
7853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	abort();
7854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* NOTREACHED */
7855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
7858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * support IEEE 802.1Q VLAN trunk over ethernet
7859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
7860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_vlan(vlan_num)
7862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int vlan_num;
7863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct	block	*b0, *b1;
7865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* can't check for VLAN-encapsulated packets inside MPLS */
7867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (label_stack_depth > 0)
7868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("no VLAN match after MPLS");
7869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
7871511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Check for a VLAN packet, and then change the offsets to point
7872511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * to the type and data fields within the VLAN packet.  Just
7873511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * increment the offsets, so that we can support a hierarchy, e.g.
7874511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * "vlan 300 && vlan 200" to capture VLAN 200 encapsulated within
7875511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * VLAN 100.
7876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 *
7877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * XXX - this is a bit of a kludge.  If we were to split the
7878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * compiler into a parser that parses an expression and
7879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * generates an expression tree, and a code generator that
7880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * takes an expression tree (which could come from our
7881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * parser or from some other parser) and generates BPF code,
7882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * we could perhaps make the offsets parameters of routines
7883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * and, in the handler for an "AND" node, pass to subnodes
7884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * other than the VLAN node the adjusted offsets.
7885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 *
7886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * This would mean that "vlan" would, instead of changing the
7887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * behavior of *all* tests after it, change only the behavior
7888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * of tests ANDed with it.  That would change the documented
7889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * semantics of "vlan", which might break some expressions.
7890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * However, it would mean that "(vlan and ip) or ip" would check
7891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * both for VLAN-encapsulated IP and IP-over-Ethernet, rather than
7892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * checking only for VLAN-encapsulated IP, so that could still
7893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * be considered worth doing; it wouldn't break expressions
7894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * that are of the form "vlan and ..." or "vlan N and ...",
7895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * which I suspect are the most common expressions involving
7896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * "vlan".  "vlan or ..." doesn't necessarily do what the user
7897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * would really want, now, as all the "or ..." tests would
7898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * be done assuming a VLAN, even though the "or" could be viewed
7899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * as meaning "or, if this isn't a VLAN packet...".
7900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
7901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	orig_nl = off_nl;
7902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (linktype) {
7904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case DLT_EN10MB:
7906511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_NETANALYZER:
7907511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case DLT_NETANALYZER_TRANSPARENT:
7908511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* check for VLAN, including QinQ */
7909511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
7910511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    (bpf_int32)ETHERTYPE_8021Q);
7911511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = gen_cmp(OR_LINK, off_linktype, BPF_H,
7912511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    (bpf_int32)ETHERTYPE_8021QINQ);
7913511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_or(b0,b1);
7914511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = b1;
7915511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7916511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* If a specific VLAN is requested, check VLAN id */
7917511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (vlan_num >= 0) {
7918511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b1 = gen_mcmp(OR_MACPL, 0, BPF_H,
7919511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    (bpf_int32)vlan_num, 0x0fff);
7920511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			gen_and(b0, b1);
7921511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			b0 = b1;
7922511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
7923511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
7924511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl += 4;
7925478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype += 4;
7926511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#if 0
7927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl_nosnap += 4;
7928478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_nl += 4;
7929511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
7930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
7931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7932478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
7933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bpf_error("no VLAN support for data link type %d",
7934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		      linktype);
7935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*NOTREACHED*/
7936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
7937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (b0);
7939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
7940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
7942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * support for MPLS
7943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
7944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
7945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_mpls(label_num)
7946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int label_num;
7947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
7948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct	block	*b0,*b1;
7949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
7951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Change the offsets to point to the type and data fields within
7952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * the MPLS packet.  Just increment the offsets, so that we
7953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * can support a hierarchy, e.g. "mpls 100000 && mpls 1024" to
7954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * capture packets with an outer label of 100000 and an inner
7955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * label of 1024.
7956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 *
7957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * XXX - this is a bit of a kludge.  See comments in gen_vlan().
7958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
7959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        orig_nl = off_nl;
7960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        if (label_stack_depth > 0) {
7962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            /* just match the bottom-of-stack bit clear */
7963511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            b0 = gen_mcmp(OR_MACPL, orig_nl-2, BPF_B, 0, 0x01);
7964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        } else {
7965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            /*
7966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project             * Indicate that we're checking MPLS-encapsulated headers,
7967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project             * to make sure higher level code generators don't try to
7968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project             * match against IP-related protocols such as Q_ARP, Q_RARP
7969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project             * etc.
7970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project             */
7971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            switch (linktype) {
7972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            case DLT_C_HDLC: /* fall through */
7974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            case DLT_EN10MB:
7975511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            case DLT_NETANALYZER:
7976511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            case DLT_NETANALYZER_TRANSPARENT:
7977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                    b0 = gen_linktype(ETHERTYPE_MPLS);
7978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                    break;
7979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            case DLT_PPP:
7981478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                    b0 = gen_linktype(PPP_MPLS_UCAST);
7982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                    break;
7983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7984478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                    /* FIXME add other DLT_s ...
7985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                     * for Frame-Relay/and ATM this may get messy due to SNAP headers
7986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                     * leave it for now */
7987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            default:
7989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                    bpf_error("no MPLS support for data link type %d",
7990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                          linktype);
7991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                    b0 = NULL;
7992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                    /*NOTREACHED*/
7993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                    break;
7994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            }
7995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        }
7996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
7997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* If a specific MPLS label is requested, check it */
7998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (label_num >= 0) {
7999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		label_num = label_num << 12; /* label is shifted 12 bits on the wire */
8000511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = gen_mcmp(OR_MACPL, orig_nl, BPF_W, (bpf_int32)label_num,
8001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    0xfffff000); /* only compare the first 20 bits */
8002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
8003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = b1;
8004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
8005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        off_nl_nosnap += 4;
8007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        off_nl += 4;
8008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        label_stack_depth++;
8009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (b0);
8010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
8011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
8013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Support PPPOE discovery and session.
8014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
8015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
8016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_pppoed()
8017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
8018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* check for PPPoE discovery */
8019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return gen_linktype((bpf_int32)ETHERTYPE_PPPOED);
8020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
8021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
8023511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgen_pppoes(sess_num)
8024511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int sess_num;
8025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
8026511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct block *b0, *b1;
8027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
8029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Test against the PPPoE session link-layer type.
8030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
8031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	b0 = gen_linktype((bpf_int32)ETHERTYPE_PPPOES);
8032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
8034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Change the offsets to point to the type and data fields within
8035511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * the PPP packet, and note that this is PPPoE rather than
8036511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * raw PPP.
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 PPPoE node the adjusted offsets.
8046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 *
8047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * This would mean that "pppoes" 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 "pppoes", which might break some expressions.
8051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * However, it would mean that "(pppoes 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 "pppoes and ..." which I suspect are the
8056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * most common expressions involving "pppoes".  "pppoes or ..."
8057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * doesn't necessarily do what the user would really want, now,
8058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * as all the "or ..." tests would be done assuming PPPoE, even
8059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * though the "or" could be viewed as meaning "or, if this isn't
8060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * a PPPoE packet...".
8061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
8062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	orig_linktype = off_linktype;	/* save original values */
8063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	orig_nl = off_nl;
8064511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	is_pppoes = 1;
8065511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
8066511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/* If a specific session is requested, check PPPoE session id */
8067511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (sess_num >= 0) {
8068511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = gen_mcmp(OR_MACPL, orig_nl, BPF_W,
8069511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    (bpf_int32)sess_num, 0x0000ffff);
8070511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_and(b0, b1);
8071511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = b1;
8072511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
8073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8074478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
8075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * The "network-layer" protocol is PPPoE, which has a 6-byte
8076511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * PPPoE header, followed by a PPP packet.
8077511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 *
8078511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * There is no HDLC encapsulation for the PPP packet (it's
8079511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * encapsulated in PPPoES instead), so the link-layer type
8080511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * starts at the first byte of the PPP packet.  For PPPoE,
8081511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * that offset is relative to the beginning of the total
8082511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * link-layer payload, including any 802.2 LLC header, so
8083511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * it's 6 bytes past off_nl.
8084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
8085511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	off_linktype = off_nl + 6;
8086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
8088511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * The network-layer offsets are relative to the beginning
8089511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * of the MAC-layer payload; that's past the 6-byte
8090511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * PPPoE header and the 2-byte PPP header.
8091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
8092511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	off_nl = 6+2;
8093511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	off_nl_nosnap = 6+2;
8094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b0;
8096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
8097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
8099478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_atmfield_code(atmfield, jvalue, jtype, reverse)
8100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int atmfield;
8101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_int32 jvalue;
8102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 jtype;
8103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int reverse;
8104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
8105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0;
8106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (atmfield) {
8108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_VPI:
8110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (!is_atm)
8111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'vpi' supported only on raw ATM");
8112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (off_vpi == (u_int)-1)
8113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			abort();
8114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_ncmp(OR_LINK, off_vpi, BPF_B, 0xffffffff, jtype,
8115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    reverse, jvalue);
8116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_VCI:
8119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (!is_atm)
8120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'vci' supported only on raw ATM");
8121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (off_vci == (u_int)-1)
8122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			abort();
8123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_ncmp(OR_LINK, off_vci, BPF_H, 0xffffffff, jtype,
8124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    reverse, jvalue);
8125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_PROTOTYPE:
8128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (off_proto == (u_int)-1)
8129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			abort();	/* XXX - this isn't on FreeBSD */
8130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_ncmp(OR_LINK, off_proto, BPF_B, 0x0f, jtype,
8131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    reverse, jvalue);
8132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_MSGTYPE:
8135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (off_payload == (u_int)-1)
8136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			abort();
8137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_ncmp(OR_LINK, off_payload + MSG_TYPE_POS, BPF_B,
8138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    0xffffffff, jtype, reverse, jvalue);
8139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_CALLREFTYPE:
8142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (!is_atm)
8143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'callref' supported only on raw ATM");
8144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (off_proto == (u_int)-1)
8145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			abort();
8146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_ncmp(OR_LINK, off_proto, BPF_B, 0xffffffff,
8147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    jtype, reverse, jvalue);
8148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
8151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
8152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
8153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b0;
8154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
8155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
8157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_atmtype_abbrev(type)
8158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int type;
8159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
8160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1;
8161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (type) {
8163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_METAC:
8165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Get all packets in Meta signalling Circuit */
8166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (!is_atm)
8167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'metac' supported only on raw ATM");
8168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
8169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_atmfield_code(A_VCI, 1, BPF_JEQ, 0);
8170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
8171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_BCC:
8174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Get all packets in Broadcast Circuit*/
8175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (!is_atm)
8176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'bcc' supported only on raw ATM");
8177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
8178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_atmfield_code(A_VCI, 2, BPF_JEQ, 0);
8179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
8180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_OAMF4SC:
8183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Get all cells in Segment OAM F4 circuit*/
8184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (!is_atm)
8185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'oam4sc' supported only on raw ATM");
8186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
8187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_atmfield_code(A_VCI, 3, BPF_JEQ, 0);
8188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
8189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_OAMF4EC:
8192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Get all cells in End-to-End OAM F4 Circuit*/
8193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (!is_atm)
8194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'oam4ec' supported only on raw ATM");
8195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
8196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_atmfield_code(A_VCI, 4, BPF_JEQ, 0);
8197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
8198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_SC:
8201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*  Get all packets in connection Signalling Circuit */
8202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (!is_atm)
8203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'sc' supported only on raw ATM");
8204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
8205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_atmfield_code(A_VCI, 5, BPF_JEQ, 0);
8206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
8207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_ILMIC:
8210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Get all packets in ILMI Circuit */
8211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (!is_atm)
8212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'ilmic' supported only on raw ATM");
8213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
8214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_atmfield_code(A_VCI, 16, BPF_JEQ, 0);
8215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
8216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_LANE:
8219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Get all LANE packets */
8220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (!is_atm)
8221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'lane' supported only on raw ATM");
8222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_atmfield_code(A_PROTOTYPE, PT_LANE, BPF_JEQ, 0);
8223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
8225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Arrange that all subsequent tests assume LANE
8226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * rather than LLC-encapsulated packets, and set
8227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the offsets appropriately for LANE-encapsulated
8228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Ethernet.
8229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 *
8230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * "off_mac" is the offset of the Ethernet header,
8231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * which is 2 bytes past the ATM pseudo-header
8232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * (skipping the pseudo-header and 2-byte LE Client
8233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * field).  The other offsets are Ethernet offsets
8234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * relative to "off_mac".
8235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
8236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		is_lane = 1;
8237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_mac = off_payload + 2;	/* MAC header */
8238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		off_linktype = off_mac + 12;
8239511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_macpl = off_mac + 14;	/* Ethernet */
8240511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl = 0;			/* Ethernet II */
8241511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		off_nl_nosnap = 3;		/* 802.3+802.2 */
8242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_LLC:
8245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Get all LLC-encapsulated packets */
8246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (!is_atm)
8247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'llc' supported only on raw ATM");
8248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_atmfield_code(A_PROTOTYPE, PT_LLC, BPF_JEQ, 0);
8249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		is_lane = 0;
8250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
8253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
8254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
8255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b1;
8256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
8257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
8259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Filtering for MTP2 messages based on li value
8260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * FISU, length is null
8261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LSSU, length is 1 or 2
8262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * MSU, length is 3 or more
8263511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * For MTP2_HSL, sequences are on 2 bytes, and length on 9 bits
8264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
8265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
8266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_mtp2type_abbrev(type)
8267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int type;
8268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
8269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1;
8270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (type) {
8272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case M_FISU:
8274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if ( (linktype != DLT_MTP2) &&
8275511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		     (linktype != DLT_ERF) &&
8276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		     (linktype != DLT_MTP2_WITH_PHDR) )
8277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'fisu' supported only on MTP2");
8278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* gen_ncmp(offrel, offset, size, mask, jtype, reverse, value) */
8279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JEQ, 0, 0);
8280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case M_LSSU:
8283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if ( (linktype != DLT_MTP2) &&
8284511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		     (linktype != DLT_ERF) &&
8285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		     (linktype != DLT_MTP2_WITH_PHDR) )
8286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'lssu' supported only on MTP2");
8287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 1, 2);
8288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 0, 0);
8289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b1, b0);
8290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case M_MSU:
8293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if ( (linktype != DLT_MTP2) &&
8294511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		     (linktype != DLT_ERF) &&
8295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		     (linktype != DLT_MTP2_WITH_PHDR) )
8296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'msu' supported only on MTP2");
8297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 0, 2);
8298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8300511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case MH_FISU:
8301511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if ( (linktype != DLT_MTP2) &&
8302511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		     (linktype != DLT_ERF) &&
8303511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		     (linktype != DLT_MTP2_WITH_PHDR) )
8304511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			bpf_error("'hfisu' supported only on MTP2_HSL");
8305511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* gen_ncmp(offrel, offset, size, mask, jtype, reverse, value) */
8306511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_ncmp(OR_PACKET, off_li_hsl, BPF_H, 0xff80, BPF_JEQ, 0, 0);
8307511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
8308511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
8309511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case MH_LSSU:
8310511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if ( (linktype != DLT_MTP2) &&
8311511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		     (linktype != DLT_ERF) &&
8312511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		     (linktype != DLT_MTP2_WITH_PHDR) )
8313511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			bpf_error("'hlssu' supported only on MTP2_HSL");
8314511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_ncmp(OR_PACKET, off_li_hsl, BPF_H, 0xff80, BPF_JGT, 1, 0x0100);
8315511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b1 = gen_ncmp(OR_PACKET, off_li_hsl, BPF_H, 0xff80, BPF_JGT, 0, 0);
8316511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gen_and(b1, b0);
8317511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
8318511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
8319511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case MH_MSU:
8320511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if ( (linktype != DLT_MTP2) &&
8321511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		     (linktype != DLT_ERF) &&
8322511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		     (linktype != DLT_MTP2_WITH_PHDR) )
8323511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			bpf_error("'hmsu' supported only on MTP2_HSL");
8324511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_ncmp(OR_PACKET, off_li_hsl, BPF_H, 0xff80, BPF_JGT, 0, 0x0100);
8325511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
8326511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
8327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
8328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
8329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
8330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b0;
8331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
8332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
8334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_mtp3field_code(mtp3field, jvalue, jtype, reverse)
8335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int mtp3field;
8336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 jvalue;
8337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 jtype;
8338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int reverse;
8339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
8340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0;
8341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32 val1 , val2 , val3;
8342511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_int newoff_sio=off_sio;
8343511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_int newoff_opc=off_opc;
8344511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_int newoff_dpc=off_dpc;
8345511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_int newoff_sls=off_sls;
8346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (mtp3field) {
8348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8349511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case MH_SIO:
8350511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		newoff_sio += 3; /* offset for MTP2_HSL */
8351511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* FALLTHROUGH */
8352511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
8353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case M_SIO:
8354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (off_sio == (u_int)-1)
8355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'sio' supported only on SS7");
8356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* sio coded on 1 byte so max value 255 */
8357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if(jvalue > 255)
8358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		        bpf_error("sio value %u too big; max value = 255",
8359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		            jvalue);
8360511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_ncmp(OR_PACKET, newoff_sio, BPF_B, 0xffffffff,
8361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    (u_int)jtype, reverse, (u_int)jvalue);
8362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8364511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case MH_OPC:
8365511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		newoff_opc+=3;
8366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        case M_OPC:
8367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	        if (off_opc == (u_int)-1)
8368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'opc' supported only on SS7");
8369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* opc coded on 14 bits so max value 16383 */
8370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (jvalue > 16383)
8371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		        bpf_error("opc value %u too big; max value = 16383",
8372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		            jvalue);
8373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* the following instructions are made to convert jvalue
8374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * to the form used to write opc in an ss7 message*/
8375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		val1 = jvalue & 0x00003c00;
8376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		val1 = val1 >>10;
8377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		val2 = jvalue & 0x000003fc;
8378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		val2 = val2 <<6;
8379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		val3 = jvalue & 0x00000003;
8380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		val3 = val3 <<22;
8381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		jvalue = val1 + val2 + val3;
8382511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_ncmp(OR_PACKET, newoff_opc, BPF_W, 0x00c0ff0f,
8383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    (u_int)jtype, reverse, (u_int)jvalue);
8384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8386511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case MH_DPC:
8387511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		newoff_dpc += 3;
8388511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* FALLTHROUGH */
8389511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
8390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case M_DPC:
8391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	        if (off_dpc == (u_int)-1)
8392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'dpc' supported only on SS7");
8393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* dpc coded on 14 bits so max value 16383 */
8394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (jvalue > 16383)
8395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		        bpf_error("dpc value %u too big; max value = 16383",
8396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		            jvalue);
8397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* the following instructions are made to convert jvalue
8398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * to the forme used to write dpc in an ss7 message*/
8399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		val1 = jvalue & 0x000000ff;
8400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		val1 = val1 << 24;
8401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		val2 = jvalue & 0x00003f00;
8402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		val2 = val2 << 8;
8403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		jvalue = val1 + val2;
8404511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_ncmp(OR_PACKET, newoff_dpc, BPF_W, 0xff3f0000,
8405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    (u_int)jtype, reverse, (u_int)jvalue);
8406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8408511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case MH_SLS:
8409511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	  newoff_sls+=3;
8410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case M_SLS:
8411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	        if (off_sls == (u_int)-1)
8412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'sls' supported only on SS7");
8413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* sls coded on 4 bits so max value 15 */
8414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (jvalue > 15)
8415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		         bpf_error("sls value %u too big; max value = 15",
8416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		             jvalue);
8417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* the following instruction is made to convert jvalue
8418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * to the forme used to write sls in an ss7 message*/
8419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		jvalue = jvalue << 4;
8420511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		b0 = gen_ncmp(OR_PACKET, newoff_sls, BPF_B, 0xf0,
8421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    (u_int)jtype,reverse, (u_int)jvalue);
8422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
8425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
8426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
8427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b0;
8428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
8429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct block *
8431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_msg_abbrev(type)
8432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int type;
8433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
8434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b1;
8435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
8437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Q.2931 signalling protocol messages for handling virtual circuits
8438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * establishment and teardown
8439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
8440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (type) {
8441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_SETUP:
8443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_atmfield_code(A_MSGTYPE, SETUP, BPF_JEQ, 0);
8444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_CALLPROCEED:
8447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_atmfield_code(A_MSGTYPE, CALL_PROCEED, BPF_JEQ, 0);
8448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_CONNECT:
8451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_atmfield_code(A_MSGTYPE, CONNECT, BPF_JEQ, 0);
8452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_CONNECTACK:
8455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_atmfield_code(A_MSGTYPE, CONNECT_ACK, BPF_JEQ, 0);
8456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_RELEASE:
8459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_atmfield_code(A_MSGTYPE, RELEASE, BPF_JEQ, 0);
8460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_RELEASE_DONE:
8463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_atmfield_code(A_MSGTYPE, RELEASE_DONE, BPF_JEQ, 0);
8464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
8467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
8468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
8469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b1;
8470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
8471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct block *
8473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectgen_atmmulti_abbrev(type)
8474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int type;
8475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
8476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct block *b0, *b1;
8477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (type) {
8479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_OAM:
8481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (!is_atm)
8482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'oam' supported only on raw ATM");
8483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_atmmulti_abbrev(A_OAMF4);
8484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_OAMF4:
8487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (!is_atm)
8488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'oamf4' supported only on raw ATM");
8489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* OAM F4 type */
8490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_atmfield_code(A_VCI, 3, BPF_JEQ, 0);
8491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_atmfield_code(A_VCI, 4, BPF_JEQ, 0);
8492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
8493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
8494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
8495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_CONNECTMSG:
8498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
8499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Get Q.2931 signalling messages for switched
8500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * virtual connection
8501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
8502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (!is_atm)
8503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'connectmsg' supported only on raw ATM");
8504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_msg_abbrev(A_SETUP);
8505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_msg_abbrev(A_CALLPROCEED);
8506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
8507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_msg_abbrev(A_CONNECT);
8508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
8509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_msg_abbrev(A_CONNECTACK);
8510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
8511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_msg_abbrev(A_RELEASE);
8512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
8513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_msg_abbrev(A_RELEASE_DONE);
8514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
8515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_atmtype_abbrev(A_SC);
8516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
8517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case A_METACONNECT:
8520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (!is_atm)
8521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			bpf_error("'metaconnect' supported only on raw ATM");
8522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_msg_abbrev(A_SETUP);
8523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b1 = gen_msg_abbrev(A_CALLPROCEED);
8524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
8525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_msg_abbrev(A_CONNECT);
8526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
8527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_msg_abbrev(A_RELEASE);
8528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
8529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_msg_abbrev(A_RELEASE_DONE);
8530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_or(b0, b1);
8531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		b0 = gen_atmtype_abbrev(A_METAC);
8532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		gen_and(b0, b1);
8533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
8534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
8535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
8536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		abort();
8537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
8538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return b1;
8539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
8540