summaryrefslogtreecommitdiffstats
path: root/freebsd/contrib/libpcap
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2015-06-15 17:42:23 +1000
committerChris Johns <chrisj@rtems.org>2015-06-15 17:42:23 +1000
commit8440506ee8945ad57f5e20e9962084d67808eb22 (patch)
tree38f567b1c56846b88f5f0828bd244b05519998ba /freebsd/contrib/libpcap
parentUpdate LibBSD doco. (diff)
downloadrtems-libbsd-8440506ee8945ad57f5e20e9962084d67808eb22.tar.bz2
Add tcpdump and libpcap.
- Update the file builder generator to handle generator specific cflags and includes. The tcpdump and libpcap have localised headers and need specific headers paths to see them. There are also module specific flags and these need to be passed to the lex and yacc generators. - Add the tcpdump support.
Diffstat (limited to 'freebsd/contrib/libpcap')
-rw-r--r--freebsd/contrib/libpcap/arcnet.h52
-rw-r--r--freebsd/contrib/libpcap/atmuni31.h87
-rw-r--r--freebsd/contrib/libpcap/bpf_image.c307
-rw-r--r--freebsd/contrib/libpcap/etherent.c176
-rw-r--r--freebsd/contrib/libpcap/ethertype.h122
-rw-r--r--freebsd/contrib/libpcap/fad-getad.c288
-rw-r--r--freebsd/contrib/libpcap/gencode.c8493
-rw-r--r--freebsd/contrib/libpcap/gencode.h343
-rw-r--r--freebsd/contrib/libpcap/grammar.c2280
-rw-r--r--freebsd/contrib/libpcap/grammar.y698
-rw-r--r--freebsd/contrib/libpcap/ieee80211.h146
-rw-r--r--freebsd/contrib/libpcap/inet.c935
-rw-r--r--freebsd/contrib/libpcap/llc.h69
-rw-r--r--freebsd/contrib/libpcap/nametoaddr.c525
-rw-r--r--freebsd/contrib/libpcap/nlpid.h58
-rw-r--r--freebsd/contrib/libpcap/optimize.c2249
-rw-r--r--freebsd/contrib/libpcap/pcap-bpf.c2719
-rw-r--r--freebsd/contrib/libpcap/pcap-common.c1174
-rw-r--r--freebsd/contrib/libpcap/pcap-common.h25
-rw-r--r--freebsd/contrib/libpcap/pcap-int.h513
-rw-r--r--freebsd/contrib/libpcap/pcap-namedb.h42
-rw-r--r--freebsd/contrib/libpcap/pcap.c1812
-rw-r--r--freebsd/contrib/libpcap/pcap.h45
-rw-r--r--freebsd/contrib/libpcap/pcap/ipnet.h43
-rw-r--r--freebsd/contrib/libpcap/pcap/namedb.h89
-rw-r--r--freebsd/contrib/libpcap/pcap/pcap.h461
-rw-r--r--freebsd/contrib/libpcap/pcap/sll.h129
-rw-r--r--freebsd/contrib/libpcap/pcap/usb.h143
-rw-r--r--freebsd/contrib/libpcap/ppp.h58
-rw-r--r--freebsd/contrib/libpcap/savefile.c396
-rw-r--r--freebsd/contrib/libpcap/scanner.c4890
-rw-r--r--freebsd/contrib/libpcap/scanner.l455
-rw-r--r--freebsd/contrib/libpcap/sf-pcap-ng.c1111
-rw-r--r--freebsd/contrib/libpcap/sf-pcap-ng.h31
-rw-r--r--freebsd/contrib/libpcap/sf-pcap.c620
-rw-r--r--freebsd/contrib/libpcap/sf-pcap.h36
-rw-r--r--freebsd/contrib/libpcap/sunatmpos.h45
37 files changed, 31665 insertions, 0 deletions
diff --git a/freebsd/contrib/libpcap/arcnet.h b/freebsd/contrib/libpcap/arcnet.h
new file mode 100644
index 00000000..4f86043e
--- /dev/null
+++ b/freebsd/contrib/libpcap/arcnet.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Id: arcnet.h,v 1.2 2001-04-24 02:17:52 guy Exp $ (LBL)
+ *
+ * from: NetBSD: if_arc.h,v 1.13 1999/11/19 20:41:19 thorpej Exp
+ */
+
+/* RFC 1051 */
+#define ARCTYPE_IP_OLD 240 /* IP protocol */
+#define ARCTYPE_ARP_OLD 241 /* address resolution protocol */
+
+/* RFC 1201 */
+#define ARCTYPE_IP 212 /* IP protocol */
+#define ARCTYPE_ARP 213 /* address resolution protocol */
+#define ARCTYPE_REVARP 214 /* reverse addr resolution protocol */
+
+#define ARCTYPE_ATALK 221 /* Appletalk */
+#define ARCTYPE_BANIAN 247 /* Banyan Vines */
+#define ARCTYPE_IPX 250 /* Novell IPX */
+
+#define ARCTYPE_INET6 0xc4 /* IPng */
+#define ARCTYPE_DIAGNOSE 0x80 /* as per ANSI/ATA 878.1 */
diff --git a/freebsd/contrib/libpcap/atmuni31.h b/freebsd/contrib/libpcap/atmuni31.h
new file mode 100644
index 00000000..880cc1a8
--- /dev/null
+++ b/freebsd/contrib/libpcap/atmuni31.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1997 Yen Yen Lim and North Dakota State University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Yen Yen Lim and
+ North Dakota State University
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/atmuni31.h,v 1.3 2007-10-22 19:28:58 guy Exp $ (LBL)
+ */
+
+/* Based on UNI3.1 standard by ATM Forum */
+
+/* ATM traffic types based on VPI=0 and (the following VCI */
+#define VCI_PPC 0x05 /* Point-to-point signal msg */
+#define VCI_BCC 0x02 /* Broadcast signal msg */
+#define VCI_OAMF4SC 0x03 /* Segment OAM F4 flow cell */
+#define VCI_OAMF4EC 0x04 /* End-to-end OAM F4 flow cell */
+#define VCI_METAC 0x01 /* Meta signal msg */
+#define VCI_ILMIC 0x10 /* ILMI msg */
+
+/* Q.2931 signalling messages */
+#define CALL_PROCEED 0x02 /* call proceeding */
+#define CONNECT 0x07 /* connect */
+#define CONNECT_ACK 0x0f /* connect_ack */
+#define SETUP 0x05 /* setup */
+#define RELEASE 0x4d /* release */
+#define RELEASE_DONE 0x5a /* release_done */
+#define RESTART 0x46 /* restart */
+#define RESTART_ACK 0x4e /* restart ack */
+#define STATUS 0x7d /* status */
+#define STATUS_ENQ 0x75 /* status ack */
+#define ADD_PARTY 0x80 /* add party */
+#define ADD_PARTY_ACK 0x81 /* add party ack */
+#define ADD_PARTY_REJ 0x82 /* add party rej */
+#define DROP_PARTY 0x83 /* drop party */
+#define DROP_PARTY_ACK 0x84 /* drop party ack */
+
+/* Information Element Parameters in the signalling messages */
+#define CAUSE 0x08 /* cause */
+#define ENDPT_REF 0x54 /* endpoint reference */
+#define AAL_PARA 0x58 /* ATM adaptation layer parameters */
+#define TRAFF_DESCRIP 0x59 /* atm traffic descriptors */
+#define CONNECT_ID 0x5a /* connection identifier */
+#define QOS_PARA 0x5c /* quality of service parameters */
+#define B_HIGHER 0x5d /* broadband higher layer information */
+#define B_BEARER 0x5e /* broadband bearer capability */
+#define B_LOWER 0x5f /* broadband lower information */
+#define CALLING_PARTY 0x6c /* calling party number */
+#define CALLED_PARTY 0x70 /* called party nmber */
+
+#define Q2931 0x09
+
+/* Q.2931 signalling general messages format */
+#define PROTO_POS 0 /* offset of protocol discriminator */
+#define CALL_REF_POS 2 /* offset of call reference value */
+#define MSG_TYPE_POS 5 /* offset of message type */
+#define MSG_LEN_POS 7 /* offset of mesage length */
+#define IE_BEGIN_POS 9 /* offset of first information element */
+
+/* format of signalling messages */
+#define TYPE_POS 0
+#define LEN_POS 2
+#define FIELD_BEGIN_POS 4
diff --git a/freebsd/contrib/libpcap/bpf_image.c b/freebsd/contrib/libpcap/bpf_image.c
new file mode 100644
index 00000000..07018b33
--- /dev/null
+++ b/freebsd/contrib/libpcap/bpf_image.c
@@ -0,0 +1,307 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1990, 1991, 1992, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/bpf_image.c,v 1.28 2008-01-02 04:16:46 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/types.h>
+#endif /* WIN32 */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "pcap-int.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+char *
+bpf_image(p, n)
+ struct bpf_insn *p;
+ int n;
+{
+ int v;
+ const char *fmt, *op;
+ static char image[256];
+ char operand[64];
+
+ v = p->k;
+ switch (p->code) {
+
+ default:
+ op = "unimp";
+ fmt = "0x%x";
+ v = p->code;
+ break;
+
+ case BPF_RET|BPF_K:
+ op = "ret";
+ fmt = "#%d";
+ break;
+
+ case BPF_RET|BPF_A:
+ op = "ret";
+ fmt = "";
+ break;
+
+ case BPF_LD|BPF_W|BPF_ABS:
+ op = "ld";
+ fmt = "[%d]";
+ break;
+
+ case BPF_LD|BPF_H|BPF_ABS:
+ op = "ldh";
+ fmt = "[%d]";
+ break;
+
+ case BPF_LD|BPF_B|BPF_ABS:
+ op = "ldb";
+ fmt = "[%d]";
+ break;
+
+ case BPF_LD|BPF_W|BPF_LEN:
+ op = "ld";
+ fmt = "#pktlen";
+ break;
+
+ case BPF_LD|BPF_W|BPF_IND:
+ op = "ld";
+ fmt = "[x + %d]";
+ break;
+
+ case BPF_LD|BPF_H|BPF_IND:
+ op = "ldh";
+ fmt = "[x + %d]";
+ break;
+
+ case BPF_LD|BPF_B|BPF_IND:
+ op = "ldb";
+ fmt = "[x + %d]";
+ break;
+
+ case BPF_LD|BPF_IMM:
+ op = "ld";
+ fmt = "#0x%x";
+ break;
+
+ case BPF_LDX|BPF_IMM:
+ op = "ldx";
+ fmt = "#0x%x";
+ break;
+
+ case BPF_LDX|BPF_MSH|BPF_B:
+ op = "ldxb";
+ fmt = "4*([%d]&0xf)";
+ break;
+
+ case BPF_LD|BPF_MEM:
+ op = "ld";
+ fmt = "M[%d]";
+ break;
+
+ case BPF_LDX|BPF_MEM:
+ op = "ldx";
+ fmt = "M[%d]";
+ break;
+
+ case BPF_ST:
+ op = "st";
+ fmt = "M[%d]";
+ break;
+
+ case BPF_STX:
+ op = "stx";
+ fmt = "M[%d]";
+ break;
+
+ case BPF_JMP|BPF_JA:
+ op = "ja";
+ fmt = "%d";
+ v = n + 1 + p->k;
+ break;
+
+ case BPF_JMP|BPF_JGT|BPF_K:
+ op = "jgt";
+ fmt = "#0x%x";
+ break;
+
+ case BPF_JMP|BPF_JGE|BPF_K:
+ op = "jge";
+ fmt = "#0x%x";
+ break;
+
+ case BPF_JMP|BPF_JEQ|BPF_K:
+ op = "jeq";
+ fmt = "#0x%x";
+ break;
+
+ case BPF_JMP|BPF_JSET|BPF_K:
+ op = "jset";
+ fmt = "#0x%x";
+ break;
+
+ case BPF_JMP|BPF_JGT|BPF_X:
+ op = "jgt";
+ fmt = "x";
+ break;
+
+ case BPF_JMP|BPF_JGE|BPF_X:
+ op = "jge";
+ fmt = "x";
+ break;
+
+ case BPF_JMP|BPF_JEQ|BPF_X:
+ op = "jeq";
+ fmt = "x";
+ break;
+
+ case BPF_JMP|BPF_JSET|BPF_X:
+ op = "jset";
+ fmt = "x";
+ break;
+
+ case BPF_ALU|BPF_ADD|BPF_X:
+ op = "add";
+ fmt = "x";
+ break;
+
+ case BPF_ALU|BPF_SUB|BPF_X:
+ op = "sub";
+ fmt = "x";
+ break;
+
+ case BPF_ALU|BPF_MUL|BPF_X:
+ op = "mul";
+ fmt = "x";
+ break;
+
+ case BPF_ALU|BPF_DIV|BPF_X:
+ op = "div";
+ fmt = "x";
+ break;
+
+ case BPF_ALU|BPF_AND|BPF_X:
+ op = "and";
+ fmt = "x";
+ break;
+
+ case BPF_ALU|BPF_OR|BPF_X:
+ op = "or";
+ fmt = "x";
+ break;
+
+ case BPF_ALU|BPF_LSH|BPF_X:
+ op = "lsh";
+ fmt = "x";
+ break;
+
+ case BPF_ALU|BPF_RSH|BPF_X:
+ op = "rsh";
+ fmt = "x";
+ break;
+
+ case BPF_ALU|BPF_ADD|BPF_K:
+ op = "add";
+ fmt = "#%d";
+ break;
+
+ case BPF_ALU|BPF_SUB|BPF_K:
+ op = "sub";
+ fmt = "#%d";
+ break;
+
+ case BPF_ALU|BPF_MUL|BPF_K:
+ op = "mul";
+ fmt = "#%d";
+ break;
+
+ case BPF_ALU|BPF_DIV|BPF_K:
+ op = "div";
+ fmt = "#%d";
+ break;
+
+ case BPF_ALU|BPF_AND|BPF_K:
+ op = "and";
+ fmt = "#0x%x";
+ break;
+
+ case BPF_ALU|BPF_OR|BPF_K:
+ op = "or";
+ fmt = "#0x%x";
+ break;
+
+ case BPF_ALU|BPF_LSH|BPF_K:
+ op = "lsh";
+ fmt = "#%d";
+ break;
+
+ case BPF_ALU|BPF_RSH|BPF_K:
+ op = "rsh";
+ fmt = "#%d";
+ break;
+
+ case BPF_ALU|BPF_NEG:
+ op = "neg";
+ fmt = "";
+ break;
+
+ case BPF_MISC|BPF_TAX:
+ op = "tax";
+ fmt = "";
+ break;
+
+ case BPF_MISC|BPF_TXA:
+ op = "txa";
+ fmt = "";
+ break;
+ }
+ (void)snprintf(operand, sizeof operand, fmt, v);
+ if (BPF_CLASS(p->code) == BPF_JMP && BPF_OP(p->code) != BPF_JA) {
+ (void)snprintf(image, sizeof image,
+ "(%03d) %-8s %-16s jt %d\tjf %d",
+ n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
+ } else {
+ (void)snprintf(image, sizeof image,
+ "(%03d) %-8s %s",
+ n, op, operand);
+ }
+ return image;
+}
diff --git a/freebsd/contrib/libpcap/etherent.c b/freebsd/contrib/libpcap/etherent.c
new file mode 100644
index 00000000..166eb3a4
--- /dev/null
+++ b/freebsd/contrib/libpcap/etherent.c
@@ -0,0 +1,176 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.23 2006-10-04 18:09:22 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/types.h>
+#endif /* WIN32 */
+
+#include <ctype.h>
+#include <memory.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "pcap-int.h"
+
+#include <pcap/namedb.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+static inline int xdtoi(int);
+static inline int skip_space(FILE *);
+static inline int skip_line(FILE *);
+
+/* Hex digit to integer. */
+static inline int
+xdtoi(c)
+ register int c;
+{
+ if (isdigit(c))
+ return c - '0';
+ else if (islower(c))
+ return c - 'a' + 10;
+ else
+ return c - 'A' + 10;
+}
+
+static inline int
+skip_space(f)
+ FILE *f;
+{
+ int c;
+
+ do {
+ c = getc(f);
+ } while (isspace(c) && c != '\n');
+
+ return c;
+}
+
+static inline int
+skip_line(f)
+ FILE *f;
+{
+ int c;
+
+ do
+ c = getc(f);
+ while (c != '\n' && c != EOF);
+
+ return c;
+}
+
+struct pcap_etherent *
+pcap_next_etherent(FILE *fp)
+{
+ register int c, d, i;
+ char *bp;
+ static struct pcap_etherent e;
+
+ memset((char *)&e, 0, sizeof(e));
+ do {
+ /* Find addr */
+ c = skip_space(fp);
+ if (c == '\n')
+ continue;
+
+ /* If this is a comment, or first thing on line
+ cannot be etehrnet address, skip the line. */
+ if (!isxdigit(c)) {
+ c = skip_line(fp);
+ continue;
+ }
+
+ /* must be the start of an address */
+ for (i = 0; i < 6; i += 1) {
+ d = xdtoi(c);
+ c = getc(fp);
+ if (isxdigit(c)) {
+ d <<= 4;
+ d |= xdtoi(c);
+ c = getc(fp);
+ }
+ e.addr[i] = d;
+ if (c != ':')
+ break;
+ c = getc(fp);
+ }
+ if (c == EOF)
+ break;
+
+ /* Must be whitespace */
+ if (!isspace(c)) {
+ c = skip_line(fp);
+ continue;
+ }
+ c = skip_space(fp);
+
+ /* hit end of line... */
+ if (c == '\n')
+ continue;
+
+ if (c == '#') {
+ c = skip_line(fp);
+ continue;
+ }
+
+ /* pick up name */
+ bp = e.name;
+ /* Use 'd' to prevent buffer overflow. */
+ d = sizeof(e.name) - 1;
+ do {
+ *bp++ = c;
+ c = getc(fp);
+ } while (!isspace(c) && c != EOF && --d > 0);
+ *bp = '\0';
+
+ /* Eat trailing junk */
+ if (c != '\n')
+ (void)skip_line(fp);
+
+ return &e;
+
+ } while (c != EOF);
+
+ return (NULL);
+}
diff --git a/freebsd/contrib/libpcap/ethertype.h b/freebsd/contrib/libpcap/ethertype.h
new file mode 100644
index 00000000..2d6bbebd
--- /dev/null
+++ b/freebsd/contrib/libpcap/ethertype.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 1993, 1994, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/ethertype.h,v 1.14 2005-09-05 09:06:58 guy Exp $ (LBL)
+ */
+
+/*
+ * Ethernet types.
+ *
+ * We wrap the declarations with #ifdef, so that if a file includes
+ * <netinet/if_ether.h>, which may declare some of these, we don't
+ * get a bunch of complaints from the C compiler about redefinitions
+ * of these values.
+ *
+ * We declare all of them here so that no file has to include
+ * <netinet/if_ether.h> if all it needs are ETHERTYPE_ values.
+ */
+
+#ifndef ETHERTYPE_PUP
+#define ETHERTYPE_PUP 0x0200 /* PUP protocol */
+#endif
+#ifndef ETHERTYPE_IP
+#define ETHERTYPE_IP 0x0800 /* IP protocol */
+#endif
+#ifndef ETHERTYPE_ARP
+#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */
+#endif
+#ifndef ETHERTYPE_REVARP
+#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */
+#endif
+#ifndef ETHERTYPE_NS
+#define ETHERTYPE_NS 0x0600
+#endif
+#ifndef ETHERTYPE_SPRITE
+#define ETHERTYPE_SPRITE 0x0500
+#endif
+#ifndef ETHERTYPE_TRAIL
+#define ETHERTYPE_TRAIL 0x1000
+#endif
+#ifndef ETHERTYPE_MOPDL
+#define ETHERTYPE_MOPDL 0x6001
+#endif
+#ifndef ETHERTYPE_MOPRC
+#define ETHERTYPE_MOPRC 0x6002
+#endif
+#ifndef ETHERTYPE_DN
+#define ETHERTYPE_DN 0x6003
+#endif
+#ifndef ETHERTYPE_LAT
+#define ETHERTYPE_LAT 0x6004
+#endif
+#ifndef ETHERTYPE_SCA
+#define ETHERTYPE_SCA 0x6007
+#endif
+#ifndef ETHERTYPE_REVARP
+#define ETHERTYPE_REVARP 0x8035
+#endif
+#ifndef ETHERTYPE_LANBRIDGE
+#define ETHERTYPE_LANBRIDGE 0x8038
+#endif
+#ifndef ETHERTYPE_DECDNS
+#define ETHERTYPE_DECDNS 0x803c
+#endif
+#ifndef ETHERTYPE_DECDTS
+#define ETHERTYPE_DECDTS 0x803e
+#endif
+#ifndef ETHERTYPE_VEXP
+#define ETHERTYPE_VEXP 0x805b
+#endif
+#ifndef ETHERTYPE_VPROD
+#define ETHERTYPE_VPROD 0x805c
+#endif
+#ifndef ETHERTYPE_ATALK
+#define ETHERTYPE_ATALK 0x809b
+#endif
+#ifndef ETHERTYPE_AARP
+#define ETHERTYPE_AARP 0x80f3
+#endif
+#ifndef ETHERTYPE_8021Q
+#define ETHERTYPE_8021Q 0x8100
+#endif
+#ifndef ETHERTYPE_IPX
+#define ETHERTYPE_IPX 0x8137
+#endif
+#ifndef ETHERTYPE_IPV6
+#define ETHERTYPE_IPV6 0x86dd
+#endif
+#ifndef ETHERTYPE_MPLS
+#define ETHERTYPE_MPLS 0x8847
+#endif
+#ifndef ETHERTYPE_MPLS_MULTI
+#define ETHERTYPE_MPLS_MULTI 0x8848
+#endif
+#ifndef ETHERTYPE_PPPOED
+#define ETHERTYPE_PPPOED 0x8863
+#endif
+#ifndef ETHERTYPE_PPPOES
+#define ETHERTYPE_PPPOES 0x8864
+#endif
+#ifndef ETHERTYPE_LOOPBACK
+#define ETHERTYPE_LOOPBACK 0x9000
+#endif
+#ifndef ETHERTYPE_8021QINQ
+#define ETHERTYPE_8021QINQ 0x9100
+#endif
diff --git a/freebsd/contrib/libpcap/fad-getad.c b/freebsd/contrib/libpcap/fad-getad.c
new file mode 100644
index 00000000..2a5b549a
--- /dev/null
+++ b/freebsd/contrib/libpcap/fad-getad.c
@@ -0,0 +1,288 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
+/*
+ * Copyright (c) 1994, 1995, 1996, 1997, 1998
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/fad-getad.c,v 1.12 2007-09-14 00:44:55 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/bsd/sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <net/if.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ifaddrs.h>
+
+#include "pcap-int.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#ifdef AF_PACKET
+# ifdef HAVE_NETPACKET_PACKET_H
+/* Solaris 11 and later, Linux distributions with newer glibc */
+# include <netpacket/packet.h>
+# else /* HAVE_NETPACKET_PACKET_H */
+/* LynxOS, Linux distributions with older glibc */
+# ifdef __Lynx__
+/* LynxOS */
+# include <netpacket/if_packet.h>
+# else /* __Lynx__ */
+/* Linux */
+# include <linux/types.h>
+# include <linux/if_packet.h>
+# endif /* __Lynx__ */
+# endif /* HAVE_NETPACKET_PACKET_H */
+#endif /* AF_PACKET */
+
+/*
+ * This is fun.
+ *
+ * In older BSD systems, socket addresses were fixed-length, and
+ * "sizeof (struct sockaddr)" gave the size of the structure.
+ * All addresses fit within a "struct sockaddr".
+ *
+ * In newer BSD systems, the socket address is variable-length, and
+ * there's an "sa_len" field giving the length of the structure;
+ * this allows socket addresses to be longer than 2 bytes of family
+ * and 14 bytes of data.
+ *
+ * Some commercial UNIXes use the old BSD scheme, some use the RFC 2553
+ * variant of the old BSD scheme (with "struct sockaddr_storage" rather
+ * than "struct sockaddr"), and some use the new BSD scheme.
+ *
+ * Some versions of GNU libc use neither scheme, but has an "SA_LEN()"
+ * macro that determines the size based on the address family. Other
+ * versions don't have "SA_LEN()" (as it was in drafts of RFC 2553
+ * but not in the final version). On the latter systems, we explicitly
+ * check the AF_ type to determine the length; we assume that on
+ * all those systems we have "struct sockaddr_storage".
+ */
+#ifndef SA_LEN
+#ifdef HAVE_SOCKADDR_SA_LEN
+#define SA_LEN(addr) ((addr)->sa_len)
+#else /* HAVE_SOCKADDR_SA_LEN */
+#ifdef HAVE_SOCKADDR_STORAGE
+static size_t
+get_sa_len(struct sockaddr *addr)
+{
+ switch (addr->sa_family) {
+
+#ifdef AF_INET
+ case AF_INET:
+ return (sizeof (struct sockaddr_in));
+#endif
+
+#ifdef AF_INET6
+ case AF_INET6:
+ return (sizeof (struct sockaddr_in6));
+#endif
+
+#ifdef AF_PACKET
+ case AF_PACKET:
+ return (sizeof (struct sockaddr_ll));
+#endif
+
+ default:
+ return (sizeof (struct sockaddr));
+ }
+}
+#define SA_LEN(addr) (get_sa_len(addr))
+#else /* HAVE_SOCKADDR_STORAGE */
+#define SA_LEN(addr) (sizeof (struct sockaddr))
+#endif /* HAVE_SOCKADDR_STORAGE */
+#endif /* HAVE_SOCKADDR_SA_LEN */
+#endif /* SA_LEN */
+
+/*
+ * Get a list of all interfaces that are up and that we can open.
+ * Returns -1 on error, 0 otherwise.
+ * The list, as returned through "alldevsp", may be null if no interfaces
+ * were up and could be opened.
+ */
+int
+pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
+{
+ pcap_if_t *devlist = NULL;
+ struct ifaddrs *ifap, *ifa;
+ struct sockaddr *addr, *netmask, *broadaddr, *dstaddr;
+ size_t addr_size, broadaddr_size, dstaddr_size;
+ int ret = 0;
+ char *p, *q;
+
+ /*
+ * Get the list of interface addresses.
+ *
+ * Note: this won't return information about interfaces
+ * with no addresses; are there any such interfaces
+ * that would be capable of receiving packets?
+ * (Interfaces incapable of receiving packets aren't
+ * very interesting from libpcap's point of view.)
+ *
+ * LAN interfaces will probably have link-layer
+ * addresses; I don't know whether all implementations
+ * of "getifaddrs()" now, or in the future, will return
+ * those.
+ */
+ if (getifaddrs(&ifap) != 0) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "getifaddrs: %s", pcap_strerror(errno));
+ return (-1);
+ }
+ for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
+ /*
+ * Is this interface up?
+ */
+ if (!(ifa->ifa_flags & IFF_UP)) {
+ /*
+ * No, so don't add it to the list.
+ */
+ continue;
+ }
+
+ /*
+ * "ifa_addr" was apparently null on at least one
+ * interface on some system.
+ *
+ * "ifa_broadaddr" may be non-null even on
+ * non-broadcast interfaces, and was null on
+ * at least one OpenBSD 3.4 system on at least
+ * one interface with IFF_BROADCAST set.
+ *
+ * "ifa_dstaddr" was, on at least one FreeBSD 4.1
+ * system, non-null on a non-point-to-point
+ * interface.
+ *
+ * Therefore, we supply the address and netmask only
+ * if "ifa_addr" is non-null (if there's no address,
+ * there's obviously no netmask), and supply the
+ * broadcast and destination addresses if the appropriate
+ * flag is set *and* the appropriate "ifa_" entry doesn't
+ * evaluate to a null pointer.
+ */
+ if (ifa->ifa_addr != NULL) {
+ addr = ifa->ifa_addr;
+ addr_size = SA_LEN(addr);
+ netmask = ifa->ifa_netmask;
+ } else {
+ addr = NULL;
+ addr_size = 0;
+ netmask = NULL;
+ }
+ if (ifa->ifa_flags & IFF_BROADCAST &&
+ ifa->ifa_broadaddr != NULL) {
+ broadaddr = ifa->ifa_broadaddr;
+ broadaddr_size = SA_LEN(broadaddr);
+ } else {
+ broadaddr = NULL;
+ broadaddr_size = 0;
+ }
+ if (ifa->ifa_flags & IFF_POINTOPOINT &&
+ ifa->ifa_dstaddr != NULL) {
+ dstaddr = ifa->ifa_dstaddr;
+ dstaddr_size = SA_LEN(ifa->ifa_dstaddr);
+ } else {
+ dstaddr = NULL;
+ dstaddr_size = 0;
+ }
+
+ /*
+ * If this entry has a colon followed by a number at
+ * the end, we assume it's a logical interface. Those
+ * are just the way you assign multiple IP addresses to
+ * a real interface on Linux, so an entry for a logical
+ * interface should be treated like the entry for the
+ * real interface; we do that by stripping off the ":"
+ * and the number.
+ *
+ * XXX - should we do this only on Linux?
+ */
+ p = strchr(ifa->ifa_name, ':');
+ if (p != NULL) {
+ /*
+ * We have a ":"; is it followed by a number?
+ */
+ q = p + 1;
+ while (isdigit((unsigned char)*q))
+ q++;
+ if (*q == '\0') {
+ /*
+ * All digits after the ":" until the end.
+ * Strip off the ":" and everything after
+ * it.
+ */
+ *p = '\0';
+ }
+ }
+
+ /*
+ * Add information for this address to the list.
+ */
+ if (add_addr_to_iflist(&devlist, ifa->ifa_name,
+ ifa->ifa_flags, addr, addr_size, netmask, addr_size,
+ broadaddr, broadaddr_size, dstaddr, dstaddr_size,
+ errbuf) < 0) {
+ ret = -1;
+ break;
+ }
+ }
+
+ freeifaddrs(ifap);
+
+ if (ret == -1) {
+ /*
+ * We had an error; free the list we've been constructing.
+ */
+ if (devlist != NULL) {
+ pcap_freealldevs(devlist);
+ devlist = NULL;
+ }
+ }
+
+ *alldevsp = devlist;
+ return (ret);
+}
diff --git a/freebsd/contrib/libpcap/gencode.c b/freebsd/contrib/libpcap/gencode.c
new file mode 100644
index 00000000..8bee7904
--- /dev/null
+++ b/freebsd/contrib/libpcap/gencode.c
@@ -0,0 +1,8493 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*#define CHASE_CHAIN*/
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.309 2008-12-23 20:13:29 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/types.h>
+#include <sys/socket.h>
+#endif /* WIN32 */
+
+/*
+ * XXX - why was this included even on UNIX?
+ */
+#ifdef __MINGW32__
+#include "ip6_misc.h"
+#endif
+
+#ifndef WIN32
+
+#ifdef __NetBSD__
+#include <rtems/bsd/sys/param.h>
+#endif
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#endif /* WIN32 */
+
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+#include <setjmp.h>
+#include <stdarg.h>
+
+#ifdef MSDOS
+#include "pcap-dos.h"
+#endif
+
+#include "pcap-int.h"
+
+#include "ethertype.h"
+#include "nlpid.h"
+#include "llc.h"
+#include "gencode.h"
+#include "ieee80211.h"
+#include "atmuni31.h"
+#include "sunatmpos.h"
+#include "ppp.h"
+#include "pcap/sll.h"
+#include "pcap/ipnet.h"
+#include "arcnet.h"
+#if defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
+#include <linux/types.h>
+#include <linux/if_packet.h>
+#include <linux/filter.h>
+#endif
+#ifdef HAVE_NET_PFVAR_H
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/pfvar.h>
+#include <net/if_pflog.h>
+#endif
+#ifndef offsetof
+#define offsetof(s, e) ((size_t)&((s *)0)->e)
+#endif
+#ifdef INET6
+#ifndef WIN32
+#include <netdb.h> /* for "struct addrinfo" */
+#endif /* WIN32 */
+#endif /*INET6*/
+#include <pcap/namedb.h>
+
+#define ETHERMTU 1500
+
+#ifndef IPPROTO_HOPOPTS
+#define IPPROTO_HOPOPTS 0
+#endif
+#ifndef IPPROTO_ROUTING
+#define IPPROTO_ROUTING 43
+#endif
+#ifndef IPPROTO_FRAGMENT
+#define IPPROTO_FRAGMENT 44
+#endif
+#ifndef IPPROTO_DSTOPTS
+#define IPPROTO_DSTOPTS 60
+#endif
+#ifndef IPPROTO_SCTP
+#define IPPROTO_SCTP 132
+#endif
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#define JMP(c) ((c)|BPF_JMP|BPF_K)
+
+/* Locals */
+static jmp_buf top_ctx;
+static pcap_t *bpf_pcap;
+
+/* Hack for updating VLAN, MPLS, and PPPoE offsets. */
+#ifdef WIN32
+static u_int orig_linktype = (u_int)-1, orig_nl = (u_int)-1, label_stack_depth = (u_int)-1;
+#else
+static u_int orig_linktype = -1U, orig_nl = -1U, label_stack_depth = -1U;
+#endif
+
+/* XXX */
+#ifdef PCAP_FDDIPAD
+static int pcap_fddipad;
+#endif
+
+/* VARARGS */
+void
+bpf_error(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ if (bpf_pcap != NULL)
+ (void)vsnprintf(pcap_geterr(bpf_pcap), PCAP_ERRBUF_SIZE,
+ fmt, ap);
+ va_end(ap);
+ longjmp(top_ctx, 1);
+ /* NOTREACHED */
+}
+
+static void init_linktype(pcap_t *);
+
+static void init_regs(void);
+static int alloc_reg(void);
+static void free_reg(int);
+
+static struct block *root;
+
+/*
+ * Value passed to gen_load_a() to indicate what the offset argument
+ * is relative to.
+ */
+enum e_offrel {
+ OR_PACKET, /* relative to the beginning of the packet */
+ OR_LINK, /* relative to the beginning of the link-layer header */
+ OR_MACPL, /* relative to the end of the MAC-layer header */
+ OR_NET, /* relative to the network-layer header */
+ OR_NET_NOSNAP, /* relative to the network-layer header, with no SNAP header at the link layer */
+ OR_TRAN_IPV4, /* relative to the transport-layer header, with IPv4 network layer */
+ OR_TRAN_IPV6 /* relative to the transport-layer header, with IPv6 network layer */
+};
+
+#ifdef INET6
+/*
+ * As errors are handled by a longjmp, anything allocated must be freed
+ * in the longjmp handler, so it must be reachable from that handler.
+ * One thing that's allocated is the result of pcap_nametoaddrinfo();
+ * it must be freed with freeaddrinfo(). This variable points to any
+ * addrinfo structure that would need to be freed.
+ */
+static struct addrinfo *ai;
+#endif
+
+/*
+ * We divy out chunks of memory rather than call malloc each time so
+ * we don't have to worry about leaking memory. It's probably
+ * not a big deal if all this memory was wasted but if this ever
+ * goes into a library that would probably not be a good idea.
+ *
+ * XXX - this *is* in a library....
+ */
+#define NCHUNKS 16
+#define CHUNK0SIZE 1024
+struct chunk {
+ u_int n_left;
+ void *m;
+};
+
+static struct chunk chunks[NCHUNKS];
+static int cur_chunk;
+
+static void *newchunk(u_int);
+static void freechunks(void);
+static inline struct block *new_block(int);
+static inline struct slist *new_stmt(int);
+static struct block *gen_retblk(int);
+static inline void syntax(void);
+
+static void backpatch(struct block *, struct block *);
+static void merge(struct block *, struct block *);
+static struct block *gen_cmp(enum e_offrel, u_int, u_int, bpf_int32);
+static struct block *gen_cmp_gt(enum e_offrel, u_int, u_int, bpf_int32);
+static struct block *gen_cmp_ge(enum e_offrel, u_int, u_int, bpf_int32);
+static struct block *gen_cmp_lt(enum e_offrel, u_int, u_int, bpf_int32);
+static struct block *gen_cmp_le(enum e_offrel, u_int, u_int, bpf_int32);
+static struct block *gen_mcmp(enum e_offrel, u_int, u_int, bpf_int32,
+ bpf_u_int32);
+static struct block *gen_bcmp(enum e_offrel, u_int, u_int, const u_char *);
+static struct block *gen_ncmp(enum e_offrel, bpf_u_int32, bpf_u_int32,
+ bpf_u_int32, bpf_u_int32, int, bpf_int32);
+static struct slist *gen_load_llrel(u_int, u_int);
+static struct slist *gen_load_macplrel(u_int, u_int);
+static struct slist *gen_load_a(enum e_offrel, u_int, u_int);
+static struct slist *gen_loadx_iphdrlen(void);
+static struct block *gen_uncond(int);
+static inline struct block *gen_true(void);
+static inline struct block *gen_false(void);
+static struct block *gen_ether_linktype(int);
+static struct block *gen_ipnet_linktype(int);
+static struct block *gen_linux_sll_linktype(int);
+static struct slist *gen_load_prism_llprefixlen(void);
+static struct slist *gen_load_avs_llprefixlen(void);
+static struct slist *gen_load_radiotap_llprefixlen(void);
+static struct slist *gen_load_ppi_llprefixlen(void);
+static void insert_compute_vloffsets(struct block *);
+static struct slist *gen_llprefixlen(void);
+static struct slist *gen_off_macpl(void);
+static int ethertype_to_ppptype(int);
+static struct block *gen_linktype(int);
+static struct block *gen_snap(bpf_u_int32, bpf_u_int32);
+static struct block *gen_llc_linktype(int);
+static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int);
+#ifdef INET6
+static struct block *gen_hostop6(struct in6_addr *, struct in6_addr *, int, int, u_int, u_int);
+#endif
+static struct block *gen_ahostop(const u_char *, int);
+static struct block *gen_ehostop(const u_char *, int);
+static struct block *gen_fhostop(const u_char *, int);
+static struct block *gen_thostop(const u_char *, int);
+static struct block *gen_wlanhostop(const u_char *, int);
+static struct block *gen_ipfchostop(const u_char *, int);
+static struct block *gen_dnhostop(bpf_u_int32, int);
+static struct block *gen_mpls_linktype(int);
+static struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int, int);
+#ifdef INET6
+static struct block *gen_host6(struct in6_addr *, struct in6_addr *, int, int, int);
+#endif
+#ifndef INET6
+static struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int);
+#endif
+static struct block *gen_ipfrag(void);
+static struct block *gen_portatom(int, bpf_int32);
+static struct block *gen_portrangeatom(int, bpf_int32, bpf_int32);
+static struct block *gen_portatom6(int, bpf_int32);
+static struct block *gen_portrangeatom6(int, bpf_int32, bpf_int32);
+struct block *gen_portop(int, int, int);
+static struct block *gen_port(int, int, int);
+struct block *gen_portrangeop(int, int, int, int);
+static struct block *gen_portrange(int, int, int, int);
+struct block *gen_portop6(int, int, int);
+static struct block *gen_port6(int, int, int);
+struct block *gen_portrangeop6(int, int, int, int);
+static struct block *gen_portrange6(int, int, int, int);
+static int lookup_proto(const char *, int);
+static struct block *gen_protochain(int, int, int);
+static struct block *gen_proto(int, int, int);
+static struct slist *xfer_to_x(struct arth *);
+static struct slist *xfer_to_a(struct arth *);
+static struct block *gen_mac_multicast(int);
+static struct block *gen_len(int, int);
+static struct block *gen_check_802_11_data_frame(void);
+
+static struct block *gen_ppi_dlt_check(void);
+static struct block *gen_msg_abbrev(int type);
+
+static void *
+newchunk(n)
+ u_int n;
+{
+ struct chunk *cp;
+ int k;
+ size_t size;
+
+#ifndef __NetBSD__
+ /* XXX Round up to nearest long. */
+ n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1);
+#else
+ /* XXX Round up to structure boundary. */
+ n = ALIGN(n);
+#endif
+
+ cp = &chunks[cur_chunk];
+ if (n > cp->n_left) {
+ ++cp, k = ++cur_chunk;
+ if (k >= NCHUNKS)
+ bpf_error("out of memory");
+ size = CHUNK0SIZE << k;
+ cp->m = (void *)malloc(size);
+ if (cp->m == NULL)
+ bpf_error("out of memory");
+ memset((char *)cp->m, 0, size);
+ cp->n_left = size;
+ if (n > size)
+ bpf_error("out of memory");
+ }
+ cp->n_left -= n;
+ return (void *)((char *)cp->m + cp->n_left);
+}
+
+static void
+freechunks()
+{
+ int i;
+
+ cur_chunk = 0;
+ for (i = 0; i < NCHUNKS; ++i)
+ if (chunks[i].m != NULL) {
+ free(chunks[i].m);
+ chunks[i].m = NULL;
+ }
+}
+
+/*
+ * A strdup whose allocations are freed after code generation is over.
+ */
+char *
+sdup(s)
+ register const char *s;
+{
+ int n = strlen(s) + 1;
+ char *cp = newchunk(n);
+
+ strlcpy(cp, s, n);
+ return (cp);
+}
+
+static inline struct block *
+new_block(code)
+ int code;
+{
+ struct block *p;
+
+ p = (struct block *)newchunk(sizeof(*p));
+ p->s.code = code;
+ p->head = p;
+
+ return p;
+}
+
+static inline struct slist *
+new_stmt(code)
+ int code;
+{
+ struct slist *p;
+
+ p = (struct slist *)newchunk(sizeof(*p));
+ p->s.code = code;
+
+ return p;
+}
+
+static struct block *
+gen_retblk(v)
+ int v;
+{
+ struct block *b = new_block(BPF_RET|BPF_K);
+
+ b->s.k = v;
+ return b;
+}
+
+static inline void
+syntax()
+{
+ bpf_error("syntax error in filter expression");
+}
+
+static bpf_u_int32 netmask;
+static int snaplen;
+int no_optimize;
+#ifdef WIN32
+static int
+pcap_compile_unsafe(pcap_t *p, struct bpf_program *program,
+ const char *buf, int optimize, bpf_u_int32 mask);
+
+int
+pcap_compile(pcap_t *p, struct bpf_program *program,
+ const char *buf, int optimize, bpf_u_int32 mask)
+{
+ int result;
+
+ EnterCriticalSection(&g_PcapCompileCriticalSection);
+
+ result = pcap_compile_unsafe(p, program, buf, optimize, mask);
+
+ LeaveCriticalSection(&g_PcapCompileCriticalSection);
+
+ return result;
+}
+
+static int
+pcap_compile_unsafe(pcap_t *p, struct bpf_program *program,
+ const char *buf, int optimize, bpf_u_int32 mask)
+#else /* WIN32 */
+int
+pcap_compile(pcap_t *p, struct bpf_program *program,
+ const char *buf, int optimize, bpf_u_int32 mask)
+#endif /* WIN32 */
+{
+#if __rtems__
+ int n_errors;
+#else
+ extern int n_errors;
+#endif
+ const char * volatile xbuf = buf;
+ u_int len;
+
+ /*
+ * If this pcap_t hasn't been activated, it doesn't have a
+ * link-layer type, so we can't use it.
+ */
+ if (!p->activated) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "not-yet-activated pcap_t passed to pcap_compile");
+ return (-1);
+ }
+ no_optimize = 0;
+ n_errors = 0;
+ root = NULL;
+ bpf_pcap = p;
+ init_regs();
+ if (setjmp(top_ctx)) {
+#ifdef INET6
+ if (ai != NULL) {
+ freeaddrinfo(ai);
+ ai = NULL;
+ }
+#endif
+ lex_cleanup();
+ freechunks();
+ return (-1);
+ }
+
+ netmask = mask;
+
+ snaplen = pcap_snapshot(p);
+ if (snaplen == 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "snaplen of 0 rejects all packets");
+ return -1;
+ }
+
+ lex_init(xbuf ? xbuf : "");
+ init_linktype(p);
+ (void)pcap_parse();
+
+ if (n_errors)
+ syntax();
+
+ if (root == NULL)
+ root = gen_retblk(snaplen);
+
+ if (optimize && !no_optimize) {
+ bpf_optimize(&root);
+ if (root == NULL ||
+ (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0))
+ bpf_error("expression rejects all packets");
+ }
+ program->bf_insns = icode_to_fcode(root, &len);
+ program->bf_len = len;
+
+ lex_cleanup();
+ freechunks();
+ return (0);
+}
+
+/*
+ * entry point for using the compiler with no pcap open
+ * pass in all the stuff that is needed explicitly instead.
+ */
+int
+pcap_compile_nopcap(int snaplen_arg, int linktype_arg,
+ struct bpf_program *program,
+ const char *buf, int optimize, bpf_u_int32 mask)
+{
+ pcap_t *p;
+ int ret;
+
+ p = pcap_open_dead(linktype_arg, snaplen_arg);
+ if (p == NULL)
+ return (-1);
+ ret = pcap_compile(p, program, buf, optimize, mask);
+ pcap_close(p);
+ return (ret);
+}
+
+/*
+ * Clean up a "struct bpf_program" by freeing all the memory allocated
+ * in it.
+ */
+void
+pcap_freecode(struct bpf_program *program)
+{
+ program->bf_len = 0;
+ if (program->bf_insns != NULL) {
+ free((char *)program->bf_insns);
+ program->bf_insns = NULL;
+ }
+}
+
+/*
+ * Backpatch the blocks in 'list' to 'target'. The 'sense' field indicates
+ * which of the jt and jf fields has been resolved and which is a pointer
+ * back to another unresolved block (or nil). At least one of the fields
+ * in each block is already resolved.
+ */
+static void
+backpatch(list, target)
+ struct block *list, *target;
+{
+ struct block *next;
+
+ while (list) {
+ if (!list->sense) {
+ next = JT(list);
+ JT(list) = target;
+ } else {
+ next = JF(list);
+ JF(list) = target;
+ }
+ list = next;
+ }
+}
+
+/*
+ * Merge the lists in b0 and b1, using the 'sense' field to indicate
+ * which of jt and jf is the link.
+ */
+static void
+merge(b0, b1)
+ struct block *b0, *b1;
+{
+ register struct block **p = &b0;
+
+ /* Find end of list. */
+ while (*p)
+ p = !((*p)->sense) ? &JT(*p) : &JF(*p);
+
+ /* Concatenate the lists. */
+ *p = b1;
+}
+
+void
+finish_parse(p)
+ struct block *p;
+{
+ struct block *ppi_dlt_check;
+
+ /*
+ * Insert before the statements of the first (root) block any
+ * statements needed to load the lengths of any variable-length
+ * headers into registers.
+ *
+ * XXX - a fancier strategy would be to insert those before the
+ * statements of all blocks that use those lengths and that
+ * have no predecessors that use them, so that we only compute
+ * the lengths if we need them. There might be even better
+ * approaches than that.
+ *
+ * However, those strategies would be more complicated, and
+ * as we don't generate code to compute a length if the
+ * program has no tests that use the length, and as most
+ * tests will probably use those lengths, we would just
+ * postpone computing the lengths so that it's not done
+ * for tests that fail early, and it's not clear that's
+ * worth the effort.
+ */
+ insert_compute_vloffsets(p->head);
+
+ /*
+ * For DLT_PPI captures, generate a check of the per-packet
+ * DLT value to make sure it's DLT_IEEE802_11.
+ */
+ ppi_dlt_check = gen_ppi_dlt_check();
+ if (ppi_dlt_check != NULL)
+ gen_and(ppi_dlt_check, p);
+
+ backpatch(p, gen_retblk(snaplen));
+ p->sense = !p->sense;
+ backpatch(p, gen_retblk(0));
+ root = p->head;
+}
+
+void
+gen_and(b0, b1)
+ struct block *b0, *b1;
+{
+ backpatch(b0, b1->head);
+ b0->sense = !b0->sense;
+ b1->sense = !b1->sense;
+ merge(b1, b0);
+ b1->sense = !b1->sense;
+ b1->head = b0->head;
+}
+
+void
+gen_or(b0, b1)
+ struct block *b0, *b1;
+{
+ b0->sense = !b0->sense;
+ backpatch(b0, b1->head);
+ b0->sense = !b0->sense;
+ merge(b1, b0);
+ b1->head = b0->head;
+}
+
+void
+gen_not(b)
+ struct block *b;
+{
+ b->sense = !b->sense;
+}
+
+static struct block *
+gen_cmp(offrel, offset, size, v)
+ enum e_offrel offrel;
+ u_int offset, size;
+ bpf_int32 v;
+{
+ return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JEQ, 0, v);
+}
+
+static struct block *
+gen_cmp_gt(offrel, offset, size, v)
+ enum e_offrel offrel;
+ u_int offset, size;
+ bpf_int32 v;
+{
+ return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGT, 0, v);
+}
+
+static struct block *
+gen_cmp_ge(offrel, offset, size, v)
+ enum e_offrel offrel;
+ u_int offset, size;
+ bpf_int32 v;
+{
+ return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGE, 0, v);
+}
+
+static struct block *
+gen_cmp_lt(offrel, offset, size, v)
+ enum e_offrel offrel;
+ u_int offset, size;
+ bpf_int32 v;
+{
+ return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGE, 1, v);
+}
+
+static struct block *
+gen_cmp_le(offrel, offset, size, v)
+ enum e_offrel offrel;
+ u_int offset, size;
+ bpf_int32 v;
+{
+ return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGT, 1, v);
+}
+
+static struct block *
+gen_mcmp(offrel, offset, size, v, mask)
+ enum e_offrel offrel;
+ u_int offset, size;
+ bpf_int32 v;
+ bpf_u_int32 mask;
+{
+ return gen_ncmp(offrel, offset, size, mask, BPF_JEQ, 0, v);
+}
+
+static struct block *
+gen_bcmp(offrel, offset, size, v)
+ enum e_offrel offrel;
+ register u_int offset, size;
+ register const u_char *v;
+{
+ register struct block *b, *tmp;
+
+ b = NULL;
+ while (size >= 4) {
+ register const u_char *p = &v[size - 4];
+ bpf_int32 w = ((bpf_int32)p[0] << 24) |
+ ((bpf_int32)p[1] << 16) | ((bpf_int32)p[2] << 8) | p[3];
+
+ tmp = gen_cmp(offrel, offset + size - 4, BPF_W, w);
+ if (b != NULL)
+ gen_and(b, tmp);
+ b = tmp;
+ size -= 4;
+ }
+ while (size >= 2) {
+ register const u_char *p = &v[size - 2];
+ bpf_int32 w = ((bpf_int32)p[0] << 8) | p[1];
+
+ tmp = gen_cmp(offrel, offset + size - 2, BPF_H, w);
+ if (b != NULL)
+ gen_and(b, tmp);
+ b = tmp;
+ size -= 2;
+ }
+ if (size > 0) {
+ tmp = gen_cmp(offrel, offset, BPF_B, (bpf_int32)v[0]);
+ if (b != NULL)
+ gen_and(b, tmp);
+ b = tmp;
+ }
+ return b;
+}
+
+/*
+ * AND the field of size "size" at offset "offset" relative to the header
+ * specified by "offrel" with "mask", and compare it with the value "v"
+ * with the test specified by "jtype"; if "reverse" is true, the test
+ * should test the opposite of "jtype".
+ */
+static struct block *
+gen_ncmp(offrel, offset, size, mask, jtype, reverse, v)
+ enum e_offrel offrel;
+ bpf_int32 v;
+ bpf_u_int32 offset, size, mask, jtype;
+ int reverse;
+{
+ struct slist *s, *s2;
+ struct block *b;
+
+ s = gen_load_a(offrel, offset, size);
+
+ if (mask != 0xffffffff) {
+ s2 = new_stmt(BPF_ALU|BPF_AND|BPF_K);
+ s2->s.k = mask;
+ sappend(s, s2);
+ }
+
+ b = new_block(JMP(jtype));
+ b->stmts = s;
+ b->s.k = v;
+ if (reverse && (jtype == BPF_JGT || jtype == BPF_JGE))
+ gen_not(b);
+ return b;
+}
+
+/*
+ * Various code constructs need to know the layout of the data link
+ * layer. These variables give the necessary offsets from the beginning
+ * of the packet data.
+ */
+
+/*
+ * This is the offset of the beginning of the link-layer header from
+ * the beginning of the raw packet data.
+ *
+ * It's usually 0, except for 802.11 with a fixed-length radio header.
+ * (For 802.11 with a variable-length radio header, we have to generate
+ * code to compute that offset; off_ll is 0 in that case.)
+ */
+static u_int off_ll;
+
+/*
+ * If there's a variable-length header preceding the link-layer header,
+ * "reg_off_ll" is the register number for a register containing the
+ * length of that header, and therefore the offset of the link-layer
+ * header from the beginning of the raw packet data. Otherwise,
+ * "reg_off_ll" is -1.
+ */
+static int reg_off_ll;
+
+/*
+ * This is the offset of the beginning of the MAC-layer header from
+ * the beginning of the link-layer header.
+ * It's usually 0, except for ATM LANE, where it's the offset, relative
+ * to the beginning of the raw packet data, of the Ethernet header, and
+ * for Ethernet with various additional information.
+ */
+static u_int off_mac;
+
+/*
+ * This is the offset of the beginning of the MAC-layer payload,
+ * from the beginning of the raw packet data.
+ *
+ * I.e., it's the sum of the length of the link-layer header (without,
+ * for example, any 802.2 LLC header, so it's the MAC-layer
+ * portion of that header), plus any prefix preceding the
+ * link-layer header.
+ */
+static u_int off_macpl;
+
+/*
+ * This is 1 if the offset of the beginning of the MAC-layer payload
+ * from the beginning of the link-layer header is variable-length.
+ */
+static int off_macpl_is_variable;
+
+/*
+ * If the link layer has variable_length headers, "reg_off_macpl"
+ * is the register number for a register containing the length of the
+ * link-layer header plus the length of any variable-length header
+ * preceding the link-layer header. Otherwise, "reg_off_macpl"
+ * is -1.
+ */
+static int reg_off_macpl;
+
+/*
+ * "off_linktype" is the offset to information in the link-layer header
+ * giving the packet type. This offset is relative to the beginning
+ * of the link-layer header (i.e., it doesn't include off_ll).
+ *
+ * For Ethernet, it's the offset of the Ethernet type field.
+ *
+ * For link-layer types that always use 802.2 headers, it's the
+ * offset of the LLC header.
+ *
+ * For PPP, it's the offset of the PPP type field.
+ *
+ * For Cisco HDLC, it's the offset of the CHDLC type field.
+ *
+ * For BSD loopback, it's the offset of the AF_ value.
+ *
+ * For Linux cooked sockets, it's the offset of the type field.
+ *
+ * It's set to -1 for no encapsulation, in which case, IP is assumed.
+ */
+static u_int off_linktype;
+
+/*
+ * TRUE if "pppoes" appeared in the filter; it causes link-layer type
+ * checks to check the PPP header, assumed to follow a LAN-style link-
+ * layer header and a PPPoE session header.
+ */
+static int is_pppoes = 0;
+
+/*
+ * TRUE if the link layer includes an ATM pseudo-header.
+ */
+static int is_atm = 0;
+
+/*
+ * TRUE if "lane" appeared in the filter; it causes us to generate
+ * code that assumes LANE rather than LLC-encapsulated traffic in SunATM.
+ */
+static int is_lane = 0;
+
+/*
+ * These are offsets for the ATM pseudo-header.
+ */
+static u_int off_vpi;
+static u_int off_vci;
+static u_int off_proto;
+
+/*
+ * These are offsets for the MTP2 fields.
+ */
+static u_int off_li;
+
+/*
+ * These are offsets for the MTP3 fields.
+ */
+static u_int off_sio;
+static u_int off_opc;
+static u_int off_dpc;
+static u_int off_sls;
+
+/*
+ * This is the offset of the first byte after the ATM pseudo_header,
+ * or -1 if there is no ATM pseudo-header.
+ */
+static u_int off_payload;
+
+/*
+ * These are offsets to the beginning of the network-layer header.
+ * They are relative to the beginning of the MAC-layer payload (i.e.,
+ * they don't include off_ll or off_macpl).
+ *
+ * If the link layer never uses 802.2 LLC:
+ *
+ * "off_nl" and "off_nl_nosnap" are the same.
+ *
+ * If the link layer always uses 802.2 LLC:
+ *
+ * "off_nl" is the offset if there's a SNAP header following
+ * the 802.2 header;
+ *
+ * "off_nl_nosnap" is the offset if there's no SNAP header.
+ *
+ * If the link layer is Ethernet:
+ *
+ * "off_nl" is the offset if the packet is an Ethernet II packet
+ * (we assume no 802.3+802.2+SNAP);
+ *
+ * "off_nl_nosnap" is the offset if the packet is an 802.3 packet
+ * with an 802.2 header following it.
+ */
+static u_int off_nl;
+static u_int off_nl_nosnap;
+
+static int linktype;
+
+static void
+init_linktype(p)
+ pcap_t *p;
+{
+ linktype = pcap_datalink(p);
+#ifdef PCAP_FDDIPAD
+ pcap_fddipad = p->fddipad;
+#endif
+
+ /*
+ * Assume it's not raw ATM with a pseudo-header, for now.
+ */
+ off_mac = 0;
+ is_atm = 0;
+ is_lane = 0;
+ off_vpi = -1;
+ off_vci = -1;
+ off_proto = -1;
+ off_payload = -1;
+
+ /*
+ * And that we're not doing PPPoE.
+ */
+ is_pppoes = 0;
+
+ /*
+ * And assume we're not doing SS7.
+ */
+ off_li = -1;
+ off_sio = -1;
+ off_opc = -1;
+ off_dpc = -1;
+ off_sls = -1;
+
+ /*
+ * Also assume it's not 802.11.
+ */
+ off_ll = 0;
+ off_macpl = 0;
+ off_macpl_is_variable = 0;
+
+ orig_linktype = -1;
+ orig_nl = -1;
+ label_stack_depth = 0;
+
+ reg_off_ll = -1;
+ reg_off_macpl = -1;
+
+ switch (linktype) {
+
+ case DLT_ARCNET:
+ off_linktype = 2;
+ off_macpl = 6;
+ off_nl = 0; /* XXX in reality, variable! */
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_ARCNET_LINUX:
+ off_linktype = 4;
+ off_macpl = 8;
+ off_nl = 0; /* XXX in reality, variable! */
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_EN10MB:
+ off_linktype = 12;
+ off_macpl = 14; /* Ethernet header length */
+ off_nl = 0; /* Ethernet II */
+ off_nl_nosnap = 3; /* 802.3+802.2 */
+ return;
+
+ case DLT_SLIP:
+ /*
+ * SLIP doesn't have a link level type. The 16 byte
+ * header is hacked into our SLIP driver.
+ */
+ off_linktype = -1;
+ off_macpl = 16;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_SLIP_BSDOS:
+ /* XXX this may be the same as the DLT_PPP_BSDOS case */
+ off_linktype = -1;
+ /* XXX end */
+ off_macpl = 24;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_NULL:
+ case DLT_LOOP:
+ off_linktype = 0;
+ off_macpl = 4;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_ENC:
+ off_linktype = 0;
+ off_macpl = 12;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_PPP:
+ case DLT_PPP_PPPD:
+ case DLT_C_HDLC: /* BSD/OS Cisco HDLC */
+ case DLT_PPP_SERIAL: /* NetBSD sync/async serial PPP */
+ off_linktype = 2;
+ off_macpl = 4;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_PPP_ETHER:
+ /*
+ * This does no include the Ethernet header, and
+ * only covers session state.
+ */
+ off_linktype = 6;
+ off_macpl = 8;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_PPP_BSDOS:
+ off_linktype = 5;
+ off_macpl = 24;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_FDDI:
+ /*
+ * FDDI doesn't really have a link-level type field.
+ * We set "off_linktype" to the offset of the LLC header.
+ *
+ * To check for Ethernet types, we assume that SSAP = SNAP
+ * is being used and pick out the encapsulated Ethernet type.
+ * XXX - should we generate code to check for SNAP?
+ */
+ off_linktype = 13;
+#ifdef PCAP_FDDIPAD
+ off_linktype += pcap_fddipad;
+#endif
+ off_macpl = 13; /* FDDI MAC header length */
+#ifdef PCAP_FDDIPAD
+ off_macpl += pcap_fddipad;
+#endif
+ off_nl = 8; /* 802.2+SNAP */
+ off_nl_nosnap = 3; /* 802.2 */
+ return;
+
+ case DLT_IEEE802:
+ /*
+ * Token Ring doesn't really have a link-level type field.
+ * We set "off_linktype" to the offset of the LLC header.
+ *
+ * To check for Ethernet types, we assume that SSAP = SNAP
+ * is being used and pick out the encapsulated Ethernet type.
+ * XXX - should we generate code to check for SNAP?
+ *
+ * XXX - the header is actually variable-length.
+ * Some various Linux patched versions gave 38
+ * as "off_linktype" and 40 as "off_nl"; however,
+ * if a token ring packet has *no* routing
+ * information, i.e. is not source-routed, the correct
+ * values are 20 and 22, as they are in the vanilla code.
+ *
+ * A packet is source-routed iff the uppermost bit
+ * of the first byte of the source address, at an
+ * offset of 8, has the uppermost bit set. If the
+ * packet is source-routed, the total number of bytes
+ * of routing information is 2 plus bits 0x1F00 of
+ * the 16-bit value at an offset of 14 (shifted right
+ * 8 - figure out which byte that is).
+ */
+ off_linktype = 14;
+ off_macpl = 14; /* Token Ring MAC header length */
+ off_nl = 8; /* 802.2+SNAP */
+ off_nl_nosnap = 3; /* 802.2 */
+ return;
+
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ /*
+ * 802.11 doesn't really have a link-level type field.
+ * We set "off_linktype" to the offset of the LLC header.
+ *
+ * To check for Ethernet types, we assume that SSAP = SNAP
+ * is being used and pick out the encapsulated Ethernet type.
+ * XXX - should we generate code to check for SNAP?
+ *
+ * We also handle variable-length radio headers here.
+ * The Prism header is in theory variable-length, but in
+ * practice it's always 144 bytes long. However, some
+ * drivers on Linux use ARPHRD_IEEE80211_PRISM, but
+ * sometimes or always supply an AVS header, so we
+ * have to check whether the radio header is a Prism
+ * header or an AVS header, so, in practice, it's
+ * variable-length.
+ */
+ off_linktype = 24;
+ off_macpl = 0; /* link-layer header is variable-length */
+ off_macpl_is_variable = 1;
+ off_nl = 8; /* 802.2+SNAP */
+ off_nl_nosnap = 3; /* 802.2 */
+ return;
+
+ case DLT_PPI:
+ /*
+ * At the moment we treat PPI the same way that we treat
+ * normal Radiotap encoded packets. The difference is in
+ * the function that generates the code at the beginning
+ * to compute the header length. Since this code generator
+ * of PPI supports bare 802.11 encapsulation only (i.e.
+ * the encapsulated DLT should be DLT_IEEE802_11) we
+ * generate code to check for this too.
+ */
+ off_linktype = 24;
+ off_macpl = 0; /* link-layer header is variable-length */
+ off_macpl_is_variable = 1;
+ off_nl = 8; /* 802.2+SNAP */
+ off_nl_nosnap = 3; /* 802.2 */
+ return;
+
+ case DLT_ATM_RFC1483:
+ case DLT_ATM_CLIP: /* Linux ATM defines this */
+ /*
+ * assume routed, non-ISO PDUs
+ * (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00)
+ *
+ * XXX - what about ISO PDUs, e.g. CLNP, ISIS, ESIS,
+ * or PPP with the PPP NLPID (e.g., PPPoA)? The
+ * latter would presumably be treated the way PPPoE
+ * should be, so you can do "pppoe and udp port 2049"
+ * or "pppoa and tcp port 80" and have it check for
+ * PPPo{A,E} and a PPP protocol of IP and....
+ */
+ off_linktype = 0;
+ off_macpl = 0; /* packet begins with LLC header */
+ off_nl = 8; /* 802.2+SNAP */
+ off_nl_nosnap = 3; /* 802.2 */
+ return;
+
+ case DLT_SUNATM:
+ /*
+ * Full Frontal ATM; you get AALn PDUs with an ATM
+ * pseudo-header.
+ */
+ is_atm = 1;
+ off_vpi = SUNATM_VPI_POS;
+ off_vci = SUNATM_VCI_POS;
+ off_proto = PROTO_POS;
+ off_mac = -1; /* assume LLC-encapsulated, so no MAC-layer header */
+ off_payload = SUNATM_PKT_BEGIN_POS;
+ off_linktype = off_payload;
+ off_macpl = off_payload; /* if LLC-encapsulated */
+ off_nl = 8; /* 802.2+SNAP */
+ off_nl_nosnap = 3; /* 802.2 */
+ return;
+
+ case DLT_RAW:
+ case DLT_IPV4:
+ case DLT_IPV6:
+ off_linktype = -1;
+ off_macpl = 0;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_LINUX_SLL: /* fake header for Linux cooked socket */
+ off_linktype = 14;
+ off_macpl = 16;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_LTALK:
+ /*
+ * LocalTalk does have a 1-byte type field in the LLAP header,
+ * but really it just indicates whether there is a "short" or
+ * "long" DDP packet following.
+ */
+ off_linktype = -1;
+ off_macpl = 0;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_IP_OVER_FC:
+ /*
+ * RFC 2625 IP-over-Fibre-Channel doesn't really have a
+ * link-level type field. We set "off_linktype" to the
+ * offset of the LLC header.
+ *
+ * To check for Ethernet types, we assume that SSAP = SNAP
+ * is being used and pick out the encapsulated Ethernet type.
+ * XXX - should we generate code to check for SNAP? RFC
+ * 2625 says SNAP should be used.
+ */
+ off_linktype = 16;
+ off_macpl = 16;
+ off_nl = 8; /* 802.2+SNAP */
+ off_nl_nosnap = 3; /* 802.2 */
+ return;
+
+ case DLT_FRELAY:
+ /*
+ * XXX - we should set this to handle SNAP-encapsulated
+ * frames (NLPID of 0x80).
+ */
+ off_linktype = -1;
+ off_macpl = 0;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ /*
+ * the only BPF-interesting FRF.16 frames are non-control frames;
+ * Frame Relay has a variable length link-layer
+ * so lets start with offset 4 for now and increments later on (FIXME);
+ */
+ case DLT_MFR:
+ off_linktype = -1;
+ off_macpl = 0;
+ off_nl = 4;
+ off_nl_nosnap = 0; /* XXX - for now -> no 802.2 LLC */
+ return;
+
+ case DLT_APPLE_IP_OVER_IEEE1394:
+ off_linktype = 16;
+ off_macpl = 18;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_SYMANTEC_FIREWALL:
+ off_linktype = 6;
+ off_macpl = 44;
+ off_nl = 0; /* Ethernet II */
+ off_nl_nosnap = 0; /* XXX - what does it do with 802.3 packets? */
+ return;
+
+#ifdef HAVE_NET_PFVAR_H
+ case DLT_PFLOG:
+ off_linktype = 0;
+ off_macpl = PFLOG_HDRLEN;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+#endif
+
+ case DLT_JUNIPER_MFR:
+ case DLT_JUNIPER_MLFR:
+ case DLT_JUNIPER_MLPPP:
+ case DLT_JUNIPER_PPP:
+ case DLT_JUNIPER_CHDLC:
+ case DLT_JUNIPER_FRELAY:
+ off_linktype = 4;
+ off_macpl = 4;
+ off_nl = 0;
+ off_nl_nosnap = -1; /* no 802.2 LLC */
+ return;
+
+ case DLT_JUNIPER_ATM1:
+ off_linktype = 4; /* in reality variable between 4-8 */
+ off_macpl = 4; /* in reality variable between 4-8 */
+ off_nl = 0;
+ off_nl_nosnap = 10;
+ return;
+
+ case DLT_JUNIPER_ATM2:
+ off_linktype = 8; /* in reality variable between 8-12 */
+ off_macpl = 8; /* in reality variable between 8-12 */
+ off_nl = 0;
+ off_nl_nosnap = 10;
+ return;
+
+ /* frames captured on a Juniper PPPoE service PIC
+ * contain raw ethernet frames */
+ case DLT_JUNIPER_PPPOE:
+ case DLT_JUNIPER_ETHER:
+ off_macpl = 14;
+ off_linktype = 16;
+ off_nl = 18; /* Ethernet II */
+ off_nl_nosnap = 21; /* 802.3+802.2 */
+ return;
+
+ case DLT_JUNIPER_PPPOE_ATM:
+ off_linktype = 4;
+ off_macpl = 6;
+ off_nl = 0;
+ off_nl_nosnap = -1; /* no 802.2 LLC */
+ return;
+
+ case DLT_JUNIPER_GGSN:
+ off_linktype = 6;
+ off_macpl = 12;
+ off_nl = 0;
+ off_nl_nosnap = -1; /* no 802.2 LLC */
+ return;
+
+ case DLT_JUNIPER_ES:
+ off_linktype = 6;
+ off_macpl = -1; /* not really a network layer but raw IP addresses */
+ off_nl = -1; /* not really a network layer but raw IP addresses */
+ off_nl_nosnap = -1; /* no 802.2 LLC */
+ return;
+
+ case DLT_JUNIPER_MONITOR:
+ off_linktype = 12;
+ off_macpl = 12;
+ off_nl = 0; /* raw IP/IP6 header */
+ off_nl_nosnap = -1; /* no 802.2 LLC */
+ return;
+
+ case DLT_JUNIPER_SERVICES:
+ off_linktype = 12;
+ off_macpl = -1; /* L3 proto location dep. on cookie type */
+ off_nl = -1; /* L3 proto location dep. on cookie type */
+ off_nl_nosnap = -1; /* no 802.2 LLC */
+ return;
+
+ case DLT_JUNIPER_VP:
+ off_linktype = 18;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+
+ case DLT_JUNIPER_ST:
+ off_linktype = 18;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+
+ case DLT_JUNIPER_ISM:
+ off_linktype = 8;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+
+ case DLT_JUNIPER_VS:
+ case DLT_JUNIPER_SRX_E2E:
+ case DLT_JUNIPER_FIBRECHANNEL:
+ case DLT_JUNIPER_ATM_CEMIC:
+ off_linktype = 8;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+
+ case DLT_MTP2:
+ off_li = 2;
+ off_sio = 3;
+ off_opc = 4;
+ off_dpc = 4;
+ off_sls = 7;
+ off_linktype = -1;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+
+ case DLT_MTP2_WITH_PHDR:
+ off_li = 6;
+ off_sio = 7;
+ off_opc = 8;
+ off_dpc = 8;
+ off_sls = 11;
+ off_linktype = -1;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+
+ case DLT_ERF:
+ off_li = 22;
+ off_sio = 23;
+ off_opc = 24;
+ off_dpc = 24;
+ off_sls = 27;
+ off_linktype = -1;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+
+ case DLT_PFSYNC:
+ off_linktype = -1;
+ off_macpl = 4;
+ off_nl = 0;
+ off_nl_nosnap = 0;
+ return;
+
+ case DLT_AX25_KISS:
+ /*
+ * Currently, only raw "link[N:M]" filtering is supported.
+ */
+ off_linktype = -1; /* variable, min 15, max 71 steps of 7 */
+ off_macpl = -1;
+ off_nl = -1; /* variable, min 16, max 71 steps of 7 */
+ off_nl_nosnap = -1; /* no 802.2 LLC */
+ off_mac = 1; /* step over the kiss length byte */
+ return;
+
+ case DLT_IPNET:
+ off_linktype = 1;
+ off_macpl = 24; /* ipnet header length */
+ off_nl = 0;
+ off_nl_nosnap = -1;
+ return;
+
+ case DLT_NETANALYZER:
+ off_mac = 4; /* MAC header is past 4-byte pseudo-header */
+ off_linktype = 16; /* includes 4-byte pseudo-header */
+ off_macpl = 18; /* pseudo-header+Ethernet header length */
+ off_nl = 0; /* Ethernet II */
+ off_nl_nosnap = 3; /* 802.3+802.2 */
+ return;
+
+ case DLT_NETANALYZER_TRANSPARENT:
+ off_mac = 12; /* MAC header is past 4-byte pseudo-header, preamble, and SFD */
+ off_linktype = 24; /* includes 4-byte pseudo-header+preamble+SFD */
+ off_macpl = 26; /* pseudo-header+preamble+SFD+Ethernet header length */
+ off_nl = 0; /* Ethernet II */
+ off_nl_nosnap = 3; /* 802.3+802.2 */
+ return;
+
+ default:
+ /*
+ * For values in the range in which we've assigned new
+ * DLT_ values, only raw "link[N:M]" filtering is supported.
+ */
+ if (linktype >= DLT_MATCHING_MIN &&
+ linktype <= DLT_MATCHING_MAX) {
+ off_linktype = -1;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+ }
+
+ }
+ bpf_error("unknown data link type %d", linktype);
+ /* NOTREACHED */
+}
+
+/*
+ * Load a value relative to the beginning of the link-layer header.
+ * The link-layer header doesn't necessarily begin at the beginning
+ * of the packet data; there might be a variable-length prefix containing
+ * radio information.
+ */
+static struct slist *
+gen_load_llrel(offset, size)
+ u_int offset, size;
+{
+ struct slist *s, *s2;
+
+ s = gen_llprefixlen();
+
+ /*
+ * If "s" is non-null, it has code to arrange that the X register
+ * contains the length of the prefix preceding the link-layer
+ * header.
+ *
+ * Otherwise, the length of the prefix preceding the link-layer
+ * header is "off_ll".
+ */
+ if (s != NULL) {
+ /*
+ * There's a variable-length prefix preceding the
+ * link-layer header. "s" points to a list of statements
+ * that put the length of that prefix into the X register.
+ * do an indirect load, to use the X register as an offset.
+ */
+ s2 = new_stmt(BPF_LD|BPF_IND|size);
+ s2->s.k = offset;
+ sappend(s, s2);
+ } else {
+ /*
+ * There is no variable-length header preceding the
+ * link-layer header; add in off_ll, which, if there's
+ * a fixed-length header preceding the link-layer header,
+ * is the length of that header.
+ */
+ s = new_stmt(BPF_LD|BPF_ABS|size);
+ s->s.k = offset + off_ll;
+ }
+ return s;
+}
+
+/*
+ * Load a value relative to the beginning of the MAC-layer payload.
+ */
+static struct slist *
+gen_load_macplrel(offset, size)
+ u_int offset, size;
+{
+ struct slist *s, *s2;
+
+ s = gen_off_macpl();
+
+ /*
+ * If s is non-null, the offset of the MAC-layer payload is
+ * variable, and s points to a list of instructions that
+ * arrange that the X register contains that offset.
+ *
+ * Otherwise, the offset of the MAC-layer payload is constant,
+ * and is in off_macpl.
+ */
+ if (s != NULL) {
+ /*
+ * The offset of the MAC-layer payload is in the X
+ * register. Do an indirect load, to use the X register
+ * as an offset.
+ */
+ s2 = new_stmt(BPF_LD|BPF_IND|size);
+ s2->s.k = offset;
+ sappend(s, s2);
+ } else {
+ /*
+ * The offset of the MAC-layer payload is constant,
+ * and is in off_macpl; load the value at that offset
+ * plus the specified offset.
+ */
+ s = new_stmt(BPF_LD|BPF_ABS|size);
+ s->s.k = off_macpl + offset;
+ }
+ return s;
+}
+
+/*
+ * Load a value relative to the beginning of the specified header.
+ */
+static struct slist *
+gen_load_a(offrel, offset, size)
+ enum e_offrel offrel;
+ u_int offset, size;
+{
+ struct slist *s, *s2;
+
+ switch (offrel) {
+
+ case OR_PACKET:
+ s = new_stmt(BPF_LD|BPF_ABS|size);
+ s->s.k = offset;
+ break;
+
+ case OR_LINK:
+ s = gen_load_llrel(offset, size);
+ break;
+
+ case OR_MACPL:
+ s = gen_load_macplrel(offset, size);
+ break;
+
+ case OR_NET:
+ s = gen_load_macplrel(off_nl + offset, size);
+ break;
+
+ case OR_NET_NOSNAP:
+ s = gen_load_macplrel(off_nl_nosnap + offset, size);
+ break;
+
+ case OR_TRAN_IPV4:
+ /*
+ * Load the X register with the length of the IPv4 header
+ * (plus the offset of the link-layer header, if it's
+ * preceded by a variable-length header such as a radio
+ * header), in bytes.
+ */
+ s = gen_loadx_iphdrlen();
+
+ /*
+ * Load the item at {offset of the MAC-layer payload} +
+ * {offset, relative to the start of the MAC-layer
+ * paylod, of the IPv4 header} + {length of the IPv4 header} +
+ * {specified offset}.
+ *
+ * (If the offset of the MAC-layer payload is variable,
+ * it's included in the value in the X register, and
+ * off_macpl is 0.)
+ */
+ s2 = new_stmt(BPF_LD|BPF_IND|size);
+ s2->s.k = off_macpl + off_nl + offset;
+ sappend(s, s2);
+ break;
+
+ case OR_TRAN_IPV6:
+ s = gen_load_macplrel(off_nl + 40 + offset, size);
+ break;
+
+ default:
+ abort();
+ return NULL;
+ }
+ return s;
+}
+
+/*
+ * Generate code to load into the X register the sum of the length of
+ * the IPv4 header and any variable-length header preceding the link-layer
+ * header.
+ */
+static struct slist *
+gen_loadx_iphdrlen()
+{
+ struct slist *s, *s2;
+
+ s = gen_off_macpl();
+ if (s != NULL) {
+ /*
+ * There's a variable-length prefix preceding the
+ * link-layer header, or the link-layer header is itself
+ * variable-length. "s" points to a list of statements
+ * that put the offset of the MAC-layer payload into
+ * the X register.
+ *
+ * The 4*([k]&0xf) addressing mode can't be used, as we
+ * don't have a constant offset, so we have to load the
+ * value in question into the A register and add to it
+ * the value from the X register.
+ */
+ s2 = new_stmt(BPF_LD|BPF_IND|BPF_B);
+ s2->s.k = off_nl;
+ sappend(s, s2);
+ s2 = new_stmt(BPF_ALU|BPF_AND|BPF_K);
+ s2->s.k = 0xf;
+ sappend(s, s2);
+ s2 = new_stmt(BPF_ALU|BPF_LSH|BPF_K);
+ s2->s.k = 2;
+ sappend(s, s2);
+
+ /*
+ * The A register now contains the length of the
+ * IP header. We need to add to it the offset of
+ * the MAC-layer payload, which is still in the X
+ * register, and move the result into the X register.
+ */
+ sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
+ sappend(s, new_stmt(BPF_MISC|BPF_TAX));
+ } else {
+ /*
+ * There is no variable-length header preceding the
+ * link-layer header, and the link-layer header is
+ * fixed-length; load the length of the IPv4 header,
+ * which is at an offset of off_nl from the beginning
+ * of the MAC-layer payload, and thus at an offset
+ * of off_mac_pl + off_nl from the beginning of the
+ * raw packet data.
+ */
+ s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
+ s->s.k = off_macpl + off_nl;
+ }
+ return s;
+}
+
+static struct block *
+gen_uncond(rsense)
+ int rsense;
+{
+ struct block *b;
+ struct slist *s;
+
+ s = new_stmt(BPF_LD|BPF_IMM);
+ s->s.k = !rsense;
+ b = new_block(JMP(BPF_JEQ));
+ b->stmts = s;
+
+ return b;
+}
+
+static inline struct block *
+gen_true()
+{
+ return gen_uncond(1);
+}
+
+static inline struct block *
+gen_false()
+{
+ return gen_uncond(0);
+}
+
+/*
+ * Byte-swap a 32-bit number.
+ * ("htonl()" or "ntohl()" won't work - we want to byte-swap even on
+ * big-endian platforms.)
+ */
+#define SWAPLONG(y) \
+((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
+
+/*
+ * Generate code to match a particular packet type.
+ *
+ * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP
+ * value, if <= ETHERMTU. We use that to determine whether to
+ * match the type/length field or to check the type/length field for
+ * a value <= ETHERMTU to see whether it's a type field and then do
+ * the appropriate test.
+ */
+static struct block *
+gen_ether_linktype(proto)
+ register int proto;
+{
+ struct block *b0, *b1;
+
+ switch (proto) {
+
+ case LLCSAP_ISONS:
+ case LLCSAP_IP:
+ case LLCSAP_NETBEUI:
+ /*
+ * OSI protocols and NetBEUI always use 802.2 encapsulation,
+ * so we check the DSAP and SSAP.
+ *
+ * LLCSAP_IP checks for IP-over-802.2, rather
+ * than IP-over-Ethernet or IP-over-SNAP.
+ *
+ * XXX - should we check both the DSAP and the
+ * SSAP, like this, or should we check just the
+ * DSAP, as we do for other types <= ETHERMTU
+ * (i.e., other SAP values)?
+ */
+ b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU);
+ gen_not(b0);
+ b1 = gen_cmp(OR_MACPL, 0, BPF_H, (bpf_int32)
+ ((proto << 8) | proto));
+ gen_and(b0, b1);
+ return b1;
+
+ case LLCSAP_IPX:
+ /*
+ * Check for;
+ *
+ * Ethernet_II frames, which are Ethernet
+ * frames with a frame type of ETHERTYPE_IPX;
+ *
+ * Ethernet_802.3 frames, which are 802.3
+ * frames (i.e., the type/length field is
+ * a length field, <= ETHERMTU, rather than
+ * a type field) with the first two bytes
+ * after the Ethernet/802.3 header being
+ * 0xFFFF;
+ *
+ * Ethernet_802.2 frames, which are 802.3
+ * frames with an 802.2 LLC header and
+ * with the IPX LSAP as the DSAP in the LLC
+ * header;
+ *
+ * Ethernet_SNAP frames, which are 802.3
+ * frames with an LLC header and a SNAP
+ * header and with an OUI of 0x000000
+ * (encapsulated Ethernet) and a protocol
+ * ID of ETHERTYPE_IPX in the SNAP header.
+ *
+ * XXX - should we generate the same code both
+ * for tests for LLCSAP_IPX and for ETHERTYPE_IPX?
+ */
+
+ /*
+ * This generates code to check both for the
+ * IPX LSAP (Ethernet_802.2) and for Ethernet_802.3.
+ */
+ b0 = gen_cmp(OR_MACPL, 0, BPF_B, (bpf_int32)LLCSAP_IPX);
+ b1 = gen_cmp(OR_MACPL, 0, BPF_H, (bpf_int32)0xFFFF);
+ gen_or(b0, b1);
+
+ /*
+ * Now we add code to check for SNAP frames with
+ * ETHERTYPE_IPX, i.e. Ethernet_SNAP.
+ */
+ b0 = gen_snap(0x000000, ETHERTYPE_IPX);
+ gen_or(b0, b1);
+
+ /*
+ * Now we generate code to check for 802.3
+ * frames in general.
+ */
+ b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU);
+ gen_not(b0);
+
+ /*
+ * Now add the check for 802.3 frames before the
+ * check for Ethernet_802.2 and Ethernet_802.3,
+ * as those checks should only be done on 802.3
+ * frames, not on Ethernet frames.
+ */
+ gen_and(b0, b1);
+
+ /*
+ * Now add the check for Ethernet_II frames, and
+ * do that before checking for the other frame
+ * types.
+ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
+ (bpf_int32)ETHERTYPE_IPX);
+ gen_or(b0, b1);
+ return b1;
+
+ case ETHERTYPE_ATALK:
+ case ETHERTYPE_AARP:
+ /*
+ * EtherTalk (AppleTalk protocols on Ethernet link
+ * layer) may use 802.2 encapsulation.
+ */
+
+ /*
+ * Check for 802.2 encapsulation (EtherTalk phase 2?);
+ * we check for an Ethernet type field less than
+ * 1500, which means it's an 802.3 length field.
+ */
+ b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU);
+ gen_not(b0);
+
+ /*
+ * 802.2-encapsulated ETHERTYPE_ATALK packets are
+ * SNAP packets with an organization code of
+ * 0x080007 (Apple, for Appletalk) and a protocol
+ * type of ETHERTYPE_ATALK (Appletalk).
+ *
+ * 802.2-encapsulated ETHERTYPE_AARP packets are
+ * SNAP packets with an organization code of
+ * 0x000000 (encapsulated Ethernet) and a protocol
+ * type of ETHERTYPE_AARP (Appletalk ARP).
+ */
+ if (proto == ETHERTYPE_ATALK)
+ b1 = gen_snap(0x080007, ETHERTYPE_ATALK);
+ else /* proto == ETHERTYPE_AARP */
+ b1 = gen_snap(0x000000, ETHERTYPE_AARP);
+ gen_and(b0, b1);
+
+ /*
+ * Check for Ethernet encapsulation (Ethertalk
+ * phase 1?); we just check for the Ethernet
+ * protocol type.
+ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);
+
+ gen_or(b0, b1);
+ return b1;
+
+ default:
+ if (proto <= ETHERMTU) {
+ /*
+ * This is an LLC SAP value, so the frames
+ * that match would be 802.2 frames.
+ * Check that the frame is an 802.2 frame
+ * (i.e., that the length/type field is
+ * a length field, <= ETHERMTU) and
+ * then check the DSAP.
+ */
+ b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU);
+ gen_not(b0);
+ b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_B,
+ (bpf_int32)proto);
+ gen_and(b0, b1);
+ return b1;
+ } else {
+ /*
+ * This is an Ethernet type, so compare
+ * the length/type field with it (if
+ * the frame is an 802.2 frame, the length
+ * field will be <= ETHERMTU, and, as
+ * "proto" is > ETHERMTU, this test
+ * will fail and the frame won't match,
+ * which is what we want).
+ */
+ return gen_cmp(OR_LINK, off_linktype, BPF_H,
+ (bpf_int32)proto);
+ }
+ }
+}
+
+/*
+ * "proto" is an Ethernet type value and for IPNET, if it is not IPv4
+ * or IPv6 then we have an error.
+ */
+static struct block *
+gen_ipnet_linktype(proto)
+ register int proto;
+{
+ switch (proto) {
+
+ case ETHERTYPE_IP:
+ return gen_cmp(OR_LINK, off_linktype, BPF_B,
+ (bpf_int32)IPH_AF_INET);
+ /* NOTREACHED */
+
+ case ETHERTYPE_IPV6:
+ return gen_cmp(OR_LINK, off_linktype, BPF_B,
+ (bpf_int32)IPH_AF_INET6);
+ /* NOTREACHED */
+
+ default:
+ break;
+ }
+
+ return gen_false();
+}
+
+/*
+ * Generate code to match a particular packet type.
+ *
+ * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP
+ * value, if <= ETHERMTU. We use that to determine whether to
+ * match the type field or to check the type field for the special
+ * LINUX_SLL_P_802_2 value and then do the appropriate test.
+ */
+static struct block *
+gen_linux_sll_linktype(proto)
+ register int proto;
+{
+ struct block *b0, *b1;
+
+ switch (proto) {
+
+ case LLCSAP_ISONS:
+ case LLCSAP_IP:
+ case LLCSAP_NETBEUI:
+ /*
+ * OSI protocols and NetBEUI always use 802.2 encapsulation,
+ * so we check the DSAP and SSAP.
+ *
+ * LLCSAP_IP checks for IP-over-802.2, rather
+ * than IP-over-Ethernet or IP-over-SNAP.
+ *
+ * XXX - should we check both the DSAP and the
+ * SSAP, like this, or should we check just the
+ * DSAP, as we do for other types <= ETHERMTU
+ * (i.e., other SAP values)?
+ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2);
+ b1 = gen_cmp(OR_MACPL, 0, BPF_H, (bpf_int32)
+ ((proto << 8) | proto));
+ gen_and(b0, b1);
+ return b1;
+
+ case LLCSAP_IPX:
+ /*
+ * Ethernet_II frames, which are Ethernet
+ * frames with a frame type of ETHERTYPE_IPX;
+ *
+ * Ethernet_802.3 frames, which have a frame
+ * type of LINUX_SLL_P_802_3;
+ *
+ * Ethernet_802.2 frames, which are 802.3
+ * frames with an 802.2 LLC header (i.e, have
+ * a frame type of LINUX_SLL_P_802_2) and
+ * with the IPX LSAP as the DSAP in the LLC
+ * header;
+ *
+ * Ethernet_SNAP frames, which are 802.3
+ * frames with an LLC header and a SNAP
+ * header and with an OUI of 0x000000
+ * (encapsulated Ethernet) and a protocol
+ * ID of ETHERTYPE_IPX in the SNAP header.
+ *
+ * First, do the checks on LINUX_SLL_P_802_2
+ * frames; generate the check for either
+ * Ethernet_802.2 or Ethernet_SNAP frames, and
+ * then put a check for LINUX_SLL_P_802_2 frames
+ * before it.
+ */
+ b0 = gen_cmp(OR_MACPL, 0, BPF_B, (bpf_int32)LLCSAP_IPX);
+ b1 = gen_snap(0x000000, ETHERTYPE_IPX);
+ gen_or(b0, b1);
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2);
+ gen_and(b0, b1);
+
+ /*
+ * Now check for 802.3 frames and OR that with
+ * the previous test.
+ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_3);
+ gen_or(b0, b1);
+
+ /*
+ * Now add the check for Ethernet_II frames, and
+ * do that before checking for the other frame
+ * types.
+ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
+ (bpf_int32)ETHERTYPE_IPX);
+ gen_or(b0, b1);
+ return b1;
+
+ case ETHERTYPE_ATALK:
+ case ETHERTYPE_AARP:
+ /*
+ * EtherTalk (AppleTalk protocols on Ethernet link
+ * layer) may use 802.2 encapsulation.
+ */
+
+ /*
+ * Check for 802.2 encapsulation (EtherTalk phase 2?);
+ * we check for the 802.2 protocol type in the
+ * "Ethernet type" field.
+ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2);
+
+ /*
+ * 802.2-encapsulated ETHERTYPE_ATALK packets are
+ * SNAP packets with an organization code of
+ * 0x080007 (Apple, for Appletalk) and a protocol
+ * type of ETHERTYPE_ATALK (Appletalk).
+ *
+ * 802.2-encapsulated ETHERTYPE_AARP packets are
+ * SNAP packets with an organization code of
+ * 0x000000 (encapsulated Ethernet) and a protocol
+ * type of ETHERTYPE_AARP (Appletalk ARP).
+ */
+ if (proto == ETHERTYPE_ATALK)
+ b1 = gen_snap(0x080007, ETHERTYPE_ATALK);
+ else /* proto == ETHERTYPE_AARP */
+ b1 = gen_snap(0x000000, ETHERTYPE_AARP);
+ gen_and(b0, b1);
+
+ /*
+ * Check for Ethernet encapsulation (Ethertalk
+ * phase 1?); we just check for the Ethernet
+ * protocol type.
+ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);
+
+ gen_or(b0, b1);
+ return b1;
+
+ default:
+ if (proto <= ETHERMTU) {
+ /*
+ * This is an LLC SAP value, so the frames
+ * that match would be 802.2 frames.
+ * Check for the 802.2 protocol type
+ * in the "Ethernet type" field, and
+ * then check the DSAP.
+ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
+ LINUX_SLL_P_802_2);
+ b1 = gen_cmp(OR_LINK, off_macpl, BPF_B,
+ (bpf_int32)proto);
+ gen_and(b0, b1);
+ return b1;
+ } else {
+ /*
+ * This is an Ethernet type, so compare
+ * the length/type field with it (if
+ * the frame is an 802.2 frame, the length
+ * field will be <= ETHERMTU, and, as
+ * "proto" is > ETHERMTU, this test
+ * will fail and the frame won't match,
+ * which is what we want).
+ */
+ return gen_cmp(OR_LINK, off_linktype, BPF_H,
+ (bpf_int32)proto);
+ }
+ }
+}
+
+static struct slist *
+gen_load_prism_llprefixlen()
+{
+ struct slist *s1, *s2;
+ struct slist *sjeq_avs_cookie;
+ struct slist *sjcommon;
+
+ /*
+ * This code is not compatible with the optimizer, as
+ * we are generating jmp instructions within a normal
+ * slist of instructions
+ */
+ no_optimize = 1;
+
+ /*
+ * Generate code to load the length of the radio header into
+ * the register assigned to hold that length, if one has been
+ * assigned. (If one hasn't been assigned, no code we've
+ * generated uses that prefix, so we don't need to generate any
+ * code to load it.)
+ *
+ * Some Linux drivers use ARPHRD_IEEE80211_PRISM but sometimes
+ * or always use the AVS header rather than the Prism header.
+ * We load a 4-byte big-endian value at the beginning of the
+ * raw packet data, and see whether, when masked with 0xFFFFF000,
+ * it's equal to 0x80211000. If so, that indicates that it's
+ * an AVS header (the masked-out bits are the version number).
+ * Otherwise, it's a Prism header.
+ *
+ * XXX - the Prism header is also, in theory, variable-length,
+ * but no known software generates headers that aren't 144
+ * bytes long.
+ */
+ if (reg_off_ll != -1) {
+ /*
+ * Load the cookie.
+ */
+ s1 = new_stmt(BPF_LD|BPF_W|BPF_ABS);
+ s1->s.k = 0;
+
+ /*
+ * AND it with 0xFFFFF000.
+ */
+ s2 = new_stmt(BPF_ALU|BPF_AND|BPF_K);
+ s2->s.k = 0xFFFFF000;
+ sappend(s1, s2);
+
+ /*
+ * Compare with 0x80211000.
+ */
+ sjeq_avs_cookie = new_stmt(JMP(BPF_JEQ));
+ sjeq_avs_cookie->s.k = 0x80211000;
+ sappend(s1, sjeq_avs_cookie);
+
+ /*
+ * If it's AVS:
+ *
+ * The 4 bytes at an offset of 4 from the beginning of
+ * the AVS header are the length of the AVS header.
+ * That field is big-endian.
+ */
+ s2 = new_stmt(BPF_LD|BPF_W|BPF_ABS);
+ s2->s.k = 4;
+ sappend(s1, s2);
+ sjeq_avs_cookie->s.jt = s2;
+
+ /*
+ * Now jump to the code to allocate a register
+ * into which to save the header length and
+ * store the length there. (The "jump always"
+ * instruction needs to have the k field set;
+ * it's added to the PC, so, as we're jumping
+ * over a single instruction, it should be 1.)
+ */
+ sjcommon = new_stmt(JMP(BPF_JA));
+ sjcommon->s.k = 1;
+ sappend(s1, sjcommon);
+
+ /*
+ * Now for the code that handles the Prism header.
+ * Just load the length of the Prism header (144)
+ * into the A register. Have the test for an AVS
+ * header branch here if we don't have an AVS header.
+ */
+ s2 = new_stmt(BPF_LD|BPF_W|BPF_IMM);
+ s2->s.k = 144;
+ sappend(s1, s2);
+ sjeq_avs_cookie->s.jf = s2;
+
+ /*
+ * Now allocate a register to hold that value and store
+ * it. The code for the AVS header will jump here after
+ * loading the length of the AVS header.
+ */
+ s2 = new_stmt(BPF_ST);
+ s2->s.k = reg_off_ll;
+ sappend(s1, s2);
+ sjcommon->s.jf = s2;
+
+ /*
+ * Now move it into the X register.
+ */
+ s2 = new_stmt(BPF_MISC|BPF_TAX);
+ sappend(s1, s2);
+
+ return (s1);
+ } else
+ return (NULL);
+}
+
+static struct slist *
+gen_load_avs_llprefixlen()
+{
+ struct slist *s1, *s2;
+
+ /*
+ * Generate code to load the length of the AVS header into
+ * the register assigned to hold that length, if one has been
+ * assigned. (If one hasn't been assigned, no code we've
+ * generated uses that prefix, so we don't need to generate any
+ * code to load it.)
+ */
+ if (reg_off_ll != -1) {
+ /*
+ * The 4 bytes at an offset of 4 from the beginning of
+ * the AVS header are the length of the AVS header.
+ * That field is big-endian.
+ */
+ s1 = new_stmt(BPF_LD|BPF_W|BPF_ABS);
+ s1->s.k = 4;
+
+ /*
+ * Now allocate a register to hold that value and store
+ * it.
+ */
+ s2 = new_stmt(BPF_ST);
+ s2->s.k = reg_off_ll;
+ sappend(s1, s2);
+
+ /*
+ * Now move it into the X register.
+ */
+ s2 = new_stmt(BPF_MISC|BPF_TAX);
+ sappend(s1, s2);
+
+ return (s1);
+ } else
+ return (NULL);
+}
+
+static struct slist *
+gen_load_radiotap_llprefixlen()
+{
+ struct slist *s1, *s2;
+
+ /*
+ * Generate code to load the length of the radiotap header into
+ * the register assigned to hold that length, if one has been
+ * assigned. (If one hasn't been assigned, no code we've
+ * generated uses that prefix, so we don't need to generate any
+ * code to load it.)
+ */
+ if (reg_off_ll != -1) {
+ /*
+ * The 2 bytes at offsets of 2 and 3 from the beginning
+ * of the radiotap header are the length of the radiotap
+ * header; unfortunately, it's little-endian, so we have
+ * to load it a byte at a time and construct the value.
+ */
+
+ /*
+ * Load the high-order byte, at an offset of 3, shift it
+ * left a byte, and put the result in the X register.
+ */
+ s1 = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s1->s.k = 3;
+ s2 = new_stmt(BPF_ALU|BPF_LSH|BPF_K);
+ sappend(s1, s2);
+ s2->s.k = 8;
+ s2 = new_stmt(BPF_MISC|BPF_TAX);
+ sappend(s1, s2);
+
+ /*
+ * Load the next byte, at an offset of 2, and OR the
+ * value from the X register into it.
+ */
+ s2 = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ sappend(s1, s2);
+ s2->s.k = 2;
+ s2 = new_stmt(BPF_ALU|BPF_OR|BPF_X);
+ sappend(s1, s2);
+
+ /*
+ * Now allocate a register to hold that value and store
+ * it.
+ */
+ s2 = new_stmt(BPF_ST);
+ s2->s.k = reg_off_ll;
+ sappend(s1, s2);
+
+ /*
+ * Now move it into the X register.
+ */
+ s2 = new_stmt(BPF_MISC|BPF_TAX);
+ sappend(s1, s2);
+
+ return (s1);
+ } else
+ return (NULL);
+}
+
+/*
+ * At the moment we treat PPI as normal Radiotap encoded
+ * packets. The difference is in the function that generates
+ * the code at the beginning to compute the header length.
+ * Since this code generator of PPI supports bare 802.11
+ * encapsulation only (i.e. the encapsulated DLT should be
+ * DLT_IEEE802_11) we generate code to check for this too;
+ * that's done in finish_parse().
+ */
+static struct slist *
+gen_load_ppi_llprefixlen()
+{
+ struct slist *s1, *s2;
+
+ /*
+ * Generate code to load the length of the radiotap header
+ * into the register assigned to hold that length, if one has
+ * been assigned.
+ */
+ if (reg_off_ll != -1) {
+ /*
+ * The 2 bytes at offsets of 2 and 3 from the beginning
+ * of the radiotap header are the length of the radiotap
+ * header; unfortunately, it's little-endian, so we have
+ * to load it a byte at a time and construct the value.
+ */
+
+ /*
+ * Load the high-order byte, at an offset of 3, shift it
+ * left a byte, and put the result in the X register.
+ */
+ s1 = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s1->s.k = 3;
+ s2 = new_stmt(BPF_ALU|BPF_LSH|BPF_K);
+ sappend(s1, s2);
+ s2->s.k = 8;
+ s2 = new_stmt(BPF_MISC|BPF_TAX);
+ sappend(s1, s2);
+
+ /*
+ * Load the next byte, at an offset of 2, and OR the
+ * value from the X register into it.
+ */
+ s2 = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ sappend(s1, s2);
+ s2->s.k = 2;
+ s2 = new_stmt(BPF_ALU|BPF_OR|BPF_X);
+ sappend(s1, s2);
+
+ /*
+ * Now allocate a register to hold that value and store
+ * it.
+ */
+ s2 = new_stmt(BPF_ST);
+ s2->s.k = reg_off_ll;
+ sappend(s1, s2);
+
+ /*
+ * Now move it into the X register.
+ */
+ s2 = new_stmt(BPF_MISC|BPF_TAX);
+ sappend(s1, s2);
+
+ return (s1);
+ } else
+ return (NULL);
+}
+
+/*
+ * Load a value relative to the beginning of the link-layer header after the 802.11
+ * header, i.e. LLC_SNAP.
+ * The link-layer header doesn't necessarily begin at the beginning
+ * of the packet data; there might be a variable-length prefix containing
+ * radio information.
+ */
+static struct slist *
+gen_load_802_11_header_len(struct slist *s, struct slist *snext)
+{
+ struct slist *s2;
+ struct slist *sjset_data_frame_1;
+ struct slist *sjset_data_frame_2;
+ struct slist *sjset_qos;
+ struct slist *sjset_radiotap_flags;
+ struct slist *sjset_radiotap_tsft;
+ struct slist *sjset_tsft_datapad, *sjset_notsft_datapad;
+ struct slist *s_roundup;
+
+ if (reg_off_macpl == -1) {
+ /*
+ * No register has been assigned to the offset of
+ * the MAC-layer payload, which means nobody needs
+ * it; don't bother computing it - just return
+ * what we already have.
+ */
+ return (s);
+ }
+
+ /*
+ * This code is not compatible with the optimizer, as
+ * we are generating jmp instructions within a normal
+ * slist of instructions
+ */
+ no_optimize = 1;
+
+ /*
+ * If "s" is non-null, it has code to arrange that the X register
+ * contains the length of the prefix preceding the link-layer
+ * header.
+ *
+ * Otherwise, the length of the prefix preceding the link-layer
+ * header is "off_ll".
+ */
+ if (s == NULL) {
+ /*
+ * There is no variable-length header preceding the
+ * link-layer header.
+ *
+ * Load the length of the fixed-length prefix preceding
+ * the link-layer header (if any) into the X register,
+ * and store it in the reg_off_macpl register.
+ * That length is off_ll.
+ */
+ s = new_stmt(BPF_LDX|BPF_IMM);
+ s->s.k = off_ll;
+ }
+
+ /*
+ * The X register contains the offset of the beginning of the
+ * link-layer header; add 24, which is the minimum length
+ * of the MAC header for a data frame, to that, and store it
+ * in reg_off_macpl, and then load the Frame Control field,
+ * which is at the offset in the X register, with an indexed load.
+ */
+ s2 = new_stmt(BPF_MISC|BPF_TXA);
+ sappend(s, s2);
+ s2 = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
+ s2->s.k = 24;
+ sappend(s, s2);
+ s2 = new_stmt(BPF_ST);
+ s2->s.k = reg_off_macpl;
+ sappend(s, s2);
+
+ s2 = new_stmt(BPF_LD|BPF_IND|BPF_B);
+ s2->s.k = 0;
+ sappend(s, s2);
+
+ /*
+ * Check the Frame Control field to see if this is a data frame;
+ * a data frame has the 0x08 bit (b3) in that field set and the
+ * 0x04 bit (b2) clear.
+ */
+ sjset_data_frame_1 = new_stmt(JMP(BPF_JSET));
+ sjset_data_frame_1->s.k = 0x08;
+ sappend(s, sjset_data_frame_1);
+
+ /*
+ * If b3 is set, test b2, otherwise go to the first statement of
+ * the rest of the program.
+ */
+ sjset_data_frame_1->s.jt = sjset_data_frame_2 = new_stmt(JMP(BPF_JSET));
+ sjset_data_frame_2->s.k = 0x04;
+ sappend(s, sjset_data_frame_2);
+ sjset_data_frame_1->s.jf = snext;
+
+ /*
+ * If b2 is not set, this is a data frame; test the QoS bit.
+ * Otherwise, go to the first statement of the rest of the
+ * program.
+ */
+ sjset_data_frame_2->s.jt = snext;
+ sjset_data_frame_2->s.jf = sjset_qos = new_stmt(JMP(BPF_JSET));
+ sjset_qos->s.k = 0x80; /* QoS bit */
+ sappend(s, sjset_qos);
+
+ /*
+ * If it's set, add 2 to reg_off_macpl, to skip the QoS
+ * field.
+ * Otherwise, go to the first statement of the rest of the
+ * program.
+ */
+ sjset_qos->s.jt = s2 = new_stmt(BPF_LD|BPF_MEM);
+ s2->s.k = reg_off_macpl;
+ sappend(s, s2);
+ s2 = new_stmt(BPF_ALU|BPF_ADD|BPF_IMM);
+ s2->s.k = 2;
+ sappend(s, s2);
+ s2 = new_stmt(BPF_ST);
+ s2->s.k = reg_off_macpl;
+ sappend(s, s2);
+
+ /*
+ * If we have a radiotap header, look at it to see whether
+ * there's Atheros padding between the MAC-layer header
+ * and the payload.
+ *
+ * Note: all of the fields in the radiotap header are
+ * little-endian, so we byte-swap all of the values
+ * we test against, as they will be loaded as big-endian
+ * values.
+ */
+ if (linktype == DLT_IEEE802_11_RADIO) {
+ /*
+ * Is the IEEE80211_RADIOTAP_FLAGS bit (0x0000002) set
+ * in the presence flag?
+ */
+ sjset_qos->s.jf = s2 = new_stmt(BPF_LD|BPF_ABS|BPF_W);
+ s2->s.k = 4;
+ sappend(s, s2);
+
+ sjset_radiotap_flags = new_stmt(JMP(BPF_JSET));
+ sjset_radiotap_flags->s.k = SWAPLONG(0x00000002);
+ sappend(s, sjset_radiotap_flags);
+
+ /*
+ * If not, skip all of this.
+ */
+ sjset_radiotap_flags->s.jf = snext;
+
+ /*
+ * Otherwise, is the IEEE80211_RADIOTAP_TSFT bit set?
+ */
+ sjset_radiotap_tsft = sjset_radiotap_flags->s.jt =
+ new_stmt(JMP(BPF_JSET));
+ sjset_radiotap_tsft->s.k = SWAPLONG(0x00000001);
+ sappend(s, sjset_radiotap_tsft);
+
+ /*
+ * If IEEE80211_RADIOTAP_TSFT is set, the flags field is
+ * at an offset of 16 from the beginning of the raw packet
+ * data (8 bytes for the radiotap header and 8 bytes for
+ * the TSFT field).
+ *
+ * Test whether the IEEE80211_RADIOTAP_F_DATAPAD bit (0x20)
+ * is set.
+ */
+ sjset_radiotap_tsft->s.jt = s2 = new_stmt(BPF_LD|BPF_ABS|BPF_B);
+ s2->s.k = 16;
+ sappend(s, s2);
+
+ sjset_tsft_datapad = new_stmt(JMP(BPF_JSET));
+ sjset_tsft_datapad->s.k = 0x20;
+ sappend(s, sjset_tsft_datapad);
+
+ /*
+ * If IEEE80211_RADIOTAP_TSFT is not set, the flags field is
+ * at an offset of 8 from the beginning of the raw packet
+ * data (8 bytes for the radiotap header).
+ *
+ * Test whether the IEEE80211_RADIOTAP_F_DATAPAD bit (0x20)
+ * is set.
+ */
+ sjset_radiotap_tsft->s.jf = s2 = new_stmt(BPF_LD|BPF_ABS|BPF_B);
+ s2->s.k = 8;
+ sappend(s, s2);
+
+ sjset_notsft_datapad = new_stmt(JMP(BPF_JSET));
+ sjset_notsft_datapad->s.k = 0x20;
+ sappend(s, sjset_notsft_datapad);
+
+ /*
+ * In either case, if IEEE80211_RADIOTAP_F_DATAPAD is
+ * set, round the length of the 802.11 header to
+ * a multiple of 4. Do that by adding 3 and then
+ * dividing by and multiplying by 4, which we do by
+ * ANDing with ~3.
+ */
+ s_roundup = new_stmt(BPF_LD|BPF_MEM);
+ s_roundup->s.k = reg_off_macpl;
+ sappend(s, s_roundup);
+ s2 = new_stmt(BPF_ALU|BPF_ADD|BPF_IMM);
+ s2->s.k = 3;
+ sappend(s, s2);
+ s2 = new_stmt(BPF_ALU|BPF_AND|BPF_IMM);
+ s2->s.k = ~3;
+ sappend(s, s2);
+ s2 = new_stmt(BPF_ST);
+ s2->s.k = reg_off_macpl;
+ sappend(s, s2);
+
+ sjset_tsft_datapad->s.jt = s_roundup;
+ sjset_tsft_datapad->s.jf = snext;
+ sjset_notsft_datapad->s.jt = s_roundup;
+ sjset_notsft_datapad->s.jf = snext;
+ } else
+ sjset_qos->s.jf = snext;
+
+ return s;
+}
+
+static void
+insert_compute_vloffsets(b)
+ struct block *b;
+{
+ struct slist *s;
+
+ /*
+ * For link-layer types that have a variable-length header
+ * preceding the link-layer header, generate code to load
+ * the offset of the link-layer header into the register
+ * assigned to that offset, if any.
+ */
+ switch (linktype) {
+
+ case DLT_PRISM_HEADER:
+ s = gen_load_prism_llprefixlen();
+ break;
+
+ case DLT_IEEE802_11_RADIO_AVS:
+ s = gen_load_avs_llprefixlen();
+ break;
+
+ case DLT_IEEE802_11_RADIO:
+ s = gen_load_radiotap_llprefixlen();
+ break;
+
+ case DLT_PPI:
+ s = gen_load_ppi_llprefixlen();
+ break;
+
+ default:
+ s = NULL;
+ break;
+ }
+
+ /*
+ * For link-layer types that have a variable-length link-layer
+ * header, generate code to load the offset of the MAC-layer
+ * payload into the register assigned to that offset, if any.
+ */
+ switch (linktype) {
+
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_PPI:
+ s = gen_load_802_11_header_len(s, b->stmts);
+ break;
+ }
+
+ /*
+ * If we have any offset-loading code, append all the
+ * existing statements in the block to those statements,
+ * and make the resulting list the list of statements
+ * for the block.
+ */
+ if (s != NULL) {
+ sappend(s, b->stmts);
+ b->stmts = s;
+ }
+}
+
+static struct block *
+gen_ppi_dlt_check(void)
+{
+ struct slist *s_load_dlt;
+ struct block *b;
+
+ if (linktype == DLT_PPI)
+ {
+ /* Create the statements that check for the DLT
+ */
+ s_load_dlt = new_stmt(BPF_LD|BPF_W|BPF_ABS);
+ s_load_dlt->s.k = 4;
+
+ b = new_block(JMP(BPF_JEQ));
+
+ b->stmts = s_load_dlt;
+ b->s.k = SWAPLONG(DLT_IEEE802_11);
+ }
+ else
+ {
+ b = NULL;
+ }
+
+ return b;
+}
+
+static struct slist *
+gen_prism_llprefixlen(void)
+{
+ struct slist *s;
+
+ if (reg_off_ll == -1) {
+ /*
+ * We haven't yet assigned a register for the length
+ * of the radio header; allocate one.
+ */
+ reg_off_ll = alloc_reg();
+ }
+
+ /*
+ * Load the register containing the radio length
+ * into the X register.
+ */
+ s = new_stmt(BPF_LDX|BPF_MEM);
+ s->s.k = reg_off_ll;
+ return s;
+}
+
+static struct slist *
+gen_avs_llprefixlen(void)
+{
+ struct slist *s;
+
+ if (reg_off_ll == -1) {
+ /*
+ * We haven't yet assigned a register for the length
+ * of the AVS header; allocate one.
+ */
+ reg_off_ll = alloc_reg();
+ }
+
+ /*
+ * Load the register containing the AVS length
+ * into the X register.
+ */
+ s = new_stmt(BPF_LDX|BPF_MEM);
+ s->s.k = reg_off_ll;
+ return s;
+}
+
+static struct slist *
+gen_radiotap_llprefixlen(void)
+{
+ struct slist *s;
+
+ if (reg_off_ll == -1) {
+ /*
+ * We haven't yet assigned a register for the length
+ * of the radiotap header; allocate one.
+ */
+ reg_off_ll = alloc_reg();
+ }
+
+ /*
+ * Load the register containing the radiotap length
+ * into the X register.
+ */
+ s = new_stmt(BPF_LDX|BPF_MEM);
+ s->s.k = reg_off_ll;
+ return s;
+}
+
+/*
+ * At the moment we treat PPI as normal Radiotap encoded
+ * packets. The difference is in the function that generates
+ * the code at the beginning to compute the header length.
+ * Since this code generator of PPI supports bare 802.11
+ * encapsulation only (i.e. the encapsulated DLT should be
+ * DLT_IEEE802_11) we generate code to check for this too.
+ */
+static struct slist *
+gen_ppi_llprefixlen(void)
+{
+ struct slist *s;
+
+ if (reg_off_ll == -1) {
+ /*
+ * We haven't yet assigned a register for the length
+ * of the radiotap header; allocate one.
+ */
+ reg_off_ll = alloc_reg();
+ }
+
+ /*
+ * Load the register containing the PPI length
+ * into the X register.
+ */
+ s = new_stmt(BPF_LDX|BPF_MEM);
+ s->s.k = reg_off_ll;
+ return s;
+}
+
+/*
+ * Generate code to compute the link-layer header length, if necessary,
+ * putting it into the X register, and to return either a pointer to a
+ * "struct slist" for the list of statements in that code, or NULL if
+ * no code is necessary.
+ */
+static struct slist *
+gen_llprefixlen(void)
+{
+ switch (linktype) {
+
+ case DLT_PRISM_HEADER:
+ return gen_prism_llprefixlen();
+
+ case DLT_IEEE802_11_RADIO_AVS:
+ return gen_avs_llprefixlen();
+
+ case DLT_IEEE802_11_RADIO:
+ return gen_radiotap_llprefixlen();
+
+ case DLT_PPI:
+ return gen_ppi_llprefixlen();
+
+ default:
+ return NULL;
+ }
+}
+
+/*
+ * Generate code to load the register containing the offset of the
+ * MAC-layer payload into the X register; if no register for that offset
+ * has been allocated, allocate it first.
+ */
+static struct slist *
+gen_off_macpl(void)
+{
+ struct slist *s;
+
+ if (off_macpl_is_variable) {
+ if (reg_off_macpl == -1) {
+ /*
+ * We haven't yet assigned a register for the offset
+ * of the MAC-layer payload; allocate one.
+ */
+ reg_off_macpl = alloc_reg();
+ }
+
+ /*
+ * Load the register containing the offset of the MAC-layer
+ * payload into the X register.
+ */
+ s = new_stmt(BPF_LDX|BPF_MEM);
+ s->s.k = reg_off_macpl;
+ return s;
+ } else {
+ /*
+ * That offset isn't variable, so we don't need to
+ * generate any code.
+ */
+ return NULL;
+ }
+}
+
+/*
+ * Map an Ethernet type to the equivalent PPP type.
+ */
+static int
+ethertype_to_ppptype(proto)
+ int proto;
+{
+ switch (proto) {
+
+ case ETHERTYPE_IP:
+ proto = PPP_IP;
+ break;
+
+ case ETHERTYPE_IPV6:
+ proto = PPP_IPV6;
+ break;
+
+ case ETHERTYPE_DN:
+ proto = PPP_DECNET;
+ break;
+
+ case ETHERTYPE_ATALK:
+ proto = PPP_APPLE;
+ break;
+
+ case ETHERTYPE_NS:
+ proto = PPP_NS;
+ break;
+
+ case LLCSAP_ISONS:
+ proto = PPP_OSI;
+ break;
+
+ case LLCSAP_8021D:
+ /*
+ * I'm assuming the "Bridging PDU"s that go
+ * over PPP are Spanning Tree Protocol
+ * Bridging PDUs.
+ */
+ proto = PPP_BRPDU;
+ break;
+
+ case LLCSAP_IPX:
+ proto = PPP_IPX;
+ break;
+ }
+ return (proto);
+}
+
+/*
+ * Generate code to match a particular packet type by matching the
+ * link-layer type field or fields in the 802.2 LLC header.
+ *
+ * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP
+ * value, if <= ETHERMTU.
+ */
+static struct block *
+gen_linktype(proto)
+ register int proto;
+{
+ struct block *b0, *b1, *b2;
+
+ /* are we checking MPLS-encapsulated packets? */
+ if (label_stack_depth > 0) {
+ switch (proto) {
+ case ETHERTYPE_IP:
+ case PPP_IP:
+ /* FIXME add other L3 proto IDs */
+ return gen_mpls_linktype(Q_IP);
+
+ case ETHERTYPE_IPV6:
+ case PPP_IPV6:
+ /* FIXME add other L3 proto IDs */
+ return gen_mpls_linktype(Q_IPV6);
+
+ default:
+ bpf_error("unsupported protocol over mpls");
+ /* NOTREACHED */
+ }
+ }
+
+ /*
+ * Are we testing PPPoE packets?
+ */
+ if (is_pppoes) {
+ /*
+ * The PPPoE session header is part of the
+ * MAC-layer payload, so all references
+ * should be relative to the beginning of
+ * that payload.
+ */
+
+ /*
+ * We use Ethernet protocol types inside libpcap;
+ * map them to the corresponding PPP protocol types.
+ */
+ proto = ethertype_to_ppptype(proto);
+ return gen_cmp(OR_MACPL, off_linktype, BPF_H, (bpf_int32)proto);
+ }
+
+ switch (linktype) {
+
+ case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
+ return gen_ether_linktype(proto);
+ /*NOTREACHED*/
+ break;
+
+ case DLT_C_HDLC:
+ switch (proto) {
+
+ case LLCSAP_ISONS:
+ proto = (proto << 8 | LLCSAP_ISONS);
+ /* fall through */
+
+ default:
+ return gen_cmp(OR_LINK, off_linktype, BPF_H,
+ (bpf_int32)proto);
+ /*NOTREACHED*/
+ break;
+ }
+ break;
+
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_PPI:
+ /*
+ * Check that we have a data frame.
+ */
+ b0 = gen_check_802_11_data_frame();
+
+ /*
+ * Now check for the specified link-layer type.
+ */
+ b1 = gen_llc_linktype(proto);
+ gen_and(b0, b1);
+ return b1;
+ /*NOTREACHED*/
+ break;
+
+ case DLT_FDDI:
+ /*
+ * XXX - check for asynchronous frames, as per RFC 1103.
+ */
+ return gen_llc_linktype(proto);
+ /*NOTREACHED*/
+ break;
+
+ case DLT_IEEE802:
+ /*
+ * XXX - check for LLC PDUs, as per IEEE 802.5.
+ */
+ return gen_llc_linktype(proto);
+ /*NOTREACHED*/
+ break;
+
+ case DLT_ATM_RFC1483:
+ case DLT_ATM_CLIP:
+ case DLT_IP_OVER_FC:
+ return gen_llc_linktype(proto);
+ /*NOTREACHED*/
+ break;
+
+ case DLT_SUNATM:
+ /*
+ * If "is_lane" is set, check for a LANE-encapsulated
+ * version of this protocol, otherwise check for an
+ * LLC-encapsulated version of this protocol.
+ *
+ * We assume LANE means Ethernet, not Token Ring.
+ */
+ if (is_lane) {
+ /*
+ * Check that the packet doesn't begin with an
+ * LE Control marker. (We've already generated
+ * a test for LANE.)
+ */
+ b0 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H,
+ 0xFF00);
+ gen_not(b0);
+
+ /*
+ * Now generate an Ethernet test.
+ */
+ b1 = gen_ether_linktype(proto);
+ gen_and(b0, b1);
+ return b1;
+ } else {
+ /*
+ * Check for LLC encapsulation and then check the
+ * protocol.
+ */
+ b0 = gen_atmfield_code(A_PROTOTYPE, PT_LLC, BPF_JEQ, 0);
+ b1 = gen_llc_linktype(proto);
+ gen_and(b0, b1);
+ return b1;
+ }
+ /*NOTREACHED*/
+ break;
+
+ case DLT_LINUX_SLL:
+ return gen_linux_sll_linktype(proto);
+ /*NOTREACHED*/
+ break;
+
+ case DLT_SLIP:
+ case DLT_SLIP_BSDOS:
+ case DLT_RAW:
+ /*
+ * These types don't provide any type field; packets
+ * are always IPv4 or IPv6.
+ *
+ * XXX - for IPv4, check for a version number of 4, and,
+ * for IPv6, check for a version number of 6?
+ */
+ switch (proto) {
+
+ case ETHERTYPE_IP:
+ /* Check for a version number of 4. */
+ return gen_mcmp(OR_LINK, 0, BPF_B, 0x40, 0xF0);
+
+ case ETHERTYPE_IPV6:
+ /* Check for a version number of 6. */
+ return gen_mcmp(OR_LINK, 0, BPF_B, 0x60, 0xF0);
+
+ default:
+ return gen_false(); /* always false */
+ }
+ /*NOTREACHED*/
+ break;
+
+ case DLT_IPV4:
+ /*
+ * Raw IPv4, so no type field.
+ */
+ if (proto == ETHERTYPE_IP)
+ return gen_true(); /* always true */
+
+ /* Checking for something other than IPv4; always false */
+ return gen_false();
+ /*NOTREACHED*/
+ break;
+
+ case DLT_IPV6:
+ /*
+ * Raw IPv6, so no type field.
+ */
+ if (proto == ETHERTYPE_IPV6)
+ return gen_true(); /* always true */
+
+ /* Checking for something other than IPv6; always false */
+ return gen_false();
+ /*NOTREACHED*/
+ break;
+
+ case DLT_PPP:
+ case DLT_PPP_PPPD:
+ case DLT_PPP_SERIAL:
+ case DLT_PPP_ETHER:
+ /*
+ * We use Ethernet protocol types inside libpcap;
+ * map them to the corresponding PPP protocol types.
+ */
+ proto = ethertype_to_ppptype(proto);
+ return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);
+ /*NOTREACHED*/
+ break;
+
+ case DLT_PPP_BSDOS:
+ /*
+ * We use Ethernet protocol types inside libpcap;
+ * map them to the corresponding PPP protocol types.
+ */
+ switch (proto) {
+
+ case ETHERTYPE_IP:
+ /*
+ * Also check for Van Jacobson-compressed IP.
+ * XXX - do this for other forms of PPP?
+ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_IP);
+ b1 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_VJC);
+ gen_or(b0, b1);
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_VJNC);
+ gen_or(b1, b0);
+ return b0;
+
+ default:
+ proto = ethertype_to_ppptype(proto);
+ return gen_cmp(OR_LINK, off_linktype, BPF_H,
+ (bpf_int32)proto);
+ }
+ /*NOTREACHED*/
+ break;
+
+ case DLT_NULL:
+ case DLT_LOOP:
+ case DLT_ENC:
+ /*
+ * For DLT_NULL, the link-layer header is a 32-bit
+ * word containing an AF_ value in *host* byte order,
+ * and for DLT_ENC, the link-layer header begins
+ * with a 32-bit work containing an AF_ value in
+ * host byte order.
+ *
+ * In addition, if we're reading a saved capture file,
+ * the host byte order in the capture may not be the
+ * same as the host byte order on this machine.
+ *
+ * For DLT_LOOP, the link-layer header is a 32-bit
+ * word containing an AF_ value in *network* byte order.
+ *
+ * XXX - AF_ values may, unfortunately, be platform-
+ * dependent; for example, FreeBSD's AF_INET6 is 24
+ * whilst NetBSD's and OpenBSD's is 26.
+ *
+ * This means that, when reading a capture file, just
+ * checking for our AF_INET6 value won't work if the
+ * capture file came from another OS.
+ */
+ switch (proto) {
+
+ case ETHERTYPE_IP:
+ proto = AF_INET;
+ break;
+
+#ifdef INET6
+ case ETHERTYPE_IPV6:
+ proto = AF_INET6;
+ break;
+#endif
+
+ default:
+ /*
+ * Not a type on which we support filtering.
+ * XXX - support those that have AF_ values
+ * #defined on this platform, at least?
+ */
+ return gen_false();
+ }
+
+ if (linktype == DLT_NULL || linktype == DLT_ENC) {
+ /*
+ * The AF_ value is in host byte order, but
+ * the BPF interpreter will convert it to
+ * network byte order.
+ *
+ * If this is a save file, and it's from a
+ * machine with the opposite byte order to
+ * ours, we byte-swap the AF_ value.
+ *
+ * Then we run it through "htonl()", and
+ * generate code to compare against the result.
+ */
+ if (bpf_pcap->sf.rfile != NULL &&
+ bpf_pcap->sf.swapped)
+ proto = SWAPLONG(proto);
+ proto = htonl(proto);
+ }
+ return (gen_cmp(OR_LINK, 0, BPF_W, (bpf_int32)proto));
+
+#ifdef HAVE_NET_PFVAR_H
+ case DLT_PFLOG:
+ /*
+ * af field is host byte order in contrast to the rest of
+ * the packet.
+ */
+ if (proto == ETHERTYPE_IP)
+ return (gen_cmp(OR_LINK, offsetof(struct pfloghdr, af),
+ BPF_B, (bpf_int32)AF_INET));
+ else if (proto == ETHERTYPE_IPV6)
+ return (gen_cmp(OR_LINK, offsetof(struct pfloghdr, af),
+ BPF_B, (bpf_int32)AF_INET6));
+ else
+ return gen_false();
+ /*NOTREACHED*/
+ break;
+#endif /* HAVE_NET_PFVAR_H */
+
+ case DLT_ARCNET:
+ case DLT_ARCNET_LINUX:
+ /*
+ * XXX should we check for first fragment if the protocol
+ * uses PHDS?
+ */
+ switch (proto) {
+
+ default:
+ return gen_false();
+
+ case ETHERTYPE_IPV6:
+ return (gen_cmp(OR_LINK, off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_INET6));
+
+ case ETHERTYPE_IP:
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_IP);
+ b1 = gen_cmp(OR_LINK, off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_IP_OLD);
+ gen_or(b0, b1);
+ return (b1);
+
+ case ETHERTYPE_ARP:
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_ARP);
+ b1 = gen_cmp(OR_LINK, off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_ARP_OLD);
+ gen_or(b0, b1);
+ return (b1);
+
+ case ETHERTYPE_REVARP:
+ return (gen_cmp(OR_LINK, off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_REVARP));
+
+ case ETHERTYPE_ATALK:
+ return (gen_cmp(OR_LINK, off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_ATALK));
+ }
+ /*NOTREACHED*/
+ break;
+
+ case DLT_LTALK:
+ switch (proto) {
+ case ETHERTYPE_ATALK:
+ return gen_true();
+ default:
+ return gen_false();
+ }
+ /*NOTREACHED*/
+ break;
+
+ case DLT_FRELAY:
+ /*
+ * XXX - assumes a 2-byte Frame Relay header with
+ * DLCI and flags. What if the address is longer?
+ */
+ switch (proto) {
+
+ case ETHERTYPE_IP:
+ /*
+ * Check for the special NLPID for IP.
+ */
+ return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | 0xcc);
+
+ case ETHERTYPE_IPV6:
+ /*
+ * Check for the special NLPID for IPv6.
+ */
+ return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | 0x8e);
+
+ case LLCSAP_ISONS:
+ /*
+ * Check for several OSI protocols.
+ *
+ * Frame Relay packets typically have an OSI
+ * NLPID at the beginning; we check for each
+ * of them.
+ *
+ * What we check for is the NLPID and a frame
+ * control field of UI, i.e. 0x03 followed
+ * by the NLPID.
+ */
+ b0 = gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | ISO8473_CLNP);
+ b1 = gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | ISO9542_ESIS);
+ b2 = gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | ISO10589_ISIS);
+ gen_or(b1, b2);
+ gen_or(b0, b2);
+ return b2;
+
+ default:
+ return gen_false();
+ }
+ /*NOTREACHED*/
+ break;
+
+ case DLT_MFR:
+ bpf_error("Multi-link Frame Relay link-layer type filtering not implemented");
+
+ case DLT_JUNIPER_MFR:
+ case DLT_JUNIPER_MLFR:
+ case DLT_JUNIPER_MLPPP:
+ case DLT_JUNIPER_ATM1:
+ case DLT_JUNIPER_ATM2:
+ case DLT_JUNIPER_PPPOE:
+ case DLT_JUNIPER_PPPOE_ATM:
+ case DLT_JUNIPER_GGSN:
+ case DLT_JUNIPER_ES:
+ case DLT_JUNIPER_MONITOR:
+ case DLT_JUNIPER_SERVICES:
+ case DLT_JUNIPER_ETHER:
+ case DLT_JUNIPER_PPP:
+ case DLT_JUNIPER_FRELAY:
+ case DLT_JUNIPER_CHDLC:
+ case DLT_JUNIPER_VP:
+ case DLT_JUNIPER_ST:
+ case DLT_JUNIPER_ISM:
+ case DLT_JUNIPER_VS:
+ case DLT_JUNIPER_SRX_E2E:
+ case DLT_JUNIPER_FIBRECHANNEL:
+ case DLT_JUNIPER_ATM_CEMIC:
+
+ /* just lets verify the magic number for now -
+ * on ATM we may have up to 6 different encapsulations on the wire
+ * and need a lot of heuristics to figure out that the payload
+ * might be;
+ *
+ * FIXME encapsulation specific BPF_ filters
+ */
+ return gen_mcmp(OR_LINK, 0, BPF_W, 0x4d474300, 0xffffff00); /* compare the magic number */
+
+ case DLT_IPNET:
+ return gen_ipnet_linktype(proto);
+
+ case DLT_LINUX_IRDA:
+ bpf_error("IrDA link-layer type filtering not implemented");
+
+ case DLT_DOCSIS:
+ bpf_error("DOCSIS link-layer type filtering not implemented");
+
+ case DLT_MTP2:
+ case DLT_MTP2_WITH_PHDR:
+ bpf_error("MTP2 link-layer type filtering not implemented");
+
+ case DLT_ERF:
+ bpf_error("ERF link-layer type filtering not implemented");
+
+ case DLT_PFSYNC:
+ bpf_error("PFSYNC link-layer type filtering not implemented");
+
+ case DLT_LINUX_LAPD:
+ bpf_error("LAPD link-layer type filtering not implemented");
+
+ case DLT_USB:
+ case DLT_USB_LINUX:
+ case DLT_USB_LINUX_MMAPPED:
+ bpf_error("USB link-layer type filtering not implemented");
+
+ case DLT_BLUETOOTH_HCI_H4:
+ case DLT_BLUETOOTH_HCI_H4_WITH_PHDR:
+ bpf_error("Bluetooth link-layer type filtering not implemented");
+
+ case DLT_CAN20B:
+ case DLT_CAN_SOCKETCAN:
+ bpf_error("CAN link-layer type filtering not implemented");
+
+ case DLT_IEEE802_15_4:
+ case DLT_IEEE802_15_4_LINUX:
+ case DLT_IEEE802_15_4_NONASK_PHY:
+ case DLT_IEEE802_15_4_NOFCS:
+ bpf_error("IEEE 802.15.4 link-layer type filtering not implemented");
+
+ case DLT_IEEE802_16_MAC_CPS_RADIO:
+ bpf_error("IEEE 802.16 link-layer type filtering not implemented");
+
+ case DLT_SITA:
+ bpf_error("SITA link-layer type filtering not implemented");
+
+ case DLT_RAIF1:
+ bpf_error("RAIF1 link-layer type filtering not implemented");
+
+ case DLT_IPMB:
+ bpf_error("IPMB link-layer type filtering not implemented");
+
+ case DLT_AX25_KISS:
+ bpf_error("AX.25 link-layer type filtering not implemented");
+ }
+
+ /*
+ * All the types that have no encapsulation should either be
+ * handled as DLT_SLIP, DLT_SLIP_BSDOS, and DLT_RAW are, if
+ * all packets are IP packets, or should be handled in some
+ * special case, if none of them are (if some are and some
+ * aren't, the lack of encapsulation is a problem, as we'd
+ * have to find some other way of determining the packet type).
+ *
+ * Therefore, if "off_linktype" is -1, there's an error.
+ */
+ if (off_linktype == (u_int)-1)
+ abort();
+
+ /*
+ * Any type not handled above should always have an Ethernet
+ * type at an offset of "off_linktype".
+ */
+ return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);
+}
+
+/*
+ * Check for an LLC SNAP packet with a given organization code and
+ * protocol type; we check the entire contents of the 802.2 LLC and
+ * snap headers, checking for DSAP and SSAP of SNAP and a control
+ * field of 0x03 in the LLC header, and for the specified organization
+ * code and protocol type in the SNAP header.
+ */
+static struct block *
+gen_snap(orgcode, ptype)
+ bpf_u_int32 orgcode;
+ bpf_u_int32 ptype;
+{
+ u_char snapblock[8];
+
+ snapblock[0] = LLCSAP_SNAP; /* DSAP = SNAP */
+ snapblock[1] = LLCSAP_SNAP; /* SSAP = SNAP */
+ snapblock[2] = 0x03; /* control = UI */
+ snapblock[3] = (orgcode >> 16); /* upper 8 bits of organization code */
+ snapblock[4] = (orgcode >> 8); /* middle 8 bits of organization code */
+ snapblock[5] = (orgcode >> 0); /* lower 8 bits of organization code */
+ snapblock[6] = (ptype >> 8); /* upper 8 bits of protocol type */
+ snapblock[7] = (ptype >> 0); /* lower 8 bits of protocol type */
+ return gen_bcmp(OR_MACPL, 0, 8, snapblock);
+}
+
+/*
+ * Generate code to match a particular packet type, for link-layer types
+ * using 802.2 LLC headers.
+ *
+ * This is *NOT* used for Ethernet; "gen_ether_linktype()" is used
+ * for that - it handles the D/I/X Ethernet vs. 802.3+802.2 issues.
+ *
+ * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP
+ * value, if <= ETHERMTU. We use that to determine whether to
+ * match the DSAP or both DSAP and LSAP or to check the OUI and
+ * protocol ID in a SNAP header.
+ */
+static struct block *
+gen_llc_linktype(proto)
+ int proto;
+{
+ /*
+ * XXX - handle token-ring variable-length header.
+ */
+ switch (proto) {
+
+ case LLCSAP_IP:
+ case LLCSAP_ISONS:
+ case LLCSAP_NETBEUI:
+ /*
+ * XXX - should we check both the DSAP and the
+ * SSAP, like this, or should we check just the
+ * DSAP, as we do for other types <= ETHERMTU
+ * (i.e., other SAP values)?
+ */
+ return gen_cmp(OR_MACPL, 0, BPF_H, (bpf_u_int32)
+ ((proto << 8) | proto));
+
+ case LLCSAP_IPX:
+ /*
+ * XXX - are there ever SNAP frames for IPX on
+ * non-Ethernet 802.x networks?
+ */
+ return gen_cmp(OR_MACPL, 0, BPF_B,
+ (bpf_int32)LLCSAP_IPX);
+
+ case ETHERTYPE_ATALK:
+ /*
+ * 802.2-encapsulated ETHERTYPE_ATALK packets are
+ * SNAP packets with an organization code of
+ * 0x080007 (Apple, for Appletalk) and a protocol
+ * type of ETHERTYPE_ATALK (Appletalk).
+ *
+ * XXX - check for an organization code of
+ * encapsulated Ethernet as well?
+ */
+ return gen_snap(0x080007, ETHERTYPE_ATALK);
+
+ default:
+ /*
+ * XXX - we don't have to check for IPX 802.3
+ * here, but should we check for the IPX Ethertype?
+ */
+ if (proto <= ETHERMTU) {
+ /*
+ * This is an LLC SAP value, so check
+ * the DSAP.
+ */
+ return gen_cmp(OR_MACPL, 0, BPF_B, (bpf_int32)proto);
+ } else {
+ /*
+ * This is an Ethernet type; we assume that it's
+ * unlikely that it'll appear in the right place
+ * at random, and therefore check only the
+ * location that would hold the Ethernet type
+ * in a SNAP frame with an organization code of
+ * 0x000000 (encapsulated Ethernet).
+ *
+ * XXX - if we were to check for the SNAP DSAP and
+ * LSAP, as per XXX, and were also to check for an
+ * organization code of 0x000000 (encapsulated
+ * Ethernet), we'd do
+ *
+ * return gen_snap(0x000000, proto);
+ *
+ * here; for now, we don't, as per the above.
+ * I don't know whether it's worth the extra CPU
+ * time to do the right check or not.
+ */
+ return gen_cmp(OR_MACPL, 6, BPF_H, (bpf_int32)proto);
+ }
+ }
+}
+
+static struct block *
+gen_hostop(addr, mask, dir, proto, src_off, dst_off)
+ bpf_u_int32 addr;
+ bpf_u_int32 mask;
+ int dir, proto;
+ u_int src_off, dst_off;
+{
+ struct block *b0, *b1;
+ u_int offset;
+
+ switch (dir) {
+
+ case Q_SRC:
+ offset = src_off;
+ break;
+
+ case Q_DST:
+ offset = dst_off;
+ break;
+
+ case Q_AND:
+ b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off);
+ b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_OR:
+ case Q_DEFAULT:
+ b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off);
+ b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off);
+ gen_or(b0, b1);
+ return b1;
+
+ default:
+ abort();
+ }
+ b0 = gen_linktype(proto);
+ b1 = gen_mcmp(OR_NET, offset, BPF_W, (bpf_int32)addr, mask);
+ gen_and(b0, b1);
+ return b1;
+}
+
+#ifdef INET6
+static struct block *
+gen_hostop6(addr, mask, dir, proto, src_off, dst_off)
+ struct in6_addr *addr;
+ struct in6_addr *mask;
+ int dir, proto;
+ u_int src_off, dst_off;
+{
+ struct block *b0, *b1;
+ u_int offset;
+ u_int32_t *a, *m;
+
+ switch (dir) {
+
+ case Q_SRC:
+ offset = src_off;
+ break;
+
+ case Q_DST:
+ offset = dst_off;
+ break;
+
+ case Q_AND:
+ b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off);
+ b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_OR:
+ case Q_DEFAULT:
+ b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off);
+ b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off);
+ gen_or(b0, b1);
+ return b1;
+
+ default:
+ abort();
+ }
+ /* this order is important */
+ a = (u_int32_t *)addr;
+ m = (u_int32_t *)mask;
+ b1 = gen_mcmp(OR_NET, offset + 12, BPF_W, ntohl(a[3]), ntohl(m[3]));
+ b0 = gen_mcmp(OR_NET, offset + 8, BPF_W, ntohl(a[2]), ntohl(m[2]));
+ gen_and(b0, b1);
+ b0 = gen_mcmp(OR_NET, offset + 4, BPF_W, ntohl(a[1]), ntohl(m[1]));
+ gen_and(b0, b1);
+ b0 = gen_mcmp(OR_NET, offset + 0, BPF_W, ntohl(a[0]), ntohl(m[0]));
+ gen_and(b0, b1);
+ b0 = gen_linktype(proto);
+ gen_and(b0, b1);
+ return b1;
+}
+#endif
+
+static struct block *
+gen_ehostop(eaddr, dir)
+ register const u_char *eaddr;
+ register int dir;
+{
+ register struct block *b0, *b1;
+
+ switch (dir) {
+ case Q_SRC:
+ return gen_bcmp(OR_LINK, off_mac + 6, 6, eaddr);
+
+ case Q_DST:
+ return gen_bcmp(OR_LINK, off_mac + 0, 6, eaddr);
+
+ case Q_AND:
+ b0 = gen_ehostop(eaddr, Q_SRC);
+ b1 = gen_ehostop(eaddr, Q_DST);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_DEFAULT:
+ case Q_OR:
+ b0 = gen_ehostop(eaddr, Q_SRC);
+ b1 = gen_ehostop(eaddr, Q_DST);
+ gen_or(b0, b1);
+ return b1;
+
+ case Q_ADDR1:
+ bpf_error("'addr1' is only supported on 802.11 with 802.11 headers");
+ break;
+
+ case Q_ADDR2:
+ bpf_error("'addr2' is only supported on 802.11 with 802.11 headers");
+ break;
+
+ case Q_ADDR3:
+ bpf_error("'addr3' is only supported on 802.11 with 802.11 headers");
+ break;
+
+ case Q_ADDR4:
+ bpf_error("'addr4' is only supported on 802.11 with 802.11 headers");
+ break;
+
+ case Q_RA:
+ bpf_error("'ra' is only supported on 802.11 with 802.11 headers");
+ break;
+
+ case Q_TA:
+ bpf_error("'ta' is only supported on 802.11 with 802.11 headers");
+ break;
+ }
+ abort();
+ /* NOTREACHED */
+}
+
+/*
+ * Like gen_ehostop, but for DLT_FDDI
+ */
+static struct block *
+gen_fhostop(eaddr, dir)
+ register const u_char *eaddr;
+ register int dir;
+{
+ struct block *b0, *b1;
+
+ switch (dir) {
+ case Q_SRC:
+#ifdef PCAP_FDDIPAD
+ return gen_bcmp(OR_LINK, 6 + 1 + pcap_fddipad, 6, eaddr);
+#else
+ return gen_bcmp(OR_LINK, 6 + 1, 6, eaddr);
+#endif
+
+ case Q_DST:
+#ifdef PCAP_FDDIPAD
+ return gen_bcmp(OR_LINK, 0 + 1 + pcap_fddipad, 6, eaddr);
+#else
+ return gen_bcmp(OR_LINK, 0 + 1, 6, eaddr);
+#endif
+
+ case Q_AND:
+ b0 = gen_fhostop(eaddr, Q_SRC);
+ b1 = gen_fhostop(eaddr, Q_DST);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_DEFAULT:
+ case Q_OR:
+ b0 = gen_fhostop(eaddr, Q_SRC);
+ b1 = gen_fhostop(eaddr, Q_DST);
+ gen_or(b0, b1);
+ return b1;
+
+ case Q_ADDR1:
+ bpf_error("'addr1' is only supported on 802.11");
+ break;
+
+ case Q_ADDR2:
+ bpf_error("'addr2' is only supported on 802.11");
+ break;
+
+ case Q_ADDR3:
+ bpf_error("'addr3' is only supported on 802.11");
+ break;
+
+ case Q_ADDR4:
+ bpf_error("'addr4' is only supported on 802.11");
+ break;
+
+ case Q_RA:
+ bpf_error("'ra' is only supported on 802.11");
+ break;
+
+ case Q_TA:
+ bpf_error("'ta' is only supported on 802.11");
+ break;
+ }
+ abort();
+ /* NOTREACHED */
+}
+
+/*
+ * Like gen_ehostop, but for DLT_IEEE802 (Token Ring)
+ */
+static struct block *
+gen_thostop(eaddr, dir)
+ register const u_char *eaddr;
+ register int dir;
+{
+ register struct block *b0, *b1;
+
+ switch (dir) {
+ case Q_SRC:
+ return gen_bcmp(OR_LINK, 8, 6, eaddr);
+
+ case Q_DST:
+ return gen_bcmp(OR_LINK, 2, 6, eaddr);
+
+ case Q_AND:
+ b0 = gen_thostop(eaddr, Q_SRC);
+ b1 = gen_thostop(eaddr, Q_DST);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_DEFAULT:
+ case Q_OR:
+ b0 = gen_thostop(eaddr, Q_SRC);
+ b1 = gen_thostop(eaddr, Q_DST);
+ gen_or(b0, b1);
+ return b1;
+
+ case Q_ADDR1:
+ bpf_error("'addr1' is only supported on 802.11");
+ break;
+
+ case Q_ADDR2:
+ bpf_error("'addr2' is only supported on 802.11");
+ break;
+
+ case Q_ADDR3:
+ bpf_error("'addr3' is only supported on 802.11");
+ break;
+
+ case Q_ADDR4:
+ bpf_error("'addr4' is only supported on 802.11");
+ break;
+
+ case Q_RA:
+ bpf_error("'ra' is only supported on 802.11");
+ break;
+
+ case Q_TA:
+ bpf_error("'ta' is only supported on 802.11");
+ break;
+ }
+ abort();
+ /* NOTREACHED */
+}
+
+/*
+ * Like gen_ehostop, but for DLT_IEEE802_11 (802.11 wireless LAN) and
+ * various 802.11 + radio headers.
+ */
+static struct block *
+gen_wlanhostop(eaddr, dir)
+ register const u_char *eaddr;
+ register int dir;
+{
+ register struct block *b0, *b1, *b2;
+ register struct slist *s;
+
+#ifdef ENABLE_WLAN_FILTERING_PATCH
+ /*
+ * TODO GV 20070613
+ * We need to disable the optimizer because the optimizer is buggy
+ * and wipes out some LD instructions generated by the below
+ * code to validate the Frame Control bits
+ */
+ no_optimize = 1;
+#endif /* ENABLE_WLAN_FILTERING_PATCH */
+
+ switch (dir) {
+ case Q_SRC:
+ /*
+ * Oh, yuk.
+ *
+ * For control frames, there is no SA.
+ *
+ * For management frames, SA is at an
+ * offset of 10 from the beginning of
+ * the packet.
+ *
+ * For data frames, SA is at an offset
+ * of 10 from the beginning of the packet
+ * if From DS is clear, at an offset of
+ * 16 from the beginning of the packet
+ * if From DS is set and To DS is clear,
+ * and an offset of 24 from the beginning
+ * of the packet if From DS is set and To DS
+ * is set.
+ */
+
+ /*
+ * Generate the tests to be done for data frames
+ * with From DS set.
+ *
+ * First, check for To DS set, i.e. check "link[1] & 0x01".
+ */
+ s = gen_load_a(OR_LINK, 1, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x01; /* To DS */
+ b1->stmts = s;
+
+ /*
+ * If To DS is set, the SA is at 24.
+ */
+ b0 = gen_bcmp(OR_LINK, 24, 6, eaddr);
+ gen_and(b1, b0);
+
+ /*
+ * Now, check for To DS not set, i.e. check
+ * "!(link[1] & 0x01)".
+ */
+ s = gen_load_a(OR_LINK, 1, BPF_B);
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x01; /* To DS */
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * If To DS is not set, the SA is at 16.
+ */
+ b1 = gen_bcmp(OR_LINK, 16, 6, eaddr);
+ gen_and(b2, b1);
+
+ /*
+ * Now OR together the last two checks. That gives
+ * the complete set of checks for data frames with
+ * From DS set.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * Now check for From DS being set, and AND that with
+ * the ORed-together checks.
+ */
+ s = gen_load_a(OR_LINK, 1, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x02; /* From DS */
+ b1->stmts = s;
+ gen_and(b1, b0);
+
+ /*
+ * Now check for data frames with From DS not set.
+ */
+ s = gen_load_a(OR_LINK, 1, BPF_B);
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x02; /* From DS */
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * If From DS isn't set, the SA is at 10.
+ */
+ b1 = gen_bcmp(OR_LINK, 10, 6, eaddr);
+ gen_and(b2, b1);
+
+ /*
+ * Now OR together the checks for data frames with
+ * From DS not set and for data frames with From DS
+ * set; that gives the checks done for data frames.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * Now check for a data frame.
+ * I.e, check "link[0] & 0x08".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x08;
+ b1->stmts = s;
+
+ /*
+ * AND that with the checks done for data frames.
+ */
+ gen_and(b1, b0);
+
+ /*
+ * If the high-order bit of the type value is 0, this
+ * is a management frame.
+ * I.e, check "!(link[0] & 0x08)".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x08;
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * For management frames, the SA is at 10.
+ */
+ b1 = gen_bcmp(OR_LINK, 10, 6, eaddr);
+ gen_and(b2, b1);
+
+ /*
+ * OR that with the checks done for data frames.
+ * That gives the checks done for management and
+ * data frames.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * If the low-order bit of the type value is 1,
+ * this is either a control frame or a frame
+ * with a reserved type, and thus not a
+ * frame with an SA.
+ *
+ * I.e., check "!(link[0] & 0x04)".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x04;
+ b1->stmts = s;
+ gen_not(b1);
+
+ /*
+ * AND that with the checks for data and management
+ * frames.
+ */
+ gen_and(b1, b0);
+ return b0;
+
+ case Q_DST:
+ /*
+ * Oh, yuk.
+ *
+ * For control frames, there is no DA.
+ *
+ * For management frames, DA is at an
+ * offset of 4 from the beginning of
+ * the packet.
+ *
+ * For data frames, DA is at an offset
+ * of 4 from the beginning of the packet
+ * if To DS is clear and at an offset of
+ * 16 from the beginning of the packet
+ * if To DS is set.
+ */
+
+ /*
+ * Generate the tests to be done for data frames.
+ *
+ * First, check for To DS set, i.e. "link[1] & 0x01".
+ */
+ s = gen_load_a(OR_LINK, 1, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x01; /* To DS */
+ b1->stmts = s;
+
+ /*
+ * If To DS is set, the DA is at 16.
+ */
+ b0 = gen_bcmp(OR_LINK, 16, 6, eaddr);
+ gen_and(b1, b0);
+
+ /*
+ * Now, check for To DS not set, i.e. check
+ * "!(link[1] & 0x01)".
+ */
+ s = gen_load_a(OR_LINK, 1, BPF_B);
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x01; /* To DS */
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * If To DS is not set, the DA is at 4.
+ */
+ b1 = gen_bcmp(OR_LINK, 4, 6, eaddr);
+ gen_and(b2, b1);
+
+ /*
+ * Now OR together the last two checks. That gives
+ * the complete set of checks for data frames.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * Now check for a data frame.
+ * I.e, check "link[0] & 0x08".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x08;
+ b1->stmts = s;
+
+ /*
+ * AND that with the checks done for data frames.
+ */
+ gen_and(b1, b0);
+
+ /*
+ * If the high-order bit of the type value is 0, this
+ * is a management frame.
+ * I.e, check "!(link[0] & 0x08)".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x08;
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * For management frames, the DA is at 4.
+ */
+ b1 = gen_bcmp(OR_LINK, 4, 6, eaddr);
+ gen_and(b2, b1);
+
+ /*
+ * OR that with the checks done for data frames.
+ * That gives the checks done for management and
+ * data frames.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * If the low-order bit of the type value is 1,
+ * this is either a control frame or a frame
+ * with a reserved type, and thus not a
+ * frame with an SA.
+ *
+ * I.e., check "!(link[0] & 0x04)".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x04;
+ b1->stmts = s;
+ gen_not(b1);
+
+ /*
+ * AND that with the checks for data and management
+ * frames.
+ */
+ gen_and(b1, b0);
+ return b0;
+
+ case Q_RA:
+ /*
+ * Not present in management frames; addr1 in other
+ * frames.
+ */
+
+ /*
+ * If the high-order bit of the type value is 0, this
+ * is a management frame.
+ * I.e, check "(link[0] & 0x08)".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x08;
+ b1->stmts = s;
+
+ /*
+ * Check addr1.
+ */
+ b0 = gen_bcmp(OR_LINK, 4, 6, eaddr);
+
+ /*
+ * AND that with the check of addr1.
+ */
+ gen_and(b1, b0);
+ return (b0);
+
+ case Q_TA:
+ /*
+ * Not present in management frames; addr2, if present,
+ * in other frames.
+ */
+
+ /*
+ * Not present in CTS or ACK control frames.
+ */
+ b0 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
+ IEEE80211_FC0_TYPE_MASK);
+ gen_not(b0);
+ b1 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_CTS,
+ IEEE80211_FC0_SUBTYPE_MASK);
+ gen_not(b1);
+ b2 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_ACK,
+ IEEE80211_FC0_SUBTYPE_MASK);
+ gen_not(b2);
+ gen_and(b1, b2);
+ gen_or(b0, b2);
+
+ /*
+ * If the high-order bit of the type value is 0, this
+ * is a management frame.
+ * I.e, check "(link[0] & 0x08)".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x08;
+ b1->stmts = s;
+
+ /*
+ * AND that with the check for frames other than
+ * CTS and ACK frames.
+ */
+ gen_and(b1, b2);
+
+ /*
+ * Check addr2.
+ */
+ b1 = gen_bcmp(OR_LINK, 10, 6, eaddr);
+ gen_and(b2, b1);
+ return b1;
+
+ /*
+ * XXX - add BSSID keyword?
+ */
+ case Q_ADDR1:
+ return (gen_bcmp(OR_LINK, 4, 6, eaddr));
+
+ case Q_ADDR2:
+ /*
+ * Not present in CTS or ACK control frames.
+ */
+ b0 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
+ IEEE80211_FC0_TYPE_MASK);
+ gen_not(b0);
+ b1 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_CTS,
+ IEEE80211_FC0_SUBTYPE_MASK);
+ gen_not(b1);
+ b2 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_ACK,
+ IEEE80211_FC0_SUBTYPE_MASK);
+ gen_not(b2);
+ gen_and(b1, b2);
+ gen_or(b0, b2);
+ b1 = gen_bcmp(OR_LINK, 10, 6, eaddr);
+ gen_and(b2, b1);
+ return b1;
+
+ case Q_ADDR3:
+ /*
+ * Not present in control frames.
+ */
+ b0 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
+ IEEE80211_FC0_TYPE_MASK);
+ gen_not(b0);
+ b1 = gen_bcmp(OR_LINK, 16, 6, eaddr);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_ADDR4:
+ /*
+ * Present only if the direction mask has both "From DS"
+ * and "To DS" set. Neither control frames nor management
+ * frames should have both of those set, so we don't
+ * check the frame type.
+ */
+ b0 = gen_mcmp(OR_LINK, 1, BPF_B,
+ IEEE80211_FC1_DIR_DSTODS, IEEE80211_FC1_DIR_MASK);
+ b1 = gen_bcmp(OR_LINK, 24, 6, eaddr);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_AND:
+ b0 = gen_wlanhostop(eaddr, Q_SRC);
+ b1 = gen_wlanhostop(eaddr, Q_DST);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_DEFAULT:
+ case Q_OR:
+ b0 = gen_wlanhostop(eaddr, Q_SRC);
+ b1 = gen_wlanhostop(eaddr, Q_DST);
+ gen_or(b0, b1);
+ return b1;
+ }
+ abort();
+ /* NOTREACHED */
+}
+
+/*
+ * Like gen_ehostop, but for RFC 2625 IP-over-Fibre-Channel.
+ * (We assume that the addresses are IEEE 48-bit MAC addresses,
+ * as the RFC states.)
+ */
+static struct block *
+gen_ipfchostop(eaddr, dir)
+ register const u_char *eaddr;
+ register int dir;
+{
+ register struct block *b0, *b1;
+
+ switch (dir) {
+ case Q_SRC:
+ return gen_bcmp(OR_LINK, 10, 6, eaddr);
+
+ case Q_DST:
+ return gen_bcmp(OR_LINK, 2, 6, eaddr);
+
+ case Q_AND:
+ b0 = gen_ipfchostop(eaddr, Q_SRC);
+ b1 = gen_ipfchostop(eaddr, Q_DST);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_DEFAULT:
+ case Q_OR:
+ b0 = gen_ipfchostop(eaddr, Q_SRC);
+ b1 = gen_ipfchostop(eaddr, Q_DST);
+ gen_or(b0, b1);
+ return b1;
+
+ case Q_ADDR1:
+ bpf_error("'addr1' is only supported on 802.11");
+ break;
+
+ case Q_ADDR2:
+ bpf_error("'addr2' is only supported on 802.11");
+ break;
+
+ case Q_ADDR3:
+ bpf_error("'addr3' is only supported on 802.11");
+ break;
+
+ case Q_ADDR4:
+ bpf_error("'addr4' is only supported on 802.11");
+ break;
+
+ case Q_RA:
+ bpf_error("'ra' is only supported on 802.11");
+ break;
+
+ case Q_TA:
+ bpf_error("'ta' is only supported on 802.11");
+ break;
+ }
+ abort();
+ /* NOTREACHED */
+}
+
+/*
+ * This is quite tricky because there may be pad bytes in front of the
+ * DECNET header, and then there are two possible data packet formats that
+ * carry both src and dst addresses, plus 5 packet types in a format that
+ * carries only the src node, plus 2 types that use a different format and
+ * also carry just the src node.
+ *
+ * Yuck.
+ *
+ * Instead of doing those all right, we just look for data packets with
+ * 0 or 1 bytes of padding. If you want to look at other packets, that
+ * will require a lot more hacking.
+ *
+ * To add support for filtering on DECNET "areas" (network numbers)
+ * one would want to add a "mask" argument to this routine. That would
+ * make the filter even more inefficient, although one could be clever
+ * and not generate masking instructions if the mask is 0xFFFF.
+ */
+static struct block *
+gen_dnhostop(addr, dir)
+ bpf_u_int32 addr;
+ int dir;
+{
+ struct block *b0, *b1, *b2, *tmp;
+ u_int offset_lh; /* offset if long header is received */
+ u_int offset_sh; /* offset if short header is received */
+
+ switch (dir) {
+
+ case Q_DST:
+ offset_sh = 1; /* follows flags */
+ offset_lh = 7; /* flgs,darea,dsubarea,HIORD */
+ break;
+
+ case Q_SRC:
+ offset_sh = 3; /* follows flags, dstnode */
+ offset_lh = 15; /* flgs,darea,dsubarea,did,sarea,ssub,HIORD */
+ break;
+
+ case Q_AND:
+ /* Inefficient because we do our Calvinball dance twice */
+ b0 = gen_dnhostop(addr, Q_SRC);
+ b1 = gen_dnhostop(addr, Q_DST);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_OR:
+ case Q_DEFAULT:
+ /* Inefficient because we do our Calvinball dance twice */
+ b0 = gen_dnhostop(addr, Q_SRC);
+ b1 = gen_dnhostop(addr, Q_DST);
+ gen_or(b0, b1);
+ return b1;
+
+ case Q_ISO:
+ bpf_error("ISO host filtering not implemented");
+
+ default:
+ abort();
+ }
+ b0 = gen_linktype(ETHERTYPE_DN);
+ /* Check for pad = 1, long header case */
+ tmp = gen_mcmp(OR_NET, 2, BPF_H,
+ (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF));
+ b1 = gen_cmp(OR_NET, 2 + 1 + offset_lh,
+ BPF_H, (bpf_int32)ntohs((u_short)addr));
+ gen_and(tmp, b1);
+ /* Check for pad = 0, long header case */
+ tmp = gen_mcmp(OR_NET, 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7);
+ b2 = gen_cmp(OR_NET, 2 + offset_lh, BPF_H, (bpf_int32)ntohs((u_short)addr));
+ gen_and(tmp, b2);
+ gen_or(b2, b1);
+ /* Check for pad = 1, short header case */
+ tmp = gen_mcmp(OR_NET, 2, BPF_H,
+ (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF));
+ b2 = gen_cmp(OR_NET, 2 + 1 + offset_sh, BPF_H, (bpf_int32)ntohs((u_short)addr));
+ gen_and(tmp, b2);
+ gen_or(b2, b1);
+ /* Check for pad = 0, short header case */
+ tmp = gen_mcmp(OR_NET, 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7);
+ b2 = gen_cmp(OR_NET, 2 + offset_sh, BPF_H, (bpf_int32)ntohs((u_short)addr));
+ gen_and(tmp, b2);
+ gen_or(b2, b1);
+
+ /* Combine with test for linktype */
+ gen_and(b0, b1);
+ return b1;
+}
+
+/*
+ * Generate a check for IPv4 or IPv6 for MPLS-encapsulated packets;
+ * test the bottom-of-stack bit, and then check the version number
+ * field in the IP header.
+ */
+static struct block *
+gen_mpls_linktype(proto)
+ int proto;
+{
+ struct block *b0, *b1;
+
+ switch (proto) {
+
+ case Q_IP:
+ /* match the bottom-of-stack bit */
+ b0 = gen_mcmp(OR_NET, -2, BPF_B, 0x01, 0x01);
+ /* match the IPv4 version number */
+ b1 = gen_mcmp(OR_NET, 0, BPF_B, 0x40, 0xf0);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_IPV6:
+ /* match the bottom-of-stack bit */
+ b0 = gen_mcmp(OR_NET, -2, BPF_B, 0x01, 0x01);
+ /* match the IPv4 version number */
+ b1 = gen_mcmp(OR_NET, 0, BPF_B, 0x60, 0xf0);
+ gen_and(b0, b1);
+ return b1;
+
+ default:
+ abort();
+ }
+}
+
+static struct block *
+gen_host(addr, mask, proto, dir, type)
+ bpf_u_int32 addr;
+ bpf_u_int32 mask;
+ int proto;
+ int dir;
+ int type;
+{
+ struct block *b0, *b1;
+ const char *typestr;
+
+ if (type == Q_NET)
+ typestr = "net";
+ else
+ typestr = "host";
+
+ switch (proto) {
+
+ case Q_DEFAULT:
+ b0 = gen_host(addr, mask, Q_IP, dir, type);
+ /*
+ * Only check for non-IPv4 addresses if we're not
+ * checking MPLS-encapsulated packets.
+ */
+ if (label_stack_depth == 0) {
+ b1 = gen_host(addr, mask, Q_ARP, dir, type);
+ gen_or(b0, b1);
+ b0 = gen_host(addr, mask, Q_RARP, dir, type);
+ gen_or(b1, b0);
+ }
+ return b0;
+
+ case Q_IP:
+ return gen_hostop(addr, mask, dir, ETHERTYPE_IP, 12, 16);
+
+ case Q_RARP:
+ return gen_hostop(addr, mask, dir, ETHERTYPE_REVARP, 14, 24);
+
+ case Q_ARP:
+ return gen_hostop(addr, mask, dir, ETHERTYPE_ARP, 14, 24);
+
+ case Q_TCP:
+ bpf_error("'tcp' modifier applied to %s", typestr);
+
+ case Q_SCTP:
+ bpf_error("'sctp' modifier applied to %s", typestr);
+
+ case Q_UDP:
+ bpf_error("'udp' modifier applied to %s", typestr);
+
+ case Q_ICMP:
+ bpf_error("'icmp' modifier applied to %s", typestr);
+
+ case Q_IGMP:
+ bpf_error("'igmp' modifier applied to %s", typestr);
+
+ case Q_IGRP:
+ bpf_error("'igrp' modifier applied to %s", typestr);
+
+ case Q_PIM:
+ bpf_error("'pim' modifier applied to %s", typestr);
+
+ case Q_VRRP:
+ bpf_error("'vrrp' modifier applied to %s", typestr);
+
+ case Q_CARP:
+ bpf_error("'carp' modifier applied to %s", typestr);
+
+ case Q_ATALK:
+ bpf_error("ATALK host filtering not implemented");
+
+ case Q_AARP:
+ bpf_error("AARP host filtering not implemented");
+
+ case Q_DECNET:
+ return gen_dnhostop(addr, dir);
+
+ case Q_SCA:
+ bpf_error("SCA host filtering not implemented");
+
+ case Q_LAT:
+ bpf_error("LAT host filtering not implemented");
+
+ case Q_MOPDL:
+ bpf_error("MOPDL host filtering not implemented");
+
+ case Q_MOPRC:
+ bpf_error("MOPRC host filtering not implemented");
+
+ case Q_IPV6:
+ bpf_error("'ip6' modifier applied to ip host");
+
+ case Q_ICMPV6:
+ bpf_error("'icmp6' modifier applied to %s", typestr);
+
+ case Q_AH:
+ bpf_error("'ah' modifier applied to %s", typestr);
+
+ case Q_ESP:
+ bpf_error("'esp' modifier applied to %s", typestr);
+
+ case Q_ISO:
+ bpf_error("ISO host filtering not implemented");
+
+ case Q_ESIS:
+ bpf_error("'esis' modifier applied to %s", typestr);
+
+ case Q_ISIS:
+ bpf_error("'isis' modifier applied to %s", typestr);
+
+ case Q_CLNP:
+ bpf_error("'clnp' modifier applied to %s", typestr);
+
+ case Q_STP:
+ bpf_error("'stp' modifier applied to %s", typestr);
+
+ case Q_IPX:
+ bpf_error("IPX host filtering not implemented");
+
+ case Q_NETBEUI:
+ bpf_error("'netbeui' modifier applied to %s", typestr);
+
+ case Q_RADIO:
+ bpf_error("'radio' modifier applied to %s", typestr);
+
+ default:
+ abort();
+ }
+ /* NOTREACHED */
+}
+
+#ifdef INET6
+static struct block *
+gen_host6(addr, mask, proto, dir, type)
+ struct in6_addr *addr;
+ struct in6_addr *mask;
+ int proto;
+ int dir;
+ int type;
+{
+ const char *typestr;
+
+ if (type == Q_NET)
+ typestr = "net";
+ else
+ typestr = "host";
+
+ switch (proto) {
+
+ case Q_DEFAULT:
+ return gen_host6(addr, mask, Q_IPV6, dir, type);
+
+ case Q_IP:
+ bpf_error("'ip' modifier applied to ip6 %s", typestr);
+
+ case Q_RARP:
+ bpf_error("'rarp' modifier applied to ip6 %s", typestr);
+
+ case Q_ARP:
+ bpf_error("'arp' modifier applied to ip6 %s", typestr);
+
+ case Q_SCTP:
+ bpf_error("'sctp' modifier applied to %s", typestr);
+
+ case Q_TCP:
+ bpf_error("'tcp' modifier applied to %s", typestr);
+
+ case Q_UDP:
+ bpf_error("'udp' modifier applied to %s", typestr);
+
+ case Q_ICMP:
+ bpf_error("'icmp' modifier applied to %s", typestr);
+
+ case Q_IGMP:
+ bpf_error("'igmp' modifier applied to %s", typestr);
+
+ case Q_IGRP:
+ bpf_error("'igrp' modifier applied to %s", typestr);
+
+ case Q_PIM:
+ bpf_error("'pim' modifier applied to %s", typestr);
+
+ case Q_VRRP:
+ bpf_error("'vrrp' modifier applied to %s", typestr);
+
+ case Q_CARP:
+ bpf_error("'carp' modifier applied to %s", typestr);
+
+ case Q_ATALK:
+ bpf_error("ATALK host filtering not implemented");
+
+ case Q_AARP:
+ bpf_error("AARP host filtering not implemented");
+
+ case Q_DECNET:
+ bpf_error("'decnet' modifier applied to ip6 %s", typestr);
+
+ case Q_SCA:
+ bpf_error("SCA host filtering not implemented");
+
+ case Q_LAT:
+ bpf_error("LAT host filtering not implemented");
+
+ case Q_MOPDL:
+ bpf_error("MOPDL host filtering not implemented");
+
+ case Q_MOPRC:
+ bpf_error("MOPRC host filtering not implemented");
+
+ case Q_IPV6:
+ return gen_hostop6(addr, mask, dir, ETHERTYPE_IPV6, 8, 24);
+
+ case Q_ICMPV6:
+ bpf_error("'icmp6' modifier applied to %s", typestr);
+
+ case Q_AH:
+ bpf_error("'ah' modifier applied to %s", typestr);
+
+ case Q_ESP:
+ bpf_error("'esp' modifier applied to %s", typestr);
+
+ case Q_ISO:
+ bpf_error("ISO host filtering not implemented");
+
+ case Q_ESIS:
+ bpf_error("'esis' modifier applied to %s", typestr);
+
+ case Q_ISIS:
+ bpf_error("'isis' modifier applied to %s", typestr);
+
+ case Q_CLNP:
+ bpf_error("'clnp' modifier applied to %s", typestr);
+
+ case Q_STP:
+ bpf_error("'stp' modifier applied to %s", typestr);
+
+ case Q_IPX:
+ bpf_error("IPX host filtering not implemented");
+
+ case Q_NETBEUI:
+ bpf_error("'netbeui' modifier applied to %s", typestr);
+
+ case Q_RADIO:
+ bpf_error("'radio' modifier applied to %s", typestr);
+
+ default:
+ abort();
+ }
+ /* NOTREACHED */
+}
+#endif
+
+#ifndef INET6
+static struct block *
+gen_gateway(eaddr, alist, proto, dir)
+ const u_char *eaddr;
+ bpf_u_int32 **alist;
+ int proto;
+ int dir;
+{
+ struct block *b0, *b1, *tmp;
+
+ if (dir != 0)
+ bpf_error("direction applied to 'gateway'");
+
+ switch (proto) {
+ case Q_DEFAULT:
+ case Q_IP:
+ case Q_ARP:
+ case Q_RARP:
+ switch (linktype) {
+ case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
+ b0 = gen_ehostop(eaddr, Q_OR);
+ break;
+ case DLT_FDDI:
+ b0 = gen_fhostop(eaddr, Q_OR);
+ break;
+ case DLT_IEEE802:
+ b0 = gen_thostop(eaddr, Q_OR);
+ break;
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_PPI:
+ b0 = gen_wlanhostop(eaddr, Q_OR);
+ break;
+ case DLT_SUNATM:
+ if (!is_lane)
+ bpf_error(
+ "'gateway' supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
+ /*
+ * Check that the packet doesn't begin with an
+ * LE Control marker. (We've already generated
+ * a test for LANE.)
+ */
+ b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS,
+ BPF_H, 0xFF00);
+ gen_not(b1);
+
+ /*
+ * Now check the MAC address.
+ */
+ b0 = gen_ehostop(eaddr, Q_OR);
+ gen_and(b1, b0);
+ break;
+ case DLT_IP_OVER_FC:
+ b0 = gen_ipfchostop(eaddr, Q_OR);
+ break;
+ default:
+ bpf_error(
+ "'gateway' supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
+ }
+ b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR, Q_HOST);
+ while (*alist) {
+ tmp = gen_host(**alist++, 0xffffffff, proto, Q_OR,
+ Q_HOST);
+ gen_or(b1, tmp);
+ b1 = tmp;
+ }
+ gen_not(b1);
+ gen_and(b0, b1);
+ return b1;
+ }
+ bpf_error("illegal modifier of 'gateway'");
+ /* NOTREACHED */
+}
+#endif
+
+struct block *
+gen_proto_abbrev(proto)
+ int proto;
+{
+ struct block *b0;
+ struct block *b1;
+
+ switch (proto) {
+
+ case Q_SCTP:
+ b1 = gen_proto(IPPROTO_SCTP, Q_IP, Q_DEFAULT);
+ b0 = gen_proto(IPPROTO_SCTP, Q_IPV6, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_TCP:
+ b1 = gen_proto(IPPROTO_TCP, Q_IP, Q_DEFAULT);
+ b0 = gen_proto(IPPROTO_TCP, Q_IPV6, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_UDP:
+ b1 = gen_proto(IPPROTO_UDP, Q_IP, Q_DEFAULT);
+ b0 = gen_proto(IPPROTO_UDP, Q_IPV6, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ICMP:
+ b1 = gen_proto(IPPROTO_ICMP, Q_IP, Q_DEFAULT);
+ break;
+
+#ifndef IPPROTO_IGMP
+#define IPPROTO_IGMP 2
+#endif
+
+ case Q_IGMP:
+ b1 = gen_proto(IPPROTO_IGMP, Q_IP, Q_DEFAULT);
+ break;
+
+#ifndef IPPROTO_IGRP
+#define IPPROTO_IGRP 9
+#endif
+ case Q_IGRP:
+ b1 = gen_proto(IPPROTO_IGRP, Q_IP, Q_DEFAULT);
+ break;
+
+#ifndef IPPROTO_PIM
+#define IPPROTO_PIM 103
+#endif
+
+ case Q_PIM:
+ b1 = gen_proto(IPPROTO_PIM, Q_IP, Q_DEFAULT);
+ b0 = gen_proto(IPPROTO_PIM, Q_IPV6, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+#ifndef IPPROTO_VRRP
+#define IPPROTO_VRRP 112
+#endif
+
+ case Q_VRRP:
+ b1 = gen_proto(IPPROTO_VRRP, Q_IP, Q_DEFAULT);
+ break;
+
+#ifndef IPPROTO_CARP
+#define IPPROTO_CARP 112
+#endif
+
+ case Q_CARP:
+ b1 = gen_proto(IPPROTO_CARP, Q_IP, Q_DEFAULT);
+ break;
+
+ case Q_IP:
+ b1 = gen_linktype(ETHERTYPE_IP);
+ break;
+
+ case Q_ARP:
+ b1 = gen_linktype(ETHERTYPE_ARP);
+ break;
+
+ case Q_RARP:
+ b1 = gen_linktype(ETHERTYPE_REVARP);
+ break;
+
+ case Q_LINK:
+ bpf_error("link layer applied in wrong context");
+
+ case Q_ATALK:
+ b1 = gen_linktype(ETHERTYPE_ATALK);
+ break;
+
+ case Q_AARP:
+ b1 = gen_linktype(ETHERTYPE_AARP);
+ break;
+
+ case Q_DECNET:
+ b1 = gen_linktype(ETHERTYPE_DN);
+ break;
+
+ case Q_SCA:
+ b1 = gen_linktype(ETHERTYPE_SCA);
+ break;
+
+ case Q_LAT:
+ b1 = gen_linktype(ETHERTYPE_LAT);
+ break;
+
+ case Q_MOPDL:
+ b1 = gen_linktype(ETHERTYPE_MOPDL);
+ break;
+
+ case Q_MOPRC:
+ b1 = gen_linktype(ETHERTYPE_MOPRC);
+ break;
+
+ case Q_IPV6:
+ b1 = gen_linktype(ETHERTYPE_IPV6);
+ break;
+
+#ifndef IPPROTO_ICMPV6
+#define IPPROTO_ICMPV6 58
+#endif
+ case Q_ICMPV6:
+ b1 = gen_proto(IPPROTO_ICMPV6, Q_IPV6, Q_DEFAULT);
+ break;
+
+#ifndef IPPROTO_AH
+#define IPPROTO_AH 51
+#endif
+ case Q_AH:
+ b1 = gen_proto(IPPROTO_AH, Q_IP, Q_DEFAULT);
+ b0 = gen_proto(IPPROTO_AH, Q_IPV6, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+#ifndef IPPROTO_ESP
+#define IPPROTO_ESP 50
+#endif
+ case Q_ESP:
+ b1 = gen_proto(IPPROTO_ESP, Q_IP, Q_DEFAULT);
+ b0 = gen_proto(IPPROTO_ESP, Q_IPV6, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISO:
+ b1 = gen_linktype(LLCSAP_ISONS);
+ break;
+
+ case Q_ESIS:
+ b1 = gen_proto(ISO9542_ESIS, Q_ISO, Q_DEFAULT);
+ break;
+
+ case Q_ISIS:
+ b1 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT);
+ break;
+
+ case Q_ISIS_L1: /* all IS-IS Level1 PDU-Types */
+ b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISIS_L2: /* all IS-IS Level2 PDU-Types */
+ b0 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISIS_IIH: /* all IS-IS Hello PDU-Types */
+ b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISIS_LSP:
+ b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISIS_SNP:
+ b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISIS_CSNP:
+ b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISIS_PSNP:
+ b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_CLNP:
+ b1 = gen_proto(ISO8473_CLNP, Q_ISO, Q_DEFAULT);
+ break;
+
+ case Q_STP:
+ b1 = gen_linktype(LLCSAP_8021D);
+ break;
+
+ case Q_IPX:
+ b1 = gen_linktype(LLCSAP_IPX);
+ break;
+
+ case Q_NETBEUI:
+ b1 = gen_linktype(LLCSAP_NETBEUI);
+ break;
+
+ case Q_RADIO:
+ bpf_error("'radio' is not a valid protocol type");
+
+ default:
+ abort();
+ }
+ return b1;
+}
+
+static struct block *
+gen_ipfrag()
+{
+ struct slist *s;
+ struct block *b;
+
+ /* not IPv4 frag other than the first frag */
+ s = gen_load_a(OR_NET, 6, BPF_H);
+ b = new_block(JMP(BPF_JSET));
+ b->s.k = 0x1fff;
+ b->stmts = s;
+ gen_not(b);
+
+ return b;
+}
+
+/*
+ * Generate a comparison to a port value in the transport-layer header
+ * at the specified offset from the beginning of that header.
+ *
+ * XXX - this handles a variable-length prefix preceding the link-layer
+ * header, such as the radiotap or AVS radio prefix, but doesn't handle
+ * variable-length link-layer headers (such as Token Ring or 802.11
+ * headers).
+ */
+static struct block *
+gen_portatom(off, v)
+ int off;
+ bpf_int32 v;
+{
+ return gen_cmp(OR_TRAN_IPV4, off, BPF_H, v);
+}
+
+static struct block *
+gen_portatom6(off, v)
+ int off;
+ bpf_int32 v;
+{
+ return gen_cmp(OR_TRAN_IPV6, off, BPF_H, v);
+}
+
+struct block *
+gen_portop(port, proto, dir)
+ int port, proto, dir;
+{
+ struct block *b0, *b1, *tmp;
+
+ /* ip proto 'proto' and not a fragment other than the first fragment */
+ tmp = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)proto);
+ b0 = gen_ipfrag();
+ gen_and(tmp, b0);
+
+ switch (dir) {
+ case Q_SRC:
+ b1 = gen_portatom(0, (bpf_int32)port);
+ break;
+
+ case Q_DST:
+ b1 = gen_portatom(2, (bpf_int32)port);
+ break;
+
+ case Q_OR:
+ case Q_DEFAULT:
+ tmp = gen_portatom(0, (bpf_int32)port);
+ b1 = gen_portatom(2, (bpf_int32)port);
+ gen_or(tmp, b1);
+ break;
+
+ case Q_AND:
+ tmp = gen_portatom(0, (bpf_int32)port);
+ b1 = gen_portatom(2, (bpf_int32)port);
+ gen_and(tmp, b1);
+ break;
+
+ default:
+ abort();
+ }
+ gen_and(b0, b1);
+
+ return b1;
+}
+
+static struct block *
+gen_port(port, ip_proto, dir)
+ int port;
+ int ip_proto;
+ int dir;
+{
+ struct block *b0, *b1, *tmp;
+
+ /*
+ * ether proto ip
+ *
+ * For FDDI, RFC 1188 says that SNAP encapsulation is used,
+ * not LLC encapsulation with LLCSAP_IP.
+ *
+ * For IEEE 802 networks - which includes 802.5 token ring
+ * (which is what DLT_IEEE802 means) and 802.11 - RFC 1042
+ * says that SNAP encapsulation is used, not LLC encapsulation
+ * with LLCSAP_IP.
+ *
+ * For LLC-encapsulated ATM/"Classical IP", RFC 1483 and
+ * RFC 2225 say that SNAP encapsulation is used, not LLC
+ * encapsulation with LLCSAP_IP.
+ *
+ * So we always check for ETHERTYPE_IP.
+ */
+ b0 = gen_linktype(ETHERTYPE_IP);
+
+ switch (ip_proto) {
+ case IPPROTO_UDP:
+ case IPPROTO_TCP:
+ case IPPROTO_SCTP:
+ b1 = gen_portop(port, ip_proto, dir);
+ break;
+
+ case PROTO_UNDEF:
+ tmp = gen_portop(port, IPPROTO_TCP, dir);
+ b1 = gen_portop(port, IPPROTO_UDP, dir);
+ gen_or(tmp, b1);
+ tmp = gen_portop(port, IPPROTO_SCTP, dir);
+ gen_or(tmp, b1);
+ break;
+
+ default:
+ abort();
+ }
+ gen_and(b0, b1);
+ return b1;
+}
+
+struct block *
+gen_portop6(port, proto, dir)
+ int port, proto, dir;
+{
+ struct block *b0, *b1, *tmp;
+
+ /* ip6 proto 'proto' */
+ /* XXX - catch the first fragment of a fragmented packet? */
+ b0 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)proto);
+
+ switch (dir) {
+ case Q_SRC:
+ b1 = gen_portatom6(0, (bpf_int32)port);
+ break;
+
+ case Q_DST:
+ b1 = gen_portatom6(2, (bpf_int32)port);
+ break;
+
+ case Q_OR:
+ case Q_DEFAULT:
+ tmp = gen_portatom6(0, (bpf_int32)port);
+ b1 = gen_portatom6(2, (bpf_int32)port);
+ gen_or(tmp, b1);
+ break;
+
+ case Q_AND:
+ tmp = gen_portatom6(0, (bpf_int32)port);
+ b1 = gen_portatom6(2, (bpf_int32)port);
+ gen_and(tmp, b1);
+ break;
+
+ default:
+ abort();
+ }
+ gen_and(b0, b1);
+
+ return b1;
+}
+
+static struct block *
+gen_port6(port, ip_proto, dir)
+ int port;
+ int ip_proto;
+ int dir;
+{
+ struct block *b0, *b1, *tmp;
+
+ /* link proto ip6 */
+ b0 = gen_linktype(ETHERTYPE_IPV6);
+
+ switch (ip_proto) {
+ case IPPROTO_UDP:
+ case IPPROTO_TCP:
+ case IPPROTO_SCTP:
+ b1 = gen_portop6(port, ip_proto, dir);
+ break;
+
+ case PROTO_UNDEF:
+ tmp = gen_portop6(port, IPPROTO_TCP, dir);
+ b1 = gen_portop6(port, IPPROTO_UDP, dir);
+ gen_or(tmp, b1);
+ tmp = gen_portop6(port, IPPROTO_SCTP, dir);
+ gen_or(tmp, b1);
+ break;
+
+ default:
+ abort();
+ }
+ gen_and(b0, b1);
+ return b1;
+}
+
+/* gen_portrange code */
+static struct block *
+gen_portrangeatom(off, v1, v2)
+ int off;
+ bpf_int32 v1, v2;
+{
+ struct block *b1, *b2;
+
+ if (v1 > v2) {
+ /*
+ * Reverse the order of the ports, so v1 is the lower one.
+ */
+ bpf_int32 vtemp;
+
+ vtemp = v1;
+ v1 = v2;
+ v2 = vtemp;
+ }
+
+ b1 = gen_cmp_ge(OR_TRAN_IPV4, off, BPF_H, v1);
+ b2 = gen_cmp_le(OR_TRAN_IPV4, off, BPF_H, v2);
+
+ gen_and(b1, b2);
+
+ return b2;
+}
+
+struct block *
+gen_portrangeop(port1, port2, proto, dir)
+ int port1, port2;
+ int proto;
+ int dir;
+{
+ struct block *b0, *b1, *tmp;
+
+ /* ip proto 'proto' and not a fragment other than the first fragment */
+ tmp = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)proto);
+ b0 = gen_ipfrag();
+ gen_and(tmp, b0);
+
+ switch (dir) {
+ case Q_SRC:
+ b1 = gen_portrangeatom(0, (bpf_int32)port1, (bpf_int32)port2);
+ break;
+
+ case Q_DST:
+ b1 = gen_portrangeatom(2, (bpf_int32)port1, (bpf_int32)port2);
+ break;
+
+ case Q_OR:
+ case Q_DEFAULT:
+ tmp = gen_portrangeatom(0, (bpf_int32)port1, (bpf_int32)port2);
+ b1 = gen_portrangeatom(2, (bpf_int32)port1, (bpf_int32)port2);
+ gen_or(tmp, b1);
+ break;
+
+ case Q_AND:
+ tmp = gen_portrangeatom(0, (bpf_int32)port1, (bpf_int32)port2);
+ b1 = gen_portrangeatom(2, (bpf_int32)port1, (bpf_int32)port2);
+ gen_and(tmp, b1);
+ break;
+
+ default:
+ abort();
+ }
+ gen_and(b0, b1);
+
+ return b1;
+}
+
+static struct block *
+gen_portrange(port1, port2, ip_proto, dir)
+ int port1, port2;
+ int ip_proto;
+ int dir;
+{
+ struct block *b0, *b1, *tmp;
+
+ /* link proto ip */
+ b0 = gen_linktype(ETHERTYPE_IP);
+
+ switch (ip_proto) {
+ case IPPROTO_UDP:
+ case IPPROTO_TCP:
+ case IPPROTO_SCTP:
+ b1 = gen_portrangeop(port1, port2, ip_proto, dir);
+ break;
+
+ case PROTO_UNDEF:
+ tmp = gen_portrangeop(port1, port2, IPPROTO_TCP, dir);
+ b1 = gen_portrangeop(port1, port2, IPPROTO_UDP, dir);
+ gen_or(tmp, b1);
+ tmp = gen_portrangeop(port1, port2, IPPROTO_SCTP, dir);
+ gen_or(tmp, b1);
+ break;
+
+ default:
+ abort();
+ }
+ gen_and(b0, b1);
+ return b1;
+}
+
+static struct block *
+gen_portrangeatom6(off, v1, v2)
+ int off;
+ bpf_int32 v1, v2;
+{
+ struct block *b1, *b2;
+
+ if (v1 > v2) {
+ /*
+ * Reverse the order of the ports, so v1 is the lower one.
+ */
+ bpf_int32 vtemp;
+
+ vtemp = v1;
+ v1 = v2;
+ v2 = vtemp;
+ }
+
+ b1 = gen_cmp_ge(OR_TRAN_IPV6, off, BPF_H, v1);
+ b2 = gen_cmp_le(OR_TRAN_IPV6, off, BPF_H, v2);
+
+ gen_and(b1, b2);
+
+ return b2;
+}
+
+struct block *
+gen_portrangeop6(port1, port2, proto, dir)
+ int port1, port2;
+ int proto;
+ int dir;
+{
+ struct block *b0, *b1, *tmp;
+
+ /* ip6 proto 'proto' */
+ /* XXX - catch the first fragment of a fragmented packet? */
+ b0 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)proto);
+
+ switch (dir) {
+ case Q_SRC:
+ b1 = gen_portrangeatom6(0, (bpf_int32)port1, (bpf_int32)port2);
+ break;
+
+ case Q_DST:
+ b1 = gen_portrangeatom6(2, (bpf_int32)port1, (bpf_int32)port2);
+ break;
+
+ case Q_OR:
+ case Q_DEFAULT:
+ tmp = gen_portrangeatom6(0, (bpf_int32)port1, (bpf_int32)port2);
+ b1 = gen_portrangeatom6(2, (bpf_int32)port1, (bpf_int32)port2);
+ gen_or(tmp, b1);
+ break;
+
+ case Q_AND:
+ tmp = gen_portrangeatom6(0, (bpf_int32)port1, (bpf_int32)port2);
+ b1 = gen_portrangeatom6(2, (bpf_int32)port1, (bpf_int32)port2);
+ gen_and(tmp, b1);
+ break;
+
+ default:
+ abort();
+ }
+ gen_and(b0, b1);
+
+ return b1;
+}
+
+static struct block *
+gen_portrange6(port1, port2, ip_proto, dir)
+ int port1, port2;
+ int ip_proto;
+ int dir;
+{
+ struct block *b0, *b1, *tmp;
+
+ /* link proto ip6 */
+ b0 = gen_linktype(ETHERTYPE_IPV6);
+
+ switch (ip_proto) {
+ case IPPROTO_UDP:
+ case IPPROTO_TCP:
+ case IPPROTO_SCTP:
+ b1 = gen_portrangeop6(port1, port2, ip_proto, dir);
+ break;
+
+ case PROTO_UNDEF:
+ tmp = gen_portrangeop6(port1, port2, IPPROTO_TCP, dir);
+ b1 = gen_portrangeop6(port1, port2, IPPROTO_UDP, dir);
+ gen_or(tmp, b1);
+ tmp = gen_portrangeop6(port1, port2, IPPROTO_SCTP, dir);
+ gen_or(tmp, b1);
+ break;
+
+ default:
+ abort();
+ }
+ gen_and(b0, b1);
+ return b1;
+}
+
+static int
+lookup_proto(name, proto)
+ register const char *name;
+ register int proto;
+{
+ register int v;
+
+ switch (proto) {
+
+ case Q_DEFAULT:
+ case Q_IP:
+ case Q_IPV6:
+ v = pcap_nametoproto(name);
+ if (v == PROTO_UNDEF)
+ bpf_error("unknown ip proto '%s'", name);
+ break;
+
+ case Q_LINK:
+ /* XXX should look up h/w protocol type based on linktype */
+ v = pcap_nametoeproto(name);
+ if (v == PROTO_UNDEF) {
+ v = pcap_nametollc(name);
+ if (v == PROTO_UNDEF)
+ bpf_error("unknown ether proto '%s'", name);
+ }
+ break;
+
+ case Q_ISO:
+ if (strcmp(name, "esis") == 0)
+ v = ISO9542_ESIS;
+ else if (strcmp(name, "isis") == 0)
+ v = ISO10589_ISIS;
+ else if (strcmp(name, "clnp") == 0)
+ v = ISO8473_CLNP;
+ else
+ bpf_error("unknown osi proto '%s'", name);
+ break;
+
+ default:
+ v = PROTO_UNDEF;
+ break;
+ }
+ return v;
+}
+
+#if 0
+struct stmt *
+gen_joinsp(s, n)
+ struct stmt **s;
+ int n;
+{
+ return NULL;
+}
+#endif
+
+static struct block *
+gen_protochain(v, proto, dir)
+ int v;
+ int proto;
+ int dir;
+{
+#ifdef NO_PROTOCHAIN
+ return gen_proto(v, proto, dir);
+#else
+ struct block *b0, *b;
+ struct slist *s[100];
+ int fix2, fix3, fix4, fix5;
+ int ahcheck, again, end;
+ int i, max;
+ int reg2 = alloc_reg();
+
+ memset(s, 0, sizeof(s));
+ fix2 = fix3 = fix4 = fix5 = 0;
+
+ switch (proto) {
+ case Q_IP:
+ case Q_IPV6:
+ break;
+ case Q_DEFAULT:
+ b0 = gen_protochain(v, Q_IP, dir);
+ b = gen_protochain(v, Q_IPV6, dir);
+ gen_or(b0, b);
+ return b;
+ default:
+ bpf_error("bad protocol applied for 'protochain'");
+ /*NOTREACHED*/
+ }
+
+ /*
+ * We don't handle variable-length prefixes before the link-layer
+ * header, or variable-length link-layer headers, here yet.
+ * We might want to add BPF instructions to do the protochain
+ * work, to simplify that and, on platforms that have a BPF
+ * interpreter with the new instructions, let the filtering
+ * be done in the kernel. (We already require a modified BPF
+ * engine to do the protochain stuff, to support backward
+ * branches, and backward branch support is unlikely to appear
+ * in kernel BPF engines.)
+ */
+ switch (linktype) {
+
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_PPI:
+ bpf_error("'protochain' not supported with 802.11");
+ }
+
+ no_optimize = 1; /*this code is not compatible with optimzer yet */
+
+ /*
+ * s[0] is a dummy entry to protect other BPF insn from damage
+ * by s[fix] = foo with uninitialized variable "fix". It is somewhat
+ * hard to find interdependency made by jump table fixup.
+ */
+ i = 0;
+ s[i] = new_stmt(0); /*dummy*/
+ i++;
+
+ switch (proto) {
+ case Q_IP:
+ b0 = gen_linktype(ETHERTYPE_IP);
+
+ /* A = ip->ip_p */
+ s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B);
+ s[i]->s.k = off_macpl + off_nl + 9;
+ i++;
+ /* X = ip->ip_hl << 2 */
+ s[i] = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
+ s[i]->s.k = off_macpl + off_nl;
+ i++;
+ break;
+
+ case Q_IPV6:
+ b0 = gen_linktype(ETHERTYPE_IPV6);
+
+ /* A = ip6->ip_nxt */
+ s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B);
+ s[i]->s.k = off_macpl + off_nl + 6;
+ i++;
+ /* X = sizeof(struct ip6_hdr) */
+ s[i] = new_stmt(BPF_LDX|BPF_IMM);
+ s[i]->s.k = 40;
+ i++;
+ break;
+
+ default:
+ bpf_error("unsupported proto to gen_protochain");
+ /*NOTREACHED*/
+ }
+
+ /* again: if (A == v) goto end; else fall through; */
+ again = i;
+ s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
+ s[i]->s.k = v;
+ s[i]->s.jt = NULL; /*later*/
+ s[i]->s.jf = NULL; /*update in next stmt*/
+ fix5 = i;
+ i++;
+
+#ifndef IPPROTO_NONE
+#define IPPROTO_NONE 59
+#endif
+ /* if (A == IPPROTO_NONE) goto end */
+ s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
+ s[i]->s.jt = NULL; /*later*/
+ s[i]->s.jf = NULL; /*update in next stmt*/
+ s[i]->s.k = IPPROTO_NONE;
+ s[fix5]->s.jf = s[i];
+ fix2 = i;
+ i++;
+
+ if (proto == Q_IPV6) {
+ int v6start, v6end, v6advance, j;
+
+ v6start = i;
+ /* if (A == IPPROTO_HOPOPTS) goto v6advance */
+ s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
+ s[i]->s.jt = NULL; /*later*/
+ s[i]->s.jf = NULL; /*update in next stmt*/
+ s[i]->s.k = IPPROTO_HOPOPTS;
+ s[fix2]->s.jf = s[i];
+ i++;
+ /* if (A == IPPROTO_DSTOPTS) goto v6advance */
+ s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
+ s[i]->s.jt = NULL; /*later*/
+ s[i]->s.jf = NULL; /*update in next stmt*/
+ s[i]->s.k = IPPROTO_DSTOPTS;
+ i++;
+ /* if (A == IPPROTO_ROUTING) goto v6advance */
+ s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
+ s[i]->s.jt = NULL; /*later*/
+ s[i]->s.jf = NULL; /*update in next stmt*/
+ s[i]->s.k = IPPROTO_ROUTING;
+ i++;
+ /* if (A == IPPROTO_FRAGMENT) goto v6advance; else goto ahcheck; */
+ s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
+ s[i]->s.jt = NULL; /*later*/
+ s[i]->s.jf = NULL; /*later*/
+ s[i]->s.k = IPPROTO_FRAGMENT;
+ fix3 = i;
+ v6end = i;
+ i++;
+
+ /* v6advance: */
+ v6advance = i;
+
+ /*
+ * in short,
+ * A = P[X + packet head];
+ * X = X + (P[X + packet head + 1] + 1) * 8;
+ */
+ /* A = P[X + packet head] */
+ s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
+ s[i]->s.k = off_macpl + off_nl;
+ i++;
+ /* MEM[reg2] = A */
+ s[i] = new_stmt(BPF_ST);
+ s[i]->s.k = reg2;
+ i++;
+ /* A = P[X + packet head + 1]; */
+ s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
+ s[i]->s.k = off_macpl + off_nl + 1;
+ i++;
+ /* A += 1 */
+ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
+ s[i]->s.k = 1;
+ i++;
+ /* A *= 8 */
+ s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K);
+ s[i]->s.k = 8;
+ i++;
+ /* A += X */
+ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_X);
+ s[i]->s.k = 0;
+ i++;
+ /* X = A; */
+ s[i] = new_stmt(BPF_MISC|BPF_TAX);
+ i++;
+ /* A = MEM[reg2] */
+ s[i] = new_stmt(BPF_LD|BPF_MEM);
+ s[i]->s.k = reg2;
+ i++;
+
+ /* goto again; (must use BPF_JA for backward jump) */
+ s[i] = new_stmt(BPF_JMP|BPF_JA);
+ s[i]->s.k = again - i - 1;
+ s[i - 1]->s.jf = s[i];
+ i++;
+
+ /* fixup */
+ for (j = v6start; j <= v6end; j++)
+ s[j]->s.jt = s[v6advance];
+ } else {
+ /* nop */
+ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
+ s[i]->s.k = 0;
+ s[fix2]->s.jf = s[i];
+ i++;
+ }
+
+ /* ahcheck: */
+ ahcheck = i;
+ /* if (A == IPPROTO_AH) then fall through; else goto end; */
+ s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
+ s[i]->s.jt = NULL; /*later*/
+ s[i]->s.jf = NULL; /*later*/
+ s[i]->s.k = IPPROTO_AH;
+ if (fix3)
+ s[fix3]->s.jf = s[ahcheck];
+ fix4 = i;
+ i++;
+
+ /*
+ * in short,
+ * A = P[X];
+ * X = X + (P[X + 1] + 2) * 4;
+ */
+ /* A = X */
+ s[i - 1]->s.jt = s[i] = new_stmt(BPF_MISC|BPF_TXA);
+ i++;
+ /* A = P[X + packet head]; */
+ s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
+ s[i]->s.k = off_macpl + off_nl;
+ i++;
+ /* MEM[reg2] = A */
+ s[i] = new_stmt(BPF_ST);
+ s[i]->s.k = reg2;
+ i++;
+ /* A = X */
+ s[i - 1]->s.jt = s[i] = new_stmt(BPF_MISC|BPF_TXA);
+ i++;
+ /* A += 1 */
+ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
+ s[i]->s.k = 1;
+ i++;
+ /* X = A */
+ s[i] = new_stmt(BPF_MISC|BPF_TAX);
+ i++;
+ /* A = P[X + packet head] */
+ s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
+ s[i]->s.k = off_macpl + off_nl;
+ i++;
+ /* A += 2 */
+ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
+ s[i]->s.k = 2;
+ i++;
+ /* A *= 4 */
+ s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K);
+ s[i]->s.k = 4;
+ i++;
+ /* X = A; */
+ s[i] = new_stmt(BPF_MISC|BPF_TAX);
+ i++;
+ /* A = MEM[reg2] */
+ s[i] = new_stmt(BPF_LD|BPF_MEM);
+ s[i]->s.k = reg2;
+ i++;
+
+ /* goto again; (must use BPF_JA for backward jump) */
+ s[i] = new_stmt(BPF_JMP|BPF_JA);
+ s[i]->s.k = again - i - 1;
+ i++;
+
+ /* end: nop */
+ end = i;
+ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
+ s[i]->s.k = 0;
+ s[fix2]->s.jt = s[end];
+ s[fix4]->s.jf = s[end];
+ s[fix5]->s.jt = s[end];
+ i++;
+
+ /*
+ * make slist chain
+ */
+ max = i;
+ for (i = 0; i < max - 1; i++)
+ s[i]->next = s[i + 1];
+ s[max - 1]->next = NULL;
+
+ /*
+ * emit final check
+ */
+ b = new_block(JMP(BPF_JEQ));
+ b->stmts = s[1]; /*remember, s[0] is dummy*/
+ b->s.k = v;
+
+ free_reg(reg2);
+
+ gen_and(b0, b);
+ return b;
+#endif
+}
+
+static struct block *
+gen_check_802_11_data_frame()
+{
+ struct slist *s;
+ struct block *b0, *b1;
+
+ /*
+ * A data frame has the 0x08 bit (b3) in the frame control field set
+ * and the 0x04 bit (b2) clear.
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b0 = new_block(JMP(BPF_JSET));
+ b0->s.k = 0x08;
+ b0->stmts = s;
+
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x04;
+ b1->stmts = s;
+ gen_not(b1);
+
+ gen_and(b1, b0);
+
+ return b0;
+}
+
+/*
+ * Generate code that checks whether the packet is a packet for protocol
+ * <proto> and whether the type field in that protocol's header has
+ * the value <v>, e.g. if <proto> is Q_IP, it checks whether it's an
+ * IP packet and checks the protocol number in the IP header against <v>.
+ *
+ * If <proto> is Q_DEFAULT, i.e. just "proto" was specified, it checks
+ * against Q_IP and Q_IPV6.
+ */
+static struct block *
+gen_proto(v, proto, dir)
+ int v;
+ int proto;
+ int dir;
+{
+ struct block *b0, *b1;
+#ifndef CHASE_CHAIN
+ struct block *b2;
+#endif
+
+ if (dir != Q_DEFAULT)
+ bpf_error("direction applied to 'proto'");
+
+ switch (proto) {
+ case Q_DEFAULT:
+ b0 = gen_proto(v, Q_IP, dir);
+ b1 = gen_proto(v, Q_IPV6, dir);
+ gen_or(b0, b1);
+ return b1;
+
+ case Q_IP:
+ /*
+ * For FDDI, RFC 1188 says that SNAP encapsulation is used,
+ * not LLC encapsulation with LLCSAP_IP.
+ *
+ * For IEEE 802 networks - which includes 802.5 token ring
+ * (which is what DLT_IEEE802 means) and 802.11 - RFC 1042
+ * says that SNAP encapsulation is used, not LLC encapsulation
+ * with LLCSAP_IP.
+ *
+ * For LLC-encapsulated ATM/"Classical IP", RFC 1483 and
+ * RFC 2225 say that SNAP encapsulation is used, not LLC
+ * encapsulation with LLCSAP_IP.
+ *
+ * So we always check for ETHERTYPE_IP.
+ */
+ b0 = gen_linktype(ETHERTYPE_IP);
+#ifndef CHASE_CHAIN
+ b1 = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)v);
+#else
+ b1 = gen_protochain(v, Q_IP);
+#endif
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_ISO:
+ switch (linktype) {
+
+ case DLT_FRELAY:
+ /*
+ * Frame Relay packets typically have an OSI
+ * NLPID at the beginning; "gen_linktype(LLCSAP_ISONS)"
+ * generates code to check for all the OSI
+ * NLPIDs, so calling it and then adding a check
+ * for the particular NLPID for which we're
+ * looking is bogus, as we can just check for
+ * the NLPID.
+ *
+ * What we check for is the NLPID and a frame
+ * control field value of UI, i.e. 0x03 followed
+ * by the NLPID.
+ *
+ * XXX - assumes a 2-byte Frame Relay header with
+ * DLCI and flags. What if the address is longer?
+ *
+ * XXX - what about SNAP-encapsulated frames?
+ */
+ return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | v);
+ /*NOTREACHED*/
+ break;
+
+ case DLT_C_HDLC:
+ /*
+ * Cisco uses an Ethertype lookalike - for OSI,
+ * it's 0xfefe.
+ */
+ b0 = gen_linktype(LLCSAP_ISONS<<8 | LLCSAP_ISONS);
+ /* OSI in C-HDLC is stuffed with a fudge byte */
+ b1 = gen_cmp(OR_NET_NOSNAP, 1, BPF_B, (long)v);
+ gen_and(b0, b1);
+ return b1;
+
+ default:
+ b0 = gen_linktype(LLCSAP_ISONS);
+ b1 = gen_cmp(OR_NET_NOSNAP, 0, BPF_B, (long)v);
+ gen_and(b0, b1);
+ return b1;
+ }
+
+ case Q_ISIS:
+ b0 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT);
+ /*
+ * 4 is the offset of the PDU type relative to the IS-IS
+ * header.
+ */
+ b1 = gen_cmp(OR_NET_NOSNAP, 4, BPF_B, (long)v);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_ARP:
+ bpf_error("arp does not encapsulate another protocol");
+ /* NOTREACHED */
+
+ case Q_RARP:
+ bpf_error("rarp does not encapsulate another protocol");
+ /* NOTREACHED */
+
+ case Q_ATALK:
+ bpf_error("atalk encapsulation is not specifiable");
+ /* NOTREACHED */
+
+ case Q_DECNET:
+ bpf_error("decnet encapsulation is not specifiable");
+ /* NOTREACHED */
+
+ case Q_SCA:
+ bpf_error("sca does not encapsulate another protocol");
+ /* NOTREACHED */
+
+ case Q_LAT:
+ bpf_error("lat does not encapsulate another protocol");
+ /* NOTREACHED */
+
+ case Q_MOPRC:
+ bpf_error("moprc does not encapsulate another protocol");
+ /* NOTREACHED */
+
+ case Q_MOPDL:
+ bpf_error("mopdl does not encapsulate another protocol");
+ /* NOTREACHED */
+
+ case Q_LINK:
+ return gen_linktype(v);
+
+ case Q_UDP:
+ bpf_error("'udp proto' is bogus");
+ /* NOTREACHED */
+
+ case Q_TCP:
+ bpf_error("'tcp proto' is bogus");
+ /* NOTREACHED */
+
+ case Q_SCTP:
+ bpf_error("'sctp proto' is bogus");
+ /* NOTREACHED */
+
+ case Q_ICMP:
+ bpf_error("'icmp proto' is bogus");
+ /* NOTREACHED */
+
+ case Q_IGMP:
+ bpf_error("'igmp proto' is bogus");
+ /* NOTREACHED */
+
+ case Q_IGRP:
+ bpf_error("'igrp proto' is bogus");
+ /* NOTREACHED */
+
+ case Q_PIM:
+ bpf_error("'pim proto' is bogus");
+ /* NOTREACHED */
+
+ case Q_VRRP:
+ bpf_error("'vrrp proto' is bogus");
+ /* NOTREACHED */
+
+ case Q_CARP:
+ bpf_error("'carp proto' is bogus");
+ /* NOTREACHED */
+
+ case Q_IPV6:
+ b0 = gen_linktype(ETHERTYPE_IPV6);
+#ifndef CHASE_CHAIN
+ /*
+ * Also check for a fragment header before the final
+ * header.
+ */
+ b2 = gen_cmp(OR_NET, 6, BPF_B, IPPROTO_FRAGMENT);
+ b1 = gen_cmp(OR_NET, 40, BPF_B, (bpf_int32)v);
+ gen_and(b2, b1);
+ b2 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)v);
+ gen_or(b2, b1);
+#else
+ b1 = gen_protochain(v, Q_IPV6);
+#endif
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_ICMPV6:
+ bpf_error("'icmp6 proto' is bogus");
+
+ case Q_AH:
+ bpf_error("'ah proto' is bogus");
+
+ case Q_ESP:
+ bpf_error("'ah proto' is bogus");
+
+ case Q_STP:
+ bpf_error("'stp proto' is bogus");
+
+ case Q_IPX:
+ bpf_error("'ipx proto' is bogus");
+
+ case Q_NETBEUI:
+ bpf_error("'netbeui proto' is bogus");
+
+ case Q_RADIO:
+ bpf_error("'radio proto' is bogus");
+
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+ /* NOTREACHED */
+}
+
+struct block *
+gen_scode(name, q)
+ register const char *name;
+ struct qual q;
+{
+ int proto = q.proto;
+ int dir = q.dir;
+ int tproto;
+ u_char *eaddr;
+ bpf_u_int32 mask, addr;
+#ifndef INET6
+ bpf_u_int32 **alist;
+#else
+ int tproto6;
+ struct sockaddr_in *sin4;
+ struct sockaddr_in6 *sin6;
+ struct addrinfo *res, *res0;
+ struct in6_addr mask128;
+#endif /*INET6*/
+ struct block *b, *tmp;
+ int port, real_proto;
+ int port1, port2;
+
+ switch (q.addr) {
+
+ case Q_NET:
+ addr = pcap_nametonetaddr(name);
+ if (addr == 0)
+ bpf_error("unknown network '%s'", name);
+ /* Left justify network addr and calculate its network mask */
+ mask = 0xffffffff;
+ while (addr && (addr & 0xff000000) == 0) {
+ addr <<= 8;
+ mask <<= 8;
+ }
+ return gen_host(addr, mask, proto, dir, q.addr);
+
+ case Q_DEFAULT:
+ case Q_HOST:
+ if (proto == Q_LINK) {
+ switch (linktype) {
+
+ case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
+ eaddr = pcap_ether_hostton(name);
+ if (eaddr == NULL)
+ bpf_error(
+ "unknown ether host '%s'", name);
+ b = gen_ehostop(eaddr, dir);
+ free(eaddr);
+ return b;
+
+ case DLT_FDDI:
+ eaddr = pcap_ether_hostton(name);
+ if (eaddr == NULL)
+ bpf_error(
+ "unknown FDDI host '%s'", name);
+ b = gen_fhostop(eaddr, dir);
+ free(eaddr);
+ return b;
+
+ case DLT_IEEE802:
+ eaddr = pcap_ether_hostton(name);
+ if (eaddr == NULL)
+ bpf_error(
+ "unknown token ring host '%s'", name);
+ b = gen_thostop(eaddr, dir);
+ free(eaddr);
+ return b;
+
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_PPI:
+ eaddr = pcap_ether_hostton(name);
+ if (eaddr == NULL)
+ bpf_error(
+ "unknown 802.11 host '%s'", name);
+ b = gen_wlanhostop(eaddr, dir);
+ free(eaddr);
+ return b;
+
+ case DLT_IP_OVER_FC:
+ eaddr = pcap_ether_hostton(name);
+ if (eaddr == NULL)
+ bpf_error(
+ "unknown Fibre Channel host '%s'", name);
+ b = gen_ipfchostop(eaddr, dir);
+ free(eaddr);
+ return b;
+
+ case DLT_SUNATM:
+ if (!is_lane)
+ break;
+
+ /*
+ * Check that the packet doesn't begin
+ * with an LE Control marker. (We've
+ * already generated a test for LANE.)
+ */
+ tmp = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS,
+ BPF_H, 0xFF00);
+ gen_not(tmp);
+
+ eaddr = pcap_ether_hostton(name);
+ if (eaddr == NULL)
+ bpf_error(
+ "unknown ether host '%s'", name);
+ b = gen_ehostop(eaddr, dir);
+ gen_and(tmp, b);
+ free(eaddr);
+ return b;
+ }
+
+ bpf_error("only ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel supports link-level host name");
+ } else if (proto == Q_DECNET) {
+ unsigned short dn_addr = __pcap_nametodnaddr(name);
+ /*
+ * I don't think DECNET hosts can be multihomed, so
+ * there is no need to build up a list of addresses
+ */
+ return (gen_host(dn_addr, 0, proto, dir, q.addr));
+ } else {
+#ifndef INET6
+ alist = pcap_nametoaddr(name);
+ if (alist == NULL || *alist == NULL)
+ bpf_error("unknown host '%s'", name);
+ tproto = proto;
+ if (off_linktype == (u_int)-1 && tproto == Q_DEFAULT)
+ tproto = Q_IP;
+ b = gen_host(**alist++, 0xffffffff, tproto, dir, q.addr);
+ while (*alist) {
+ tmp = gen_host(**alist++, 0xffffffff,
+ tproto, dir, q.addr);
+ gen_or(b, tmp);
+ b = tmp;
+ }
+ return b;
+#else
+ memset(&mask128, 0xff, sizeof(mask128));
+ res0 = res = pcap_nametoaddrinfo(name);
+ if (res == NULL)
+ bpf_error("unknown host '%s'", name);
+ ai = res;
+ b = tmp = NULL;
+ tproto = tproto6 = proto;
+ if (off_linktype == -1 && tproto == Q_DEFAULT) {
+ tproto = Q_IP;
+ tproto6 = Q_IPV6;
+ }
+ for (res = res0; res; res = res->ai_next) {
+ switch (res->ai_family) {
+ case AF_INET:
+ if (tproto == Q_IPV6)
+ continue;
+
+ sin4 = (struct sockaddr_in *)
+ res->ai_addr;
+ tmp = gen_host(ntohl(sin4->sin_addr.s_addr),
+ 0xffffffff, tproto, dir, q.addr);
+ break;
+ case AF_INET6:
+ if (tproto6 == Q_IP)
+ continue;
+
+ sin6 = (struct sockaddr_in6 *)
+ res->ai_addr;
+ tmp = gen_host6(&sin6->sin6_addr,
+ &mask128, tproto6, dir, q.addr);
+ break;
+ default:
+ continue;
+ }
+ if (b)
+ gen_or(b, tmp);
+ b = tmp;
+ }
+ ai = NULL;
+ freeaddrinfo(res0);
+ if (b == NULL) {
+ bpf_error("unknown host '%s'%s", name,
+ (proto == Q_DEFAULT)
+ ? ""
+ : " for specified address family");
+ }
+ return b;
+#endif /*INET6*/
+ }
+
+ case Q_PORT:
+ if (proto != Q_DEFAULT &&
+ proto != Q_UDP && proto != Q_TCP && proto != Q_SCTP)
+ bpf_error("illegal qualifier of 'port'");
+ if (pcap_nametoport(name, &port, &real_proto) == 0)
+ bpf_error("unknown port '%s'", name);
+ if (proto == Q_UDP) {
+ if (real_proto == IPPROTO_TCP)
+ bpf_error("port '%s' is tcp", name);
+ else if (real_proto == IPPROTO_SCTP)
+ bpf_error("port '%s' is sctp", name);
+ else
+ /* override PROTO_UNDEF */
+ real_proto = IPPROTO_UDP;
+ }
+ if (proto == Q_TCP) {
+ if (real_proto == IPPROTO_UDP)
+ bpf_error("port '%s' is udp", name);
+
+ else if (real_proto == IPPROTO_SCTP)
+ bpf_error("port '%s' is sctp", name);
+ else
+ /* override PROTO_UNDEF */
+ real_proto = IPPROTO_TCP;
+ }
+ if (proto == Q_SCTP) {
+ if (real_proto == IPPROTO_UDP)
+ bpf_error("port '%s' is udp", name);
+
+ else if (real_proto == IPPROTO_TCP)
+ bpf_error("port '%s' is tcp", name);
+ else
+ /* override PROTO_UNDEF */
+ real_proto = IPPROTO_SCTP;
+ }
+ if (port < 0)
+ bpf_error("illegal port number %d < 0", port);
+ if (port > 65535)
+ bpf_error("illegal port number %d > 65535", port);
+ b = gen_port(port, real_proto, dir);
+ gen_or(gen_port6(port, real_proto, dir), b);
+ return b;
+
+ case Q_PORTRANGE:
+ if (proto != Q_DEFAULT &&
+ proto != Q_UDP && proto != Q_TCP && proto != Q_SCTP)
+ bpf_error("illegal qualifier of 'portrange'");
+ if (pcap_nametoportrange(name, &port1, &port2, &real_proto) == 0)
+ bpf_error("unknown port in range '%s'", name);
+ if (proto == Q_UDP) {
+ if (real_proto == IPPROTO_TCP)
+ bpf_error("port in range '%s' is tcp", name);
+ else if (real_proto == IPPROTO_SCTP)
+ bpf_error("port in range '%s' is sctp", name);
+ else
+ /* override PROTO_UNDEF */
+ real_proto = IPPROTO_UDP;
+ }
+ if (proto == Q_TCP) {
+ if (real_proto == IPPROTO_UDP)
+ bpf_error("port in range '%s' is udp", name);
+ else if (real_proto == IPPROTO_SCTP)
+ bpf_error("port in range '%s' is sctp", name);
+ else
+ /* override PROTO_UNDEF */
+ real_proto = IPPROTO_TCP;
+ }
+ if (proto == Q_SCTP) {
+ if (real_proto == IPPROTO_UDP)
+ bpf_error("port in range '%s' is udp", name);
+ else if (real_proto == IPPROTO_TCP)
+ bpf_error("port in range '%s' is tcp", name);
+ else
+ /* override PROTO_UNDEF */
+ real_proto = IPPROTO_SCTP;
+ }
+ if (port1 < 0)
+ bpf_error("illegal port number %d < 0", port1);
+ if (port1 > 65535)
+ bpf_error("illegal port number %d > 65535", port1);
+ if (port2 < 0)
+ bpf_error("illegal port number %d < 0", port2);
+ if (port2 > 65535)
+ bpf_error("illegal port number %d > 65535", port2);
+
+ b = gen_portrange(port1, port2, real_proto, dir);
+ gen_or(gen_portrange6(port1, port2, real_proto, dir), b);
+ return b;
+
+ case Q_GATEWAY:
+#ifndef INET6
+ eaddr = pcap_ether_hostton(name);
+ if (eaddr == NULL)
+ bpf_error("unknown ether host: %s", name);
+
+ alist = pcap_nametoaddr(name);
+ if (alist == NULL || *alist == NULL)
+ bpf_error("unknown host '%s'", name);
+ b = gen_gateway(eaddr, alist, proto, dir);
+ free(eaddr);
+ return b;
+#else
+ bpf_error("'gateway' not supported in this configuration");
+#endif /*INET6*/
+
+ case Q_PROTO:
+ real_proto = lookup_proto(name, proto);
+ if (real_proto >= 0)
+ return gen_proto(real_proto, proto, dir);
+ else
+ bpf_error("unknown protocol: %s", name);
+
+ case Q_PROTOCHAIN:
+ real_proto = lookup_proto(name, proto);
+ if (real_proto >= 0)
+ return gen_protochain(real_proto, proto, dir);
+ else
+ bpf_error("unknown protocol: %s", name);
+
+ case Q_UNDEF:
+ syntax();
+ /* NOTREACHED */
+ }
+ abort();
+ /* NOTREACHED */
+}
+
+struct block *
+gen_mcode(s1, s2, masklen, q)
+ register const char *s1, *s2;
+ register int masklen;
+ struct qual q;
+{
+ register int nlen, mlen;
+ bpf_u_int32 n, m;
+
+ nlen = __pcap_atoin(s1, &n);
+ /* Promote short ipaddr */
+ n <<= 32 - nlen;
+
+ if (s2 != NULL) {
+ mlen = __pcap_atoin(s2, &m);
+ /* Promote short ipaddr */
+ m <<= 32 - mlen;
+ if ((n & ~m) != 0)
+ bpf_error("non-network bits set in \"%s mask %s\"",
+ s1, s2);
+ } else {
+ /* Convert mask len to mask */
+ if (masklen > 32)
+ bpf_error("mask length must be <= 32");
+ if (masklen == 0) {
+ /*
+ * X << 32 is not guaranteed by C to be 0; it's
+ * undefined.
+ */
+ m = 0;
+ } else
+ m = 0xffffffff << (32 - masklen);
+ if ((n & ~m) != 0)
+ bpf_error("non-network bits set in \"%s/%d\"",
+ s1, masklen);
+ }
+
+ switch (q.addr) {
+
+ case Q_NET:
+ return gen_host(n, m, q.proto, q.dir, q.addr);
+
+ default:
+ bpf_error("Mask syntax for networks only");
+ /* NOTREACHED */
+ }
+ /* NOTREACHED */
+ return NULL;
+}
+
+struct block *
+gen_ncode(s, v, q)
+ register const char *s;
+ bpf_u_int32 v;
+ struct qual q;
+{
+ bpf_u_int32 mask;
+ int proto = q.proto;
+ int dir = q.dir;
+ register int vlen;
+
+ if (s == NULL)
+ vlen = 32;
+ else if (q.proto == Q_DECNET)
+ vlen = __pcap_atodn(s, &v);
+ else
+ vlen = __pcap_atoin(s, &v);
+
+ switch (q.addr) {
+
+ case Q_DEFAULT:
+ case Q_HOST:
+ case Q_NET:
+ if (proto == Q_DECNET)
+ return gen_host(v, 0, proto, dir, q.addr);
+ else if (proto == Q_LINK) {
+ bpf_error("illegal link layer address");
+ } else {
+ mask = 0xffffffff;
+ if (s == NULL && q.addr == Q_NET) {
+ /* Promote short net number */
+ while (v && (v & 0xff000000) == 0) {
+ v <<= 8;
+ mask <<= 8;
+ }
+ } else {
+ /* Promote short ipaddr */
+ v <<= 32 - vlen;
+ mask <<= 32 - vlen;
+ }
+ return gen_host(v, mask, proto, dir, q.addr);
+ }
+
+ case Q_PORT:
+ if (proto == Q_UDP)
+ proto = IPPROTO_UDP;
+ else if (proto == Q_TCP)
+ proto = IPPROTO_TCP;
+ else if (proto == Q_SCTP)
+ proto = IPPROTO_SCTP;
+ else if (proto == Q_DEFAULT)
+ proto = PROTO_UNDEF;
+ else
+ bpf_error("illegal qualifier of 'port'");
+
+ if (v > 65535)
+ bpf_error("illegal port number %u > 65535", v);
+
+ {
+ struct block *b;
+ b = gen_port((int)v, proto, dir);
+ gen_or(gen_port6((int)v, proto, dir), b);
+ return b;
+ }
+
+ case Q_PORTRANGE:
+ if (proto == Q_UDP)
+ proto = IPPROTO_UDP;
+ else if (proto == Q_TCP)
+ proto = IPPROTO_TCP;
+ else if (proto == Q_SCTP)
+ proto = IPPROTO_SCTP;
+ else if (proto == Q_DEFAULT)
+ proto = PROTO_UNDEF;
+ else
+ bpf_error("illegal qualifier of 'portrange'");
+
+ if (v > 65535)
+ bpf_error("illegal port number %u > 65535", v);
+
+ {
+ struct block *b;
+ b = gen_portrange((int)v, (int)v, proto, dir);
+ gen_or(gen_portrange6((int)v, (int)v, proto, dir), b);
+ return b;
+ }
+
+ case Q_GATEWAY:
+ bpf_error("'gateway' requires a name");
+ /* NOTREACHED */
+
+ case Q_PROTO:
+ return gen_proto((int)v, proto, dir);
+
+ case Q_PROTOCHAIN:
+ return gen_protochain((int)v, proto, dir);
+
+ case Q_UNDEF:
+ syntax();
+ /* NOTREACHED */
+
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+ /* NOTREACHED */
+}
+
+#ifdef INET6
+struct block *
+gen_mcode6(s1, s2, masklen, q)
+ register const char *s1, *s2;
+ register int masklen;
+ struct qual q;
+{
+ struct addrinfo *res;
+ struct in6_addr *addr;
+ struct in6_addr mask;
+ struct block *b;
+ u_int32_t *a, *m;
+
+ if (s2)
+ bpf_error("no mask %s supported", s2);
+
+ res = pcap_nametoaddrinfo(s1);
+ if (!res)
+ bpf_error("invalid ip6 address %s", s1);
+ ai = res;
+ if (res->ai_next)
+ bpf_error("%s resolved to multiple address", s1);
+ addr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
+
+ if (sizeof(mask) * 8 < masklen)
+ bpf_error("mask length must be <= %u", (unsigned int)(sizeof(mask) * 8));
+ memset(&mask, 0, sizeof(mask));
+ memset(&mask, 0xff, masklen / 8);
+ if (masklen % 8) {
+ mask.s6_addr[masklen / 8] =
+ (0xff << (8 - masklen % 8)) & 0xff;
+ }
+
+ a = (u_int32_t *)addr;
+ m = (u_int32_t *)&mask;
+ if ((a[0] & ~m[0]) || (a[1] & ~m[1])
+ || (a[2] & ~m[2]) || (a[3] & ~m[3])) {
+ bpf_error("non-network bits set in \"%s/%d\"", s1, masklen);
+ }
+
+ switch (q.addr) {
+
+ case Q_DEFAULT:
+ case Q_HOST:
+ if (masklen != 128)
+ bpf_error("Mask syntax for networks only");
+ /* FALLTHROUGH */
+
+ case Q_NET:
+ b = gen_host6(addr, &mask, q.proto, q.dir, q.addr);
+ ai = NULL;
+ freeaddrinfo(res);
+ return b;
+
+ default:
+ bpf_error("invalid qualifier against IPv6 address");
+ /* NOTREACHED */
+ }
+ return NULL;
+}
+#endif /*INET6*/
+
+struct block *
+gen_ecode(eaddr, q)
+ register const u_char *eaddr;
+ struct qual q;
+{
+ struct block *b, *tmp;
+
+ if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
+ switch (linktype) {
+ case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
+ return gen_ehostop(eaddr, (int)q.dir);
+ case DLT_FDDI:
+ return gen_fhostop(eaddr, (int)q.dir);
+ case DLT_IEEE802:
+ return gen_thostop(eaddr, (int)q.dir);
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_PPI:
+ return gen_wlanhostop(eaddr, (int)q.dir);
+ case DLT_SUNATM:
+ if (is_lane) {
+ /*
+ * Check that the packet doesn't begin with an
+ * LE Control marker. (We've already generated
+ * a test for LANE.)
+ */
+ tmp = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H,
+ 0xFF00);
+ gen_not(tmp);
+
+ /*
+ * Now check the MAC address.
+ */
+ b = gen_ehostop(eaddr, (int)q.dir);
+ gen_and(tmp, b);
+ return b;
+ }
+ break;
+ case DLT_IP_OVER_FC:
+ return gen_ipfchostop(eaddr, (int)q.dir);
+ default:
+ bpf_error("ethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
+ break;
+ }
+ }
+ bpf_error("ethernet address used in non-ether expression");
+ /* NOTREACHED */
+ return NULL;
+}
+
+void
+sappend(s0, s1)
+ struct slist *s0, *s1;
+{
+ /*
+ * This is definitely not the best way to do this, but the
+ * lists will rarely get long.
+ */
+ while (s0->next)
+ s0 = s0->next;
+ s0->next = s1;
+}
+
+static struct slist *
+xfer_to_x(a)
+ struct arth *a;
+{
+ struct slist *s;
+
+ s = new_stmt(BPF_LDX|BPF_MEM);
+ s->s.k = a->regno;
+ return s;
+}
+
+static struct slist *
+xfer_to_a(a)
+ struct arth *a;
+{
+ struct slist *s;
+
+ s = new_stmt(BPF_LD|BPF_MEM);
+ s->s.k = a->regno;
+ return s;
+}
+
+/*
+ * Modify "index" to use the value stored into its register as an
+ * offset relative to the beginning of the header for the protocol
+ * "proto", and allocate a register and put an item "size" bytes long
+ * (1, 2, or 4) at that offset into that register, making it the register
+ * for "index".
+ */
+struct arth *
+gen_load(proto, inst, size)
+ int proto;
+ struct arth *inst;
+ int size;
+{
+ struct slist *s, *tmp;
+ struct block *b;
+ int regno = alloc_reg();
+
+ free_reg(inst->regno);
+ switch (size) {
+
+ default:
+ bpf_error("data size must be 1, 2, or 4");
+
+ case 1:
+ size = BPF_B;
+ break;
+
+ case 2:
+ size = BPF_H;
+ break;
+
+ case 4:
+ size = BPF_W;
+ break;
+ }
+ switch (proto) {
+ default:
+ bpf_error("unsupported index operation");
+
+ case Q_RADIO:
+ /*
+ * The offset is relative to the beginning of the packet
+ * data, if we have a radio header. (If we don't, this
+ * is an error.)
+ */
+ if (linktype != DLT_IEEE802_11_RADIO_AVS &&
+ linktype != DLT_IEEE802_11_RADIO &&
+ linktype != DLT_PRISM_HEADER)
+ bpf_error("radio information not present in capture");
+
+ /*
+ * Load into the X register the offset computed into the
+ * register specified by "index".
+ */
+ s = xfer_to_x(inst);
+
+ /*
+ * Load the item at that offset.
+ */
+ tmp = new_stmt(BPF_LD|BPF_IND|size);
+ sappend(s, tmp);
+ sappend(inst->s, s);
+ break;
+
+ case Q_LINK:
+ /*
+ * The offset is relative to the beginning of
+ * the link-layer header.
+ *
+ * XXX - what about ATM LANE? Should the index be
+ * relative to the beginning of the AAL5 frame, so
+ * that 0 refers to the beginning of the LE Control
+ * field, or relative to the beginning of the LAN
+ * frame, so that 0 refers, for Ethernet LANE, to
+ * the beginning of the destination address?
+ */
+ s = gen_llprefixlen();
+
+ /*
+ * If "s" is non-null, it has code to arrange that the
+ * X register contains the length of the prefix preceding
+ * the link-layer header. Add to it the offset computed
+ * into the register specified by "index", and move that
+ * into the X register. Otherwise, just load into the X
+ * register the offset computed into the register specified
+ * by "index".
+ */
+ if (s != NULL) {
+ sappend(s, xfer_to_a(inst));
+ sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
+ sappend(s, new_stmt(BPF_MISC|BPF_TAX));
+ } else
+ s = xfer_to_x(inst);
+
+ /*
+ * Load the item at the sum of the offset we've put in the
+ * X register and the offset of the start of the link
+ * layer header (which is 0 if the radio header is
+ * variable-length; that header length is what we put
+ * into the X register and then added to the index).
+ */
+ tmp = new_stmt(BPF_LD|BPF_IND|size);
+ tmp->s.k = off_ll;
+ sappend(s, tmp);
+ sappend(inst->s, s);
+ break;
+
+ case Q_IP:
+ case Q_ARP:
+ case Q_RARP:
+ case Q_ATALK:
+ case Q_DECNET:
+ case Q_SCA:
+ case Q_LAT:
+ case Q_MOPRC:
+ case Q_MOPDL:
+ case Q_IPV6:
+ /*
+ * The offset is relative to the beginning of
+ * the network-layer header.
+ * XXX - are there any cases where we want
+ * off_nl_nosnap?
+ */
+ s = gen_off_macpl();
+
+ /*
+ * If "s" is non-null, it has code to arrange that the
+ * X register contains the offset of the MAC-layer
+ * payload. Add to it the offset computed into the
+ * register specified by "index", and move that into
+ * the X register. Otherwise, just load into the X
+ * register the offset computed into the register specified
+ * by "index".
+ */
+ if (s != NULL) {
+ sappend(s, xfer_to_a(inst));
+ sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
+ sappend(s, new_stmt(BPF_MISC|BPF_TAX));
+ } else
+ s = xfer_to_x(inst);
+
+ /*
+ * Load the item at the sum of the offset we've put in the
+ * X register, the offset of the start of the network
+ * layer header from the beginning of the MAC-layer
+ * payload, and the purported offset of the start of the
+ * MAC-layer payload (which might be 0 if there's a
+ * variable-length prefix before the link-layer header
+ * or the link-layer header itself is variable-length;
+ * the variable-length offset of the start of the
+ * MAC-layer payload is what we put into the X register
+ * and then added to the index).
+ */
+ tmp = new_stmt(BPF_LD|BPF_IND|size);
+ tmp->s.k = off_macpl + off_nl;
+ sappend(s, tmp);
+ sappend(inst->s, s);
+
+ /*
+ * Do the computation only if the packet contains
+ * the protocol in question.
+ */
+ b = gen_proto_abbrev(proto);
+ if (inst->b)
+ gen_and(inst->b, b);
+ inst->b = b;
+ break;
+
+ case Q_SCTP:
+ case Q_TCP:
+ case Q_UDP:
+ case Q_ICMP:
+ case Q_IGMP:
+ case Q_IGRP:
+ case Q_PIM:
+ case Q_VRRP:
+ case Q_CARP:
+ /*
+ * The offset is relative to the beginning of
+ * the transport-layer header.
+ *
+ * Load the X register with the length of the IPv4 header
+ * (plus the offset of the link-layer header, if it's
+ * a variable-length header), in bytes.
+ *
+ * XXX - are there any cases where we want
+ * off_nl_nosnap?
+ * XXX - we should, if we're built with
+ * IPv6 support, generate code to load either
+ * IPv4, IPv6, or both, as appropriate.
+ */
+ s = gen_loadx_iphdrlen();
+
+ /*
+ * The X register now contains the sum of the length
+ * of any variable-length header preceding the link-layer
+ * header, any variable-length link-layer header, and the
+ * length of the network-layer header.
+ *
+ * Load into the A register the offset relative to
+ * the beginning of the transport layer header,
+ * add the X register to that, move that to the
+ * X register, and load with an offset from the
+ * X register equal to the offset of the network
+ * layer header relative to the beginning of
+ * the MAC-layer payload plus the fixed-length
+ * portion of the offset of the MAC-layer payload
+ * from the beginning of the raw packet data.
+ */
+ sappend(s, xfer_to_a(inst));
+ sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
+ sappend(s, new_stmt(BPF_MISC|BPF_TAX));
+ sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size));
+ tmp->s.k = off_macpl + off_nl;
+ sappend(inst->s, s);
+
+ /*
+ * Do the computation only if the packet contains
+ * the protocol in question - which is true only
+ * if this is an IP datagram and is the first or
+ * only fragment of that datagram.
+ */
+ gen_and(gen_proto_abbrev(proto), b = gen_ipfrag());
+ if (inst->b)
+ gen_and(inst->b, b);
+ gen_and(gen_proto_abbrev(Q_IP), b);
+ inst->b = b;
+ break;
+ case Q_ICMPV6:
+ bpf_error("IPv6 upper-layer protocol is not supported by proto[x]");
+ /*NOTREACHED*/
+ }
+ inst->regno = regno;
+ s = new_stmt(BPF_ST);
+ s->s.k = regno;
+ sappend(inst->s, s);
+
+ return inst;
+}
+
+struct block *
+gen_relation(code, a0, a1, reversed)
+ int code;
+ struct arth *a0, *a1;
+ int reversed;
+{
+ struct slist *s0, *s1, *s2;
+ struct block *b, *tmp;
+
+ s0 = xfer_to_x(a1);
+ s1 = xfer_to_a(a0);
+ if (code == BPF_JEQ) {
+ s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X);
+ b = new_block(JMP(code));
+ sappend(s1, s2);
+ }
+ else
+ b = new_block(BPF_JMP|code|BPF_X);
+ if (reversed)
+ gen_not(b);
+
+ sappend(s0, s1);
+ sappend(a1->s, s0);
+ sappend(a0->s, a1->s);
+
+ b->stmts = a0->s;
+
+ free_reg(a0->regno);
+ free_reg(a1->regno);
+
+ /* 'and' together protocol checks */
+ if (a0->b) {
+ if (a1->b) {
+ gen_and(a0->b, tmp = a1->b);
+ }
+ else
+ tmp = a0->b;
+ } else
+ tmp = a1->b;
+
+ if (tmp)
+ gen_and(tmp, b);
+
+ return b;
+}
+
+struct arth *
+gen_loadlen()
+{
+ int regno = alloc_reg();
+ struct arth *a = (struct arth *)newchunk(sizeof(*a));
+ struct slist *s;
+
+ s = new_stmt(BPF_LD|BPF_LEN);
+ s->next = new_stmt(BPF_ST);
+ s->next->s.k = regno;
+ a->s = s;
+ a->regno = regno;
+
+ return a;
+}
+
+struct arth *
+gen_loadi(val)
+ int val;
+{
+ struct arth *a;
+ struct slist *s;
+ int reg;
+
+ a = (struct arth *)newchunk(sizeof(*a));
+
+ reg = alloc_reg();
+
+ s = new_stmt(BPF_LD|BPF_IMM);
+ s->s.k = val;
+ s->next = new_stmt(BPF_ST);
+ s->next->s.k = reg;
+ a->s = s;
+ a->regno = reg;
+
+ return a;
+}
+
+struct arth *
+gen_neg(a)
+ struct arth *a;
+{
+ struct slist *s;
+
+ s = xfer_to_a(a);
+ sappend(a->s, s);
+ s = new_stmt(BPF_ALU|BPF_NEG);
+ s->s.k = 0;
+ sappend(a->s, s);
+ s = new_stmt(BPF_ST);
+ s->s.k = a->regno;
+ sappend(a->s, s);
+
+ return a;
+}
+
+struct arth *
+gen_arth(code, a0, a1)
+ int code;
+ struct arth *a0, *a1;
+{
+ struct slist *s0, *s1, *s2;
+
+ s0 = xfer_to_x(a1);
+ s1 = xfer_to_a(a0);
+ s2 = new_stmt(BPF_ALU|BPF_X|code);
+
+ sappend(s1, s2);
+ sappend(s0, s1);
+ sappend(a1->s, s0);
+ sappend(a0->s, a1->s);
+
+ free_reg(a0->regno);
+ free_reg(a1->regno);
+
+ s0 = new_stmt(BPF_ST);
+ a0->regno = s0->s.k = alloc_reg();
+ sappend(a0->s, s0);
+
+ return a0;
+}
+
+/*
+ * Here we handle simple allocation of the scratch registers.
+ * If too many registers are alloc'd, the allocator punts.
+ */
+static int regused[BPF_MEMWORDS];
+static int curreg;
+
+/*
+ * Initialize the table of used registers and the current register.
+ */
+static void
+init_regs()
+{
+ curreg = 0;
+ memset(regused, 0, sizeof regused);
+}
+
+/*
+ * Return the next free register.
+ */
+static int
+alloc_reg()
+{
+ int n = BPF_MEMWORDS;
+
+ while (--n >= 0) {
+ if (regused[curreg])
+ curreg = (curreg + 1) % BPF_MEMWORDS;
+ else {
+ regused[curreg] = 1;
+ return curreg;
+ }
+ }
+ bpf_error("too many registers needed to evaluate expression");
+ /* NOTREACHED */
+ return 0;
+}
+
+/*
+ * Return a register to the table so it can
+ * be used later.
+ */
+static void
+free_reg(n)
+ int n;
+{
+ regused[n] = 0;
+}
+
+static struct block *
+gen_len(jmp, n)
+ int jmp, n;
+{
+ struct slist *s;
+ struct block *b;
+
+ s = new_stmt(BPF_LD|BPF_LEN);
+ b = new_block(JMP(jmp));
+ b->stmts = s;
+ b->s.k = n;
+
+ return b;
+}
+
+struct block *
+gen_greater(n)
+ int n;
+{
+ return gen_len(BPF_JGE, n);
+}
+
+/*
+ * Actually, this is less than or equal.
+ */
+struct block *
+gen_less(n)
+ int n;
+{
+ struct block *b;
+
+ b = gen_len(BPF_JGT, n);
+ gen_not(b);
+
+ return b;
+}
+
+/*
+ * This is for "byte {idx} {op} {val}"; "idx" is treated as relative to
+ * the beginning of the link-layer header.
+ * XXX - that means you can't test values in the radiotap header, but
+ * as that header is difficult if not impossible to parse generally
+ * without a loop, that might not be a severe problem. A new keyword
+ * "radio" could be added for that, although what you'd really want
+ * would be a way of testing particular radio header values, which
+ * would generate code appropriate to the radio header in question.
+ */
+struct block *
+gen_byteop(op, idx, val)
+ int op, idx, val;
+{
+ struct block *b;
+ struct slist *s;
+
+ switch (op) {
+ default:
+ abort();
+
+ case '=':
+ return gen_cmp(OR_LINK, (u_int)idx, BPF_B, (bpf_int32)val);
+
+ case '<':
+ b = gen_cmp_lt(OR_LINK, (u_int)idx, BPF_B, (bpf_int32)val);
+ return b;
+
+ case '>':
+ b = gen_cmp_gt(OR_LINK, (u_int)idx, BPF_B, (bpf_int32)val);
+ return b;
+
+ case '|':
+ s = new_stmt(BPF_ALU|BPF_OR|BPF_K);
+ break;
+
+ case '&':
+ s = new_stmt(BPF_ALU|BPF_AND|BPF_K);
+ break;
+ }
+ s->s.k = val;
+ b = new_block(JMP(BPF_JEQ));
+ b->stmts = s;
+ gen_not(b);
+
+ return b;
+}
+
+static u_char abroadcast[] = { 0x0 };
+
+struct block *
+gen_broadcast(proto)
+ int proto;
+{
+ bpf_u_int32 hostmask;
+ struct block *b0, *b1, *b2;
+ static u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+ switch (proto) {
+
+ case Q_DEFAULT:
+ case Q_LINK:
+ switch (linktype) {
+ case DLT_ARCNET:
+ case DLT_ARCNET_LINUX:
+ return gen_ahostop(abroadcast, Q_DST);
+ case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
+ return gen_ehostop(ebroadcast, Q_DST);
+ case DLT_FDDI:
+ return gen_fhostop(ebroadcast, Q_DST);
+ case DLT_IEEE802:
+ return gen_thostop(ebroadcast, Q_DST);
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_PPI:
+ return gen_wlanhostop(ebroadcast, Q_DST);
+ case DLT_IP_OVER_FC:
+ return gen_ipfchostop(ebroadcast, Q_DST);
+ case DLT_SUNATM:
+ if (is_lane) {
+ /*
+ * Check that the packet doesn't begin with an
+ * LE Control marker. (We've already generated
+ * a test for LANE.)
+ */
+ b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS,
+ BPF_H, 0xFF00);
+ gen_not(b1);
+
+ /*
+ * Now check the MAC address.
+ */
+ b0 = gen_ehostop(ebroadcast, Q_DST);
+ gen_and(b1, b0);
+ return b0;
+ }
+ break;
+ default:
+ bpf_error("not a broadcast link");
+ }
+ break;
+
+ case Q_IP:
+ /*
+ * We treat a netmask of PCAP_NETMASK_UNKNOWN (0xffffffff)
+ * as an indication that we don't know the netmask, and fail
+ * in that case.
+ */
+ if (netmask == PCAP_NETMASK_UNKNOWN)
+ bpf_error("netmask not known, so 'ip broadcast' not supported");
+ b0 = gen_linktype(ETHERTYPE_IP);
+ hostmask = ~netmask;
+ b1 = gen_mcmp(OR_NET, 16, BPF_W, (bpf_int32)0, hostmask);
+ b2 = gen_mcmp(OR_NET, 16, BPF_W,
+ (bpf_int32)(~0 & hostmask), hostmask);
+ gen_or(b1, b2);
+ gen_and(b0, b2);
+ return b2;
+ }
+ bpf_error("only link-layer/IP broadcast filters supported");
+ /* NOTREACHED */
+ return NULL;
+}
+
+/*
+ * Generate code to test the low-order bit of a MAC address (that's
+ * the bottom bit of the *first* byte).
+ */
+static struct block *
+gen_mac_multicast(offset)
+ int offset;
+{
+ register struct block *b0;
+ register struct slist *s;
+
+ /* link[offset] & 1 != 0 */
+ s = gen_load_a(OR_LINK, offset, BPF_B);
+ b0 = new_block(JMP(BPF_JSET));
+ b0->s.k = 1;
+ b0->stmts = s;
+ return b0;
+}
+
+struct block *
+gen_multicast(proto)
+ int proto;
+{
+ register struct block *b0, *b1, *b2;
+ register struct slist *s;
+
+ switch (proto) {
+
+ case Q_DEFAULT:
+ case Q_LINK:
+ switch (linktype) {
+ case DLT_ARCNET:
+ case DLT_ARCNET_LINUX:
+ /* all ARCnet multicasts use the same address */
+ return gen_ahostop(abroadcast, Q_DST);
+ case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
+ /* ether[0] & 1 != 0 */
+ return gen_mac_multicast(0);
+ case DLT_FDDI:
+ /*
+ * XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX
+ *
+ * XXX - was that referring to bit-order issues?
+ */
+ /* fddi[1] & 1 != 0 */
+ return gen_mac_multicast(1);
+ case DLT_IEEE802:
+ /* tr[2] & 1 != 0 */
+ return gen_mac_multicast(2);
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_PPI:
+ /*
+ * Oh, yuk.
+ *
+ * For control frames, there is no DA.
+ *
+ * For management frames, DA is at an
+ * offset of 4 from the beginning of
+ * the packet.
+ *
+ * For data frames, DA is at an offset
+ * of 4 from the beginning of the packet
+ * if To DS is clear and at an offset of
+ * 16 from the beginning of the packet
+ * if To DS is set.
+ */
+
+ /*
+ * Generate the tests to be done for data frames.
+ *
+ * First, check for To DS set, i.e. "link[1] & 0x01".
+ */
+ s = gen_load_a(OR_LINK, 1, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x01; /* To DS */
+ b1->stmts = s;
+
+ /*
+ * If To DS is set, the DA is at 16.
+ */
+ b0 = gen_mac_multicast(16);
+ gen_and(b1, b0);
+
+ /*
+ * Now, check for To DS not set, i.e. check
+ * "!(link[1] & 0x01)".
+ */
+ s = gen_load_a(OR_LINK, 1, BPF_B);
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x01; /* To DS */
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * If To DS is not set, the DA is at 4.
+ */
+ b1 = gen_mac_multicast(4);
+ gen_and(b2, b1);
+
+ /*
+ * Now OR together the last two checks. That gives
+ * the complete set of checks for data frames.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * Now check for a data frame.
+ * I.e, check "link[0] & 0x08".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x08;
+ b1->stmts = s;
+
+ /*
+ * AND that with the checks done for data frames.
+ */
+ gen_and(b1, b0);
+
+ /*
+ * If the high-order bit of the type value is 0, this
+ * is a management frame.
+ * I.e, check "!(link[0] & 0x08)".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x08;
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * For management frames, the DA is at 4.
+ */
+ b1 = gen_mac_multicast(4);
+ gen_and(b2, b1);
+
+ /*
+ * OR that with the checks done for data frames.
+ * That gives the checks done for management and
+ * data frames.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * If the low-order bit of the type value is 1,
+ * this is either a control frame or a frame
+ * with a reserved type, and thus not a
+ * frame with an SA.
+ *
+ * I.e., check "!(link[0] & 0x04)".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x04;
+ b1->stmts = s;
+ gen_not(b1);
+
+ /*
+ * AND that with the checks for data and management
+ * frames.
+ */
+ gen_and(b1, b0);
+ return b0;
+ case DLT_IP_OVER_FC:
+ b0 = gen_mac_multicast(2);
+ return b0;
+ case DLT_SUNATM:
+ if (is_lane) {
+ /*
+ * Check that the packet doesn't begin with an
+ * LE Control marker. (We've already generated
+ * a test for LANE.)
+ */
+ b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS,
+ BPF_H, 0xFF00);
+ gen_not(b1);
+
+ /* ether[off_mac] & 1 != 0 */
+ b0 = gen_mac_multicast(off_mac);
+ gen_and(b1, b0);
+ return b0;
+ }
+ break;
+ default:
+ break;
+ }
+ /* Link not known to support multicasts */
+ break;
+
+ case Q_IP:
+ b0 = gen_linktype(ETHERTYPE_IP);
+ b1 = gen_cmp_ge(OR_NET, 16, BPF_B, (bpf_int32)224);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_IPV6:
+ b0 = gen_linktype(ETHERTYPE_IPV6);
+ b1 = gen_cmp(OR_NET, 24, BPF_B, (bpf_int32)255);
+ gen_and(b0, b1);
+ return b1;
+ }
+ bpf_error("link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel");
+ /* NOTREACHED */
+ return NULL;
+}
+
+/*
+ * Filter on inbound (dir == 0) or outbound (dir == 1) traffic.
+ * Outbound traffic is sent by this machine, while inbound traffic is
+ * sent by a remote machine (and may include packets destined for a
+ * unicast or multicast link-layer address we are not subscribing to).
+ * These are the same definitions implemented by pcap_setdirection().
+ * Capturing only unicast traffic destined for this host is probably
+ * better accomplished using a higher-layer filter.
+ */
+struct block *
+gen_inbound(dir)
+ int dir;
+{
+ register struct block *b0;
+
+ /*
+ * Only some data link types support inbound/outbound qualifiers.
+ */
+ switch (linktype) {
+ case DLT_SLIP:
+ b0 = gen_relation(BPF_JEQ,
+ gen_load(Q_LINK, gen_loadi(0), 1),
+ gen_loadi(0),
+ dir);
+ break;
+
+ case DLT_IPNET:
+ if (dir) {
+ /* match outgoing packets */
+ b0 = gen_cmp(OR_LINK, 2, BPF_H, IPNET_OUTBOUND);
+ } else {
+ /* match incoming packets */
+ b0 = gen_cmp(OR_LINK, 2, BPF_H, IPNET_INBOUND);
+ }
+ break;
+
+ case DLT_LINUX_SLL:
+ /* match outgoing packets */
+ b0 = gen_cmp(OR_LINK, 0, BPF_H, LINUX_SLL_OUTGOING);
+ if (!dir) {
+ /* to filter on inbound traffic, invert the match */
+ gen_not(b0);
+ }
+ break;
+
+#ifdef HAVE_NET_PFVAR_H
+ case DLT_PFLOG:
+ b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, dir), BPF_B,
+ (bpf_int32)((dir == 0) ? PF_IN : PF_OUT));
+ break;
+#endif
+
+ case DLT_PPP_PPPD:
+ if (dir) {
+ /* match outgoing packets */
+ b0 = gen_cmp(OR_LINK, 0, BPF_B, PPP_PPPD_OUT);
+ } else {
+ /* match incoming packets */
+ b0 = gen_cmp(OR_LINK, 0, BPF_B, PPP_PPPD_IN);
+ }
+ break;
+
+ case DLT_JUNIPER_MFR:
+ case DLT_JUNIPER_MLFR:
+ case DLT_JUNIPER_MLPPP:
+ case DLT_JUNIPER_ATM1:
+ case DLT_JUNIPER_ATM2:
+ case DLT_JUNIPER_PPPOE:
+ case DLT_JUNIPER_PPPOE_ATM:
+ case DLT_JUNIPER_GGSN:
+ case DLT_JUNIPER_ES:
+ case DLT_JUNIPER_MONITOR:
+ case DLT_JUNIPER_SERVICES:
+ case DLT_JUNIPER_ETHER:
+ case DLT_JUNIPER_PPP:
+ case DLT_JUNIPER_FRELAY:
+ case DLT_JUNIPER_CHDLC:
+ case DLT_JUNIPER_VP:
+ case DLT_JUNIPER_ST:
+ case DLT_JUNIPER_ISM:
+ case DLT_JUNIPER_VS:
+ case DLT_JUNIPER_SRX_E2E:
+ case DLT_JUNIPER_FIBRECHANNEL:
+ case DLT_JUNIPER_ATM_CEMIC:
+
+ /* juniper flags (including direction) are stored
+ * the byte after the 3-byte magic number */
+ if (dir) {
+ /* match outgoing packets */
+ b0 = gen_mcmp(OR_LINK, 3, BPF_B, 0, 0x01);
+ } else {
+ /* match incoming packets */
+ b0 = gen_mcmp(OR_LINK, 3, BPF_B, 1, 0x01);
+ }
+ break;
+
+ default:
+ /*
+ * If we have packet meta-data indicating a direction,
+ * check it, otherwise give up as this link-layer type
+ * has nothing in the packet data.
+ */
+#if defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
+ /*
+ * We infer that this is Linux with PF_PACKET support.
+ * If this is a *live* capture, we can look at
+ * special meta-data in the filter expression;
+ * if it's a savefile, we can't.
+ */
+ if (bpf_pcap->sf.rfile != NULL) {
+ /* We have a FILE *, so this is a savefile */
+ bpf_error("inbound/outbound not supported on linktype %d when reading savefiles",
+ linktype);
+ b0 = NULL;
+ /* NOTREACHED */
+ }
+ /* match outgoing packets */
+ b0 = gen_cmp(OR_LINK, SKF_AD_OFF + SKF_AD_PKTTYPE, BPF_H,
+ PACKET_OUTGOING);
+ if (!dir) {
+ /* to filter on inbound traffic, invert the match */
+ gen_not(b0);
+ }
+#else /* defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
+ bpf_error("inbound/outbound not supported on linktype %d",
+ linktype);
+ b0 = NULL;
+ /* NOTREACHED */
+#endif /* defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
+ }
+ return (b0);
+}
+
+#ifdef HAVE_NET_PFVAR_H
+/* PF firewall log matched interface */
+struct block *
+gen_pf_ifname(const char *ifname)
+{
+ struct block *b0;
+ u_int len, off;
+
+ if (linktype != DLT_PFLOG) {
+ bpf_error("ifname supported only on PF linktype");
+ /* NOTREACHED */
+ }
+ len = sizeof(((struct pfloghdr *)0)->ifname);
+ off = offsetof(struct pfloghdr, ifname);
+ if (strlen(ifname) >= len) {
+ bpf_error("ifname interface names can only be %d characters",
+ len-1);
+ /* NOTREACHED */
+ }
+ b0 = gen_bcmp(OR_LINK, off, strlen(ifname), (const u_char *)ifname);
+ return (b0);
+}
+
+/* PF firewall log ruleset name */
+struct block *
+gen_pf_ruleset(char *ruleset)
+{
+ struct block *b0;
+
+ if (linktype != DLT_PFLOG) {
+ bpf_error("ruleset supported only on PF linktype");
+ /* NOTREACHED */
+ }
+
+ if (strlen(ruleset) >= sizeof(((struct pfloghdr *)0)->ruleset)) {
+ bpf_error("ruleset names can only be %ld characters",
+ (long)(sizeof(((struct pfloghdr *)0)->ruleset) - 1));
+ /* NOTREACHED */
+ }
+
+ b0 = gen_bcmp(OR_LINK, offsetof(struct pfloghdr, ruleset),
+ strlen(ruleset), (const u_char *)ruleset);
+ return (b0);
+}
+
+/* PF firewall log rule number */
+struct block *
+gen_pf_rnr(int rnr)
+{
+ struct block *b0;
+
+ if (linktype != DLT_PFLOG) {
+ bpf_error("rnr supported only on PF linktype");
+ /* NOTREACHED */
+ }
+
+ b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, rulenr), BPF_W,
+ (bpf_int32)rnr);
+ return (b0);
+}
+
+/* PF firewall log sub-rule number */
+struct block *
+gen_pf_srnr(int srnr)
+{
+ struct block *b0;
+
+ if (linktype != DLT_PFLOG) {
+ bpf_error("srnr supported only on PF linktype");
+ /* NOTREACHED */
+ }
+
+ b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, subrulenr), BPF_W,
+ (bpf_int32)srnr);
+ return (b0);
+}
+
+/* PF firewall log reason code */
+struct block *
+gen_pf_reason(int reason)
+{
+ struct block *b0;
+
+ if (linktype != DLT_PFLOG) {
+ bpf_error("reason supported only on PF linktype");
+ /* NOTREACHED */
+ }
+
+ b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, reason), BPF_B,
+ (bpf_int32)reason);
+ return (b0);
+}
+
+/* PF firewall log action */
+struct block *
+gen_pf_action(int action)
+{
+ struct block *b0;
+
+ if (linktype != DLT_PFLOG) {
+ bpf_error("action supported only on PF linktype");
+ /* NOTREACHED */
+ }
+
+ b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, action), BPF_B,
+ (bpf_int32)action);
+ return (b0);
+}
+#else /* !HAVE_NET_PFVAR_H */
+struct block *
+gen_pf_ifname(const char *ifname)
+{
+ bpf_error("libpcap was compiled without pf support");
+ /* NOTREACHED */
+ return (NULL);
+}
+
+struct block *
+gen_pf_ruleset(char *ruleset)
+{
+ bpf_error("libpcap was compiled on a machine without pf support");
+ /* NOTREACHED */
+ return (NULL);
+}
+
+struct block *
+gen_pf_rnr(int rnr)
+{
+ bpf_error("libpcap was compiled on a machine without pf support");
+ /* NOTREACHED */
+ return (NULL);
+}
+
+struct block *
+gen_pf_srnr(int srnr)
+{
+ bpf_error("libpcap was compiled on a machine without pf support");
+ /* NOTREACHED */
+ return (NULL);
+}
+
+struct block *
+gen_pf_reason(int reason)
+{
+ bpf_error("libpcap was compiled on a machine without pf support");
+ /* NOTREACHED */
+ return (NULL);
+}
+
+struct block *
+gen_pf_action(int action)
+{
+ bpf_error("libpcap was compiled on a machine without pf support");
+ /* NOTREACHED */
+ return (NULL);
+}
+#endif /* HAVE_NET_PFVAR_H */
+
+/* IEEE 802.11 wireless header */
+struct block *
+gen_p80211_type(int type, int mask)
+{
+ struct block *b0;
+
+ switch (linktype) {
+
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ b0 = gen_mcmp(OR_LINK, 0, BPF_B, (bpf_int32)type,
+ (bpf_int32)mask);
+ break;
+
+ default:
+ bpf_error("802.11 link-layer types supported only on 802.11");
+ /* NOTREACHED */
+ }
+
+ return (b0);
+}
+
+struct block *
+gen_p80211_fcdir(int fcdir)
+{
+ struct block *b0;
+
+ switch (linktype) {
+
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ break;
+
+ default:
+ bpf_error("frame direction supported only with 802.11 headers");
+ /* NOTREACHED */
+ }
+
+ b0 = gen_mcmp(OR_LINK, 1, BPF_B, (bpf_int32)fcdir,
+ (bpf_u_int32)IEEE80211_FC1_DIR_MASK);
+
+ return (b0);
+}
+
+struct block *
+gen_acode(eaddr, q)
+ register const u_char *eaddr;
+ struct qual q;
+{
+ switch (linktype) {
+
+ case DLT_ARCNET:
+ case DLT_ARCNET_LINUX:
+ if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) &&
+ q.proto == Q_LINK)
+ return (gen_ahostop(eaddr, (int)q.dir));
+ else {
+ bpf_error("ARCnet address used in non-arc expression");
+ /* NOTREACHED */
+ }
+ break;
+
+ default:
+ bpf_error("aid supported only on ARCnet");
+ /* NOTREACHED */
+ }
+ bpf_error("ARCnet address used in non-arc expression");
+ /* NOTREACHED */
+ return NULL;
+}
+
+static struct block *
+gen_ahostop(eaddr, dir)
+ register const u_char *eaddr;
+ register int dir;
+{
+ register struct block *b0, *b1;
+
+ switch (dir) {
+ /* src comes first, different from Ethernet */
+ case Q_SRC:
+ return gen_bcmp(OR_LINK, 0, 1, eaddr);
+
+ case Q_DST:
+ return gen_bcmp(OR_LINK, 1, 1, eaddr);
+
+ case Q_AND:
+ b0 = gen_ahostop(eaddr, Q_SRC);
+ b1 = gen_ahostop(eaddr, Q_DST);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_DEFAULT:
+ case Q_OR:
+ b0 = gen_ahostop(eaddr, Q_SRC);
+ b1 = gen_ahostop(eaddr, Q_DST);
+ gen_or(b0, b1);
+ return b1;
+
+ case Q_ADDR1:
+ bpf_error("'addr1' is only supported on 802.11");
+ break;
+
+ case Q_ADDR2:
+ bpf_error("'addr2' is only supported on 802.11");
+ break;
+
+ case Q_ADDR3:
+ bpf_error("'addr3' is only supported on 802.11");
+ break;
+
+ case Q_ADDR4:
+ bpf_error("'addr4' is only supported on 802.11");
+ break;
+
+ case Q_RA:
+ bpf_error("'ra' is only supported on 802.11");
+ break;
+
+ case Q_TA:
+ bpf_error("'ta' is only supported on 802.11");
+ break;
+ }
+ abort();
+ /* NOTREACHED */
+}
+
+/*
+ * support IEEE 802.1Q VLAN trunk over ethernet
+ */
+struct block *
+gen_vlan(vlan_num)
+ int vlan_num;
+{
+ struct block *b0, *b1;
+
+ /* can't check for VLAN-encapsulated packets inside MPLS */
+ if (label_stack_depth > 0)
+ bpf_error("no VLAN match after MPLS");
+
+ /*
+ * Check for a VLAN packet, and then change the offsets to point
+ * to the type and data fields within the VLAN packet. Just
+ * increment the offsets, so that we can support a hierarchy, e.g.
+ * "vlan 300 && vlan 200" to capture VLAN 200 encapsulated within
+ * VLAN 100.
+ *
+ * XXX - this is a bit of a kludge. If we were to split the
+ * compiler into a parser that parses an expression and
+ * generates an expression tree, and a code generator that
+ * takes an expression tree (which could come from our
+ * parser or from some other parser) and generates BPF code,
+ * we could perhaps make the offsets parameters of routines
+ * and, in the handler for an "AND" node, pass to subnodes
+ * other than the VLAN node the adjusted offsets.
+ *
+ * This would mean that "vlan" would, instead of changing the
+ * behavior of *all* tests after it, change only the behavior
+ * of tests ANDed with it. That would change the documented
+ * semantics of "vlan", which might break some expressions.
+ * However, it would mean that "(vlan and ip) or ip" would check
+ * both for VLAN-encapsulated IP and IP-over-Ethernet, rather than
+ * checking only for VLAN-encapsulated IP, so that could still
+ * be considered worth doing; it wouldn't break expressions
+ * that are of the form "vlan and ..." or "vlan N and ...",
+ * which I suspect are the most common expressions involving
+ * "vlan". "vlan or ..." doesn't necessarily do what the user
+ * would really want, now, as all the "or ..." tests would
+ * be done assuming a VLAN, even though the "or" could be viewed
+ * as meaning "or, if this isn't a VLAN packet...".
+ */
+ orig_nl = off_nl;
+
+ switch (linktype) {
+
+ case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
+ /* check for VLAN, including QinQ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
+ (bpf_int32)ETHERTYPE_8021Q);
+ b1 = gen_cmp(OR_LINK, off_linktype, BPF_H,
+ (bpf_int32)ETHERTYPE_8021QINQ);
+ gen_or(b0,b1);
+ b0 = b1;
+
+ /* If a specific VLAN is requested, check VLAN id */
+ if (vlan_num >= 0) {
+ b1 = gen_mcmp(OR_MACPL, 0, BPF_H,
+ (bpf_int32)vlan_num, 0x0fff);
+ gen_and(b0, b1);
+ b0 = b1;
+ }
+
+ off_macpl += 4;
+ off_linktype += 4;
+#if 0
+ off_nl_nosnap += 4;
+ off_nl += 4;
+#endif
+ break;
+
+ default:
+ bpf_error("no VLAN support for data link type %d",
+ linktype);
+ /*NOTREACHED*/
+ }
+
+ return (b0);
+}
+
+/*
+ * support for MPLS
+ */
+struct block *
+gen_mpls(label_num)
+ int label_num;
+{
+ struct block *b0,*b1;
+
+ /*
+ * Change the offsets to point to the type and data fields within
+ * the MPLS packet. Just increment the offsets, so that we
+ * can support a hierarchy, e.g. "mpls 100000 && mpls 1024" to
+ * capture packets with an outer label of 100000 and an inner
+ * label of 1024.
+ *
+ * XXX - this is a bit of a kludge. See comments in gen_vlan().
+ */
+ orig_nl = off_nl;
+
+ if (label_stack_depth > 0) {
+ /* just match the bottom-of-stack bit clear */
+ b0 = gen_mcmp(OR_MACPL, orig_nl-2, BPF_B, 0, 0x01);
+ } else {
+ /*
+ * Indicate that we're checking MPLS-encapsulated headers,
+ * to make sure higher level code generators don't try to
+ * match against IP-related protocols such as Q_ARP, Q_RARP
+ * etc.
+ */
+ switch (linktype) {
+
+ case DLT_C_HDLC: /* fall through */
+ case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
+ b0 = gen_linktype(ETHERTYPE_MPLS);
+ break;
+
+ case DLT_PPP:
+ b0 = gen_linktype(PPP_MPLS_UCAST);
+ break;
+
+ /* FIXME add other DLT_s ...
+ * for Frame-Relay/and ATM this may get messy due to SNAP headers
+ * leave it for now */
+
+ default:
+ bpf_error("no MPLS support for data link type %d",
+ linktype);
+ b0 = NULL;
+ /*NOTREACHED*/
+ break;
+ }
+ }
+
+ /* If a specific MPLS label is requested, check it */
+ if (label_num >= 0) {
+ label_num = label_num << 12; /* label is shifted 12 bits on the wire */
+ b1 = gen_mcmp(OR_MACPL, orig_nl, BPF_W, (bpf_int32)label_num,
+ 0xfffff000); /* only compare the first 20 bits */
+ gen_and(b0, b1);
+ b0 = b1;
+ }
+
+ off_nl_nosnap += 4;
+ off_nl += 4;
+ label_stack_depth++;
+ return (b0);
+}
+
+/*
+ * Support PPPOE discovery and session.
+ */
+struct block *
+gen_pppoed()
+{
+ /* check for PPPoE discovery */
+ return gen_linktype((bpf_int32)ETHERTYPE_PPPOED);
+}
+
+struct block *
+gen_pppoes()
+{
+ struct block *b0;
+
+ /*
+ * Test against the PPPoE session link-layer type.
+ */
+ b0 = gen_linktype((bpf_int32)ETHERTYPE_PPPOES);
+
+ /*
+ * Change the offsets to point to the type and data fields within
+ * the PPP packet, and note that this is PPPoE rather than
+ * raw PPP.
+ *
+ * XXX - this is a bit of a kludge. If we were to split the
+ * compiler into a parser that parses an expression and
+ * generates an expression tree, and a code generator that
+ * takes an expression tree (which could come from our
+ * parser or from some other parser) and generates BPF code,
+ * we could perhaps make the offsets parameters of routines
+ * and, in the handler for an "AND" node, pass to subnodes
+ * other than the PPPoE node the adjusted offsets.
+ *
+ * This would mean that "pppoes" would, instead of changing the
+ * behavior of *all* tests after it, change only the behavior
+ * of tests ANDed with it. That would change the documented
+ * semantics of "pppoes", which might break some expressions.
+ * However, it would mean that "(pppoes and ip) or ip" would check
+ * both for VLAN-encapsulated IP and IP-over-Ethernet, rather than
+ * checking only for VLAN-encapsulated IP, so that could still
+ * be considered worth doing; it wouldn't break expressions
+ * that are of the form "pppoes and ..." which I suspect are the
+ * most common expressions involving "pppoes". "pppoes or ..."
+ * doesn't necessarily do what the user would really want, now,
+ * as all the "or ..." tests would be done assuming PPPoE, even
+ * though the "or" could be viewed as meaning "or, if this isn't
+ * a PPPoE packet...".
+ */
+ orig_linktype = off_linktype; /* save original values */
+ orig_nl = off_nl;
+ is_pppoes = 1;
+
+ /*
+ * The "network-layer" protocol is PPPoE, which has a 6-byte
+ * PPPoE header, followed by a PPP packet.
+ *
+ * There is no HDLC encapsulation for the PPP packet (it's
+ * encapsulated in PPPoES instead), so the link-layer type
+ * starts at the first byte of the PPP packet. For PPPoE,
+ * that offset is relative to the beginning of the total
+ * link-layer payload, including any 802.2 LLC header, so
+ * it's 6 bytes past off_nl.
+ */
+ off_linktype = off_nl + 6;
+
+ /*
+ * The network-layer offsets are relative to the beginning
+ * of the MAC-layer payload; that's past the 6-byte
+ * PPPoE header and the 2-byte PPP header.
+ */
+ off_nl = 6+2;
+ off_nl_nosnap = 6+2;
+
+ return b0;
+}
+
+struct block *
+gen_atmfield_code(atmfield, jvalue, jtype, reverse)
+ int atmfield;
+ bpf_int32 jvalue;
+ bpf_u_int32 jtype;
+ int reverse;
+{
+ struct block *b0;
+
+ switch (atmfield) {
+
+ case A_VPI:
+ if (!is_atm)
+ bpf_error("'vpi' supported only on raw ATM");
+ if (off_vpi == (u_int)-1)
+ abort();
+ b0 = gen_ncmp(OR_LINK, off_vpi, BPF_B, 0xffffffff, jtype,
+ reverse, jvalue);
+ break;
+
+ case A_VCI:
+ if (!is_atm)
+ bpf_error("'vci' supported only on raw ATM");
+ if (off_vci == (u_int)-1)
+ abort();
+ b0 = gen_ncmp(OR_LINK, off_vci, BPF_H, 0xffffffff, jtype,
+ reverse, jvalue);
+ break;
+
+ case A_PROTOTYPE:
+ if (off_proto == (u_int)-1)
+ abort(); /* XXX - this isn't on FreeBSD */
+ b0 = gen_ncmp(OR_LINK, off_proto, BPF_B, 0x0f, jtype,
+ reverse, jvalue);
+ break;
+
+ case A_MSGTYPE:
+ if (off_payload == (u_int)-1)
+ abort();
+ b0 = gen_ncmp(OR_LINK, off_payload + MSG_TYPE_POS, BPF_B,
+ 0xffffffff, jtype, reverse, jvalue);
+ break;
+
+ case A_CALLREFTYPE:
+ if (!is_atm)
+ bpf_error("'callref' supported only on raw ATM");
+ if (off_proto == (u_int)-1)
+ abort();
+ b0 = gen_ncmp(OR_LINK, off_proto, BPF_B, 0xffffffff,
+ jtype, reverse, jvalue);
+ break;
+
+ default:
+ abort();
+ }
+ return b0;
+}
+
+struct block *
+gen_atmtype_abbrev(type)
+ int type;
+{
+ struct block *b0, *b1;
+
+ switch (type) {
+
+ case A_METAC:
+ /* Get all packets in Meta signalling Circuit */
+ if (!is_atm)
+ bpf_error("'metac' supported only on raw ATM");
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 1, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_BCC:
+ /* Get all packets in Broadcast Circuit*/
+ if (!is_atm)
+ bpf_error("'bcc' supported only on raw ATM");
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 2, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_OAMF4SC:
+ /* Get all cells in Segment OAM F4 circuit*/
+ if (!is_atm)
+ bpf_error("'oam4sc' supported only on raw ATM");
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 3, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_OAMF4EC:
+ /* Get all cells in End-to-End OAM F4 Circuit*/
+ if (!is_atm)
+ bpf_error("'oam4ec' supported only on raw ATM");
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 4, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_SC:
+ /* Get all packets in connection Signalling Circuit */
+ if (!is_atm)
+ bpf_error("'sc' supported only on raw ATM");
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 5, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_ILMIC:
+ /* Get all packets in ILMI Circuit */
+ if (!is_atm)
+ bpf_error("'ilmic' supported only on raw ATM");
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 16, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_LANE:
+ /* Get all LANE packets */
+ if (!is_atm)
+ bpf_error("'lane' supported only on raw ATM");
+ b1 = gen_atmfield_code(A_PROTOTYPE, PT_LANE, BPF_JEQ, 0);
+
+ /*
+ * Arrange that all subsequent tests assume LANE
+ * rather than LLC-encapsulated packets, and set
+ * the offsets appropriately for LANE-encapsulated
+ * Ethernet.
+ *
+ * "off_mac" is the offset of the Ethernet header,
+ * which is 2 bytes past the ATM pseudo-header
+ * (skipping the pseudo-header and 2-byte LE Client
+ * field). The other offsets are Ethernet offsets
+ * relative to "off_mac".
+ */
+ is_lane = 1;
+ off_mac = off_payload + 2; /* MAC header */
+ off_linktype = off_mac + 12;
+ off_macpl = off_mac + 14; /* Ethernet */
+ off_nl = 0; /* Ethernet II */
+ off_nl_nosnap = 3; /* 802.3+802.2 */
+ break;
+
+ case A_LLC:
+ /* Get all LLC-encapsulated packets */
+ if (!is_atm)
+ bpf_error("'llc' supported only on raw ATM");
+ b1 = gen_atmfield_code(A_PROTOTYPE, PT_LLC, BPF_JEQ, 0);
+ is_lane = 0;
+ break;
+
+ default:
+ abort();
+ }
+ return b1;
+}
+
+/*
+ * Filtering for MTP2 messages based on li value
+ * FISU, length is null
+ * LSSU, length is 1 or 2
+ * MSU, length is 3 or more
+ */
+struct block *
+gen_mtp2type_abbrev(type)
+ int type;
+{
+ struct block *b0, *b1;
+
+ switch (type) {
+
+ case M_FISU:
+ if ( (linktype != DLT_MTP2) &&
+ (linktype != DLT_ERF) &&
+ (linktype != DLT_MTP2_WITH_PHDR) )
+ bpf_error("'fisu' supported only on MTP2");
+ /* gen_ncmp(offrel, offset, size, mask, jtype, reverse, value) */
+ b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JEQ, 0, 0);
+ break;
+
+ case M_LSSU:
+ if ( (linktype != DLT_MTP2) &&
+ (linktype != DLT_ERF) &&
+ (linktype != DLT_MTP2_WITH_PHDR) )
+ bpf_error("'lssu' supported only on MTP2");
+ b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 1, 2);
+ b1 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 0, 0);
+ gen_and(b1, b0);
+ break;
+
+ case M_MSU:
+ if ( (linktype != DLT_MTP2) &&
+ (linktype != DLT_ERF) &&
+ (linktype != DLT_MTP2_WITH_PHDR) )
+ bpf_error("'msu' supported only on MTP2");
+ b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 0, 2);
+ break;
+
+ default:
+ abort();
+ }
+ return b0;
+}
+
+struct block *
+gen_mtp3field_code(mtp3field, jvalue, jtype, reverse)
+ int mtp3field;
+ bpf_u_int32 jvalue;
+ bpf_u_int32 jtype;
+ int reverse;
+{
+ struct block *b0;
+ bpf_u_int32 val1 , val2 , val3;
+
+ switch (mtp3field) {
+
+ case M_SIO:
+ if (off_sio == (u_int)-1)
+ bpf_error("'sio' supported only on SS7");
+ /* sio coded on 1 byte so max value 255 */
+ if(jvalue > 255)
+ bpf_error("sio value %u too big; max value = 255",
+ jvalue);
+ b0 = gen_ncmp(OR_PACKET, off_sio, BPF_B, 0xffffffff,
+ (u_int)jtype, reverse, (u_int)jvalue);
+ break;
+
+ case M_OPC:
+ if (off_opc == (u_int)-1)
+ bpf_error("'opc' supported only on SS7");
+ /* opc coded on 14 bits so max value 16383 */
+ if (jvalue > 16383)
+ bpf_error("opc value %u too big; max value = 16383",
+ jvalue);
+ /* the following instructions are made to convert jvalue
+ * to the form used to write opc in an ss7 message*/
+ val1 = jvalue & 0x00003c00;
+ val1 = val1 >>10;
+ val2 = jvalue & 0x000003fc;
+ val2 = val2 <<6;
+ val3 = jvalue & 0x00000003;
+ val3 = val3 <<22;
+ jvalue = val1 + val2 + val3;
+ b0 = gen_ncmp(OR_PACKET, off_opc, BPF_W, 0x00c0ff0f,
+ (u_int)jtype, reverse, (u_int)jvalue);
+ break;
+
+ case M_DPC:
+ if (off_dpc == (u_int)-1)
+ bpf_error("'dpc' supported only on SS7");
+ /* dpc coded on 14 bits so max value 16383 */
+ if (jvalue > 16383)
+ bpf_error("dpc value %u too big; max value = 16383",
+ jvalue);
+ /* the following instructions are made to convert jvalue
+ * to the forme used to write dpc in an ss7 message*/
+ val1 = jvalue & 0x000000ff;
+ val1 = val1 << 24;
+ val2 = jvalue & 0x00003f00;
+ val2 = val2 << 8;
+ jvalue = val1 + val2;
+ b0 = gen_ncmp(OR_PACKET, off_dpc, BPF_W, 0xff3f0000,
+ (u_int)jtype, reverse, (u_int)jvalue);
+ break;
+
+ case M_SLS:
+ if (off_sls == (u_int)-1)
+ bpf_error("'sls' supported only on SS7");
+ /* sls coded on 4 bits so max value 15 */
+ if (jvalue > 15)
+ bpf_error("sls value %u too big; max value = 15",
+ jvalue);
+ /* the following instruction is made to convert jvalue
+ * to the forme used to write sls in an ss7 message*/
+ jvalue = jvalue << 4;
+ b0 = gen_ncmp(OR_PACKET, off_sls, BPF_B, 0xf0,
+ (u_int)jtype,reverse, (u_int)jvalue);
+ break;
+
+ default:
+ abort();
+ }
+ return b0;
+}
+
+static struct block *
+gen_msg_abbrev(type)
+ int type;
+{
+ struct block *b1;
+
+ /*
+ * Q.2931 signalling protocol messages for handling virtual circuits
+ * establishment and teardown
+ */
+ switch (type) {
+
+ case A_SETUP:
+ b1 = gen_atmfield_code(A_MSGTYPE, SETUP, BPF_JEQ, 0);
+ break;
+
+ case A_CALLPROCEED:
+ b1 = gen_atmfield_code(A_MSGTYPE, CALL_PROCEED, BPF_JEQ, 0);
+ break;
+
+ case A_CONNECT:
+ b1 = gen_atmfield_code(A_MSGTYPE, CONNECT, BPF_JEQ, 0);
+ break;
+
+ case A_CONNECTACK:
+ b1 = gen_atmfield_code(A_MSGTYPE, CONNECT_ACK, BPF_JEQ, 0);
+ break;
+
+ case A_RELEASE:
+ b1 = gen_atmfield_code(A_MSGTYPE, RELEASE, BPF_JEQ, 0);
+ break;
+
+ case A_RELEASE_DONE:
+ b1 = gen_atmfield_code(A_MSGTYPE, RELEASE_DONE, BPF_JEQ, 0);
+ break;
+
+ default:
+ abort();
+ }
+ return b1;
+}
+
+struct block *
+gen_atmmulti_abbrev(type)
+ int type;
+{
+ struct block *b0, *b1;
+
+ switch (type) {
+
+ case A_OAM:
+ if (!is_atm)
+ bpf_error("'oam' supported only on raw ATM");
+ b1 = gen_atmmulti_abbrev(A_OAMF4);
+ break;
+
+ case A_OAMF4:
+ if (!is_atm)
+ bpf_error("'oamf4' supported only on raw ATM");
+ /* OAM F4 type */
+ b0 = gen_atmfield_code(A_VCI, 3, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 4, BPF_JEQ, 0);
+ gen_or(b0, b1);
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_CONNECTMSG:
+ /*
+ * Get Q.2931 signalling messages for switched
+ * virtual connection
+ */
+ if (!is_atm)
+ bpf_error("'connectmsg' supported only on raw ATM");
+ b0 = gen_msg_abbrev(A_SETUP);
+ b1 = gen_msg_abbrev(A_CALLPROCEED);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_CONNECT);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_CONNECTACK);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_RELEASE);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_RELEASE_DONE);
+ gen_or(b0, b1);
+ b0 = gen_atmtype_abbrev(A_SC);
+ gen_and(b0, b1);
+ break;
+
+ case A_METACONNECT:
+ if (!is_atm)
+ bpf_error("'metaconnect' supported only on raw ATM");
+ b0 = gen_msg_abbrev(A_SETUP);
+ b1 = gen_msg_abbrev(A_CALLPROCEED);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_CONNECT);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_RELEASE);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_RELEASE_DONE);
+ gen_or(b0, b1);
+ b0 = gen_atmtype_abbrev(A_METAC);
+ gen_and(b0, b1);
+ break;
+
+ default:
+ abort();
+ }
+ return b1;
+}
diff --git a/freebsd/contrib/libpcap/gencode.h b/freebsd/contrib/libpcap/gencode.h
new file mode 100644
index 00000000..29d2d10f
--- /dev/null
+++ b/freebsd/contrib/libpcap/gencode.h
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.71 2007-11-18 02:03:52 guy Exp $ (LBL)
+ */
+
+/*
+ * ATM support:
+ *
+ * Copyright (c) 1997 Yen Yen Lim and North Dakota State University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Yen Yen Lim and
+ * North Dakota State University
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HAVE___ATTRIBUTE__
+#define __attribute__(x)
+#endif /* HAVE___ATTRIBUTE__ */
+
+/* Address qualifiers. */
+
+#define Q_HOST 1
+#define Q_NET 2
+#define Q_PORT 3
+#define Q_GATEWAY 4
+#define Q_PROTO 5
+#define Q_PROTOCHAIN 6
+#define Q_PORTRANGE 7
+
+/* Protocol qualifiers. */
+
+#define Q_LINK 1
+#define Q_IP 2
+#define Q_ARP 3
+#define Q_RARP 4
+#define Q_SCTP 5
+#define Q_TCP 6
+#define Q_UDP 7
+#define Q_ICMP 8
+#define Q_IGMP 9
+#define Q_IGRP 10
+
+
+#define Q_ATALK 11
+#define Q_DECNET 12
+#define Q_LAT 13
+#define Q_SCA 14
+#define Q_MOPRC 15
+#define Q_MOPDL 16
+
+
+#define Q_IPV6 17
+#define Q_ICMPV6 18
+#define Q_AH 19
+#define Q_ESP 20
+
+#define Q_PIM 21
+#define Q_VRRP 22
+
+#define Q_AARP 23
+
+#define Q_ISO 24
+#define Q_ESIS 25
+#define Q_ISIS 26
+#define Q_CLNP 27
+
+#define Q_STP 28
+
+#define Q_IPX 29
+
+#define Q_NETBEUI 30
+
+/* IS-IS Levels */
+#define Q_ISIS_L1 31
+#define Q_ISIS_L2 32
+/* PDU types */
+#define Q_ISIS_IIH 33
+#define Q_ISIS_LAN_IIH 34
+#define Q_ISIS_PTP_IIH 35
+#define Q_ISIS_SNP 36
+#define Q_ISIS_CSNP 37
+#define Q_ISIS_PSNP 38
+#define Q_ISIS_LSP 39
+
+#define Q_RADIO 40
+
+#define Q_CARP 41
+
+/* Directional qualifiers. */
+
+#define Q_SRC 1
+#define Q_DST 2
+#define Q_OR 3
+#define Q_AND 4
+#define Q_ADDR1 5
+#define Q_ADDR2 6
+#define Q_ADDR3 7
+#define Q_ADDR4 8
+#define Q_RA 9
+#define Q_TA 10
+
+#define Q_DEFAULT 0
+#define Q_UNDEF 255
+
+/* ATM types */
+#define A_METAC 22 /* Meta signalling Circuit */
+#define A_BCC 23 /* Broadcast Circuit */
+#define A_OAMF4SC 24 /* Segment OAM F4 Circuit */
+#define A_OAMF4EC 25 /* End-to-End OAM F4 Circuit */
+#define A_SC 26 /* Signalling Circuit*/
+#define A_ILMIC 27 /* ILMI Circuit */
+#define A_OAM 28 /* OAM cells : F4 only */
+#define A_OAMF4 29 /* OAM F4 cells: Segment + End-to-end */
+#define A_LANE 30 /* LANE traffic */
+#define A_LLC 31 /* LLC-encapsulated traffic */
+
+/* Based on Q.2931 signalling protocol */
+#define A_SETUP 41 /* Setup message */
+#define A_CALLPROCEED 42 /* Call proceeding message */
+#define A_CONNECT 43 /* Connect message */
+#define A_CONNECTACK 44 /* Connect Ack message */
+#define A_RELEASE 45 /* Release message */
+#define A_RELEASE_DONE 46 /* Release message */
+
+/* ATM field types */
+#define A_VPI 51
+#define A_VCI 52
+#define A_PROTOTYPE 53
+#define A_MSGTYPE 54
+#define A_CALLREFTYPE 55
+
+#define A_CONNECTMSG 70 /* returns Q.2931 signalling messages for
+ establishing and destroying switched
+ virtual connection */
+#define A_METACONNECT 71 /* returns Q.2931 signalling messages for
+ establishing and destroying predefined
+ virtual circuits, such as broadcast
+ circuit, oamf4 segment circuit, oamf4
+ end-to-end circuits, ILMI circuits or
+ connection signalling circuit. */
+
+/* MTP2 types */
+#define M_FISU 22 /* FISU */
+#define M_LSSU 23 /* LSSU */
+#define M_MSU 24 /* MSU */
+
+/* MTP3 field types */
+#define M_SIO 1
+#define M_OPC 2
+#define M_DPC 3
+#define M_SLS 4
+
+
+struct slist;
+
+struct stmt {
+ int code;
+ struct slist *jt; /*only for relative jump in block*/
+ struct slist *jf; /*only for relative jump in block*/
+ bpf_int32 k;
+};
+
+struct slist {
+ struct stmt s;
+ struct slist *next;
+};
+
+/*
+ * A bit vector to represent definition sets. We assume TOT_REGISTERS
+ * is smaller than 8*sizeof(atomset).
+ */
+typedef bpf_u_int32 atomset;
+#define ATOMMASK(n) (1 << (n))
+#define ATOMELEM(d, n) (d & ATOMMASK(n))
+
+/*
+ * An unbounded set.
+ */
+typedef bpf_u_int32 *uset;
+
+/*
+ * Total number of atomic entities, including accumulator (A) and index (X).
+ * We treat all these guys similarly during flow analysis.
+ */
+#define N_ATOMS (BPF_MEMWORDS+2)
+
+struct edge {
+ int id;
+ int code;
+ uset edom;
+ struct block *succ;
+ struct block *pred;
+ struct edge *next; /* link list of incoming edges for a node */
+};
+
+struct block {
+ int id;
+ struct slist *stmts; /* side effect stmts */
+ struct stmt s; /* branch stmt */
+ int mark;
+ u_int longjt; /* jt branch requires long jump */
+ u_int longjf; /* jf branch requires long jump */
+ int level;
+ int offset;
+ int sense;
+ struct edge et;
+ struct edge ef;
+ struct block *head;
+ struct block *link; /* link field used by optimizer */
+ uset dom;
+ uset closure;
+ struct edge *in_edges;
+ atomset def, kill;
+ atomset in_use;
+ atomset out_use;
+ int oval;
+ int val[N_ATOMS];
+};
+
+struct arth {
+ struct block *b; /* protocol checks */
+ struct slist *s; /* stmt list */
+ int regno; /* virtual register number of result */
+};
+
+struct qual {
+ unsigned char addr;
+ unsigned char proto;
+ unsigned char dir;
+ unsigned char pad;
+};
+
+struct arth *gen_loadi(int);
+struct arth *gen_load(int, struct arth *, int);
+struct arth *gen_loadlen(void);
+struct arth *gen_neg(struct arth *);
+struct arth *gen_arth(int, struct arth *, struct arth *);
+
+void gen_and(struct block *, struct block *);
+void gen_or(struct block *, struct block *);
+void gen_not(struct block *);
+
+struct block *gen_scode(const char *, struct qual);
+struct block *gen_ecode(const u_char *, struct qual);
+struct block *gen_acode(const u_char *, struct qual);
+struct block *gen_mcode(const char *, const char *, int, struct qual);
+#ifdef INET6
+struct block *gen_mcode6(const char *, const char *, int, struct qual);
+#endif
+struct block *gen_ncode(const char *, bpf_u_int32, struct qual);
+struct block *gen_proto_abbrev(int);
+struct block *gen_relation(int, struct arth *, struct arth *, int);
+struct block *gen_less(int);
+struct block *gen_greater(int);
+struct block *gen_byteop(int, int, int);
+struct block *gen_broadcast(int);
+struct block *gen_multicast(int);
+struct block *gen_inbound(int);
+
+struct block *gen_vlan(int);
+struct block *gen_mpls(int);
+
+struct block *gen_pppoed(void);
+struct block *gen_pppoes(void);
+
+struct block *gen_atmfield_code(int atmfield, bpf_int32 jvalue, bpf_u_int32 jtype, int reverse);
+struct block *gen_atmtype_abbrev(int type);
+struct block *gen_atmmulti_abbrev(int type);
+
+struct block *gen_mtp2type_abbrev(int type);
+struct block *gen_mtp3field_code(int mtp3field, bpf_u_int32 jvalue, bpf_u_int32 jtype, int reverse);
+
+struct block *gen_pf_ifname(const char *);
+struct block *gen_pf_rnr(int);
+struct block *gen_pf_srnr(int);
+struct block *gen_pf_ruleset(char *);
+struct block *gen_pf_reason(int);
+struct block *gen_pf_action(int);
+struct block *gen_pf_dir(int);
+
+struct block *gen_p80211_type(int, int);
+struct block *gen_p80211_fcdir(int);
+
+void bpf_optimize(struct block **);
+void bpf_error(const char *, ...)
+ __attribute__((noreturn, format (printf, 1, 2)));
+
+void finish_parse(struct block *);
+char *sdup(const char *);
+
+struct bpf_insn *icode_to_fcode(struct block *, u_int *);
+int pcap_parse(void);
+void lex_init(const char *);
+void lex_cleanup(void);
+void sappend(struct slist *, struct slist *);
+
+/* XXX */
+#define JT(b) ((b)->et.succ)
+#define JF(b) ((b)->ef.succ)
+
+extern int no_optimize;
diff --git a/freebsd/contrib/libpcap/grammar.c b/freebsd/contrib/libpcap/grammar.c
new file mode 100644
index 00000000..bfd9927a
--- /dev/null
+++ b/freebsd/contrib/libpcap/grammar.c
@@ -0,0 +1,2280 @@
+/* original parser id follows */
+/* yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93" */
+/* (use YYMAJOR/YYMINOR for ifdefs dependent on parser version) */
+
+#define YYBYACC 1
+#define YYMAJOR 1
+#define YYMINOR 9
+
+#define YYEMPTY (-1)
+#define yyclearin (yychar = YYEMPTY)
+#define yyerrok (yyerrflag = 0)
+#define YYRECOVERING() (yyerrflag != 0)
+#define YYENOMEM (-2)
+#define YYEOF 0
+
+#ifndef yyparse
+#define yyparse pcapparse
+#endif /* yyparse */
+
+#ifndef yylex
+#define yylex pcaplex
+#endif /* yylex */
+
+#ifndef yyerror
+#define yyerror pcaperror
+#endif /* yyerror */
+
+#ifndef yychar
+#define yychar pcapchar
+#endif /* yychar */
+
+#ifndef yyval
+#define yyval pcapval
+#endif /* yyval */
+
+#ifndef yylval
+#define yylval pcaplval
+#endif /* yylval */
+
+#ifndef yydebug
+#define yydebug pcapdebug
+#endif /* yydebug */
+
+#ifndef yynerrs
+#define yynerrs pcapnerrs
+#endif /* yynerrs */
+
+#ifndef yyerrflag
+#define yyerrflag pcaperrflag
+#endif /* yyerrflag */
+
+#ifndef yylhs
+#define yylhs pcaplhs
+#endif /* yylhs */
+
+#ifndef yylen
+#define yylen pcaplen
+#endif /* yylen */
+
+#ifndef yydefred
+#define yydefred pcapdefred
+#endif /* yydefred */
+
+#ifndef yydgoto
+#define yydgoto pcapdgoto
+#endif /* yydgoto */
+
+#ifndef yysindex
+#define yysindex pcapsindex
+#endif /* yysindex */
+
+#ifndef yyrindex
+#define yyrindex pcaprindex
+#endif /* yyrindex */
+
+#ifndef yygindex
+#define yygindex pcapgindex
+#endif /* yygindex */
+
+#ifndef yytable
+#define yytable pcaptable
+#endif /* yytable */
+
+#ifndef yycheck
+#define yycheck pcapcheck
+#endif /* yycheck */
+
+#ifndef yyname
+#define yyname pcapname
+#endif /* yyname */
+
+#ifndef yyrule
+#define yyrule pcaprule
+#endif /* yyrule */
+#define YYPREFIX "pcap"
+
+#define YYPURE 0
+
+#line 2 "../../freebsd/contrib/libpcap/grammar.y"
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.101 2007-11-18 02:03:52 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#include <sys/types.h>
+#include <sys/socket.h>
+#endif /* WIN32 */
+
+#include <stdlib.h>
+
+#ifndef WIN32
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif /* WIN32 */
+
+#include <stdio.h>
+
+#include "pcap-int.h"
+
+#include "gencode.h"
+#ifdef HAVE_NET_PFVAR_H
+#include <net/if.h>
+#include <net/pfvar.h>
+#include <net/if_pflog.h>
+#endif
+#include "ieee80211.h"
+#include <pcap/namedb.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#define QSET(q, p, d, a) (q).proto = (p),\
+ (q).dir = (d),\
+ (q).addr = (a)
+
+struct tok {
+ int v; /* value */
+ const char *s; /* string */
+};
+
+static const struct tok ieee80211_types[] = {
+ { IEEE80211_FC0_TYPE_DATA, "data" },
+ { IEEE80211_FC0_TYPE_MGT, "mgt" },
+ { IEEE80211_FC0_TYPE_MGT, "management" },
+ { IEEE80211_FC0_TYPE_CTL, "ctl" },
+ { IEEE80211_FC0_TYPE_CTL, "control" },
+ { 0, NULL }
+};
+static const struct tok ieee80211_mgt_subtypes[] = {
+ { IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assocreq" },
+ { IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assoc-req" },
+ { IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assocresp" },
+ { IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assoc-resp" },
+ { IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassocreq" },
+ { IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassoc-req" },
+ { IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassocresp" },
+ { IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassoc-resp" },
+ { IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probereq" },
+ { IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probe-req" },
+ { IEEE80211_FC0_SUBTYPE_PROBE_RESP, "proberesp" },
+ { IEEE80211_FC0_SUBTYPE_PROBE_RESP, "probe-resp" },
+ { IEEE80211_FC0_SUBTYPE_BEACON, "beacon" },
+ { IEEE80211_FC0_SUBTYPE_ATIM, "atim" },
+ { IEEE80211_FC0_SUBTYPE_DISASSOC, "disassoc" },
+ { IEEE80211_FC0_SUBTYPE_DISASSOC, "disassociation" },
+ { IEEE80211_FC0_SUBTYPE_AUTH, "auth" },
+ { IEEE80211_FC0_SUBTYPE_AUTH, "authentication" },
+ { IEEE80211_FC0_SUBTYPE_DEAUTH, "deauth" },
+ { IEEE80211_FC0_SUBTYPE_DEAUTH, "deauthentication" },
+ { 0, NULL }
+};
+static const struct tok ieee80211_ctl_subtypes[] = {
+ { IEEE80211_FC0_SUBTYPE_PS_POLL, "ps-poll" },
+ { IEEE80211_FC0_SUBTYPE_RTS, "rts" },
+ { IEEE80211_FC0_SUBTYPE_CTS, "cts" },
+ { IEEE80211_FC0_SUBTYPE_ACK, "ack" },
+ { IEEE80211_FC0_SUBTYPE_CF_END, "cf-end" },
+ { IEEE80211_FC0_SUBTYPE_CF_END_ACK, "cf-end-ack" },
+ { 0, NULL }
+};
+static const struct tok ieee80211_data_subtypes[] = {
+ { IEEE80211_FC0_SUBTYPE_DATA, "data" },
+ { IEEE80211_FC0_SUBTYPE_CF_ACK, "data-cf-ack" },
+ { IEEE80211_FC0_SUBTYPE_CF_POLL, "data-cf-poll" },
+ { IEEE80211_FC0_SUBTYPE_CF_ACPL, "data-cf-ack-poll" },
+ { IEEE80211_FC0_SUBTYPE_NODATA, "null" },
+ { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK, "cf-ack" },
+ { IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "cf-poll" },
+ { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "cf-ack-poll" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA, "qos-data" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK, "qos-data-cf-ack" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL, "qos-data-cf-poll" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL, "qos-data-cf-ack-poll" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA, "qos" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "qos-cf-poll" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "qos-cf-ack-poll" },
+ { 0, NULL }
+};
+struct type2tok {
+ int type;
+ const struct tok *tok;
+};
+static const struct type2tok ieee80211_type_subtypes[] = {
+ { IEEE80211_FC0_TYPE_MGT, ieee80211_mgt_subtypes },
+ { IEEE80211_FC0_TYPE_CTL, ieee80211_ctl_subtypes },
+ { IEEE80211_FC0_TYPE_DATA, ieee80211_data_subtypes },
+ { 0, NULL }
+};
+
+static int
+str2tok(const char *str, const struct tok *toks)
+{
+ int i;
+
+ for (i = 0; toks[i].s != NULL; i++) {
+ if (pcap_strcasecmp(toks[i].s, str) == 0)
+ return (toks[i].v);
+ }
+ return (-1);
+}
+
+int n_errors = 0;
+
+static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
+
+static void
+yyerror(const char *msg)
+{
+ ++n_errors;
+ bpf_error("%s", msg);
+ /* NOTREACHED */
+}
+
+#ifdef NEED_YYPARSE_WRAPPER
+int yyparse(void);
+
+int
+pcap_parse()
+{
+ return (yyparse());
+}
+#endif
+
+#ifdef HAVE_NET_PFVAR_H
+static int
+pfreason_to_num(const char *reason)
+{
+ const char *reasons[] = PFRES_NAMES;
+ int i;
+
+ for (i = 0; reasons[i]; i++) {
+ if (pcap_strcasecmp(reason, reasons[i]) == 0)
+ return (i);
+ }
+ bpf_error("unknown PF reason");
+ /*NOTREACHED*/
+}
+
+static int
+pfaction_to_num(const char *action)
+{
+ if (pcap_strcasecmp(action, "pass") == 0 ||
+ pcap_strcasecmp(action, "accept") == 0)
+ return (PF_PASS);
+ else if (pcap_strcasecmp(action, "drop") == 0 ||
+ pcap_strcasecmp(action, "block") == 0)
+ return (PF_DROP);
+#if HAVE_PF_NAT_THROUGH_PF_NORDR
+ else if (pcap_strcasecmp(action, "rdr") == 0)
+ return (PF_RDR);
+ else if (pcap_strcasecmp(action, "nat") == 0)
+ return (PF_NAT);
+ else if (pcap_strcasecmp(action, "binat") == 0)
+ return (PF_BINAT);
+ else if (pcap_strcasecmp(action, "nordr") == 0)
+ return (PF_NORDR);
+#endif
+ else {
+ bpf_error("unknown PF action");
+ /*NOTREACHED*/
+ }
+}
+#else /* !HAVE_NET_PFVAR_H */
+static int
+pfreason_to_num(const char *reason)
+{
+ bpf_error("libpcap was compiled on a machine without pf support");
+ /*NOTREACHED*/
+
+ /* this is to make the VC compiler happy */
+ return -1;
+}
+
+static int
+pfaction_to_num(const char *action)
+{
+ bpf_error("libpcap was compiled on a machine without pf support");
+ /*NOTREACHED*/
+
+ /* this is to make the VC compiler happy */
+ return -1;
+}
+#endif /* HAVE_NET_PFVAR_H */
+#line 243 "../../freebsd/contrib/libpcap/grammar.y"
+#ifdef YYSTYPE
+#undef YYSTYPE_IS_DECLARED
+#define YYSTYPE_IS_DECLARED 1
+#endif
+#ifndef YYSTYPE_IS_DECLARED
+#define YYSTYPE_IS_DECLARED 1
+typedef union {
+ int i;
+ bpf_u_int32 h;
+ u_char *e;
+ char *s;
+ struct stmt *stmt;
+ struct arth *a;
+ struct {
+ struct qual q;
+ int atmfieldtype;
+ int mtp3fieldtype;
+ struct block *b;
+ } blk;
+ struct block *rblk;
+} YYSTYPE;
+#endif /* !YYSTYPE_IS_DECLARED */
+#line 363 "pcap.tab.c"
+
+/* compatibility with bison */
+#ifdef YYPARSE_PARAM
+/* compatibility with FreeBSD */
+# ifdef YYPARSE_PARAM_TYPE
+# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)
+# else
+# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)
+# endif
+#else
+# define YYPARSE_DECL() yyparse(void)
+#endif
+
+/* Parameters sent to lex. */
+#ifdef YYLEX_PARAM
+# define YYLEX_DECL() yylex(void *YYLEX_PARAM)
+# define YYLEX yylex(YYLEX_PARAM)
+#else
+# define YYLEX_DECL() yylex(void)
+# define YYLEX yylex()
+#endif
+
+/* Parameters sent to yyerror. */
+#ifndef YYERROR_DECL
+#define YYERROR_DECL() yyerror(const char *s)
+#endif
+#ifndef YYERROR_CALL
+#define YYERROR_CALL(msg) yyerror(msg)
+#endif
+
+extern int YYPARSE_DECL();
+
+#define DST 257
+#define SRC 258
+#define HOST 259
+#define GATEWAY 260
+#define NET 261
+#define NETMASK 262
+#define PORT 263
+#define PORTRANGE 264
+#define LESS 265
+#define GREATER 266
+#define PROTO 267
+#define PROTOCHAIN 268
+#define CBYTE 269
+#define ARP 270
+#define RARP 271
+#define IP 272
+#define SCTP 273
+#define TCP 274
+#define UDP 275
+#define ICMP 276
+#define IGMP 277
+#define IGRP 278
+#define PIM 279
+#define VRRP 280
+#define CARP 281
+#define ATALK 282
+#define AARP 283
+#define DECNET 284
+#define LAT 285
+#define SCA 286
+#define MOPRC 287
+#define MOPDL 288
+#define TK_BROADCAST 289
+#define TK_MULTICAST 290
+#define NUM 291
+#define INBOUND 292
+#define OUTBOUND 293
+#define PF_IFNAME 294
+#define PF_RSET 295
+#define PF_RNR 296
+#define PF_SRNR 297
+#define PF_REASON 298
+#define PF_ACTION 299
+#define TYPE 300
+#define SUBTYPE 301
+#define DIR 302
+#define ADDR1 303
+#define ADDR2 304
+#define ADDR3 305
+#define ADDR4 306
+#define RA 307
+#define TA 308
+#define LINK 309
+#define GEQ 310
+#define LEQ 311
+#define NEQ 312
+#define ID 313
+#define EID 314
+#define HID 315
+#define HID6 316
+#define AID 317
+#define LSH 318
+#define RSH 319
+#define LEN 320
+#define IPV6 321
+#define ICMPV6 322
+#define AH 323
+#define ESP 324
+#define VLAN 325
+#define MPLS 326
+#define PPPOED 327
+#define PPPOES 328
+#define ISO 329
+#define ESIS 330
+#define CLNP 331
+#define ISIS 332
+#define L1 333
+#define L2 334
+#define IIH 335
+#define LSP 336
+#define SNP 337
+#define CSNP 338
+#define PSNP 339
+#define STP 340
+#define IPX 341
+#define NETBEUI 342
+#define LANE 343
+#define LLC 344
+#define METAC 345
+#define BCC 346
+#define SC 347
+#define ILMIC 348
+#define OAMF4EC 349
+#define OAMF4SC 350
+#define OAM 351
+#define OAMF4 352
+#define CONNECTMSG 353
+#define METACONNECT 354
+#define VPI 355
+#define VCI 356
+#define RADIO 357
+#define FISU 358
+#define LSSU 359
+#define MSU 360
+#define SIO 361
+#define OPC 362
+#define DPC 363
+#define SLS 364
+#define OR 365
+#define AND 366
+#define UMINUS 367
+#define YYERRCODE 256
+typedef short YYINT;
+static const YYINT pcaplhs[] = { -1,
+ 0, 0, 24, 1, 1, 1, 1, 1, 20, 21,
+ 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 23, 22, 4, 4, 4, 7, 7, 5,
+ 5, 8, 8, 8, 8, 8, 8, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 9, 9,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 11, 11, 11, 11, 12, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 26, 26, 26, 26, 26, 26, 27, 27, 27,
+ 27, 41, 41, 42, 42, 43, 44, 44, 40, 40,
+ 39, 18, 18, 18, 19, 19, 19, 13, 13, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 15, 15, 15, 15, 15, 17, 17, 28,
+ 28, 28, 28, 28, 28, 28, 28, 29, 29, 29,
+ 29, 30, 30, 32, 32, 32, 32, 31, 33, 33,
+ 34, 34, 34, 35, 35, 35, 35, 37, 37, 37,
+ 37, 36, 38, 38,
+};
+static const YYINT pcaplen[] = { 2,
+ 2, 1, 0, 1, 3, 3, 3, 3, 1, 1,
+ 1, 1, 3, 1, 3, 3, 1, 3, 1, 1,
+ 1, 2, 1, 1, 1, 3, 3, 1, 1, 1,
+ 2, 3, 2, 2, 2, 2, 2, 2, 3, 1,
+ 3, 3, 1, 1, 1, 2, 1, 2, 1, 0,
+ 1, 1, 3, 3, 3, 3, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
+ 4, 1, 1, 2, 1, 2, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 4, 2, 2,
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 4,
+ 6, 3, 3, 3, 3, 3, 3, 3, 3, 2,
+ 3, 1, 1, 1, 1, 1, 1, 1, 3, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 2, 2, 3, 1, 1, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+ 3, 1, 1, 3,
+};
+static const YYINT pcapdefred[] = { 3,
+ 0, 0, 0, 0, 0, 70, 71, 69, 72, 73,
+ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ 84, 85, 87, 86, 168, 112, 113, 0, 0, 0,
+ 0, 0, 0, 68, 162, 88, 89, 90, 91, 0,
+ 0, 118, 119, 92, 93, 102, 94, 95, 96, 97,
+ 98, 99, 101, 100, 103, 104, 105, 170, 171, 172,
+ 173, 176, 177, 174, 175, 178, 179, 180, 181, 182,
+ 183, 106, 191, 192, 193, 194, 195, 196, 197, 23,
+ 0, 24, 0, 4, 30, 0, 0, 0, 149, 0,
+ 148, 0, 0, 43, 120, 44, 45, 0, 47, 0,
+ 109, 110, 0, 122, 123, 124, 125, 139, 140, 126,
+ 141, 127, 114, 0, 116, 160, 0, 0, 10, 9,
+ 0, 0, 14, 20, 0, 0, 21, 38, 11, 12,
+ 0, 0, 0, 0, 63, 67, 64, 65, 66, 35,
+ 36, 107, 108, 0, 0, 0, 57, 58, 59, 60,
+ 61, 62, 0, 34, 37, 121, 143, 145, 147, 0,
+ 0, 0, 0, 0, 0, 0, 0, 142, 144, 146,
+ 0, 0, 0, 0, 0, 0, 31, 188, 0, 0,
+ 0, 184, 46, 202, 0, 0, 0, 198, 48, 164,
+ 163, 166, 167, 165, 0, 0, 0, 6, 5, 0,
+ 0, 0, 8, 7, 0, 0, 0, 25, 0, 0,
+ 0, 22, 0, 0, 0, 0, 132, 133, 0, 136,
+ 130, 137, 138, 131, 32, 0, 0, 0, 0, 0,
+ 0, 154, 155, 0, 0, 0, 39, 161, 169, 185,
+ 186, 189, 0, 199, 200, 203, 0, 111, 0, 16,
+ 15, 18, 13, 0, 0, 54, 56, 53, 55, 0,
+ 150, 0, 187, 0, 201, 0, 26, 27, 134, 135,
+ 128, 0, 190, 204, 151,
+};
+static const YYINT pcapdgoto[] = { 1,
+ 174, 212, 129, 209, 84, 85, 210, 86, 87, 153,
+ 154, 155, 88, 89, 195, 117, 91, 171, 172, 121,
+ 122, 118, 132, 2, 94, 95, 156, 96, 97, 98,
+ 182, 183, 243, 99, 100, 188, 189, 247, 112, 110,
+ 219, 271, 221, 224,
+};
+static const YYINT pcapsindex[] = { 0,
+ 0, 296, -268, -231, -223, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, -216, -204, -174,
+ -169, -284, -193, 0, 0, 0, 0, 0, 0, -40,
+ -40, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 396, 0, -334, 0, 0, -19, 611, 647, 0, 34,
+ 0, 296, 296, 0, 0, 0, 0, 42, 0, 651,
+ 0, 0, 96, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, -40, 0, 0, 34, 396, 0, 0,
+ 185, 185, 0, 0, -38, 88, 0, 0, 0, 0,
+ -19, -19, -236, -233, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, -258, -172, -251, 0, 0, 0, 0,
+ 0, 0, -85, 0, 0, 0, 0, 0, 0, 396,
+ 396, 396, 396, 396, 396, 396, 396, 0, 0, 0,
+ 396, 396, 396, -39, 113, 126, 0, 0, -122, -121,
+ -118, 0, 0, 0, -99, -98, -91, 0, 0, 0,
+ 0, 0, 0, 0, -86, 126, 236, 0, 0, 0,
+ 185, 185, 0, 0, -140, -84, -81, 0, 165, -334,
+ 126, 0, -42, -36, -34, -31, 0, 0, -82, 0,
+ 0, 0, 0, 0, 0, 170, 170, -8, 108, -23,
+ -23, 0, 0, 236, 236, 156, 0, 0, 0, 0,
+ 0, 0, -37, 0, 0, 0, -35, 0, 126, 0,
+ 0, 0, 0, -19, -19, 0, 0, 0, 0, -221,
+ 0, -70, 0, -118, 0, -91, 0, 0, 0, 0,
+ 0, 134, 0, 0, 0,
+};
+static const YYINT pcaprindex[] = { 0,
+ 0, 488, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,
+ 11, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 228, 0, 0, 0, 0, 0, 0, 1,
+ 0, 686, 686, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 686, 686, 0, 0, 16, 18, 0, 0, 0, 0,
+ 0, 0, -28, 520, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 132, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 725, 759, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 686, 686, 0, 0, 0, 0, 0, 0, -222, 0,
+ -205, 0, 0, 0, 0, 0, 0, 0, 20, 0,
+ 0, 0, 0, 0, 0, 28, 53, 87, 78, 13,
+ 38, 0, 0, 26, 36, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 121, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+};
+static const YYINT pcapgindex[] = { 0,
+ 227, -14, -116, 0, 2, 0, 0, 0, 0, 0,
+ 79, 0, 24, -75, 0, 116, 724, -73, 12, 29,
+ -163, 767, 722, 0, 0, 0, 0, 0, 0, 0,
+ -171, 0, 0, 0, 0, -165, 0, 0, 0, 0,
+ 0, 0, 0, 0,
+};
+#define YYTABLESIZE 1078
+static const YYINT pcaptable[] = { 82,
+ 40, 237, 12, 263, 52, 265, 108, 115, 206, 242,
+ 117, 52, 152, 80, 208, 17, 175, 19, 166, 129,
+ 82, 246, 101, 167, 179, 41, 185, 158, 109, 163,
+ 119, 120, 217, 166, 164, 42, 165, 153, 167, 222,
+ 148, 40, 175, 12, 148, 148, 255, 148, 115, 148,
+ 152, 117, 159, 152, 218, 152, 17, 152, 19, 102,
+ 129, 223, 148, 148, 148, 158, 41, 103, 158, 269,
+ 152, 128, 152, 152, 152, 153, 42, 156, 153, 264,
+ 153, 82, 153, 266, 208, 158, 157, 158, 158, 158,
+ 159, 270, 273, 159, 177, 153, 104, 153, 153, 153,
+ 274, 170, 169, 168, 116, 152, 198, 203, 105, 180,
+ 159, 186, 159, 159, 159, 156, 106, 90, 156, 111,
+ 158, 107, 199, 204, 173, 175, 148, 157, 213, 214,
+ 153, 215, 216, 191, 207, 156, 152, 156, 156, 156,
+ 220, 197, 29, 29, 157, 159, 157, 157, 157, 166,
+ 164, 158, 165, 238, 167, 194, 193, 192, 148, 28,
+ 28, 153, 148, 148, 33, 148, 239, 148, 240, 241,
+ 156, 33, 178, 135, 250, 137, 159, 138, 139, 157,
+ 148, 148, 148, 226, 227, 228, 229, 230, 231, 232,
+ 233, 244, 245, 163, 234, 235, 236, 166, 164, 184,
+ 165, 156, 167, 177, 248, 253, 251, 90, 90, 252,
+ 157, 166, 164, 262, 165, 256, 167, 80, 260, 190,
+ 272, 257, 258, 205, 82, 259, 275, 1, 83, 81,
+ 52, 225, 52, 0, 52, 52, 90, 90, 254, 267,
+ 268, 0, 0, 0, 148, 0, 0, 0, 261, 0,
+ 25, 0, 0, 0, 0, 0, 0, 49, 49, 49,
+ 49, 49, 52, 49, 49, 0, 0, 49, 49, 0,
+ 0, 25, 0, 163, 0, 0, 0, 166, 164, 162,
+ 165, 0, 167, 0, 52, 52, 52, 52, 52, 49,
+ 49, 0, 0, 123, 124, 125, 126, 127, 0, 0,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 160,
+ 161, 0, 148, 148, 148, 0, 90, 90, 0, 0,
+ 148, 148, 152, 152, 152, 119, 120, 119, 80, 119,
+ 152, 152, 178, 0, 0, 82, 0, 158, 158, 158,
+ 81, 0, 0, 0, 0, 158, 158, 153, 153, 153,
+ 0, 157, 158, 159, 0, 153, 153, 0, 0, 162,
+ 0, 0, 159, 159, 159, 40, 40, 12, 12, 0,
+ 159, 159, 115, 115, 0, 117, 117, 152, 152, 0,
+ 17, 17, 19, 19, 129, 129, 0, 156, 156, 156,
+ 41, 41, 158, 158, 0, 0, 157, 157, 157, 0,
+ 42, 42, 153, 153, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 159, 159, 0,
+ 0, 0, 33, 0, 0, 160, 161, 0, 0, 0,
+ 148, 148, 148, 0, 0, 82, 0, 0, 148, 148,
+ 81, 0, 156, 156, 33, 33, 33, 33, 33, 3,
+ 4, 157, 157, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 160, 161, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 0, 28, 28, 2, 0, 0,
+ 0, 0, 0, 34, 0, 0, 0, 123, 124, 125,
+ 126, 127, 0, 0, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ 71, 72, 73, 74, 75, 76, 77, 78, 79, 0,
+ 0, 0, 51, 160, 161, 0, 0, 0, 0, 51,
+ 3, 4, 0, 0, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 0, 0, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 34, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 0, 0, 0, 0, 0, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 163, 0, 25, 0, 166, 164,
+ 82, 165, 0, 167, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 34, 0, 170, 169, 168, 0,
+ 170, 169, 168, 0, 0, 35, 36, 37, 38, 39,
+ 0, 0, 0, 93, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 0, 0,
+ 0, 0, 0, 0, 50, 50, 50, 50, 50, 0,
+ 50, 50, 72, 0, 50, 50, 0, 0, 0, 0,
+ 0, 0, 149, 113, 115, 0, 149, 149, 92, 149,
+ 162, 149, 0, 0, 0, 0, 50, 50, 51, 0,
+ 51, 0, 51, 51, 149, 149, 149, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 148, 0, 0, 0,
+ 148, 148, 0, 148, 0, 148, 114, 114, 0, 130,
+ 51, 0, 0, 93, 93, 176, 0, 0, 148, 148,
+ 148, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 51, 51, 51, 51, 51, 196, 0, 0,
+ 0, 176, 202, 202, 200, 200, 0, 0, 149, 0,
+ 0, 0, 131, 0, 211, 130, 0, 0, 92, 92,
+ 0, 0, 0, 0, 181, 0, 187, 133, 134, 135,
+ 136, 137, 0, 138, 139, 0, 0, 140, 141, 0,
+ 114, 0, 148, 0, 0, 0, 0, 201, 201, 0,
+ 0, 0, 0, 0, 0, 0, 0, 114, 131, 142,
+ 143, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 144, 145, 146, 147, 148, 149, 150, 151, 152, 0,
+ 0, 0, 202, 202, 249, 200, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 184, 50, 50, 50, 50, 50, 0, 50, 50,
+ 0, 0, 50, 50, 0, 0, 157, 158, 159, 0,
+ 157, 158, 159, 0, 160, 161, 0, 92, 201, 0,
+ 0, 0, 0, 0, 50, 50, 0, 130, 130, 0,
+ 0, 0, 0, 0, 0, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 131, 131, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 149, 149, 149, 0, 0, 0,
+ 0, 0, 149, 149, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 148, 148,
+ 148, 0, 0, 0, 0, 0, 148, 148,
+};
+static const YYINT pcapcheck[] = { 40,
+ 0, 41, 0, 41, 33, 41, 291, 0, 47, 181,
+ 0, 40, 0, 33, 131, 0, 92, 0, 42, 0,
+ 40, 187, 291, 47, 98, 0, 100, 0, 313, 38,
+ 365, 366, 291, 42, 43, 0, 45, 0, 47, 291,
+ 38, 41, 118, 41, 42, 43, 210, 45, 41, 47,
+ 38, 41, 0, 41, 313, 43, 41, 45, 41, 291,
+ 41, 313, 60, 61, 62, 38, 41, 291, 41, 291,
+ 58, 86, 60, 61, 62, 38, 41, 0, 41, 243,
+ 43, 40, 45, 247, 201, 58, 0, 60, 61, 62,
+ 38, 313, 264, 41, 93, 58, 313, 60, 61, 62,
+ 266, 60, 61, 62, 81, 93, 121, 122, 313, 98,
+ 58, 100, 60, 61, 62, 38, 291, 2, 41, 313,
+ 93, 291, 121, 122, 91, 201, 124, 41, 365, 366,
+ 93, 365, 366, 38, 47, 58, 124, 60, 61, 62,
+ 313, 118, 365, 366, 58, 93, 60, 61, 62, 42,
+ 43, 124, 45, 41, 47, 60, 61, 62, 38, 365,
+ 366, 124, 42, 43, 33, 45, 41, 47, 291, 291,
+ 93, 40, 291, 259, 315, 261, 124, 263, 264, 93,
+ 60, 61, 62, 160, 161, 162, 163, 164, 165, 166,
+ 167, 291, 291, 38, 171, 172, 173, 42, 43, 291,
+ 45, 124, 47, 202, 291, 41, 291, 92, 93, 291,
+ 124, 42, 43, 58, 45, 258, 47, 33, 301, 124,
+ 291, 258, 257, 262, 40, 257, 93, 0, 2, 45,
+ 259, 153, 261, -1, 263, 264, 121, 122, 210, 254,
+ 255, -1, -1, -1, 124, -1, -1, -1, 93, -1,
+ 291, -1, -1, -1, -1, -1, -1, 257, 258, 259,
+ 260, 261, 291, 263, 264, -1, -1, 267, 268, -1,
+ -1, 291, -1, 38, -1, -1, -1, 42, 43, 124,
+ 45, -1, 47, -1, 313, 314, 315, 316, 317, 289,
+ 290, -1, -1, 313, 314, 315, 316, 317, -1, -1,
+ 300, 301, 302, 303, 304, 305, 306, 307, 308, 318,
+ 319, -1, 310, 311, 312, -1, 201, 202, -1, -1,
+ 318, 319, 310, 311, 312, 365, 366, 365, 33, 365,
+ 318, 319, 291, -1, -1, 40, -1, 310, 311, 312,
+ 45, -1, -1, -1, -1, 318, 319, 310, 311, 312,
+ -1, 310, 311, 312, -1, 318, 319, -1, -1, 124,
+ -1, -1, 310, 311, 312, 365, 366, 365, 366, -1,
+ 318, 319, 365, 366, -1, 365, 366, 365, 366, -1,
+ 365, 366, 365, 366, 365, 366, -1, 310, 311, 312,
+ 365, 366, 365, 366, -1, -1, 310, 311, 312, -1,
+ 365, 366, 365, 366, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 365, 366, -1,
+ -1, -1, 291, -1, -1, 318, 319, -1, -1, -1,
+ 310, 311, 312, -1, -1, 40, -1, -1, 318, 319,
+ 45, -1, 365, 366, 313, 314, 315, 316, 317, 265,
+ 266, 365, 366, 269, 270, 271, 272, 273, 274, 275,
+ 276, 277, 278, 279, 280, 281, 282, 283, 284, 285,
+ 286, 287, 288, 318, 319, 291, 292, 293, 294, 295,
+ 296, 297, 298, 299, -1, 365, 366, 0, -1, -1,
+ -1, -1, -1, 309, -1, -1, -1, 313, 314, 315,
+ 316, 317, -1, -1, 320, 321, 322, 323, 324, 325,
+ 326, 327, 328, 329, 330, 331, 332, 333, 334, 335,
+ 336, 337, 338, 339, 340, 341, 342, 343, 344, 345,
+ 346, 347, 348, 349, 350, 351, 352, 353, 354, 355,
+ 356, 357, 358, 359, 360, 361, 362, 363, 364, -1,
+ -1, -1, 33, 318, 319, -1, -1, -1, -1, 40,
+ 265, 266, -1, -1, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, -1, -1, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 309, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 320, 321, 322, 323, 324,
+ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
+ 345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
+ 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
+ -1, -1, -1, -1, -1, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 38, -1, 291, -1, 42, 43,
+ 40, 45, -1, 47, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 309, -1, 60, 61, 62, -1,
+ 60, 61, 62, -1, -1, 320, 321, 322, 323, 324,
+ -1, -1, -1, 2, 329, 330, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 340, 341, 342, -1, -1,
+ -1, -1, -1, -1, 257, 258, 259, 260, 261, -1,
+ 263, 264, 357, -1, 267, 268, -1, -1, -1, -1,
+ -1, -1, 38, 40, 41, -1, 42, 43, 2, 45,
+ 124, 47, -1, -1, -1, -1, 289, 290, 259, -1,
+ 261, -1, 263, 264, 60, 61, 62, 300, 301, 302,
+ 303, 304, 305, 306, 307, 308, 38, -1, -1, -1,
+ 42, 43, -1, 45, -1, 47, 40, 41, -1, 86,
+ 291, -1, -1, 92, 93, 92, -1, -1, 60, 61,
+ 62, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 313, 314, 315, 316, 317, 114, -1, -1,
+ -1, 118, 121, 122, 121, 122, -1, -1, 124, -1,
+ -1, -1, 86, -1, 131, 132, -1, -1, 92, 93,
+ -1, -1, -1, -1, 98, -1, 100, 257, 258, 259,
+ 260, 261, -1, 263, 264, -1, -1, 267, 268, -1,
+ 114, -1, 124, -1, -1, -1, -1, 121, 122, -1,
+ -1, -1, -1, -1, -1, -1, -1, 131, 132, 289,
+ 290, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 300, 301, 302, 303, 304, 305, 306, 307, 308, -1,
+ -1, -1, 201, 202, 201, 202, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 291, 257, 258, 259, 260, 261, -1, 263, 264,
+ -1, -1, 267, 268, -1, -1, 310, 311, 312, -1,
+ 310, 311, 312, -1, 318, 319, -1, 201, 202, -1,
+ -1, -1, -1, -1, 289, 290, -1, 254, 255, -1,
+ -1, -1, -1, -1, -1, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 254, 255, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 310, 311, 312, -1, -1, -1,
+ -1, -1, 318, 319, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 310, 311,
+ 312, -1, -1, -1, -1, -1, 318, 319,
+};
+#define YYFINAL 1
+#ifndef YYDEBUG
+#define YYDEBUG 0
+#endif
+#define YYMAXTOKEN 367
+#define YYUNDFTOKEN 414
+#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? YYUNDFTOKEN : (a))
+#if YYDEBUG
+static const char *const pcapname[] = {
+
+"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+"'!'",0,0,0,0,"'&'",0,"'('","')'","'*'","'+'",0,"'-'",0,"'/'",0,0,0,0,0,0,0,0,0,
+0,"':'",0,"'<'","'='","'>'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,"'['",0,"']'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+"'|'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"DST","SRC","HOST","GATEWAY","NET","NETMASK",
+"PORT","PORTRANGE","LESS","GREATER","PROTO","PROTOCHAIN","CBYTE","ARP","RARP",
+"IP","SCTP","TCP","UDP","ICMP","IGMP","IGRP","PIM","VRRP","CARP","ATALK","AARP",
+"DECNET","LAT","SCA","MOPRC","MOPDL","TK_BROADCAST","TK_MULTICAST","NUM",
+"INBOUND","OUTBOUND","PF_IFNAME","PF_RSET","PF_RNR","PF_SRNR","PF_REASON",
+"PF_ACTION","TYPE","SUBTYPE","DIR","ADDR1","ADDR2","ADDR3","ADDR4","RA","TA",
+"LINK","GEQ","LEQ","NEQ","ID","EID","HID","HID6","AID","LSH","RSH","LEN","IPV6",
+"ICMPV6","AH","ESP","VLAN","MPLS","PPPOED","PPPOES","ISO","ESIS","CLNP","ISIS",
+"L1","L2","IIH","LSP","SNP","CSNP","PSNP","STP","IPX","NETBEUI","LANE","LLC",
+"METAC","BCC","SC","ILMIC","OAMF4EC","OAMF4SC","OAM","OAMF4","CONNECTMSG",
+"METACONNECT","VPI","VCI","RADIO","FISU","LSSU","MSU","SIO","OPC","DPC","SLS",
+"OR","AND","UMINUS",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"illegal-symbol",
+};
+static const char *const pcaprule[] = {
+"$accept : prog",
+"prog : null expr",
+"prog : null",
+"null :",
+"expr : term",
+"expr : expr and term",
+"expr : expr and id",
+"expr : expr or term",
+"expr : expr or id",
+"and : AND",
+"or : OR",
+"id : nid",
+"id : pnum",
+"id : paren pid ')'",
+"nid : ID",
+"nid : HID '/' NUM",
+"nid : HID NETMASK HID",
+"nid : HID",
+"nid : HID6 '/' NUM",
+"nid : HID6",
+"nid : EID",
+"nid : AID",
+"nid : not id",
+"not : '!'",
+"paren : '('",
+"pid : nid",
+"pid : qid and id",
+"pid : qid or id",
+"qid : pnum",
+"qid : pid",
+"term : rterm",
+"term : not term",
+"head : pqual dqual aqual",
+"head : pqual dqual",
+"head : pqual aqual",
+"head : pqual PROTO",
+"head : pqual PROTOCHAIN",
+"head : pqual ndaqual",
+"rterm : head id",
+"rterm : paren expr ')'",
+"rterm : pname",
+"rterm : arth relop arth",
+"rterm : arth irelop arth",
+"rterm : other",
+"rterm : atmtype",
+"rterm : atmmultitype",
+"rterm : atmfield atmvalue",
+"rterm : mtp2type",
+"rterm : mtp3field mtp3value",
+"pqual : pname",
+"pqual :",
+"dqual : SRC",
+"dqual : DST",
+"dqual : SRC OR DST",
+"dqual : DST OR SRC",
+"dqual : SRC AND DST",
+"dqual : DST AND SRC",
+"dqual : ADDR1",
+"dqual : ADDR2",
+"dqual : ADDR3",
+"dqual : ADDR4",
+"dqual : RA",
+"dqual : TA",
+"aqual : HOST",
+"aqual : NET",
+"aqual : PORT",
+"aqual : PORTRANGE",
+"ndaqual : GATEWAY",
+"pname : LINK",
+"pname : IP",
+"pname : ARP",
+"pname : RARP",
+"pname : SCTP",
+"pname : TCP",
+"pname : UDP",
+"pname : ICMP",
+"pname : IGMP",
+"pname : IGRP",
+"pname : PIM",
+"pname : VRRP",
+"pname : CARP",
+"pname : ATALK",
+"pname : AARP",
+"pname : DECNET",
+"pname : LAT",
+"pname : SCA",
+"pname : MOPDL",
+"pname : MOPRC",
+"pname : IPV6",
+"pname : ICMPV6",
+"pname : AH",
+"pname : ESP",
+"pname : ISO",
+"pname : ESIS",
+"pname : ISIS",
+"pname : L1",
+"pname : L2",
+"pname : IIH",
+"pname : LSP",
+"pname : SNP",
+"pname : PSNP",
+"pname : CSNP",
+"pname : CLNP",
+"pname : STP",
+"pname : IPX",
+"pname : NETBEUI",
+"pname : RADIO",
+"other : pqual TK_BROADCAST",
+"other : pqual TK_MULTICAST",
+"other : LESS NUM",
+"other : GREATER NUM",
+"other : CBYTE NUM byteop NUM",
+"other : INBOUND",
+"other : OUTBOUND",
+"other : VLAN pnum",
+"other : VLAN",
+"other : MPLS pnum",
+"other : MPLS",
+"other : PPPOED",
+"other : PPPOES",
+"other : pfvar",
+"other : pqual p80211",
+"pfvar : PF_IFNAME ID",
+"pfvar : PF_RSET ID",
+"pfvar : PF_RNR NUM",
+"pfvar : PF_SRNR NUM",
+"pfvar : PF_REASON reason",
+"pfvar : PF_ACTION action",
+"p80211 : TYPE type SUBTYPE subtype",
+"p80211 : TYPE type",
+"p80211 : SUBTYPE type_subtype",
+"p80211 : DIR dir",
+"type : NUM",
+"type : ID",
+"subtype : NUM",
+"subtype : ID",
+"type_subtype : ID",
+"dir : NUM",
+"dir : ID",
+"reason : NUM",
+"reason : ID",
+"action : ID",
+"relop : '>'",
+"relop : GEQ",
+"relop : '='",
+"irelop : LEQ",
+"irelop : '<'",
+"irelop : NEQ",
+"arth : pnum",
+"arth : narth",
+"narth : pname '[' arth ']'",
+"narth : pname '[' arth ':' NUM ']'",
+"narth : arth '+' arth",
+"narth : arth '-' arth",
+"narth : arth '*' arth",
+"narth : arth '/' arth",
+"narth : arth '&' arth",
+"narth : arth '|' arth",
+"narth : arth LSH arth",
+"narth : arth RSH arth",
+"narth : '-' arth",
+"narth : paren narth ')'",
+"narth : LEN",
+"byteop : '&'",
+"byteop : '|'",
+"byteop : '<'",
+"byteop : '>'",
+"byteop : '='",
+"pnum : NUM",
+"pnum : paren pnum ')'",
+"atmtype : LANE",
+"atmtype : LLC",
+"atmtype : METAC",
+"atmtype : BCC",
+"atmtype : OAMF4EC",
+"atmtype : OAMF4SC",
+"atmtype : SC",
+"atmtype : ILMIC",
+"atmmultitype : OAM",
+"atmmultitype : OAMF4",
+"atmmultitype : CONNECTMSG",
+"atmmultitype : METACONNECT",
+"atmfield : VPI",
+"atmfield : VCI",
+"atmvalue : atmfieldvalue",
+"atmvalue : relop NUM",
+"atmvalue : irelop NUM",
+"atmvalue : paren atmlistvalue ')'",
+"atmfieldvalue : NUM",
+"atmlistvalue : atmfieldvalue",
+"atmlistvalue : atmlistvalue or atmfieldvalue",
+"mtp2type : FISU",
+"mtp2type : LSSU",
+"mtp2type : MSU",
+"mtp3field : SIO",
+"mtp3field : OPC",
+"mtp3field : DPC",
+"mtp3field : SLS",
+"mtp3value : mtp3fieldvalue",
+"mtp3value : relop NUM",
+"mtp3value : irelop NUM",
+"mtp3value : paren mtp3listvalue ')'",
+"mtp3fieldvalue : NUM",
+"mtp3listvalue : mtp3fieldvalue",
+"mtp3listvalue : mtp3listvalue or mtp3fieldvalue",
+
+};
+#endif
+
+int yydebug;
+int yynerrs;
+
+int yyerrflag;
+int yychar;
+YYSTYPE yyval;
+YYSTYPE yylval;
+
+/* define the initial stack-sizes */
+#ifdef YYSTACKSIZE
+#undef YYMAXDEPTH
+#define YYMAXDEPTH YYSTACKSIZE
+#else
+#ifdef YYMAXDEPTH
+#define YYSTACKSIZE YYMAXDEPTH
+#else
+#define YYSTACKSIZE 10000
+#define YYMAXDEPTH 10000
+#endif
+#endif
+
+#define YYINITSTACKSIZE 200
+
+typedef struct {
+ unsigned stacksize;
+ YYINT *s_base;
+ YYINT *s_mark;
+ YYINT *s_last;
+ YYSTYPE *l_base;
+ YYSTYPE *l_mark;
+} YYSTACKDATA;
+/* variables for the parser stack */
+static YYSTACKDATA yystack;
+
+#if YYDEBUG
+#include <stdio.h> /* needed for printf */
+#endif
+
+#include <stdlib.h> /* needed for malloc, etc */
+#include <string.h> /* needed for memset */
+
+/* allocate initial stack or double stack size, up to YYMAXDEPTH */
+static int yygrowstack(YYSTACKDATA *data)
+{
+ int i;
+ unsigned newsize;
+ YYINT *newss;
+ YYSTYPE *newvs;
+
+ if ((newsize = data->stacksize) == 0)
+ newsize = YYINITSTACKSIZE;
+ else if (newsize >= YYMAXDEPTH)
+ return YYENOMEM;
+ else if ((newsize *= 2) > YYMAXDEPTH)
+ newsize = YYMAXDEPTH;
+
+ i = (int) (data->s_mark - data->s_base);
+ newss = (YYINT *)realloc(data->s_base, newsize * sizeof(*newss));
+ if (newss == 0)
+ return YYENOMEM;
+
+ data->s_base = newss;
+ data->s_mark = newss + i;
+
+ newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs));
+ if (newvs == 0)
+ return YYENOMEM;
+
+ data->l_base = newvs;
+ data->l_mark = newvs + i;
+
+ data->stacksize = newsize;
+ data->s_last = data->s_base + newsize - 1;
+ return 0;
+}
+
+#if YYPURE || defined(YY_NO_LEAKS)
+static void yyfreestack(YYSTACKDATA *data)
+{
+ free(data->s_base);
+ free(data->l_base);
+ memset(data, 0, sizeof(*data));
+}
+#else
+#define yyfreestack(data) /* nothing */
+#endif
+
+#define YYABORT goto yyabort
+#define YYREJECT goto yyabort
+#define YYACCEPT goto yyaccept
+#define YYERROR goto yyerrlab
+
+int
+YYPARSE_DECL()
+{
+ int yym, yyn, yystate;
+#if YYDEBUG
+ const char *yys;
+
+ if ((yys = getenv("YYDEBUG")) != 0)
+ {
+ yyn = *yys;
+ if (yyn >= '0' && yyn <= '9')
+ yydebug = yyn - '0';
+ }
+#endif
+
+ yynerrs = 0;
+ yyerrflag = 0;
+ yychar = YYEMPTY;
+ yystate = 0;
+
+#if YYPURE
+ memset(&yystack, 0, sizeof(yystack));
+#endif
+
+ if (yystack.s_base == NULL && yygrowstack(&yystack) == YYENOMEM) goto yyoverflow;
+ yystack.s_mark = yystack.s_base;
+ yystack.l_mark = yystack.l_base;
+ yystate = 0;
+ *yystack.s_mark = 0;
+
+yyloop:
+ if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
+ if (yychar < 0)
+ {
+ if ((yychar = YYLEX) < 0) yychar = YYEOF;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = yyname[YYTRANSLATE(yychar)];
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, yystate, yychar, yys);
+ }
+#endif
+ }
+ if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, shifting to state %d\n",
+ YYPREFIX, yystate, yytable[yyn]);
+#endif
+ if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM)
+ {
+ goto yyoverflow;
+ }
+ yystate = yytable[yyn];
+ *++yystack.s_mark = yytable[yyn];
+ *++yystack.l_mark = yylval;
+ yychar = YYEMPTY;
+ if (yyerrflag > 0) --yyerrflag;
+ goto yyloop;
+ }
+ if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ {
+ yyn = yytable[yyn];
+ goto yyreduce;
+ }
+ if (yyerrflag) goto yyinrecovery;
+
+ YYERROR_CALL("syntax error");
+
+ goto yyerrlab;
+
+yyerrlab:
+ ++yynerrs;
+
+yyinrecovery:
+ if (yyerrflag < 3)
+ {
+ yyerrflag = 3;
+ for (;;)
+ {
+ if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, error recovery shifting\
+ to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]);
+#endif
+ if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM)
+ {
+ goto yyoverflow;
+ }
+ yystate = yytable[yyn];
+ *++yystack.s_mark = yytable[yyn];
+ *++yystack.l_mark = yylval;
+ goto yyloop;
+ }
+ else
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: error recovery discarding state %d\n",
+ YYPREFIX, *yystack.s_mark);
+#endif
+ if (yystack.s_mark <= yystack.s_base) goto yyabort;
+ --yystack.s_mark;
+ --yystack.l_mark;
+ }
+ }
+ }
+ else
+ {
+ if (yychar == YYEOF) goto yyabort;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = yyname[YYTRANSLATE(yychar)];
+ printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
+ YYPREFIX, yystate, yychar, yys);
+ }
+#endif
+ yychar = YYEMPTY;
+ goto yyloop;
+ }
+
+yyreduce:
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, reducing by rule %d (%s)\n",
+ YYPREFIX, yystate, yyn, yyrule[yyn]);
+#endif
+ yym = yylen[yyn];
+ if (yym)
+ yyval = yystack.l_mark[1-yym];
+ else
+ memset(&yyval, 0, sizeof yyval);
+ switch (yyn)
+ {
+case 1:
+#line 317 "../../freebsd/contrib/libpcap/grammar.y"
+ {
+ finish_parse(yystack.l_mark[0].blk.b);
+}
+break;
+case 3:
+#line 322 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.q = qerr; }
+break;
+case 5:
+#line 325 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_and(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 6:
+#line 326 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_and(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 7:
+#line 327 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 8:
+#line 328 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 9:
+#line 330 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk = yystack.l_mark[-1].blk; }
+break;
+case 10:
+#line 332 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk = yystack.l_mark[-1].blk; }
+break;
+case 12:
+#line 335 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_ncode(NULL, (bpf_u_int32)yystack.l_mark[0].i,
+ yyval.blk.q = yystack.l_mark[-1].blk.q); }
+break;
+case 13:
+#line 337 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk = yystack.l_mark[-1].blk; }
+break;
+case 14:
+#line 339 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_scode(yystack.l_mark[0].s, yyval.blk.q = yystack.l_mark[-1].blk.q); }
+break;
+case 15:
+#line 340 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_mcode(yystack.l_mark[-2].s, NULL, yystack.l_mark[0].i,
+ yyval.blk.q = yystack.l_mark[-3].blk.q); }
+break;
+case 16:
+#line 342 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_mcode(yystack.l_mark[-2].s, yystack.l_mark[0].s, 0,
+ yyval.blk.q = yystack.l_mark[-3].blk.q); }
+break;
+case 17:
+#line 344 "../../freebsd/contrib/libpcap/grammar.y"
+ {
+ /* Decide how to parse HID based on proto */
+ yyval.blk.q = yystack.l_mark[-1].blk.q;
+ if (yyval.blk.q.addr == Q_PORT)
+ bpf_error("'port' modifier applied to ip host");
+ else if (yyval.blk.q.addr == Q_PORTRANGE)
+ bpf_error("'portrange' modifier applied to ip host");
+ else if (yyval.blk.q.addr == Q_PROTO)
+ bpf_error("'proto' modifier applied to ip host");
+ else if (yyval.blk.q.addr == Q_PROTOCHAIN)
+ bpf_error("'protochain' modifier applied to ip host");
+ yyval.blk.b = gen_ncode(yystack.l_mark[0].s, 0, yyval.blk.q);
+ }
+break;
+case 18:
+#line 357 "../../freebsd/contrib/libpcap/grammar.y"
+ {
+#ifdef INET6
+ yyval.blk.b = gen_mcode6(yystack.l_mark[-2].s, NULL, yystack.l_mark[0].i,
+ yyval.blk.q = yystack.l_mark[-3].blk.q);
+#else
+ bpf_error("'ip6addr/prefixlen' not supported "
+ "in this configuration");
+#endif /*INET6*/
+ }
+break;
+case 19:
+#line 366 "../../freebsd/contrib/libpcap/grammar.y"
+ {
+#ifdef INET6
+ yyval.blk.b = gen_mcode6(yystack.l_mark[0].s, 0, 128,
+ yyval.blk.q = yystack.l_mark[-1].blk.q);
+#else
+ bpf_error("'ip6addr' not supported "
+ "in this configuration");
+#endif /*INET6*/
+ }
+break;
+case 20:
+#line 375 "../../freebsd/contrib/libpcap/grammar.y"
+ {
+ yyval.blk.b = gen_ecode(yystack.l_mark[0].e, yyval.blk.q = yystack.l_mark[-1].blk.q);
+ /*
+ * $1 was allocated by "pcap_ether_aton()",
+ * so we must free it now that we're done
+ * with it.
+ */
+ free(yystack.l_mark[0].e);
+ }
+break;
+case 21:
+#line 384 "../../freebsd/contrib/libpcap/grammar.y"
+ {
+ yyval.blk.b = gen_acode(yystack.l_mark[0].e, yyval.blk.q = yystack.l_mark[-1].blk.q);
+ /*
+ * $1 was allocated by "pcap_ether_aton()",
+ * so we must free it now that we're done
+ * with it.
+ */
+ free(yystack.l_mark[0].e);
+ }
+break;
+case 22:
+#line 393 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_not(yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 23:
+#line 395 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk = yystack.l_mark[-1].blk; }
+break;
+case 24:
+#line 397 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk = yystack.l_mark[-1].blk; }
+break;
+case 26:
+#line 400 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_and(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 27:
+#line 401 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 28:
+#line 403 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_ncode(NULL, (bpf_u_int32)yystack.l_mark[0].i,
+ yyval.blk.q = yystack.l_mark[-1].blk.q); }
+break;
+case 31:
+#line 408 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_not(yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 32:
+#line 410 "../../freebsd/contrib/libpcap/grammar.y"
+ { QSET(yyval.blk.q, yystack.l_mark[-2].i, yystack.l_mark[-1].i, yystack.l_mark[0].i); }
+break;
+case 33:
+#line 411 "../../freebsd/contrib/libpcap/grammar.y"
+ { QSET(yyval.blk.q, yystack.l_mark[-1].i, yystack.l_mark[0].i, Q_DEFAULT); }
+break;
+case 34:
+#line 412 "../../freebsd/contrib/libpcap/grammar.y"
+ { QSET(yyval.blk.q, yystack.l_mark[-1].i, Q_DEFAULT, yystack.l_mark[0].i); }
+break;
+case 35:
+#line 413 "../../freebsd/contrib/libpcap/grammar.y"
+ { QSET(yyval.blk.q, yystack.l_mark[-1].i, Q_DEFAULT, Q_PROTO); }
+break;
+case 36:
+#line 414 "../../freebsd/contrib/libpcap/grammar.y"
+ { QSET(yyval.blk.q, yystack.l_mark[-1].i, Q_DEFAULT, Q_PROTOCHAIN); }
+break;
+case 37:
+#line 415 "../../freebsd/contrib/libpcap/grammar.y"
+ { QSET(yyval.blk.q, yystack.l_mark[-1].i, Q_DEFAULT, yystack.l_mark[0].i); }
+break;
+case 38:
+#line 417 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 39:
+#line 418 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = yystack.l_mark[-1].blk.b; yyval.blk.q = yystack.l_mark[-2].blk.q; }
+break;
+case 40:
+#line 419 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_proto_abbrev(yystack.l_mark[0].i); yyval.blk.q = qerr; }
+break;
+case 41:
+#line 420 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_relation(yystack.l_mark[-1].i, yystack.l_mark[-2].a, yystack.l_mark[0].a, 0);
+ yyval.blk.q = qerr; }
+break;
+case 42:
+#line 422 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_relation(yystack.l_mark[-1].i, yystack.l_mark[-2].a, yystack.l_mark[0].a, 1);
+ yyval.blk.q = qerr; }
+break;
+case 43:
+#line 424 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = yystack.l_mark[0].rblk; yyval.blk.q = qerr; }
+break;
+case 44:
+#line 425 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_atmtype_abbrev(yystack.l_mark[0].i); yyval.blk.q = qerr; }
+break;
+case 45:
+#line 426 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_atmmulti_abbrev(yystack.l_mark[0].i); yyval.blk.q = qerr; }
+break;
+case 46:
+#line 427 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = yystack.l_mark[0].blk.b; yyval.blk.q = qerr; }
+break;
+case 47:
+#line 428 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_mtp2type_abbrev(yystack.l_mark[0].i); yyval.blk.q = qerr; }
+break;
+case 48:
+#line 429 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = yystack.l_mark[0].blk.b; yyval.blk.q = qerr; }
+break;
+case 50:
+#line 433 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_DEFAULT; }
+break;
+case 51:
+#line 436 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_SRC; }
+break;
+case 52:
+#line 437 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_DST; }
+break;
+case 53:
+#line 438 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_OR; }
+break;
+case 54:
+#line 439 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_OR; }
+break;
+case 55:
+#line 440 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_AND; }
+break;
+case 56:
+#line 441 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_AND; }
+break;
+case 57:
+#line 442 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ADDR1; }
+break;
+case 58:
+#line 443 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ADDR2; }
+break;
+case 59:
+#line 444 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ADDR3; }
+break;
+case 60:
+#line 445 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ADDR4; }
+break;
+case 61:
+#line 446 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_RA; }
+break;
+case 62:
+#line 447 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_TA; }
+break;
+case 63:
+#line 450 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_HOST; }
+break;
+case 64:
+#line 451 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_NET; }
+break;
+case 65:
+#line 452 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_PORT; }
+break;
+case 66:
+#line 453 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_PORTRANGE; }
+break;
+case 67:
+#line 456 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_GATEWAY; }
+break;
+case 68:
+#line 458 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_LINK; }
+break;
+case 69:
+#line 459 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_IP; }
+break;
+case 70:
+#line 460 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ARP; }
+break;
+case 71:
+#line 461 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_RARP; }
+break;
+case 72:
+#line 462 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_SCTP; }
+break;
+case 73:
+#line 463 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_TCP; }
+break;
+case 74:
+#line 464 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_UDP; }
+break;
+case 75:
+#line 465 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ICMP; }
+break;
+case 76:
+#line 466 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_IGMP; }
+break;
+case 77:
+#line 467 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_IGRP; }
+break;
+case 78:
+#line 468 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_PIM; }
+break;
+case 79:
+#line 469 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_VRRP; }
+break;
+case 80:
+#line 470 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_CARP; }
+break;
+case 81:
+#line 471 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ATALK; }
+break;
+case 82:
+#line 472 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_AARP; }
+break;
+case 83:
+#line 473 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_DECNET; }
+break;
+case 84:
+#line 474 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_LAT; }
+break;
+case 85:
+#line 475 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_SCA; }
+break;
+case 86:
+#line 476 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_MOPDL; }
+break;
+case 87:
+#line 477 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_MOPRC; }
+break;
+case 88:
+#line 478 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_IPV6; }
+break;
+case 89:
+#line 479 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ICMPV6; }
+break;
+case 90:
+#line 480 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_AH; }
+break;
+case 91:
+#line 481 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ESP; }
+break;
+case 92:
+#line 482 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ISO; }
+break;
+case 93:
+#line 483 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ESIS; }
+break;
+case 94:
+#line 484 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ISIS; }
+break;
+case 95:
+#line 485 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ISIS_L1; }
+break;
+case 96:
+#line 486 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ISIS_L2; }
+break;
+case 97:
+#line 487 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ISIS_IIH; }
+break;
+case 98:
+#line 488 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ISIS_LSP; }
+break;
+case 99:
+#line 489 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ISIS_SNP; }
+break;
+case 100:
+#line 490 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ISIS_PSNP; }
+break;
+case 101:
+#line 491 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ISIS_CSNP; }
+break;
+case 102:
+#line 492 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_CLNP; }
+break;
+case 103:
+#line 493 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_STP; }
+break;
+case 104:
+#line 494 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_IPX; }
+break;
+case 105:
+#line 495 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_NETBEUI; }
+break;
+case 106:
+#line 496 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_RADIO; }
+break;
+case 107:
+#line 498 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_broadcast(yystack.l_mark[-1].i); }
+break;
+case 108:
+#line 499 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_multicast(yystack.l_mark[-1].i); }
+break;
+case 109:
+#line 500 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_less(yystack.l_mark[0].i); }
+break;
+case 110:
+#line 501 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_greater(yystack.l_mark[0].i); }
+break;
+case 111:
+#line 502 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_byteop(yystack.l_mark[-1].i, yystack.l_mark[-2].i, yystack.l_mark[0].i); }
+break;
+case 112:
+#line 503 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_inbound(0); }
+break;
+case 113:
+#line 504 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_inbound(1); }
+break;
+case 114:
+#line 505 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_vlan(yystack.l_mark[0].i); }
+break;
+case 115:
+#line 506 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_vlan(-1); }
+break;
+case 116:
+#line 507 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_mpls(yystack.l_mark[0].i); }
+break;
+case 117:
+#line 508 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_mpls(-1); }
+break;
+case 118:
+#line 509 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_pppoed(); }
+break;
+case 119:
+#line 510 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_pppoes(); }
+break;
+case 120:
+#line 511 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = yystack.l_mark[0].rblk; }
+break;
+case 121:
+#line 512 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = yystack.l_mark[0].rblk; }
+break;
+case 122:
+#line 515 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_pf_ifname(yystack.l_mark[0].s); }
+break;
+case 123:
+#line 516 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_pf_ruleset(yystack.l_mark[0].s); }
+break;
+case 124:
+#line 517 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_pf_rnr(yystack.l_mark[0].i); }
+break;
+case 125:
+#line 518 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_pf_srnr(yystack.l_mark[0].i); }
+break;
+case 126:
+#line 519 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_pf_reason(yystack.l_mark[0].i); }
+break;
+case 127:
+#line 520 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_pf_action(yystack.l_mark[0].i); }
+break;
+case 128:
+#line 524 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_p80211_type(yystack.l_mark[-2].i | yystack.l_mark[0].i,
+ IEEE80211_FC0_TYPE_MASK |
+ IEEE80211_FC0_SUBTYPE_MASK);
+ }
+break;
+case 129:
+#line 528 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_p80211_type(yystack.l_mark[0].i,
+ IEEE80211_FC0_TYPE_MASK);
+ }
+break;
+case 130:
+#line 531 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_p80211_type(yystack.l_mark[0].i,
+ IEEE80211_FC0_TYPE_MASK |
+ IEEE80211_FC0_SUBTYPE_MASK);
+ }
+break;
+case 131:
+#line 535 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_p80211_fcdir(yystack.l_mark[0].i); }
+break;
+case 133:
+#line 539 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = str2tok(yystack.l_mark[0].s, ieee80211_types);
+ if (yyval.i == -1)
+ bpf_error("unknown 802.11 type name");
+ }
+break;
+case 135:
+#line 546 "../../freebsd/contrib/libpcap/grammar.y"
+ { const struct tok *types = NULL;
+ int i;
+ for (i = 0;; i++) {
+ if (ieee80211_type_subtypes[i].tok == NULL) {
+ /* Ran out of types */
+ bpf_error("unknown 802.11 type");
+ break;
+ }
+ if (yystack.l_mark[-2].i == ieee80211_type_subtypes[i].type) {
+ types = ieee80211_type_subtypes[i].tok;
+ break;
+ }
+ }
+
+ yyval.i = str2tok(yystack.l_mark[0].s, types);
+ if (yyval.i == -1)
+ bpf_error("unknown 802.11 subtype name");
+ }
+break;
+case 136:
+#line 566 "../../freebsd/contrib/libpcap/grammar.y"
+ { int i;
+ for (i = 0;; i++) {
+ if (ieee80211_type_subtypes[i].tok == NULL) {
+ /* Ran out of types */
+ bpf_error("unknown 802.11 type name");
+ break;
+ }
+ yyval.i = str2tok(yystack.l_mark[0].s, ieee80211_type_subtypes[i].tok);
+ if (yyval.i != -1) {
+ yyval.i |= ieee80211_type_subtypes[i].type;
+ break;
+ }
+ }
+ }
+break;
+case 138:
+#line 583 "../../freebsd/contrib/libpcap/grammar.y"
+ { if (pcap_strcasecmp(yystack.l_mark[0].s, "nods") == 0)
+ yyval.i = IEEE80211_FC1_DIR_NODS;
+ else if (pcap_strcasecmp(yystack.l_mark[0].s, "tods") == 0)
+ yyval.i = IEEE80211_FC1_DIR_TODS;
+ else if (pcap_strcasecmp(yystack.l_mark[0].s, "fromds") == 0)
+ yyval.i = IEEE80211_FC1_DIR_FROMDS;
+ else if (pcap_strcasecmp(yystack.l_mark[0].s, "dstods") == 0)
+ yyval.i = IEEE80211_FC1_DIR_DSTODS;
+ else
+ bpf_error("unknown 802.11 direction");
+ }
+break;
+case 139:
+#line 596 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = yystack.l_mark[0].i; }
+break;
+case 140:
+#line 597 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = pfreason_to_num(yystack.l_mark[0].s); }
+break;
+case 141:
+#line 600 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = pfaction_to_num(yystack.l_mark[0].s); }
+break;
+case 142:
+#line 603 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = BPF_JGT; }
+break;
+case 143:
+#line 604 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = BPF_JGE; }
+break;
+case 144:
+#line 605 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = BPF_JEQ; }
+break;
+case 145:
+#line 607 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = BPF_JGT; }
+break;
+case 146:
+#line 608 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = BPF_JGE; }
+break;
+case 147:
+#line 609 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = BPF_JEQ; }
+break;
+case 148:
+#line 611 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_loadi(yystack.l_mark[0].i); }
+break;
+case 150:
+#line 614 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_load(yystack.l_mark[-3].i, yystack.l_mark[-1].a, 1); }
+break;
+case 151:
+#line 615 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_load(yystack.l_mark[-5].i, yystack.l_mark[-3].a, yystack.l_mark[-1].i); }
+break;
+case 152:
+#line 616 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_arth(BPF_ADD, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+break;
+case 153:
+#line 617 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_arth(BPF_SUB, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+break;
+case 154:
+#line 618 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_arth(BPF_MUL, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+break;
+case 155:
+#line 619 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_arth(BPF_DIV, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+break;
+case 156:
+#line 620 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_arth(BPF_AND, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+break;
+case 157:
+#line 621 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_arth(BPF_OR, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+break;
+case 158:
+#line 622 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_arth(BPF_LSH, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+break;
+case 159:
+#line 623 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_arth(BPF_RSH, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+break;
+case 160:
+#line 624 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_neg(yystack.l_mark[0].a); }
+break;
+case 161:
+#line 625 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = yystack.l_mark[-1].a; }
+break;
+case 162:
+#line 626 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_loadlen(); }
+break;
+case 163:
+#line 628 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = '&'; }
+break;
+case 164:
+#line 629 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = '|'; }
+break;
+case 165:
+#line 630 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = '<'; }
+break;
+case 166:
+#line 631 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = '>'; }
+break;
+case 167:
+#line 632 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = '='; }
+break;
+case 169:
+#line 635 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = yystack.l_mark[-1].i; }
+break;
+case 170:
+#line 637 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_LANE; }
+break;
+case 171:
+#line 638 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_LLC; }
+break;
+case 172:
+#line 639 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_METAC; }
+break;
+case 173:
+#line 640 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_BCC; }
+break;
+case 174:
+#line 641 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_OAMF4EC; }
+break;
+case 175:
+#line 642 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_OAMF4SC; }
+break;
+case 176:
+#line 643 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_SC; }
+break;
+case 177:
+#line 644 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_ILMIC; }
+break;
+case 178:
+#line 646 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_OAM; }
+break;
+case 179:
+#line 647 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_OAMF4; }
+break;
+case 180:
+#line 648 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_CONNECTMSG; }
+break;
+case 181:
+#line 649 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_METACONNECT; }
+break;
+case 182:
+#line 652 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.atmfieldtype = A_VPI; }
+break;
+case 183:
+#line 653 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.atmfieldtype = A_VCI; }
+break;
+case 185:
+#line 656 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_atmfield_code(yystack.l_mark[-2].blk.atmfieldtype, (bpf_int32)yystack.l_mark[0].i, (bpf_u_int32)yystack.l_mark[-1].i, 0); }
+break;
+case 186:
+#line 657 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_atmfield_code(yystack.l_mark[-2].blk.atmfieldtype, (bpf_int32)yystack.l_mark[0].i, (bpf_u_int32)yystack.l_mark[-1].i, 1); }
+break;
+case 187:
+#line 658 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = yystack.l_mark[-1].blk.b; yyval.blk.q = qerr; }
+break;
+case 188:
+#line 660 "../../freebsd/contrib/libpcap/grammar.y"
+ {
+ yyval.blk.atmfieldtype = yystack.l_mark[-1].blk.atmfieldtype;
+ if (yyval.blk.atmfieldtype == A_VPI ||
+ yyval.blk.atmfieldtype == A_VCI)
+ yyval.blk.b = gen_atmfield_code(yyval.blk.atmfieldtype, (bpf_int32) yystack.l_mark[0].i, BPF_JEQ, 0);
+ }
+break;
+case 190:
+#line 668 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 191:
+#line 671 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = M_FISU; }
+break;
+case 192:
+#line 672 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = M_LSSU; }
+break;
+case 193:
+#line 673 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = M_MSU; }
+break;
+case 194:
+#line 676 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.mtp3fieldtype = M_SIO; }
+break;
+case 195:
+#line 677 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.mtp3fieldtype = M_OPC; }
+break;
+case 196:
+#line 678 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.mtp3fieldtype = M_DPC; }
+break;
+case 197:
+#line 679 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.mtp3fieldtype = M_SLS; }
+break;
+case 199:
+#line 682 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_mtp3field_code(yystack.l_mark[-2].blk.mtp3fieldtype, (u_int)yystack.l_mark[0].i, (u_int)yystack.l_mark[-1].i, 0); }
+break;
+case 200:
+#line 683 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_mtp3field_code(yystack.l_mark[-2].blk.mtp3fieldtype, (u_int)yystack.l_mark[0].i, (u_int)yystack.l_mark[-1].i, 1); }
+break;
+case 201:
+#line 684 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = yystack.l_mark[-1].blk.b; yyval.blk.q = qerr; }
+break;
+case 202:
+#line 686 "../../freebsd/contrib/libpcap/grammar.y"
+ {
+ yyval.blk.mtp3fieldtype = yystack.l_mark[-1].blk.mtp3fieldtype;
+ if (yyval.blk.mtp3fieldtype == M_SIO ||
+ yyval.blk.mtp3fieldtype == M_OPC ||
+ yyval.blk.mtp3fieldtype == M_DPC ||
+ yyval.blk.mtp3fieldtype == M_SLS )
+ yyval.blk.b = gen_mtp3field_code(yyval.blk.mtp3fieldtype, (u_int) yystack.l_mark[0].i, BPF_JEQ, 0);
+ }
+break;
+case 204:
+#line 696 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+#line 2222 "pcap.tab.c"
+ }
+ yystack.s_mark -= yym;
+ yystate = *yystack.s_mark;
+ yystack.l_mark -= yym;
+ yym = yylhs[yyn];
+ if (yystate == 0 && yym == 0)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: after reduction, shifting from state 0 to\
+ state %d\n", YYPREFIX, YYFINAL);
+#endif
+ yystate = YYFINAL;
+ *++yystack.s_mark = YYFINAL;
+ *++yystack.l_mark = yyval;
+ if (yychar < 0)
+ {
+ if ((yychar = YYLEX) < 0) yychar = YYEOF;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = yyname[YYTRANSLATE(yychar)];
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, YYFINAL, yychar, yys);
+ }
+#endif
+ }
+ if (yychar == YYEOF) goto yyaccept;
+ goto yyloop;
+ }
+ if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
+ yystate = yytable[yyn];
+ else
+ yystate = yydgoto[yym];
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: after reduction, shifting from state %d \
+to state %d\n", YYPREFIX, *yystack.s_mark, yystate);
+#endif
+ if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM)
+ {
+ goto yyoverflow;
+ }
+ *++yystack.s_mark = (YYINT) yystate;
+ *++yystack.l_mark = yyval;
+ goto yyloop;
+
+yyoverflow:
+ YYERROR_CALL("yacc stack overflow");
+
+yyabort:
+ yyfreestack(&yystack);
+ return (1);
+
+yyaccept:
+ yyfreestack(&yystack);
+ return (0);
+}
diff --git a/freebsd/contrib/libpcap/grammar.y b/freebsd/contrib/libpcap/grammar.y
new file mode 100644
index 00000000..ac69db9f
--- /dev/null
+++ b/freebsd/contrib/libpcap/grammar.y
@@ -0,0 +1,698 @@
+%{
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.101 2007-11-18 02:03:52 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#include <sys/types.h>
+#include <sys/socket.h>
+#endif /* WIN32 */
+
+#include <stdlib.h>
+
+#ifndef WIN32
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif /* WIN32 */
+
+#include <stdio.h>
+
+#include "pcap-int.h"
+
+#include "gencode.h"
+#ifdef HAVE_NET_PFVAR_H
+#include <net/if.h>
+#include <net/pfvar.h>
+#include <net/if_pflog.h>
+#endif
+#include "ieee80211.h"
+#include <pcap/namedb.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#define QSET(q, p, d, a) (q).proto = (p),\
+ (q).dir = (d),\
+ (q).addr = (a)
+
+struct tok {
+ int v; /* value */
+ const char *s; /* string */
+};
+
+static const struct tok ieee80211_types[] = {
+ { IEEE80211_FC0_TYPE_DATA, "data" },
+ { IEEE80211_FC0_TYPE_MGT, "mgt" },
+ { IEEE80211_FC0_TYPE_MGT, "management" },
+ { IEEE80211_FC0_TYPE_CTL, "ctl" },
+ { IEEE80211_FC0_TYPE_CTL, "control" },
+ { 0, NULL }
+};
+static const struct tok ieee80211_mgt_subtypes[] = {
+ { IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assocreq" },
+ { IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assoc-req" },
+ { IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assocresp" },
+ { IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assoc-resp" },
+ { IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassocreq" },
+ { IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassoc-req" },
+ { IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassocresp" },
+ { IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassoc-resp" },
+ { IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probereq" },
+ { IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probe-req" },
+ { IEEE80211_FC0_SUBTYPE_PROBE_RESP, "proberesp" },
+ { IEEE80211_FC0_SUBTYPE_PROBE_RESP, "probe-resp" },
+ { IEEE80211_FC0_SUBTYPE_BEACON, "beacon" },
+ { IEEE80211_FC0_SUBTYPE_ATIM, "atim" },
+ { IEEE80211_FC0_SUBTYPE_DISASSOC, "disassoc" },
+ { IEEE80211_FC0_SUBTYPE_DISASSOC, "disassociation" },
+ { IEEE80211_FC0_SUBTYPE_AUTH, "auth" },
+ { IEEE80211_FC0_SUBTYPE_AUTH, "authentication" },
+ { IEEE80211_FC0_SUBTYPE_DEAUTH, "deauth" },
+ { IEEE80211_FC0_SUBTYPE_DEAUTH, "deauthentication" },
+ { 0, NULL }
+};
+static const struct tok ieee80211_ctl_subtypes[] = {
+ { IEEE80211_FC0_SUBTYPE_PS_POLL, "ps-poll" },
+ { IEEE80211_FC0_SUBTYPE_RTS, "rts" },
+ { IEEE80211_FC0_SUBTYPE_CTS, "cts" },
+ { IEEE80211_FC0_SUBTYPE_ACK, "ack" },
+ { IEEE80211_FC0_SUBTYPE_CF_END, "cf-end" },
+ { IEEE80211_FC0_SUBTYPE_CF_END_ACK, "cf-end-ack" },
+ { 0, NULL }
+};
+static const struct tok ieee80211_data_subtypes[] = {
+ { IEEE80211_FC0_SUBTYPE_DATA, "data" },
+ { IEEE80211_FC0_SUBTYPE_CF_ACK, "data-cf-ack" },
+ { IEEE80211_FC0_SUBTYPE_CF_POLL, "data-cf-poll" },
+ { IEEE80211_FC0_SUBTYPE_CF_ACPL, "data-cf-ack-poll" },
+ { IEEE80211_FC0_SUBTYPE_NODATA, "null" },
+ { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK, "cf-ack" },
+ { IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "cf-poll" },
+ { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "cf-ack-poll" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA, "qos-data" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK, "qos-data-cf-ack" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL, "qos-data-cf-poll" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL, "qos-data-cf-ack-poll" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA, "qos" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "qos-cf-poll" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "qos-cf-ack-poll" },
+ { 0, NULL }
+};
+struct type2tok {
+ int type;
+ const struct tok *tok;
+};
+static const struct type2tok ieee80211_type_subtypes[] = {
+ { IEEE80211_FC0_TYPE_MGT, ieee80211_mgt_subtypes },
+ { IEEE80211_FC0_TYPE_CTL, ieee80211_ctl_subtypes },
+ { IEEE80211_FC0_TYPE_DATA, ieee80211_data_subtypes },
+ { 0, NULL }
+};
+
+static int
+str2tok(const char *str, const struct tok *toks)
+{
+ int i;
+
+ for (i = 0; toks[i].s != NULL; i++) {
+ if (pcap_strcasecmp(toks[i].s, str) == 0)
+ return (toks[i].v);
+ }
+ return (-1);
+}
+
+int n_errors = 0;
+
+static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
+
+static void
+yyerror(const char *msg)
+{
+ ++n_errors;
+ bpf_error("%s", msg);
+ /* NOTREACHED */
+}
+
+#ifdef NEED_YYPARSE_WRAPPER
+int yyparse(void);
+
+int
+pcap_parse()
+{
+ return (yyparse());
+}
+#endif
+
+#ifdef HAVE_NET_PFVAR_H
+static int
+pfreason_to_num(const char *reason)
+{
+ const char *reasons[] = PFRES_NAMES;
+ int i;
+
+ for (i = 0; reasons[i]; i++) {
+ if (pcap_strcasecmp(reason, reasons[i]) == 0)
+ return (i);
+ }
+ bpf_error("unknown PF reason");
+ /*NOTREACHED*/
+}
+
+static int
+pfaction_to_num(const char *action)
+{
+ if (pcap_strcasecmp(action, "pass") == 0 ||
+ pcap_strcasecmp(action, "accept") == 0)
+ return (PF_PASS);
+ else if (pcap_strcasecmp(action, "drop") == 0 ||
+ pcap_strcasecmp(action, "block") == 0)
+ return (PF_DROP);
+#if HAVE_PF_NAT_THROUGH_PF_NORDR
+ else if (pcap_strcasecmp(action, "rdr") == 0)
+ return (PF_RDR);
+ else if (pcap_strcasecmp(action, "nat") == 0)
+ return (PF_NAT);
+ else if (pcap_strcasecmp(action, "binat") == 0)
+ return (PF_BINAT);
+ else if (pcap_strcasecmp(action, "nordr") == 0)
+ return (PF_NORDR);
+#endif
+ else {
+ bpf_error("unknown PF action");
+ /*NOTREACHED*/
+ }
+}
+#else /* !HAVE_NET_PFVAR_H */
+static int
+pfreason_to_num(const char *reason)
+{
+ bpf_error("libpcap was compiled on a machine without pf support");
+ /*NOTREACHED*/
+
+ /* this is to make the VC compiler happy */
+ return -1;
+}
+
+static int
+pfaction_to_num(const char *action)
+{
+ bpf_error("libpcap was compiled on a machine without pf support");
+ /*NOTREACHED*/
+
+ /* this is to make the VC compiler happy */
+ return -1;
+}
+#endif /* HAVE_NET_PFVAR_H */
+%}
+
+%union {
+ int i;
+ bpf_u_int32 h;
+ u_char *e;
+ char *s;
+ struct stmt *stmt;
+ struct arth *a;
+ struct {
+ struct qual q;
+ int atmfieldtype;
+ int mtp3fieldtype;
+ struct block *b;
+ } blk;
+ struct block *rblk;
+}
+
+%type <blk> expr id nid pid term rterm qid
+%type <blk> head
+%type <i> pqual dqual aqual ndaqual
+%type <a> arth narth
+%type <i> byteop pname pnum relop irelop
+%type <blk> and or paren not null prog
+%type <rblk> other pfvar p80211
+%type <i> atmtype atmmultitype
+%type <blk> atmfield
+%type <blk> atmfieldvalue atmvalue atmlistvalue
+%type <i> mtp2type
+%type <blk> mtp3field
+%type <blk> mtp3fieldvalue mtp3value mtp3listvalue
+
+
+%token DST SRC HOST GATEWAY
+%token NET NETMASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE
+%token ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP CARP
+%token ATALK AARP DECNET LAT SCA MOPRC MOPDL
+%token TK_BROADCAST TK_MULTICAST
+%token NUM INBOUND OUTBOUND
+%token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
+%token TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4 RA TA
+%token LINK
+%token GEQ LEQ NEQ
+%token ID EID HID HID6 AID
+%token LSH RSH
+%token LEN
+%token IPV6 ICMPV6 AH ESP
+%token VLAN MPLS
+%token PPPOED PPPOES
+%token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
+%token STP
+%token IPX
+%token NETBEUI
+%token LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
+%token OAM OAMF4 CONNECTMSG METACONNECT
+%token VPI VCI
+%token RADIO
+%token FISU LSSU MSU
+%token SIO OPC DPC SLS
+
+%type <s> ID
+%type <e> EID
+%type <e> AID
+%type <s> HID HID6
+%type <i> NUM action reason type subtype type_subtype dir
+
+%left OR AND
+%nonassoc '!'
+%left '|'
+%left '&'
+%left LSH RSH
+%left '+' '-'
+%left '*' '/'
+%nonassoc UMINUS
+%%
+prog: null expr
+{
+ finish_parse($2.b);
+}
+ | null
+ ;
+null: /* null */ { $$.q = qerr; }
+ ;
+expr: term
+ | expr and term { gen_and($1.b, $3.b); $$ = $3; }
+ | expr and id { gen_and($1.b, $3.b); $$ = $3; }
+ | expr or term { gen_or($1.b, $3.b); $$ = $3; }
+ | expr or id { gen_or($1.b, $3.b); $$ = $3; }
+ ;
+and: AND { $$ = $<blk>0; }
+ ;
+or: OR { $$ = $<blk>0; }
+ ;
+id: nid
+ | pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
+ $$.q = $<blk>0.q); }
+ | paren pid ')' { $$ = $2; }
+ ;
+nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); }
+ | HID '/' NUM { $$.b = gen_mcode($1, NULL, $3,
+ $$.q = $<blk>0.q); }
+ | HID NETMASK HID { $$.b = gen_mcode($1, $3, 0,
+ $$.q = $<blk>0.q); }
+ | HID {
+ /* Decide how to parse HID based on proto */
+ $$.q = $<blk>0.q;
+ if ($$.q.addr == Q_PORT)
+ bpf_error("'port' modifier applied to ip host");
+ else if ($$.q.addr == Q_PORTRANGE)
+ bpf_error("'portrange' modifier applied to ip host");
+ else if ($$.q.addr == Q_PROTO)
+ bpf_error("'proto' modifier applied to ip host");
+ else if ($$.q.addr == Q_PROTOCHAIN)
+ bpf_error("'protochain' modifier applied to ip host");
+ $$.b = gen_ncode($1, 0, $$.q);
+ }
+ | HID6 '/' NUM {
+#ifdef INET6
+ $$.b = gen_mcode6($1, NULL, $3,
+ $$.q = $<blk>0.q);
+#else
+ bpf_error("'ip6addr/prefixlen' not supported "
+ "in this configuration");
+#endif /*INET6*/
+ }
+ | HID6 {
+#ifdef INET6
+ $$.b = gen_mcode6($1, 0, 128,
+ $$.q = $<blk>0.q);
+#else
+ bpf_error("'ip6addr' not supported "
+ "in this configuration");
+#endif /*INET6*/
+ }
+ | EID {
+ $$.b = gen_ecode($1, $$.q = $<blk>0.q);
+ /*
+ * $1 was allocated by "pcap_ether_aton()",
+ * so we must free it now that we're done
+ * with it.
+ */
+ free($1);
+ }
+ | AID {
+ $$.b = gen_acode($1, $$.q = $<blk>0.q);
+ /*
+ * $1 was allocated by "pcap_ether_aton()",
+ * so we must free it now that we're done
+ * with it.
+ */
+ free($1);
+ }
+ | not id { gen_not($2.b); $$ = $2; }
+ ;
+not: '!' { $$ = $<blk>0; }
+ ;
+paren: '(' { $$ = $<blk>0; }
+ ;
+pid: nid
+ | qid and id { gen_and($1.b, $3.b); $$ = $3; }
+ | qid or id { gen_or($1.b, $3.b); $$ = $3; }
+ ;
+qid: pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
+ $$.q = $<blk>0.q); }
+ | pid
+ ;
+term: rterm
+ | not term { gen_not($2.b); $$ = $2; }
+ ;
+head: pqual dqual aqual { QSET($$.q, $1, $2, $3); }
+ | pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); }
+ | pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); }
+ | pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
+ | pqual PROTOCHAIN { QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); }
+ | pqual ndaqual { QSET($$.q, $1, Q_DEFAULT, $2); }
+ ;
+rterm: head id { $$ = $2; }
+ | paren expr ')' { $$.b = $2.b; $$.q = $1.q; }
+ | pname { $$.b = gen_proto_abbrev($1); $$.q = qerr; }
+ | arth relop arth { $$.b = gen_relation($2, $1, $3, 0);
+ $$.q = qerr; }
+ | arth irelop arth { $$.b = gen_relation($2, $1, $3, 1);
+ $$.q = qerr; }
+ | other { $$.b = $1; $$.q = qerr; }
+ | atmtype { $$.b = gen_atmtype_abbrev($1); $$.q = qerr; }
+ | atmmultitype { $$.b = gen_atmmulti_abbrev($1); $$.q = qerr; }
+ | atmfield atmvalue { $$.b = $2.b; $$.q = qerr; }
+ | mtp2type { $$.b = gen_mtp2type_abbrev($1); $$.q = qerr; }
+ | mtp3field mtp3value { $$.b = $2.b; $$.q = qerr; }
+ ;
+/* protocol level qualifiers */
+pqual: pname
+ | { $$ = Q_DEFAULT; }
+ ;
+/* 'direction' qualifiers */
+dqual: SRC { $$ = Q_SRC; }
+ | DST { $$ = Q_DST; }
+ | SRC OR DST { $$ = Q_OR; }
+ | DST OR SRC { $$ = Q_OR; }
+ | SRC AND DST { $$ = Q_AND; }
+ | DST AND SRC { $$ = Q_AND; }
+ | ADDR1 { $$ = Q_ADDR1; }
+ | ADDR2 { $$ = Q_ADDR2; }
+ | ADDR3 { $$ = Q_ADDR3; }
+ | ADDR4 { $$ = Q_ADDR4; }
+ | RA { $$ = Q_RA; }
+ | TA { $$ = Q_TA; }
+ ;
+/* address type qualifiers */
+aqual: HOST { $$ = Q_HOST; }
+ | NET { $$ = Q_NET; }
+ | PORT { $$ = Q_PORT; }
+ | PORTRANGE { $$ = Q_PORTRANGE; }
+ ;
+/* non-directional address type qualifiers */
+ndaqual: GATEWAY { $$ = Q_GATEWAY; }
+ ;
+pname: LINK { $$ = Q_LINK; }
+ | IP { $$ = Q_IP; }
+ | ARP { $$ = Q_ARP; }
+ | RARP { $$ = Q_RARP; }
+ | SCTP { $$ = Q_SCTP; }
+ | TCP { $$ = Q_TCP; }
+ | UDP { $$ = Q_UDP; }
+ | ICMP { $$ = Q_ICMP; }
+ | IGMP { $$ = Q_IGMP; }
+ | IGRP { $$ = Q_IGRP; }
+ | PIM { $$ = Q_PIM; }
+ | VRRP { $$ = Q_VRRP; }
+ | CARP { $$ = Q_CARP; }
+ | ATALK { $$ = Q_ATALK; }
+ | AARP { $$ = Q_AARP; }
+ | DECNET { $$ = Q_DECNET; }
+ | LAT { $$ = Q_LAT; }
+ | SCA { $$ = Q_SCA; }
+ | MOPDL { $$ = Q_MOPDL; }
+ | MOPRC { $$ = Q_MOPRC; }
+ | IPV6 { $$ = Q_IPV6; }
+ | ICMPV6 { $$ = Q_ICMPV6; }
+ | AH { $$ = Q_AH; }
+ | ESP { $$ = Q_ESP; }
+ | ISO { $$ = Q_ISO; }
+ | ESIS { $$ = Q_ESIS; }
+ | ISIS { $$ = Q_ISIS; }
+ | L1 { $$ = Q_ISIS_L1; }
+ | L2 { $$ = Q_ISIS_L2; }
+ | IIH { $$ = Q_ISIS_IIH; }
+ | LSP { $$ = Q_ISIS_LSP; }
+ | SNP { $$ = Q_ISIS_SNP; }
+ | PSNP { $$ = Q_ISIS_PSNP; }
+ | CSNP { $$ = Q_ISIS_CSNP; }
+ | CLNP { $$ = Q_CLNP; }
+ | STP { $$ = Q_STP; }
+ | IPX { $$ = Q_IPX; }
+ | NETBEUI { $$ = Q_NETBEUI; }
+ | RADIO { $$ = Q_RADIO; }
+ ;
+other: pqual TK_BROADCAST { $$ = gen_broadcast($1); }
+ | pqual TK_MULTICAST { $$ = gen_multicast($1); }
+ | LESS NUM { $$ = gen_less($2); }
+ | GREATER NUM { $$ = gen_greater($2); }
+ | CBYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); }
+ | INBOUND { $$ = gen_inbound(0); }
+ | OUTBOUND { $$ = gen_inbound(1); }
+ | VLAN pnum { $$ = gen_vlan($2); }
+ | VLAN { $$ = gen_vlan(-1); }
+ | MPLS pnum { $$ = gen_mpls($2); }
+ | MPLS { $$ = gen_mpls(-1); }
+ | PPPOED { $$ = gen_pppoed(); }
+ | PPPOES { $$ = gen_pppoes(); }
+ | pfvar { $$ = $1; }
+ | pqual p80211 { $$ = $2; }
+ ;
+
+pfvar: PF_IFNAME ID { $$ = gen_pf_ifname($2); }
+ | PF_RSET ID { $$ = gen_pf_ruleset($2); }
+ | PF_RNR NUM { $$ = gen_pf_rnr($2); }
+ | PF_SRNR NUM { $$ = gen_pf_srnr($2); }
+ | PF_REASON reason { $$ = gen_pf_reason($2); }
+ | PF_ACTION action { $$ = gen_pf_action($2); }
+ ;
+
+p80211: TYPE type SUBTYPE subtype
+ { $$ = gen_p80211_type($2 | $4,
+ IEEE80211_FC0_TYPE_MASK |
+ IEEE80211_FC0_SUBTYPE_MASK);
+ }
+ | TYPE type { $$ = gen_p80211_type($2,
+ IEEE80211_FC0_TYPE_MASK);
+ }
+ | SUBTYPE type_subtype { $$ = gen_p80211_type($2,
+ IEEE80211_FC0_TYPE_MASK |
+ IEEE80211_FC0_SUBTYPE_MASK);
+ }
+ | DIR dir { $$ = gen_p80211_fcdir($2); }
+ ;
+
+type: NUM
+ | ID { $$ = str2tok($1, ieee80211_types);
+ if ($$ == -1)
+ bpf_error("unknown 802.11 type name");
+ }
+ ;
+
+subtype: NUM
+ | ID { const struct tok *types = NULL;
+ int i;
+ for (i = 0;; i++) {
+ if (ieee80211_type_subtypes[i].tok == NULL) {
+ /* Ran out of types */
+ bpf_error("unknown 802.11 type");
+ break;
+ }
+ if ($<i>-1 == ieee80211_type_subtypes[i].type) {
+ types = ieee80211_type_subtypes[i].tok;
+ break;
+ }
+ }
+
+ $$ = str2tok($1, types);
+ if ($$ == -1)
+ bpf_error("unknown 802.11 subtype name");
+ }
+ ;
+
+type_subtype: ID { int i;
+ for (i = 0;; i++) {
+ if (ieee80211_type_subtypes[i].tok == NULL) {
+ /* Ran out of types */
+ bpf_error("unknown 802.11 type name");
+ break;
+ }
+ $$ = str2tok($1, ieee80211_type_subtypes[i].tok);
+ if ($$ != -1) {
+ $$ |= ieee80211_type_subtypes[i].type;
+ break;
+ }
+ }
+ }
+ ;
+
+dir: NUM
+ | ID { if (pcap_strcasecmp($1, "nods") == 0)
+ $$ = IEEE80211_FC1_DIR_NODS;
+ else if (pcap_strcasecmp($1, "tods") == 0)
+ $$ = IEEE80211_FC1_DIR_TODS;
+ else if (pcap_strcasecmp($1, "fromds") == 0)
+ $$ = IEEE80211_FC1_DIR_FROMDS;
+ else if (pcap_strcasecmp($1, "dstods") == 0)
+ $$ = IEEE80211_FC1_DIR_DSTODS;
+ else
+ bpf_error("unknown 802.11 direction");
+ }
+ ;
+
+reason: NUM { $$ = $1; }
+ | ID { $$ = pfreason_to_num($1); }
+ ;
+
+action: ID { $$ = pfaction_to_num($1); }
+ ;
+
+relop: '>' { $$ = BPF_JGT; }
+ | GEQ { $$ = BPF_JGE; }
+ | '=' { $$ = BPF_JEQ; }
+ ;
+irelop: LEQ { $$ = BPF_JGT; }
+ | '<' { $$ = BPF_JGE; }
+ | NEQ { $$ = BPF_JEQ; }
+ ;
+arth: pnum { $$ = gen_loadi($1); }
+ | narth
+ ;
+narth: pname '[' arth ']' { $$ = gen_load($1, $3, 1); }
+ | pname '[' arth ':' NUM ']' { $$ = gen_load($1, $3, $5); }
+ | arth '+' arth { $$ = gen_arth(BPF_ADD, $1, $3); }
+ | arth '-' arth { $$ = gen_arth(BPF_SUB, $1, $3); }
+ | arth '*' arth { $$ = gen_arth(BPF_MUL, $1, $3); }
+ | arth '/' arth { $$ = gen_arth(BPF_DIV, $1, $3); }
+ | arth '&' arth { $$ = gen_arth(BPF_AND, $1, $3); }
+ | arth '|' arth { $$ = gen_arth(BPF_OR, $1, $3); }
+ | arth LSH arth { $$ = gen_arth(BPF_LSH, $1, $3); }
+ | arth RSH arth { $$ = gen_arth(BPF_RSH, $1, $3); }
+ | '-' arth %prec UMINUS { $$ = gen_neg($2); }
+ | paren narth ')' { $$ = $2; }
+ | LEN { $$ = gen_loadlen(); }
+ ;
+byteop: '&' { $$ = '&'; }
+ | '|' { $$ = '|'; }
+ | '<' { $$ = '<'; }
+ | '>' { $$ = '>'; }
+ | '=' { $$ = '='; }
+ ;
+pnum: NUM
+ | paren pnum ')' { $$ = $2; }
+ ;
+atmtype: LANE { $$ = A_LANE; }
+ | LLC { $$ = A_LLC; }
+ | METAC { $$ = A_METAC; }
+ | BCC { $$ = A_BCC; }
+ | OAMF4EC { $$ = A_OAMF4EC; }
+ | OAMF4SC { $$ = A_OAMF4SC; }
+ | SC { $$ = A_SC; }
+ | ILMIC { $$ = A_ILMIC; }
+ ;
+atmmultitype: OAM { $$ = A_OAM; }
+ | OAMF4 { $$ = A_OAMF4; }
+ | CONNECTMSG { $$ = A_CONNECTMSG; }
+ | METACONNECT { $$ = A_METACONNECT; }
+ ;
+ /* ATM field types quantifier */
+atmfield: VPI { $$.atmfieldtype = A_VPI; }
+ | VCI { $$.atmfieldtype = A_VCI; }
+ ;
+atmvalue: atmfieldvalue
+ | relop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0); }
+ | irelop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1); }
+ | paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
+ ;
+atmfieldvalue: NUM {
+ $$.atmfieldtype = $<blk>0.atmfieldtype;
+ if ($$.atmfieldtype == A_VPI ||
+ $$.atmfieldtype == A_VCI)
+ $$.b = gen_atmfield_code($$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0);
+ }
+ ;
+atmlistvalue: atmfieldvalue
+ | atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; }
+ ;
+ /* MTP2 types quantifier */
+mtp2type: FISU { $$ = M_FISU; }
+ | LSSU { $$ = M_LSSU; }
+ | MSU { $$ = M_MSU; }
+ ;
+ /* MTP3 field types quantifier */
+mtp3field: SIO { $$.mtp3fieldtype = M_SIO; }
+ | OPC { $$.mtp3fieldtype = M_OPC; }
+ | DPC { $$.mtp3fieldtype = M_DPC; }
+ | SLS { $$.mtp3fieldtype = M_SLS; }
+ ;
+mtp3value: mtp3fieldvalue
+ | relop NUM { $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); }
+ | irelop NUM { $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1); }
+ | paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
+ ;
+mtp3fieldvalue: NUM {
+ $$.mtp3fieldtype = $<blk>0.mtp3fieldtype;
+ if ($$.mtp3fieldtype == M_SIO ||
+ $$.mtp3fieldtype == M_OPC ||
+ $$.mtp3fieldtype == M_DPC ||
+ $$.mtp3fieldtype == M_SLS )
+ $$.b = gen_mtp3field_code($$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0);
+ }
+ ;
+mtp3listvalue: mtp3fieldvalue
+ | mtp3listvalue or mtp3fieldvalue { gen_or($1.b, $3.b); $$ = $3; }
+ ;
+%%
diff --git a/freebsd/contrib/libpcap/ieee80211.h b/freebsd/contrib/libpcap/ieee80211.h
new file mode 100644
index 00000000..d79f0f8e
--- /dev/null
+++ b/freebsd/contrib/libpcap/ieee80211.h
@@ -0,0 +1,146 @@
+/*-
+ * Copyright (c) 2001 Atsushi Onoe
+ * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifndef _NET80211_IEEE80211_H_
+#define _NET80211_IEEE80211_H_
+
+/*
+ * 802.11 protocol definitions.
+ */
+
+#define IEEE80211_FC0_VERSION_MASK 0x03
+#define IEEE80211_FC0_VERSION_SHIFT 0
+#define IEEE80211_FC0_VERSION_0 0x00
+#define IEEE80211_FC0_TYPE_MASK 0x0c
+#define IEEE80211_FC0_TYPE_SHIFT 2
+#define IEEE80211_FC0_TYPE_MGT 0x00
+#define IEEE80211_FC0_TYPE_CTL 0x04
+#define IEEE80211_FC0_TYPE_DATA 0x08
+
+#define IEEE80211_FC0_SUBTYPE_MASK 0xf0
+#define IEEE80211_FC0_SUBTYPE_SHIFT 4
+/* for TYPE_MGT */
+#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ 0x00
+#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP 0x10
+#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ 0x20
+#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP 0x30
+#define IEEE80211_FC0_SUBTYPE_PROBE_REQ 0x40
+#define IEEE80211_FC0_SUBTYPE_PROBE_RESP 0x50
+#define IEEE80211_FC0_SUBTYPE_BEACON 0x80
+#define IEEE80211_FC0_SUBTYPE_ATIM 0x90
+#define IEEE80211_FC0_SUBTYPE_DISASSOC 0xa0
+#define IEEE80211_FC0_SUBTYPE_AUTH 0xb0
+#define IEEE80211_FC0_SUBTYPE_DEAUTH 0xc0
+/* for TYPE_CTL */
+#define IEEE80211_FC0_SUBTYPE_PS_POLL 0xa0
+#define IEEE80211_FC0_SUBTYPE_RTS 0xb0
+#define IEEE80211_FC0_SUBTYPE_CTS 0xc0
+#define IEEE80211_FC0_SUBTYPE_ACK 0xd0
+#define IEEE80211_FC0_SUBTYPE_CF_END 0xe0
+#define IEEE80211_FC0_SUBTYPE_CF_END_ACK 0xf0
+/* for TYPE_DATA (bit combination) */
+#define IEEE80211_FC0_SUBTYPE_DATA 0x00
+#define IEEE80211_FC0_SUBTYPE_CF_ACK 0x10
+#define IEEE80211_FC0_SUBTYPE_CF_POLL 0x20
+#define IEEE80211_FC0_SUBTYPE_CF_ACPL 0x30
+#define IEEE80211_FC0_SUBTYPE_NODATA 0x40
+#define IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK 0x50
+#define IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL 0x60
+#define IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL 0x70
+#define IEEE80211_FC0_SUBTYPE_QOS 0x80
+#define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0
+
+#define IEEE80211_FC1_DIR_MASK 0x03
+#define IEEE80211_FC1_DIR_NODS 0x00 /* STA->STA */
+#define IEEE80211_FC1_DIR_TODS 0x01 /* STA->AP */
+#define IEEE80211_FC1_DIR_FROMDS 0x02 /* AP ->STA */
+#define IEEE80211_FC1_DIR_DSTODS 0x03 /* AP ->AP */
+
+#define IEEE80211_FC1_MORE_FRAG 0x04
+#define IEEE80211_FC1_RETRY 0x08
+#define IEEE80211_FC1_PWR_MGT 0x10
+#define IEEE80211_FC1_MORE_DATA 0x20
+#define IEEE80211_FC1_WEP 0x40
+#define IEEE80211_FC1_ORDER 0x80
+
+#define IEEE80211_SEQ_FRAG_MASK 0x000f
+#define IEEE80211_SEQ_FRAG_SHIFT 0
+#define IEEE80211_SEQ_SEQ_MASK 0xfff0
+#define IEEE80211_SEQ_SEQ_SHIFT 4
+
+#define IEEE80211_NWID_LEN 32
+
+#define IEEE80211_QOS_TXOP 0x00ff
+/* bit 8 is reserved */
+#define IEEE80211_QOS_ACKPOLICY 0x60
+#define IEEE80211_QOS_ACKPOLICY_S 5
+#define IEEE80211_QOS_ESOP 0x10
+#define IEEE80211_QOS_ESOP_S 4
+#define IEEE80211_QOS_TID 0x0f
+
+#define IEEE80211_MGT_SUBTYPE_NAMES { \
+ "assoc-req", "assoc-resp", \
+ "reassoc-req", "reassoc-resp", \
+ "probe-req", "probe-resp", \
+ "reserved#6", "reserved#7", \
+ "beacon", "atim", \
+ "disassoc", "auth", \
+ "deauth", "reserved#13", \
+ "reserved#14", "reserved#15" \
+}
+
+#define IEEE80211_CTL_SUBTYPE_NAMES { \
+ "reserved#0", "reserved#1", \
+ "reserved#2", "reserved#3", \
+ "reserved#3", "reserved#5", \
+ "reserved#6", "reserved#7", \
+ "reserved#8", "reserved#9", \
+ "ps-poll", "rts", \
+ "cts", "ack", \
+ "cf-end", "cf-end-ack" \
+}
+
+#define IEEE80211_DATA_SUBTYPE_NAMES { \
+ "data", "data-cf-ack", \
+ "data-cf-poll", "data-cf-ack-poll", \
+ "null", "cf-ack", \
+ "cf-poll", "cf-ack-poll", \
+ "qos-data", "qos-data-cf-ack", \
+ "qos-data-cf-poll", "qos-data-cf-ack-poll", \
+ "qos", "reserved#13", \
+ "qos-cf-poll", "qos-cf-ack-poll" \
+}
+
+#define IEEE80211_TYPE_NAMES { "mgt", "ctl", "data", "reserved#4" }
+
+#endif /* _NET80211_IEEE80211_H_ */
diff --git a/freebsd/contrib/libpcap/inet.c b/freebsd/contrib/libpcap/inet.c
new file mode 100644
index 00000000..08867903
--- /dev/null
+++ b/freebsd/contrib/libpcap/inet.c
@@ -0,0 +1,935 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
+/*
+ * Copyright (c) 1994, 1995, 1996, 1997, 1998
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.79 2008-04-20 18:19:02 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+
+#include <rtems/bsd/sys/param.h>
+#ifndef MSDOS
+#include <sys/file.h>
+#endif
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
+
+struct mbuf; /* Squelch compiler warnings on some platforms for */
+struct rtentry; /* declarations in <net/if.h> */
+#include <net/if.h>
+#include <netinet/in.h>
+#endif /* WIN32 */
+
+#include <ctype.h>
+#include <errno.h>
+#include <memory.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if !defined(WIN32) && !defined(__BORLANDC__)
+#include <unistd.h>
+#endif /* !WIN32 && !__BORLANDC__ */
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#else
+#define INT_MAX 2147483647
+#endif
+
+#include "pcap-int.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+/* Not all systems have IFF_LOOPBACK */
+#ifdef IFF_LOOPBACK
+#define ISLOOPBACK(name, flags) ((flags) & IFF_LOOPBACK)
+#else
+#define ISLOOPBACK(name, flags) ((name)[0] == 'l' && (name)[1] == 'o' && \
+ (isdigit((unsigned char)((name)[2])) || (name)[2] == '\0'))
+#endif
+
+struct sockaddr *
+dup_sockaddr(struct sockaddr *sa, size_t sa_length)
+{
+ struct sockaddr *newsa;
+
+ if ((newsa = malloc(sa_length)) == NULL)
+ return (NULL);
+ return (memcpy(newsa, sa, sa_length));
+}
+
+static int
+get_instance(const char *name)
+{
+ const char *cp, *endcp;
+ int n;
+
+ if (strcmp(name, "any") == 0) {
+ /*
+ * Give the "any" device an artificially high instance
+ * number, so it shows up after all other non-loopback
+ * interfaces.
+ */
+ return INT_MAX;
+ }
+
+ endcp = name + strlen(name);
+ for (cp = name; cp < endcp && !isdigit((unsigned char)*cp); ++cp)
+ continue;
+
+ if (isdigit((unsigned char)*cp))
+ n = atoi(cp);
+ else
+ n = 0;
+ return (n);
+}
+
+int
+add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
+ u_int flags, const char *description, char *errbuf)
+{
+ pcap_t *p;
+ pcap_if_t *curdev, *prevdev, *nextdev;
+ int this_instance;
+ char open_errbuf[PCAP_ERRBUF_SIZE];
+
+ /*
+ * Is there already an entry in the list for this interface?
+ */
+ for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) {
+ if (strcmp(name, curdev->name) == 0)
+ break; /* yes, we found it */
+ }
+
+ if (curdev == NULL) {
+ /*
+ * No, we didn't find it.
+ *
+ * Can we open this interface for live capture?
+ *
+ * We do this check so that interfaces that are
+ * supplied by the interface enumeration mechanism
+ * we're using but that don't support packet capture
+ * aren't included in the list. Loopback interfaces
+ * on Solaris are an example of this; we don't just
+ * omit loopback interfaces on all platforms because
+ * you *can* capture on loopback interfaces on some
+ * OSes.
+ *
+ * On OS X, we don't do this check if the device
+ * name begins with "wlt"; at least some versions
+ * of OS X offer monitor mode capturing by having
+ * a separate "monitor mode" device for each wireless
+ * adapter, rather than by implementing the ioctls
+ * that {Free,Net,Open,DragonFly}BSD provide.
+ * Opening that device puts the adapter into monitor
+ * mode, which, at least for some adapters, causes
+ * them to deassociate from the network with which
+ * they're associated.
+ *
+ * Instead, we try to open the corresponding "en"
+ * device (so that we don't end up with, for users
+ * without sufficient privilege to open capture
+ * devices, a list of adapters that only includes
+ * the wlt devices).
+ */
+#ifdef __APPLE__
+ if (strncmp(name, "wlt", 3) == 0) {
+ char *en_name;
+ size_t en_name_len;
+
+ /*
+ * Try to allocate a buffer for the "en"
+ * device's name.
+ */
+ en_name_len = strlen(name) - 1;
+ en_name = malloc(en_name_len + 1);
+ if (en_name == NULL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ return (-1);
+ }
+ strcpy(en_name, "en");
+ strcat(en_name, name + 3);
+ p = pcap_open_live(en_name, 68, 0, 0, open_errbuf);
+ free(en_name);
+ } else
+#endif /* __APPLE */
+ p = pcap_open_live(name, 68, 0, 0, open_errbuf);
+ if (p == NULL) {
+ /*
+ * No. Don't bother including it.
+ * Don't treat this as an error, though.
+ */
+ *curdev_ret = NULL;
+ return (0);
+ }
+ pcap_close(p);
+
+ /*
+ * Yes, we can open it.
+ * Allocate a new entry.
+ */
+ curdev = malloc(sizeof(pcap_if_t));
+ if (curdev == NULL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ return (-1);
+ }
+
+ /*
+ * Fill in the entry.
+ */
+ curdev->next = NULL;
+ curdev->name = strdup(name);
+ if (curdev->name == NULL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ free(curdev);
+ return (-1);
+ }
+ if (description != NULL) {
+ /*
+ * We have a description for this interface.
+ */
+ curdev->description = strdup(description);
+ if (curdev->description == NULL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ free(curdev->name);
+ free(curdev);
+ return (-1);
+ }
+ } else {
+ /*
+ * We don't.
+ */
+ curdev->description = NULL;
+ }
+ curdev->addresses = NULL; /* list starts out as empty */
+ curdev->flags = 0;
+ if (ISLOOPBACK(name, flags))
+ curdev->flags |= PCAP_IF_LOOPBACK;
+
+ /*
+ * Add it to the list, in the appropriate location.
+ * First, get the instance number of this interface.
+ */
+ this_instance = get_instance(name);
+
+ /*
+ * Now look for the last interface with an instance number
+ * less than or equal to the new interface's instance
+ * number - except that non-loopback interfaces are
+ * arbitrarily treated as having interface numbers less
+ * than those of loopback interfaces, so the loopback
+ * interfaces are put at the end of the list.
+ *
+ * We start with "prevdev" being NULL, meaning we're before
+ * the first element in the list.
+ */
+ prevdev = NULL;
+ for (;;) {
+ /*
+ * Get the interface after this one.
+ */
+ if (prevdev == NULL) {
+ /*
+ * The next element is the first element.
+ */
+ nextdev = *alldevs;
+ } else
+ nextdev = prevdev->next;
+
+ /*
+ * Are we at the end of the list?
+ */
+ if (nextdev == NULL) {
+ /*
+ * Yes - we have to put the new entry
+ * after "prevdev".
+ */
+ break;
+ }
+
+ /*
+ * Is the new interface a non-loopback interface
+ * and the next interface a loopback interface?
+ */
+ if (!(curdev->flags & PCAP_IF_LOOPBACK) &&
+ (nextdev->flags & PCAP_IF_LOOPBACK)) {
+ /*
+ * Yes, we should put the new entry
+ * before "nextdev", i.e. after "prevdev".
+ */
+ break;
+ }
+
+ /*
+ * Is the new interface's instance number less
+ * than the next interface's instance number,
+ * and is it the case that the new interface is a
+ * non-loopback interface or the next interface is
+ * a loopback interface?
+ *
+ * (The goal of both loopback tests is to make
+ * sure that we never put a loopback interface
+ * before any non-loopback interface and that we
+ * always put a non-loopback interface before all
+ * loopback interfaces.)
+ */
+ if (this_instance < get_instance(nextdev->name) &&
+ (!(curdev->flags & PCAP_IF_LOOPBACK) ||
+ (nextdev->flags & PCAP_IF_LOOPBACK))) {
+ /*
+ * Yes - we should put the new entry
+ * before "nextdev", i.e. after "prevdev".
+ */
+ break;
+ }
+
+ prevdev = nextdev;
+ }
+
+ /*
+ * Insert before "nextdev".
+ */
+ curdev->next = nextdev;
+
+ /*
+ * Insert after "prevdev" - unless "prevdev" is null,
+ * in which case this is the first interface.
+ */
+ if (prevdev == NULL) {
+ /*
+ * This is the first interface. Pass back a
+ * pointer to it, and put "curdev" before
+ * "nextdev".
+ */
+ *alldevs = curdev;
+ } else
+ prevdev->next = curdev;
+ }
+
+ *curdev_ret = curdev;
+ return (0);
+}
+
+/*
+ * XXX - on FreeBSDs that support it, should it get the sysctl named
+ * "dev.{adapter family name}.{adapter unit}.%desc" to get a description
+ * of the adapter? Note that "dev.an.0.%desc" is "Aironet PC4500/PC4800"
+ * with my Cisco 350 card, so the name isn't entirely descriptive. The
+ * "dev.an.0.%pnpinfo" has a better description, although one might argue
+ * that the problem is really a driver bug - if it can find out that it's
+ * a Cisco 340 or 350, rather than an old Aironet card, it should use
+ * that in the description.
+ *
+ * Do NetBSD, DragonflyBSD, or OpenBSD support this as well? FreeBSD
+ * and OpenBSD let you get a description, but it's not generated by the OS,
+ * it's set with another ioctl that ifconfig supports; we use that to get
+ * a description in FreeBSD and OpenBSD, but if there is no such
+ * description available, it still might be nice to get some description
+ * string based on the device type or something such as that.
+ *
+ * In OS X, the System Configuration framework can apparently return
+ * names in 10.4 and later.
+ *
+ * It also appears that freedesktop.org's HAL offers an "info.product"
+ * string, but the HAL specification says it "should not be used in any
+ * UI" and "subsystem/capability specific properties" should be used
+ * instead and, in any case, I think HAL is being deprecated in
+ * favor of other stuff such as DeviceKit. DeviceKit doesn't appear
+ * to have any obvious product information for devices, but maybe
+ * I haven't looked hard enough.
+ *
+ * Using the System Configuration framework, or HAL, or DeviceKit, or
+ * whatever, would require that libpcap applications be linked with
+ * the frameworks/libraries in question. That shouldn't be a problem
+ * for programs linking with the shared version of libpcap (unless
+ * you're running on AIX - which I think is the only UN*X that doesn't
+ * support linking a shared library with other libraries on which it
+ * depends, and having an executable linked only with the first shared
+ * library automatically pick up the other libraries when started -
+ * and using HAL or whatever). Programs linked with the static
+ * version of libpcap would have to use pcap-config with the --static
+ * flag in order to get the right linker flags in order to pick up
+ * the additional libraries/frameworks; those programs need that anyway
+ * for libpcap 1.1 and beyond on Linux, as, by default, it requires
+ * -lnl.
+ *
+ * Do any other UN*Xes, or desktop environments support getting a
+ * description?
+ */
+int
+add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags,
+ struct sockaddr *addr, size_t addr_size,
+ struct sockaddr *netmask, size_t netmask_size,
+ struct sockaddr *broadaddr, size_t broadaddr_size,
+ struct sockaddr *dstaddr, size_t dstaddr_size,
+ char *errbuf)
+{
+ pcap_if_t *curdev;
+ char *description = NULL;
+ pcap_addr_t *curaddr, *prevaddr, *nextaddr;
+#ifdef SIOCGIFDESCR
+ int s;
+ struct ifreq ifrdesc;
+#ifndef IFDESCRSIZE
+ size_t descrlen = 64;
+#else
+ size_t descrlen = IFDESCRSIZE;
+#endif /* IFDESCRSIZE */
+#endif /* SIOCGIFDESCR */
+
+#ifdef SIOCGIFDESCR
+ /*
+ * Get the description for the interface.
+ */
+ memset(&ifrdesc, 0, sizeof ifrdesc);
+ strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s >= 0) {
+#ifdef __FreeBSD__
+ /*
+ * On FreeBSD, if the buffer isn't big enough for the
+ * description, the ioctl succeeds, but the description
+ * isn't copied, ifr_buffer.length is set to the description
+ * length, and ifr_buffer.buffer is set to NULL.
+ */
+ for (;;) {
+ free(description);
+ if ((description = malloc(descrlen)) != NULL) {
+ ifrdesc.ifr_buffer.buffer = description;
+ ifrdesc.ifr_buffer.length = descrlen;
+ if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0) {
+ if (ifrdesc.ifr_buffer.buffer ==
+ description)
+ break;
+ else
+ descrlen = ifrdesc.ifr_buffer.length;
+ } else {
+ /*
+ * Failed to get interface description.
+ */
+ free(description);
+ description = NULL;
+ break;
+ }
+ } else
+ break;
+ }
+#else /* __FreeBSD__ */
+ /*
+ * The only other OS that currently supports
+ * SIOCGIFDESCR is OpenBSD, and it has no way
+ * to get the description length - it's clamped
+ * to a maximum of IFDESCRSIZE.
+ */
+ if ((description = malloc(descrlen)) != NULL) {
+ ifrdesc.ifr_data = (caddr_t)description;
+ if (ioctl(s, SIOCGIFDESCR, &ifrdesc) != 0) {
+ /*
+ * Failed to get interface description.
+ */
+ free(description);
+ description = NULL;
+ }
+ }
+#endif /* __FreeBSD__ */
+ close(s);
+ if (description != NULL && strlen(description) == 0) {
+ free(description);
+ description = NULL;
+ }
+ }
+#endif /* SIOCGIFDESCR */
+
+ if (add_or_find_if(&curdev, alldevs, name, flags, description,
+ errbuf) == -1) {
+ free(description);
+ /*
+ * Error - give up.
+ */
+ return (-1);
+ }
+ free(description);
+ if (curdev == NULL) {
+ /*
+ * Device wasn't added because it can't be opened.
+ * Not a fatal error.
+ */
+ return (0);
+ }
+
+ /*
+ * "curdev" is an entry for this interface; add an entry for this
+ * address to its list of addresses.
+ *
+ * Allocate the new entry and fill it in.
+ */
+ curaddr = malloc(sizeof(pcap_addr_t));
+ if (curaddr == NULL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ return (-1);
+ }
+
+ curaddr->next = NULL;
+ if (addr != NULL) {
+ curaddr->addr = dup_sockaddr(addr, addr_size);
+ if (curaddr->addr == NULL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ free(curaddr);
+ return (-1);
+ }
+ } else
+ curaddr->addr = NULL;
+
+ if (netmask != NULL) {
+ curaddr->netmask = dup_sockaddr(netmask, netmask_size);
+ if (curaddr->netmask == NULL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ if (curaddr->addr != NULL)
+ free(curaddr->addr);
+ free(curaddr);
+ return (-1);
+ }
+ } else
+ curaddr->netmask = NULL;
+
+ if (broadaddr != NULL) {
+ curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size);
+ if (curaddr->broadaddr == NULL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ if (curaddr->netmask != NULL)
+ free(curaddr->netmask);
+ if (curaddr->addr != NULL)
+ free(curaddr->addr);
+ free(curaddr);
+ return (-1);
+ }
+ } else
+ curaddr->broadaddr = NULL;
+
+ if (dstaddr != NULL) {
+ curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size);
+ if (curaddr->dstaddr == NULL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ if (curaddr->broadaddr != NULL)
+ free(curaddr->broadaddr);
+ if (curaddr->netmask != NULL)
+ free(curaddr->netmask);
+ if (curaddr->addr != NULL)
+ free(curaddr->addr);
+ free(curaddr);
+ return (-1);
+ }
+ } else
+ curaddr->dstaddr = NULL;
+
+ /*
+ * Find the end of the list of addresses.
+ */
+ for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) {
+ nextaddr = prevaddr->next;
+ if (nextaddr == NULL) {
+ /*
+ * This is the end of the list.
+ */
+ break;
+ }
+ }
+
+ if (prevaddr == NULL) {
+ /*
+ * The list was empty; this is the first member.
+ */
+ curdev->addresses = curaddr;
+ } else {
+ /*
+ * "prevaddr" is the last member of the list; append
+ * this member to it.
+ */
+ prevaddr->next = curaddr;
+ }
+
+ return (0);
+}
+
+int
+pcap_add_if(pcap_if_t **devlist, const char *name, u_int flags,
+ const char *description, char *errbuf)
+{
+ pcap_if_t *curdev;
+
+ return (add_or_find_if(&curdev, devlist, name, flags, description,
+ errbuf));
+}
+
+
+/*
+ * Free a list of interfaces.
+ */
+void
+pcap_freealldevs(pcap_if_t *alldevs)
+{
+ pcap_if_t *curdev, *nextdev;
+ pcap_addr_t *curaddr, *nextaddr;
+
+ for (curdev = alldevs; curdev != NULL; curdev = nextdev) {
+ nextdev = curdev->next;
+
+ /*
+ * Free all addresses.
+ */
+ for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) {
+ nextaddr = curaddr->next;
+ if (curaddr->addr)
+ free(curaddr->addr);
+ if (curaddr->netmask)
+ free(curaddr->netmask);
+ if (curaddr->broadaddr)
+ free(curaddr->broadaddr);
+ if (curaddr->dstaddr)
+ free(curaddr->dstaddr);
+ free(curaddr);
+ }
+
+ /*
+ * Free the name string.
+ */
+ free(curdev->name);
+
+ /*
+ * Free the description string, if any.
+ */
+ if (curdev->description != NULL)
+ free(curdev->description);
+
+ /*
+ * Free the interface.
+ */
+ free(curdev);
+ }
+}
+
+#if !defined(WIN32) && !defined(MSDOS)
+
+/*
+ * Return the name of a network interface attached to the system, or NULL
+ * if none can be found. The interface must be configured up; the
+ * lowest unit number is preferred; loopback is ignored.
+ */
+char *
+pcap_lookupdev(errbuf)
+ register char *errbuf;
+{
+ pcap_if_t *alldevs;
+/* for old BSD systems, including bsdi3 */
+#ifndef IF_NAMESIZE
+#define IF_NAMESIZE IFNAMSIZ
+#endif
+ static char device[IF_NAMESIZE + 1];
+ char *ret;
+
+ if (pcap_findalldevs(&alldevs, errbuf) == -1)
+ return (NULL);
+
+ if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) {
+ /*
+ * There are no devices on the list, or the first device
+ * on the list is a loopback device, which means there
+ * are no non-loopback devices on the list. This means
+ * we can't return any device.
+ *
+ * XXX - why not return a loopback device? If we can't
+ * capture on it, it won't be on the list, and if it's
+ * on the list, there aren't any non-loopback devices,
+ * so why not just supply it as the default device?
+ */
+ (void)strlcpy(errbuf, "no suitable device found",
+ PCAP_ERRBUF_SIZE);
+ ret = NULL;
+ } else {
+ /*
+ * Return the name of the first device on the list.
+ */
+ (void)strlcpy(device, alldevs->name, sizeof(device));
+ ret = device;
+ }
+
+ pcap_freealldevs(alldevs);
+ return (ret);
+}
+
+int
+pcap_lookupnet(device, netp, maskp, errbuf)
+ register const char *device;
+ register bpf_u_int32 *netp, *maskp;
+ register char *errbuf;
+{
+ register int fd;
+ register struct sockaddr_in *sin4;
+ struct ifreq ifr;
+
+ /*
+ * The pseudo-device "any" listens on all interfaces and therefore
+ * has the network address and -mask "0.0.0.0" therefore catching
+ * all traffic. Using NULL for the interface is the same as "any".
+ */
+ if (!device || strcmp(device, "any") == 0
+#ifdef HAVE_DAG_API
+ || strstr(device, "dag") != NULL
+#endif
+#ifdef HAVE_SEPTEL_API
+ || strstr(device, "septel") != NULL
+#endif
+#ifdef PCAP_SUPPORT_BT
+ || strstr(device, "bluetooth") != NULL
+#endif
+#ifdef PCAP_SUPPORT_USB
+ || strstr(device, "usbmon") != NULL
+#endif
+#ifdef HAVE_SNF_API
+ || strstr(device, "snf") != NULL
+#endif
+ ) {
+ *netp = *maskp = 0;
+ return 0;
+ }
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
+ pcap_strerror(errno));
+ return (-1);
+ }
+ memset(&ifr, 0, sizeof(ifr));
+#ifdef linux
+ /* XXX Work around Linux kernel bug */
+ ifr.ifr_addr.sa_family = AF_INET;
+#endif
+ (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
+ if (errno == EADDRNOTAVAIL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "%s: no IPv4 address assigned", device);
+ } else {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "SIOCGIFADDR: %s: %s",
+ device, pcap_strerror(errno));
+ }
+ (void)close(fd);
+ return (-1);
+ }
+ sin4 = (struct sockaddr_in *)&ifr.ifr_addr;
+ *netp = sin4->sin_addr.s_addr;
+ memset(&ifr, 0, sizeof(ifr));
+#ifdef linux
+ /* XXX Work around Linux kernel bug */
+ ifr.ifr_addr.sa_family = AF_INET;
+#endif
+ (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno));
+ (void)close(fd);
+ return (-1);
+ }
+ (void)close(fd);
+ *maskp = sin4->sin_addr.s_addr;
+ if (*maskp == 0) {
+ if (IN_CLASSA(*netp))
+ *maskp = IN_CLASSA_NET;
+ else if (IN_CLASSB(*netp))
+ *maskp = IN_CLASSB_NET;
+ else if (IN_CLASSC(*netp))
+ *maskp = IN_CLASSC_NET;
+ else {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "inet class for 0x%x unknown", *netp);
+ return (-1);
+ }
+ }
+ *netp &= *maskp;
+ return (0);
+}
+
+#elif defined(WIN32)
+
+/*
+ * Return the name of a network interface attached to the system, or NULL
+ * if none can be found. The interface must be configured up; the
+ * lowest unit number is preferred; loopback is ignored.
+ */
+char *
+pcap_lookupdev(errbuf)
+ register char *errbuf;
+{
+ DWORD dwVersion;
+ DWORD dwWindowsMajorVersion;
+ dwVersion = GetVersion(); /* get the OS version */
+ dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
+
+ if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
+ /*
+ * Windows 95, 98, ME.
+ */
+ ULONG NameLength = 8192;
+ static char AdaptersName[8192];
+
+ if (PacketGetAdapterNames(AdaptersName,&NameLength) )
+ return (AdaptersName);
+ else
+ return NULL;
+ } else {
+ /*
+ * Windows NT (NT 4.0, W2K, WXP). Convert the names to UNICODE for backward compatibility
+ */
+ ULONG NameLength = 8192;
+ static WCHAR AdaptersName[8192];
+ char *tAstr;
+ WCHAR *tUstr;
+ WCHAR *TAdaptersName = (WCHAR*)malloc(8192 * sizeof(WCHAR));
+ int NAdapts = 0;
+
+ if(TAdaptersName == NULL)
+ {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure");
+ return NULL;
+ }
+
+ if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
+ {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "PacketGetAdapterNames: %s",
+ pcap_win32strerror());
+ free(TAdaptersName);
+ return NULL;
+ }
+
+
+ tAstr = (char*)TAdaptersName;
+ tUstr = (WCHAR*)AdaptersName;
+
+ /*
+ * Convert and copy the device names
+ */
+ while(sscanf(tAstr, "%S", tUstr) > 0)
+ {
+ tAstr += strlen(tAstr) + 1;
+ tUstr += wcslen(tUstr) + 1;
+ NAdapts ++;
+ }
+
+ tAstr++;
+ *tUstr = 0;
+ tUstr++;
+
+ /*
+ * Copy the descriptions
+ */
+ while(NAdapts--)
+ {
+ char* tmp = (char*)tUstr;
+ strcpy(tmp, tAstr);
+ tmp += strlen(tAstr) + 1;
+ tUstr = (WCHAR*)tmp;
+ tAstr += strlen(tAstr) + 1;
+ }
+
+ free(TAdaptersName);
+ return (char *)(AdaptersName);
+ }
+}
+
+
+int
+pcap_lookupnet(device, netp, maskp, errbuf)
+ register const char *device;
+ register bpf_u_int32 *netp, *maskp;
+ register char *errbuf;
+{
+ /*
+ * We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo()
+ * in order to skip non IPv4 (i.e. IPv6 addresses)
+ */
+ npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
+ LONG if_addr_size = 1;
+ struct sockaddr_in *t_addr;
+ unsigned int i;
+
+ if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) {
+ *netp = *maskp = 0;
+ return (0);
+ }
+
+ for(i=0; i<MAX_NETWORK_ADDRESSES; i++)
+ {
+ if(if_addrs[i].IPAddress.ss_family == AF_INET)
+ {
+ t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress);
+ *netp = t_addr->sin_addr.S_un.S_addr;
+ t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask);
+ *maskp = t_addr->sin_addr.S_un.S_addr;
+
+ *netp &= *maskp;
+ return (0);
+ }
+
+ }
+
+ *netp = *maskp = 0;
+ return (0);
+}
+
+#endif /* !WIN32 && !MSDOS */
diff --git a/freebsd/contrib/libpcap/llc.h b/freebsd/contrib/libpcap/llc.h
new file mode 100644
index 00000000..b8c221fa
--- /dev/null
+++ b/freebsd/contrib/libpcap/llc.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1993, 1994, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/llc.h,v 1.2 2001-01-28 09:44:50 guy Exp $ (LBL)
+ */
+
+/*
+ * 802.2 LLC SAP values.
+ */
+
+#ifndef LLCSAP_NULL
+#define LLCSAP_NULL 0x00
+#endif
+#ifndef LLCSAP_GLOBAL
+#define LLCSAP_GLOBAL 0xff
+#endif
+#ifndef LLCSAP_8021B
+#define LLCSAP_8021B_I 0x02
+#endif
+#ifndef LLCSAP_8021B
+#define LLCSAP_8021B_G 0x03
+#endif
+#ifndef LLCSAP_IP
+#define LLCSAP_IP 0x06
+#endif
+#ifndef LLCSAP_PROWAYNM
+#define LLCSAP_PROWAYNM 0x0e
+#endif
+#ifndef LLCSAP_8021D
+#define LLCSAP_8021D 0x42
+#endif
+#ifndef LLCSAP_RS511
+#define LLCSAP_RS511 0x4e
+#endif
+#ifndef LLCSAP_ISO8208
+#define LLCSAP_ISO8208 0x7e
+#endif
+#ifndef LLCSAP_PROWAY
+#define LLCSAP_PROWAY 0x8e
+#endif
+#ifndef LLCSAP_SNAP
+#define LLCSAP_SNAP 0xaa
+#endif
+#ifndef LLCSAP_IPX
+#define LLCSAP_IPX 0xe0
+#endif
+#ifndef LLCSAP_NETBEUI
+#define LLCSAP_NETBEUI 0xf0
+#endif
+#ifndef LLCSAP_ISONS
+#define LLCSAP_ISONS 0xfe
+#endif
diff --git a/freebsd/contrib/libpcap/nametoaddr.c b/freebsd/contrib/libpcap/nametoaddr.c
new file mode 100644
index 00000000..af761744
--- /dev/null
+++ b/freebsd/contrib/libpcap/nametoaddr.c
@@ -0,0 +1,525 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Name to id translation routines used by the scanner.
+ * These functions are not time critical.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.83 2008-02-06 10:21:30 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef DECNETLIB
+#include <rtems/bsd/sys/types.h>
+#include <netdnet/dnetdb.h>
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+
+#else /* WIN32 */
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/types.h> /* concession to AIX */
+#include <sys/socket.h>
+#include <rtems/bsd/sys/time.h>
+
+#include <netinet/in.h>
+#endif /* WIN32 */
+
+#ifndef WIN32
+#ifdef HAVE_ETHER_HOSTTON
+/*
+ * XXX - do we need any of this if <netinet/if_ether.h> doesn't declare
+ * ether_hostton()?
+ */
+#ifdef HAVE_NETINET_IF_ETHER_H
+struct mbuf; /* Squelch compiler warnings on some platforms for */
+struct rtentry; /* declarations in <net/if.h> */
+#include <net/if.h> /* for "struct ifnet" in "struct arpcom" on Solaris */
+#include <netinet/if_ether.h>
+#endif /* HAVE_NETINET_IF_ETHER_H */
+#ifdef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON
+#include <netinet/ether.h>
+#endif /* NETINET_ETHER_H_DECLARES_ETHER_HOSTTON */
+#endif /* HAVE_ETHER_HOSTTON */
+#include <arpa/inet.h>
+#include <netdb.h>
+#endif /* WIN32 */
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "pcap-int.h"
+
+#include "gencode.h"
+#include <pcap/namedb.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#ifndef NTOHL
+#define NTOHL(x) (x) = ntohl(x)
+#define NTOHS(x) (x) = ntohs(x)
+#endif
+
+static inline int xdtoi(int);
+
+/*
+ * Convert host name to internet address.
+ * Return 0 upon failure.
+ */
+bpf_u_int32 **
+pcap_nametoaddr(const char *name)
+{
+#ifndef h_addr
+ static bpf_u_int32 *hlist[2];
+#endif
+ bpf_u_int32 **p;
+ struct hostent *hp;
+
+ if ((hp = gethostbyname(name)) != NULL) {
+#ifndef h_addr
+ hlist[0] = (bpf_u_int32 *)hp->h_addr;
+ NTOHL(hp->h_addr);
+ return hlist;
+#else
+ for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p)
+ NTOHL(**p);
+ return (bpf_u_int32 **)hp->h_addr_list;
+#endif
+ }
+ else
+ return 0;
+}
+
+#ifdef INET6
+struct addrinfo *
+pcap_nametoaddrinfo(const char *name)
+{
+ struct addrinfo hints, *res;
+ int error;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM; /*not really*/
+ hints.ai_protocol = IPPROTO_TCP; /*not really*/
+ error = getaddrinfo(name, NULL, &hints, &res);
+ if (error)
+ return NULL;
+ else
+ return res;
+}
+#endif /*INET6*/
+
+/*
+ * Convert net name to internet address.
+ * Return 0 upon failure.
+ */
+bpf_u_int32
+pcap_nametonetaddr(const char *name)
+{
+#ifndef WIN32
+ struct netent *np;
+
+ if ((np = getnetbyname(name)) != NULL)
+ return np->n_net;
+ else
+ return 0;
+#else
+ /*
+ * There's no "getnetbyname()" on Windows.
+ */
+ return 0;
+#endif
+}
+
+/*
+ * Convert a port name to its port and protocol numbers.
+ * We assume only TCP or UDP.
+ * Return 0 upon failure.
+ */
+int
+pcap_nametoport(const char *name, int *port, int *proto)
+{
+ struct servent *sp;
+ int tcp_port = -1;
+ int udp_port = -1;
+
+ /*
+ * We need to check /etc/services for ambiguous entries.
+ * If we find the ambiguous entry, and it has the
+ * same port number, change the proto to PROTO_UNDEF
+ * so both TCP and UDP will be checked.
+ */
+ sp = getservbyname(name, "tcp");
+ if (sp != NULL) tcp_port = ntohs(sp->s_port);
+ sp = getservbyname(name, "udp");
+ if (sp != NULL) udp_port = ntohs(sp->s_port);
+ if (tcp_port >= 0) {
+ *port = tcp_port;
+ *proto = IPPROTO_TCP;
+ if (udp_port >= 0) {
+ if (udp_port == tcp_port)
+ *proto = PROTO_UNDEF;
+#ifdef notdef
+ else
+ /* Can't handle ambiguous names that refer
+ to different port numbers. */
+ warning("ambiguous port %s in /etc/services",
+ name);
+#endif
+ }
+ return 1;
+ }
+ if (udp_port >= 0) {
+ *port = udp_port;
+ *proto = IPPROTO_UDP;
+ return 1;
+ }
+#if defined(ultrix) || defined(__osf__)
+ /* Special hack in case NFS isn't in /etc/services */
+ if (strcmp(name, "nfs") == 0) {
+ *port = 2049;
+ *proto = PROTO_UNDEF;
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+/*
+ * Convert a string in the form PPP-PPP, where correspond to ports, to
+ * a starting and ending port in a port range.
+ * Return 0 on failure.
+ */
+int
+pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto)
+{
+ u_int p1, p2;
+ char *off, *cpy;
+ int save_proto;
+
+ if (sscanf(name, "%d-%d", &p1, &p2) != 2) {
+ if ((cpy = strdup(name)) == NULL)
+ return 0;
+
+ if ((off = strchr(cpy, '-')) == NULL) {
+ free(cpy);
+ return 0;
+ }
+
+ *off = '\0';
+
+ if (pcap_nametoport(cpy, port1, proto) == 0) {
+ free(cpy);
+ return 0;
+ }
+ save_proto = *proto;
+
+ if (pcap_nametoport(off + 1, port2, proto) == 0) {
+ free(cpy);
+ return 0;
+ }
+ free(cpy);
+
+ if (*proto != save_proto)
+ *proto = PROTO_UNDEF;
+ } else {
+ *port1 = p1;
+ *port2 = p2;
+ *proto = PROTO_UNDEF;
+ }
+
+ return 1;
+}
+
+int
+pcap_nametoproto(const char *str)
+{
+ struct protoent *p;
+
+ p = getprotobyname(str);
+ if (p != 0)
+ return p->p_proto;
+ else
+ return PROTO_UNDEF;
+}
+
+#include "ethertype.h"
+
+struct eproto {
+ const char *s;
+ u_short p;
+};
+
+/* Static data base of ether protocol types. */
+struct eproto eproto_db[] = {
+#if 0
+ /* The FreeBSD elf linker generates a request to copy this array
+ * (including its size) when you link with -lpcap. In order to
+ * not bump the major version number of this libpcap.so, we need
+ * to ensure that the array stays the same size. Since PUP is
+ * likely never seen in real life any more, it's the first to
+ * be sacrificed (in favor of ip6).
+ */
+ { "pup", ETHERTYPE_PUP },
+#endif
+ { "xns", ETHERTYPE_NS },
+ { "ip", ETHERTYPE_IP },
+#ifdef INET6
+ { "ip6", ETHERTYPE_IPV6 },
+#endif
+ { "arp", ETHERTYPE_ARP },
+ { "rarp", ETHERTYPE_REVARP },
+ { "sprite", ETHERTYPE_SPRITE },
+ { "mopdl", ETHERTYPE_MOPDL },
+ { "moprc", ETHERTYPE_MOPRC },
+ { "decnet", ETHERTYPE_DN },
+ { "lat", ETHERTYPE_LAT },
+ { "sca", ETHERTYPE_SCA },
+ { "lanbridge", ETHERTYPE_LANBRIDGE },
+ { "vexp", ETHERTYPE_VEXP },
+ { "vprod", ETHERTYPE_VPROD },
+ { "atalk", ETHERTYPE_ATALK },
+ { "atalkarp", ETHERTYPE_AARP },
+ { "loopback", ETHERTYPE_LOOPBACK },
+ { "decdts", ETHERTYPE_DECDTS },
+ { "decdns", ETHERTYPE_DECDNS },
+ { (char *)0, 0 }
+};
+
+int
+pcap_nametoeproto(const char *s)
+{
+ struct eproto *p = eproto_db;
+
+ while (p->s != 0) {
+ if (strcmp(p->s, s) == 0)
+ return p->p;
+ p += 1;
+ }
+ return PROTO_UNDEF;
+}
+
+#include "llc.h"
+
+/* Static data base of LLC values. */
+static struct eproto llc_db[] = {
+ { "iso", LLCSAP_ISONS },
+ { "stp", LLCSAP_8021D },
+ { "ipx", LLCSAP_IPX },
+ { "netbeui", LLCSAP_NETBEUI },
+ { (char *)0, 0 }
+};
+
+int
+pcap_nametollc(const char *s)
+{
+ struct eproto *p = llc_db;
+
+ while (p->s != 0) {
+ if (strcmp(p->s, s) == 0)
+ return p->p;
+ p += 1;
+ }
+ return PROTO_UNDEF;
+}
+
+/* Hex digit to integer. */
+static inline int
+xdtoi(c)
+ register int c;
+{
+ if (isdigit(c))
+ return c - '0';
+ else if (islower(c))
+ return c - 'a' + 10;
+ else
+ return c - 'A' + 10;
+}
+
+int
+__pcap_atoin(const char *s, bpf_u_int32 *addr)
+{
+ u_int n;
+ int len;
+
+ *addr = 0;
+ len = 0;
+ while (1) {
+ n = 0;
+ while (*s && *s != '.')
+ n = n * 10 + *s++ - '0';
+ *addr <<= 8;
+ *addr |= n & 0xff;
+ len += 8;
+ if (*s == '\0')
+ return len;
+ ++s;
+ }
+ /* NOTREACHED */
+}
+
+int
+__pcap_atodn(const char *s, bpf_u_int32 *addr)
+{
+#define AREASHIFT 10
+#define AREAMASK 0176000
+#define NODEMASK 01777
+
+ u_int node, area;
+
+ if (sscanf(s, "%d.%d", &area, &node) != 2)
+ bpf_error("malformed decnet address '%s'", s);
+
+ *addr = (area << AREASHIFT) & AREAMASK;
+ *addr |= (node & NODEMASK);
+
+ return(32);
+}
+
+/*
+ * Convert 's', which can have the one of the forms:
+ *
+ * "xx:xx:xx:xx:xx:xx"
+ * "xx.xx.xx.xx.xx.xx"
+ * "xx-xx-xx-xx-xx-xx"
+ * "xxxx.xxxx.xxxx"
+ * "xxxxxxxxxxxx"
+ *
+ * (or various mixes of ':', '.', and '-') into a new
+ * ethernet address. Assumes 's' is well formed.
+ */
+u_char *
+pcap_ether_aton(const char *s)
+{
+ register u_char *ep, *e;
+ register u_int d;
+
+ e = ep = (u_char *)malloc(6);
+
+ while (*s) {
+ if (*s == ':' || *s == '.' || *s == '-')
+ s += 1;
+ d = xdtoi(*s++);
+ if (isxdigit((unsigned char)*s)) {
+ d <<= 4;
+ d |= xdtoi(*s++);
+ }
+ *ep++ = d;
+ }
+
+ return (e);
+}
+
+#ifndef HAVE_ETHER_HOSTTON
+/* Roll our own */
+u_char *
+pcap_ether_hostton(const char *name)
+{
+ register struct pcap_etherent *ep;
+ register u_char *ap;
+ static FILE *fp = NULL;
+ static int init = 0;
+
+ if (!init) {
+ fp = fopen(PCAP_ETHERS_FILE, "r");
+ ++init;
+ if (fp == NULL)
+ return (NULL);
+ } else if (fp == NULL)
+ return (NULL);
+ else
+ rewind(fp);
+
+ while ((ep = pcap_next_etherent(fp)) != NULL) {
+ if (strcmp(ep->name, name) == 0) {
+ ap = (u_char *)malloc(6);
+ if (ap != NULL) {
+ memcpy(ap, ep->addr, 6);
+ return (ap);
+ }
+ break;
+ }
+ }
+ return (NULL);
+}
+#else
+
+#if !defined(HAVE_DECL_ETHER_HOSTTON) || !HAVE_DECL_ETHER_HOSTTON
+#ifndef HAVE_STRUCT_ETHER_ADDR
+struct ether_addr {
+ unsigned char ether_addr_octet[6];
+};
+#endif
+extern int ether_hostton(const char *, struct ether_addr *);
+#endif
+
+/* Use the os supplied routines */
+u_char *
+pcap_ether_hostton(const char *name)
+{
+ register u_char *ap;
+ u_char a[6];
+
+ ap = NULL;
+ if (ether_hostton(name, (struct ether_addr *)a) == 0) {
+ ap = (u_char *)malloc(6);
+ if (ap != NULL)
+ memcpy((char *)ap, (char *)a, 6);
+ }
+ return (ap);
+}
+#endif
+
+u_short
+__pcap_nametodnaddr(const char *name)
+{
+#ifdef DECNETLIB
+ struct nodeent *getnodebyname();
+ struct nodeent *nep;
+ unsigned short res;
+
+ nep = getnodebyname(name);
+ if (nep == ((struct nodeent *)0))
+ bpf_error("unknown decnet host name '%s'\n", name);
+
+ memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short));
+ return(res);
+#else
+ bpf_error("decnet name support not included, '%s' cannot be translated\n",
+ name);
+ return(0);
+#endif
+}
diff --git a/freebsd/contrib/libpcap/nlpid.h b/freebsd/contrib/libpcap/nlpid.h
new file mode 100644
index 00000000..5327a362
--- /dev/null
+++ b/freebsd/contrib/libpcap/nlpid.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1996
+ * Juniper Networks, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution. The name of Juniper Networks may not
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/nlpid.h,v 1.2 2002-12-06 00:01:34 hannes Exp $ (Juniper)
+ */
+
+/* Types missing from some systems */
+
+/*
+ * Network layer prototocol identifiers
+ */
+#ifndef ISO8473_CLNP
+#define ISO8473_CLNP 0x81
+#endif
+#ifndef ISO9542_ESIS
+#define ISO9542_ESIS 0x82
+#endif
+#ifndef ISO9542X25_ESIS
+#define ISO9542X25_ESIS 0x8a
+#endif
+#ifndef ISO10589_ISIS
+#define ISO10589_ISIS 0x83
+#endif
+/*
+ * this does not really belong in the nlpid.h file
+ * however we need it for generating nice
+ * IS-IS related BPF filters
+ */
+#define ISIS_L1_LAN_IIH 15
+#define ISIS_L2_LAN_IIH 16
+#define ISIS_PTP_IIH 17
+#define ISIS_L1_LSP 18
+#define ISIS_L2_LSP 20
+#define ISIS_L1_CSNP 24
+#define ISIS_L2_CSNP 25
+#define ISIS_L1_PSNP 26
+#define ISIS_L2_PSNP 27
+
+#ifndef ISO8878A_CONS
+#define ISO8878A_CONS 0x84
+#endif
+#ifndef ISO10747_IDRP
+#define ISO10747_IDRP 0x85
+#endif
diff --git a/freebsd/contrib/libpcap/optimize.c b/freebsd/contrib/libpcap/optimize.c
new file mode 100644
index 00000000..14eced3c
--- /dev/null
+++ b/freebsd/contrib/libpcap/optimize.c
@@ -0,0 +1,2249 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Optimization module for tcpdump intermediate representation.
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.91 2008-01-02 04:16:46 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/types.h>
+#endif /* WIN32 */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <string.h>
+
+#include <errno.h>
+
+#include "pcap-int.h"
+
+#include "gencode.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#ifdef BDEBUG
+extern int dflag;
+#endif
+
+#if defined(MSDOS) && !defined(__DJGPP__)
+extern int _w32_ffs (int mask);
+#define ffs _w32_ffs
+#endif
+
+#if defined(WIN32) && defined (_MSC_VER)
+int ffs(int mask);
+#endif
+
+/*
+ * Represents a deleted instruction.
+ */
+#define NOP -1
+
+/*
+ * Register numbers for use-def values.
+ * 0 through BPF_MEMWORDS-1 represent the corresponding scratch memory
+ * location. A_ATOM is the accumulator and X_ATOM is the index
+ * register.
+ */
+#define A_ATOM BPF_MEMWORDS
+#define X_ATOM (BPF_MEMWORDS+1)
+
+/*
+ * This define is used to represent *both* the accumulator and
+ * x register in use-def computations.
+ * Currently, the use-def code assumes only one definition per instruction.
+ */
+#define AX_ATOM N_ATOMS
+
+/*
+ * A flag to indicate that further optimization is needed.
+ * Iterative passes are continued until a given pass yields no
+ * branch movement.
+ */
+static int done;
+
+/*
+ * A block is marked if only if its mark equals the current mark.
+ * Rather than traverse the code array, marking each item, 'cur_mark' is
+ * incremented. This automatically makes each element unmarked.
+ */
+static int cur_mark;
+#define isMarked(p) ((p)->mark == cur_mark)
+#define unMarkAll() cur_mark += 1
+#define Mark(p) ((p)->mark = cur_mark)
+
+static void opt_init(struct block *);
+static void opt_cleanup(void);
+
+static void intern_blocks(struct block *);
+
+static void find_inedges(struct block *);
+#ifdef BDEBUG
+static void opt_dump(struct block *);
+#endif
+
+static int n_blocks;
+struct block **blocks;
+static int n_edges;
+struct edge **edges;
+
+/*
+ * A bit vector set representation of the dominators.
+ * We round up the set size to the next power of two.
+ */
+static int nodewords;
+static int edgewords;
+struct block **levels;
+bpf_u_int32 *space;
+#define BITS_PER_WORD (8*sizeof(bpf_u_int32))
+/*
+ * True if a is in uset {p}
+ */
+#define SET_MEMBER(p, a) \
+((p)[(unsigned)(a) / BITS_PER_WORD] & (1 << ((unsigned)(a) % BITS_PER_WORD)))
+
+/*
+ * Add 'a' to uset p.
+ */
+#define SET_INSERT(p, a) \
+(p)[(unsigned)(a) / BITS_PER_WORD] |= (1 << ((unsigned)(a) % BITS_PER_WORD))
+
+/*
+ * Delete 'a' from uset p.
+ */
+#define SET_DELETE(p, a) \
+(p)[(unsigned)(a) / BITS_PER_WORD] &= ~(1 << ((unsigned)(a) % BITS_PER_WORD))
+
+/*
+ * a := a intersect b
+ */
+#define SET_INTERSECT(a, b, n)\
+{\
+ register bpf_u_int32 *_x = a, *_y = b;\
+ register int _n = n;\
+ while (--_n >= 0) *_x++ &= *_y++;\
+}
+
+/*
+ * a := a - b
+ */
+#define SET_SUBTRACT(a, b, n)\
+{\
+ register bpf_u_int32 *_x = a, *_y = b;\
+ register int _n = n;\
+ while (--_n >= 0) *_x++ &=~ *_y++;\
+}
+
+/*
+ * a := a union b
+ */
+#define SET_UNION(a, b, n)\
+{\
+ register bpf_u_int32 *_x = a, *_y = b;\
+ register int _n = n;\
+ while (--_n >= 0) *_x++ |= *_y++;\
+}
+
+static uset all_dom_sets;
+static uset all_closure_sets;
+static uset all_edge_sets;
+
+#ifndef MAX
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#endif
+
+static void
+find_levels_r(struct block *b)
+{
+ int level;
+
+ if (isMarked(b))
+ return;
+
+ Mark(b);
+ b->link = 0;
+
+ if (JT(b)) {
+ find_levels_r(JT(b));
+ find_levels_r(JF(b));
+ level = MAX(JT(b)->level, JF(b)->level) + 1;
+ } else
+ level = 0;
+ b->level = level;
+ b->link = levels[level];
+ levels[level] = b;
+}
+
+/*
+ * Level graph. The levels go from 0 at the leaves to
+ * N_LEVELS at the root. The levels[] array points to the
+ * first node of the level list, whose elements are linked
+ * with the 'link' field of the struct block.
+ */
+static void
+find_levels(struct block *root)
+{
+ memset((char *)levels, 0, n_blocks * sizeof(*levels));
+ unMarkAll();
+ find_levels_r(root);
+}
+
+/*
+ * Find dominator relationships.
+ * Assumes graph has been leveled.
+ */
+static void
+find_dom(struct block *root)
+{
+ int i;
+ struct block *b;
+ bpf_u_int32 *x;
+
+ /*
+ * Initialize sets to contain all nodes.
+ */
+ x = all_dom_sets;
+ i = n_blocks * nodewords;
+ while (--i >= 0)
+ *x++ = ~0;
+ /* Root starts off empty. */
+ for (i = nodewords; --i >= 0;)
+ root->dom[i] = 0;
+
+ /* root->level is the highest level no found. */
+ for (i = root->level; i >= 0; --i) {
+ for (b = levels[i]; b; b = b->link) {
+ SET_INSERT(b->dom, b->id);
+ if (JT(b) == 0)
+ continue;
+ SET_INTERSECT(JT(b)->dom, b->dom, nodewords);
+ SET_INTERSECT(JF(b)->dom, b->dom, nodewords);
+ }
+ }
+}
+
+static void
+propedom(struct edge *ep)
+{
+ SET_INSERT(ep->edom, ep->id);
+ if (ep->succ) {
+ SET_INTERSECT(ep->succ->et.edom, ep->edom, edgewords);
+ SET_INTERSECT(ep->succ->ef.edom, ep->edom, edgewords);
+ }
+}
+
+/*
+ * Compute edge dominators.
+ * Assumes graph has been leveled and predecessors established.
+ */
+static void
+find_edom(struct block *root)
+{
+ int i;
+ uset x;
+ struct block *b;
+
+ x = all_edge_sets;
+ for (i = n_edges * edgewords; --i >= 0; )
+ x[i] = ~0;
+
+ /* root->level is the highest level no found. */
+ memset(root->et.edom, 0, edgewords * sizeof(*(uset)0));
+ memset(root->ef.edom, 0, edgewords * sizeof(*(uset)0));
+ for (i = root->level; i >= 0; --i) {
+ for (b = levels[i]; b != 0; b = b->link) {
+ propedom(&b->et);
+ propedom(&b->ef);
+ }
+ }
+}
+
+/*
+ * Find the backwards transitive closure of the flow graph. These sets
+ * are backwards in the sense that we find the set of nodes that reach
+ * a given node, not the set of nodes that can be reached by a node.
+ *
+ * Assumes graph has been leveled.
+ */
+static void
+find_closure(struct block *root)
+{
+ int i;
+ struct block *b;
+
+ /*
+ * Initialize sets to contain no nodes.
+ */
+ memset((char *)all_closure_sets, 0,
+ n_blocks * nodewords * sizeof(*all_closure_sets));
+
+ /* root->level is the highest level no found. */
+ for (i = root->level; i >= 0; --i) {
+ for (b = levels[i]; b; b = b->link) {
+ SET_INSERT(b->closure, b->id);
+ if (JT(b) == 0)
+ continue;
+ SET_UNION(JT(b)->closure, b->closure, nodewords);
+ SET_UNION(JF(b)->closure, b->closure, nodewords);
+ }
+ }
+}
+
+/*
+ * Return the register number that is used by s. If A and X are both
+ * used, return AX_ATOM. If no register is used, return -1.
+ *
+ * The implementation should probably change to an array access.
+ */
+static int
+atomuse(struct stmt *s)
+{
+ register int c = s->code;
+
+ if (c == NOP)
+ return -1;
+
+ switch (BPF_CLASS(c)) {
+
+ case BPF_RET:
+ return (BPF_RVAL(c) == BPF_A) ? A_ATOM :
+ (BPF_RVAL(c) == BPF_X) ? X_ATOM : -1;
+
+ case BPF_LD:
+ case BPF_LDX:
+ return (BPF_MODE(c) == BPF_IND) ? X_ATOM :
+ (BPF_MODE(c) == BPF_MEM) ? s->k : -1;
+
+ case BPF_ST:
+ return A_ATOM;
+
+ case BPF_STX:
+ return X_ATOM;
+
+ case BPF_JMP:
+ case BPF_ALU:
+ if (BPF_SRC(c) == BPF_X)
+ return AX_ATOM;
+ return A_ATOM;
+
+ case BPF_MISC:
+ return BPF_MISCOP(c) == BPF_TXA ? X_ATOM : A_ATOM;
+ }
+ abort();
+ /* NOTREACHED */
+}
+
+/*
+ * Return the register number that is defined by 's'. We assume that
+ * a single stmt cannot define more than one register. If no register
+ * is defined, return -1.
+ *
+ * The implementation should probably change to an array access.
+ */
+static int
+atomdef(struct stmt *s)
+{
+ if (s->code == NOP)
+ return -1;
+
+ switch (BPF_CLASS(s->code)) {
+
+ case BPF_LD:
+ case BPF_ALU:
+ return A_ATOM;
+
+ case BPF_LDX:
+ return X_ATOM;
+
+ case BPF_ST:
+ case BPF_STX:
+ return s->k;
+
+ case BPF_MISC:
+ return BPF_MISCOP(s->code) == BPF_TAX ? X_ATOM : A_ATOM;
+ }
+ return -1;
+}
+
+/*
+ * Compute the sets of registers used, defined, and killed by 'b'.
+ *
+ * "Used" means that a statement in 'b' uses the register before any
+ * statement in 'b' defines it, i.e. it uses the value left in
+ * that register by a predecessor block of this block.
+ * "Defined" means that a statement in 'b' defines it.
+ * "Killed" means that a statement in 'b' defines it before any
+ * statement in 'b' uses it, i.e. it kills the value left in that
+ * register by a predecessor block of this block.
+ */
+static void
+compute_local_ud(struct block *b)
+{
+ struct slist *s;
+ atomset def = 0, use = 0, kill = 0;
+ int atom;
+
+ for (s = b->stmts; s; s = s->next) {
+ if (s->s.code == NOP)
+ continue;
+ atom = atomuse(&s->s);
+ if (atom >= 0) {
+ if (atom == AX_ATOM) {
+ if (!ATOMELEM(def, X_ATOM))
+ use |= ATOMMASK(X_ATOM);
+ if (!ATOMELEM(def, A_ATOM))
+ use |= ATOMMASK(A_ATOM);
+ }
+ else if (atom < N_ATOMS) {
+ if (!ATOMELEM(def, atom))
+ use |= ATOMMASK(atom);
+ }
+ else
+ abort();
+ }
+ atom = atomdef(&s->s);
+ if (atom >= 0) {
+ if (!ATOMELEM(use, atom))
+ kill |= ATOMMASK(atom);
+ def |= ATOMMASK(atom);
+ }
+ }
+ if (BPF_CLASS(b->s.code) == BPF_JMP) {
+ /*
+ * XXX - what about RET?
+ */
+ atom = atomuse(&b->s);
+ if (atom >= 0) {
+ if (atom == AX_ATOM) {
+ if (!ATOMELEM(def, X_ATOM))
+ use |= ATOMMASK(X_ATOM);
+ if (!ATOMELEM(def, A_ATOM))
+ use |= ATOMMASK(A_ATOM);
+ }
+ else if (atom < N_ATOMS) {
+ if (!ATOMELEM(def, atom))
+ use |= ATOMMASK(atom);
+ }
+ else
+ abort();
+ }
+ }
+
+ b->def = def;
+ b->kill = kill;
+ b->in_use = use;
+}
+
+/*
+ * Assume graph is already leveled.
+ */
+static void
+find_ud(struct block *root)
+{
+ int i, maxlevel;
+ struct block *p;
+
+ /*
+ * root->level is the highest level no found;
+ * count down from there.
+ */
+ maxlevel = root->level;
+ for (i = maxlevel; i >= 0; --i)
+ for (p = levels[i]; p; p = p->link) {
+ compute_local_ud(p);
+ p->out_use = 0;
+ }
+
+ for (i = 1; i <= maxlevel; ++i) {
+ for (p = levels[i]; p; p = p->link) {
+ p->out_use |= JT(p)->in_use | JF(p)->in_use;
+ p->in_use |= p->out_use &~ p->kill;
+ }
+ }
+}
+
+/*
+ * These data structures are used in a Cocke and Shwarz style
+ * value numbering scheme. Since the flowgraph is acyclic,
+ * exit values can be propagated from a node's predecessors
+ * provided it is uniquely defined.
+ */
+struct valnode {
+ int code;
+ int v0, v1;
+ int val;
+ struct valnode *next;
+};
+
+#define MODULUS 213
+static struct valnode *hashtbl[MODULUS];
+static int curval;
+static int maxval;
+
+/* Integer constants mapped with the load immediate opcode. */
+#define K(i) F(BPF_LD|BPF_IMM|BPF_W, i, 0L)
+
+struct vmapinfo {
+ int is_const;
+ bpf_int32 const_val;
+};
+
+struct vmapinfo *vmap;
+struct valnode *vnode_base;
+struct valnode *next_vnode;
+
+static void
+init_val(void)
+{
+ curval = 0;
+ next_vnode = vnode_base;
+ memset((char *)vmap, 0, maxval * sizeof(*vmap));
+ memset((char *)hashtbl, 0, sizeof hashtbl);
+}
+
+/* Because we really don't have an IR, this stuff is a little messy. */
+static int
+F(int code, int v0, int v1)
+{
+ u_int hash;
+ int val;
+ struct valnode *p;
+
+ hash = (u_int)code ^ (v0 << 4) ^ (v1 << 8);
+ hash %= MODULUS;
+
+ for (p = hashtbl[hash]; p; p = p->next)
+ if (p->code == code && p->v0 == v0 && p->v1 == v1)
+ return p->val;
+
+ val = ++curval;
+ if (BPF_MODE(code) == BPF_IMM &&
+ (BPF_CLASS(code) == BPF_LD || BPF_CLASS(code) == BPF_LDX)) {
+ vmap[val].const_val = v0;
+ vmap[val].is_const = 1;
+ }
+ p = next_vnode++;
+ p->val = val;
+ p->code = code;
+ p->v0 = v0;
+ p->v1 = v1;
+ p->next = hashtbl[hash];
+ hashtbl[hash] = p;
+
+ return val;
+}
+
+static inline void
+vstore(struct stmt *s, int *valp, int newval, int alter)
+{
+ if (alter && *valp == newval)
+ s->code = NOP;
+ else
+ *valp = newval;
+}
+
+static void
+fold_op(struct stmt *s, int v0, int v1)
+{
+ bpf_u_int32 a, b;
+
+ a = vmap[v0].const_val;
+ b = vmap[v1].const_val;
+
+ switch (BPF_OP(s->code)) {
+ case BPF_ADD:
+ a += b;
+ break;
+
+ case BPF_SUB:
+ a -= b;
+ break;
+
+ case BPF_MUL:
+ a *= b;
+ break;
+
+ case BPF_DIV:
+ if (b == 0)
+ bpf_error("division by zero");
+ a /= b;
+ break;
+
+ case BPF_AND:
+ a &= b;
+ break;
+
+ case BPF_OR:
+ a |= b;
+ break;
+
+ case BPF_LSH:
+ a <<= b;
+ break;
+
+ case BPF_RSH:
+ a >>= b;
+ break;
+
+ case BPF_NEG:
+ a = -a;
+ break;
+
+ default:
+ abort();
+ }
+ s->k = a;
+ s->code = BPF_LD|BPF_IMM;
+ done = 0;
+}
+
+static inline struct slist *
+this_op(struct slist *s)
+{
+ while (s != 0 && s->s.code == NOP)
+ s = s->next;
+ return s;
+}
+
+static void
+opt_not(struct block *b)
+{
+ struct block *tmp = JT(b);
+
+ JT(b) = JF(b);
+ JF(b) = tmp;
+}
+
+static void
+opt_peep(struct block *b)
+{
+ struct slist *s;
+ struct slist *next, *last;
+ int val;
+
+ s = b->stmts;
+ if (s == 0)
+ return;
+
+ last = s;
+ for (/*empty*/; /*empty*/; s = next) {
+ /*
+ * Skip over nops.
+ */
+ s = this_op(s);
+ if (s == 0)
+ break; /* nothing left in the block */
+
+ /*
+ * Find the next real instruction after that one
+ * (skipping nops).
+ */
+ next = this_op(s->next);
+ if (next == 0)
+ break; /* no next instruction */
+ last = next;
+
+ /*
+ * st M[k] --> st M[k]
+ * ldx M[k] tax
+ */
+ if (s->s.code == BPF_ST &&
+ next->s.code == (BPF_LDX|BPF_MEM) &&
+ s->s.k == next->s.k) {
+ done = 0;
+ next->s.code = BPF_MISC|BPF_TAX;
+ }
+ /*
+ * ld #k --> ldx #k
+ * tax txa
+ */
+ if (s->s.code == (BPF_LD|BPF_IMM) &&
+ next->s.code == (BPF_MISC|BPF_TAX)) {
+ s->s.code = BPF_LDX|BPF_IMM;
+ next->s.code = BPF_MISC|BPF_TXA;
+ done = 0;
+ }
+ /*
+ * This is an ugly special case, but it happens
+ * when you say tcp[k] or udp[k] where k is a constant.
+ */
+ if (s->s.code == (BPF_LD|BPF_IMM)) {
+ struct slist *add, *tax, *ild;
+
+ /*
+ * Check that X isn't used on exit from this
+ * block (which the optimizer might cause).
+ * We know the code generator won't generate
+ * any local dependencies.
+ */
+ if (ATOMELEM(b->out_use, X_ATOM))
+ continue;
+
+ /*
+ * Check that the instruction following the ldi
+ * is an addx, or it's an ldxms with an addx
+ * following it (with 0 or more nops between the
+ * ldxms and addx).
+ */
+ if (next->s.code != (BPF_LDX|BPF_MSH|BPF_B))
+ add = next;
+ else
+ add = this_op(next->next);
+ if (add == 0 || add->s.code != (BPF_ALU|BPF_ADD|BPF_X))
+ continue;
+
+ /*
+ * Check that a tax follows that (with 0 or more
+ * nops between them).
+ */
+ tax = this_op(add->next);
+ if (tax == 0 || tax->s.code != (BPF_MISC|BPF_TAX))
+ continue;
+
+ /*
+ * Check that an ild follows that (with 0 or more
+ * nops between them).
+ */
+ ild = this_op(tax->next);
+ if (ild == 0 || BPF_CLASS(ild->s.code) != BPF_LD ||
+ BPF_MODE(ild->s.code) != BPF_IND)
+ continue;
+ /*
+ * We want to turn this sequence:
+ *
+ * (004) ldi #0x2 {s}
+ * (005) ldxms [14] {next} -- optional
+ * (006) addx {add}
+ * (007) tax {tax}
+ * (008) ild [x+0] {ild}
+ *
+ * into this sequence:
+ *
+ * (004) nop
+ * (005) ldxms [14]
+ * (006) nop
+ * (007) nop
+ * (008) ild [x+2]
+ *
+ * XXX We need to check that X is not
+ * subsequently used, because we want to change
+ * what'll be in it after this sequence.
+ *
+ * We know we can eliminate the accumulator
+ * modifications earlier in the sequence since
+ * it is defined by the last stmt of this sequence
+ * (i.e., the last statement of the sequence loads
+ * a value into the accumulator, so we can eliminate
+ * earlier operations on the accumulator).
+ */
+ ild->s.k += s->s.k;
+ s->s.code = NOP;
+ add->s.code = NOP;
+ tax->s.code = NOP;
+ done = 0;
+ }
+ }
+ /*
+ * If the comparison at the end of a block is an equality
+ * comparison against a constant, and nobody uses the value
+ * we leave in the A register at the end of a block, and
+ * the operation preceding the comparison is an arithmetic
+ * operation, we can sometime optimize it away.
+ */
+ if (b->s.code == (BPF_JMP|BPF_JEQ|BPF_K) &&
+ !ATOMELEM(b->out_use, A_ATOM)) {
+ /*
+ * We can optimize away certain subtractions of the
+ * X register.
+ */
+ if (last->s.code == (BPF_ALU|BPF_SUB|BPF_X)) {
+ val = b->val[X_ATOM];
+ if (vmap[val].is_const) {
+ /*
+ * If we have a subtract to do a comparison,
+ * and the X register is a known constant,
+ * we can merge this value into the
+ * comparison:
+ *
+ * sub x -> nop
+ * jeq #y jeq #(x+y)
+ */
+ b->s.k += vmap[val].const_val;
+ last->s.code = NOP;
+ done = 0;
+ } else if (b->s.k == 0) {
+ /*
+ * If the X register isn't a constant,
+ * and the comparison in the test is
+ * against 0, we can compare with the
+ * X register, instead:
+ *
+ * sub x -> nop
+ * jeq #0 jeq x
+ */
+ last->s.code = NOP;
+ b->s.code = BPF_JMP|BPF_JEQ|BPF_X;
+ done = 0;
+ }
+ }
+ /*
+ * Likewise, a constant subtract can be simplified:
+ *
+ * sub #x -> nop
+ * jeq #y -> jeq #(x+y)
+ */
+ else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K)) {
+ last->s.code = NOP;
+ b->s.k += last->s.k;
+ done = 0;
+ }
+ /*
+ * And, similarly, a constant AND can be simplified
+ * if we're testing against 0, i.e.:
+ *
+ * and #k nop
+ * jeq #0 -> jset #k
+ */
+ else if (last->s.code == (BPF_ALU|BPF_AND|BPF_K) &&
+ b->s.k == 0) {
+ b->s.k = last->s.k;
+ b->s.code = BPF_JMP|BPF_K|BPF_JSET;
+ last->s.code = NOP;
+ done = 0;
+ opt_not(b);
+ }
+ }
+ /*
+ * jset #0 -> never
+ * jset #ffffffff -> always
+ */
+ if (b->s.code == (BPF_JMP|BPF_K|BPF_JSET)) {
+ if (b->s.k == 0)
+ JT(b) = JF(b);
+ if (b->s.k == 0xffffffff)
+ JF(b) = JT(b);
+ }
+ /*
+ * If we're comparing against the index register, and the index
+ * register is a known constant, we can just compare against that
+ * constant.
+ */
+ val = b->val[X_ATOM];
+ if (vmap[val].is_const && BPF_SRC(b->s.code) == BPF_X) {
+ bpf_int32 v = vmap[val].const_val;
+ b->s.code &= ~BPF_X;
+ b->s.k = v;
+ }
+ /*
+ * If the accumulator is a known constant, we can compute the
+ * comparison result.
+ */
+ val = b->val[A_ATOM];
+ if (vmap[val].is_const && BPF_SRC(b->s.code) == BPF_K) {
+ bpf_int32 v = vmap[val].const_val;
+ switch (BPF_OP(b->s.code)) {
+
+ case BPF_JEQ:
+ v = v == b->s.k;
+ break;
+
+ case BPF_JGT:
+ v = (unsigned)v > b->s.k;
+ break;
+
+ case BPF_JGE:
+ v = (unsigned)v >= b->s.k;
+ break;
+
+ case BPF_JSET:
+ v &= b->s.k;
+ break;
+
+ default:
+ abort();
+ }
+ if (JF(b) != JT(b))
+ done = 0;
+ if (v)
+ JF(b) = JT(b);
+ else
+ JT(b) = JF(b);
+ }
+}
+
+/*
+ * Compute the symbolic value of expression of 's', and update
+ * anything it defines in the value table 'val'. If 'alter' is true,
+ * do various optimizations. This code would be cleaner if symbolic
+ * evaluation and code transformations weren't folded together.
+ */
+static void
+opt_stmt(struct stmt *s, int val[], int alter)
+{
+ int op;
+ int v;
+
+ switch (s->code) {
+
+ case BPF_LD|BPF_ABS|BPF_W:
+ case BPF_LD|BPF_ABS|BPF_H:
+ case BPF_LD|BPF_ABS|BPF_B:
+ v = F(s->code, s->k, 0L);
+ vstore(s, &val[A_ATOM], v, alter);
+ break;
+
+ case BPF_LD|BPF_IND|BPF_W:
+ case BPF_LD|BPF_IND|BPF_H:
+ case BPF_LD|BPF_IND|BPF_B:
+ v = val[X_ATOM];
+ if (alter && vmap[v].is_const) {
+ s->code = BPF_LD|BPF_ABS|BPF_SIZE(s->code);
+ s->k += vmap[v].const_val;
+ v = F(s->code, s->k, 0L);
+ done = 0;
+ }
+ else
+ v = F(s->code, s->k, v);
+ vstore(s, &val[A_ATOM], v, alter);
+ break;
+
+ case BPF_LD|BPF_LEN:
+ v = F(s->code, 0L, 0L);
+ vstore(s, &val[A_ATOM], v, alter);
+ break;
+
+ case BPF_LD|BPF_IMM:
+ v = K(s->k);
+ vstore(s, &val[A_ATOM], v, alter);
+ break;
+
+ case BPF_LDX|BPF_IMM:
+ v = K(s->k);
+ vstore(s, &val[X_ATOM], v, alter);
+ break;
+
+ case BPF_LDX|BPF_MSH|BPF_B:
+ v = F(s->code, s->k, 0L);
+ vstore(s, &val[X_ATOM], v, alter);
+ break;
+
+ case BPF_ALU|BPF_NEG:
+ if (alter && vmap[val[A_ATOM]].is_const) {
+ s->code = BPF_LD|BPF_IMM;
+ s->k = -vmap[val[A_ATOM]].const_val;
+ val[A_ATOM] = K(s->k);
+ }
+ else
+ val[A_ATOM] = F(s->code, val[A_ATOM], 0L);
+ break;
+
+ case BPF_ALU|BPF_ADD|BPF_K:
+ case BPF_ALU|BPF_SUB|BPF_K:
+ case BPF_ALU|BPF_MUL|BPF_K:
+ case BPF_ALU|BPF_DIV|BPF_K:
+ case BPF_ALU|BPF_AND|BPF_K:
+ case BPF_ALU|BPF_OR|BPF_K:
+ case BPF_ALU|BPF_LSH|BPF_K:
+ case BPF_ALU|BPF_RSH|BPF_K:
+ op = BPF_OP(s->code);
+ if (alter) {
+ if (s->k == 0) {
+ /* don't optimize away "sub #0"
+ * as it may be needed later to
+ * fixup the generated math code */
+ if (op == BPF_ADD ||
+ op == BPF_LSH || op == BPF_RSH ||
+ op == BPF_OR) {
+ s->code = NOP;
+ break;
+ }
+ if (op == BPF_MUL || op == BPF_AND) {
+ s->code = BPF_LD|BPF_IMM;
+ val[A_ATOM] = K(s->k);
+ break;
+ }
+ }
+ if (vmap[val[A_ATOM]].is_const) {
+ fold_op(s, val[A_ATOM], K(s->k));
+ val[A_ATOM] = K(s->k);
+ break;
+ }
+ }
+ val[A_ATOM] = F(s->code, val[A_ATOM], K(s->k));
+ break;
+
+ case BPF_ALU|BPF_ADD|BPF_X:
+ case BPF_ALU|BPF_SUB|BPF_X:
+ case BPF_ALU|BPF_MUL|BPF_X:
+ case BPF_ALU|BPF_DIV|BPF_X:
+ case BPF_ALU|BPF_AND|BPF_X:
+ case BPF_ALU|BPF_OR|BPF_X:
+ case BPF_ALU|BPF_LSH|BPF_X:
+ case BPF_ALU|BPF_RSH|BPF_X:
+ op = BPF_OP(s->code);
+ if (alter && vmap[val[X_ATOM]].is_const) {
+ if (vmap[val[A_ATOM]].is_const) {
+ fold_op(s, val[A_ATOM], val[X_ATOM]);
+ val[A_ATOM] = K(s->k);
+ }
+ else {
+ s->code = BPF_ALU|BPF_K|op;
+ s->k = vmap[val[X_ATOM]].const_val;
+ done = 0;
+ val[A_ATOM] =
+ F(s->code, val[A_ATOM], K(s->k));
+ }
+ break;
+ }
+ /*
+ * Check if we're doing something to an accumulator
+ * that is 0, and simplify. This may not seem like
+ * much of a simplification but it could open up further
+ * optimizations.
+ * XXX We could also check for mul by 1, etc.
+ */
+ if (alter && vmap[val[A_ATOM]].is_const
+ && vmap[val[A_ATOM]].const_val == 0) {
+ if (op == BPF_ADD || op == BPF_OR) {
+ s->code = BPF_MISC|BPF_TXA;
+ vstore(s, &val[A_ATOM], val[X_ATOM], alter);
+ break;
+ }
+ else if (op == BPF_MUL || op == BPF_DIV ||
+ op == BPF_AND || op == BPF_LSH || op == BPF_RSH) {
+ s->code = BPF_LD|BPF_IMM;
+ s->k = 0;
+ vstore(s, &val[A_ATOM], K(s->k), alter);
+ break;
+ }
+ else if (op == BPF_NEG) {
+ s->code = NOP;
+ break;
+ }
+ }
+ val[A_ATOM] = F(s->code, val[A_ATOM], val[X_ATOM]);
+ break;
+
+ case BPF_MISC|BPF_TXA:
+ vstore(s, &val[A_ATOM], val[X_ATOM], alter);
+ break;
+
+ case BPF_LD|BPF_MEM:
+ v = val[s->k];
+ if (alter && vmap[v].is_const) {
+ s->code = BPF_LD|BPF_IMM;
+ s->k = vmap[v].const_val;
+ done = 0;
+ }
+ vstore(s, &val[A_ATOM], v, alter);
+ break;
+
+ case BPF_MISC|BPF_TAX:
+ vstore(s, &val[X_ATOM], val[A_ATOM], alter);
+ break;
+
+ case BPF_LDX|BPF_MEM:
+ v = val[s->k];
+ if (alter && vmap[v].is_const) {
+ s->code = BPF_LDX|BPF_IMM;
+ s->k = vmap[v].const_val;
+ done = 0;
+ }
+ vstore(s, &val[X_ATOM], v, alter);
+ break;
+
+ case BPF_ST:
+ vstore(s, &val[s->k], val[A_ATOM], alter);
+ break;
+
+ case BPF_STX:
+ vstore(s, &val[s->k], val[X_ATOM], alter);
+ break;
+ }
+}
+
+static void
+deadstmt(register struct stmt *s, register struct stmt *last[])
+{
+ register int atom;
+
+ atom = atomuse(s);
+ if (atom >= 0) {
+ if (atom == AX_ATOM) {
+ last[X_ATOM] = 0;
+ last[A_ATOM] = 0;
+ }
+ else
+ last[atom] = 0;
+ }
+ atom = atomdef(s);
+ if (atom >= 0) {
+ if (last[atom]) {
+ done = 0;
+ last[atom]->code = NOP;
+ }
+ last[atom] = s;
+ }
+}
+
+static void
+opt_deadstores(register struct block *b)
+{
+ register struct slist *s;
+ register int atom;
+ struct stmt *last[N_ATOMS];
+
+ memset((char *)last, 0, sizeof last);
+
+ for (s = b->stmts; s != 0; s = s->next)
+ deadstmt(&s->s, last);
+ deadstmt(&b->s, last);
+
+ for (atom = 0; atom < N_ATOMS; ++atom)
+ if (last[atom] && !ATOMELEM(b->out_use, atom)) {
+ last[atom]->code = NOP;
+ done = 0;
+ }
+}
+
+static void
+opt_blk(struct block *b, int do_stmts)
+{
+ struct slist *s;
+ struct edge *p;
+ int i;
+ bpf_int32 aval, xval;
+
+#if 0
+ for (s = b->stmts; s && s->next; s = s->next)
+ if (BPF_CLASS(s->s.code) == BPF_JMP) {
+ do_stmts = 0;
+ break;
+ }
+#endif
+
+ /*
+ * Initialize the atom values.
+ */
+ p = b->in_edges;
+ if (p == 0) {
+ /*
+ * We have no predecessors, so everything is undefined
+ * upon entry to this block.
+ */
+ memset((char *)b->val, 0, sizeof(b->val));
+ } else {
+ /*
+ * Inherit values from our predecessors.
+ *
+ * First, get the values from the predecessor along the
+ * first edge leading to this node.
+ */
+ memcpy((char *)b->val, (char *)p->pred->val, sizeof(b->val));
+ /*
+ * Now look at all the other nodes leading to this node.
+ * If, for the predecessor along that edge, a register
+ * has a different value from the one we have (i.e.,
+ * control paths are merging, and the merging paths
+ * assign different values to that register), give the
+ * register the undefined value of 0.
+ */
+ while ((p = p->next) != NULL) {
+ for (i = 0; i < N_ATOMS; ++i)
+ if (b->val[i] != p->pred->val[i])
+ b->val[i] = 0;
+ }
+ }
+ aval = b->val[A_ATOM];
+ xval = b->val[X_ATOM];
+ for (s = b->stmts; s; s = s->next)
+ opt_stmt(&s->s, b->val, do_stmts);
+
+ /*
+ * This is a special case: if we don't use anything from this
+ * block, and we load the accumulator or index register with a
+ * value that is already there, or if this block is a return,
+ * eliminate all the statements.
+ *
+ * XXX - what if it does a store?
+ *
+ * XXX - why does it matter whether we use anything from this
+ * block? If the accumulator or index register doesn't change
+ * its value, isn't that OK even if we use that value?
+ *
+ * XXX - if we load the accumulator with a different value,
+ * and the block ends with a conditional branch, we obviously
+ * can't eliminate it, as the branch depends on that value.
+ * For the index register, the conditional branch only depends
+ * on the index register value if the test is against the index
+ * register value rather than a constant; if nothing uses the
+ * value we put into the index register, and we're not testing
+ * against the index register's value, and there aren't any
+ * other problems that would keep us from eliminating this
+ * block, can we eliminate it?
+ */
+ if (do_stmts &&
+ ((b->out_use == 0 && aval != 0 && b->val[A_ATOM] == aval &&
+ xval != 0 && b->val[X_ATOM] == xval) ||
+ BPF_CLASS(b->s.code) == BPF_RET)) {
+ if (b->stmts != 0) {
+ b->stmts = 0;
+ done = 0;
+ }
+ } else {
+ opt_peep(b);
+ opt_deadstores(b);
+ }
+ /*
+ * Set up values for branch optimizer.
+ */
+ if (BPF_SRC(b->s.code) == BPF_K)
+ b->oval = K(b->s.k);
+ else
+ b->oval = b->val[X_ATOM];
+ b->et.code = b->s.code;
+ b->ef.code = -b->s.code;
+}
+
+/*
+ * Return true if any register that is used on exit from 'succ', has
+ * an exit value that is different from the corresponding exit value
+ * from 'b'.
+ */
+static int
+use_conflict(struct block *b, struct block *succ)
+{
+ int atom;
+ atomset use = succ->out_use;
+
+ if (use == 0)
+ return 0;
+
+ for (atom = 0; atom < N_ATOMS; ++atom)
+ if (ATOMELEM(use, atom))
+ if (b->val[atom] != succ->val[atom])
+ return 1;
+ return 0;
+}
+
+static struct block *
+fold_edge(struct block *child, struct edge *ep)
+{
+ int sense;
+ int aval0, aval1, oval0, oval1;
+ int code = ep->code;
+
+ if (code < 0) {
+ code = -code;
+ sense = 0;
+ } else
+ sense = 1;
+
+ if (child->s.code != code)
+ return 0;
+
+ aval0 = child->val[A_ATOM];
+ oval0 = child->oval;
+ aval1 = ep->pred->val[A_ATOM];
+ oval1 = ep->pred->oval;
+
+ if (aval0 != aval1)
+ return 0;
+
+ if (oval0 == oval1)
+ /*
+ * The operands of the branch instructions are
+ * identical, so the result is true if a true
+ * branch was taken to get here, otherwise false.
+ */
+ return sense ? JT(child) : JF(child);
+
+ if (sense && code == (BPF_JMP|BPF_JEQ|BPF_K))
+ /*
+ * At this point, we only know the comparison if we
+ * came down the true branch, and it was an equality
+ * comparison with a constant.
+ *
+ * I.e., if we came down the true branch, and the branch
+ * was an equality comparison with a constant, we know the
+ * accumulator contains that constant. If we came down
+ * the false branch, or the comparison wasn't with a
+ * constant, we don't know what was in the accumulator.
+ *
+ * We rely on the fact that distinct constants have distinct
+ * value numbers.
+ */
+ return JF(child);
+
+ return 0;
+}
+
+static void
+opt_j(struct edge *ep)
+{
+ register int i, k;
+ register struct block *target;
+
+ if (JT(ep->succ) == 0)
+ return;
+
+ if (JT(ep->succ) == JF(ep->succ)) {
+ /*
+ * Common branch targets can be eliminated, provided
+ * there is no data dependency.
+ */
+ if (!use_conflict(ep->pred, ep->succ->et.succ)) {
+ done = 0;
+ ep->succ = JT(ep->succ);
+ }
+ }
+ /*
+ * For each edge dominator that matches the successor of this
+ * edge, promote the edge successor to the its grandchild.
+ *
+ * XXX We violate the set abstraction here in favor a reasonably
+ * efficient loop.
+ */
+ top:
+ for (i = 0; i < edgewords; ++i) {
+ register bpf_u_int32 x = ep->edom[i];
+
+ while (x != 0) {
+ k = ffs(x) - 1;
+ x &=~ (1 << k);
+ k += i * BITS_PER_WORD;
+
+ target = fold_edge(ep->succ, edges[k]);
+ /*
+ * Check that there is no data dependency between
+ * nodes that will be violated if we move the edge.
+ */
+ if (target != 0 && !use_conflict(ep->pred, target)) {
+ done = 0;
+ ep->succ = target;
+ if (JT(target) != 0)
+ /*
+ * Start over unless we hit a leaf.
+ */
+ goto top;
+ return;
+ }
+ }
+ }
+}
+
+
+static void
+or_pullup(struct block *b)
+{
+ int val, at_top;
+ struct block *pull;
+ struct block **diffp, **samep;
+ struct edge *ep;
+
+ ep = b->in_edges;
+ if (ep == 0)
+ return;
+
+ /*
+ * Make sure each predecessor loads the same value.
+ * XXX why?
+ */
+ val = ep->pred->val[A_ATOM];
+ for (ep = ep->next; ep != 0; ep = ep->next)
+ if (val != ep->pred->val[A_ATOM])
+ return;
+
+ if (JT(b->in_edges->pred) == b)
+ diffp = &JT(b->in_edges->pred);
+ else
+ diffp = &JF(b->in_edges->pred);
+
+ at_top = 1;
+ while (1) {
+ if (*diffp == 0)
+ return;
+
+ if (JT(*diffp) != JT(b))
+ return;
+
+ if (!SET_MEMBER((*diffp)->dom, b->id))
+ return;
+
+ if ((*diffp)->val[A_ATOM] != val)
+ break;
+
+ diffp = &JF(*diffp);
+ at_top = 0;
+ }
+ samep = &JF(*diffp);
+ while (1) {
+ if (*samep == 0)
+ return;
+
+ if (JT(*samep) != JT(b))
+ return;
+
+ if (!SET_MEMBER((*samep)->dom, b->id))
+ return;
+
+ if ((*samep)->val[A_ATOM] == val)
+ break;
+
+ /* XXX Need to check that there are no data dependencies
+ between dp0 and dp1. Currently, the code generator
+ will not produce such dependencies. */
+ samep = &JF(*samep);
+ }
+#ifdef notdef
+ /* XXX This doesn't cover everything. */
+ for (i = 0; i < N_ATOMS; ++i)
+ if ((*samep)->val[i] != pred->val[i])
+ return;
+#endif
+ /* Pull up the node. */
+ pull = *samep;
+ *samep = JF(pull);
+ JF(pull) = *diffp;
+
+ /*
+ * At the top of the chain, each predecessor needs to point at the
+ * pulled up node. Inside the chain, there is only one predecessor
+ * to worry about.
+ */
+ if (at_top) {
+ for (ep = b->in_edges; ep != 0; ep = ep->next) {
+ if (JT(ep->pred) == b)
+ JT(ep->pred) = pull;
+ else
+ JF(ep->pred) = pull;
+ }
+ }
+ else
+ *diffp = pull;
+
+ done = 0;
+}
+
+static void
+and_pullup(struct block *b)
+{
+ int val, at_top;
+ struct block *pull;
+ struct block **diffp, **samep;
+ struct edge *ep;
+
+ ep = b->in_edges;
+ if (ep == 0)
+ return;
+
+ /*
+ * Make sure each predecessor loads the same value.
+ */
+ val = ep->pred->val[A_ATOM];
+ for (ep = ep->next; ep != 0; ep = ep->next)
+ if (val != ep->pred->val[A_ATOM])
+ return;
+
+ if (JT(b->in_edges->pred) == b)
+ diffp = &JT(b->in_edges->pred);
+ else
+ diffp = &JF(b->in_edges->pred);
+
+ at_top = 1;
+ while (1) {
+ if (*diffp == 0)
+ return;
+
+ if (JF(*diffp) != JF(b))
+ return;
+
+ if (!SET_MEMBER((*diffp)->dom, b->id))
+ return;
+
+ if ((*diffp)->val[A_ATOM] != val)
+ break;
+
+ diffp = &JT(*diffp);
+ at_top = 0;
+ }
+ samep = &JT(*diffp);
+ while (1) {
+ if (*samep == 0)
+ return;
+
+ if (JF(*samep) != JF(b))
+ return;
+
+ if (!SET_MEMBER((*samep)->dom, b->id))
+ return;
+
+ if ((*samep)->val[A_ATOM] == val)
+ break;
+
+ /* XXX Need to check that there are no data dependencies
+ between diffp and samep. Currently, the code generator
+ will not produce such dependencies. */
+ samep = &JT(*samep);
+ }
+#ifdef notdef
+ /* XXX This doesn't cover everything. */
+ for (i = 0; i < N_ATOMS; ++i)
+ if ((*samep)->val[i] != pred->val[i])
+ return;
+#endif
+ /* Pull up the node. */
+ pull = *samep;
+ *samep = JT(pull);
+ JT(pull) = *diffp;
+
+ /*
+ * At the top of the chain, each predecessor needs to point at the
+ * pulled up node. Inside the chain, there is only one predecessor
+ * to worry about.
+ */
+ if (at_top) {
+ for (ep = b->in_edges; ep != 0; ep = ep->next) {
+ if (JT(ep->pred) == b)
+ JT(ep->pred) = pull;
+ else
+ JF(ep->pred) = pull;
+ }
+ }
+ else
+ *diffp = pull;
+
+ done = 0;
+}
+
+static void
+opt_blks(struct block *root, int do_stmts)
+{
+ int i, maxlevel;
+ struct block *p;
+
+ init_val();
+ maxlevel = root->level;
+
+ find_inedges(root);
+ for (i = maxlevel; i >= 0; --i)
+ for (p = levels[i]; p; p = p->link)
+ opt_blk(p, do_stmts);
+
+ if (do_stmts)
+ /*
+ * No point trying to move branches; it can't possibly
+ * make a difference at this point.
+ */
+ return;
+
+ for (i = 1; i <= maxlevel; ++i) {
+ for (p = levels[i]; p; p = p->link) {
+ opt_j(&p->et);
+ opt_j(&p->ef);
+ }
+ }
+
+ find_inedges(root);
+ for (i = 1; i <= maxlevel; ++i) {
+ for (p = levels[i]; p; p = p->link) {
+ or_pullup(p);
+ and_pullup(p);
+ }
+ }
+}
+
+static inline void
+link_inedge(struct edge *parent, struct block *child)
+{
+ parent->next = child->in_edges;
+ child->in_edges = parent;
+}
+
+static void
+find_inedges(struct block *root)
+{
+ int i;
+ struct block *b;
+
+ for (i = 0; i < n_blocks; ++i)
+ blocks[i]->in_edges = 0;
+
+ /*
+ * Traverse the graph, adding each edge to the predecessor
+ * list of its successors. Skip the leaves (i.e. level 0).
+ */
+ for (i = root->level; i > 0; --i) {
+ for (b = levels[i]; b != 0; b = b->link) {
+ link_inedge(&b->et, JT(b));
+ link_inedge(&b->ef, JF(b));
+ }
+ }
+}
+
+static void
+opt_root(struct block **b)
+{
+ struct slist *tmp, *s;
+
+ s = (*b)->stmts;
+ (*b)->stmts = 0;
+ while (BPF_CLASS((*b)->s.code) == BPF_JMP && JT(*b) == JF(*b))
+ *b = JT(*b);
+
+ tmp = (*b)->stmts;
+ if (tmp != 0)
+ sappend(s, tmp);
+ (*b)->stmts = s;
+
+ /*
+ * If the root node is a return, then there is no
+ * point executing any statements (since the bpf machine
+ * has no side effects).
+ */
+ if (BPF_CLASS((*b)->s.code) == BPF_RET)
+ (*b)->stmts = 0;
+}
+
+static void
+opt_loop(struct block *root, int do_stmts)
+{
+
+#ifdef BDEBUG
+ if (dflag > 1) {
+ printf("opt_loop(root, %d) begin\n", do_stmts);
+ opt_dump(root);
+ }
+#endif
+ do {
+ done = 1;
+ find_levels(root);
+ find_dom(root);
+ find_closure(root);
+ find_ud(root);
+ find_edom(root);
+ opt_blks(root, do_stmts);
+#ifdef BDEBUG
+ if (dflag > 1) {
+ printf("opt_loop(root, %d) bottom, done=%d\n", do_stmts, done);
+ opt_dump(root);
+ }
+#endif
+ } while (!done);
+}
+
+/*
+ * Optimize the filter code in its dag representation.
+ */
+void
+bpf_optimize(struct block **rootp)
+{
+ struct block *root;
+
+ root = *rootp;
+
+ opt_init(root);
+ opt_loop(root, 0);
+ opt_loop(root, 1);
+ intern_blocks(root);
+#ifdef BDEBUG
+ if (dflag > 1) {
+ printf("after intern_blocks()\n");
+ opt_dump(root);
+ }
+#endif
+ opt_root(rootp);
+#ifdef BDEBUG
+ if (dflag > 1) {
+ printf("after opt_root()\n");
+ opt_dump(root);
+ }
+#endif
+ opt_cleanup();
+}
+
+static void
+make_marks(struct block *p)
+{
+ if (!isMarked(p)) {
+ Mark(p);
+ if (BPF_CLASS(p->s.code) != BPF_RET) {
+ make_marks(JT(p));
+ make_marks(JF(p));
+ }
+ }
+}
+
+/*
+ * Mark code array such that isMarked(i) is true
+ * only for nodes that are alive.
+ */
+static void
+mark_code(struct block *p)
+{
+ cur_mark += 1;
+ make_marks(p);
+}
+
+/*
+ * True iff the two stmt lists load the same value from the packet into
+ * the accumulator.
+ */
+static int
+eq_slist(struct slist *x, struct slist *y)
+{
+ while (1) {
+ while (x && x->s.code == NOP)
+ x = x->next;
+ while (y && y->s.code == NOP)
+ y = y->next;
+ if (x == 0)
+ return y == 0;
+ if (y == 0)
+ return x == 0;
+ if (x->s.code != y->s.code || x->s.k != y->s.k)
+ return 0;
+ x = x->next;
+ y = y->next;
+ }
+}
+
+static inline int
+eq_blk(struct block *b0, struct block *b1)
+{
+ if (b0->s.code == b1->s.code &&
+ b0->s.k == b1->s.k &&
+ b0->et.succ == b1->et.succ &&
+ b0->ef.succ == b1->ef.succ)
+ return eq_slist(b0->stmts, b1->stmts);
+ return 0;
+}
+
+static void
+intern_blocks(struct block *root)
+{
+ struct block *p;
+ int i, j;
+ int done1; /* don't shadow global */
+ top:
+ done1 = 1;
+ for (i = 0; i < n_blocks; ++i)
+ blocks[i]->link = 0;
+
+ mark_code(root);
+
+ for (i = n_blocks - 1; --i >= 0; ) {
+ if (!isMarked(blocks[i]))
+ continue;
+ for (j = i + 1; j < n_blocks; ++j) {
+ if (!isMarked(blocks[j]))
+ continue;
+ if (eq_blk(blocks[i], blocks[j])) {
+ blocks[i]->link = blocks[j]->link ?
+ blocks[j]->link : blocks[j];
+ break;
+ }
+ }
+ }
+ for (i = 0; i < n_blocks; ++i) {
+ p = blocks[i];
+ if (JT(p) == 0)
+ continue;
+ if (JT(p)->link) {
+ done1 = 0;
+ JT(p) = JT(p)->link;
+ }
+ if (JF(p)->link) {
+ done1 = 0;
+ JF(p) = JF(p)->link;
+ }
+ }
+ if (!done1)
+ goto top;
+}
+
+static void
+opt_cleanup(void)
+{
+ free((void *)vnode_base);
+ free((void *)vmap);
+ free((void *)edges);
+ free((void *)space);
+ free((void *)levels);
+ free((void *)blocks);
+}
+
+/*
+ * Return the number of stmts in 's'.
+ */
+static u_int
+slength(struct slist *s)
+{
+ u_int n = 0;
+
+ for (; s; s = s->next)
+ if (s->s.code != NOP)
+ ++n;
+ return n;
+}
+
+/*
+ * Return the number of nodes reachable by 'p'.
+ * All nodes should be initially unmarked.
+ */
+static int
+count_blocks(struct block *p)
+{
+ if (p == 0 || isMarked(p))
+ return 0;
+ Mark(p);
+ return count_blocks(JT(p)) + count_blocks(JF(p)) + 1;
+}
+
+/*
+ * Do a depth first search on the flow graph, numbering the
+ * the basic blocks, and entering them into the 'blocks' array.`
+ */
+static void
+number_blks_r(struct block *p)
+{
+ int n;
+
+ if (p == 0 || isMarked(p))
+ return;
+
+ Mark(p);
+ n = n_blocks++;
+ p->id = n;
+ blocks[n] = p;
+
+ number_blks_r(JT(p));
+ number_blks_r(JF(p));
+}
+
+/*
+ * Return the number of stmts in the flowgraph reachable by 'p'.
+ * The nodes should be unmarked before calling.
+ *
+ * Note that "stmts" means "instructions", and that this includes
+ *
+ * side-effect statements in 'p' (slength(p->stmts));
+ *
+ * statements in the true branch from 'p' (count_stmts(JT(p)));
+ *
+ * statements in the false branch from 'p' (count_stmts(JF(p)));
+ *
+ * the conditional jump itself (1);
+ *
+ * an extra long jump if the true branch requires it (p->longjt);
+ *
+ * an extra long jump if the false branch requires it (p->longjf).
+ */
+static u_int
+count_stmts(struct block *p)
+{
+ u_int n;
+
+ if (p == 0 || isMarked(p))
+ return 0;
+ Mark(p);
+ n = count_stmts(JT(p)) + count_stmts(JF(p));
+ return slength(p->stmts) + n + 1 + p->longjt + p->longjf;
+}
+
+/*
+ * Allocate memory. All allocation is done before optimization
+ * is begun. A linear bound on the size of all data structures is computed
+ * from the total number of blocks and/or statements.
+ */
+static void
+opt_init(struct block *root)
+{
+ bpf_u_int32 *p;
+ int i, n, max_stmts;
+
+ /*
+ * First, count the blocks, so we can malloc an array to map
+ * block number to block. Then, put the blocks into the array.
+ */
+ unMarkAll();
+ n = count_blocks(root);
+ blocks = (struct block **)calloc(n, sizeof(*blocks));
+ if (blocks == NULL)
+ bpf_error("malloc");
+ unMarkAll();
+ n_blocks = 0;
+ number_blks_r(root);
+
+ n_edges = 2 * n_blocks;
+ edges = (struct edge **)calloc(n_edges, sizeof(*edges));
+ if (edges == NULL)
+ bpf_error("malloc");
+
+ /*
+ * The number of levels is bounded by the number of nodes.
+ */
+ levels = (struct block **)calloc(n_blocks, sizeof(*levels));
+ if (levels == NULL)
+ bpf_error("malloc");
+
+ edgewords = n_edges / (8 * sizeof(bpf_u_int32)) + 1;
+ nodewords = n_blocks / (8 * sizeof(bpf_u_int32)) + 1;
+
+ /* XXX */
+ space = (bpf_u_int32 *)malloc(2 * n_blocks * nodewords * sizeof(*space)
+ + n_edges * edgewords * sizeof(*space));
+ if (space == NULL)
+ bpf_error("malloc");
+ p = space;
+ all_dom_sets = p;
+ for (i = 0; i < n; ++i) {
+ blocks[i]->dom = p;
+ p += nodewords;
+ }
+ all_closure_sets = p;
+ for (i = 0; i < n; ++i) {
+ blocks[i]->closure = p;
+ p += nodewords;
+ }
+ all_edge_sets = p;
+ for (i = 0; i < n; ++i) {
+ register struct block *b = blocks[i];
+
+ b->et.edom = p;
+ p += edgewords;
+ b->ef.edom = p;
+ p += edgewords;
+ b->et.id = i;
+ edges[i] = &b->et;
+ b->ef.id = n_blocks + i;
+ edges[n_blocks + i] = &b->ef;
+ b->et.pred = b;
+ b->ef.pred = b;
+ }
+ max_stmts = 0;
+ for (i = 0; i < n; ++i)
+ max_stmts += slength(blocks[i]->stmts) + 1;
+ /*
+ * We allocate at most 3 value numbers per statement,
+ * so this is an upper bound on the number of valnodes
+ * we'll need.
+ */
+ maxval = 3 * max_stmts;
+ vmap = (struct vmapinfo *)calloc(maxval, sizeof(*vmap));
+ vnode_base = (struct valnode *)calloc(maxval, sizeof(*vnode_base));
+ if (vmap == NULL || vnode_base == NULL)
+ bpf_error("malloc");
+}
+
+/*
+ * Some pointers used to convert the basic block form of the code,
+ * into the array form that BPF requires. 'fstart' will point to
+ * the malloc'd array while 'ftail' is used during the recursive traversal.
+ */
+static struct bpf_insn *fstart;
+static struct bpf_insn *ftail;
+
+#ifdef BDEBUG
+int bids[1000];
+#endif
+
+/*
+ * Returns true if successful. Returns false if a branch has
+ * an offset that is too large. If so, we have marked that
+ * branch so that on a subsequent iteration, it will be treated
+ * properly.
+ */
+static int
+convert_code_r(struct block *p)
+{
+ struct bpf_insn *dst;
+ struct slist *src;
+ int slen;
+ u_int off;
+ int extrajmps; /* number of extra jumps inserted */
+ struct slist **offset = NULL;
+
+ if (p == 0 || isMarked(p))
+ return (1);
+ Mark(p);
+
+ if (convert_code_r(JF(p)) == 0)
+ return (0);
+ if (convert_code_r(JT(p)) == 0)
+ return (0);
+
+ slen = slength(p->stmts);
+ dst = ftail -= (slen + 1 + p->longjt + p->longjf);
+ /* inflate length by any extra jumps */
+
+ p->offset = dst - fstart;
+
+ /* generate offset[] for convenience */
+ if (slen) {
+ offset = (struct slist **)calloc(slen, sizeof(struct slist *));
+ if (!offset) {
+ bpf_error("not enough core");
+ /*NOTREACHED*/
+ }
+ }
+ src = p->stmts;
+ for (off = 0; off < slen && src; off++) {
+#if 0
+ printf("off=%d src=%x\n", off, src);
+#endif
+ offset[off] = src;
+ src = src->next;
+ }
+
+ off = 0;
+ for (src = p->stmts; src; src = src->next) {
+ if (src->s.code == NOP)
+ continue;
+ dst->code = (u_short)src->s.code;
+ dst->k = src->s.k;
+
+ /* fill block-local relative jump */
+ if (BPF_CLASS(src->s.code) != BPF_JMP || src->s.code == (BPF_JMP|BPF_JA)) {
+#if 0
+ if (src->s.jt || src->s.jf) {
+ bpf_error("illegal jmp destination");
+ /*NOTREACHED*/
+ }
+#endif
+ goto filled;
+ }
+ if (off == slen - 2) /*???*/
+ goto filled;
+
+ {
+ int i;
+ int jt, jf;
+ const char *ljerr = "%s for block-local relative jump: off=%d";
+
+#if 0
+ printf("code=%x off=%d %x %x\n", src->s.code,
+ off, src->s.jt, src->s.jf);
+#endif
+
+ if (!src->s.jt || !src->s.jf) {
+ bpf_error(ljerr, "no jmp destination", off);
+ /*NOTREACHED*/
+ }
+
+ jt = jf = 0;
+ for (i = 0; i < slen; i++) {
+ if (offset[i] == src->s.jt) {
+ if (jt) {
+ bpf_error(ljerr, "multiple matches", off);
+ /*NOTREACHED*/
+ }
+
+ dst->jt = i - off - 1;
+ jt++;
+ }
+ if (offset[i] == src->s.jf) {
+ if (jf) {
+ bpf_error(ljerr, "multiple matches", off);
+ /*NOTREACHED*/
+ }
+ dst->jf = i - off - 1;
+ jf++;
+ }
+ }
+ if (!jt || !jf) {
+ bpf_error(ljerr, "no destination found", off);
+ /*NOTREACHED*/
+ }
+ }
+filled:
+ ++dst;
+ ++off;
+ }
+ if (offset)
+ free(offset);
+
+#ifdef BDEBUG
+ bids[dst - fstart] = p->id + 1;
+#endif
+ dst->code = (u_short)p->s.code;
+ dst->k = p->s.k;
+ if (JT(p)) {
+ extrajmps = 0;
+ off = JT(p)->offset - (p->offset + slen) - 1;
+ if (off >= 256) {
+ /* offset too large for branch, must add a jump */
+ if (p->longjt == 0) {
+ /* mark this instruction and retry */
+ p->longjt++;
+ return(0);
+ }
+ /* branch if T to following jump */
+ dst->jt = extrajmps;
+ extrajmps++;
+ dst[extrajmps].code = BPF_JMP|BPF_JA;
+ dst[extrajmps].k = off - extrajmps;
+ }
+ else
+ dst->jt = off;
+ off = JF(p)->offset - (p->offset + slen) - 1;
+ if (off >= 256) {
+ /* offset too large for branch, must add a jump */
+ if (p->longjf == 0) {
+ /* mark this instruction and retry */
+ p->longjf++;
+ return(0);
+ }
+ /* branch if F to following jump */
+ /* if two jumps are inserted, F goes to second one */
+ dst->jf = extrajmps;
+ extrajmps++;
+ dst[extrajmps].code = BPF_JMP|BPF_JA;
+ dst[extrajmps].k = off - extrajmps;
+ }
+ else
+ dst->jf = off;
+ }
+ return (1);
+}
+
+
+/*
+ * Convert flowgraph intermediate representation to the
+ * BPF array representation. Set *lenp to the number of instructions.
+ *
+ * This routine does *NOT* leak the memory pointed to by fp. It *must
+ * not* do free(fp) before returning fp; doing so would make no sense,
+ * as the BPF array pointed to by the return value of icode_to_fcode()
+ * must be valid - it's being returned for use in a bpf_program structure.
+ *
+ * If it appears that icode_to_fcode() is leaking, the problem is that
+ * the program using pcap_compile() is failing to free the memory in
+ * the BPF program when it's done - the leak is in the program, not in
+ * the routine that happens to be allocating the memory. (By analogy, if
+ * a program calls fopen() without ever calling fclose() on the FILE *,
+ * it will leak the FILE structure; the leak is not in fopen(), it's in
+ * the program.) Change the program to use pcap_freecode() when it's
+ * done with the filter program. See the pcap man page.
+ */
+struct bpf_insn *
+icode_to_fcode(struct block *root, u_int *lenp)
+{
+ u_int n;
+ struct bpf_insn *fp;
+
+ /*
+ * Loop doing convert_code_r() until no branches remain
+ * with too-large offsets.
+ */
+ while (1) {
+ unMarkAll();
+ n = *lenp = count_stmts(root);
+
+ fp = (struct bpf_insn *)malloc(sizeof(*fp) * n);
+ if (fp == NULL)
+ bpf_error("malloc");
+ memset((char *)fp, 0, sizeof(*fp) * n);
+ fstart = fp;
+ ftail = fp + n;
+
+ unMarkAll();
+ if (convert_code_r(root))
+ break;
+ free(fp);
+ }
+
+ return fp;
+}
+
+/*
+ * Make a copy of a BPF program and put it in the "fcode" member of
+ * a "pcap_t".
+ *
+ * If we fail to allocate memory for the copy, fill in the "errbuf"
+ * member of the "pcap_t" with an error message, and return -1;
+ * otherwise, return 0.
+ */
+int
+install_bpf_program(pcap_t *p, struct bpf_program *fp)
+{
+ size_t prog_size;
+
+ /*
+ * Validate the program.
+ */
+ if (!bpf_validate(fp->bf_insns, fp->bf_len)) {
+ snprintf(p->errbuf, sizeof(p->errbuf),
+ "BPF program is not valid");
+ return (-1);
+ }
+
+ /*
+ * Free up any already installed program.
+ */
+ pcap_freecode(&p->fcode);
+
+ prog_size = sizeof(*fp->bf_insns) * fp->bf_len;
+ p->fcode.bf_len = fp->bf_len;
+ p->fcode.bf_insns = (struct bpf_insn *)malloc(prog_size);
+ if (p->fcode.bf_insns == NULL) {
+ snprintf(p->errbuf, sizeof(p->errbuf),
+ "malloc: %s", pcap_strerror(errno));
+ return (-1);
+ }
+ memcpy(p->fcode.bf_insns, fp->bf_insns, prog_size);
+ return (0);
+}
+
+#ifdef BDEBUG
+static void
+opt_dump(struct block *root)
+{
+ struct bpf_program f;
+
+ memset(bids, 0, sizeof bids);
+ f.bf_insns = icode_to_fcode(root, &f.bf_len);
+ bpf_dump(&f, 1);
+ putchar('\n');
+ free((char *)f.bf_insns);
+}
+#endif
diff --git a/freebsd/contrib/libpcap/pcap-bpf.c b/freebsd/contrib/libpcap/pcap-bpf.c
new file mode 100644
index 00000000..0a942601
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap-bpf.c
@@ -0,0 +1,2719 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1998
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.116 2008-09-16 18:42:29 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/bsd/sys/param.h> /* optionally get BSD define */
+#ifdef HAVE_ZEROCOPY_BPF
+#include <sys/mman.h>
+#endif
+#include <sys/socket.h>
+#include <time.h>
+/*
+ * <net/bpf.h> defines ioctls, but doesn't include <sys/ioccom.h>.
+ *
+ * We include <sys/ioctl.h> as it might be necessary to declare ioctl();
+ * at least on *BSD and Mac OS X, it also defines various SIOC ioctls -
+ * we could include <sys/sockio.h>, but if we're already including
+ * <sys/ioctl.h>, which includes <sys/sockio.h> on those platforms,
+ * there's not much point in doing so.
+ *
+ * If we have <sys/ioccom.h>, we include it as well, to handle systems
+ * such as Solaris which don't arrange to include <sys/ioccom.h> if you
+ * include <sys/ioctl.h>
+ */
+#include <sys/ioctl.h>
+#ifdef HAVE_SYS_IOCCOM_H
+#include <sys/ioccom.h>
+#endif
+#include <sys/utsname.h>
+
+#ifdef HAVE_ZEROCOPY_BPF
+#include <machine/atomic.h>
+#endif
+
+#include <net/if.h>
+
+#ifdef _AIX
+
+/*
+ * Make "pcap.h" not include "pcap/bpf.h"; we are going to include the
+ * native OS version, as we need "struct bpf_config" from it.
+ */
+#define PCAP_DONT_INCLUDE_PCAP_BPF_H
+
+#include <rtems/bsd/sys/types.h>
+
+/*
+ * Prevent bpf.h from redefining the DLT_ values to their
+ * IFT_ values, as we're going to return the standard libpcap
+ * values, not IBM's non-standard IFT_ values.
+ */
+#undef _AIX
+#include <net/bpf.h>
+#define _AIX
+
+#include <net/if_types.h> /* for IFT_ values */
+#include <sys/sysconfig.h>
+#include <sys/device.h>
+#include <sys/cfgodm.h>
+#include <cf.h>
+
+#ifdef __64BIT__
+#define domakedev makedev64
+#define getmajor major64
+#define bpf_hdr bpf_hdr32
+#else /* __64BIT__ */
+#define domakedev makedev
+#define getmajor major
+#endif /* __64BIT__ */
+
+#define BPF_NAME "bpf"
+#define BPF_MINORS 4
+#define DRIVER_PATH "/usr/lib/drivers"
+#define BPF_NODE "/dev/bpf"
+static int bpfloadedflag = 0;
+static int odmlockid = 0;
+
+static int bpf_load(char *errbuf);
+
+#else /* _AIX */
+
+#include <net/bpf.h>
+
+#endif /* _AIX */
+
+#include <ctype.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef HAVE_NET_IF_MEDIA_H
+# include <net/if_media.h>
+#endif
+
+#include "pcap-int.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#ifdef BIOCGDLTLIST
+# if (defined(HAVE_NET_IF_MEDIA_H) && defined(IFM_IEEE80211)) && !defined(__APPLE__)
+#define HAVE_BSD_IEEE80211
+# endif
+
+# if defined(__APPLE__) || defined(HAVE_BSD_IEEE80211)
+static int find_802_11(struct bpf_dltlist *);
+
+# ifdef HAVE_BSD_IEEE80211
+static int monitor_mode(pcap_t *, int);
+# endif
+
+# if defined(__APPLE__)
+static void remove_en(pcap_t *);
+static void remove_802_11(pcap_t *);
+# endif
+
+# endif /* defined(__APPLE__) || defined(HAVE_BSD_IEEE80211) */
+
+#endif /* BIOCGDLTLIST */
+
+#if defined(sun) && defined(LIFNAMSIZ) && defined(lifr_zoneid)
+#include <zone.h>
+#endif
+
+/*
+ * We include the OS's <net/bpf.h>, not our "pcap/bpf.h", so we probably
+ * don't get DLT_DOCSIS defined.
+ */
+#ifndef DLT_DOCSIS
+#define DLT_DOCSIS 143
+#endif
+
+/*
+ * On OS X, we don't even get any of the 802.11-plus-radio-header DLT_'s
+ * defined, even though some of them are used by various Airport drivers.
+ */
+#ifndef DLT_PRISM_HEADER
+#define DLT_PRISM_HEADER 119
+#endif
+#ifndef DLT_AIRONET_HEADER
+#define DLT_AIRONET_HEADER 120
+#endif
+#ifndef DLT_IEEE802_11_RADIO
+#define DLT_IEEE802_11_RADIO 127
+#endif
+#ifndef DLT_IEEE802_11_RADIO_AVS
+#define DLT_IEEE802_11_RADIO_AVS 163
+#endif
+
+static int pcap_can_set_rfmon_bpf(pcap_t *p);
+static int pcap_activate_bpf(pcap_t *p);
+static int pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp);
+static int pcap_setdirection_bpf(pcap_t *, pcap_direction_t);
+static int pcap_set_datalink_bpf(pcap_t *p, int dlt);
+
+/*
+ * For zerocopy bpf, the setnonblock/getnonblock routines need to modify
+ * p->md.timeout so we don't call select(2) if the pcap handle is in non-
+ * blocking mode. We preserve the timeout supplied by pcap_open functions
+ * to make sure it does not get clobbered if the pcap handle moves between
+ * blocking and non-blocking mode.
+ */
+static int
+pcap_getnonblock_bpf(pcap_t *p, char *errbuf)
+{
+#ifdef HAVE_ZEROCOPY_BPF
+ if (p->md.zerocopy) {
+ /*
+ * Use a negative value for the timeout to represent that the
+ * pcap handle is in non-blocking mode.
+ */
+ return (p->md.timeout < 0);
+ }
+#endif
+ return (pcap_getnonblock_fd(p, errbuf));
+}
+
+static int
+pcap_setnonblock_bpf(pcap_t *p, int nonblock, char *errbuf)
+{
+#ifdef HAVE_ZEROCOPY_BPF
+ if (p->md.zerocopy) {
+ /*
+ * Map each value to their corresponding negation to
+ * preserve the timeout value provided with pcap_set_timeout.
+ * (from pcap-linux.c).
+ */
+ if (nonblock) {
+ if (p->md.timeout >= 0) {
+ /*
+ * Indicate that we're switching to
+ * non-blocking mode.
+ */
+ p->md.timeout = ~p->md.timeout;
+ }
+ } else {
+ if (p->md.timeout < 0) {
+ p->md.timeout = ~p->md.timeout;
+ }
+ }
+ return (0);
+ }
+#endif
+ return (pcap_setnonblock_fd(p, nonblock, errbuf));
+}
+
+#ifdef HAVE_ZEROCOPY_BPF
+/*
+ * Zero-copy BPF buffer routines to check for and acknowledge BPF data in
+ * shared memory buffers.
+ *
+ * pcap_next_zbuf_shm(): Check for a newly available shared memory buffer,
+ * and set up p->buffer and cc to reflect one if available. Notice that if
+ * there was no prior buffer, we select zbuf1 as this will be the first
+ * buffer filled for a fresh BPF session.
+ */
+static int
+pcap_next_zbuf_shm(pcap_t *p, int *cc)
+{
+ struct bpf_zbuf_header *bzh;
+
+ if (p->md.zbuffer == p->md.zbuf2 || p->md.zbuffer == NULL) {
+ bzh = (struct bpf_zbuf_header *)p->md.zbuf1;
+ if (bzh->bzh_user_gen !=
+ atomic_load_acq_int(&bzh->bzh_kernel_gen)) {
+ p->md.bzh = bzh;
+ p->md.zbuffer = (u_char *)p->md.zbuf1;
+ p->buffer = p->md.zbuffer + sizeof(*bzh);
+ *cc = bzh->bzh_kernel_len;
+ return (1);
+ }
+ } else if (p->md.zbuffer == p->md.zbuf1) {
+ bzh = (struct bpf_zbuf_header *)p->md.zbuf2;
+ if (bzh->bzh_user_gen !=
+ atomic_load_acq_int(&bzh->bzh_kernel_gen)) {
+ p->md.bzh = bzh;
+ p->md.zbuffer = (u_char *)p->md.zbuf2;
+ p->buffer = p->md.zbuffer + sizeof(*bzh);
+ *cc = bzh->bzh_kernel_len;
+ return (1);
+ }
+ }
+ *cc = 0;
+ return (0);
+}
+
+/*
+ * pcap_next_zbuf() -- Similar to pcap_next_zbuf_shm(), except wait using
+ * select() for data or a timeout, and possibly force rotation of the buffer
+ * in the event we time out or are in immediate mode. Invoke the shared
+ * memory check before doing system calls in order to avoid doing avoidable
+ * work.
+ */
+static int
+pcap_next_zbuf(pcap_t *p, int *cc)
+{
+ struct bpf_zbuf bz;
+ struct timeval tv;
+ struct timespec cur;
+ fd_set r_set;
+ int data, r;
+ int expire, tmout;
+
+#define TSTOMILLI(ts) (((ts)->tv_sec * 1000) + ((ts)->tv_nsec / 1000000))
+ /*
+ * Start out by seeing whether anything is waiting by checking the
+ * next shared memory buffer for data.
+ */
+ data = pcap_next_zbuf_shm(p, cc);
+ if (data)
+ return (data);
+ /*
+ * If a previous sleep was interrupted due to signal delivery, make
+ * sure that the timeout gets adjusted accordingly. This requires
+ * that we analyze when the timeout should be been expired, and
+ * subtract the current time from that. If after this operation,
+ * our timeout is less then or equal to zero, handle it like a
+ * regular timeout.
+ */
+ tmout = p->md.timeout;
+ if (tmout)
+ (void) clock_gettime(CLOCK_MONOTONIC, &cur);
+ if (p->md.interrupted && p->md.timeout) {
+ expire = TSTOMILLI(&p->md.firstsel) + p->md.timeout;
+ tmout = expire - TSTOMILLI(&cur);
+#undef TSTOMILLI
+ if (tmout <= 0) {
+ p->md.interrupted = 0;
+ data = pcap_next_zbuf_shm(p, cc);
+ if (data)
+ return (data);
+ if (ioctl(p->fd, BIOCROTZBUF, &bz) < 0) {
+ (void) snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "BIOCROTZBUF: %s", strerror(errno));
+ return (PCAP_ERROR);
+ }
+ return (pcap_next_zbuf_shm(p, cc));
+ }
+ }
+ /*
+ * No data in the buffer, so must use select() to wait for data or
+ * the next timeout. Note that we only call select if the handle
+ * is in blocking mode.
+ */
+ if (p->md.timeout >= 0) {
+ FD_ZERO(&r_set);
+ FD_SET(p->fd, &r_set);
+ if (tmout != 0) {
+ tv.tv_sec = tmout / 1000;
+ tv.tv_usec = (tmout * 1000) % 1000000;
+ }
+ r = select(p->fd + 1, &r_set, NULL, NULL,
+ p->md.timeout != 0 ? &tv : NULL);
+ if (r < 0 && errno == EINTR) {
+ if (!p->md.interrupted && p->md.timeout) {
+ p->md.interrupted = 1;
+ p->md.firstsel = cur;
+ }
+ return (0);
+ } else if (r < 0) {
+ (void) snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "select: %s", strerror(errno));
+ return (PCAP_ERROR);
+ }
+ }
+ p->md.interrupted = 0;
+ /*
+ * Check again for data, which may exist now that we've either been
+ * woken up as a result of data or timed out. Try the "there's data"
+ * case first since it doesn't require a system call.
+ */
+ data = pcap_next_zbuf_shm(p, cc);
+ if (data)
+ return (data);
+ /*
+ * Try forcing a buffer rotation to dislodge timed out or immediate
+ * data.
+ */
+ if (ioctl(p->fd, BIOCROTZBUF, &bz) < 0) {
+ (void) snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "BIOCROTZBUF: %s", strerror(errno));
+ return (PCAP_ERROR);
+ }
+ return (pcap_next_zbuf_shm(p, cc));
+}
+
+/*
+ * Notify kernel that we are done with the buffer. We don't reset zbuffer so
+ * that we know which buffer to use next time around.
+ */
+static int
+pcap_ack_zbuf(pcap_t *p)
+{
+
+ atomic_store_rel_int(&p->md.bzh->bzh_user_gen,
+ p->md.bzh->bzh_kernel_gen);
+ p->md.bzh = NULL;
+ p->buffer = NULL;
+ return (0);
+}
+#endif /* HAVE_ZEROCOPY_BPF */
+
+pcap_t *
+pcap_create_interface(const char *device, char *ebuf)
+{
+ pcap_t *p;
+
+ p = pcap_create_common(device, ebuf);
+ if (p == NULL)
+ return (NULL);
+
+ p->activate_op = pcap_activate_bpf;
+ p->can_set_rfmon_op = pcap_can_set_rfmon_bpf;
+ return (p);
+}
+
+/*
+ * On success, returns a file descriptor for a BPF device.
+ * On failure, returns a PCAP_ERROR_ value, and sets p->errbuf.
+ */
+static int
+bpf_open(pcap_t *p)
+{
+ int fd;
+#ifdef HAVE_CLONING_BPF
+ static const char device[] = "/dev/bpf";
+#else
+ int n = 0;
+ char device[sizeof "/dev/bpf0000000000"];
+#endif
+
+#ifdef _AIX
+ /*
+ * Load the bpf driver, if it isn't already loaded,
+ * and create the BPF device entries, if they don't
+ * already exist.
+ */
+ if (bpf_load(p->errbuf) == PCAP_ERROR)
+ return (PCAP_ERROR);
+#endif
+
+#ifdef HAVE_CLONING_BPF
+ if ((fd = open(device, O_RDWR)) == -1 &&
+ (errno != EACCES || (fd = open(device, O_RDONLY)) == -1)) {
+ if (errno == EACCES)
+ fd = PCAP_ERROR_PERM_DENIED;
+ else
+ fd = PCAP_ERROR;
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "(cannot open device) %s: %s", device, pcap_strerror(errno));
+ }
+#else
+ /*
+ * Go through all the minors and find one that isn't in use.
+ */
+ do {
+ (void)snprintf(device, sizeof(device), "/dev/bpf%d", n++);
+ /*
+ * Initially try a read/write open (to allow the inject
+ * method to work). If that fails due to permission
+ * issues, fall back to read-only. This allows a
+ * non-root user to be granted specific access to pcap
+ * capabilities via file permissions.
+ *
+ * XXX - we should have an API that has a flag that
+ * controls whether to open read-only or read-write,
+ * so that denial of permission to send (or inability
+ * to send, if sending packets isn't supported on
+ * the device in question) can be indicated at open
+ * time.
+ */
+ fd = open(device, O_RDWR);
+ if (fd == -1 && errno == EACCES)
+ fd = open(device, O_RDONLY);
+ } while (fd < 0 && errno == EBUSY);
+
+ /*
+ * XXX better message for all minors used
+ */
+ if (fd < 0) {
+ switch (errno) {
+
+ case ENOENT:
+ fd = PCAP_ERROR;
+ if (n == 1) {
+ /*
+ * /dev/bpf0 doesn't exist, which
+ * means we probably have no BPF
+ * devices.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "(there are no BPF devices)");
+ } else {
+ /*
+ * We got EBUSY on at least one
+ * BPF device, so we have BPF
+ * devices, but all the ones
+ * that exist are busy.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "(all BPF devices are busy)");
+ }
+ break;
+
+ case EACCES:
+ /*
+ * Got EACCES on the last device we tried,
+ * and EBUSY on all devices before that,
+ * if any.
+ */
+ fd = PCAP_ERROR_PERM_DENIED;
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "(cannot open BPF device) %s: %s", device,
+ pcap_strerror(errno));
+ break;
+
+ default:
+ /*
+ * Some other problem.
+ */
+ fd = PCAP_ERROR;
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "(cannot open BPF device) %s: %s", device,
+ pcap_strerror(errno));
+ break;
+ }
+ }
+#endif
+
+ return (fd);
+}
+
+#ifdef BIOCGDLTLIST
+static int
+get_dlt_list(int fd, int v, struct bpf_dltlist *bdlp, char *ebuf)
+{
+ memset(bdlp, 0, sizeof(*bdlp));
+ if (ioctl(fd, BIOCGDLTLIST, (caddr_t)bdlp) == 0) {
+ u_int i;
+ int is_ethernet;
+
+ bdlp->bfl_list = (u_int *) malloc(sizeof(u_int) * (bdlp->bfl_len + 1));
+ if (bdlp->bfl_list == NULL) {
+ (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
+ pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+
+ if (ioctl(fd, BIOCGDLTLIST, (caddr_t)bdlp) < 0) {
+ (void)snprintf(ebuf, PCAP_ERRBUF_SIZE,
+ "BIOCGDLTLIST: %s", pcap_strerror(errno));
+ free(bdlp->bfl_list);
+ return (PCAP_ERROR);
+ }
+
+ /*
+ * OK, for real Ethernet devices, add DLT_DOCSIS to the
+ * list, so that an application can let you choose it,
+ * in case you're capturing DOCSIS traffic that a Cisco
+ * Cable Modem Termination System is putting out onto
+ * an Ethernet (it doesn't put an Ethernet header onto
+ * the wire, it puts raw DOCSIS frames out on the wire
+ * inside the low-level Ethernet framing).
+ *
+ * A "real Ethernet device" is defined here as a device
+ * that has a link-layer type of DLT_EN10MB and that has
+ * no alternate link-layer types; that's done to exclude
+ * 802.11 interfaces (which might or might not be the
+ * right thing to do, but I suspect it is - Ethernet <->
+ * 802.11 bridges would probably badly mishandle frames
+ * that don't have Ethernet headers).
+ *
+ * On Solaris with BPF, Ethernet devices also offer
+ * DLT_IPNET, so we, if DLT_IPNET is defined, we don't
+ * treat it as an indication that the device isn't an
+ * Ethernet.
+ */
+ if (v == DLT_EN10MB) {
+ is_ethernet = 1;
+ for (i = 0; i < bdlp->bfl_len; i++) {
+ if (bdlp->bfl_list[i] != DLT_EN10MB
+#ifdef DLT_IPNET
+ && bdlp->bfl_list[i] != DLT_IPNET
+#endif
+ ) {
+ is_ethernet = 0;
+ break;
+ }
+ }
+ if (is_ethernet) {
+ /*
+ * We reserved one more slot at the end of
+ * the list.
+ */
+ bdlp->bfl_list[bdlp->bfl_len] = DLT_DOCSIS;
+ bdlp->bfl_len++;
+ }
+ }
+ } else {
+ /*
+ * EINVAL just means "we don't support this ioctl on
+ * this device"; don't treat it as an error.
+ */
+ if (errno != EINVAL) {
+ (void)snprintf(ebuf, PCAP_ERRBUF_SIZE,
+ "BIOCGDLTLIST: %s", pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+ }
+ return (0);
+}
+#endif
+
+static int
+pcap_can_set_rfmon_bpf(pcap_t *p)
+{
+#if defined(__APPLE__)
+ struct utsname osinfo;
+ struct ifreq ifr;
+ int fd;
+#ifdef BIOCGDLTLIST
+ struct bpf_dltlist bdl;
+#endif
+
+ /*
+ * The joys of monitor mode on OS X.
+ *
+ * Prior to 10.4, it's not supported at all.
+ *
+ * In 10.4, if adapter enN supports monitor mode, there's a
+ * wltN adapter corresponding to it; you open it, instead of
+ * enN, to get monitor mode. You get whatever link-layer
+ * headers it supplies.
+ *
+ * In 10.5, and, we assume, later releases, if adapter enN
+ * supports monitor mode, it offers, among its selectable
+ * DLT_ values, values that let you get the 802.11 header;
+ * selecting one of those values puts the adapter into monitor
+ * mode (i.e., you can't get 802.11 headers except in monitor
+ * mode, and you can't get Ethernet headers in monitor mode).
+ */
+ if (uname(&osinfo) == -1) {
+ /*
+ * Can't get the OS version; just say "no".
+ */
+ return (0);
+ }
+ /*
+ * We assume osinfo.sysname is "Darwin", because
+ * __APPLE__ is defined. We just check the version.
+ */
+ if (osinfo.release[0] < '8' && osinfo.release[1] == '.') {
+ /*
+ * 10.3 (Darwin 7.x) or earlier.
+ * Monitor mode not supported.
+ */
+ return (0);
+ }
+ if (osinfo.release[0] == '8' && osinfo.release[1] == '.') {
+ /*
+ * 10.4 (Darwin 8.x). s/en/wlt/, and check
+ * whether the device exists.
+ */
+ if (strncmp(p->opt.source, "en", 2) != 0) {
+ /*
+ * Not an enN device; no monitor mode.
+ */
+ return (0);
+ }
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd == -1) {
+ (void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "socket: %s", pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+ strlcpy(ifr.ifr_name, "wlt", sizeof(ifr.ifr_name));
+ strlcat(ifr.ifr_name, p->opt.source + 2, sizeof(ifr.ifr_name));
+ if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
+ /*
+ * No such device?
+ */
+ close(fd);
+ return (0);
+ }
+ close(fd);
+ return (1);
+ }
+
+#ifdef BIOCGDLTLIST
+ /*
+ * Everything else is 10.5 or later; for those,
+ * we just open the enN device, and check whether
+ * we have any 802.11 devices.
+ *
+ * First, open a BPF device.
+ */
+ fd = bpf_open(p);
+ if (fd < 0)
+ return (fd); /* fd is the appropriate error code */
+
+ /*
+ * Now bind to the device.
+ */
+ (void)strncpy(ifr.ifr_name, p->opt.source, sizeof(ifr.ifr_name));
+ if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
+ switch (errno) {
+
+ case ENXIO:
+ /*
+ * There's no such device.
+ */
+ close(fd);
+ return (PCAP_ERROR_NO_SUCH_DEVICE);
+
+ case ENETDOWN:
+ /*
+ * Return a "network down" indication, so that
+ * the application can report that rather than
+ * saying we had a mysterious failure and
+ * suggest that they report a problem to the
+ * libpcap developers.
+ */
+ close(fd);
+ return (PCAP_ERROR_IFACE_NOT_UP);
+
+ default:
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "BIOCSETIF: %s: %s",
+ p->opt.source, pcap_strerror(errno));
+ close(fd);
+ return (PCAP_ERROR);
+ }
+ }
+
+ /*
+ * We know the default link type -- now determine all the DLTs
+ * this interface supports. If this fails with EINVAL, it's
+ * not fatal; we just don't get to use the feature later.
+ * (We don't care about DLT_DOCSIS, so we pass DLT_NULL
+ * as the default DLT for this adapter.)
+ */
+ if (get_dlt_list(fd, DLT_NULL, &bdl, p->errbuf) == PCAP_ERROR) {
+ close(fd);
+ return (PCAP_ERROR);
+ }
+ if (find_802_11(&bdl) != -1) {
+ /*
+ * We have an 802.11 DLT, so we can set monitor mode.
+ */
+ free(bdl.bfl_list);
+ close(fd);
+ return (1);
+ }
+ free(bdl.bfl_list);
+#endif /* BIOCGDLTLIST */
+ return (0);
+#elif defined(HAVE_BSD_IEEE80211)
+ int ret;
+
+ ret = monitor_mode(p, 0);
+ if (ret == PCAP_ERROR_RFMON_NOTSUP)
+ return (0); /* not an error, just a "can't do" */
+ if (ret == 0)
+ return (1); /* success */
+ return (ret);
+#else
+ return (0);
+#endif
+}
+
+static int
+pcap_stats_bpf(pcap_t *p, struct pcap_stat *ps)
+{
+ struct bpf_stat s;
+
+ /*
+ * "ps_recv" counts packets handed to the filter, not packets
+ * that passed the filter. This includes packets later dropped
+ * because we ran out of buffer space.
+ *
+ * "ps_drop" counts packets dropped inside the BPF device
+ * because we ran out of buffer space. It doesn't count
+ * packets dropped by the interface driver. It counts
+ * only packets that passed the filter.
+ *
+ * Both statistics include packets not yet read from the kernel
+ * by libpcap, and thus not yet seen by the application.
+ */
+ if (ioctl(p->fd, BIOCGSTATS, (caddr_t)&s) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGSTATS: %s",
+ pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+
+ ps->ps_recv = s.bs_recv;
+ ps->ps_drop = s.bs_drop;
+ ps->ps_ifdrop = 0;
+ return (0);
+}
+
+static int
+pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
+{
+ int cc;
+ int n = 0;
+ register u_char *bp, *ep;
+ u_char *datap;
+#ifdef PCAP_FDDIPAD
+ register int pad;
+#endif
+#ifdef HAVE_ZEROCOPY_BPF
+ int i;
+#endif
+
+ again:
+ /*
+ * Has "pcap_breakloop()" been called?
+ */
+ if (p->break_loop) {
+ /*
+ * Yes - clear the flag that indicates that it
+ * has, and return PCAP_ERROR_BREAK to indicate
+ * that we were told to break out of the loop.
+ */
+ p->break_loop = 0;
+ return (PCAP_ERROR_BREAK);
+ }
+ cc = p->cc;
+ if (p->cc == 0) {
+ /*
+ * When reading without zero-copy from a file descriptor, we
+ * use a single buffer and return a length of data in the
+ * buffer. With zero-copy, we update the p->buffer pointer
+ * to point at whatever underlying buffer contains the next
+ * data and update cc to reflect the data found in the
+ * buffer.
+ */
+#ifdef HAVE_ZEROCOPY_BPF
+ if (p->md.zerocopy) {
+ if (p->buffer != NULL)
+ pcap_ack_zbuf(p);
+ i = pcap_next_zbuf(p, &cc);
+ if (i == 0)
+ goto again;
+ if (i < 0)
+ return (PCAP_ERROR);
+ } else
+#endif
+ {
+ cc = read(p->fd, (char *)p->buffer, p->bufsize);
+ }
+ if (cc < 0) {
+ /* Don't choke when we get ptraced */
+ switch (errno) {
+
+ case EINTR:
+ goto again;
+
+#ifdef _AIX
+ case EFAULT:
+ /*
+ * Sigh. More AIX wonderfulness.
+ *
+ * For some unknown reason the uiomove()
+ * operation in the bpf kernel extension
+ * used to copy the buffer into user
+ * space sometimes returns EFAULT. I have
+ * no idea why this is the case given that
+ * a kernel debugger shows the user buffer
+ * is correct. This problem appears to
+ * be mostly mitigated by the memset of
+ * the buffer before it is first used.
+ * Very strange.... Shaun Clowes
+ *
+ * In any case this means that we shouldn't
+ * treat EFAULT as a fatal error; as we
+ * don't have an API for returning
+ * a "some packets were dropped since
+ * the last packet you saw" indication,
+ * we just ignore EFAULT and keep reading.
+ */
+ goto again;
+#endif
+
+ case EWOULDBLOCK:
+ return (0);
+
+ case ENXIO:
+ /*
+ * The device on which we're capturing
+ * went away.
+ *
+ * XXX - we should really return
+ * PCAP_ERROR_IFACE_NOT_UP, but
+ * pcap_dispatch() etc. aren't
+ * defined to retur that.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "The interface went down");
+ return (PCAP_ERROR);
+
+#if defined(sun) && !defined(BSD) && !defined(__svr4__) && !defined(__SVR4)
+ /*
+ * Due to a SunOS bug, after 2^31 bytes, the kernel
+ * file offset overflows and read fails with EINVAL.
+ * The lseek() to 0 will fix things.
+ */
+ case EINVAL:
+ if (lseek(p->fd, 0L, SEEK_CUR) +
+ p->bufsize < 0) {
+ (void)lseek(p->fd, 0L, SEEK_SET);
+ goto again;
+ }
+ /* fall through */
+#endif
+ }
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read: %s",
+ pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+ bp = p->buffer;
+ } else
+ bp = p->bp;
+
+ /*
+ * Loop through each packet.
+ */
+#define bhp ((struct bpf_hdr *)bp)
+ ep = bp + cc;
+#ifdef PCAP_FDDIPAD
+ pad = p->fddipad;
+#endif
+ while (bp < ep) {
+ register int caplen, hdrlen;
+
+ /*
+ * Has "pcap_breakloop()" been called?
+ * If so, return immediately - if we haven't read any
+ * packets, clear the flag and return PCAP_ERROR_BREAK
+ * to indicate that we were told to break out of the loop,
+ * otherwise leave the flag set, so that the *next* call
+ * will break out of the loop without having read any
+ * packets, and return the number of packets we've
+ * processed so far.
+ */
+ if (p->break_loop) {
+ p->bp = bp;
+ p->cc = ep - bp;
+ /*
+ * ep is set based on the return value of read(),
+ * but read() from a BPF device doesn't necessarily
+ * return a value that's a multiple of the alignment
+ * value for BPF_WORDALIGN(). However, whenever we
+ * increment bp, we round up the increment value by
+ * a value rounded up by BPF_WORDALIGN(), so we
+ * could increment bp past ep after processing the
+ * last packet in the buffer.
+ *
+ * We treat ep < bp as an indication that this
+ * happened, and just set p->cc to 0.
+ */
+ if (p->cc < 0)
+ p->cc = 0;
+ if (n == 0) {
+ p->break_loop = 0;
+ return (PCAP_ERROR_BREAK);
+ } else
+ return (n);
+ }
+
+ caplen = bhp->bh_caplen;
+ hdrlen = bhp->bh_hdrlen;
+ datap = bp + hdrlen;
+ /*
+ * Short-circuit evaluation: if using BPF filter
+ * in kernel, no need to do it now - we already know
+ * the packet passed the filter.
+ *
+#ifdef PCAP_FDDIPAD
+ * Note: the filter code was generated assuming
+ * that p->fddipad was the amount of padding
+ * before the header, as that's what's required
+ * in the kernel, so we run the filter before
+ * skipping that padding.
+#endif
+ */
+ if (p->md.use_bpf ||
+ bpf_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) {
+ struct pcap_pkthdr pkthdr;
+
+ pkthdr.ts.tv_sec = bhp->bh_tstamp.tv_sec;
+#ifdef _AIX
+ /*
+ * AIX's BPF returns seconds/nanoseconds time
+ * stamps, not seconds/microseconds time stamps.
+ */
+ pkthdr.ts.tv_usec = bhp->bh_tstamp.tv_usec/1000;
+#else
+ pkthdr.ts.tv_usec = bhp->bh_tstamp.tv_usec;
+#endif
+#ifdef PCAP_FDDIPAD
+ if (caplen > pad)
+ pkthdr.caplen = caplen - pad;
+ else
+ pkthdr.caplen = 0;
+ if (bhp->bh_datalen > pad)
+ pkthdr.len = bhp->bh_datalen - pad;
+ else
+ pkthdr.len = 0;
+ datap += pad;
+#else
+ pkthdr.caplen = caplen;
+ pkthdr.len = bhp->bh_datalen;
+#endif
+ (*callback)(user, &pkthdr, datap);
+ bp += BPF_WORDALIGN(caplen + hdrlen);
+ if (++n >= cnt && cnt > 0) {
+ p->bp = bp;
+ p->cc = ep - bp;
+ /*
+ * See comment above about p->cc < 0.
+ */
+ if (p->cc < 0)
+ p->cc = 0;
+ return (n);
+ }
+ } else {
+ /*
+ * Skip this packet.
+ */
+ bp += BPF_WORDALIGN(caplen + hdrlen);
+ }
+ }
+#undef bhp
+ p->cc = 0;
+ return (n);
+}
+
+static int
+pcap_inject_bpf(pcap_t *p, const void *buf, size_t size)
+{
+ int ret;
+
+ ret = write(p->fd, buf, size);
+#ifdef __APPLE__
+ if (ret == -1 && errno == EAFNOSUPPORT) {
+ /*
+ * In Mac OS X, there's a bug wherein setting the
+ * BIOCSHDRCMPLT flag causes writes to fail; see,
+ * for example:
+ *
+ * http://cerberus.sourcefire.com/~jeff/archives/patches/macosx/BIOCSHDRCMPLT-10.3.3.patch
+ *
+ * So, if, on OS X, we get EAFNOSUPPORT from the write, we
+ * assume it's due to that bug, and turn off that flag
+ * and try again. If we succeed, it either means that
+ * somebody applied the fix from that URL, or other patches
+ * for that bug from
+ *
+ * http://cerberus.sourcefire.com/~jeff/archives/patches/macosx/
+ *
+ * and are running a Darwin kernel with those fixes, or
+ * that Apple fixed the problem in some OS X release.
+ */
+ u_int spoof_eth_src = 0;
+
+ if (ioctl(p->fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) {
+ (void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "send: can't turn off BIOCSHDRCMPLT: %s",
+ pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+
+ /*
+ * Now try the write again.
+ */
+ ret = write(p->fd, buf, size);
+ }
+#endif /* __APPLE__ */
+ if (ret == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
+ pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+ return (ret);
+}
+
+#ifdef _AIX
+static int
+bpf_odminit(char *errbuf)
+{
+ char *errstr;
+
+ if (odm_initialize() == -1) {
+ if (odm_err_msg(odmerrno, &errstr) == -1)
+ errstr = "Unknown error";
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: odm_initialize failed: %s",
+ errstr);
+ return (PCAP_ERROR);
+ }
+
+ if ((odmlockid = odm_lock("/etc/objrepos/config_lock", ODM_WAIT)) == -1) {
+ if (odm_err_msg(odmerrno, &errstr) == -1)
+ errstr = "Unknown error";
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: odm_lock of /etc/objrepos/config_lock failed: %s",
+ errstr);
+ (void)odm_terminate();
+ return (PCAP_ERROR);
+ }
+
+ return (0);
+}
+
+static int
+bpf_odmcleanup(char *errbuf)
+{
+ char *errstr;
+
+ if (odm_unlock(odmlockid) == -1) {
+ if (errbuf != NULL) {
+ if (odm_err_msg(odmerrno, &errstr) == -1)
+ errstr = "Unknown error";
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: odm_unlock failed: %s",
+ errstr);
+ }
+ return (PCAP_ERROR);
+ }
+
+ if (odm_terminate() == -1) {
+ if (errbuf != NULL) {
+ if (odm_err_msg(odmerrno, &errstr) == -1)
+ errstr = "Unknown error";
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: odm_terminate failed: %s",
+ errstr);
+ }
+ return (PCAP_ERROR);
+ }
+
+ return (0);
+}
+
+static int
+bpf_load(char *errbuf)
+{
+ long major;
+ int *minors;
+ int numminors, i, rc;
+ char buf[1024];
+ struct stat sbuf;
+ struct bpf_config cfg_bpf;
+ struct cfg_load cfg_ld;
+ struct cfg_kmod cfg_km;
+
+ /*
+ * This is very very close to what happens in the real implementation
+ * but I've fixed some (unlikely) bug situations.
+ */
+ if (bpfloadedflag)
+ return (0);
+
+ if (bpf_odminit(errbuf) == PCAP_ERROR)
+ return (PCAP_ERROR);
+
+ major = genmajor(BPF_NAME);
+ if (major == -1) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: genmajor failed: %s", pcap_strerror(errno));
+ (void)bpf_odmcleanup(NULL);
+ return (PCAP_ERROR);
+ }
+
+ minors = getminor(major, &numminors, BPF_NAME);
+ if (!minors) {
+ minors = genminor("bpf", major, 0, BPF_MINORS, 1, 1);
+ if (!minors) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: genminor failed: %s",
+ pcap_strerror(errno));
+ (void)bpf_odmcleanup(NULL);
+ return (PCAP_ERROR);
+ }
+ }
+
+ if (bpf_odmcleanup(errbuf) == PCAP_ERROR)
+ return (PCAP_ERROR);
+
+ rc = stat(BPF_NODE "0", &sbuf);
+ if (rc == -1 && errno != ENOENT) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: can't stat %s: %s",
+ BPF_NODE "0", pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+
+ if (rc == -1 || getmajor(sbuf.st_rdev) != major) {
+ for (i = 0; i < BPF_MINORS; i++) {
+ sprintf(buf, "%s%d", BPF_NODE, i);
+ unlink(buf);
+ if (mknod(buf, S_IRUSR | S_IFCHR, domakedev(major, i)) == -1) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: can't mknod %s: %s",
+ buf, pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+ }
+ }
+
+ /* Check if the driver is loaded */
+ memset(&cfg_ld, 0x0, sizeof(cfg_ld));
+ cfg_ld.path = buf;
+ sprintf(cfg_ld.path, "%s/%s", DRIVER_PATH, BPF_NAME);
+ if ((sysconfig(SYS_QUERYLOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) ||
+ (cfg_ld.kmid == 0)) {
+ /* Driver isn't loaded, load it now */
+ if (sysconfig(SYS_SINGLELOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: could not load driver: %s",
+ strerror(errno));
+ return (PCAP_ERROR);
+ }
+ }
+
+ /* Configure the driver */
+ cfg_km.cmd = CFG_INIT;
+ cfg_km.kmid = cfg_ld.kmid;
+ cfg_km.mdilen = sizeof(cfg_bpf);
+ cfg_km.mdiptr = (void *)&cfg_bpf;
+ for (i = 0; i < BPF_MINORS; i++) {
+ cfg_bpf.devno = domakedev(major, i);
+ if (sysconfig(SYS_CFGKMOD, (void *)&cfg_km, sizeof(cfg_km)) == -1) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: could not configure driver: %s",
+ strerror(errno));
+ return (PCAP_ERROR);
+ }
+ }
+
+ bpfloadedflag = 1;
+
+ return (0);
+}
+#endif
+
+/*
+ * Turn off rfmon mode if necessary.
+ */
+static void
+pcap_cleanup_bpf(pcap_t *p)
+{
+#ifdef HAVE_BSD_IEEE80211
+ int sock;
+ struct ifmediareq req;
+ struct ifreq ifr;
+#endif
+
+ if (p->md.must_do_on_close != 0) {
+ /*
+ * There's something we have to do when closing this
+ * pcap_t.
+ */
+#ifdef HAVE_BSD_IEEE80211
+ if (p->md.must_do_on_close & MUST_CLEAR_RFMON) {
+ /*
+ * We put the interface into rfmon mode;
+ * take it out of rfmon mode.
+ *
+ * XXX - if somebody else wants it in rfmon
+ * mode, this code cannot know that, so it'll take
+ * it out of rfmon mode.
+ */
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock == -1) {
+ fprintf(stderr,
+ "Can't restore interface flags (socket() failed: %s).\n"
+ "Please adjust manually.\n",
+ strerror(errno));
+ } else {
+ memset(&req, 0, sizeof(req));
+ strncpy(req.ifm_name, p->md.device,
+ sizeof(req.ifm_name));
+ if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) {
+ fprintf(stderr,
+ "Can't restore interface flags (SIOCGIFMEDIA failed: %s).\n"
+ "Please adjust manually.\n",
+ strerror(errno));
+ } else {
+ if (req.ifm_current & IFM_IEEE80211_MONITOR) {
+ /*
+ * Rfmon mode is currently on;
+ * turn it off.
+ */
+ memset(&ifr, 0, sizeof(ifr));
+ (void)strncpy(ifr.ifr_name,
+ p->md.device,
+ sizeof(ifr.ifr_name));
+ ifr.ifr_media =
+ req.ifm_current & ~IFM_IEEE80211_MONITOR;
+ if (ioctl(sock, SIOCSIFMEDIA,
+ &ifr) == -1) {
+ fprintf(stderr,
+ "Can't restore interface flags (SIOCSIFMEDIA failed: %s).\n"
+ "Please adjust manually.\n",
+ strerror(errno));
+ }
+ }
+ }
+ close(sock);
+ }
+ }
+#endif /* HAVE_BSD_IEEE80211 */
+
+ /*
+ * Take this pcap out of the list of pcaps for which we
+ * have to take the interface out of some mode.
+ */
+ pcap_remove_from_pcaps_to_close(p);
+ p->md.must_do_on_close = 0;
+ }
+
+#ifdef HAVE_ZEROCOPY_BPF
+ if (p->md.zerocopy) {
+ /*
+ * Delete the mappings. Note that p->buffer gets
+ * initialized to one of the mmapped regions in
+ * this case, so do not try and free it directly;
+ * null it out so that pcap_cleanup_live_common()
+ * doesn't try to free it.
+ */
+ if (p->md.zbuf1 != MAP_FAILED && p->md.zbuf1 != NULL)
+ (void) munmap(p->md.zbuf1, p->md.zbufsize);
+ if (p->md.zbuf2 != MAP_FAILED && p->md.zbuf2 != NULL)
+ (void) munmap(p->md.zbuf2, p->md.zbufsize);
+ p->buffer = NULL;
+ p->buffer = NULL;
+ }
+#endif
+ if (p->md.device != NULL) {
+ free(p->md.device);
+ p->md.device = NULL;
+ }
+ pcap_cleanup_live_common(p);
+}
+
+static int
+check_setif_failure(pcap_t *p, int error)
+{
+#ifdef __APPLE__
+ int fd;
+ struct ifreq ifr;
+ int err;
+#endif
+
+ if (error == ENXIO) {
+ /*
+ * No such device exists.
+ */
+#ifdef __APPLE__
+ if (p->opt.rfmon && strncmp(p->opt.source, "wlt", 3) == 0) {
+ /*
+ * Monitor mode was requested, and we're trying
+ * to open a "wltN" device. Assume that this
+ * is 10.4 and that we were asked to open an
+ * "enN" device; if that device exists, return
+ * "monitor mode not supported on the device".
+ */
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd != -1) {
+ strlcpy(ifr.ifr_name, "en",
+ sizeof(ifr.ifr_name));
+ strlcat(ifr.ifr_name, p->opt.source + 3,
+ sizeof(ifr.ifr_name));
+ if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
+ /*
+ * We assume this failed because
+ * the underlying device doesn't
+ * exist.
+ */
+ err = PCAP_ERROR_NO_SUCH_DEVICE;
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "SIOCGIFFLAGS on %s failed: %s",
+ ifr.ifr_name, pcap_strerror(errno));
+ } else {
+ /*
+ * The underlying "enN" device
+ * exists, but there's no
+ * corresponding "wltN" device;
+ * that means that the "enN"
+ * device doesn't support
+ * monitor mode, probably because
+ * it's an Ethernet device rather
+ * than a wireless device.
+ */
+ err = PCAP_ERROR_RFMON_NOTSUP;
+ }
+ close(fd);
+ } else {
+ /*
+ * We can't find out whether there's
+ * an underlying "enN" device, so
+ * just report "no such device".
+ */
+ err = PCAP_ERROR_NO_SUCH_DEVICE;
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "socket() failed: %s",
+ pcap_strerror(errno));
+ }
+ return (err);
+ }
+#endif
+ /*
+ * No such device.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETIF failed: %s",
+ pcap_strerror(errno));
+ return (PCAP_ERROR_NO_SUCH_DEVICE);
+ } else if (errno == ENETDOWN) {
+ /*
+ * Return a "network down" indication, so that
+ * the application can report that rather than
+ * saying we had a mysterious failure and
+ * suggest that they report a problem to the
+ * libpcap developers.
+ */
+ return (PCAP_ERROR_IFACE_NOT_UP);
+ } else {
+ /*
+ * Some other error; fill in the error string, and
+ * return PCAP_ERROR.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s",
+ p->opt.source, pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+}
+
+/*
+ * Default capture buffer size.
+ * 32K isn't very much for modern machines with fast networks; we
+ * pick .5M, as that's the maximum on at least some systems with BPF.
+ *
+ * However, on AIX 3.5, the larger buffer sized caused unrecoverable
+ * read failures under stress, so we leave it as 32K; yet another
+ * place where AIX's BPF is broken.
+ */
+#ifdef _AIX
+#define DEFAULT_BUFSIZE 32768
+#else
+#define DEFAULT_BUFSIZE 524288
+#endif
+
+static int
+pcap_activate_bpf(pcap_t *p)
+{
+ int status = 0;
+ int fd;
+#ifdef LIFNAMSIZ
+ char *zonesep;
+ struct lifreq ifr;
+ char *ifrname = ifr.lifr_name;
+ const size_t ifnamsiz = sizeof(ifr.lifr_name);
+#else
+ struct ifreq ifr;
+ char *ifrname = ifr.ifr_name;
+ const size_t ifnamsiz = sizeof(ifr.ifr_name);
+#endif
+ struct bpf_version bv;
+#ifdef __APPLE__
+ int sockfd;
+ char *wltdev = NULL;
+#endif
+#ifdef BIOCGDLTLIST
+ struct bpf_dltlist bdl;
+#if defined(__APPLE__) || defined(HAVE_BSD_IEEE80211)
+ int new_dlt;
+#endif
+#endif /* BIOCGDLTLIST */
+#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT)
+ u_int spoof_eth_src = 1;
+#endif
+ u_int v;
+ struct bpf_insn total_insn;
+ struct bpf_program total_prog;
+ struct utsname osinfo;
+
+#ifdef HAVE_DAG_API
+ if (strstr(device, "dag")) {
+ return dag_open_live(device, snaplen, promisc, to_ms, ebuf);
+ }
+#endif /* HAVE_DAG_API */
+
+#ifdef BIOCGDLTLIST
+ memset(&bdl, 0, sizeof(bdl));
+ int have_osinfo = 0;
+#ifdef HAVE_ZEROCOPY_BPF
+ struct bpf_zbuf bz;
+ u_int bufmode, zbufmax;
+#endif
+
+ fd = bpf_open(p);
+ if (fd < 0) {
+ status = fd;
+ goto bad;
+ }
+
+ p->fd = fd;
+
+ if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s",
+ pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+ if (bv.bv_major != BPF_MAJOR_VERSION ||
+ bv.bv_minor < BPF_MINOR_VERSION) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "kernel bpf filter out of date");
+ status = PCAP_ERROR;
+ goto bad;
+ }
+
+#if defined(LIFNAMSIZ) && defined(ZONENAME_MAX) && defined(lifr_zoneid)
+ /*
+ * Check if the given source network device has a '/' separated
+ * zonename prefix string. The zonename prefixed source device
+ * can be used by libpcap consumers to capture network traffic
+ * in non-global zones from the global zone on Solaris 11 and
+ * above. If the zonename prefix is present then we strip the
+ * prefix and pass the zone ID as part of lifr_zoneid.
+ */
+ if ((zonesep = strchr(p->opt.source, '/')) != NULL) {
+ char zonename[ZONENAME_MAX];
+ int znamelen;
+ char *lnamep;
+
+ znamelen = zonesep - p->opt.source;
+ (void) strlcpy(zonename, p->opt.source, znamelen + 1);
+ lnamep = strdup(zonesep + 1);
+ ifr.lifr_zoneid = getzoneidbyname(zonename);
+ free(p->opt.source);
+ p->opt.source = lnamep;
+ }
+#endif
+
+ p->md.device = strdup(p->opt.source);
+ if (p->md.device == NULL) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s",
+ pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+
+ /*
+ * Try finding a good size for the buffer; 32768 may be too
+ * big, so keep cutting it in half until we find a size
+ * that works, or run out of sizes to try. If the default
+ * is larger, don't make it smaller.
+ *
+ * XXX - there should be a user-accessible hook to set the
+ * initial buffer size.
+ * Attempt to find out the version of the OS on which we're running.
+ */
+ if (uname(&osinfo) == 0)
+ have_osinfo = 1;
+
+#ifdef __APPLE__
+ /*
+ * See comment in pcap_can_set_rfmon_bpf() for an explanation
+ * of why we check the version number.
+ */
+ if (p->opt.rfmon) {
+ if (have_osinfo) {
+ /*
+ * We assume osinfo.sysname is "Darwin", because
+ * __APPLE__ is defined. We just check the version.
+ */
+ if (osinfo.release[0] < '8' &&
+ osinfo.release[1] == '.') {
+ /*
+ * 10.3 (Darwin 7.x) or earlier.
+ */
+ status = PCAP_ERROR_RFMON_NOTSUP;
+ goto bad;
+ }
+ if (osinfo.release[0] == '8' &&
+ osinfo.release[1] == '.') {
+ /*
+ * 10.4 (Darwin 8.x). s/en/wlt/
+ */
+ if (strncmp(p->opt.source, "en", 2) != 0) {
+ /*
+ * Not an enN device; check
+ * whether the device even exists.
+ */
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sockfd != -1) {
+ strlcpy(ifrname,
+ p->opt.source, ifnamsiz);
+ if (ioctl(sockfd, SIOCGIFFLAGS,
+ (char *)&ifr) < 0) {
+ /*
+ * We assume this
+ * failed because
+ * the underlying
+ * device doesn't
+ * exist.
+ */
+ status = PCAP_ERROR_NO_SUCH_DEVICE;
+ snprintf(p->errbuf,
+ PCAP_ERRBUF_SIZE,
+ "SIOCGIFFLAGS failed: %s",
+ pcap_strerror(errno));
+ } else
+ status = PCAP_ERROR_RFMON_NOTSUP;
+ close(sockfd);
+ } else {
+ /*
+ * We can't find out whether
+ * the device exists, so just
+ * report "no such device".
+ */
+ status = PCAP_ERROR_NO_SUCH_DEVICE;
+ snprintf(p->errbuf,
+ PCAP_ERRBUF_SIZE,
+ "socket() failed: %s",
+ pcap_strerror(errno));
+ }
+ goto bad;
+ }
+ wltdev = malloc(strlen(p->opt.source) + 2);
+ if (wltdev == NULL) {
+ (void)snprintf(p->errbuf,
+ PCAP_ERRBUF_SIZE, "malloc: %s",
+ pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+ strcpy(wltdev, "wlt");
+ strcat(wltdev, p->opt.source + 2);
+ free(p->opt.source);
+ p->opt.source = wltdev;
+ }
+ /*
+ * Everything else is 10.5 or later; for those,
+ * we just open the enN device, and set the DLT.
+ */
+ }
+ }
+#endif /* __APPLE__ */
+#ifdef HAVE_ZEROCOPY_BPF
+ /*
+ * If the BPF extension to set buffer mode is present, try setting
+ * the mode to zero-copy. If that fails, use regular buffering. If
+ * it succeeds but other setup fails, return an error to the user.
+ */
+ bufmode = BPF_BUFMODE_ZBUF;
+ if (ioctl(fd, BIOCSETBUFMODE, (caddr_t)&bufmode) == 0) {
+ /*
+ * We have zerocopy BPF; use it.
+ */
+ p->md.zerocopy = 1;
+
+ /*
+ * How to pick a buffer size: first, query the maximum buffer
+ * size supported by zero-copy. This also lets us quickly
+ * determine whether the kernel generally supports zero-copy.
+ * Then, if a buffer size was specified, use that, otherwise
+ * query the default buffer size, which reflects kernel
+ * policy for a desired default. Round to the nearest page
+ * size.
+ */
+ if (ioctl(fd, BIOCGETZMAX, (caddr_t)&zbufmax) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGETZMAX: %s",
+ pcap_strerror(errno));
+ goto bad;
+ }
+
+ if (p->opt.buffer_size != 0) {
+ /*
+ * A buffer size was explicitly specified; use it.
+ */
+ v = p->opt.buffer_size;
+ } else {
+ if ((ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) ||
+ v < DEFAULT_BUFSIZE)
+ v = DEFAULT_BUFSIZE;
+ }
+#ifndef roundup
+#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */
+#endif
+ p->md.zbufsize = roundup(v, getpagesize());
+ if (p->md.zbufsize > zbufmax)
+ p->md.zbufsize = zbufmax;
+ p->md.zbuf1 = mmap(NULL, p->md.zbufsize, PROT_READ | PROT_WRITE,
+ MAP_ANON, -1, 0);
+ p->md.zbuf2 = mmap(NULL, p->md.zbufsize, PROT_READ | PROT_WRITE,
+ MAP_ANON, -1, 0);
+ if (p->md.zbuf1 == MAP_FAILED || p->md.zbuf2 == MAP_FAILED) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "mmap: %s",
+ pcap_strerror(errno));
+ goto bad;
+ }
+ memset(&bz, 0, sizeof(bz)); /* bzero() deprecated, replaced with memset() */
+ bz.bz_bufa = p->md.zbuf1;
+ bz.bz_bufb = p->md.zbuf2;
+ bz.bz_buflen = p->md.zbufsize;
+ if (ioctl(fd, BIOCSETZBUF, (caddr_t)&bz) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETZBUF: %s",
+ pcap_strerror(errno));
+ goto bad;
+ }
+ (void)strncpy(ifrname, p->opt.source, ifnamsiz);
+ if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s",
+ p->opt.source, pcap_strerror(errno));
+ goto bad;
+ }
+ v = p->md.zbufsize - sizeof(struct bpf_zbuf_header);
+ } else
+#endif
+ {
+ /*
+ * We don't have zerocopy BPF.
+ * Set the buffer size.
+ */
+ if (p->opt.buffer_size != 0) {
+ /*
+ * A buffer size was explicitly specified; use it.
+ */
+ if (ioctl(fd, BIOCSBLEN,
+ (caddr_t)&p->opt.buffer_size) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "BIOCSBLEN: %s: %s", p->opt.source,
+ pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+
+ /*
+ * Now bind to the device.
+ */
+ (void)strncpy(ifrname, p->opt.source, ifnamsiz);
+#ifdef BIOCSETLIF
+ if (ioctl(fd, BIOCSETLIF, (caddr_t)&ifr) < 0)
+#else
+ if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0)
+#endif
+ {
+ status = check_setif_failure(p, errno);
+ goto bad;
+ }
+ } else {
+ /*
+ * No buffer size was explicitly specified.
+ *
+ * Try finding a good size for the buffer;
+ * DEFAULT_BUFSIZE may be too big, so keep
+ * cutting it in half until we find a size
+ * that works, or run out of sizes to try.
+ * If the default is larger, don't make it smaller.
+ */
+ if ((ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) ||
+ v < DEFAULT_BUFSIZE)
+ v = DEFAULT_BUFSIZE;
+ for ( ; v != 0; v >>= 1) {
+ /*
+ * Ignore the return value - this is because the
+ * call fails on BPF systems that don't have
+ * kernel malloc. And if the call fails, it's
+ * no big deal, we just continue to use the
+ * standard buffer size.
+ */
+ (void) ioctl(fd, BIOCSBLEN, (caddr_t)&v);
+
+ (void)strncpy(ifrname, p->opt.source, ifnamsiz);
+#ifdef BIOCSETLIF
+ if (ioctl(fd, BIOCSETLIF, (caddr_t)&ifr) >= 0)
+#else
+ if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0)
+#endif
+ break; /* that size worked; we're done */
+
+ if (errno != ENOBUFS) {
+ status = check_setif_failure(p, errno);
+ goto bad;
+ }
+ }
+
+ if (v == 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "BIOCSBLEN: %s: No buffer size worked",
+ p->opt.source);
+ status = PCAP_ERROR;
+ goto bad;
+ }
+ }
+ }
+#endif
+
+ /* Get the data link layer type. */
+ if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s",
+ pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+
+#ifdef _AIX
+ /*
+ * AIX's BPF returns IFF_ types, not DLT_ types, in BIOCGDLT.
+ */
+ switch (v) {
+
+ case IFT_ETHER:
+ case IFT_ISO88023:
+ v = DLT_EN10MB;
+ break;
+
+ case IFT_FDDI:
+ v = DLT_FDDI;
+ break;
+
+ case IFT_ISO88025:
+ v = DLT_IEEE802;
+ break;
+
+ case IFT_LOOP:
+ v = DLT_NULL;
+ break;
+
+ default:
+ /*
+ * We don't know what to map this to yet.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown interface type %u",
+ v);
+ status = PCAP_ERROR;
+ goto bad;
+ }
+#endif
+#if _BSDI_VERSION - 0 >= 199510
+ /* The SLIP and PPP link layer header changed in BSD/OS 2.1 */
+ switch (v) {
+
+ case DLT_SLIP:
+ v = DLT_SLIP_BSDOS;
+ break;
+
+ case DLT_PPP:
+ v = DLT_PPP_BSDOS;
+ break;
+
+ case 11: /*DLT_FR*/
+ v = DLT_FRELAY;
+ break;
+
+ case 12: /*DLT_C_HDLC*/
+ v = DLT_CHDLC;
+ break;
+ }
+#endif
+
+#ifdef BIOCGDLTLIST
+ /*
+ * We know the default link type -- now determine all the DLTs
+ * this interface supports. If this fails with EINVAL, it's
+ * not fatal; we just don't get to use the feature later.
+ */
+ if (get_dlt_list(fd, v, &bdl, p->errbuf) == -1) {
+ status = PCAP_ERROR;
+ goto bad;
+ }
+ p->dlt_count = bdl.bfl_len;
+ p->dlt_list = bdl.bfl_list;
+
+#ifdef __APPLE__
+ /*
+ * Monitor mode fun, continued.
+ *
+ * For 10.5 and, we're assuming, later releases, as noted above,
+ * 802.1 adapters that support monitor mode offer both DLT_EN10MB,
+ * DLT_IEEE802_11, and possibly some 802.11-plus-radio-information
+ * DLT_ value. Choosing one of the 802.11 DLT_ values will turn
+ * monitor mode on.
+ *
+ * Therefore, if the user asked for monitor mode, we filter out
+ * the DLT_EN10MB value, as you can't get that in monitor mode,
+ * and, if the user didn't ask for monitor mode, we filter out
+ * the 802.11 DLT_ values, because selecting those will turn
+ * monitor mode on. Then, for monitor mode, if an 802.11-plus-
+ * radio DLT_ value is offered, we try to select that, otherwise
+ * we try to select DLT_IEEE802_11.
+ */
+ if (have_osinfo) {
+ if (isdigit((unsigned)osinfo.release[0]) &&
+ (osinfo.release[0] == '9' ||
+ isdigit((unsigned)osinfo.release[1]))) {
+ /*
+ * 10.5 (Darwin 9.x), or later.
+ */
+ new_dlt = find_802_11(&bdl);
+ if (new_dlt != -1) {
+ /*
+ * We have at least one 802.11 DLT_ value,
+ * so this is an 802.11 interface.
+ * new_dlt is the best of the 802.11
+ * DLT_ values in the list.
+ */
+ if (p->opt.rfmon) {
+ /*
+ * Our caller wants monitor mode.
+ * Purge DLT_EN10MB from the list
+ * of link-layer types, as selecting
+ * it will keep monitor mode off.
+ */
+ remove_en(p);
+
+ /*
+ * If the new mode we want isn't
+ * the default mode, attempt to
+ * select the new mode.
+ */
+ if (new_dlt != v) {
+ if (ioctl(p->fd, BIOCSDLT,
+ &new_dlt) != -1) {
+ /*
+ * We succeeded;
+ * make this the
+ * new DLT_ value.
+ */
+ v = new_dlt;
+ }
+ }
+ } else {
+ /*
+ * Our caller doesn't want
+ * monitor mode. Unless this
+ * is being done by pcap_open_live(),
+ * purge the 802.11 link-layer types
+ * from the list, as selecting
+ * one of them will turn monitor
+ * mode on.
+ */
+ if (!p->oldstyle)
+ remove_802_11(p);
+ }
+ } else {
+ if (p->opt.rfmon) {
+ /*
+ * The caller requested monitor
+ * mode, but we have no 802.11
+ * link-layer types, so they
+ * can't have it.
+ */
+ status = PCAP_ERROR_RFMON_NOTSUP;
+ goto bad;
+ }
+ }
+ }
+ }
+#elif defined(HAVE_BSD_IEEE80211)
+ /*
+ * *BSD with the new 802.11 ioctls.
+ * Do we want monitor mode?
+ */
+ if (p->opt.rfmon) {
+ /*
+ * Try to put the interface into monitor mode.
+ */
+ status = monitor_mode(p, 1);
+ if (status != 0) {
+ /*
+ * We failed.
+ */
+ goto bad;
+ }
+
+ /*
+ * We're in monitor mode.
+ * Try to find the best 802.11 DLT_ value and, if we
+ * succeed, try to switch to that mode if we're not
+ * already in that mode.
+ */
+ new_dlt = find_802_11(&bdl);
+ if (new_dlt != -1) {
+ /*
+ * We have at least one 802.11 DLT_ value.
+ * new_dlt is the best of the 802.11
+ * DLT_ values in the list.
+ *
+ * If the new mode we want isn't the default mode,
+ * attempt to select the new mode.
+ */
+ if (new_dlt != v) {
+ if (ioctl(p->fd, BIOCSDLT, &new_dlt) != -1) {
+ /*
+ * We succeeded; make this the
+ * new DLT_ value.
+ */
+ v = new_dlt;
+ }
+ }
+ }
+ }
+#endif /* various platforms */
+#endif /* BIOCGDLTLIST */
+
+ /*
+ * If this is an Ethernet device, and we don't have a DLT_ list,
+ * give it a list with DLT_EN10MB and DLT_DOCSIS. (That'd give
+ * 802.11 interfaces DLT_DOCSIS, which isn't the right thing to
+ * do, but there's not much we can do about that without finding
+ * some other way of determining whether it's an Ethernet or 802.11
+ * device.)
+ */
+ if (v == DLT_EN10MB && p->dlt_count == 0) {
+ p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
+ /*
+ * If that fails, just leave the list empty.
+ */
+ if (p->dlt_list != NULL) {
+ p->dlt_list[0] = DLT_EN10MB;
+ p->dlt_list[1] = DLT_DOCSIS;
+ p->dlt_count = 2;
+ }
+ }
+#ifdef PCAP_FDDIPAD
+ if (v == DLT_FDDI)
+ p->fddipad = PCAP_FDDIPAD;
+ else
+ p->fddipad = 0;
+#endif
+ p->linktype = v;
+
+#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT)
+ /*
+ * Do a BIOCSHDRCMPLT, if defined, to turn that flag on, so
+ * the link-layer source address isn't forcibly overwritten.
+ * (Should we ignore errors? Should we do this only if
+ * we're open for writing?)
+ *
+ * XXX - I seem to remember some packet-sending bug in some
+ * BSDs - check CVS log for "bpf.c"?
+ */
+ if (ioctl(fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) {
+ (void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "BIOCSHDRCMPLT: %s", pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+#endif
+ /* set timeout */
+#ifdef HAVE_ZEROCOPY_BPF
+ if (p->md.timeout != 0 && !p->md.zerocopy) {
+#else
+ if (p->md.timeout) {
+#endif
+ /*
+ * XXX - is this seconds/nanoseconds in AIX?
+ * (Treating it as such doesn't fix the timeout
+ * problem described below.)
+ *
+ * XXX - Mac OS X 10.6 mishandles BIOCSRTIMEOUT in
+ * 64-bit userland - it takes, as an argument, a
+ * "struct BPF_TIMEVAL", which has 32-bit tv_sec
+ * and tv_usec, rather than a "struct timeval".
+ *
+ * If this platform defines "struct BPF_TIMEVAL",
+ * we check whether the structure size in BIOCSRTIMEOUT
+ * is that of a "struct timeval" and, if not, we use
+ * a "struct BPF_TIMEVAL" rather than a "struct timeval".
+ * (That way, if the bug is fixed in a future release,
+ * we will still do the right thing.)
+ */
+ struct timeval to;
+#ifdef HAVE_STRUCT_BPF_TIMEVAL
+ struct BPF_TIMEVAL bpf_to;
+
+ if (IOCPARM_LEN(BIOCSRTIMEOUT) != sizeof(struct timeval)) {
+ bpf_to.tv_sec = p->md.timeout / 1000;
+ bpf_to.tv_usec = (p->md.timeout * 1000) % 1000000;
+ if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&bpf_to) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "BIOCSRTIMEOUT: %s", pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+ } else {
+#endif
+ to.tv_sec = p->md.timeout / 1000;
+ to.tv_usec = (p->md.timeout * 1000) % 1000000;
+ if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "BIOCSRTIMEOUT: %s", pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+#ifdef HAVE_STRUCT_BPF_TIMEVAL
+ }
+#endif
+ }
+
+#ifdef _AIX
+#ifdef BIOCIMMEDIATE
+ /*
+ * Darren Reed notes that
+ *
+ * On AIX (4.2 at least), if BIOCIMMEDIATE is not set, the
+ * timeout appears to be ignored and it waits until the buffer
+ * is filled before returning. The result of not having it
+ * set is almost worse than useless if your BPF filter
+ * is reducing things to only a few packets (i.e. one every
+ * second or so).
+ *
+ * so we turn BIOCIMMEDIATE mode on if this is AIX.
+ *
+ * We don't turn it on for other platforms, as that means we
+ * get woken up for every packet, which may not be what we want;
+ * in the Winter 1993 USENIX paper on BPF, they say:
+ *
+ * Since a process might want to look at every packet on a
+ * network and the time between packets can be only a few
+ * microseconds, it is not possible to do a read system call
+ * per packet and BPF must collect the data from several
+ * packets and return it as a unit when the monitoring
+ * application does a read.
+ *
+ * which I infer is the reason for the timeout - it means we
+ * wait that amount of time, in the hopes that more packets
+ * will arrive and we'll get them all with one read.
+ *
+ * Setting BIOCIMMEDIATE mode on FreeBSD (and probably other
+ * BSDs) causes the timeout to be ignored.
+ *
+ * On the other hand, some platforms (e.g., Linux) don't support
+ * timeouts, they just hand stuff to you as soon as it arrives;
+ * if that doesn't cause a problem on those platforms, it may
+ * be OK to have BIOCIMMEDIATE mode on BSD as well.
+ *
+ * (Note, though, that applications may depend on the read
+ * completing, even if no packets have arrived, when the timeout
+ * expires, e.g. GUI applications that have to check for input
+ * while waiting for packets to arrive; a non-zero timeout
+ * prevents "select()" from working right on FreeBSD and
+ * possibly other BSDs, as the timer doesn't start until a
+ * "read()" is done, so the timer isn't in effect if the
+ * application is blocked on a "select()", and the "select()"
+ * doesn't get woken up for a BPF device until the buffer
+ * fills up.)
+ */
+ v = 1;
+ if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCIMMEDIATE: %s",
+ pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+#endif /* BIOCIMMEDIATE */
+#endif /* _AIX */
+
+ if (p->opt.promisc) {
+ /* set promiscuous mode, just warn if it fails */
+ if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s",
+ pcap_strerror(errno));
+ status = PCAP_WARNING_PROMISC_NOTSUP;
+ }
+ }
+
+ if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s",
+ pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+ p->bufsize = v;
+#ifdef HAVE_ZEROCOPY_BPF
+ if (!p->md.zerocopy) {
+#endif
+ p->buffer = (u_char *)malloc(p->bufsize);
+ if (p->buffer == NULL) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
+ pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+#ifdef _AIX
+ /* For some strange reason this seems to prevent the EFAULT
+ * problems we have experienced from AIX BPF. */
+ memset(p->buffer, 0x0, p->bufsize);
+#endif
+#ifdef HAVE_ZEROCOPY_BPF
+ }
+#endif
+
+ /*
+ * If there's no filter program installed, there's
+ * no indication to the kernel of what the snapshot
+ * length should be, so no snapshotting is done.
+ *
+ * Therefore, when we open the device, we install
+ * an "accept everything" filter with the specified
+ * snapshot length.
+ */
+ total_insn.code = (u_short)(BPF_RET | BPF_K);
+ total_insn.jt = 0;
+ total_insn.jf = 0;
+ total_insn.k = p->snapshot;
+
+ total_prog.bf_len = 1;
+ total_prog.bf_insns = &total_insn;
+ if (ioctl(p->fd, BIOCSETF, (caddr_t)&total_prog) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
+ pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+
+ /*
+ * On most BPF platforms, either you can do a "select()" or
+ * "poll()" on a BPF file descriptor and it works correctly,
+ * or you can do it and it will return "readable" if the
+ * hold buffer is full but not if the timeout expires *and*
+ * a non-blocking read will, if the hold buffer is empty
+ * but the store buffer isn't empty, rotate the buffers
+ * and return what packets are available.
+ *
+ * In the latter case, the fact that a non-blocking read
+ * will give you the available packets means you can work
+ * around the failure of "select()" and "poll()" to wake up
+ * and return "readable" when the timeout expires by using
+ * the timeout as the "select()" or "poll()" timeout, putting
+ * the BPF descriptor into non-blocking mode, and read from
+ * it regardless of whether "select()" reports it as readable
+ * or not.
+ *
+ * However, in FreeBSD 4.3 and 4.4, "select()" and "poll()"
+ * won't wake up and return "readable" if the timer expires
+ * and non-blocking reads return EWOULDBLOCK if the hold
+ * buffer is empty, even if the store buffer is non-empty.
+ *
+ * This means the workaround in question won't work.
+ *
+ * Therefore, on FreeBSD 4.3 and 4.4, we set "p->selectable_fd"
+ * to -1, which means "sorry, you can't use 'select()' or 'poll()'
+ * here". On all other BPF platforms, we set it to the FD for
+ * the BPF device; in NetBSD, OpenBSD, and Darwin, a non-blocking
+ * read will, if the hold buffer is empty and the store buffer
+ * isn't empty, rotate the buffers and return what packets are
+ * there (and in sufficiently recent versions of OpenBSD
+ * "select()" and "poll()" should work correctly).
+ *
+ * XXX - what about AIX?
+ */
+ p->selectable_fd = p->fd; /* assume select() works until we know otherwise */
+ if (have_osinfo) {
+ /*
+ * We can check what OS this is.
+ */
+ if (strcmp(osinfo.sysname, "FreeBSD") == 0) {
+ if (strncmp(osinfo.release, "4.3-", 4) == 0 ||
+ strncmp(osinfo.release, "4.4-", 4) == 0)
+ p->selectable_fd = -1;
+ }
+ }
+
+ p->read_op = pcap_read_bpf;
+ p->inject_op = pcap_inject_bpf;
+ p->setfilter_op = pcap_setfilter_bpf;
+ p->setdirection_op = pcap_setdirection_bpf;
+ p->set_datalink_op = pcap_set_datalink_bpf;
+ p->getnonblock_op = pcap_getnonblock_bpf;
+ p->setnonblock_op = pcap_setnonblock_bpf;
+ p->stats_op = pcap_stats_bpf;
+ p->cleanup_op = pcap_cleanup_bpf;
+
+ return (status);
+ bad:
+ pcap_cleanup_bpf(p);
+ return (status);
+}
+
+int
+pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
+{
+ return (0);
+}
+
+#ifdef HAVE_BSD_IEEE80211
+static int
+monitor_mode(pcap_t *p, int set)
+{
+ int sock;
+ struct ifmediareq req;
+ int *media_list;
+ int i;
+ int can_do;
+ struct ifreq ifr;
+
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't open socket: %s",
+ pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+
+ memset(&req, 0, sizeof req);
+ strncpy(req.ifm_name, p->opt.source, sizeof req.ifm_name);
+
+ /*
+ * Find out how many media types we have.
+ */
+ if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) {
+ /*
+ * Can't get the media types.
+ */
+ switch (errno) {
+
+ case ENXIO:
+ /*
+ * There's no such device.
+ */
+ close(sock);
+ return (PCAP_ERROR_NO_SUCH_DEVICE);
+
+ case EINVAL:
+ /*
+ * Interface doesn't support SIOC{G,S}IFMEDIA.
+ */
+ close(sock);
+ return (PCAP_ERROR_RFMON_NOTSUP);
+
+ default:
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "SIOCGIFMEDIA 1: %s", pcap_strerror(errno));
+ close(sock);
+ return (PCAP_ERROR);
+ }
+ }
+ if (req.ifm_count == 0) {
+ /*
+ * No media types.
+ */
+ close(sock);
+ return (PCAP_ERROR_RFMON_NOTSUP);
+ }
+
+ /*
+ * Allocate a buffer to hold all the media types, and
+ * get the media types.
+ */
+ media_list = malloc(req.ifm_count * sizeof(int));
+ if (media_list == NULL) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
+ pcap_strerror(errno));
+ close(sock);
+ return (PCAP_ERROR);
+ }
+ req.ifm_ulist = media_list;
+ if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFMEDIA: %s",
+ pcap_strerror(errno));
+ free(media_list);
+ close(sock);
+ return (PCAP_ERROR);
+ }
+
+ /*
+ * Look for an 802.11 "automatic" media type.
+ * We assume that all 802.11 adapters have that media type,
+ * and that it will carry the monitor mode supported flag.
+ */
+ can_do = 0;
+ for (i = 0; i < req.ifm_count; i++) {
+ if (IFM_TYPE(media_list[i]) == IFM_IEEE80211
+ && IFM_SUBTYPE(media_list[i]) == IFM_AUTO) {
+ /* OK, does it do monitor mode? */
+ if (media_list[i] & IFM_IEEE80211_MONITOR) {
+ can_do = 1;
+ break;
+ }
+ }
+ }
+ free(media_list);
+ if (!can_do) {
+ /*
+ * This adapter doesn't support monitor mode.
+ */
+ close(sock);
+ return (PCAP_ERROR_RFMON_NOTSUP);
+ }
+
+ if (set) {
+ /*
+ * Don't just check whether we can enable monitor mode,
+ * do so, if it's not already enabled.
+ */
+ if ((req.ifm_current & IFM_IEEE80211_MONITOR) == 0) {
+ /*
+ * Monitor mode isn't currently on, so turn it on,
+ * and remember that we should turn it off when the
+ * pcap_t is closed.
+ */
+
+ /*
+ * If we haven't already done so, arrange to have
+ * "pcap_close_all()" called when we exit.
+ */
+ if (!pcap_do_addexit(p)) {
+ /*
+ * "atexit()" failed; don't put the interface
+ * in monitor mode, just give up.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "atexit failed");
+ close(sock);
+ return (PCAP_ERROR);
+ }
+ memset(&ifr, 0, sizeof(ifr));
+ (void)strncpy(ifr.ifr_name, p->opt.source,
+ sizeof(ifr.ifr_name));
+ ifr.ifr_media = req.ifm_current | IFM_IEEE80211_MONITOR;
+ if (ioctl(sock, SIOCSIFMEDIA, &ifr) == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "SIOCSIFMEDIA: %s", pcap_strerror(errno));
+ close(sock);
+ return (PCAP_ERROR);
+ }
+
+ p->md.must_do_on_close |= MUST_CLEAR_RFMON;
+
+ /*
+ * Add this to the list of pcaps to close when we exit.
+ */
+ pcap_add_to_pcaps_to_close(p);
+ }
+ }
+ return (0);
+}
+#endif /* HAVE_BSD_IEEE80211 */
+
+#if defined(BIOCGDLTLIST) && (defined(__APPLE__) || defined(HAVE_BSD_IEEE80211))
+/*
+ * Check whether we have any 802.11 link-layer types; return the best
+ * of the 802.11 link-layer types if we find one, and return -1
+ * otherwise.
+ *
+ * DLT_IEEE802_11_RADIO, with the radiotap header, is considered the
+ * best 802.11 link-layer type; any of the other 802.11-plus-radio
+ * headers are second-best; 802.11 with no radio information is
+ * the least good.
+ */
+static int
+find_802_11(struct bpf_dltlist *bdlp)
+{
+ int new_dlt;
+ int i;
+
+ /*
+ * Scan the list of DLT_ values, looking for 802.11 values,
+ * and, if we find any, choose the best of them.
+ */
+ new_dlt = -1;
+ for (i = 0; i < bdlp->bfl_len; i++) {
+ switch (bdlp->bfl_list[i]) {
+
+ case DLT_IEEE802_11:
+ /*
+ * 802.11, but no radio.
+ *
+ * Offer this, and select it as the new mode
+ * unless we've already found an 802.11
+ * header with radio information.
+ */
+ if (new_dlt == -1)
+ new_dlt = bdlp->bfl_list[i];
+ break;
+
+ case DLT_PRISM_HEADER:
+ case DLT_AIRONET_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ /*
+ * 802.11 with radio, but not radiotap.
+ *
+ * Offer this, and select it as the new mode
+ * unless we've already found the radiotap DLT_.
+ */
+ if (new_dlt != DLT_IEEE802_11_RADIO)
+ new_dlt = bdlp->bfl_list[i];
+ break;
+
+ case DLT_IEEE802_11_RADIO:
+ /*
+ * 802.11 with radiotap.
+ *
+ * Offer this, and select it as the new mode.
+ */
+ new_dlt = bdlp->bfl_list[i];
+ break;
+
+ default:
+ /*
+ * Not 802.11.
+ */
+ break;
+ }
+ }
+
+ return (new_dlt);
+}
+#endif /* defined(BIOCGDLTLIST) && (defined(__APPLE__) || defined(HAVE_BSD_IEEE80211)) */
+
+#if defined(__APPLE__) && defined(BIOCGDLTLIST)
+/*
+ * Remove DLT_EN10MB from the list of DLT_ values, as we're in monitor mode,
+ * and DLT_EN10MB isn't supported in monitor mode.
+ */
+static void
+remove_en(pcap_t *p)
+{
+ int i, j;
+
+ /*
+ * Scan the list of DLT_ values and discard DLT_EN10MB.
+ */
+ j = 0;
+ for (i = 0; i < p->dlt_count; i++) {
+ switch (p->dlt_list[i]) {
+
+ case DLT_EN10MB:
+ /*
+ * Don't offer this one.
+ */
+ continue;
+
+ default:
+ /*
+ * Just copy this mode over.
+ */
+ break;
+ }
+
+ /*
+ * Copy this DLT_ value to its new position.
+ */
+ p->dlt_list[j] = p->dlt_list[i];
+ j++;
+ }
+
+ /*
+ * Set the DLT_ count to the number of entries we copied.
+ */
+ p->dlt_count = j;
+}
+
+/*
+ * Remove 802.11 link-layer types from the list of DLT_ values, as
+ * we're not in monitor mode, and those DLT_ values will switch us
+ * to monitor mode.
+ */
+static void
+remove_802_11(pcap_t *p)
+{
+ int i, j;
+
+ /*
+ * Scan the list of DLT_ values and discard 802.11 values.
+ */
+ j = 0;
+ for (i = 0; i < p->dlt_count; i++) {
+ switch (p->dlt_list[i]) {
+
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_AIRONET_HEADER:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_IEEE802_11_RADIO_AVS:
+ /*
+ * 802.11. Don't offer this one.
+ */
+ continue;
+
+ default:
+ /*
+ * Just copy this mode over.
+ */
+ break;
+ }
+
+ /*
+ * Copy this DLT_ value to its new position.
+ */
+ p->dlt_list[j] = p->dlt_list[i];
+ j++;
+ }
+
+ /*
+ * Set the DLT_ count to the number of entries we copied.
+ */
+ p->dlt_count = j;
+}
+#endif /* defined(__APPLE__) && defined(BIOCGDLTLIST) */
+
+static int
+pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
+{
+ /*
+ * Free any user-mode filter we might happen to have installed.
+ */
+ pcap_freecode(&p->fcode);
+
+ /*
+ * Try to install the kernel filter.
+ */
+ if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) == 0) {
+ /*
+ * It worked.
+ */
+ p->md.use_bpf = 1; /* filtering in the kernel */
+
+ /*
+ * Discard any previously-received packets, as they might
+ * have passed whatever filter was formerly in effect, but
+ * might not pass this filter (BIOCSETF discards packets
+ * buffered in the kernel, so you can lose packets in any
+ * case).
+ */
+ p->cc = 0;
+ return (0);
+ }
+
+ /*
+ * We failed.
+ *
+ * If it failed with EINVAL, that's probably because the program
+ * is invalid or too big. Validate it ourselves; if we like it
+ * (we currently allow backward branches, to support protochain),
+ * run it in userland. (There's no notion of "too big" for
+ * userland.)
+ *
+ * Otherwise, just give up.
+ * XXX - if the copy of the program into the kernel failed,
+ * we will get EINVAL rather than, say, EFAULT on at least
+ * some kernels.
+ */
+ if (errno != EINVAL) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
+ pcap_strerror(errno));
+ return (-1);
+ }
+
+ /*
+ * install_bpf_program() validates the program.
+ *
+ * XXX - what if we already have a filter in the kernel?
+ */
+ if (install_bpf_program(p, fp) < 0)
+ return (-1);
+ p->md.use_bpf = 0; /* filtering in userland */
+ return (0);
+}
+
+/*
+ * Set direction flag: Which packets do we accept on a forwarding
+ * single device? IN, OUT or both?
+ */
+static int
+pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
+{
+#if defined(BIOCSDIRECTION)
+ u_int direction;
+
+ direction = (d == PCAP_D_IN) ? BPF_D_IN :
+ ((d == PCAP_D_OUT) ? BPF_D_OUT : BPF_D_INOUT);
+ if (ioctl(p->fd, BIOCSDIRECTION, &direction) == -1) {
+ (void) snprintf(p->errbuf, sizeof(p->errbuf),
+ "Cannot set direction to %s: %s",
+ (d == PCAP_D_IN) ? "PCAP_D_IN" :
+ ((d == PCAP_D_OUT) ? "PCAP_D_OUT" : "PCAP_D_INOUT"),
+ strerror(errno));
+ return (-1);
+ }
+ return (0);
+#elif defined(BIOCSSEESENT)
+ u_int seesent;
+
+ /*
+ * We don't support PCAP_D_OUT.
+ */
+ if (d == PCAP_D_OUT) {
+ snprintf(p->errbuf, sizeof(p->errbuf),
+ "Setting direction to PCAP_D_OUT is not supported on BPF");
+ return -1;
+ }
+
+ seesent = (d == PCAP_D_INOUT);
+ if (ioctl(p->fd, BIOCSSEESENT, &seesent) == -1) {
+ (void) snprintf(p->errbuf, sizeof(p->errbuf),
+ "Cannot set direction to %s: %s",
+ (d == PCAP_D_INOUT) ? "PCAP_D_INOUT" : "PCAP_D_IN",
+ strerror(errno));
+ return (-1);
+ }
+ return (0);
+#else
+ (void) snprintf(p->errbuf, sizeof(p->errbuf),
+ "This system doesn't support BIOCSSEESENT, so the direction can't be set");
+ return (-1);
+#endif
+}
+
+static int
+pcap_set_datalink_bpf(pcap_t *p, int dlt)
+{
+#ifdef BIOCSDLT
+ if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) {
+ (void) snprintf(p->errbuf, sizeof(p->errbuf),
+ "Cannot set DLT %d: %s", dlt, strerror(errno));
+ return (-1);
+ }
+#endif
+ return (0);
+}
diff --git a/freebsd/contrib/libpcap/pcap-common.c b/freebsd/contrib/libpcap/pcap-common.c
new file mode 100644
index 00000000..7b683a9e
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap-common.c
@@ -0,0 +1,1174 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * pcap-common.c - common code for pcap and pcap-ng files
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/types.h>
+#endif /* WIN32 */
+
+#include "pcap-int.h"
+#include "pcap/usb.h"
+
+#include "pcap-common.h"
+
+/*
+ * We don't write DLT_* values to capture files, because they're not the
+ * same on all platforms.
+ *
+ * Unfortunately, the various flavors of BSD have not always used the same
+ * numerical values for the same data types, and various patches to
+ * libpcap for non-BSD OSes have added their own DLT_* codes for link
+ * layer encapsulation types seen on those OSes, and those codes have had,
+ * in some cases, values that were also used, on other platforms, for other
+ * link layer encapsulation types.
+ *
+ * This means that capture files of a type whose numerical DLT_* code
+ * means different things on different BSDs, or with different versions
+ * of libpcap, can't always be read on systems other than those like
+ * the one running on the machine on which the capture was made.
+ *
+ * Instead, we define here a set of LINKTYPE_* codes, and map DLT_* codes
+ * to LINKTYPE_* codes when writing a savefile header, and map LINKTYPE_*
+ * codes to DLT_* codes when reading a savefile header.
+ *
+ * For those DLT_* codes that have, as far as we know, the same values on
+ * all platforms (DLT_NULL through DLT_FDDI), we define LINKTYPE_xxx as
+ * DLT_xxx; that way, captures of those types can still be read by
+ * versions of libpcap that map LINKTYPE_* values to DLT_* values, and
+ * captures of those types written by versions of libpcap that map DLT_
+ * values to LINKTYPE_ values can still be read by older versions
+ * of libpcap.
+ *
+ * The other LINKTYPE_* codes are given values starting at 100, in the
+ * hopes that no DLT_* code will be given one of those values.
+ *
+ * In order to ensure that a given LINKTYPE_* code's value will refer to
+ * the same encapsulation type on all platforms, you should not allocate
+ * a new LINKTYPE_* value without consulting
+ * "tcpdump-workers@lists.tcpdump.org". The tcpdump developers will
+ * allocate a value for you, and will not subsequently allocate it to
+ * anybody else; that value will be added to the "pcap.h" in the
+ * tcpdump.org Git repository, so that a future libpcap release will
+ * include it.
+ *
+ * You should, if possible, also contribute patches to libpcap and tcpdump
+ * to handle the new encapsulation type, so that they can also be checked
+ * into the tcpdump.org Git repository and so that they will appear in
+ * future libpcap and tcpdump releases.
+ *
+ * Do *NOT* assume that any values after the largest value in this file
+ * are available; you might not have the most up-to-date version of this
+ * file, and new values after that one might have been assigned. Also,
+ * do *NOT* use any values below 100 - those might already have been
+ * taken by one (or more!) organizations.
+ *
+ * Any platform that defines additional DLT_* codes should:
+ *
+ * request a LINKTYPE_* code and value from tcpdump.org,
+ * as per the above;
+ *
+ * add, in their version of libpcap, an entry to map
+ * those DLT_* codes to the corresponding LINKTYPE_*
+ * code;
+ *
+ * redefine, in their "net/bpf.h", any DLT_* values
+ * that collide with the values used by their additional
+ * DLT_* codes, to remove those collisions (but without
+ * making them collide with any of the LINKTYPE_*
+ * values equal to 50 or above; they should also avoid
+ * defining DLT_* values that collide with those
+ * LINKTYPE_* values, either).
+ */
+#define LINKTYPE_NULL DLT_NULL
+#define LINKTYPE_ETHERNET DLT_EN10MB /* also for 100Mb and up */
+#define LINKTYPE_EXP_ETHERNET DLT_EN3MB /* 3Mb experimental Ethernet */
+#define LINKTYPE_AX25 DLT_AX25
+#define LINKTYPE_PRONET DLT_PRONET
+#define LINKTYPE_CHAOS DLT_CHAOS
+#define LINKTYPE_IEEE802_5 DLT_IEEE802 /* DLT_IEEE802 is used for 802.5 Token Ring */
+#define LINKTYPE_ARCNET_BSD DLT_ARCNET /* BSD-style headers */
+#define LINKTYPE_SLIP DLT_SLIP
+#define LINKTYPE_PPP DLT_PPP
+#define LINKTYPE_FDDI DLT_FDDI
+
+/*
+ * LINKTYPE_PPP is for use when there might, or might not, be an RFC 1662
+ * PPP in HDLC-like framing header (with 0xff 0x03 before the PPP protocol
+ * field) at the beginning of the packet.
+ *
+ * This is for use when there is always such a header; the address field
+ * might be 0xff, for regular PPP, or it might be an address field for Cisco
+ * point-to-point with HDLC framing as per section 4.3.1 of RFC 1547 ("Cisco
+ * HDLC"). This is, for example, what you get with NetBSD's DLT_PPP_SERIAL.
+ *
+ * We give it the same value as NetBSD's DLT_PPP_SERIAL, in the hopes that
+ * nobody else will choose a DLT_ value of 50, and so that DLT_PPP_SERIAL
+ * captures will be written out with a link type that NetBSD's tcpdump
+ * can read.
+ */
+#define LINKTYPE_PPP_HDLC 50 /* PPP in HDLC-like framing */
+
+#define LINKTYPE_PPP_ETHER 51 /* NetBSD PPP-over-Ethernet */
+
+#define LINKTYPE_SYMANTEC_FIREWALL 99 /* Symantec Enterprise Firewall */
+
+/*
+ * These correspond to DLT_s that have different values on different
+ * platforms; we map between these values in capture files and
+ * the DLT_ values as returned by pcap_datalink() and passed to
+ * pcap_open_dead().
+ */
+#define LINKTYPE_ATM_RFC1483 100 /* LLC/SNAP-encapsulated ATM */
+#define LINKTYPE_RAW 101 /* raw IP */
+#define LINKTYPE_SLIP_BSDOS 102 /* BSD/OS SLIP BPF header */
+#define LINKTYPE_PPP_BSDOS 103 /* BSD/OS PPP BPF header */
+
+/*
+ * Values starting with 104 are used for newly-assigned link-layer
+ * header type values; for those link-layer header types, the DLT_
+ * value returned by pcap_datalink() and passed to pcap_open_dead(),
+ * and the LINKTYPE_ value that appears in capture files, are the
+ * same.
+ *
+ * LINKTYPE_MATCHING_MIN is the lowest such value; LINKTYPE_MATCHING_MAX
+ * is the highest such value.
+ */
+#define LINKTYPE_MATCHING_MIN 104 /* lowest value in the "matching" range */
+
+#define LINKTYPE_C_HDLC 104 /* Cisco HDLC */
+#define LINKTYPE_IEEE802_11 105 /* IEEE 802.11 (wireless) */
+#define LINKTYPE_ATM_CLIP 106 /* Linux Classical IP over ATM */
+#define LINKTYPE_FRELAY 107 /* Frame Relay */
+#define LINKTYPE_LOOP 108 /* OpenBSD loopback */
+#define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */
+
+/*
+ * These three types are reserved for future use.
+ */
+#define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */
+#define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */
+#define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */
+
+#define LINKTYPE_LINUX_SLL 113 /* Linux cooked socket capture */
+#define LINKTYPE_LTALK 114 /* Apple LocalTalk hardware */
+#define LINKTYPE_ECONET 115 /* Acorn Econet */
+
+/*
+ * Reserved for use with OpenBSD ipfilter.
+ */
+#define LINKTYPE_IPFILTER 116
+
+#define LINKTYPE_PFLOG 117 /* OpenBSD DLT_PFLOG */
+#define LINKTYPE_CISCO_IOS 118 /* For Cisco-internal use */
+#define LINKTYPE_IEEE802_11_PRISM 119 /* 802.11 plus Prism II monitor mode radio metadata header */
+#define LINKTYPE_IEEE802_11_AIRONET 120 /* 802.11 plus FreeBSD Aironet driver radio metadata header */
+
+/*
+ * Reserved for Siemens HiPath HDLC.
+ */
+#define LINKTYPE_HHDLC 121
+
+#define LINKTYPE_IP_OVER_FC 122 /* RFC 2625 IP-over-Fibre Channel */
+#define LINKTYPE_SUNATM 123 /* Solaris+SunATM */
+
+/*
+ * Reserved as per request from Kent Dahlgren <kent@praesum.com>
+ * for private use.
+ */
+#define LINKTYPE_RIO 124 /* RapidIO */
+#define LINKTYPE_PCI_EXP 125 /* PCI Express */
+#define LINKTYPE_AURORA 126 /* Xilinx Aurora link layer */
+
+#define LINKTYPE_IEEE802_11_RADIOTAP 127 /* 802.11 plus radiotap radio metadata header */
+
+/*
+ * Reserved for the TZSP encapsulation, as per request from
+ * Chris Waters <chris.waters@networkchemistry.com>
+ * TZSP is a generic encapsulation for any other link type,
+ * which includes a means to include meta-information
+ * with the packet, e.g. signal strength and channel
+ * for 802.11 packets.
+ */
+#define LINKTYPE_TZSP 128 /* Tazmen Sniffer Protocol */
+
+#define LINKTYPE_ARCNET_LINUX 129 /* Linux-style headers */
+
+/*
+ * Juniper-private data link types, as per request from
+ * Hannes Gredler <hannes@juniper.net>. The corresponding
+ * DLT_s are used for passing on chassis-internal
+ * metainformation such as QOS profiles, etc..
+ */
+#define LINKTYPE_JUNIPER_MLPPP 130
+#define LINKTYPE_JUNIPER_MLFR 131
+#define LINKTYPE_JUNIPER_ES 132
+#define LINKTYPE_JUNIPER_GGSN 133
+#define LINKTYPE_JUNIPER_MFR 134
+#define LINKTYPE_JUNIPER_ATM2 135
+#define LINKTYPE_JUNIPER_SERVICES 136
+#define LINKTYPE_JUNIPER_ATM1 137
+
+#define LINKTYPE_APPLE_IP_OVER_IEEE1394 138 /* Apple IP-over-IEEE 1394 cooked header */
+
+#define LINKTYPE_MTP2_WITH_PHDR 139
+#define LINKTYPE_MTP2 140
+#define LINKTYPE_MTP3 141
+#define LINKTYPE_SCCP 142
+
+#define LINKTYPE_DOCSIS 143 /* DOCSIS MAC frames */
+
+#define LINKTYPE_LINUX_IRDA 144 /* Linux-IrDA */
+
+/*
+ * Reserved for IBM SP switch and IBM Next Federation switch.
+ */
+#define LINKTYPE_IBM_SP 145
+#define LINKTYPE_IBM_SN 146
+
+/*
+ * Reserved for private use. If you have some link-layer header type
+ * that you want to use within your organization, with the capture files
+ * using that link-layer header type not ever be sent outside your
+ * organization, you can use these values.
+ *
+ * No libpcap release will use these for any purpose, nor will any
+ * tcpdump release use them, either.
+ *
+ * Do *NOT* use these in capture files that you expect anybody not using
+ * your private versions of capture-file-reading tools to read; in
+ * particular, do *NOT* use them in products, otherwise you may find that
+ * people won't be able to use tcpdump, or snort, or Ethereal, or... to
+ * read capture files from your firewall/intrusion detection/traffic
+ * monitoring/etc. appliance, or whatever product uses that LINKTYPE_ value,
+ * and you may also find that the developers of those applications will
+ * not accept patches to let them read those files.
+ *
+ * Also, do not use them if somebody might send you a capture using them
+ * for *their* private type and tools using them for *your* private type
+ * would have to read them.
+ *
+ * Instead, in those cases, ask "tcpdump-workers@lists.tcpdump.org" for a
+ * new DLT_ and LINKTYPE_ value, as per the comment in pcap/bpf.h, and use
+ * the type you're given.
+ */
+#define LINKTYPE_USER0 147
+#define LINKTYPE_USER1 148
+#define LINKTYPE_USER2 149
+#define LINKTYPE_USER3 150
+#define LINKTYPE_USER4 151
+#define LINKTYPE_USER5 152
+#define LINKTYPE_USER6 153
+#define LINKTYPE_USER7 154
+#define LINKTYPE_USER8 155
+#define LINKTYPE_USER9 156
+#define LINKTYPE_USER10 157
+#define LINKTYPE_USER11 158
+#define LINKTYPE_USER12 159
+#define LINKTYPE_USER13 160
+#define LINKTYPE_USER14 161
+#define LINKTYPE_USER15 162
+
+/*
+ * For future use with 802.11 captures - defined by AbsoluteValue
+ * Systems to store a number of bits of link-layer information
+ * including radio information:
+ *
+ * http://www.shaftnet.org/~pizza/software/capturefrm.txt
+ */
+#define LINKTYPE_IEEE802_11_AVS 163 /* 802.11 plus AVS radio metadata header */
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>. The corresponding
+ * DLT_s are used for passing on chassis-internal
+ * metainformation such as QOS profiles, etc..
+ */
+#define LINKTYPE_JUNIPER_MONITOR 164
+
+/*
+ * BACnet MS/TP frames.
+ */
+#define LINKTYPE_BACNET_MS_TP 165
+
+/*
+ * Another PPP variant as per request from Karsten Keil <kkeil@suse.de>.
+ *
+ * This is used in some OSes to allow a kernel socket filter to distinguish
+ * between incoming and outgoing packets, on a socket intended to
+ * supply pppd with outgoing packets so it can do dial-on-demand and
+ * hangup-on-lack-of-demand; incoming packets are filtered out so they
+ * don't cause pppd to hold the connection up (you don't want random
+ * input packets such as port scans, packets from old lost connections,
+ * etc. to force the connection to stay up).
+ *
+ * The first byte of the PPP header (0xff03) is modified to accomodate
+ * the direction - 0x00 = IN, 0x01 = OUT.
+ */
+#define LINKTYPE_PPP_PPPD 166
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>. The DLT_s are used
+ * for passing on chassis-internal metainformation such as
+ * QOS profiles, cookies, etc..
+ */
+#define LINKTYPE_JUNIPER_PPPOE 167
+#define LINKTYPE_JUNIPER_PPPOE_ATM 168
+
+#define LINKTYPE_GPRS_LLC 169 /* GPRS LLC */
+#define LINKTYPE_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */
+#define LINKTYPE_GPF_F 171 /* GPF-T (ITU-T G.7041/Y.1303) */
+
+/*
+ * Requested by Oolan Zimmer <oz@gcom.com> for use in Gcom's T1/E1 line
+ * monitoring equipment.
+ */
+#define LINKTYPE_GCOM_T1E1 172
+#define LINKTYPE_GCOM_SERIAL 173
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>. The DLT_ is used
+ * for internal communication to Physical Interface Cards (PIC)
+ */
+#define LINKTYPE_JUNIPER_PIC_PEER 174
+
+/*
+ * Link types requested by Gregor Maier <gregor@endace.com> of Endace
+ * Measurement Systems. They add an ERF header (see
+ * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of
+ * the link-layer header.
+ */
+#define LINKTYPE_ERF_ETH 175 /* Ethernet */
+#define LINKTYPE_ERF_POS 176 /* Packet-over-SONET */
+
+/*
+ * Requested by Daniele Orlandi <daniele@orlandi.com> for raw LAPD
+ * for vISDN (http://www.orlandi.com/visdn/). Its link-layer header
+ * includes additional information before the LAPD header, so it's
+ * not necessarily a generic LAPD header.
+ */
+#define LINKTYPE_LINUX_LAPD 177
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>.
+ * The Link Types are used for prepending meta-information
+ * like interface index, interface name
+ * before standard Ethernet, PPP, Frelay & C-HDLC Frames
+ */
+#define LINKTYPE_JUNIPER_ETHER 178
+#define LINKTYPE_JUNIPER_PPP 179
+#define LINKTYPE_JUNIPER_FRELAY 180
+#define LINKTYPE_JUNIPER_CHDLC 181
+
+/*
+ * Multi Link Frame Relay (FRF.16)
+ */
+#define LINKTYPE_MFR 182
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>.
+ * The DLT_ is used for internal communication with a
+ * voice Adapter Card (PIC)
+ */
+#define LINKTYPE_JUNIPER_VP 183
+
+/*
+ * Arinc 429 frames.
+ * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
+ * Every frame contains a 32bit A429 label.
+ * More documentation on Arinc 429 can be found at
+ * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf
+ */
+#define LINKTYPE_A429 184
+
+/*
+ * Arinc 653 Interpartition Communication messages.
+ * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
+ * Please refer to the A653-1 standard for more information.
+ */
+#define LINKTYPE_A653_ICM 185
+
+/*
+ * USB packets, beginning with a USB setup header; requested by
+ * Paolo Abeni <paolo.abeni@email.it>.
+ */
+#define LINKTYPE_USB 186
+
+/*
+ * Bluetooth HCI UART transport layer (part H:4); requested by
+ * Paolo Abeni.
+ */
+#define LINKTYPE_BLUETOOTH_HCI_H4 187
+
+/*
+ * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz
+ * <cruz_petagay@bah.com>.
+ */
+#define LINKTYPE_IEEE802_16_MAC_CPS 188
+
+/*
+ * USB packets, beginning with a Linux USB header; requested by
+ * Paolo Abeni <paolo.abeni@email.it>.
+ */
+#define LINKTYPE_USB_LINUX 189
+
+/*
+ * Controller Area Network (CAN) v. 2.0B packets.
+ * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
+ * Used to dump CAN packets coming from a CAN Vector board.
+ * More documentation on the CAN v2.0B frames can be found at
+ * http://www.can-cia.org/downloads/?269
+ */
+#define LINKTYPE_CAN20B 190
+
+/*
+ * IEEE 802.15.4, with address fields padded, as is done by Linux
+ * drivers; requested by Juergen Schimmer.
+ */
+#define LINKTYPE_IEEE802_15_4_LINUX 191
+
+/*
+ * Per Packet Information encapsulated packets.
+ * LINKTYPE_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
+ */
+#define LINKTYPE_PPI 192
+
+/*
+ * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header;
+ * requested by Charles Clancy.
+ */
+#define LINKTYPE_IEEE802_16_MAC_CPS_RADIO 193
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>.
+ * The DLT_ is used for internal communication with a
+ * integrated service module (ISM).
+ */
+#define LINKTYPE_JUNIPER_ISM 194
+
+/*
+ * IEEE 802.15.4, exactly as it appears in the spec (no padding, no
+ * nothing); requested by Mikko Saarnivala <mikko.saarnivala@sensinode.com>.
+ */
+#define LINKTYPE_IEEE802_15_4 195
+
+/*
+ * Various link-layer types, with a pseudo-header, for SITA
+ * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com).
+ */
+#define LINKTYPE_SITA 196
+
+/*
+ * Various link-layer types, with a pseudo-header, for Endace DAG cards;
+ * encapsulates Endace ERF records. Requested by Stephen Donnelly
+ * <stephen@endace.com>.
+ */
+#define LINKTYPE_ERF 197
+
+/*
+ * Special header prepended to Ethernet packets when capturing from a
+ * u10 Networks board. Requested by Phil Mulholland
+ * <phil@u10networks.com>.
+ */
+#define LINKTYPE_RAIF1 198
+
+/*
+ * IPMB packet for IPMI, beginning with the I2C slave address, followed
+ * by the netFn and LUN, etc.. Requested by Chanthy Toeung
+ * <chanthy.toeung@ca.kontron.com>.
+ */
+#define LINKTYPE_IPMB 199
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>.
+ * The DLT_ is used for capturing data on a secure tunnel interface.
+ */
+#define LINKTYPE_JUNIPER_ST 200
+
+/*
+ * Bluetooth HCI UART transport layer (part H:4), with pseudo-header
+ * that includes direction information; requested by Paolo Abeni.
+ */
+#define LINKTYPE_BLUETOOTH_HCI_H4_WITH_PHDR 201
+
+/*
+ * AX.25 packet with a 1-byte KISS header; see
+ *
+ * http://www.ax25.net/kiss.htm
+ *
+ * as per Richard Stearn <richard@rns-stearn.demon.co.uk>.
+ */
+#define LINKTYPE_AX25_KISS 202
+
+/*
+ * LAPD packets from an ISDN channel, starting with the address field,
+ * with no pseudo-header.
+ * Requested by Varuna De Silva <varunax@gmail.com>.
+ */
+#define LINKTYPE_LAPD 203
+
+/*
+ * Variants of various link-layer headers, with a one-byte direction
+ * pseudo-header prepended - zero means "received by this host",
+ * non-zero (any non-zero value) means "sent by this host" - as per
+ * Will Barker <w.barker@zen.co.uk>.
+ */
+#define LINKTYPE_PPP_WITH_DIR 204 /* PPP */
+#define LINKTYPE_C_HDLC_WITH_DIR 205 /* Cisco HDLC */
+#define LINKTYPE_FRELAY_WITH_DIR 206 /* Frame Relay */
+#define LINKTYPE_LAPB_WITH_DIR 207 /* LAPB */
+
+/*
+ * 208 is reserved for an as-yet-unspecified proprietary link-layer
+ * type, as requested by Will Barker.
+ */
+
+/*
+ * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman
+ * <avn@pigeonpoint.com>.
+ */
+#define LINKTYPE_IPMB_LINUX 209
+
+/*
+ * FlexRay automotive bus - http://www.flexray.com/ - as requested
+ * by Hannes Kaelber <hannes.kaelber@x2e.de>.
+ */
+#define LINKTYPE_FLEXRAY 210
+
+/*
+ * Media Oriented Systems Transport (MOST) bus for multimedia
+ * transport - http://www.mostcooperation.com/ - as requested
+ * by Hannes Kaelber <hannes.kaelber@x2e.de>.
+ */
+#define LINKTYPE_MOST 211
+
+/*
+ * Local Interconnect Network (LIN) bus for vehicle networks -
+ * http://www.lin-subbus.org/ - as requested by Hannes Kaelber
+ * <hannes.kaelber@x2e.de>.
+ */
+#define LINKTYPE_LIN 212
+
+/*
+ * X2E-private data link type used for serial line capture,
+ * as requested by Hannes Kaelber <hannes.kaelber@x2e.de>.
+ */
+#define LINKTYPE_X2E_SERIAL 213
+
+/*
+ * X2E-private data link type used for the Xoraya data logger
+ * family, as requested by Hannes Kaelber <hannes.kaelber@x2e.de>.
+ */
+#define LINKTYPE_X2E_XORAYA 214
+
+/*
+ * IEEE 802.15.4, exactly as it appears in the spec (no padding, no
+ * nothing), but with the PHY-level data for non-ASK PHYs (4 octets
+ * of 0 as preamble, one octet of SFD, one octet of frame length+
+ * reserved bit, and then the MAC-layer data, starting with the
+ * frame control field).
+ *
+ * Requested by Max Filippov <jcmvbkbc@gmail.com>.
+ */
+#define LINKTYPE_IEEE802_15_4_NONASK_PHY 215
+
+/*
+ * David Gibson <david@gibson.dropbear.id.au> requested this for
+ * captures from the Linux kernel /dev/input/eventN devices. This
+ * is used to communicate keystrokes and mouse movements from the
+ * Linux kernel to display systems, such as Xorg.
+ */
+#define LINKTYPE_LINUX_EVDEV 216
+
+/*
+ * GSM Um and Abis interfaces, preceded by a "gsmtap" header.
+ *
+ * Requested by Harald Welte <laforge@gnumonks.org>.
+ */
+#define LINKTYPE_GSMTAP_UM 217
+#define LINKTYPE_GSMTAP_ABIS 218
+
+/*
+ * MPLS, with an MPLS label as the link-layer header.
+ * Requested by Michele Marchetto <michele@openbsd.org> on behalf
+ * of OpenBSD.
+ */
+#define LINKTYPE_MPLS 219
+
+/*
+ * USB packets, beginning with a Linux USB header, with the USB header
+ * padded to 64 bytes; required for memory-mapped access.
+ */
+#define LINKTYPE_USB_LINUX_MMAPPED 220
+
+/*
+ * DECT packets, with a pseudo-header; requested by
+ * Matthias Wenzel <tcpdump@mazzoo.de>.
+ */
+#define LINKTYPE_DECT 221
+
+/*
+ * From: "Lidwa, Eric (GSFC-582.0)[SGT INC]" <eric.lidwa-1@nasa.gov>
+ * Date: Mon, 11 May 2009 11:18:30 -0500
+ *
+ * DLT_AOS. We need it for AOS Space Data Link Protocol.
+ * I have already written dissectors for but need an OK from
+ * legal before I can submit a patch.
+ *
+ */
+#define LINKTYPE_AOS 222
+
+/*
+ * Wireless HART (Highway Addressable Remote Transducer)
+ * From the HART Communication Foundation
+ * IES/PAS 62591
+ *
+ * Requested by Sam Roberts <vieuxtech@gmail.com>.
+ */
+#define LINKTYPE_WIHART 223
+
+/*
+ * Fibre Channel FC-2 frames, beginning with a Frame_Header.
+ * Requested by Kahou Lei <kahou82@gmail.com>.
+ */
+#define LINKTYPE_FC_2 224
+
+/*
+ * Fibre Channel FC-2 frames, beginning with an encoding of the
+ * SOF, and ending with an encoding of the EOF.
+ *
+ * The encodings represent the frame delimiters as 4-byte sequences
+ * representing the corresponding ordered sets, with K28.5
+ * represented as 0xBC, and the D symbols as the corresponding
+ * byte values; for example, SOFi2, which is K28.5 - D21.5 - D1.2 - D21.2,
+ * is represented as 0xBC 0xB5 0x55 0x55.
+ *
+ * Requested by Kahou Lei <kahou82@gmail.com>.
+ */
+#define LINKTYPE_FC_2_WITH_FRAME_DELIMS 225
+
+/*
+ * Solaris ipnet pseudo-header; requested by Darren Reed <Darren.Reed@Sun.COM>.
+ *
+ * The pseudo-header starts with a one-byte version number; for version 2,
+ * the pseudo-header is:
+ *
+ * struct dl_ipnetinfo {
+ * u_int8_t dli_version;
+ * u_int8_t dli_family;
+ * u_int16_t dli_htype;
+ * u_int32_t dli_pktlen;
+ * u_int32_t dli_ifindex;
+ * u_int32_t dli_grifindex;
+ * u_int32_t dli_zsrc;
+ * u_int32_t dli_zdst;
+ * };
+ *
+ * dli_version is 2 for the current version of the pseudo-header.
+ *
+ * dli_family is a Solaris address family value, so it's 2 for IPv4
+ * and 26 for IPv6.
+ *
+ * dli_htype is a "hook type" - 0 for incoming packets, 1 for outgoing
+ * packets, and 2 for packets arriving from another zone on the same
+ * machine.
+ *
+ * dli_pktlen is the length of the packet data following the pseudo-header
+ * (so the captured length minus dli_pktlen is the length of the
+ * pseudo-header, assuming the entire pseudo-header was captured).
+ *
+ * dli_ifindex is the interface index of the interface on which the
+ * packet arrived.
+ *
+ * dli_grifindex is the group interface index number (for IPMP interfaces).
+ *
+ * dli_zsrc is the zone identifier for the source of the packet.
+ *
+ * dli_zdst is the zone identifier for the destination of the packet.
+ *
+ * A zone number of 0 is the global zone; a zone number of 0xffffffff
+ * means that the packet arrived from another host on the network, not
+ * from another zone on the same machine.
+ *
+ * An IPv4 or IPv6 datagram follows the pseudo-header; dli_family indicates
+ * which of those it is.
+ */
+#define LINKTYPE_IPNET 226
+
+/*
+ * CAN (Controller Area Network) frames, with a pseudo-header as supplied
+ * by Linux SocketCAN. See Documentation/networking/can.txt in the Linux
+ * source.
+ *
+ * Requested by Felix Obenhuber <felix@obenhuber.de>.
+ */
+#define LINKTYPE_CAN_SOCKETCAN 227
+
+/*
+ * Raw IPv4/IPv6; different from DLT_RAW in that the DLT_ value specifies
+ * whether it's v4 or v6. Requested by Darren Reed <Darren.Reed@Sun.COM>.
+ */
+#define LINKTYPE_IPV4 228
+#define LINKTYPE_IPV6 229
+
+/*
+ * IEEE 802.15.4, exactly as it appears in the spec (no padding, no
+ * nothing), and with no FCS at the end of the frame; requested by
+ * Jon Smirl <jonsmirl@gmail.com>.
+ */
+#define LINKTYPE_IEEE802_15_4_NOFCS 230
+
+/*
+ * Raw D-Bus:
+ *
+ * http://www.freedesktop.org/wiki/Software/dbus
+ *
+ * messages:
+ *
+ * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages
+ *
+ * starting with the endianness flag, followed by the message type, etc.,
+ * but without the authentication handshake before the message sequence:
+ *
+ * http://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol
+ *
+ * Requested by Martin Vidner <martin@vidner.net>.
+ */
+#define LINKTYPE_DBUS 231
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>.
+ */
+#define LINKTYPE_JUNIPER_VS 232
+#define LINKTYPE_JUNIPER_SRX_E2E 233
+#define LINKTYPE_JUNIPER_FIBRECHANNEL 234
+
+/*
+ * DVB-CI (DVB Common Interface for communication between a PC Card
+ * module and a DVB receiver). See
+ *
+ * http://www.kaiser.cx/pcap-dvbci.html
+ *
+ * for the specification.
+ *
+ * Requested by Martin Kaiser <martin@kaiser.cx>.
+ */
+#define LINKTYPE_DVB_CI 235
+
+/*
+ * Variant of 3GPP TS 27.010 multiplexing protocol. Requested
+ * by Hans-Christoph Schemmel <hans-christoph.schemmel@cinterion.com>.
+ */
+#define LINKTYPE_MUX27010 236
+
+/*
+ * STANAG 5066 D_PDUs. Requested by M. Baris Demiray
+ * <barisdemiray@gmail.com>.
+ */
+#define LINKTYPE_STANAG_5066_D_PDU 237
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>.
+ */
+#define LINKTYPE_JUNIPER_ATM_CEMIC 238
+
+/*
+ * NetFilter LOG messages
+ * (payload of netlink NFNL_SUBSYS_ULOG/NFULNL_MSG_PACKET packets)
+ *
+ * Requested by Jakub Zawadzki <darkjames-ws@darkjames.pl>
+ */
+#define LINKTYPE_NFLOG 239
+
+/*
+ * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type
+ * for Ethernet packets with a 4-byte pseudo-header and always
+ * with the payload including the FCS, as supplied by their
+ * netANALYZER hardware and software.
+ *
+ * Requested by Holger P. Frommer <HPfrommer@hilscher.com>
+ */
+#define LINKTYPE_NETANALYZER 240
+
+/*
+ * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type
+ * for Ethernet packets with a 4-byte pseudo-header and FCS and
+ * 1 byte of SFD, as supplied by their netANALYZER hardware and
+ * software.
+ *
+ * Requested by Holger P. Frommer <HPfrommer@hilscher.com>
+ */
+#define LINKTYPE_NETANALYZER_TRANSPARENT 241
+
+/*
+ * IP-over-InfiniBand, as specified by RFC 4391.
+ *
+ * Requested by Petr Sumbera <petr.sumbera@oracle.com>.
+ */
+#define LINKTYPE_IPOIB 242
+
+/*
+ * MPEG-2 transport stream (ISO 13818-1/ITU-T H.222.0).
+ *
+ * Requested by Guy Martin <gmsoft@tuxicoman.be>.
+ */
+#define LINKTYPE_MPEG_2_TS 243
+
+/*
+ * ng4T GmbH's UMTS Iub/Iur-over-ATM and Iub/Iur-over-IP format as
+ * used by their ng40 protocol tester.
+ *
+ * Requested by Jens Grimmer <jens.grimmer@ng4t.com>.
+ */
+#define LINKTYPE_NG40 244
+
+/*
+ * Pseudo-header giving adapter number and flags, followed by an NFC
+ * (Near-Field Communications) Logical Link Control Protocol (LLCP) PDU,
+ * as specified by NFC Forum Logical Link Control Protocol Technical
+ * Specification LLCP 1.1.
+ *
+ * Requested by Mike Wakerly <mikey@google.com>.
+ */
+#define LINKTYPE_NFC_LLCP 245
+
+/*
+ * pfsync output; DLT_PFSYNC is 18, which collides with DLT_CIP in
+ * SuSE 6.3, on OpenBSD, NetBSD, DragonFly BSD, and Mac OS X, and
+ * is 121, which collides with DLT_HHDLC, in FreeBSD. We pick a
+ * shiny new link-layer header type value that doesn't collide with
+ * anything, in the hopes that future pfsync savefiles, if any,
+ * won't require special hacks to distinguish from other savefiles.
+ *
+ */
+#define LINKTYPE_PFSYNC 246
+
+/*
+ * Raw InfiniBand packets, starting with the Local Routing Header.
+ *
+ * Requested by Oren Kladnitsky <orenk@mellanox.com>.
+ */
+#define LINKTYPE_INFINIBAND 247
+
+/*
+ * SCTP, with no lower-level protocols (i.e., no IPv4 or IPv6).
+ *
+ * Requested by Michael Tuexen <Michael.Tuexen@lurchi.franken.de>.
+ */
+#define LINKTYPE_SCTP 248
+
+#define LINKTYPE_MATCHING_MAX 248 /* highest value in the "matching" range */
+
+static struct linktype_map {
+ int dlt;
+ int linktype;
+} map[] = {
+ /*
+ * These DLT_* codes have LINKTYPE_* codes with values identical
+ * to the values of the corresponding DLT_* code.
+ */
+ { DLT_NULL, LINKTYPE_NULL },
+ { DLT_EN10MB, LINKTYPE_ETHERNET },
+ { DLT_EN3MB, LINKTYPE_EXP_ETHERNET },
+ { DLT_AX25, LINKTYPE_AX25 },
+ { DLT_PRONET, LINKTYPE_PRONET },
+ { DLT_CHAOS, LINKTYPE_CHAOS },
+ { DLT_IEEE802, LINKTYPE_IEEE802_5 },
+ { DLT_ARCNET, LINKTYPE_ARCNET_BSD },
+ { DLT_SLIP, LINKTYPE_SLIP },
+ { DLT_PPP, LINKTYPE_PPP },
+ { DLT_FDDI, LINKTYPE_FDDI },
+ { DLT_SYMANTEC_FIREWALL, LINKTYPE_SYMANTEC_FIREWALL },
+
+ /*
+ * These DLT_* codes have different values on different
+ * platforms; we map them to LINKTYPE_* codes that
+ * have values that should never be equal to any DLT_*
+ * code.
+ */
+#ifdef DLT_FR
+ /* BSD/OS Frame Relay */
+ { DLT_FR, LINKTYPE_FRELAY },
+#endif
+
+ { DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 },
+ { DLT_RAW, LINKTYPE_RAW },
+ { DLT_SLIP_BSDOS, LINKTYPE_SLIP_BSDOS },
+ { DLT_PPP_BSDOS, LINKTYPE_PPP_BSDOS },
+
+ /* BSD/OS Cisco HDLC */
+ { DLT_C_HDLC, LINKTYPE_C_HDLC },
+
+ /*
+ * These DLT_* codes are not on all platforms, but, so far,
+ * there don't appear to be any platforms that define
+ * other codes with those values; we map them to
+ * different LINKTYPE_* values anyway, just in case.
+ */
+
+ /* Linux ATM Classical IP */
+ { DLT_ATM_CLIP, LINKTYPE_ATM_CLIP },
+
+ /* NetBSD sync/async serial PPP (or Cisco HDLC) */
+ { DLT_PPP_SERIAL, LINKTYPE_PPP_HDLC },
+
+ /* NetBSD PPP over Ethernet */
+ { DLT_PPP_ETHER, LINKTYPE_PPP_ETHER },
+
+ /*
+ * All LINKTYPE_ values between LINKTYPE_MATCHING_MIN
+ * and LINKTYPE_MATCHING_MAX are mapped to identical
+ * DLT_ values.
+ */
+
+ { -1, -1 }
+};
+
+int
+dlt_to_linktype(int dlt)
+{
+ int i;
+
+ /*
+ * Map DLT_PFSYNC, whatever it might be, to LINKTYPE_PFSYNC.
+ */
+ if (dlt == DLT_PFSYNC)
+ return (LINKTYPE_PFSYNC);
+
+ /*
+ * Map the values in the matching range.
+ */
+ if (dlt >= DLT_MATCHING_MIN && dlt <= DLT_MATCHING_MAX)
+ return (dlt);
+
+ /*
+ * Map the values outside that range.
+ */
+ for (i = 0; map[i].dlt != -1; i++) {
+ if (map[i].dlt == dlt)
+ return (map[i].linktype);
+ }
+
+ /*
+ * If we don't have a mapping for this DLT_ code, return an
+ * error; that means that this is a value with no corresponding
+ * LINKTYPE_ code, and we need to assign one.
+ */
+ return (-1);
+}
+
+int
+linktype_to_dlt(int linktype)
+{
+ int i;
+
+ /*
+ * Map LINKTYPE_PFSYNC to DLT_PFSYNC, whatever it might be.
+ * LINKTYPE_PFSYNC is in the matching range, to make sure
+ * it's as safe from reuse as we can arrange, so we do
+ * this test first.
+ */
+ if (linktype == LINKTYPE_PFSYNC)
+ return (DLT_PFSYNC);
+
+ /*
+ * Map the values in the matching range.
+ */
+ if (linktype >= LINKTYPE_MATCHING_MIN &&
+ linktype <= LINKTYPE_MATCHING_MAX)
+ return (linktype);
+
+ /*
+ * Map the values outside that range.
+ */
+ for (i = 0; map[i].linktype != -1; i++) {
+ if (map[i].linktype == linktype)
+ return (map[i].dlt);
+ }
+
+ /*
+ * If we don't have an entry for this link type, return
+ * the link type value; it may be a DLT_ value from an
+ * older version of libpcap.
+ */
+ return linktype;
+}
+
+/*
+ * The DLT_USB_LINUX and DLT_USB_LINUX_MMAPPED headers are in host
+ * byte order when capturing (it's supplied directly from a
+ * memory-mapped buffer shared by the kernel).
+ *
+ * When reading a DLT_USB_LINUX or DLT_USB_LINUX_MMAPPED capture file,
+ * we need to convert it from the capturing host's byte order to
+ * the reading host's byte order.
+ */
+void
+swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
+ int header_len_64_bytes)
+{
+ pcap_usb_header_mmapped *uhdr = (pcap_usb_header_mmapped *)buf;
+ bpf_u_int32 offset = 0;
+ usb_isodesc *pisodesc;
+ int32_t numdesc, i;
+
+ /*
+ * "offset" is the offset *past* the field we're swapping;
+ * we skip the field *before* checking to make sure
+ * the captured data length includes the entire field.
+ */
+
+ /*
+ * The URB id is a totally opaque value; do we really need to
+ * convert it to the reading host's byte order???
+ */
+ offset += 8; /* skip past id */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->id = SWAPLL(uhdr->id);
+
+ offset += 4; /* skip past various 1-byte fields */
+
+ offset += 2; /* skip past bus_id */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->bus_id = SWAPSHORT(uhdr->bus_id);
+
+ offset += 2; /* skip past various 1-byte fields */
+
+ offset += 8; /* skip past ts_sec */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->ts_sec = SWAPLL(uhdr->ts_sec);
+
+ offset += 4; /* skip past ts_usec */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->ts_usec = SWAPLONG(uhdr->ts_usec);
+
+ offset += 4; /* skip past status */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->status = SWAPLONG(uhdr->status);
+
+ offset += 4; /* skip past urb_len */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->urb_len = SWAPLONG(uhdr->urb_len);
+
+ offset += 4; /* skip past data_len */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->data_len = SWAPLONG(uhdr->data_len);
+
+ if (uhdr->transfer_type == URB_ISOCHRONOUS) {
+ offset += 4; /* skip past s.iso.error_count */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->s.iso.error_count = SWAPLONG(uhdr->s.iso.error_count);
+
+ offset += 4; /* skip past s.iso.numdesc */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->s.iso.numdesc = SWAPLONG(uhdr->s.iso.numdesc);
+ } else
+ offset += 8; /* skip USB setup header */
+
+ if (header_len_64_bytes) {
+ /*
+ * This is either the "version 1" header, with
+ * 16 bytes of additional fields at the end, or
+ * a "version 0" header from a memory-mapped
+ * capture, with 16 bytes of zeroed-out padding
+ * at the end. Byte swap them as if this were
+ * a "version 1" header.
+ */
+ offset += 4; /* skip past interval */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->interval = SWAPLONG(uhdr->interval);
+
+ offset += 4; /* skip past start_frame */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->start_frame = SWAPLONG(uhdr->start_frame);
+
+ offset += 4; /* skip past xfer_flags */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->xfer_flags = SWAPLONG(uhdr->xfer_flags);
+
+ offset += 4; /* skip past ndesc */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->ndesc = SWAPLONG(uhdr->ndesc);
+ }
+
+ if (uhdr->transfer_type == URB_ISOCHRONOUS) {
+ /* swap the values in struct linux_usb_isodesc */
+ pisodesc = (usb_isodesc *)(void *)(buf+offset);
+ numdesc = uhdr->s.iso.numdesc;
+ for (i = 0; i < numdesc; i++) {
+ offset += 4; /* skip past status */
+ if (hdr->caplen < offset)
+ return;
+ pisodesc->status = SWAPLONG(pisodesc->status);
+
+ offset += 4; /* skip past offset */
+ if (hdr->caplen < offset)
+ return;
+ pisodesc->offset = SWAPLONG(pisodesc->offset);
+
+ offset += 4; /* skip past len */
+ if (hdr->caplen < offset)
+ return;
+ pisodesc->len = SWAPLONG(pisodesc->len);
+
+ offset += 4; /* skip past padding */
+
+ pisodesc++;
+ }
+ }
+}
diff --git a/freebsd/contrib/libpcap/pcap-common.h b/freebsd/contrib/libpcap/pcap-common.h
new file mode 100644
index 00000000..0c80ba32
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap-common.h
@@ -0,0 +1,25 @@
+
+/*
+ * We use the "receiver-makes-right" approach to byte order,
+ * because time is at a premium when we are writing the file.
+ * In other words, the pcap_file_header and pcap_pkthdr,
+ * records are written in host byte order.
+ * Note that the bytes of packet data are written out in the order in
+ * which they were received, so multi-byte fields in packets are not
+ * written in host byte order, they're written in whatever order the
+ * sending machine put them in.
+ *
+ * ntoh[ls] aren't sufficient because we might need to swap on a big-endian
+ * machine (if the file was written in little-end order).
+ */
+#define SWAPLONG(y) \
+((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
+#define SWAPSHORT(y) \
+ ( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) )
+
+extern int dlt_to_linktype(int dlt);
+
+extern int linktype_to_dlt(int linktype);
+
+extern void swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
+ int header_len_64_bytes);
diff --git a/freebsd/contrib/libpcap/pcap-int.h b/freebsd/contrib/libpcap/pcap-int.h
new file mode 100644
index 00000000..059b597c
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap-int.h
@@ -0,0 +1,513 @@
+/*
+ * Copyright (c) 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.94 2008-09-16 00:20:23 guy Exp $ (LBL)
+ */
+
+#ifndef pcap_int_h
+#define pcap_int_h
+
+#include <pcap/pcap.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_LIBDLPI
+#include <libdlpi.h>
+#endif
+
+#ifdef WIN32
+#include <Packet32.h>
+extern CRITICAL_SECTION g_PcapCompileCriticalSection;
+#endif /* WIN32 */
+
+#ifdef MSDOS
+#include <fcntl.h>
+#include <io.h>
+#endif
+
+#ifdef HAVE_SNF_API
+#include <snf.h>
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER <= 1200)) /* we are compiling with Visual Studio 6, that doesn't support the LL suffix*/
+
+/*
+ * Swap byte ordering of unsigned long long timestamp on a big endian
+ * machine.
+ */
+#define SWAPLL(ull) ((ull & 0xff00000000000000) >> 56) | \
+ ((ull & 0x00ff000000000000) >> 40) | \
+ ((ull & 0x0000ff0000000000) >> 24) | \
+ ((ull & 0x000000ff00000000) >> 8) | \
+ ((ull & 0x00000000ff000000) << 8) | \
+ ((ull & 0x0000000000ff0000) << 24) | \
+ ((ull & 0x000000000000ff00) << 40) | \
+ ((ull & 0x00000000000000ff) << 56)
+
+#else /* A recent Visual studio compiler or not VC */
+
+/*
+ * Swap byte ordering of unsigned long long timestamp on a big endian
+ * machine.
+ */
+#define SWAPLL(ull) ((ull & 0xff00000000000000LL) >> 56) | \
+ ((ull & 0x00ff000000000000LL) >> 40) | \
+ ((ull & 0x0000ff0000000000LL) >> 24) | \
+ ((ull & 0x000000ff00000000LL) >> 8) | \
+ ((ull & 0x00000000ff000000LL) << 8) | \
+ ((ull & 0x0000000000ff0000LL) << 24) | \
+ ((ull & 0x000000000000ff00LL) << 40) | \
+ ((ull & 0x00000000000000ffLL) << 56)
+
+#endif /* _MSC_VER */
+
+/*
+ * Savefile
+ */
+typedef enum {
+ NOT_SWAPPED,
+ SWAPPED,
+ MAYBE_SWAPPED
+} swapped_type_t;
+
+/*
+ * Used when reading a savefile.
+ */
+struct pcap_sf {
+ FILE *rfile;
+ int (*next_packet_op)(pcap_t *, struct pcap_pkthdr *, u_char **);
+ int swapped;
+ size_t hdrsize;
+ swapped_type_t lengths_swapped;
+ int version_major;
+ int version_minor;
+ bpf_u_int32 ifcount; /* number of interfaces seen in this capture */
+ u_int tsresol; /* time stamp resolution */
+ u_int tsscale; /* scaling factor for resolution -> microseconds */
+ u_int64_t tsoffset; /* time stamp offset */
+};
+
+/*
+ * Used when doing a live capture.
+ */
+struct pcap_md {
+ struct pcap_stat stat;
+ /*XXX*/
+ int use_bpf; /* using kernel filter */
+ u_long TotPkts; /* can't oflow for 79 hrs on ether */
+ u_long TotAccepted; /* count accepted by filter */
+ u_long TotDrops; /* count of dropped packets */
+ long TotMissed; /* missed by i/f during this run */
+ long OrigMissed; /* missed by i/f before this run */
+ char *device; /* device name */
+ int timeout; /* timeout for buffering */
+ int must_do_on_close; /* stuff we must do when we close */
+ struct pcap *next; /* list of open pcaps that need stuff cleared on close */
+#ifdef linux
+ int sock_packet; /* using Linux 2.0 compatible interface */
+ int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */
+ int ifindex; /* interface index of device we're bound to */
+ int lo_ifindex; /* interface index of the loopback device */
+ u_int packets_read; /* count of packets read with recvfrom() */
+ bpf_u_int32 oldmode; /* mode to restore when turning monitor mode off */
+ char *mondevice; /* mac80211 monitor device we created */
+ u_char *mmapbuf; /* memory-mapped region pointer */
+ size_t mmapbuflen; /* size of region */
+ int vlan_offset; /* offset at which to insert vlan tags; if -1, don't insert */
+ u_int tp_version; /* version of tpacket_hdr for mmaped ring */
+ u_int tp_hdrlen; /* hdrlen of tpacket_hdr for mmaped ring */
+ u_char *oneshot_buffer; /* buffer for copy of packet */
+ long proc_dropped; /* packets reported dropped by /proc/net/dev */
+#endif /* linux */
+
+#ifdef HAVE_DAG_API
+#ifdef HAVE_DAG_STREAMS_API
+ u_char *dag_mem_bottom; /* DAG card current memory bottom pointer */
+ u_char *dag_mem_top; /* DAG card current memory top pointer */
+#else /* HAVE_DAG_STREAMS_API */
+ void *dag_mem_base; /* DAG card memory base address */
+ u_int dag_mem_bottom; /* DAG card current memory bottom offset */
+ u_int dag_mem_top; /* DAG card current memory top offset */
+#endif /* HAVE_DAG_STREAMS_API */
+ int dag_fcs_bits; /* Number of checksum bits from link layer */
+ int dag_offset_flags; /* Flags to pass to dag_offset(). */
+ int dag_stream; /* DAG stream number */
+ int dag_timeout; /* timeout specified to pcap_open_live.
+ * Same as in linux above, introduce
+ * generally? */
+#endif /* HAVE_DAG_API */
+#ifdef HAVE_SNF_API
+ snf_handle_t snf_handle; /* opaque device handle */
+ snf_ring_t snf_ring; /* opaque device ring handle */
+ int snf_timeout;
+ int snf_boardnum;
+#endif /*HAVE_SNF_API*/
+
+#ifdef HAVE_ZEROCOPY_BPF
+ /*
+ * Zero-copy read buffer -- for zero-copy BPF. 'buffer' above will
+ * alternative between these two actual mmap'd buffers as required.
+ * As there is a header on the front size of the mmap'd buffer, only
+ * some of the buffer is exposed to libpcap as a whole via bufsize;
+ * zbufsize is the true size. zbuffer tracks the current zbuf
+ * assocated with buffer so that it can be used to decide which the
+ * next buffer to read will be.
+ */
+ u_char *zbuf1, *zbuf2, *zbuffer;
+ u_int zbufsize;
+ u_int zerocopy;
+ u_int interrupted;
+ struct timespec firstsel;
+ /*
+ * If there's currently a buffer being actively processed, then it is
+ * referenced here; 'buffer' is also pointed at it, but offset by the
+ * size of the header.
+ */
+ struct bpf_zbuf_header *bzh;
+#endif /* HAVE_ZEROCOPY_BPF */
+};
+
+/*
+ * Stuff to do when we close.
+ */
+#define MUST_CLEAR_PROMISC 0x00000001 /* clear promiscuous mode */
+#define MUST_CLEAR_RFMON 0x00000002 /* clear rfmon (monitor) mode */
+#define MUST_DELETE_MONIF 0x00000004 /* delete monitor-mode interface */
+
+struct pcap_opt {
+ int buffer_size;
+ char *source;
+ int promisc;
+ int rfmon;
+ int tstamp_type;
+};
+
+/*
+ * Ultrix, DEC OSF/1^H^H^H^H^H^H^H^H^HDigital UNIX^H^H^H^H^H^H^H^H^H^H^H^H
+ * Tru64 UNIX, and some versions of NetBSD pad FDDI packets to make everything
+ * line up on a nice boundary.
+ */
+#ifdef __NetBSD__
+#include <rtems/bsd/sys/param.h> /* needed to declare __NetBSD_Version__ */
+#endif
+
+#if defined(ultrix) || defined(__osf__) || (defined(__NetBSD__) && __NetBSD_Version__ > 106000000)
+#define PCAP_FDDIPAD 3
+#endif
+
+typedef int (*activate_op_t)(pcap_t *);
+typedef int (*can_set_rfmon_op_t)(pcap_t *);
+typedef int (*read_op_t)(pcap_t *, int cnt, pcap_handler, u_char *);
+typedef int (*inject_op_t)(pcap_t *, const void *, size_t);
+typedef int (*setfilter_op_t)(pcap_t *, struct bpf_program *);
+typedef int (*setdirection_op_t)(pcap_t *, pcap_direction_t);
+typedef int (*set_datalink_op_t)(pcap_t *, int);
+typedef int (*getnonblock_op_t)(pcap_t *, char *);
+typedef int (*setnonblock_op_t)(pcap_t *, int, char *);
+typedef int (*stats_op_t)(pcap_t *, struct pcap_stat *);
+#ifdef WIN32
+typedef int (*setbuff_op_t)(pcap_t *, int);
+typedef int (*setmode_op_t)(pcap_t *, int);
+typedef int (*setmintocopy_op_t)(pcap_t *, int);
+#endif
+typedef void (*cleanup_op_t)(pcap_t *);
+
+struct pcap {
+#ifdef WIN32
+ ADAPTER *adapter;
+ LPPACKET Packet;
+ int nonblock;
+#else
+ int fd;
+ int selectable_fd;
+ int send_fd;
+#endif /* WIN32 */
+
+#ifdef HAVE_LIBDLPI
+ dlpi_handle_t dlpi_hd;
+#endif
+ int snapshot;
+ int linktype; /* Network linktype */
+ int linktype_ext; /* Extended information stored in the linktype field of a file */
+ int tzoff; /* timezone offset */
+ int offset; /* offset for proper alignment */
+ int activated; /* true if the capture is really started */
+ int oldstyle; /* if we're opening with pcap_open_live() */
+
+ int break_loop; /* flag set to force break from packet-reading loop */
+
+#ifdef PCAP_FDDIPAD
+ int fddipad;
+#endif
+
+#ifdef MSDOS
+ void (*wait_proc)(void); /* call proc while waiting */
+#endif
+
+ struct pcap_sf sf;
+ struct pcap_md md;
+ struct pcap_opt opt;
+
+ /*
+ * Read buffer.
+ */
+ int bufsize;
+ u_char *buffer;
+ u_char *bp;
+ int cc;
+
+ /*
+ * Place holder for pcap_next().
+ */
+ u_char *pkt;
+
+ /* We're accepting only packets in this direction/these directions. */
+ pcap_direction_t direction;
+
+ /*
+ * Methods.
+ */
+ activate_op_t activate_op;
+ can_set_rfmon_op_t can_set_rfmon_op;
+ read_op_t read_op;
+ inject_op_t inject_op;
+ setfilter_op_t setfilter_op;
+ setdirection_op_t setdirection_op;
+ set_datalink_op_t set_datalink_op;
+ getnonblock_op_t getnonblock_op;
+ setnonblock_op_t setnonblock_op;
+ stats_op_t stats_op;
+
+ /*
+ * Routine to use as callback for pcap_next()/pcap_next_ex().
+ */
+ pcap_handler oneshot_callback;
+
+#ifdef WIN32
+ /*
+ * These are, at least currently, specific to the Win32 NPF
+ * driver.
+ */
+ setbuff_op_t setbuff_op;
+ setmode_op_t setmode_op;
+ setmintocopy_op_t setmintocopy_op;
+#endif
+ cleanup_op_t cleanup_op;
+
+ /*
+ * Placeholder for filter code if bpf not in kernel.
+ */
+ struct bpf_program fcode;
+
+ char errbuf[PCAP_ERRBUF_SIZE + 1];
+ int dlt_count;
+ u_int *dlt_list;
+ int tstamp_type_count;
+ u_int *tstamp_type_list;
+
+ struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */
+};
+
+/*
+ * This is a timeval as stored in a savefile.
+ * It has to use the same types everywhere, independent of the actual
+ * `struct timeval'; `struct timeval' has 32-bit tv_sec values on some
+ * platforms and 64-bit tv_sec values on other platforms, and writing
+ * out native `struct timeval' values would mean files could only be
+ * read on systems with the same tv_sec size as the system on which
+ * the file was written.
+ */
+
+struct pcap_timeval {
+ bpf_int32 tv_sec; /* seconds */
+ bpf_int32 tv_usec; /* microseconds */
+};
+
+/*
+ * This is a `pcap_pkthdr' as actually stored in a savefile.
+ *
+ * Do not change the format of this structure, in any way (this includes
+ * changes that only affect the length of fields in this structure),
+ * and do not make the time stamp anything other than seconds and
+ * microseconds (e.g., seconds and nanoseconds). Instead:
+ *
+ * introduce a new structure for the new format;
+ *
+ * send mail to "tcpdump-workers@lists.tcpdump.org", requesting
+ * a new magic number for your new capture file format, and, when
+ * you get the new magic number, put it in "savefile.c";
+ *
+ * use that magic number for save files with the changed record
+ * header;
+ *
+ * make the code in "savefile.c" capable of reading files with
+ * the old record header as well as files with the new record header
+ * (using the magic number to determine the header format).
+ *
+ * Then supply the changes by forking the branch at
+ *
+ * https://github.com/mcr/libpcap/issues
+ *
+ * and issuing a pull request, so that future versions of libpcap and
+ * programs that use it (such as tcpdump) will be able to read your new
+ * capture file format.
+ */
+
+struct pcap_sf_pkthdr {
+ struct pcap_timeval ts; /* time stamp */
+ bpf_u_int32 caplen; /* length of portion present */
+ bpf_u_int32 len; /* length this packet (off wire) */
+};
+
+/*
+ * How a `pcap_pkthdr' is actually stored in savefiles written
+ * by some patched versions of libpcap (e.g. the ones in Red
+ * Hat Linux 6.1 and 6.2).
+ *
+ * Do not change the format of this structure, in any way (this includes
+ * changes that only affect the length of fields in this structure).
+ * Instead, introduce a new structure, as per the above.
+ */
+
+struct pcap_sf_patched_pkthdr {
+ struct pcap_timeval ts; /* time stamp */
+ bpf_u_int32 caplen; /* length of portion present */
+ bpf_u_int32 len; /* length this packet (off wire) */
+ int index;
+ unsigned short protocol;
+ unsigned char pkt_type;
+};
+
+/*
+ * User data structure for the one-shot callback used for pcap_next()
+ * and pcap_next_ex().
+ */
+struct oneshot_userdata {
+ struct pcap_pkthdr *hdr;
+ const u_char **pkt;
+ pcap_t *pd;
+};
+
+int yylex(void);
+
+#ifndef min
+#define min(a, b) ((a) > (b) ? (b) : (a))
+#endif
+
+/* XXX should these be in pcap.h? */
+int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *);
+int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *);
+
+#ifndef HAVE_STRLCPY
+#define strlcpy(x, y, z) \
+ (strncpy((x), (y), (z)), \
+ ((z) <= 0 ? 0 : ((x)[(z) - 1] = '\0')), \
+ strlen((y)))
+#endif
+
+#include <stdarg.h>
+
+#if !defined(HAVE_SNPRINTF)
+#define snprintf pcap_snprintf
+extern int snprintf (char *, size_t, const char *, ...);
+#endif
+
+#if !defined(HAVE_VSNPRINTF)
+#define vsnprintf pcap_vsnprintf
+extern int vsnprintf (char *, size_t, const char *, va_list ap);
+#endif
+
+/*
+ * Routines that most pcap implementations can use for non-blocking mode.
+ */
+#if !defined(WIN32) && !defined(MSDOS)
+int pcap_getnonblock_fd(pcap_t *, char *);
+int pcap_setnonblock_fd(pcap_t *p, int, char *);
+#endif
+
+/*
+ * Internal interfaces for "pcap_create()".
+ *
+ * "pcap_create_interface()" is the routine to do a pcap_create on
+ * a regular network interface. There are multiple implementations
+ * of this, one for each platform type (Linux, BPF, DLPI, etc.),
+ * with the one used chosen by the configure script.
+ *
+ * "pcap_create_common()" allocates and fills in a pcap_t, for use
+ * by pcap_create routines.
+ */
+pcap_t *pcap_create_interface(const char *, char *);
+pcap_t *pcap_create_common(const char *, char *);
+int pcap_do_addexit(pcap_t *);
+void pcap_add_to_pcaps_to_close(pcap_t *);
+void pcap_remove_from_pcaps_to_close(pcap_t *);
+void pcap_cleanup_live_common(pcap_t *);
+int pcap_not_initialized(pcap_t *);
+int pcap_check_activated(pcap_t *);
+
+/*
+ * Internal interfaces for "pcap_findalldevs()".
+ *
+ * "pcap_findalldevs_interfaces()" finds interfaces using the
+ * "standard" mechanisms (SIOCGIFCONF, "getifaddrs()", etc.).
+ *
+ * "pcap_platform_finddevs()" is a platform-dependent routine to
+ * add devices not found by the "standard" mechanisms.
+ *
+ * "pcap_add_if()" adds an interface to the list of interfaces, for
+ * use by various "find interfaces" routines.
+ */
+int pcap_findalldevs_interfaces(pcap_if_t **, char *);
+int pcap_platform_finddevs(pcap_if_t **, char *);
+int add_addr_to_iflist(pcap_if_t **, const char *, u_int, struct sockaddr *,
+ size_t, struct sockaddr *, size_t, struct sockaddr *, size_t,
+ struct sockaddr *, size_t, char *);
+int pcap_add_if(pcap_if_t **, const char *, u_int, const char *, char *);
+struct sockaddr *dup_sockaddr(struct sockaddr *, size_t);
+int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, u_int,
+ const char *, char *);
+
+#ifdef WIN32
+char *pcap_win32strerror(void);
+#endif
+
+int install_bpf_program(pcap_t *, struct bpf_program *);
+
+int pcap_strcasecmp(const char *, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/freebsd/contrib/libpcap/pcap-namedb.h b/freebsd/contrib/libpcap/pcap-namedb.h
new file mode 100644
index 00000000..d0b22310
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap-namedb.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 1994, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.13 2006-10-04 18:13:32 guy Exp $ (LBL)
+ */
+
+/*
+ * For backwards compatibility.
+ *
+ * Note to OS vendors: do NOT get rid of this file! Some applications
+ * might expect to be able to include <pcap-namedb.h>.
+ */
+#include <pcap/namedb.h>
diff --git a/freebsd/contrib/libpcap/pcap.c b/freebsd/contrib/libpcap/pcap.c
new file mode 100644
index 00000000..11334563
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap.c
@@ -0,0 +1,1812 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.128 2008-12-23 20:13:29 guy Exp $ (LBL)";
+#endif
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/types.h>
+#include <sys/mman.h>
+#endif /* WIN32 */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(__MINGW32__)
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <errno.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#ifdef MSDOS
+#include "pcap-dos.h"
+#endif
+
+#include "pcap-int.h"
+
+#ifdef HAVE_DAG_API
+#include "pcap-dag.h"
+#endif /* HAVE_DAG_API */
+
+#ifdef HAVE_SEPTEL_API
+#include "pcap-septel.h"
+#endif /* HAVE_SEPTEL_API */
+
+#ifdef HAVE_SNF_API
+#include "pcap-snf.h"
+#endif /* HAVE_SNF_API */
+
+#ifdef PCAP_SUPPORT_USB
+#include "pcap-usb-linux.h"
+#endif
+
+#ifdef PCAP_SUPPORT_BT
+#include "pcap-bt-linux.h"
+#endif
+
+#ifdef PCAP_SUPPORT_CAN
+#include "pcap-can-linux.h"
+#endif
+
+#ifdef PCAP_SUPPORT_CANUSB
+#include "pcap-canusb-linux.h"
+#endif
+
+#ifdef PCAP_SUPPORT_NETFILTER
+#include "pcap-netfilter-linux.h"
+#endif
+
+int
+pcap_not_initialized(pcap_t *pcap)
+{
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+/*
+ * Returns 1 if rfmon mode can be set on the pcap_t, 0 if it can't,
+ * a PCAP_ERROR value on an error.
+ */
+int
+pcap_can_set_rfmon(pcap_t *p)
+{
+ return (p->can_set_rfmon_op(p));
+}
+
+/*
+ * For systems where rfmon mode is never supported.
+ */
+static int
+pcap_cant_set_rfmon(pcap_t *p _U_)
+{
+ return (0);
+}
+
+/*
+ * Sets *tstamp_typesp to point to an array 1 or more supported time stamp
+ * types; the return value is the number of supported time stamp types.
+ * The list should be freed by a call to pcap_free_tstamp_types() when
+ * you're done with it.
+ *
+ * A return value of 0 means "you don't get a choice of time stamp type",
+ * in which case *tstamp_typesp is set to null.
+ *
+ * PCAP_ERROR is returned on error.
+ */
+int
+pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp)
+{
+ if (p->tstamp_type_count == 0) {
+ /*
+ * We don't support multiple time stamp types.
+ */
+ *tstamp_typesp = NULL;
+ } else {
+ *tstamp_typesp = (int*)calloc(sizeof(**tstamp_typesp),
+ p->tstamp_type_count);
+ if (*tstamp_typesp == NULL) {
+ (void)snprintf(p->errbuf, sizeof(p->errbuf),
+ "malloc: %s", pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+ (void)memcpy(*tstamp_typesp, p->tstamp_type_list,
+ sizeof(**tstamp_typesp) * p->tstamp_type_count);
+ }
+ return (p->tstamp_type_count);
+}
+
+/*
+ * In Windows, you might have a library built with one version of the
+ * C runtime library and an application built with another version of
+ * the C runtime library, which means that the library might use one
+ * version of malloc() and free() and the application might use another
+ * version of malloc() and free(). If so, that means something
+ * allocated by the library cannot be freed by the application, so we
+ * need to have a pcap_free_tstamp_types() routine to free up the list
+ * allocated by pcap_list_tstamp_types(), even though it's just a wrapper
+ * around free().
+ */
+void
+pcap_free_tstamp_types(int *tstamp_type_list)
+{
+ free(tstamp_type_list);
+}
+
+/*
+ * Default one-shot callback; overridden for capture types where the
+ * packet data cannot be guaranteed to be available after the callback
+ * returns, so that a copy must be made.
+ */
+static void
+pcap_oneshot(u_char *user, const struct pcap_pkthdr *h, const u_char *pkt)
+{
+ struct oneshot_userdata *sp = (struct oneshot_userdata *)user;
+
+ *sp->hdr = *h;
+ *sp->pkt = pkt;
+}
+
+const u_char *
+pcap_next(pcap_t *p, struct pcap_pkthdr *h)
+{
+ struct oneshot_userdata s;
+ const u_char *pkt;
+
+ s.hdr = h;
+ s.pkt = &pkt;
+ s.pd = p;
+ if (pcap_dispatch(p, 1, p->oneshot_callback, (u_char *)&s) <= 0)
+ return (0);
+ return (pkt);
+}
+
+int
+pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
+ const u_char **pkt_data)
+{
+ struct oneshot_userdata s;
+
+ s.hdr = &p->pcap_header;
+ s.pkt = pkt_data;
+ s.pd = p;
+
+ /* Saves a pointer to the packet headers */
+ *pkt_header= &p->pcap_header;
+
+ if (p->sf.rfile != NULL) {
+ int status;
+
+ /* We are on an offline capture */
+ status = pcap_offline_read(p, 1, p->oneshot_callback,
+ (u_char *)&s);
+
+ /*
+ * Return codes for pcap_offline_read() are:
+ * - 0: EOF
+ * - -1: error
+ * - >1: OK
+ * The first one ('0') conflicts with the return code of
+ * 0 from pcap_read() meaning "no packets arrived before
+ * the timeout expired", so we map it to -2 so you can
+ * distinguish between an EOF from a savefile and a
+ * "no packets arrived before the timeout expired, try
+ * again" from a live capture.
+ */
+ if (status == 0)
+ return (-2);
+ else
+ return (status);
+ }
+
+ /*
+ * Return codes for pcap_read() are:
+ * - 0: timeout
+ * - -1: error
+ * - -2: loop was broken out of with pcap_breakloop()
+ * - >1: OK
+ * The first one ('0') conflicts with the return code of 0 from
+ * pcap_offline_read() meaning "end of file".
+ */
+ return (p->read_op(p, 1, p->oneshot_callback, (u_char *)&s));
+}
+
+#if defined(DAG_ONLY)
+int
+pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+{
+ return (dag_findalldevs(alldevsp, errbuf));
+}
+
+pcap_t *
+pcap_create(const char *source, char *errbuf)
+{
+ return (dag_create(source, errbuf));
+}
+#elif defined(SEPTEL_ONLY)
+int
+pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+{
+ return (septel_findalldevs(alldevsp, errbuf));
+}
+
+pcap_t *
+pcap_create(const char *source, char *errbuf)
+{
+ return (septel_create(source, errbuf));
+}
+#elif defined(SNF_ONLY)
+int
+pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+{
+ return (snf_findalldevs(alldevsp, errbuf));
+}
+
+pcap_t *
+pcap_create(const char *source, char *errbuf)
+{
+ return (snf_create(source, errbuf));
+}
+#else /* regular pcap */
+struct capture_source_type {
+ int (*findalldevs_op)(pcap_if_t **, char *);
+ pcap_t *(*create_op)(const char *, char *, int *);
+} capture_source_types[] = {
+#ifdef HAVE_DAG_API
+ { dag_findalldevs, dag_create },
+#endif
+#ifdef HAVE_SEPTEL_API
+ { septel_findalldevs, septel_create },
+#endif
+#ifdef HAVE_SNF_API
+ { snf_findalldevs, snf_create },
+#endif
+#ifdef PCAP_SUPPORT_BT
+ { bt_findalldevs, bt_create },
+#endif
+#if PCAP_SUPPORT_CANUSB
+ { canusb_findalldevs, canusb_create },
+#endif
+#ifdef PCAP_SUPPORT_CAN
+ { can_findalldevs, can_create },
+#endif
+#ifdef PCAP_SUPPORT_USB
+ { usb_findalldevs, usb_create },
+#endif
+#ifdef PCAP_SUPPORT_NETFILTER
+ { netfilter_findalldevs, netfilter_create },
+#endif
+ { NULL, NULL }
+};
+
+/*
+ * Get a list of all capture sources that are up and that we can open.
+ * Returns -1 on error, 0 otherwise.
+ * The list, as returned through "alldevsp", may be null if no interfaces
+ * were up and could be opened.
+ */
+int
+pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+{
+ size_t i;
+
+ /*
+ * Get the list of regular interfaces first.
+ */
+ if (pcap_findalldevs_interfaces(alldevsp, errbuf) == -1)
+ return (-1); /* failure */
+
+ /*
+ * Add any interfaces that need a platform-specific mechanism
+ * to find.
+ */
+ if (pcap_platform_finddevs(alldevsp, errbuf) == -1) {
+ /*
+ * We had an error; free the list we've been
+ * constructing.
+ */
+ if (*alldevsp != NULL) {
+ pcap_freealldevs(*alldevsp);
+ *alldevsp = NULL;
+ }
+ return (-1);
+ }
+
+ /*
+ * Ask each of the non-local-network-interface capture
+ * source types what interfaces they have.
+ */
+ for (i = 0; capture_source_types[i].findalldevs_op != NULL; i++) {
+ if (capture_source_types[i].findalldevs_op(alldevsp, errbuf) == -1) {
+ /*
+ * We had an error; free the list we've been
+ * constructing.
+ */
+ if (*alldevsp != NULL) {
+ pcap_freealldevs(*alldevsp);
+ *alldevsp = NULL;
+ }
+ return (-1);
+ }
+ }
+ return (0);
+}
+
+pcap_t *
+pcap_create(const char *source, char *errbuf)
+{
+ size_t i;
+ int is_theirs;
+ pcap_t *p;
+
+ /*
+ * A null source name is equivalent to the "any" device -
+ * which might not be supported on this platform, but
+ * this means that you'll get a "not supported" error
+ * rather than, say, a crash when we try to dereference
+ * the null pointer.
+ */
+ if (source == NULL)
+ source = "any";
+
+ /*
+ * Try each of the non-local-network-interface capture
+ * source types until we find one that works for this
+ * device or run out of types.
+ */
+ for (i = 0; capture_source_types[i].create_op != NULL; i++) {
+ is_theirs = 0;
+ p = capture_source_types[i].create_op(source, errbuf, &is_theirs);
+ if (is_theirs) {
+ /*
+ * The device name refers to a device of the
+ * type in question; either it succeeded,
+ * in which case p refers to a pcap_t to
+ * later activate for the device, or it
+ * failed, in which case p is null and we
+ * should return that to report the failure
+ * to create.
+ */
+ return (p);
+ }
+ }
+
+ /*
+ * OK, try it as a regular network interface.
+ */
+ return (pcap_create_interface(source, errbuf));
+}
+#endif
+
+static void
+initialize_ops(pcap_t *p)
+{
+ /*
+ * Set operation pointers for operations that only work on
+ * an activated pcap_t to point to a routine that returns
+ * a "this isn't activated" error.
+ */
+ p->read_op = (read_op_t)pcap_not_initialized;
+ p->inject_op = (inject_op_t)pcap_not_initialized;
+ p->setfilter_op = (setfilter_op_t)pcap_not_initialized;
+ p->setdirection_op = (setdirection_op_t)pcap_not_initialized;
+ p->set_datalink_op = (set_datalink_op_t)pcap_not_initialized;
+ p->getnonblock_op = (getnonblock_op_t)pcap_not_initialized;
+ p->setnonblock_op = (setnonblock_op_t)pcap_not_initialized;
+ p->stats_op = (stats_op_t)pcap_not_initialized;
+#ifdef WIN32
+ p->setbuff_op = (setbuff_op_t)pcap_not_initialized;
+ p->setmode_op = (setmode_op_t)pcap_not_initialized;
+ p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized;
+#endif
+
+ /*
+ * Default cleanup operation - implementations can override
+ * this, but should call pcap_cleanup_live_common() after
+ * doing their own additional cleanup.
+ */
+ p->cleanup_op = pcap_cleanup_live_common;
+
+ /*
+ * In most cases, the standard one-short callback can
+ * be used for pcap_next()/pcap_next_ex().
+ */
+ p->oneshot_callback = pcap_oneshot;
+}
+
+pcap_t *
+pcap_create_common(const char *source, char *ebuf)
+{
+ pcap_t *p;
+
+ p = malloc(sizeof(*p));
+ if (p == NULL) {
+ snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
+ pcap_strerror(errno));
+ return (NULL);
+ }
+ memset(p, 0, sizeof(*p));
+#ifndef WIN32
+ p->fd = -1; /* not opened yet */
+ p->selectable_fd = -1;
+ p->send_fd = -1;
+#endif
+
+ p->opt.source = strdup(source);
+ if (p->opt.source == NULL) {
+ snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
+ pcap_strerror(errno));
+ free(p);
+ return (NULL);
+ }
+
+ /*
+ * Default to "can't set rfmon mode"; if it's supported by
+ * a platform, the create routine that called us can set
+ * the op to its routine to check whether a particular
+ * device supports it.
+ */
+ p->can_set_rfmon_op = pcap_cant_set_rfmon;
+
+ initialize_ops(p);
+
+ /* put in some defaults*/
+ pcap_set_timeout(p, 0);
+ pcap_set_snaplen(p, 65535); /* max packet size */
+ p->opt.promisc = 0;
+ p->opt.buffer_size = 0;
+ p->opt.tstamp_type = -1; /* default to not setting time stamp type */
+ return (p);
+}
+
+int
+pcap_check_activated(pcap_t *p)
+{
+ if (p->activated) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't perform "
+ " operation on activated capture");
+ return (-1);
+ }
+ return (0);
+}
+
+int
+pcap_set_snaplen(pcap_t *p, int snaplen)
+{
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+ p->snapshot = snaplen;
+ return (0);
+}
+
+int
+pcap_set_promisc(pcap_t *p, int promisc)
+{
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+ p->opt.promisc = promisc;
+ return (0);
+}
+
+int
+pcap_set_rfmon(pcap_t *p, int rfmon)
+{
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+ p->opt.rfmon = rfmon;
+ return (0);
+}
+
+int
+pcap_set_timeout(pcap_t *p, int timeout_ms)
+{
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+ p->md.timeout = timeout_ms;
+ return (0);
+}
+
+int
+pcap_set_tstamp_type(pcap_t *p, int tstamp_type)
+{
+ int i;
+
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+
+ /*
+ * If p->tstamp_type_count is 0, we don't support setting
+ * the time stamp type at all.
+ */
+ if (p->tstamp_type_count == 0)
+ return (PCAP_ERROR_CANTSET_TSTAMP_TYPE);
+
+ /*
+ * Check whether we claim to support this type of time stamp.
+ */
+ for (i = 0; i < p->tstamp_type_count; i++) {
+ if (p->tstamp_type_list[i] == tstamp_type) {
+ /*
+ * Yes.
+ */
+ p->opt.tstamp_type = tstamp_type;
+ return (0);
+ }
+ }
+
+ /*
+ * No. We support setting the time stamp type, but not to this
+ * particular value.
+ */
+ return (PCAP_WARNING_TSTAMP_TYPE_NOTSUP);
+}
+
+int
+pcap_set_buffer_size(pcap_t *p, int buffer_size)
+{
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+ p->opt.buffer_size = buffer_size;
+ return (0);
+}
+
+int
+pcap_activate(pcap_t *p)
+{
+ int status;
+
+ /*
+ * Catch attempts to re-activate an already-activated
+ * pcap_t; this should, for example, catch code that
+ * calls pcap_open_live() followed by pcap_activate(),
+ * as some code that showed up in a Stack Exchange
+ * question did.
+ */
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+ status = p->activate_op(p);
+ if (status >= 0)
+ p->activated = 1;
+ else {
+ if (p->errbuf[0] == '\0') {
+ /*
+ * No error message supplied by the activate routine;
+ * for the benefit of programs that don't specially
+ * handle errors other than PCAP_ERROR, return the
+ * error message corresponding to the status.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s",
+ pcap_statustostr(status));
+ }
+
+ /*
+ * Undo any operation pointer setting, etc. done by
+ * the activate operation.
+ */
+ initialize_ops(p);
+ }
+ return (status);
+}
+
+pcap_t *
+pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf)
+{
+ pcap_t *p;
+ int status;
+
+ p = pcap_create(source, errbuf);
+ if (p == NULL)
+ return (NULL);
+ status = pcap_set_snaplen(p, snaplen);
+ if (status < 0)
+ goto fail;
+ status = pcap_set_promisc(p, promisc);
+ if (status < 0)
+ goto fail;
+ status = pcap_set_timeout(p, to_ms);
+ if (status < 0)
+ goto fail;
+ /*
+ * Mark this as opened with pcap_open_live(), so that, for
+ * example, we show the full list of DLT_ values, rather
+ * than just the ones that are compatible with capturing
+ * when not in monitor mode. That allows existing applications
+ * to work the way they used to work, but allows new applications
+ * that know about the new open API to, for example, find out the
+ * DLT_ values that they can select without changing whether
+ * the adapter is in monitor mode or not.
+ */
+ p->oldstyle = 1;
+ status = pcap_activate(p);
+ if (status < 0)
+ goto fail;
+ return (p);
+fail:
+ if (status == PCAP_ERROR)
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source,
+ p->errbuf);
+ else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
+ status == PCAP_ERROR_PERM_DENIED ||
+ status == PCAP_ERROR_PROMISC_PERM_DENIED)
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", source,
+ pcap_statustostr(status), p->errbuf);
+ else
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source,
+ pcap_statustostr(status));
+ pcap_close(p);
+ return (NULL);
+}
+
+int
+pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
+{
+ return (p->read_op(p, cnt, callback, user));
+}
+
+/*
+ * XXX - is this necessary?
+ */
+int
+pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
+{
+
+ return (p->read_op(p, cnt, callback, user));
+}
+
+int
+pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
+{
+ register int n;
+
+ for (;;) {
+ if (p->sf.rfile != NULL) {
+ /*
+ * 0 means EOF, so don't loop if we get 0.
+ */
+ n = pcap_offline_read(p, cnt, callback, user);
+ } else {
+ /*
+ * XXX keep reading until we get something
+ * (or an error occurs)
+ */
+ do {
+ n = p->read_op(p, cnt, callback, user);
+ } while (n == 0);
+ }
+ if (n <= 0)
+ return (n);
+ if (cnt > 0) {
+ cnt -= n;
+ if (cnt <= 0)
+ return (0);
+ }
+ }
+}
+
+/*
+ * Force the loop in "pcap_read()" or "pcap_read_offline()" to terminate.
+ */
+void
+pcap_breakloop(pcap_t *p)
+{
+ p->break_loop = 1;
+}
+
+int
+pcap_datalink(pcap_t *p)
+{
+ return (p->linktype);
+}
+
+int
+pcap_datalink_ext(pcap_t *p)
+{
+ return (p->linktype_ext);
+}
+
+int
+pcap_list_datalinks(pcap_t *p, int **dlt_buffer)
+{
+ if (p->dlt_count == 0) {
+ /*
+ * We couldn't fetch the list of DLTs, which means
+ * this platform doesn't support changing the
+ * DLT for an interface. Return a list of DLTs
+ * containing only the DLT this device supports.
+ */
+ *dlt_buffer = (int*)malloc(sizeof(**dlt_buffer));
+ if (*dlt_buffer == NULL) {
+ (void)snprintf(p->errbuf, sizeof(p->errbuf),
+ "malloc: %s", pcap_strerror(errno));
+ return (-1);
+ }
+ **dlt_buffer = p->linktype;
+ return (1);
+ } else {
+ *dlt_buffer = (int*)calloc(sizeof(**dlt_buffer), p->dlt_count);
+ if (*dlt_buffer == NULL) {
+ (void)snprintf(p->errbuf, sizeof(p->errbuf),
+ "malloc: %s", pcap_strerror(errno));
+ return (-1);
+ }
+ (void)memcpy(*dlt_buffer, p->dlt_list,
+ sizeof(**dlt_buffer) * p->dlt_count);
+ return (p->dlt_count);
+ }
+}
+
+/*
+ * In Windows, you might have a library built with one version of the
+ * C runtime library and an application built with another version of
+ * the C runtime library, which means that the library might use one
+ * version of malloc() and free() and the application might use another
+ * version of malloc() and free(). If so, that means something
+ * allocated by the library cannot be freed by the application, so we
+ * need to have a pcap_free_datalinks() routine to free up the list
+ * allocated by pcap_list_datalinks(), even though it's just a wrapper
+ * around free().
+ */
+void
+pcap_free_datalinks(int *dlt_list)
+{
+ free(dlt_list);
+}
+
+int
+pcap_set_datalink(pcap_t *p, int dlt)
+{
+ int i;
+ const char *dlt_name;
+
+ if (p->dlt_count == 0 || p->set_datalink_op == NULL) {
+ /*
+ * We couldn't fetch the list of DLTs, or we don't
+ * have a "set datalink" operation, which means
+ * this platform doesn't support changing the
+ * DLT for an interface. Check whether the new
+ * DLT is the one this interface supports.
+ */
+ if (p->linktype != dlt)
+ goto unsupported;
+
+ /*
+ * It is, so there's nothing we need to do here.
+ */
+ return (0);
+ }
+ for (i = 0; i < p->dlt_count; i++)
+ if (p->dlt_list[i] == dlt)
+ break;
+ if (i >= p->dlt_count)
+ goto unsupported;
+ if (p->dlt_count == 2 && p->dlt_list[0] == DLT_EN10MB &&
+ dlt == DLT_DOCSIS) {
+ /*
+ * This is presumably an Ethernet device, as the first
+ * link-layer type it offers is DLT_EN10MB, and the only
+ * other type it offers is DLT_DOCSIS. That means that
+ * we can't tell the driver to supply DOCSIS link-layer
+ * headers - we're just pretending that's what we're
+ * getting, as, presumably, we're capturing on a dedicated
+ * link to a Cisco Cable Modem Termination System, and
+ * it's putting raw DOCSIS frames on the wire inside low-level
+ * Ethernet framing.
+ */
+ p->linktype = dlt;
+ return (0);
+ }
+ if (p->set_datalink_op(p, dlt) == -1)
+ return (-1);
+ p->linktype = dlt;
+ return (0);
+
+unsupported:
+ dlt_name = pcap_datalink_val_to_name(dlt);
+ if (dlt_name != NULL) {
+ (void) snprintf(p->errbuf, sizeof(p->errbuf),
+ "%s is not one of the DLTs supported by this device",
+ dlt_name);
+ } else {
+ (void) snprintf(p->errbuf, sizeof(p->errbuf),
+ "DLT %d is not one of the DLTs supported by this device",
+ dlt);
+ }
+ return (-1);
+}
+
+/*
+ * This array is designed for mapping upper and lower case letter
+ * together for a case independent comparison. The mappings are
+ * based upon ascii character sequences.
+ */
+static const u_char charmap[] = {
+ (u_char)'\000', (u_char)'\001', (u_char)'\002', (u_char)'\003',
+ (u_char)'\004', (u_char)'\005', (u_char)'\006', (u_char)'\007',
+ (u_char)'\010', (u_char)'\011', (u_char)'\012', (u_char)'\013',
+ (u_char)'\014', (u_char)'\015', (u_char)'\016', (u_char)'\017',
+ (u_char)'\020', (u_char)'\021', (u_char)'\022', (u_char)'\023',
+ (u_char)'\024', (u_char)'\025', (u_char)'\026', (u_char)'\027',
+ (u_char)'\030', (u_char)'\031', (u_char)'\032', (u_char)'\033',
+ (u_char)'\034', (u_char)'\035', (u_char)'\036', (u_char)'\037',
+ (u_char)'\040', (u_char)'\041', (u_char)'\042', (u_char)'\043',
+ (u_char)'\044', (u_char)'\045', (u_char)'\046', (u_char)'\047',
+ (u_char)'\050', (u_char)'\051', (u_char)'\052', (u_char)'\053',
+ (u_char)'\054', (u_char)'\055', (u_char)'\056', (u_char)'\057',
+ (u_char)'\060', (u_char)'\061', (u_char)'\062', (u_char)'\063',
+ (u_char)'\064', (u_char)'\065', (u_char)'\066', (u_char)'\067',
+ (u_char)'\070', (u_char)'\071', (u_char)'\072', (u_char)'\073',
+ (u_char)'\074', (u_char)'\075', (u_char)'\076', (u_char)'\077',
+ (u_char)'\100', (u_char)'\141', (u_char)'\142', (u_char)'\143',
+ (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147',
+ (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153',
+ (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157',
+ (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163',
+ (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167',
+ (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\133',
+ (u_char)'\134', (u_char)'\135', (u_char)'\136', (u_char)'\137',
+ (u_char)'\140', (u_char)'\141', (u_char)'\142', (u_char)'\143',
+ (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147',
+ (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153',
+ (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157',
+ (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163',
+ (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167',
+ (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\173',
+ (u_char)'\174', (u_char)'\175', (u_char)'\176', (u_char)'\177',
+ (u_char)'\200', (u_char)'\201', (u_char)'\202', (u_char)'\203',
+ (u_char)'\204', (u_char)'\205', (u_char)'\206', (u_char)'\207',
+ (u_char)'\210', (u_char)'\211', (u_char)'\212', (u_char)'\213',
+ (u_char)'\214', (u_char)'\215', (u_char)'\216', (u_char)'\217',
+ (u_char)'\220', (u_char)'\221', (u_char)'\222', (u_char)'\223',
+ (u_char)'\224', (u_char)'\225', (u_char)'\226', (u_char)'\227',
+ (u_char)'\230', (u_char)'\231', (u_char)'\232', (u_char)'\233',
+ (u_char)'\234', (u_char)'\235', (u_char)'\236', (u_char)'\237',
+ (u_char)'\240', (u_char)'\241', (u_char)'\242', (u_char)'\243',
+ (u_char)'\244', (u_char)'\245', (u_char)'\246', (u_char)'\247',
+ (u_char)'\250', (u_char)'\251', (u_char)'\252', (u_char)'\253',
+ (u_char)'\254', (u_char)'\255', (u_char)'\256', (u_char)'\257',
+ (u_char)'\260', (u_char)'\261', (u_char)'\262', (u_char)'\263',
+ (u_char)'\264', (u_char)'\265', (u_char)'\266', (u_char)'\267',
+ (u_char)'\270', (u_char)'\271', (u_char)'\272', (u_char)'\273',
+ (u_char)'\274', (u_char)'\275', (u_char)'\276', (u_char)'\277',
+ (u_char)'\300', (u_char)'\341', (u_char)'\342', (u_char)'\343',
+ (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347',
+ (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353',
+ (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357',
+ (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363',
+ (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367',
+ (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\333',
+ (u_char)'\334', (u_char)'\335', (u_char)'\336', (u_char)'\337',
+ (u_char)'\340', (u_char)'\341', (u_char)'\342', (u_char)'\343',
+ (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347',
+ (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353',
+ (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357',
+ (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363',
+ (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367',
+ (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\373',
+ (u_char)'\374', (u_char)'\375', (u_char)'\376', (u_char)'\377',
+};
+
+int
+pcap_strcasecmp(const char *s1, const char *s2)
+{
+ register const u_char *cm = charmap,
+ *us1 = (const u_char *)s1,
+ *us2 = (const u_char *)s2;
+
+ while (cm[*us1] == cm[*us2++])
+ if (*us1++ == '\0')
+ return(0);
+ return (cm[*us1] - cm[*--us2]);
+}
+
+struct dlt_choice {
+ const char *name;
+ const char *description;
+ int dlt;
+};
+
+#define DLT_CHOICE(code, description) { #code, description, code }
+#define DLT_CHOICE_SENTINEL { NULL, NULL, 0 }
+
+static struct dlt_choice dlt_choices[] = {
+ DLT_CHOICE(DLT_NULL, "BSD loopback"),
+ DLT_CHOICE(DLT_EN10MB, "Ethernet"),
+ DLT_CHOICE(DLT_IEEE802, "Token ring"),
+ DLT_CHOICE(DLT_ARCNET, "BSD ARCNET"),
+ DLT_CHOICE(DLT_SLIP, "SLIP"),
+ DLT_CHOICE(DLT_PPP, "PPP"),
+ DLT_CHOICE(DLT_FDDI, "FDDI"),
+ DLT_CHOICE(DLT_ATM_RFC1483, "RFC 1483 LLC-encapsulated ATM"),
+ DLT_CHOICE(DLT_RAW, "Raw IP"),
+ DLT_CHOICE(DLT_SLIP_BSDOS, "BSD/OS SLIP"),
+ DLT_CHOICE(DLT_PPP_BSDOS, "BSD/OS PPP"),
+ DLT_CHOICE(DLT_ATM_CLIP, "Linux Classical IP-over-ATM"),
+ DLT_CHOICE(DLT_PPP_SERIAL, "PPP over serial"),
+ DLT_CHOICE(DLT_PPP_ETHER, "PPPoE"),
+ DLT_CHOICE(DLT_SYMANTEC_FIREWALL, "Symantec Firewall"),
+ DLT_CHOICE(DLT_C_HDLC, "Cisco HDLC"),
+ DLT_CHOICE(DLT_IEEE802_11, "802.11"),
+ DLT_CHOICE(DLT_FRELAY, "Frame Relay"),
+ DLT_CHOICE(DLT_LOOP, "OpenBSD loopback"),
+ DLT_CHOICE(DLT_ENC, "OpenBSD encapsulated IP"),
+ DLT_CHOICE(DLT_LINUX_SLL, "Linux cooked"),
+ DLT_CHOICE(DLT_LTALK, "Localtalk"),
+ DLT_CHOICE(DLT_PFLOG, "OpenBSD pflog file"),
+ DLT_CHOICE(DLT_PFSYNC, "Packet filter state syncing"),
+ DLT_CHOICE(DLT_PRISM_HEADER, "802.11 plus Prism header"),
+ DLT_CHOICE(DLT_IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"),
+ DLT_CHOICE(DLT_SUNATM, "Sun raw ATM"),
+ DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus radiotap header"),
+ DLT_CHOICE(DLT_ARCNET_LINUX, "Linux ARCNET"),
+ DLT_CHOICE(DLT_JUNIPER_MLPPP, "Juniper Multi-Link PPP"),
+ DLT_CHOICE(DLT_JUNIPER_MLFR, "Juniper Multi-Link Frame Relay"),
+ DLT_CHOICE(DLT_JUNIPER_ES, "Juniper Encryption Services PIC"),
+ DLT_CHOICE(DLT_JUNIPER_GGSN, "Juniper GGSN PIC"),
+ DLT_CHOICE(DLT_JUNIPER_MFR, "Juniper FRF.16 Frame Relay"),
+ DLT_CHOICE(DLT_JUNIPER_ATM2, "Juniper ATM2 PIC"),
+ DLT_CHOICE(DLT_JUNIPER_SERVICES, "Juniper Advanced Services PIC"),
+ DLT_CHOICE(DLT_JUNIPER_ATM1, "Juniper ATM1 PIC"),
+ DLT_CHOICE(DLT_APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"),
+ DLT_CHOICE(DLT_MTP2_WITH_PHDR, "SS7 MTP2 with Pseudo-header"),
+ DLT_CHOICE(DLT_MTP2, "SS7 MTP2"),
+ DLT_CHOICE(DLT_MTP3, "SS7 MTP3"),
+ DLT_CHOICE(DLT_SCCP, "SS7 SCCP"),
+ DLT_CHOICE(DLT_DOCSIS, "DOCSIS"),
+ DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"),
+ DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"),
+ DLT_CHOICE(DLT_JUNIPER_MONITOR, "Juniper Passive Monitor PIC"),
+ DLT_CHOICE(DLT_PPP_PPPD, "PPP for pppd, with direction flag"),
+ DLT_CHOICE(DLT_JUNIPER_PPPOE, "Juniper PPPoE"),
+ DLT_CHOICE(DLT_JUNIPER_PPPOE_ATM, "Juniper PPPoE/ATM"),
+ DLT_CHOICE(DLT_GPRS_LLC, "GPRS LLC"),
+ DLT_CHOICE(DLT_GPF_T, "GPF-T"),
+ DLT_CHOICE(DLT_GPF_F, "GPF-F"),
+ DLT_CHOICE(DLT_JUNIPER_PIC_PEER, "Juniper PIC Peer"),
+ DLT_CHOICE(DLT_ERF_ETH, "Ethernet with Endace ERF header"),
+ DLT_CHOICE(DLT_ERF_POS, "Packet-over-SONET with Endace ERF header"),
+ DLT_CHOICE(DLT_LINUX_LAPD, "Linux vISDN LAPD"),
+ DLT_CHOICE(DLT_JUNIPER_ETHER, "Juniper Ethernet"),
+ DLT_CHOICE(DLT_JUNIPER_PPP, "Juniper PPP"),
+ DLT_CHOICE(DLT_JUNIPER_FRELAY, "Juniper Frame Relay"),
+ DLT_CHOICE(DLT_JUNIPER_CHDLC, "Juniper C-HDLC"),
+ DLT_CHOICE(DLT_MFR, "FRF.16 Frame Relay"),
+ DLT_CHOICE(DLT_JUNIPER_VP, "Juniper Voice PIC"),
+ DLT_CHOICE(DLT_A429, "Arinc 429"),
+ DLT_CHOICE(DLT_A653_ICM, "Arinc 653 Interpartition Communication"),
+ DLT_CHOICE(DLT_USB, "USB"),
+ DLT_CHOICE(DLT_BLUETOOTH_HCI_H4, "Bluetooth HCI UART transport layer"),
+ DLT_CHOICE(DLT_IEEE802_16_MAC_CPS, "IEEE 802.16 MAC Common Part Sublayer"),
+ DLT_CHOICE(DLT_USB_LINUX, "USB with Linux header"),
+ DLT_CHOICE(DLT_CAN20B, "Controller Area Network (CAN) v. 2.0B"),
+ DLT_CHOICE(DLT_IEEE802_15_4_LINUX, "IEEE 802.15.4 with Linux padding"),
+ DLT_CHOICE(DLT_PPI, "Per-Packet Information"),
+ DLT_CHOICE(DLT_IEEE802_16_MAC_CPS_RADIO, "IEEE 802.16 MAC Common Part Sublayer plus radiotap header"),
+ DLT_CHOICE(DLT_JUNIPER_ISM, "Juniper Integrated Service Module"),
+ DLT_CHOICE(DLT_IEEE802_15_4, "IEEE 802.15.4 with FCS"),
+ DLT_CHOICE(DLT_SITA, "SITA pseudo-header"),
+ DLT_CHOICE(DLT_ERF, "Endace ERF header"),
+ DLT_CHOICE(DLT_RAIF1, "Ethernet with u10 Networks pseudo-header"),
+ DLT_CHOICE(DLT_IPMB, "IPMB"),
+ DLT_CHOICE(DLT_JUNIPER_ST, "Juniper Secure Tunnel"),
+ DLT_CHOICE(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, "Bluetooth HCI UART transport layer plus pseudo-header"),
+ DLT_CHOICE(DLT_AX25_KISS, "AX.25 with KISS header"),
+ DLT_CHOICE(DLT_IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"),
+ DLT_CHOICE(DLT_MPLS, "MPLS with label as link-layer header"),
+ DLT_CHOICE(DLT_USB_LINUX_MMAPPED, "USB with padded Linux header"),
+ DLT_CHOICE(DLT_DECT, "DECT"),
+ DLT_CHOICE(DLT_AOS, "AOS Space Data Link protocol"),
+ DLT_CHOICE(DLT_WIHART, "Wireless HART"),
+ DLT_CHOICE(DLT_FC_2, "Fibre Channel FC-2"),
+ DLT_CHOICE(DLT_FC_2_WITH_FRAME_DELIMS, "Fibre Channel FC-2 with frame delimiters"),
+ DLT_CHOICE(DLT_IPNET, "Solaris ipnet"),
+ DLT_CHOICE(DLT_CAN_SOCKETCAN, "CAN-bus with SocketCAN headers"),
+ DLT_CHOICE(DLT_IPV4, "Raw IPv4"),
+ DLT_CHOICE(DLT_IPV6, "Raw IPv6"),
+ DLT_CHOICE(DLT_IEEE802_15_4_NOFCS, "IEEE 802.15.4 without FCS"),
+ DLT_CHOICE(DLT_JUNIPER_VS, "Juniper Virtual Server"),
+ DLT_CHOICE(DLT_JUNIPER_SRX_E2E, "Juniper SRX E2E"),
+ DLT_CHOICE(DLT_JUNIPER_FIBRECHANNEL, "Juniper Fibre Channel"),
+ DLT_CHOICE(DLT_DVB_CI, "DVB-CI"),
+ DLT_CHOICE(DLT_JUNIPER_ATM_CEMIC, "Juniper ATM CEMIC"),
+ DLT_CHOICE(DLT_NFLOG, "Linux netfilter log messages"),
+ DLT_CHOICE(DLT_NETANALYZER, "Ethernet with Hilscher netANALYZER pseudo-header"),
+ DLT_CHOICE(DLT_NETANALYZER_TRANSPARENT, "Ethernet with Hilscher netANALYZER pseudo-header and with preamble and SFD"),
+ DLT_CHOICE(DLT_IPOIB, "RFC 4391 IP-over-Infiniband"),
+ DLT_CHOICE_SENTINEL
+};
+
+int
+pcap_datalink_name_to_val(const char *name)
+{
+ int i;
+
+ for (i = 0; dlt_choices[i].name != NULL; i++) {
+ if (pcap_strcasecmp(dlt_choices[i].name + sizeof("DLT_") - 1,
+ name) == 0)
+ return (dlt_choices[i].dlt);
+ }
+ return (-1);
+}
+
+const char *
+pcap_datalink_val_to_name(int dlt)
+{
+ int i;
+
+ for (i = 0; dlt_choices[i].name != NULL; i++) {
+ if (dlt_choices[i].dlt == dlt)
+ return (dlt_choices[i].name + sizeof("DLT_") - 1);
+ }
+ return (NULL);
+}
+
+const char *
+pcap_datalink_val_to_description(int dlt)
+{
+ int i;
+
+ for (i = 0; dlt_choices[i].name != NULL; i++) {
+ if (dlt_choices[i].dlt == dlt)
+ return (dlt_choices[i].description);
+ }
+ return (NULL);
+}
+
+struct tstamp_type_choice {
+ const char *name;
+ const char *description;
+ int type;
+};
+
+static struct tstamp_type_choice tstamp_type_choices[] = {
+ { "host", "Host", PCAP_TSTAMP_HOST },
+ { "host_lowprec", "Host, low precision", PCAP_TSTAMP_HOST_LOWPREC },
+ { "host_hiprec", "Host, high precision", PCAP_TSTAMP_HOST_HIPREC },
+ { "adapter", "Adapter", PCAP_TSTAMP_ADAPTER },
+ { "adapter_unsynced", "Adapter, not synced with system time", PCAP_TSTAMP_ADAPTER_UNSYNCED },
+ { NULL, NULL, 0 }
+};
+
+int
+pcap_tstamp_type_name_to_val(const char *name)
+{
+ int i;
+
+ for (i = 0; tstamp_type_choices[i].name != NULL; i++) {
+ if (pcap_strcasecmp(tstamp_type_choices[i].name, name) == 0)
+ return (tstamp_type_choices[i].type);
+ }
+ return (PCAP_ERROR);
+}
+
+const char *
+pcap_tstamp_type_val_to_name(int tstamp_type)
+{
+ int i;
+
+ for (i = 0; tstamp_type_choices[i].name != NULL; i++) {
+ if (tstamp_type_choices[i].type == tstamp_type)
+ return (tstamp_type_choices[i].name);
+ }
+ return (NULL);
+}
+
+const char *
+pcap_tstamp_type_val_to_description(int tstamp_type)
+{
+ int i;
+
+ for (i = 0; tstamp_type_choices[i].name != NULL; i++) {
+ if (tstamp_type_choices[i].type == tstamp_type)
+ return (tstamp_type_choices[i].description);
+ }
+ return (NULL);
+}
+
+int
+pcap_snapshot(pcap_t *p)
+{
+ return (p->snapshot);
+}
+
+int
+pcap_is_swapped(pcap_t *p)
+{
+ return (p->sf.swapped);
+}
+
+int
+pcap_major_version(pcap_t *p)
+{
+ return (p->sf.version_major);
+}
+
+int
+pcap_minor_version(pcap_t *p)
+{
+ return (p->sf.version_minor);
+}
+
+FILE *
+pcap_file(pcap_t *p)
+{
+ return (p->sf.rfile);
+}
+
+int
+pcap_fileno(pcap_t *p)
+{
+#ifndef WIN32
+ return (p->fd);
+#else
+ if (p->adapter != NULL)
+ return ((int)(DWORD)p->adapter->hFile);
+ else
+ return (-1);
+#endif
+}
+
+#if !defined(WIN32) && !defined(MSDOS)
+int
+pcap_get_selectable_fd(pcap_t *p)
+{
+ return (p->selectable_fd);
+}
+#endif
+
+void
+pcap_perror(pcap_t *p, char *prefix)
+{
+ fprintf(stderr, "%s: %s\n", prefix, p->errbuf);
+}
+
+char *
+pcap_geterr(pcap_t *p)
+{
+ return (p->errbuf);
+}
+
+int
+pcap_getnonblock(pcap_t *p, char *errbuf)
+{
+ int ret;
+
+ ret = p->getnonblock_op(p, errbuf);
+ if (ret == -1) {
+ /*
+ * In case somebody depended on the bug wherein
+ * the error message was put into p->errbuf
+ * by pcap_getnonblock_fd().
+ */
+ strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE);
+ }
+ return (ret);
+}
+
+/*
+ * Get the current non-blocking mode setting, under the assumption that
+ * it's just the standard POSIX non-blocking flag.
+ *
+ * We don't look at "p->nonblock", in case somebody tweaked the FD
+ * directly.
+ */
+#if !defined(WIN32) && !defined(MSDOS)
+int
+pcap_getnonblock_fd(pcap_t *p, char *errbuf)
+{
+ int fdflags;
+
+ fdflags = fcntl(p->fd, F_GETFL, 0);
+ if (fdflags == -1) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
+ pcap_strerror(errno));
+ return (-1);
+ }
+ if (fdflags & O_NONBLOCK)
+ return (1);
+ else
+ return (0);
+}
+#endif
+
+int
+pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
+{
+ int ret;
+
+ ret = p->setnonblock_op(p, nonblock, errbuf);
+ if (ret == -1) {
+ /*
+ * In case somebody depended on the bug wherein
+ * the error message was put into p->errbuf
+ * by pcap_setnonblock_fd().
+ */
+ strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE);
+ }
+ return (ret);
+}
+
+#if !defined(WIN32) && !defined(MSDOS)
+/*
+ * Set non-blocking mode, under the assumption that it's just the
+ * standard POSIX non-blocking flag. (This can be called by the
+ * per-platform non-blocking-mode routine if that routine also
+ * needs to do some additional work.)
+ */
+int
+pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf)
+{
+ int fdflags;
+
+ fdflags = fcntl(p->fd, F_GETFL, 0);
+ if (fdflags == -1) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
+ pcap_strerror(errno));
+ return (-1);
+ }
+ if (nonblock)
+ fdflags |= O_NONBLOCK;
+ else
+ fdflags &= ~O_NONBLOCK;
+ if (fcntl(p->fd, F_SETFL, fdflags) == -1) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
+ pcap_strerror(errno));
+ return (-1);
+ }
+ return (0);
+}
+#endif
+
+#ifdef WIN32
+/*
+ * Generate a string for the last Win32-specific error (i.e. an error generated when
+ * calling a Win32 API).
+ * For errors occurred during standard C calls, we still use pcap_strerror()
+ */
+char *
+pcap_win32strerror(void)
+{
+ DWORD error;
+ static char errbuf[PCAP_ERRBUF_SIZE+1];
+ int errlen;
+ char *p;
+
+ error = GetLastError();
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
+ PCAP_ERRBUF_SIZE, NULL);
+
+ /*
+ * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
+ * message. Get rid of it.
+ */
+ errlen = strlen(errbuf);
+ if (errlen >= 2) {
+ errbuf[errlen - 1] = '\0';
+ errbuf[errlen - 2] = '\0';
+ }
+ p = strchr(errbuf, '\0');
+ snprintf (p, sizeof(errbuf)-(p-errbuf), " (%lu)", error);
+ return (errbuf);
+}
+#endif
+
+/*
+ * Generate error strings for PCAP_ERROR_ and PCAP_WARNING_ values.
+ */
+const char *
+pcap_statustostr(int errnum)
+{
+ static char ebuf[15+10+1];
+
+ switch (errnum) {
+
+ case PCAP_WARNING:
+ return("Generic warning");
+
+ case PCAP_WARNING_TSTAMP_TYPE_NOTSUP:
+ return ("That type of time stamp is not supported by that device");
+
+ case PCAP_WARNING_PROMISC_NOTSUP:
+ return ("That device doesn't support promiscuous mode");
+
+ case PCAP_ERROR:
+ return("Generic error");
+
+ case PCAP_ERROR_BREAK:
+ return("Loop terminated by pcap_breakloop");
+
+ case PCAP_ERROR_NOT_ACTIVATED:
+ return("The pcap_t has not been activated");
+
+ case PCAP_ERROR_ACTIVATED:
+ return ("The setting can't be changed after the pcap_t is activated");
+
+ case PCAP_ERROR_NO_SUCH_DEVICE:
+ return ("No such device exists");
+
+ case PCAP_ERROR_RFMON_NOTSUP:
+ return ("That device doesn't support monitor mode");
+
+ case PCAP_ERROR_NOT_RFMON:
+ return ("That operation is supported only in monitor mode");
+
+ case PCAP_ERROR_PERM_DENIED:
+ return ("You don't have permission to capture on that device");
+
+ case PCAP_ERROR_IFACE_NOT_UP:
+ return ("That device is not up");
+
+ case PCAP_ERROR_CANTSET_TSTAMP_TYPE:
+ return ("That device doesn't support setting the time stamp type");
+
+ case PCAP_ERROR_PROMISC_PERM_DENIED:
+ return ("You don't have permission to capture in promiscuous mode on that device");
+ }
+ (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
+ return(ebuf);
+}
+
+/*
+ * Not all systems have strerror().
+ */
+const char *
+pcap_strerror(int errnum)
+{
+#ifdef HAVE_STRERROR
+ return (strerror(errnum));
+#else
+ extern int sys_nerr;
+ extern const char *const sys_errlist[];
+ static char ebuf[15+10+1];
+
+ if ((unsigned int)errnum < sys_nerr)
+ return ((char *)sys_errlist[errnum]);
+ (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
+ return(ebuf);
+#endif
+}
+
+int
+pcap_setfilter(pcap_t *p, struct bpf_program *fp)
+{
+ return (p->setfilter_op(p, fp));
+}
+
+/*
+ * Set direction flag, which controls whether we accept only incoming
+ * packets, only outgoing packets, or both.
+ * Note that, depending on the platform, some or all direction arguments
+ * might not be supported.
+ */
+int
+pcap_setdirection(pcap_t *p, pcap_direction_t d)
+{
+ if (p->setdirection_op == NULL) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Setting direction is not implemented on this platform");
+ return (-1);
+ } else
+ return (p->setdirection_op(p, d));
+}
+
+int
+pcap_stats(pcap_t *p, struct pcap_stat *ps)
+{
+ return (p->stats_op(p, ps));
+}
+
+static int
+pcap_stats_dead(pcap_t *p, struct pcap_stat *ps _U_)
+{
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Statistics aren't available from a pcap_open_dead pcap_t");
+ return (-1);
+}
+
+#ifdef WIN32
+int
+pcap_setbuff(pcap_t *p, int dim)
+{
+ return (p->setbuff_op(p, dim));
+}
+
+static int
+pcap_setbuff_dead(pcap_t *p, int dim)
+{
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "The kernel buffer size cannot be set on a pcap_open_dead pcap_t");
+ return (-1);
+}
+
+int
+pcap_setmode(pcap_t *p, int mode)
+{
+ return (p->setmode_op(p, mode));
+}
+
+static int
+pcap_setmode_dead(pcap_t *p, int mode)
+{
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "impossible to set mode on a pcap_open_dead pcap_t");
+ return (-1);
+}
+
+int
+pcap_setmintocopy(pcap_t *p, int size)
+{
+ return (p->setmintocopy_op(p, size));
+}
+
+static int
+pcap_setmintocopy_dead(pcap_t *p, int size)
+{
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "The mintocopy parameter cannot be set on a pcap_open_dead pcap_t");
+ return (-1);
+}
+#endif
+
+/*
+ * On some platforms, we need to clean up promiscuous or monitor mode
+ * when we close a device - and we want that to happen even if the
+ * application just exits without explicitl closing devices.
+ * On those platforms, we need to register a "close all the pcaps"
+ * routine to be called when we exit, and need to maintain a list of
+ * pcaps that need to be closed to clean up modes.
+ *
+ * XXX - not thread-safe.
+ */
+
+/*
+ * List of pcaps on which we've done something that needs to be
+ * cleaned up.
+ * If there are any such pcaps, we arrange to call "pcap_close_all()"
+ * when we exit, and have it close all of them.
+ */
+static struct pcap *pcaps_to_close;
+
+/*
+ * TRUE if we've already called "atexit()" to cause "pcap_close_all()" to
+ * be called on exit.
+ */
+static int did_atexit;
+
+static void
+pcap_close_all(void)
+{
+ struct pcap *handle;
+
+ while ((handle = pcaps_to_close) != NULL)
+ pcap_close(handle);
+}
+
+int
+pcap_do_addexit(pcap_t *p)
+{
+ /*
+ * If we haven't already done so, arrange to have
+ * "pcap_close_all()" called when we exit.
+ */
+ if (!did_atexit) {
+ if (atexit(pcap_close_all) == -1) {
+ /*
+ * "atexit()" failed; let our caller know.
+ */
+ strncpy(p->errbuf, "atexit failed",
+ PCAP_ERRBUF_SIZE);
+ return (0);
+ }
+ did_atexit = 1;
+ }
+ return (1);
+}
+
+void
+pcap_add_to_pcaps_to_close(pcap_t *p)
+{
+ p->md.next = pcaps_to_close;
+ pcaps_to_close = p;
+}
+
+void
+pcap_remove_from_pcaps_to_close(pcap_t *p)
+{
+ pcap_t *pc, *prevpc;
+
+ for (pc = pcaps_to_close, prevpc = NULL; pc != NULL;
+ prevpc = pc, pc = pc->md.next) {
+ if (pc == p) {
+ /*
+ * Found it. Remove it from the list.
+ */
+ if (prevpc == NULL) {
+ /*
+ * It was at the head of the list.
+ */
+ pcaps_to_close = pc->md.next;
+ } else {
+ /*
+ * It was in the middle of the list.
+ */
+ prevpc->md.next = pc->md.next;
+ }
+ break;
+ }
+ }
+}
+
+void
+pcap_cleanup_live_common(pcap_t *p)
+{
+ if (p->buffer != NULL) {
+ free(p->buffer);
+ p->buffer = NULL;
+ }
+ if (p->dlt_list != NULL) {
+ free(p->dlt_list);
+ p->dlt_list = NULL;
+ p->dlt_count = 0;
+ }
+ if (p->tstamp_type_list != NULL) {
+ free(p->tstamp_type_list);
+ p->tstamp_type_list = NULL;
+ p->tstamp_type_count = 0;
+ }
+ pcap_freecode(&p->fcode);
+#if !defined(WIN32) && !defined(MSDOS)
+ if (p->fd >= 0) {
+ close(p->fd);
+ p->fd = -1;
+ }
+ p->selectable_fd = -1;
+ p->send_fd = -1;
+#endif
+}
+
+static void
+pcap_cleanup_dead(pcap_t *p _U_)
+{
+ /* Nothing to do. */
+}
+
+pcap_t *
+pcap_open_dead(int linktype, int snaplen)
+{
+ pcap_t *p;
+
+ p = malloc(sizeof(*p));
+ if (p == NULL)
+ return NULL;
+ memset (p, 0, sizeof(*p));
+ p->snapshot = snaplen;
+ p->linktype = linktype;
+ p->stats_op = pcap_stats_dead;
+#ifdef WIN32
+ p->setbuff_op = pcap_setbuff_dead;
+ p->setmode_op = pcap_setmode_dead;
+ p->setmintocopy_op = pcap_setmintocopy_dead;
+#endif
+ p->cleanup_op = pcap_cleanup_dead;
+ p->activated = 1;
+ return (p);
+}
+
+/*
+ * API compatible with WinPcap's "send a packet" routine - returns -1
+ * on error, 0 otherwise.
+ *
+ * XXX - what if we get a short write?
+ */
+int
+pcap_sendpacket(pcap_t *p, const u_char *buf, int size)
+{
+ if (p->inject_op(p, buf, size) == -1)
+ return (-1);
+ return (0);
+}
+
+/*
+ * API compatible with OpenBSD's "send a packet" routine - returns -1 on
+ * error, number of bytes written otherwise.
+ */
+int
+pcap_inject(pcap_t *p, const void *buf, size_t size)
+{
+ return (p->inject_op(p, buf, size));
+}
+
+void
+pcap_close(pcap_t *p)
+{
+ if (p->opt.source != NULL)
+ free(p->opt.source);
+ p->cleanup_op(p);
+ free(p);
+}
+
+/*
+ * Given a BPF program, a pcap_pkthdr structure for a packet, and the raw
+ * data for the packet, check whether the packet passes the filter.
+ * Returns the return value of the filter program, which will be zero if
+ * the packet doesn't pass and non-zero if the packet does pass.
+ */
+int
+pcap_offline_filter(const struct bpf_program *fp, const struct pcap_pkthdr *h,
+ const u_char *pkt)
+{
+ const struct bpf_insn *fcode = fp->bf_insns;
+
+ if (fcode != NULL)
+ return (bpf_filter(fcode, pkt, h->len, h->caplen));
+ else
+ return (0);
+}
+
+/*
+ * We make the version string static, and return a pointer to it, rather
+ * than exporting the version string directly. On at least some UNIXes,
+ * if you import data from a shared library into an program, the data is
+ * bound into the program binary, so if the string in the version of the
+ * library with which the program was linked isn't the same as the
+ * string in the version of the library with which the program is being
+ * run, various undesirable things may happen (warnings, the string
+ * being the one from the version of the library with which the program
+ * was linked, or even weirder things, such as the string being the one
+ * from the library but being truncated).
+ */
+#ifdef HAVE_VERSION_H
+#include "version.h"
+#else
+static const char pcap_version_string[] = "libpcap version 1.x.y";
+#endif
+
+#ifdef WIN32
+/*
+ * XXX - it'd be nice if we could somehow generate the WinPcap and libpcap
+ * version numbers when building WinPcap. (It'd be nice to do so for
+ * the packet.dll version number as well.)
+ */
+static const char wpcap_version_string[] = "4.0";
+static const char pcap_version_string_fmt[] =
+ "WinPcap version %s, based on %s";
+static const char pcap_version_string_packet_dll_fmt[] =
+ "WinPcap version %s (packet.dll version %s), based on %s";
+static char *full_pcap_version_string;
+
+const char *
+pcap_lib_version(void)
+{
+ char *packet_version_string;
+ size_t full_pcap_version_string_len;
+
+ if (full_pcap_version_string == NULL) {
+ /*
+ * Generate the version string.
+ */
+ packet_version_string = PacketGetVersion();
+ if (strcmp(wpcap_version_string, packet_version_string) == 0) {
+ /*
+ * WinPcap version string and packet.dll version
+ * string are the same; just report the WinPcap
+ * version.
+ */
+ full_pcap_version_string_len =
+ (sizeof pcap_version_string_fmt - 4) +
+ strlen(wpcap_version_string) +
+ strlen(pcap_version_string);
+ full_pcap_version_string =
+ malloc(full_pcap_version_string_len);
+ sprintf(full_pcap_version_string,
+ pcap_version_string_fmt, wpcap_version_string,
+ pcap_version_string);
+ } else {
+ /*
+ * WinPcap version string and packet.dll version
+ * string are different; that shouldn't be the
+ * case (the two libraries should come from the
+ * same version of WinPcap), so we report both
+ * versions.
+ */
+ full_pcap_version_string_len =
+ (sizeof pcap_version_string_packet_dll_fmt - 6) +
+ strlen(wpcap_version_string) +
+ strlen(packet_version_string) +
+ strlen(pcap_version_string);
+ full_pcap_version_string = malloc(full_pcap_version_string_len);
+
+ sprintf(full_pcap_version_string,
+ pcap_version_string_packet_dll_fmt,
+ wpcap_version_string, packet_version_string,
+ pcap_version_string);
+ }
+ }
+ return (full_pcap_version_string);
+}
+
+#elif defined(MSDOS)
+
+static char *full_pcap_version_string;
+
+const char *
+pcap_lib_version (void)
+{
+ char *packet_version_string;
+ size_t full_pcap_version_string_len;
+ static char dospfx[] = "DOS-";
+
+ if (full_pcap_version_string == NULL) {
+ /*
+ * Generate the version string.
+ */
+ full_pcap_version_string_len =
+ sizeof dospfx + strlen(pcap_version_string);
+ full_pcap_version_string =
+ malloc(full_pcap_version_string_len);
+ strcpy(full_pcap_version_string, dospfx);
+ strcat(full_pcap_version_string, pcap_version_string);
+ }
+ return (full_pcap_version_string);
+}
+
+#else /* UN*X */
+
+const char *
+pcap_lib_version(void)
+{
+ return (pcap_version_string);
+}
+#endif
diff --git a/freebsd/contrib/libpcap/pcap.h b/freebsd/contrib/libpcap/pcap.h
new file mode 100644
index 00000000..490a4bfb
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.59 2006-10-04 18:09:22 guy Exp $ (LBL)
+ */
+
+/*
+ * For backwards compatibility.
+ *
+ * Note to OS vendors: do NOT get rid of this file! Many applications
+ * expect to be able to include <pcap.h>, and at least some of them
+ * go through contortions in their configure scripts to try to detect
+ * OSes that have "helpfully" moved pcap.h to <pcap/pcap.h> without
+ * leaving behind a <pcap.h> file.
+ */
+#include <pcap/pcap.h>
diff --git a/freebsd/contrib/libpcap/pcap/ipnet.h b/freebsd/contrib/libpcap/pcap/ipnet.h
new file mode 100644
index 00000000..53308470
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap/ipnet.h
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from the Stanford/CMU enet packet filter,
+ * (net/enet.c) distributed as part of 4.3BSD, and code contributed
+ * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
+ * Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define IPH_AF_INET 2 /* Matches Solaris's AF_INET */
+#define IPH_AF_INET6 26 /* Matches Solaris's AF_INET6 */
+
+#define IPNET_OUTBOUND 1
+#define IPNET_INBOUND 2
diff --git a/freebsd/contrib/libpcap/pcap/namedb.h b/freebsd/contrib/libpcap/pcap/namedb.h
new file mode 100644
index 00000000..e3145579
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap/namedb.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1994, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/pcap/namedb.h,v 1.1 2006-10-04 18:09:22 guy Exp $ (LBL)
+ */
+
+#ifndef lib_pcap_namedb_h
+#define lib_pcap_namedb_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * As returned by the pcap_next_etherent()
+ * XXX this stuff doesn't belong in this interface, but this
+ * library already must do name to address translation, so
+ * on systems that don't have support for /etc/ethers, we
+ * export these hooks since they'll
+ */
+struct pcap_etherent {
+ u_char addr[6];
+ char name[122];
+};
+#ifndef PCAP_ETHERS_FILE
+#define PCAP_ETHERS_FILE "/etc/ethers"
+#endif
+struct pcap_etherent *pcap_next_etherent(FILE *);
+u_char *pcap_ether_hostton(const char*);
+u_char *pcap_ether_aton(const char *);
+
+bpf_u_int32 **pcap_nametoaddr(const char *);
+#ifdef INET6
+struct addrinfo *pcap_nametoaddrinfo(const char *);
+#endif
+bpf_u_int32 pcap_nametonetaddr(const char *);
+
+int pcap_nametoport(const char *, int *, int *);
+int pcap_nametoportrange(const char *, int *, int *, int *);
+int pcap_nametoproto(const char *);
+int pcap_nametoeproto(const char *);
+int pcap_nametollc(const char *);
+/*
+ * If a protocol is unknown, PROTO_UNDEF is returned.
+ * Also, pcap_nametoport() returns the protocol along with the port number.
+ * If there are ambiguous entried in /etc/services (i.e. domain
+ * can be either tcp or udp) PROTO_UNDEF is returned.
+ */
+#define PROTO_UNDEF -1
+
+/* XXX move these to pcap-int.h? */
+int __pcap_atodn(const char *, bpf_u_int32 *);
+int __pcap_atoin(const char *, bpf_u_int32 *);
+u_short __pcap_nametodnaddr(const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/freebsd/contrib/libpcap/pcap/pcap.h b/freebsd/contrib/libpcap/pcap/pcap.h
new file mode 100644
index 00000000..60bb36e5
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap/pcap.h
@@ -0,0 +1,461 @@
+/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.15 2008-10-06 15:27:32 gianluca Exp $ (LBL)
+ */
+
+#ifndef lib_pcap_pcap_h
+#define lib_pcap_pcap_h
+
+#if defined(WIN32)
+ #include <pcap-stdinc.h>
+#elif defined(MSDOS)
+ #include <rtems/bsd/sys/types.h>
+ #include <sys/socket.h> /* u_int, u_char etc. */
+#else /* UN*X */
+ #include <rtems/bsd/sys/types.h>
+ #include <rtems/bsd/sys/time.h>
+#endif /* WIN32/MSDOS/UN*X */
+
+#include <net/bpf.h>
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Version number of the current version of the pcap file format.
+ *
+ * NOTE: this is *NOT* the version number of the libpcap library.
+ * To fetch the version information for the version of libpcap
+ * you're using, use pcap_lib_version().
+ */
+#define PCAP_VERSION_MAJOR 2
+#define PCAP_VERSION_MINOR 4
+
+#define PCAP_ERRBUF_SIZE 256
+
+/*
+ * Compatibility for systems that have a bpf.h that
+ * predates the bpf typedefs for 64-bit support.
+ */
+#if BPF_RELEASE - 0 < 199406
+typedef int bpf_int32;
+typedef u_int bpf_u_int32;
+#endif
+
+typedef struct pcap pcap_t;
+typedef struct pcap_dumper pcap_dumper_t;
+typedef struct pcap_if pcap_if_t;
+typedef struct pcap_addr pcap_addr_t;
+
+/*
+ * The first record in the file contains saved values for some
+ * of the flags used in the printout phases of tcpdump.
+ * Many fields here are 32 bit ints so compilers won't insert unwanted
+ * padding; these files need to be interchangeable across architectures.
+ *
+ * Do not change the layout of this structure, in any way (this includes
+ * changes that only affect the length of fields in this structure).
+ *
+ * Also, do not change the interpretation of any of the members of this
+ * structure, in any way (this includes using values other than
+ * LINKTYPE_ values, as defined in "savefile.c", in the "linktype"
+ * field).
+ *
+ * Instead:
+ *
+ * introduce a new structure for the new format, if the layout
+ * of the structure changed;
+ *
+ * send mail to "tcpdump-workers@lists.tcpdump.org", requesting
+ * a new magic number for your new capture file format, and, when
+ * you get the new magic number, put it in "savefile.c";
+ *
+ * use that magic number for save files with the changed file
+ * header;
+ *
+ * make the code in "savefile.c" capable of reading files with
+ * the old file header as well as files with the new file header
+ * (using the magic number to determine the header format).
+ *
+ * Then supply the changes by forking the branch at
+ *
+ * https://github.com/mcr/libpcap/issues
+ *
+ * and issuing a pull request, so that future versions of libpcap and
+ * programs that use it (such as tcpdump) will be able to read your new
+ * capture file format.
+ */
+struct pcap_file_header {
+ bpf_u_int32 magic;
+ u_short version_major;
+ u_short version_minor;
+ bpf_int32 thiszone; /* gmt to local correction */
+ bpf_u_int32 sigfigs; /* accuracy of timestamps */
+ bpf_u_int32 snaplen; /* max length saved portion of each pkt */
+ bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
+};
+
+/*
+ * Macros for the value returned by pcap_datalink_ext().
+ *
+ * If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro
+ * gives the FCS length of packets in the capture.
+ */
+#define LT_FCS_LENGTH_PRESENT(x) ((x) & 0x04000000)
+#define LT_FCS_LENGTH(x) (((x) & 0xF0000000) >> 28)
+#define LT_FCS_DATALINK_EXT(x) ((((x) & 0xF) << 28) | 0x04000000)
+
+typedef enum {
+ PCAP_D_INOUT = 0,
+ PCAP_D_IN,
+ PCAP_D_OUT
+} pcap_direction_t;
+
+/*
+ * Generic per-packet information, as supplied by libpcap.
+ *
+ * The time stamp can and should be a "struct timeval", regardless of
+ * whether your system supports 32-bit tv_sec in "struct timeval",
+ * 64-bit tv_sec in "struct timeval", or both if it supports both 32-bit
+ * and 64-bit applications. The on-disk format of savefiles uses 32-bit
+ * tv_sec (and tv_usec); this structure is irrelevant to that. 32-bit
+ * and 64-bit versions of libpcap, even if they're on the same platform,
+ * should supply the appropriate version of "struct timeval", even if
+ * that's not what the underlying packet capture mechanism supplies.
+ */
+struct pcap_pkthdr {
+ struct timeval ts; /* time stamp */
+ bpf_u_int32 caplen; /* length of portion present */
+ bpf_u_int32 len; /* length this packet (off wire) */
+};
+
+/*
+ * As returned by the pcap_stats()
+ */
+struct pcap_stat {
+ u_int ps_recv; /* number of packets received */
+ u_int ps_drop; /* number of packets dropped */
+ u_int ps_ifdrop; /* drops by interface -- only supported on some platforms */
+#ifdef WIN32
+ u_int bs_capt; /* number of packets that reach the application */
+#endif /* WIN32 */
+};
+
+#ifdef MSDOS
+/*
+ * As returned by the pcap_stats_ex()
+ */
+struct pcap_stat_ex {
+ u_long rx_packets; /* total packets received */
+ u_long tx_packets; /* total packets transmitted */
+ u_long rx_bytes; /* total bytes received */
+ u_long tx_bytes; /* total bytes transmitted */
+ u_long rx_errors; /* bad packets received */
+ u_long tx_errors; /* packet transmit problems */
+ u_long rx_dropped; /* no space in Rx buffers */
+ u_long tx_dropped; /* no space available for Tx */
+ u_long multicast; /* multicast packets received */
+ u_long collisions;
+
+ /* detailed rx_errors: */
+ u_long rx_length_errors;
+ u_long rx_over_errors; /* receiver ring buff overflow */
+ u_long rx_crc_errors; /* recv'd pkt with crc error */
+ u_long rx_frame_errors; /* recv'd frame alignment error */
+ u_long rx_fifo_errors; /* recv'r fifo overrun */
+ u_long rx_missed_errors; /* recv'r missed packet */
+
+ /* detailed tx_errors */
+ u_long tx_aborted_errors;
+ u_long tx_carrier_errors;
+ u_long tx_fifo_errors;
+ u_long tx_heartbeat_errors;
+ u_long tx_window_errors;
+ };
+#endif
+
+/*
+ * Item in a list of interfaces.
+ */
+struct pcap_if {
+ struct pcap_if *next;
+ char *name; /* name to hand to "pcap_open_live()" */
+ char *description; /* textual description of interface, or NULL */
+ struct pcap_addr *addresses;
+ bpf_u_int32 flags; /* PCAP_IF_ interface flags */
+};
+
+#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */
+
+/*
+ * Representation of an interface address.
+ */
+struct pcap_addr {
+ struct pcap_addr *next;
+ struct sockaddr *addr; /* address */
+ struct sockaddr *netmask; /* netmask for that address */
+ struct sockaddr *broadaddr; /* broadcast address for that address */
+ struct sockaddr *dstaddr; /* P2P destination address for that address */
+};
+
+typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
+ const u_char *);
+
+/*
+ * Error codes for the pcap API.
+ * These will all be negative, so you can check for the success or
+ * failure of a call that returns these codes by checking for a
+ * negative value.
+ */
+#define PCAP_ERROR -1 /* generic error code */
+#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */
+#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */
+#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */
+#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */
+#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */
+#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */
+#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */
+#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */
+#define PCAP_ERROR_CANTSET_TSTAMP_TYPE -10 /* this device doesn't support setting the time stamp type */
+#define PCAP_ERROR_PROMISC_PERM_DENIED -11 /* you don't have permission to capture in promiscuous mode */
+
+/*
+ * Warning codes for the pcap API.
+ * These will all be positive and non-zero, so they won't look like
+ * errors.
+ */
+#define PCAP_WARNING 1 /* generic warning code */
+#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */
+#define PCAP_WARNING_TSTAMP_TYPE_NOTSUP 3 /* the requested time stamp type is not supported */
+
+/*
+ * Value to pass to pcap_compile() as the netmask if you don't know what
+ * the netmask is.
+ */
+#define PCAP_NETMASK_UNKNOWN 0xffffffff
+
+char *pcap_lookupdev(char *);
+int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
+
+pcap_t *pcap_create(const char *, char *);
+int pcap_set_snaplen(pcap_t *, int);
+int pcap_set_promisc(pcap_t *, int);
+int pcap_can_set_rfmon(pcap_t *);
+int pcap_set_rfmon(pcap_t *, int);
+int pcap_set_timeout(pcap_t *, int);
+int pcap_set_tstamp_type(pcap_t *, int);
+int pcap_set_buffer_size(pcap_t *, int);
+int pcap_activate(pcap_t *);
+
+int pcap_list_tstamp_types(pcap_t *, int **);
+void pcap_free_tstamp_types(int *);
+int pcap_tstamp_type_name_to_val(const char *);
+const char *pcap_tstamp_type_val_to_name(int);
+const char *pcap_tstamp_type_val_to_description(int);
+
+/*
+ * Time stamp types.
+ * Not all systems and interfaces will necessarily support all of these.
+ *
+ * A system that supports PCAP_TSTAMP_HOST is offering time stamps
+ * provided by the host machine, rather than by the capture device,
+ * but not committing to any characteristics of the time stamp;
+ * it will not offer any of the PCAP_TSTAMP_HOST_ subtypes.
+ *
+ * PCAP_TSTAMP_HOST_LOWPREC is a time stamp, provided by the host machine,
+ * that's low-precision but relatively cheap to fetch; it's normally done
+ * using the system clock, so it's normally synchronized with times you'd
+ * fetch from system calls.
+ *
+ * PCAP_TSTAMP_HOST_HIPREC is a time stamp, provided by the host machine,
+ * that's high-precision; it might be more expensive to fetch. It might
+ * or might not be synchronized with the system clock, and might have
+ * problems with time stamps for packets received on different CPUs,
+ * depending on the platform.
+ *
+ * PCAP_TSTAMP_ADAPTER is a high-precision time stamp supplied by the
+ * capture device; it's synchronized with the system clock.
+ *
+ * PCAP_TSTAMP_ADAPTER_UNSYNCED is a high-precision time stamp supplied by
+ * the capture device; it's not synchronized with the system clock.
+ *
+ * Note that time stamps synchronized with the system clock can go
+ * backwards, as the system clock can go backwards. If a clock is
+ * not in sync with the system clock, that could be because the
+ * system clock isn't keeping accurate time, because the other
+ * clock isn't keeping accurate time, or both.
+ *
+ * Note that host-provided time stamps generally correspond to the
+ * time when the time-stamping code sees the packet; this could
+ * be some unknown amount of time after the first or last bit of
+ * the packet is received by the network adapter, due to batching
+ * of interrupts for packet arrival, queueing delays, etc..
+ */
+#define PCAP_TSTAMP_HOST 0 /* host-provided, unknown characteristics */
+#define PCAP_TSTAMP_HOST_LOWPREC 1 /* host-provided, low precision */
+#define PCAP_TSTAMP_HOST_HIPREC 2 /* host-provided, high precision */
+#define PCAP_TSTAMP_ADAPTER 3 /* device-provided, synced with the system clock */
+#define PCAP_TSTAMP_ADAPTER_UNSYNCED 4 /* device-provided, not synced with the system clock */
+
+pcap_t *pcap_open_live(const char *, int, int, int, char *);
+pcap_t *pcap_open_dead(int, int);
+pcap_t *pcap_open_offline(const char *, char *);
+#if defined(WIN32)
+pcap_t *pcap_hopen_offline(intptr_t, char *);
+#if !defined(LIBPCAP_EXPORTS)
+#define pcap_fopen_offline(f,b) \
+ pcap_hopen_offline(_get_osfhandle(_fileno(f)), b)
+#else /*LIBPCAP_EXPORTS*/
+static pcap_t *pcap_fopen_offline(FILE *, char *);
+#endif
+#else /*WIN32*/
+pcap_t *pcap_fopen_offline(FILE *, char *);
+#endif /*WIN32*/
+
+void pcap_close(pcap_t *);
+int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
+int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
+const u_char*
+ pcap_next(pcap_t *, struct pcap_pkthdr *);
+int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **);
+void pcap_breakloop(pcap_t *);
+int pcap_stats(pcap_t *, struct pcap_stat *);
+int pcap_setfilter(pcap_t *, struct bpf_program *);
+int pcap_setdirection(pcap_t *, pcap_direction_t);
+int pcap_getnonblock(pcap_t *, char *);
+int pcap_setnonblock(pcap_t *, int, char *);
+int pcap_inject(pcap_t *, const void *, size_t);
+int pcap_sendpacket(pcap_t *, const u_char *, int);
+const char *pcap_statustostr(int);
+const char *pcap_strerror(int);
+char *pcap_geterr(pcap_t *);
+void pcap_perror(pcap_t *, char *);
+int pcap_compile(pcap_t *, struct bpf_program *, const char *, int,
+ bpf_u_int32);
+int pcap_compile_nopcap(int, int, struct bpf_program *,
+ const char *, int, bpf_u_int32);
+void pcap_freecode(struct bpf_program *);
+int pcap_offline_filter(const struct bpf_program *,
+ const struct pcap_pkthdr *, const u_char *);
+int pcap_datalink(pcap_t *);
+int pcap_datalink_ext(pcap_t *);
+int pcap_list_datalinks(pcap_t *, int **);
+int pcap_set_datalink(pcap_t *, int);
+void pcap_free_datalinks(int *);
+int pcap_datalink_name_to_val(const char *);
+const char *pcap_datalink_val_to_name(int);
+const char *pcap_datalink_val_to_description(int);
+int pcap_snapshot(pcap_t *);
+int pcap_is_swapped(pcap_t *);
+int pcap_major_version(pcap_t *);
+int pcap_minor_version(pcap_t *);
+
+/* XXX */
+FILE *pcap_file(pcap_t *);
+int pcap_fileno(pcap_t *);
+
+pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
+pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
+FILE *pcap_dump_file(pcap_dumper_t *);
+long pcap_dump_ftell(pcap_dumper_t *);
+int pcap_dump_flush(pcap_dumper_t *);
+void pcap_dump_close(pcap_dumper_t *);
+void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
+
+int pcap_findalldevs(pcap_if_t **, char *);
+void pcap_freealldevs(pcap_if_t *);
+
+const char *pcap_lib_version(void);
+
+/*
+ * On at least some versions of NetBSD, we don't want to declare
+ * bpf_filter() here, as it's also be declared in <net/bpf.h>, with a
+ * different signature, but, on other BSD-flavored UN*Xes, it's not
+ * declared in <net/bpf.h>, so we *do* want to declare it here, so it's
+ * declared when we build pcap-bpf.c.
+ */
+#ifndef __NetBSD__
+u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
+#endif
+int bpf_validate(const struct bpf_insn *f, int len);
+char *bpf_image(struct bpf_insn *, int);
+void bpf_dump(const struct bpf_program *, int);
+
+#if defined(WIN32)
+
+/*
+ * Win32 definitions
+ */
+
+int pcap_setbuff(pcap_t *p, int dim);
+int pcap_setmode(pcap_t *p, int mode);
+int pcap_setmintocopy(pcap_t *p, int size);
+
+#ifdef WPCAP
+/* Include file with the wpcap-specific extensions */
+#include <Win32-Extensions.h>
+#endif /* WPCAP */
+
+#define MODE_CAPT 0
+#define MODE_STAT 1
+#define MODE_MON 2
+
+#elif defined(MSDOS)
+
+/*
+ * MS-DOS definitions
+ */
+
+int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *);
+void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait);
+u_long pcap_mac_packets (void);
+
+#else /* UN*X */
+
+/*
+ * UN*X definitions
+ */
+
+int pcap_get_selectable_fd(pcap_t *);
+
+#endif /* WIN32/MSDOS/UN*X */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* lib_pcap_pcap_h */
diff --git a/freebsd/contrib/libpcap/pcap/sll.h b/freebsd/contrib/libpcap/pcap/sll.h
new file mode 100644
index 00000000..7ad811d7
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap/sll.h
@@ -0,0 +1,129 @@
+/*-
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from the Stanford/CMU enet packet filter,
+ * (net/enet.c) distributed as part of 4.3BSD, and code contributed
+ * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
+ * Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/pcap/sll.h,v 1.3 2008-05-30 01:35:33 guy Exp $ (LBL)
+ */
+
+/*
+ * For captures on Linux cooked sockets, we construct a fake header
+ * that includes:
+ *
+ * a 2-byte "packet type" which is one of:
+ *
+ * LINUX_SLL_HOST packet was sent to us
+ * LINUX_SLL_BROADCAST packet was broadcast
+ * LINUX_SLL_MULTICAST packet was multicast
+ * LINUX_SLL_OTHERHOST packet was sent to somebody else
+ * LINUX_SLL_OUTGOING packet was sent *by* us;
+ *
+ * a 2-byte Ethernet protocol field;
+ *
+ * a 2-byte link-layer type;
+ *
+ * a 2-byte link-layer address length;
+ *
+ * an 8-byte source link-layer address, whose actual length is
+ * specified by the previous value.
+ *
+ * All fields except for the link-layer address are in network byte order.
+ *
+ * DO NOT change the layout of this structure, or change any of the
+ * LINUX_SLL_ values below. If you must change the link-layer header
+ * for a "cooked" Linux capture, introduce a new DLT_ type (ask
+ * "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it
+ * a value that collides with a value already being used), and use the
+ * new header in captures of that type, so that programs that can
+ * handle DLT_LINUX_SLL captures will continue to handle them correctly
+ * without any change, and so that capture files with different headers
+ * can be told apart and programs that read them can dissect the
+ * packets in them.
+ */
+
+#ifndef lib_pcap_sll_h
+#define lib_pcap_sll_h
+
+/*
+ * A DLT_LINUX_SLL fake link-layer header.
+ */
+#define SLL_HDR_LEN 16 /* total header length */
+#define SLL_ADDRLEN 8 /* length of address field */
+
+struct sll_header {
+ u_int16_t sll_pkttype; /* packet type */
+ u_int16_t sll_hatype; /* link-layer address type */
+ u_int16_t sll_halen; /* link-layer address length */
+ u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
+ u_int16_t sll_protocol; /* protocol */
+};
+
+/*
+ * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
+ * PACKET_ values on Linux, but are defined here so that they're
+ * available even on systems other than Linux, and so that they
+ * don't change even if the PACKET_ values change.
+ */
+#define LINUX_SLL_HOST 0
+#define LINUX_SLL_BROADCAST 1
+#define LINUX_SLL_MULTICAST 2
+#define LINUX_SLL_OTHERHOST 3
+#define LINUX_SLL_OUTGOING 4
+
+/*
+ * The LINUX_SLL_ values for "sll_protocol"; these correspond to the
+ * ETH_P_ values on Linux, but are defined here so that they're
+ * available even on systems other than Linux. We assume, for now,
+ * that the ETH_P_ values won't change in Linux; if they do, then:
+ *
+ * if we don't translate them in "pcap-linux.c", capture files
+ * won't necessarily be readable if captured on a system that
+ * defines ETH_P_ values that don't match these values;
+ *
+ * if we do translate them in "pcap-linux.c", that makes life
+ * unpleasant for the BPF code generator, as the values you test
+ * for in the kernel aren't the values that you test for when
+ * reading a capture file, so the fixup code run on BPF programs
+ * handed to the kernel ends up having to do more work.
+ *
+ * Add other values here as necessary, for handling packet types that
+ * might show up on non-Ethernet, non-802.x networks. (Not all the ones
+ * in the Linux "if_ether.h" will, I suspect, actually show up in
+ * captures.)
+ */
+#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */
+#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */
+
+#endif
diff --git a/freebsd/contrib/libpcap/pcap/usb.h b/freebsd/contrib/libpcap/pcap/usb.h
new file mode 100644
index 00000000..aa351225
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap/usb.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2006 Paolo Abeni (Italy)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Basic USB data struct
+ * By Paolo Abeni <paolo.abeni@email.it>
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/pcap/usb.h,v 1.9 2008-12-23 20:13:29 guy Exp $
+ */
+
+#ifndef _PCAP_USB_STRUCTS_H__
+#define _PCAP_USB_STRUCTS_H__
+
+/*
+ * possible transfer mode
+ */
+#define URB_TRANSFER_IN 0x80
+#define URB_ISOCHRONOUS 0x0
+#define URB_INTERRUPT 0x1
+#define URB_CONTROL 0x2
+#define URB_BULK 0x3
+
+/*
+ * possible event type
+ */
+#define URB_SUBMIT 'S'
+#define URB_COMPLETE 'C'
+#define URB_ERROR 'E'
+
+/*
+ * USB setup header as defined in USB specification.
+ * Appears at the front of each Control S-type packet in DLT_USB captures.
+ */
+typedef struct _usb_setup {
+ u_int8_t bmRequestType;
+ u_int8_t bRequest;
+ u_int16_t wValue;
+ u_int16_t wIndex;
+ u_int16_t wLength;
+} pcap_usb_setup;
+
+/*
+ * Information from the URB for Isochronous transfers.
+ */
+typedef struct _iso_rec {
+ int32_t error_count;
+ int32_t numdesc;
+} iso_rec;
+
+/*
+ * Header prepended by linux kernel to each event.
+ * Appears at the front of each packet in DLT_USB_LINUX captures.
+ */
+typedef struct _usb_header {
+ u_int64_t id;
+ u_int8_t event_type;
+ u_int8_t transfer_type;
+ u_int8_t endpoint_number;
+ u_int8_t device_address;
+ u_int16_t bus_id;
+ char setup_flag;/*if !=0 the urb setup header is not present*/
+ char data_flag; /*if !=0 no urb data is present*/
+ int64_t ts_sec;
+ int32_t ts_usec;
+ int32_t status;
+ u_int32_t urb_len;
+ u_int32_t data_len; /* amount of urb data really present in this event*/
+ pcap_usb_setup setup;
+} pcap_usb_header;
+
+/*
+ * Header prepended by linux kernel to each event for the 2.6.31
+ * and later kernels; for the 2.6.21 through 2.6.30 kernels, the
+ * "iso_rec" information, and the fields starting with "interval"
+ * are zeroed-out padding fields.
+ *
+ * Appears at the front of each packet in DLT_USB_LINUX_MMAPPED captures.
+ */
+typedef struct _usb_header_mmapped {
+ u_int64_t id;
+ u_int8_t event_type;
+ u_int8_t transfer_type;
+ u_int8_t endpoint_number;
+ u_int8_t device_address;
+ u_int16_t bus_id;
+ char setup_flag;/*if !=0 the urb setup header is not present*/
+ char data_flag; /*if !=0 no urb data is present*/
+ int64_t ts_sec;
+ int32_t ts_usec;
+ int32_t status;
+ u_int32_t urb_len;
+ u_int32_t data_len; /* amount of urb data really present in this event*/
+ union {
+ pcap_usb_setup setup;
+ iso_rec iso;
+ } s;
+ int32_t interval; /* for Interrupt and Isochronous events */
+ int32_t start_frame; /* for Isochronous events */
+ u_int32_t xfer_flags; /* copy of URB's transfer flags */
+ u_int32_t ndesc; /* number of isochronous descriptors */
+} pcap_usb_header_mmapped;
+
+/*
+ * Isochronous descriptors; for isochronous transfers there might be
+ * one or more of these at the beginning of the packet data. The
+ * number of descriptors is given by the "ndesc" field in the header;
+ * as indicated, in older kernels that don't put the descriptors at
+ * the beginning of the packet, that field is zeroed out, so that field
+ * can be trusted even in captures from older kernels.
+ */
+typedef struct _usb_isodesc {
+ int32_t status;
+ u_int32_t offset;
+ u_int32_t len;
+ u_int8_t pad[4];
+} usb_isodesc;
+
+#endif
diff --git a/freebsd/contrib/libpcap/ppp.h b/freebsd/contrib/libpcap/ppp.h
new file mode 100644
index 00000000..4e1d08de
--- /dev/null
+++ b/freebsd/contrib/libpcap/ppp.h
@@ -0,0 +1,58 @@
+/* @(#) $Header: /tcpdump/master/libpcap/ppp.h,v 1.12 2005-02-08 19:52:19 guy Exp $ (LBL) */
+/*
+ * Point to Point Protocol (PPP) RFC1331
+ *
+ * Copyright 1989 by Carnegie Mellon.
+ *
+ * Permission to use, copy, modify, and distribute this program for any
+ * purpose and without fee is hereby granted, provided that this copyright
+ * and permission notice appear on all copies and supporting documentation,
+ * the name of Carnegie Mellon not be used in advertising or publicity
+ * pertaining to distribution of the program without specific prior
+ * permission, and notice be given in supporting documentation that copying
+ * and distribution is by permission of Carnegie Mellon and Stanford
+ * University. Carnegie Mellon makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+#define PPP_ADDRESS 0xff /* The address byte value */
+#define PPP_CONTROL 0x03 /* The control byte value */
+
+#define PPP_PPPD_IN 0x00 /* non-standard for DLT_PPP_PPPD */
+#define PPP_PPPD_OUT 0x01 /* non-standard for DLT_PPP_PPPD */
+
+/* Protocol numbers */
+#define PPP_IP 0x0021 /* Raw IP */
+#define PPP_OSI 0x0023 /* OSI Network Layer */
+#define PPP_NS 0x0025 /* Xerox NS IDP */
+#define PPP_DECNET 0x0027 /* DECnet Phase IV */
+#define PPP_APPLE 0x0029 /* Appletalk */
+#define PPP_IPX 0x002b /* Novell IPX */
+#define PPP_VJC 0x002d /* Van Jacobson Compressed TCP/IP */
+#define PPP_VJNC 0x002f /* Van Jacobson Uncompressed TCP/IP */
+#define PPP_BRPDU 0x0031 /* Bridging PDU */
+#define PPP_STII 0x0033 /* Stream Protocol (ST-II) */
+#define PPP_VINES 0x0035 /* Banyan Vines */
+#define PPP_IPV6 0x0057 /* Internet Protocol version 6 */
+
+#define PPP_HELLO 0x0201 /* 802.1d Hello Packets */
+#define PPP_LUXCOM 0x0231 /* Luxcom */
+#define PPP_SNS 0x0233 /* Sigma Network Systems */
+#define PPP_MPLS_UCAST 0x0281 /* rfc 3032 */
+#define PPP_MPLS_MCAST 0x0283 /* rfc 3022 */
+
+#define PPP_IPCP 0x8021 /* IP Control Protocol */
+#define PPP_OSICP 0x8023 /* OSI Network Layer Control Protocol */
+#define PPP_NSCP 0x8025 /* Xerox NS IDP Control Protocol */
+#define PPP_DECNETCP 0x8027 /* DECnet Control Protocol */
+#define PPP_APPLECP 0x8029 /* Appletalk Control Protocol */
+#define PPP_IPXCP 0x802b /* Novell IPX Control Protocol */
+#define PPP_STIICP 0x8033 /* Strean Protocol Control Protocol */
+#define PPP_VINESCP 0x8035 /* Banyan Vines Control Protocol */
+#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */
+#define PPP_MPLSCP 0x8281 /* rfc 3022 */
+
+#define PPP_LCP 0xc021 /* Link Control Protocol */
+#define PPP_PAP 0xc023 /* Password Authentication Protocol */
+#define PPP_LQM 0xc025 /* Link Quality Monitoring */
+#define PPP_CHAP 0xc223 /* Challenge Handshake Authentication Protocol */
diff --git a/freebsd/contrib/libpcap/savefile.c b/freebsd/contrib/libpcap/savefile.c
new file mode 100644
index 00000000..cf22f22a
--- /dev/null
+++ b/freebsd/contrib/libpcap/savefile.c
@@ -0,0 +1,396 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * savefile.c - supports offline use of tcpdump
+ * Extraction/creation by Jeffrey Mogul, DECWRL
+ * Modified by Steve McCanne, LBL.
+ *
+ * Used to save the received packet headers, after filtering, to
+ * a file, and then read them later.
+ * The first record in the file contains saved values for the machine
+ * dependent values so we can print the dump file on any architecture.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.183 2008-12-23 20:13:29 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/types.h>
+#endif /* WIN32 */
+
+#include <errno.h>
+#include <memory.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pcap-int.h"
+#include "pcap/usb.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "sf-pcap.h"
+#include "sf-pcap-ng.h"
+
+/*
+ * Setting O_BINARY on DOS/Windows is a bit tricky
+ */
+#if defined(WIN32)
+ #define SET_BINMODE(f) _setmode(_fileno(f), _O_BINARY)
+#elif defined(MSDOS)
+ #if defined(__HIGHC__)
+ #define SET_BINMODE(f) setmode(f, O_BINARY)
+ #else
+ #define SET_BINMODE(f) setmode(fileno(f), O_BINARY)
+ #endif
+#endif
+
+static int
+sf_getnonblock(pcap_t *p, char *errbuf)
+{
+ /*
+ * This is a savefile, not a live capture file, so never say
+ * it's in non-blocking mode.
+ */
+ return (0);
+}
+
+static int
+sf_setnonblock(pcap_t *p, int nonblock, char *errbuf)
+{
+ /*
+ * This is a savefile, not a live capture file, so reject
+ * requests to put it in non-blocking mode. (If it's a
+ * pipe, it could be put in non-blocking mode, but that
+ * would significantly complicate the code to read packets,
+ * as it would have to handle reading partial packets and
+ * keeping the state of the read.)
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Savefiles cannot be put into non-blocking mode");
+ return (-1);
+}
+
+static int
+sf_stats(pcap_t *p, struct pcap_stat *ps)
+{
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Statistics aren't available from savefiles");
+ return (-1);
+}
+
+#ifdef WIN32
+static int
+sf_setbuff(pcap_t *p, int dim)
+{
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "The kernel buffer size cannot be set while reading from a file");
+ return (-1);
+}
+
+static int
+sf_setmode(pcap_t *p, int mode)
+{
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "impossible to set mode while reading from a file");
+ return (-1);
+}
+
+static int
+sf_setmintocopy(pcap_t *p, int size)
+{
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "The mintocopy parameter cannot be set while reading from a file");
+ return (-1);
+}
+#endif
+
+static int
+sf_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
+{
+ strlcpy(p->errbuf, "Sending packets isn't supported on savefiles",
+ PCAP_ERRBUF_SIZE);
+ return (-1);
+}
+
+/*
+ * Set direction flag: Which packets do we accept on a forwarding
+ * single device? IN, OUT or both?
+ */
+static int
+sf_setdirection(pcap_t *p, pcap_direction_t d)
+{
+ snprintf(p->errbuf, sizeof(p->errbuf),
+ "Setting direction is not supported on savefiles");
+ return (-1);
+}
+
+static void
+sf_cleanup(pcap_t *p)
+{
+ if (p->sf.rfile != stdin)
+ (void)fclose(p->sf.rfile);
+ if (p->buffer != NULL)
+ free(p->buffer);
+ pcap_freecode(&p->fcode);
+}
+
+pcap_t *
+pcap_open_offline(const char *fname, char *errbuf)
+{
+ FILE *fp;
+ pcap_t *p;
+
+ if (fname[0] == '-' && fname[1] == '\0')
+ {
+ fp = stdin;
+#if defined(WIN32) || defined(MSDOS)
+ /*
+ * We're reading from the standard input, so put it in binary
+ * mode, as savefiles are binary files.
+ */
+ SET_BINMODE(fp);
+#endif
+ }
+ else {
+#if !defined(WIN32) && !defined(MSDOS)
+ fp = fopen(fname, "r");
+#else
+ fp = fopen(fname, "rb");
+#endif
+ if (fp == NULL) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname,
+ pcap_strerror(errno));
+ return (NULL);
+ }
+ }
+ p = pcap_fopen_offline(fp, errbuf);
+ if (p == NULL) {
+ if (fp != stdin)
+ fclose(fp);
+ }
+ return (p);
+}
+
+#ifdef WIN32
+pcap_t* pcap_hopen_offline(intptr_t osfd, char *errbuf)
+{
+ int fd;
+ FILE *file;
+
+ fd = _open_osfhandle(osfd, _O_RDONLY);
+ if ( fd < 0 )
+ {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, pcap_strerror(errno));
+ return NULL;
+ }
+
+ file = _fdopen(fd, "rb");
+ if ( file == NULL )
+ {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, pcap_strerror(errno));
+ return NULL;
+ }
+
+ return pcap_fopen_offline(file, errbuf);
+}
+#endif
+
+static int (*check_headers[])(pcap_t *, bpf_u_int32, FILE *, char *) = {
+ pcap_check_header,
+ pcap_ng_check_header
+};
+
+#define N_FILE_TYPES (sizeof check_headers / sizeof check_headers[0])
+
+#ifdef WIN32
+static
+#endif
+pcap_t *
+pcap_fopen_offline(FILE *fp, char *errbuf)
+{
+ register pcap_t *p;
+ bpf_u_int32 magic;
+ size_t amt_read;
+ u_int i;
+
+ p = pcap_create_common("(savefile)", errbuf);
+ if (p == NULL)
+ return (NULL);
+
+ /*
+ * Read the first 4 bytes of the file; the network analyzer dump
+ * file formats we support (pcap and pcap-ng), and several other
+ * formats we might support in the future (such as snoop, DOS and
+ * Windows Sniffer, and Microsoft Network Monitor) all have magic
+ * numbers that are unique in their first 4 bytes.
+ */
+ amt_read = fread((char *)&magic, 1, sizeof(magic), fp);
+ if (amt_read != sizeof(magic)) {
+ if (ferror(fp)) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ } else {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "truncated dump file; tried to read %lu file header bytes, only got %lu",
+ (unsigned long)sizeof(magic),
+ (unsigned long)amt_read);
+ }
+ goto bad;
+ }
+
+ /*
+ * Try all file types.
+ */
+ for (i = 0; i < N_FILE_TYPES; i++) {
+ switch ((*check_headers[i])(p, magic, fp, errbuf)) {
+
+ case -1:
+ /*
+ * Error trying to read the header.
+ */
+ goto bad;
+
+ case 1:
+ /*
+ * Yup, that's it.
+ */
+ goto found;
+ }
+ }
+
+ /*
+ * Well, who knows what this mess is....
+ */
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "unknown file format");
+ goto bad;
+
+found:
+ p->sf.rfile = fp;
+
+#ifdef PCAP_FDDIPAD
+ /* Padding only needed for live capture fcode */
+ p->fddipad = 0;
+#endif
+
+#if !defined(WIN32) && !defined(MSDOS)
+ /*
+ * You can do "select()" and "poll()" on plain files on most
+ * platforms, and should be able to do so on pipes.
+ *
+ * You can't do "select()" on anything other than sockets in
+ * Windows, so, on Win32 systems, we don't have "selectable_fd".
+ */
+ p->selectable_fd = fileno(fp);
+#endif
+
+ p->read_op = pcap_offline_read;
+ p->inject_op = sf_inject;
+ p->setfilter_op = install_bpf_program;
+ p->setdirection_op = sf_setdirection;
+ p->set_datalink_op = NULL; /* we don't support munging link-layer headers */
+ p->getnonblock_op = sf_getnonblock;
+ p->setnonblock_op = sf_setnonblock;
+ p->stats_op = sf_stats;
+#ifdef WIN32
+ p->setbuff_op = sf_setbuff;
+ p->setmode_op = sf_setmode;
+ p->setmintocopy_op = sf_setmintocopy;
+#endif
+ p->cleanup_op = sf_cleanup;
+ p->activated = 1;
+
+ return (p);
+ bad:
+ free(p);
+ return (NULL);
+}
+
+/*
+ * Read packets from a capture file, and call the callback for each
+ * packet.
+ * If cnt > 0, return after 'cnt' packets, otherwise continue until eof.
+ */
+int
+pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
+{
+ struct bpf_insn *fcode;
+ int status = 0;
+ int n = 0;
+ u_char *data;
+
+ while (status == 0) {
+ struct pcap_pkthdr h;
+
+ /*
+ * Has "pcap_breakloop()" been called?
+ * If so, return immediately - if we haven't read any
+ * packets, clear the flag and return -2 to indicate
+ * that we were told to break out of the loop, otherwise
+ * leave the flag set, so that the *next* call will break
+ * out of the loop without having read any packets, and
+ * return the number of packets we've processed so far.
+ */
+ if (p->break_loop) {
+ if (n == 0) {
+ p->break_loop = 0;
+ return (-2);
+ } else
+ return (n);
+ }
+
+ status = p->sf.next_packet_op(p, &h, &data);
+ if (status) {
+ if (status == 1)
+ return (0);
+ return (status);
+ }
+
+ if ((fcode = p->fcode.bf_insns) == NULL ||
+ bpf_filter(fcode, data, h.len, h.caplen)) {
+ (*callback)(user, &h, data);
+ if (++n >= cnt && cnt > 0)
+ break;
+ }
+ }
+ /*XXX this breaks semantics tcpslice expects */
+ return (n);
+}
diff --git a/freebsd/contrib/libpcap/scanner.c b/freebsd/contrib/libpcap/scanner.c
new file mode 100644
index 00000000..d6f0498d
--- /dev/null
+++ b/freebsd/contrib/libpcap/scanner.c
@@ -0,0 +1,4890 @@
+
+#line 3 "<stdout>"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define yy_create_buffer pcap_create_buffer
+#define yy_delete_buffer pcap_delete_buffer
+#define yy_flex_debug pcap_flex_debug
+#define yy_init_buffer pcap_init_buffer
+#define yy_flush_buffer pcap_flush_buffer
+#define yy_load_buffer_state pcap_load_buffer_state
+#define yy_switch_to_buffer pcap_switch_to_buffer
+#define yyin pcapin
+#define yyleng pcapleng
+#define yylex pcaplex
+#define yylineno pcaplineno
+#define yyout pcapout
+#define yyrestart pcaprestart
+#define yytext pcaptext
+#define yywrap pcapwrap
+#define yyalloc pcapalloc
+#define yyrealloc pcaprealloc
+#define yyfree pcapfree
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 37
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+#if defined(__FreeBSD__)
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS
+#endif
+#include <sys/cdefs.h>
+#include <stdint.h>
+#else
+#define __dead2
+#endif
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined(__FreeBSD__) || \
+ (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE pcaprestart(pcapin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 1024
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern yy_size_t pcapleng;
+
+extern FILE *pcapin, *pcapout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up pcaptext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up pcaptext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ yy_size_t yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via pcaprestart()), so that the user can continue scanning by
+ * just pointing pcapin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+#define yy_current_buffer YY_CURRENT_BUFFER
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when pcaptext is formed. */
+static char yy_hold_char;
+static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */
+yy_size_t pcapleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow pcapwrap()'s to do buffer switches
+ * instead of setting up a fresh pcapin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void pcaprestart (FILE *input_file );
+void pcap_switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE pcap_create_buffer (FILE *file,int size );
+void pcap_delete_buffer (YY_BUFFER_STATE b );
+void pcap_flush_buffer (YY_BUFFER_STATE b );
+void pcappush_buffer_state (YY_BUFFER_STATE new_buffer );
+void pcappop_buffer_state (void );
+
+static void pcapensure_buffer_stack (void );
+static void pcap_load_buffer_state (void );
+static void pcap_init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER pcap_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE pcap_scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE pcap_scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE pcap_scan_bytes (yyconst char *bytes,yy_size_t len );
+
+void *pcapalloc (yy_size_t );
+void *pcaprealloc (void *,yy_size_t );
+void pcapfree (void * );
+
+#define yy_new_buffer pcap_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ pcapensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ pcap_create_buffer(pcapin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ pcapensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ pcap_create_buffer(pcapin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+typedef unsigned char YY_CHAR;
+
+FILE *pcapin = (FILE *) 0, *pcapout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int pcaplineno;
+
+int pcaplineno = 1;
+
+extern char *pcaptext;
+#define yytext_ptr pcaptext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[] ) __dead2;
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up pcaptext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ pcapleng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 147
+#define YY_END_OF_BUFFER 148
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[1438] =
+ { 0,
+ 0, 0, 148, 145, 105, 105, 105, 106, 145, 106,
+ 106, 106, 146, 115, 115, 106, 106, 106, 106, 143,
+ 143, 145, 143, 143, 143, 143, 143, 143, 143, 143,
+ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
+ 143, 143, 106, 145, 109, 113, 67, 0, 143, 115,
+ 0, 143, 143, 143, 0, 117, 111, 108, 110, 107,
+ 112, 143, 144, 144, 143, 143, 143, 20, 143, 143,
+ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
+ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
+ 143, 143, 143, 143, 143, 7, 143, 34, 35, 143,
+
+ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
+ 143, 143, 143, 91, 143, 68, 143, 143, 143, 143,
+ 143, 143, 60, 143, 143, 143, 143, 85, 143, 143,
+ 143, 143, 143, 143, 61, 143, 4, 143, 143, 143,
+ 143, 143, 143, 143, 68, 113, 143, 116, 116, 143,
+ 115, 143, 0, 117, 115, 117, 117, 117, 143, 143,
+ 143, 67, 5, 143, 80, 143, 143, 143, 143, 143,
+ 143, 143, 55, 103, 1, 0, 143, 21, 143, 143,
+ 143, 143, 143, 143, 143, 143, 143, 143, 36, 143,
+ 143, 18, 43, 0, 143, 29, 143, 25, 70, 143,
+
+ 143, 78, 37, 143, 99, 143, 143, 143, 143, 100,
+ 143, 46, 69, 81, 102, 143, 14, 143, 3, 143,
+ 143, 143, 143, 143, 93, 143, 143, 26, 143, 101,
+ 143, 104, 38, 2, 143, 42, 143, 9, 143, 10,
+ 88, 143, 87, 143, 143, 0, 143, 143, 116, 143,
+ 143, 143, 143, 115, 0, 143, 0, 118, 117, 117,
+ 0, 117, 0, 117, 0, 117, 0, 23, 143, 143,
+ 143, 143, 64, 16, 41, 143, 39, 143, 143, 143,
+ 30, 143, 97, 143, 143, 45, 11, 143, 12, 13,
+ 143, 143, 143, 32, 77, 143, 62, 3, 98, 47,
+
+ 143, 143, 143, 74, 143, 143, 143, 143, 48, 143,
+ 143, 40, 143, 6, 143, 92, 143, 8, 94, 143,
+ 143, 0, 143, 53, 73, 15, 143, 116, 116, 143,
+ 116, 116, 116, 143, 115, 143, 0, 117, 143, 0,
+ 0, 117, 0, 117, 118, 117, 0, 0, 0, 0,
+ 117, 117, 117, 117, 117, 0, 143, 56, 57, 58,
+ 59, 143, 22, 143, 143, 143, 143, 31, 143, 143,
+ 0, 19, 143, 143, 143, 86, 143, 33, 143, 79,
+ 28, 27, 143, 143, 82, 143, 143, 143, 50, 17,
+ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
+
+ 143, 143, 0, 143, 143, 116, 143, 143, 143, 143,
+ 116, 116, 143, 115, 143, 0, 0, 117, 117, 117,
+ 0, 0, 118, 117, 117, 118, 117, 0, 0, 117,
+ 117, 117, 117, 117, 0, 0, 0, 0, 117, 117,
+ 0, 117, 0, 117, 0, 96, 143, 143, 143, 24,
+ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
+ 143, 143, 143, 143, 70, 143, 143, 143, 143, 143,
+ 143, 143, 75, 76, 143, 95, 143, 143, 143, 143,
+ 143, 143, 143, 143, 143, 143, 143, 143, 116, 116,
+ 143, 116, 116, 116, 116, 143, 115, 143, 0, 117,
+
+ 117, 0, 117, 0, 0, 117, 0, 117, 118, 117,
+ 0, 0, 0, 117, 117, 0, 117, 118, 117, 0,
+ 0, 0, 0, 0, 0, 0, 117, 117, 117, 117,
+ 117, 0, 143, 143, 143, 143, 52, 63, 143, 143,
+ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
+ 71, 143, 143, 44, 83, 84, 143, 143, 143, 143,
+ 54, 141, 137, 143, 139, 138, 142, 143, 0, 143,
+ 143, 116, 143, 143, 143, 116, 143, 115, 143, 0,
+ 0, 117, 117, 117, 117, 117, 117, 0, 0, 118,
+ 117, 117, 117, 0, 0, 117, 117, 117, 117, 117,
+
+ 0, 0, 0, 0, 0, 0, 0, 117, 117, 117,
+ 117, 117, 0, 0, 0, 0, 0, 117, 117, 0,
+ 117, 0, 117, 0, 143, 143, 143, 143, 143, 143,
+ 143, 143, 143, 143, 143, 143, 143, 120, 119, 143,
+ 143, 72, 143, 143, 143, 140, 136, 143, 143, 116,
+ 116, 116, 116, 143, 115, 143, 0, 117, 117, 0,
+ 117, 117, 0, 117, 0, 0, 117, 0, 117, 118,
+ 117, 0, 0, 0, 117, 117, 0, 117, 118, 117,
+ 0, 0, 0, 0, 0, 117, 117, 0, 117, 118,
+ 117, 0, 117, 117, 0, 0, 0, 0, 0, 0,
+
+ 0, 117, 117, 117, 117, 117, 0, 65, 143, 55,
+ 125, 132, 143, 143, 143, 143, 143, 143, 143, 143,
+ 143, 66, 49, 143, 143, 0, 143, 143, 143, 143,
+ 143, 115, 143, 0, 0, 117, 117, 117, 117, 117,
+ 117, 117, 117, 117, 0, 0, 118, 117, 117, 117,
+ 0, 0, 117, 117, 117, 117, 117, 0, 0, 0,
+ 0, 0, 0, 0, 117, 117, 117, 117, 117, 0,
+ 117, 117, 0, 0, 0, 0, 0, 0, 0, 117,
+ 117, 117, 117, 117, 0, 0, 0, 0, 0, 0,
+ 117, 117, 0, 117, 0, 117, 0, 89, 143, 143,
+
+ 143, 143, 143, 143, 143, 143, 143, 143, 143, 51,
+ 114, 114, 116, 116, 143, 115, 143, 0, 117, 117,
+ 0, 117, 117, 0, 117, 117, 0, 117, 0, 114,
+ 117, 0, 117, 118, 117, 0, 0, 0, 117, 117,
+ 0, 117, 118, 117, 0, 0, 0, 0, 0, 117,
+ 117, 0, 117, 118, 117, 0, 0, 0, 0, 0,
+ 0, 117, 117, 0, 117, 118, 117, 0, 117, 117,
+ 117, 0, 0, 0, 0, 0, 0, 0, 117, 117,
+ 117, 117, 117, 0, 143, 143, 143, 143, 143, 143,
+ 143, 143, 130, 143, 90, 114, 114, 116, 143, 114,
+
+ 114, 0, 0, 117, 117, 117, 117, 117, 117, 117,
+ 117, 117, 117, 117, 117, 0, 114, 118, 117, 117,
+ 117, 0, 0, 117, 117, 117, 117, 117, 0, 0,
+ 0, 0, 0, 0, 0, 117, 117, 117, 117, 117,
+ 0, 117, 117, 0, 0, 0, 0, 0, 0, 0,
+ 117, 117, 117, 117, 117, 0, 117, 117, 117, 0,
+ 0, 0, 0, 0, 0, 0, 117, 117, 117, 117,
+ 117, 0, 0, 0, 0, 0, 0, 117, 117, 0,
+ 117, 0, 117, 0, 143, 143, 143, 134, 143, 143,
+ 143, 143, 143, 143, 143, 122, 116, 143, 115, 0,
+
+ 117, 117, 0, 117, 117, 0, 117, 117, 0, 117,
+ 117, 0, 117, 0, 0, 0, 117, 0, 0, 117,
+ 118, 117, 0, 0, 0, 117, 117, 0, 117, 118,
+ 117, 0, 0, 0, 0, 0, 117, 117, 0, 117,
+ 118, 117, 0, 0, 0, 0, 0, 0, 117, 117,
+ 0, 117, 118, 117, 0, 0, 0, 0, 0, 0,
+ 117, 117, 0, 117, 118, 117, 0, 117, 117, 117,
+ 0, 0, 0, 0, 0, 0, 0, 117, 117, 117,
+ 117, 117, 0, 143, 143, 143, 143, 124, 143, 143,
+ 143, 128, 143, 114, 0, 0, 117, 117, 117, 117,
+
+ 117, 117, 117, 117, 117, 117, 117, 117, 117, 117,
+ 117, 0, 0, 0, 118, 0, 0, 117, 0, 0,
+ 117, 117, 117, 0, 0, 0, 0, 0, 0, 0,
+ 117, 117, 117, 0, 117, 117, 0, 0, 0, 0,
+ 0, 0, 0, 117, 117, 117, 0, 117, 117, 117,
+ 0, 0, 0, 0, 0, 0, 0, 117, 117, 117,
+ 0, 117, 117, 117, 0, 0, 0, 0, 0, 0,
+ 0, 117, 117, 117, 0, 0, 0, 0, 0, 0,
+ 117, 117, 0, 117, 0, 117, 0, 121, 133, 135,
+ 129, 143, 143, 143, 143, 0, 0, 117, 0, 117,
+
+ 0, 117, 117, 0, 117, 117, 0, 117, 117, 0,
+ 117, 117, 0, 117, 0, 0, 0, 0, 117, 117,
+ 0, 117, 0, 0, 117, 117, 117, 0, 0, 0,
+ 0, 117, 117, 117, 0, 0, 0, 0, 0, 117,
+ 117, 117, 0, 0, 0, 0, 0, 117, 117, 117,
+ 0, 0, 0, 0, 0, 117, 117, 117, 117, 117,
+ 117, 0, 0, 0, 0, 0, 0, 0, 117, 117,
+ 117, 0, 143, 143, 143, 143, 0, 0, 0, 117,
+ 117, 117, 117, 117, 117, 0, 0, 0, 0, 117,
+ 117, 0, 0, 0, 0, 117, 117, 117, 0, 0,
+
+ 0, 0, 0, 117, 117, 117, 117, 0, 0, 0,
+ 0, 0, 117, 117, 117, 117, 0, 0, 0, 0,
+ 0, 117, 117, 117, 117, 0, 0, 0, 0, 0,
+ 117, 0, 0, 0, 0, 0, 117, 117, 117, 143,
+ 143, 143, 131, 117, 117, 117, 117, 117, 117, 117,
+ 117, 0, 0, 0, 0, 117, 117, 0, 0, 117,
+ 0, 0, 0, 117, 0, 0, 0, 117, 0, 0,
+ 0, 117, 0, 0, 0, 117, 117, 117, 117, 0,
+ 0, 0, 0, 0, 117, 126, 143, 123, 117, 0,
+ 0, 117, 117, 0, 117, 117, 117, 0, 117, 117,
+
+ 117, 0, 117, 117, 117, 0, 117, 117, 117, 0,
+ 0, 0, 0, 117, 127, 117, 117, 0, 0, 0,
+ 0, 0, 0, 117, 117, 117, 0, 0, 117, 117,
+ 117, 117, 117, 0, 117, 117, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 5, 1, 1, 6, 1, 7, 1, 8,
+ 8, 9, 9, 1, 10, 11, 9, 12, 13, 14,
+ 15, 16, 17, 18, 17, 17, 17, 19, 1, 20,
+ 21, 22, 1, 1, 23, 23, 23, 23, 23, 23,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 25, 24, 24,
+ 26, 27, 26, 1, 28, 1, 29, 30, 31, 32,
+
+ 33, 34, 35, 36, 37, 24, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 24, 1, 53, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[54] =
+ { 0,
+ 1, 2, 2, 1, 2, 1, 3, 2, 1, 4,
+ 5, 6, 6, 6, 6, 6, 6, 6, 7, 3,
+ 3, 3, 8, 4, 9, 3, 1, 4, 8, 8,
+ 8, 8, 8, 8, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 9, 4, 3
+ } ;
+
+static yyconst flex_int16_t yy_base[1898] =
+ { 0,
+ 0, 0, 3858, 53, 7396, 7396, 54, 3836, 60, 3849,
+ 7396, 82, 7396, 100, 31, 152, 47, 3834, 49, 169,
+ 211, 169, 61, 44, 126, 61, 30, 63, 76, 3811,
+ 215, 218, 160, 32, 166, 117, 171, 228, 145, 3820,
+ 229, 3812, 3782, 276, 7396, 0, 7396, 292, 315, 339,
+ 3815, 363, 0, 370, 0, 404, 7396, 7396, 7396, 7396,
+ 7396, 274, 292, 0, 3788, 3785, 3799, 0, 3797, 3785,
+ 3798, 3781, 3769, 3763, 3764, 3767, 3765, 3764, 3773, 3743,
+ 3756, 3739, 324, 3749, 3752, 3736, 3734, 3747, 3719, 3724,
+ 3722, 82, 3726, 3721, 3729, 148, 229, 0, 0, 37,
+
+ 123, 3717, 3726, 167, 3695, 3693, 3696, 3699, 3689, 3695,
+ 3686, 3671, 3677, 0, 3685, 0, 3668, 3674, 3667, 3668,
+ 3668, 3653, 160, 3664, 3647, 3658, 3650, 56, 3645, 216,
+ 3628, 126, 3627, 3639, 0, 3625, 0, 3624, 3622, 3627,
+ 3634, 3610, 3601, 3616, 7396, 7396, 429, 453, 212, 494,
+ 518, 542, 3625, 549, 3631, 573, 269, 3621, 3581, 3586,
+ 3577, 0, 0, 3582, 0, 3591, 3585, 3574, 3573, 3559,
+ 3556, 3557, 3564, 0, 0, 3558, 3548, 0, 3560, 3540,
+ 3528, 3542, 3545, 3526, 3528, 3541, 3526, 3525, 0, 3509,
+ 3503, 0, 0, 3506, 3496, 0, 3507, 0, 3504, 3492,
+
+ 3499, 0, 0, 3474, 0, 3483, 3491, 203, 3473, 0,
+ 3469, 3485, 0, 3480, 0, 3483, 0, 3456, 3440, 3434,
+ 3437, 3441, 3433, 3429, 0, 3427, 3440, 0, 3414, 0,
+ 3413, 0, 0, 0, 3410, 0, 171, 167, 3421, 0,
+ 0, 3411, 0, 3408, 3409, 613, 3439, 636, 660, 3423,
+ 667, 476, 267, 691, 3414, 715, 3412, 3410, 723, 288,
+ 3409, 3407, 483, 764, 787, 3391, 0, 0, 3367, 327,
+ 3370, 3375, 0, 0, 0, 3371, 0, 3370, 3371, 3340,
+ 0, 3340, 0, 3334, 3334, 0, 590, 3328, 0, 0,
+ 3334, 3307, 3308, 0, 0, 3298, 0, 0, 0, 0,
+
+ 3313, 3303, 3291, 0, 3284, 3287, 3303, 3276, 3271, 3268,
+ 3248, 0, 3246, 0, 3239, 0, 192, 0, 0, 3232,
+ 3227, 715, 3218, 0, 0, 0, 812, 836, 312, 877,
+ 3245, 3244, 381, 900, 924, 948, 3235, 955, 597, 3234,
+ 3231, 978, 752, 1002, 1025, 3230, 0, 3219, 400, 403,
+ 1049, 3197, 1073, 339, 3196, 3203, 3168, 0, 0, 0,
+ 0, 3162, 0, 3161, 3159, 3142, 3141, 0, 3156, 3140,
+ 1092, 0, 3126, 3115, 3133, 0, 3108, 0, 3111, 3102,
+ 0, 0, 3101, 3080, 237, 3079, 3097, 268, 3072, 0,
+ 3050, 3039, 3053, 3046, 3041, 3050, 3043, 3031, 3032, 3025,
+
+ 3022, 3036, 1129, 3051, 1152, 1176, 3039, 1183, 859, 305,
+ 1207, 340, 1247, 1270, 1294, 3009, 3008, 1302, 364, 3007,
+ 3005, 3003, 3002, 1343, 373, 3001, 2976, 491, 607, 1384,
+ 2975, 1408, 404, 2974, 2981, 2971, 866, 0, 347, 2970,
+ 1096, 1449, 1472, 2969, 0, 0, 2926, 2942, 2923, 0,
+ 2931, 2914, 2920, 2933, 2918, 2919, 2918, 407, 2901, 411,
+ 2901, 2909, 2897, 2893, 0, 2883, 2893, 2881, 2886, 2853,
+ 2842, 2841, 0, 0, 2844, 0, 2838, 2830, 2843, 2827,
+ 2821, 2817, 2811, 2809, 2813, 2818, 2817, 1497, 1521, 405,
+ 1562, 2825, 2824, 609, 1586, 1610, 1617, 1641, 2815, 1648,
+
+ 1672, 1695, 2814, 2813, 2811, 1718, 1103, 1742, 1765, 2810,
+ 0, 1230, 0, 461, 2809, 1237, 1789, 1812, 2794, 0,
+ 734, 761, 2801, 462, 781, 812, 1836, 2792, 1860, 428,
+ 2791, 2798, 381, 2761, 2766, 2763, 0, 0, 2753, 2755,
+ 2741, 2741, 2753, 2735, 2734, 2741, 2719, 2720, 2731, 2730,
+ 0, 2721, 2714, 0, 0, 0, 2727, 2723, 2713, 2700,
+ 0, 0, 0, 2704, 0, 0, 0, 2693, 1900, 2728,
+ 1923, 1947, 2725, 1954, 324, 1978, 2002, 2009, 2033, 2716,
+ 2715, 2041, 452, 2700, 2082, 488, 2699, 2698, 2697, 2696,
+ 2123, 489, 2694, 874, 894, 2164, 2693, 2188, 493, 2692,
+
+ 2684, 1123, 1125, 2683, 2682, 1246, 1312, 2229, 2673, 2253,
+ 494, 2672, 2677, 1326, 0, 1333, 0, 527, 2668, 1366,
+ 2294, 2317, 2653, 0, 2340, 428, 79, 255, 237, 617,
+ 546, 586, 2624, 362, 522, 547, 379, 2623, 2622, 1124,
+ 2621, 2619, 1242, 849, 473, 2618, 2617, 2378, 2415, 2451,
+ 2487, 546, 2511, 588, 2519, 2543, 2629, 2550, 2574, 2597,
+ 2628, 2621, 2644, 2627, 2626, 2624, 2667, 1373, 2691, 2714,
+ 2622, 0, 1431, 0, 675, 2606, 1438, 2738, 2761, 2605,
+ 0, 1544, 0, 1551, 0, 676, 2604, 1883, 2785, 2808,
+ 2603, 0, 637, 1890, 2610, 1381, 1446, 2608, 2607, 1466,
+
+ 1497, 2832, 2598, 2856, 638, 2582, 2589, 567, 682, 591,
+ 612, 763, 1246, 2051, 1383, 628, 803, 805, 2078, 683,
+ 829, 761, 828, 2076, 2080, 2898, 830, 2921, 892, 2944,
+ 2109, 2968, 2992, 2580, 2579, 3000, 737, 2577, 3041, 873,
+ 2576, 3082, 876, 2575, 2559, 2558, 2557, 3123, 897, 2556,
+ 1559, 1689, 3164, 2555, 3188, 901, 2553, 2560, 1899, 2051,
+ 2559, 2558, 2052, 2058, 3229, 2528, 3253, 924, 2527, 2534,
+ 925, 2146, 2533, 2118, 2119, 2532, 2530, 2120, 2140, 3294,
+ 2521, 3318, 926, 2520, 2527, 0, 2211, 0, 2218, 0,
+ 732, 2496, 2276, 3359, 3382, 2495, 0, 918, 970, 971,
+
+ 972, 1899, 996, 1448, 1017, 1018, 2271, 1042, 1561, 1043,
+ 3407, 3430, 3454, 998, 3494, 3518, 3542, 2494, 3549, 3573,
+ 3596, 2493, 3620, 3643, 2492, 3667, 3690, 2490, 2489, 2488,
+ 3713, 2363, 3737, 3760, 2487, 0, 2401, 0, 1011, 2440,
+ 2438, 3784, 3807, 2439, 0, 2458, 0, 2465, 0, 1058,
+ 2438, 2472, 3831, 3854, 2424, 0, 0, 2479, 0, 2879,
+ 0, 1082, 2423, 2886, 3878, 3901, 2422, 0, 0, 1049,
+ 3023, 2429, 2161, 2226, 2378, 2351, 2290, 2291, 3925, 2342,
+ 3949, 1072, 2341, 2348, 2293, 2354, 2355, 2122, 1123, 2228,
+ 2356, 1066, 2357, 1198, 1121, 1145, 1199, 3991, 4015, 4024,
+
+ 1200, 2326, 2325, 4042, 1102, 2324, 4083, 1105, 2320, 4124,
+ 1152, 2319, 4165, 1153, 2318, 2303, 2301, 4205, 4229, 1154,
+ 2300, 2409, 2410, 4270, 2281, 4294, 1182, 2278, 2285, 2591,
+ 2638, 2284, 2268, 2894, 2895, 4335, 2256, 4359, 1241, 2254,
+ 2244, 1243, 3030, 2243, 2898, 3038, 2242, 2239, 3051, 3057,
+ 4400, 2230, 4424, 1244, 2197, 2204, 0, 1247, 3105, 2203,
+ 3058, 3079, 2199, 2198, 3099, 3118, 4465, 2170, 4489, 1271,
+ 2169, 2174, 0, 3146, 0, 3211, 0, 1161, 2154, 3218,
+ 4530, 4553, 2149, 0, 3263, 3264, 3328, 1201, 2394, 2100,
+ 1402, 2395, 2270, 1464, 1488, 1342, 4578, 4602, 4611, 2130,
+
+ 4628, 4652, 4675, 2100, 4699, 4722, 2070, 4746, 4769, 2068,
+ 4793, 4816, 2065, 2063, 4840, 1384, 2062, 2061, 3281, 4881,
+ 2059, 2049, 0, 3345, 0, 1530, 2046, 3477, 4905, 2018,
+ 2016, 0, 3484, 0, 3972, 0, 1571, 2015, 3979, 4929,
+ 2014, 2011, 0, 0, 4031, 0, 4065, 0, 1594, 1981,
+ 4072, 4953, 1980, 1906, 0, 0, 4106, 0, 4113, 0,
+ 1595, 1863, 4147, 4977, 1844, 1819, 0, 0, 1385, 4154,
+ 1822, 3120, 3140, 1806, 1802, 3159, 3161, 5001, 1771, 5025,
+ 1448, 1770, 1756, 1490, 1664, 1665, 1515, 1666, 1736, 4163,
+ 1687, 1711, 2396, 5067, 1747, 5084, 5108, 1556, 1725, 5149,
+
+ 1561, 1724, 5190, 1586, 1723, 5231, 1616, 1719, 5272, 1617,
+ 1704, 1700, 4191, 5313, 1626, 1620, 0, 1619, 3226, 3264,
+ 5337, 1617, 1569, 1576, 3289, 3328, 1572, 1536, 3355, 3376,
+ 5361, 1521, 1505, 1512, 1618, 4252, 1508, 3407, 3493, 1483,
+ 1464, 3590, 3637, 5385, 1451, 1450, 1418, 0, 1619, 4259,
+ 1397, 3684, 4175, 1394, 1393, 4176, 4200, 5409, 1352, 1350,
+ 1356, 0, 1647, 4317, 1354, 4204, 4267, 1353, 1319, 4311,
+ 4330, 5433, 1310, 1309, 1315, 0, 4382, 0, 4389, 0,
+ 1751, 1305, 4447, 5457, 0, 1271, 0, 1735, 1758, 1759,
+ 1781, 1782, 1969, 4483, 4499, 5481, 1648, 0, 1254, 5522,
+
+ 0, 1248, 5546, 0, 1216, 5570, 0, 1212, 5594, 0,
+ 1183, 5618, 0, 1109, 4332, 4397, 5642, 1107, 1103, 1076,
+ 1064, 1028, 4454, 0, 1821, 1007, 983, 4516, 0, 4618,
+ 0, 1845, 964, 960, 0, 4863, 0, 4870, 0, 1869,
+ 955, 925, 0, 5048, 0, 5055, 0, 1909, 924, 902,
+ 0, 5074, 0, 5131, 0, 1932, 885, 80, 0, 1671,
+ 5138, 180, 4462, 4526, 187, 225, 4547, 4627, 5666, 280,
+ 0, 301, 2358, 1783, 1806, 1829, 5690, 299, 340, 0,
+ 0, 0, 0, 0, 0, 5172, 0, 1962, 431, 496,
+ 0, 4669, 4716, 511, 532, 0, 1811, 5179, 559, 4763,
+
+ 4810, 563, 605, 0, 0, 1833, 5213, 606, 4878, 5083,
+ 628, 630, 0, 0, 1835, 5220, 680, 5228, 5241, 702,
+ 704, 0, 0, 1836, 5255, 705, 5269, 5282, 707, 708,
+ 0, 0, 5296, 0, 5504, 0, 1963, 728, 0, 3078,
+ 2959, 2156, 1916, 0, 7396, 0, 0, 0, 0, 0,
+ 0, 5310, 5498, 739, 773, 0, 7396, 5512, 0, 7396,
+ 0, 5713, 0, 7396, 0, 5720, 0, 7396, 0, 5727,
+ 0, 7396, 0, 5734, 0, 7396, 0, 1894, 5741, 779,
+ 5749, 5750, 796, 2017, 0, 1970, 3336, 2057, 0, 5750,
+ 0, 1896, 5764, 798, 0, 1897, 5771, 800, 0, 1924,
+
+ 5778, 803, 0, 1951, 5790, 844, 0, 1953, 5797, 851,
+ 0, 5804, 0, 7396, 2180, 1978, 5811, 853, 0, 0,
+ 0, 0, 0, 0, 1980, 5818, 886, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7396, 5836, 5844, 5848,
+ 5851, 5854, 5857, 5860, 5863, 5866, 5869, 5872, 5875, 5878,
+ 5881, 5884, 5887, 5890, 5893, 5896, 5900, 5904, 5907, 5910,
+ 5913, 5916, 5919, 5922, 5925, 5928, 5932, 5936, 5939, 5942,
+ 5946, 5948, 5951, 5954, 5957, 5960, 5963, 5966, 5969, 5972,
+ 5976, 5978, 5981, 5985, 5990, 5994, 5997, 6001, 6004, 6007,
+ 6010, 6013, 6016, 6019, 6022, 6026, 6030, 6033, 6037, 6041,
+
+ 6046, 6050, 6052, 6056, 6059, 6063, 6066, 6069, 6073, 6075,
+ 6078, 6081, 6084, 6087, 6090, 6093, 6096, 6099, 6102, 6106,
+ 6108, 6111, 6114, 6117, 6121, 6123, 6126, 6129, 6134, 6138,
+ 6143, 6147, 6149, 6153, 6156, 6160, 6165, 6169, 6172, 6175,
+ 6178, 6181, 6184, 6187, 6190, 6194, 6198, 6201, 6205, 6209,
+ 6214, 6218, 6220, 6224, 6227, 6231, 6234, 6239, 6243, 6248,
+ 6252, 6254, 6258, 6261, 6265, 6268, 6271, 6274, 6278, 6280,
+ 6283, 6288, 6292, 6295, 6298, 6301, 6304, 6307, 6310, 6313,
+ 6316, 6320, 6322, 6325, 6328, 6331, 6335, 6337, 6340, 6343,
+ 6346, 6349, 6353, 6355, 6358, 6361, 6364, 6369, 6373, 6378,
+
+ 6382, 6384, 6388, 6391, 6395, 6400, 6404, 6407, 6410, 6413,
+ 6416, 6419, 6422, 6425, 6429, 6433, 6436, 6440, 6444, 6449,
+ 6453, 6455, 6459, 6462, 6466, 6469, 6474, 6478, 6483, 6487,
+ 6489, 6493, 6496, 6500, 6503, 6506, 6511, 6515, 6520, 6524,
+ 6526, 6530, 6533, 6537, 6540, 6543, 6546, 6550, 6552, 6555,
+ 6560, 6564, 6567, 6570, 6573, 6576, 6579, 6582, 6585, 6588,
+ 6591, 6594, 6597, 6601, 6603, 6606, 6609, 6612, 6615, 6619,
+ 6621, 6624, 6627, 6630, 6633, 6636, 6640, 6642, 6645, 6648,
+ 6651, 6654, 6657, 6661, 6663, 6666, 6669, 6672, 6675, 6680,
+ 6684, 6689, 6693, 6695, 6699, 6702, 6706, 6711, 6715, 6718,
+
+ 6721, 6724, 6727, 6730, 6733, 6736, 6739, 6742, 6746, 6750,
+ 6753, 6757, 6761, 6766, 6770, 6772, 6776, 6779, 6783, 6786,
+ 6791, 6795, 6800, 6804, 6806, 6810, 6813, 6817, 6820, 6823,
+ 6828, 6832, 6837, 6841, 6843, 6847, 6850, 6854, 6857, 6860,
+ 6865, 6869, 6874, 6878, 6880, 6884, 6887, 6891, 6894, 6897,
+ 6900, 6904, 6906, 6909, 6912, 6917, 6921, 6924, 6927, 6930,
+ 6933, 6936, 6939, 6942, 6945, 6948, 6951, 6954, 6958, 6962,
+ 6965, 6968, 6972, 6975, 6978, 6982, 6984, 6987, 6990, 6994,
+ 6996, 6999, 7002, 7005, 7009, 7011, 7014, 7017, 7020, 7024,
+ 7026, 7029, 7032, 7035, 7039, 7041, 7044, 7047, 7052, 7056,
+
+ 7061, 7065, 7067, 7071, 7074, 7078, 7083, 7087, 7090, 7093,
+ 7096, 7099, 7102, 7105, 7108, 7111, 7115, 7117, 7120, 7124,
+ 7129, 7133, 7134, 7137, 7142, 7146, 7151, 7155, 7156, 7159,
+ 7162, 7167, 7171, 7176, 7180, 7181, 7184, 7187, 7192, 7196,
+ 7201, 7205, 7206, 7209, 7212, 7217, 7221, 7226, 7230, 7231,
+ 7234, 7237, 7240, 7244, 7246, 7251, 7255, 7258, 7261, 7264,
+ 7267, 7270, 7273, 7277, 7282, 7286, 7287, 7290, 7293, 7296,
+ 7299, 7302, 7305, 7308, 7311, 7314, 7317, 7322, 7326, 7329,
+ 7332, 7335, 7339, 7343, 7347, 7351, 7355, 7358, 7361, 7365,
+ 7368, 7371, 7374, 7377, 7380, 7384, 7387
+
+ } ;
+
+static yyconst flex_int16_t yy_def[1898] =
+ { 0,
+ 1437, 1, 1437, 1437, 1437, 1437, 1437, 1437, 1438, 1437,
+ 1437, 1437, 1437, 1437, 14, 1437, 1437, 1437, 1437, 14,
+ 20, 1439, 20, 20, 20, 20, 20, 20, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 1437, 1437, 1437, 1440, 1437, 21, 21, 20,
+ 1441, 50, 21, 21, 21, 1437, 1437, 1437, 1437, 1437,
+ 1437, 49, 1439, 1439, 52, 52, 52, 21, 21, 21,
+ 21, 52, 21, 21, 52, 21, 21, 21, 52, 21,
+ 21, 21, 21, 21, 52, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 1437, 1437, 21, 21, 148, 21,
+ 21, 151, 1442, 1437, 54, 1437, 156, 1443, 21, 21,
+ 152, 21, 21, 21, 152, 21, 21, 21, 21, 21,
+ 21, 152, 21, 21, 21, 21, 21, 21, 21, 152,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 248, 249, 152, 1444, 254, 1445, 1446, 1437, 259,
+ 1447, 1448, 1437, 1437, 1437, 1449, 1450, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 328, 21,
+ 249, 251, 249, 251, 251, 335, 1451, 1437, 334, 1452,
+ 1453, 1437, 1437, 1437, 1437, 1454, 1455, 1456, 1457, 1457,
+ 1437, 1458, 1437, 353, 1459, 1450, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+
+ 21, 21, 21, 21, 21, 21, 21, 21, 405, 406,
+ 406, 411, 405, 335, 414, 1460, 1461, 1437, 418, 1462,
+ 1437, 1463, 1464, 1437, 424, 1465, 1466, 1467, 1467, 1437,
+ 1468, 1437, 432, 1469, 1455, 1437, 1437, 1470, 1471, 1437,
+ 1437, 1437, 1437, 1472, 1473, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 489,
+ 21, 406, 408, 406, 406, 495, 414, 497, 1474, 1437,
+
+ 1437, 1437, 1475, 1476, 1477, 1437, 1437, 1437, 1437, 1478,
+ 1479, 1437, 1480, 1481, 1437, 1437, 1437, 1437, 1482, 1483,
+ 1484, 1484, 1470, 1471, 1485, 1485, 1437, 1486, 1437, 529,
+ 1487, 1488, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 572, 572, 576, 497, 578, 1489,
+ 1490, 1437, 582, 1491, 1437, 585, 1492, 1437, 1493, 1494,
+ 1437, 591, 1495, 1496, 1496, 1437, 1497, 1437, 598, 1498,
+
+ 1499, 1500, 1500, 1501, 1502, 1503, 1503, 1437, 1504, 1437,
+ 610, 1505, 1506, 1437, 1507, 1437, 1508, 1509, 1437, 1437,
+ 1437, 1437, 1510, 1511, 579, 625, 625, 625, 625, 625,
+ 625, 625, 625, 625, 625, 625, 625, 625, 625, 625,
+ 625, 625, 625, 625, 625, 625, 625, 625, 625, 625,
+ 650, 650, 650, 625, 650, 655, 1512, 1437, 1437, 1437,
+ 1513, 1437, 1437, 1514, 1515, 1516, 1437, 1437, 1437, 1437,
+ 1517, 1518, 1437, 1519, 1520, 1437, 1437, 1437, 1437, 1521,
+ 1522, 1437, 1523, 1437, 1524, 1525, 1437, 1437, 1437, 1437,
+ 1526, 1527, 1528, 1437, 1529, 1530, 1530, 1531, 1532, 1533,
+
+ 1533, 1437, 1534, 1437, 704, 1535, 1536, 1537, 1537, 1537,
+ 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537,
+ 1537, 1537, 1537, 1537, 1537, 1537, 1537, 726, 1537, 726,
+ 730, 730, 732, 1538, 1539, 1437, 736, 1540, 1437, 739,
+ 1541, 1437, 742, 1542, 1437, 1543, 1544, 1437, 748, 1545,
+ 1546, 1546, 1437, 1547, 1437, 755, 1548, 1549, 1550, 1550,
+ 1551, 1552, 1553, 1553, 1437, 1554, 1437, 767, 1555, 1556,
+ 1557, 1437, 1558, 1559, 1559, 1560, 1561, 1562, 1562, 1437,
+ 1563, 1437, 782, 1564, 1565, 1566, 1437, 1567, 1437, 1568,
+ 1569, 1437, 1437, 1437, 1437, 1570, 1571, 1572, 1572, 1572,
+
+ 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572,
+ 1572, 811, 811, 813, 811, 811, 816, 1573, 1437, 1437,
+ 1437, 1574, 1437, 1437, 1575, 1437, 1437, 1576, 1577, 1578,
+ 1437, 1437, 1437, 1437, 1579, 1580, 1437, 1581, 1582, 1437,
+ 1437, 1437, 1437, 1583, 1584, 1437, 1585, 1437, 1586, 1587,
+ 1437, 1437, 1437, 1437, 1588, 1589, 1590, 1437, 1591, 1437,
+ 1592, 1593, 1437, 1437, 1437, 1437, 1594, 1595, 1596, 1597,
+ 1437, 1598, 1599, 1599, 1600, 1601, 1602, 1602, 1437, 1603,
+ 1437, 881, 1604, 1605, 1606, 1606, 1606, 1606, 1606, 1606,
+ 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 898, 1606,
+
+ 1606, 1607, 1608, 1437, 904, 1609, 1437, 907, 1610, 1437,
+ 910, 1611, 1437, 913, 1612, 1437, 1613, 1437, 1437, 919,
+ 1614, 1615, 1615, 1437, 1616, 1437, 926, 1617, 1618, 1619,
+ 1619, 1620, 1621, 1622, 1622, 1437, 1623, 1437, 938, 1624,
+ 1625, 1626, 1437, 1627, 1628, 1628, 1629, 1630, 1631, 1631,
+ 1437, 1632, 1437, 953, 1633, 1634, 1635, 1636, 1437, 1637,
+ 1638, 1638, 1639, 1640, 1641, 1641, 1437, 1642, 1437, 969,
+ 1643, 1644, 1645, 1437, 1646, 1437, 1647, 1648, 1437, 1437,
+ 1437, 1437, 1649, 1650, 1651, 1651, 1651, 1651, 1651, 1651,
+ 1651, 1651, 1651, 1651, 1651, 1651, 1651, 997, 1651, 1652,
+
+ 1437, 1437, 1437, 1653, 1437, 1437, 1654, 1437, 1437, 1655,
+ 1437, 1437, 1656, 1657, 1437, 1015, 1658, 1659, 1437, 1437,
+ 1660, 1661, 1662, 1437, 1663, 1664, 1437, 1437, 1437, 1665,
+ 1666, 1667, 1437, 1668, 1437, 1669, 1670, 1437, 1437, 1437,
+ 1671, 1672, 1673, 1674, 1437, 1675, 1437, 1676, 1677, 1437,
+ 1437, 1437, 1678, 1679, 1680, 1681, 1437, 1682, 1437, 1683,
+ 1684, 1437, 1437, 1437, 1685, 1686, 1687, 1688, 1689, 1437,
+ 1690, 1691, 1691, 1692, 1693, 1694, 1694, 1437, 1695, 1437,
+ 1080, 1696, 1697, 1698, 1698, 1698, 1698, 1698, 1698, 1698,
+ 1698, 1698, 1698, 1698, 1699, 1437, 1437, 1097, 1700, 1437,
+
+ 1100, 1701, 1437, 1103, 1702, 1437, 1106, 1703, 1437, 1109,
+ 1704, 1437, 1437, 1437, 1705, 1706, 1707, 1708, 1709, 1709,
+ 1437, 1710, 1711, 1712, 1713, 1713, 1714, 1715, 1716, 1716,
+ 1437, 1717, 1718, 1719, 1720, 1437, 1721, 1722, 1722, 1723,
+ 1724, 1725, 1725, 1437, 1726, 1727, 1728, 1729, 1730, 1437,
+ 1731, 1732, 1732, 1733, 1734, 1735, 1735, 1437, 1736, 1737,
+ 1738, 1739, 1740, 1437, 1741, 1742, 1742, 1743, 1744, 1745,
+ 1745, 1437, 1746, 1747, 1748, 1749, 1437, 1750, 1437, 1751,
+ 1752, 1437, 1437, 1437, 1753, 1754, 1755, 1756, 1756, 1756,
+ 1756, 1756, 1756, 1756, 1756, 1437, 1196, 1757, 1758, 1437,
+
+ 1759, 1760, 1437, 1761, 1762, 1437, 1763, 1764, 1437, 1765,
+ 1766, 1437, 1767, 1768, 1769, 1769, 1437, 1770, 1771, 1772,
+ 1773, 1774, 1437, 1775, 1776, 1437, 1777, 1437, 1778, 1437,
+ 1779, 1780, 1437, 1781, 1782, 1437, 1783, 1437, 1784, 1785,
+ 1437, 1786, 1787, 1437, 1788, 1437, 1789, 1790, 1437, 1791,
+ 1792, 1437, 1793, 1437, 1794, 1795, 1437, 1796, 1797, 1798,
+ 1437, 1799, 1800, 1800, 1801, 1802, 1803, 1803, 1437, 1804,
+ 1805, 1806, 1807, 1807, 1807, 1807, 1437, 1808, 1809, 1810,
+ 1811, 1812, 1813, 1814, 1815, 1437, 1816, 1817, 1437, 1818,
+ 1819, 1820, 1820, 1821, 1822, 1823, 1824, 1437, 1825, 1826,
+
+ 1826, 1827, 1828, 1829, 1830, 1831, 1437, 1832, 1833, 1833,
+ 1834, 1835, 1836, 1837, 1838, 1437, 1839, 1840, 1840, 1841,
+ 1842, 1843, 1844, 1845, 1437, 1846, 1847, 1847, 1848, 1849,
+ 1850, 1851, 1437, 1852, 1437, 1853, 1854, 1437, 1855, 1856,
+ 1856, 1856, 1856, 1857, 1437, 1858, 1859, 1860, 1861, 1862,
+ 1863, 1864, 1864, 1865, 1866, 1867, 1437, 1437, 1868, 1437,
+ 1869, 1437, 1870, 1437, 1871, 1437, 1872, 1437, 1873, 1437,
+ 1874, 1437, 1875, 1437, 1876, 1437, 1851, 1877, 1437, 1852,
+ 1878, 1878, 1853, 1854, 1879, 1856, 1856, 1856, 1880, 1437,
+ 1881, 1882, 1437, 1868, 1869, 1883, 1437, 1870, 1871, 1884,
+
+ 1437, 1872, 1873, 1885, 1437, 1874, 1875, 1886, 1437, 1876,
+ 1887, 1437, 1888, 1437, 1856, 1889, 1437, 1881, 1890, 1891,
+ 1892, 1893, 1894, 1887, 1895, 1437, 1888, 1896, 1890, 1891,
+ 1892, 1893, 1894, 1897, 1896, 1897, 0, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437
+
+ } ;
+
+static yyconst flex_int16_t yy_nxt[7450] =
+ { 0,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 11,
+ 13, 14, 15, 15, 15, 15, 15, 15, 16, 17,
+ 18, 19, 20, 21, 21, 11, 22, 13, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 21, 32, 33,
+ 34, 35, 36, 21, 37, 38, 39, 40, 41, 42,
+ 21, 21, 43, 44, 44, 53, 44, 44, 44, 44,
+ 44, 44, 44, 44, 111, 44, 57, 58, 44, 60,
+ 61, 44, 44, 112, 72, 83, 84, 197, 44, 44,
+ 44, 53, 44, 198, 228, 44, 44, 44, 73, 65,
+ 44, 66, 67, 79, 85, 74, 68, 80, 426, 86,
+
+ 44, 69, 229, 81, 87, 70, 82, 71, 44, 48,
+ 49, 50, 50, 50, 50, 50, 50, 50, 51, 710,
+ 88, 187, 52, 53, 54, 53, 188, 55, 52, 52,
+ 52, 52, 52, 52, 53, 53, 53, 53, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+ 54, 53, 44, 118, 75, 44, 234, 44, 119, 120,
+ 44, 121, 122, 199, 76, 192, 235, 77, 200, 63,
+ 56, 78, 63, 135, 63, 136, 322, 63, 44, 62,
+ 52, 52, 52, 52, 52, 52, 52, 63, 105, 137,
+ 1177, 222, 106, 53, 113, 63, 138, 1179, 193, 123,
+
+ 323, 107, 108, 124, 223, 109, 114, 110, 115, 203,
+ 116, 125, 204, 117, 205, 320, 126, 321, 127, 53,
+ 55, 53, 53, 53, 53, 53, 53, 53, 53, 1437,
+ 98, 99, 392, 53, 302, 980, 53, 393, 194, 53,
+ 53, 53, 53, 53, 53, 90, 100, 303, 91, 92,
+ 101, 93, 231, 94, 102, 95, 103, 96, 128, 140,
+ 97, 232, 53, 104, 129, 195, 130, 141, 131, 469,
+ 196, 142, 132, 143, 133, 134, 44, 53, 333, 44,
+ 712, 44, 470, 53, 44, 150, 150, 150, 150, 150,
+ 150, 150, 63, 1437, 44, 63, 711, 63, 1185, 473,
+
+ 63, 53, 44, 147, 147, 147, 147, 147, 147, 147,
+ 63, 1183, 1437, 474, 147, 53, 494, 1345, 63, 1437,
+ 147, 147, 147, 147, 147, 147, 148, 149, 149, 149,
+ 149, 149, 149, 176, 53, 652, 53, 150, 1437, 358,
+ 359, 360, 361, 150, 150, 150, 150, 150, 150, 49,
+ 151, 151, 151, 151, 151, 151, 151, 263, 1278, 362,
+ 177, 152, 53, 1437, 53, 265, 178, 152, 152, 152,
+ 152, 152, 152, 62, 152, 152, 152, 152, 152, 152,
+ 152, 155, 155, 155, 155, 155, 155, 155, 1437, 1437,
+ 53, 410, 155, 358, 359, 360, 361, 1437, 155, 155,
+
+ 155, 155, 155, 155, 44, 251, 717, 44, 53, 44,
+ 437, 720, 44, 437, 1437, 156, 157, 157, 157, 157,
+ 157, 157, 44, 1437, 438, 53, 158, 1437, 1437, 53,
+ 44, 251, 158, 158, 158, 158, 158, 158, 246, 543,
+ 247, 247, 247, 247, 247, 247, 247, 546, 544, 1278,
+ 438, 247, 1437, 1437, 1437, 53, 547, 247, 247, 247,
+ 247, 247, 247, 248, 249, 249, 249, 249, 249, 249,
+ 249, 343, 263, 709, 53, 250, 1437, 251, 1437, 502,
+ 1437, 250, 250, 250, 250, 250, 250, 330, 330, 330,
+ 330, 330, 330, 330, 349, 350, 350, 350, 350, 350,
+
+ 350, 512, 1437, 251, 252, 250, 250, 250, 250, 250,
+ 250, 250, 1437, 1437, 426, 513, 250, 1437, 1437, 53,
+ 725, 1223, 250, 250, 250, 250, 250, 250, 253, 254,
+ 254, 254, 254, 254, 254, 254, 255, 441, 1437, 1437,
+ 256, 513, 1019, 1437, 1437, 443, 256, 256, 256, 256,
+ 256, 256, 53, 256, 256, 256, 256, 256, 256, 256,
+ 259, 260, 260, 260, 260, 260, 260, 261, 53, 1228,
+ 574, 262, 718, 1230, 714, 719, 55, 262, 262, 262,
+ 262, 262, 262, 263, 264, 264, 264, 264, 264, 264,
+ 264, 265, 53, 53, 55, 266, 574, 267, 731, 371,
+
+ 55, 266, 266, 266, 266, 266, 266, 372, 413, 413,
+ 413, 413, 413, 413, 413, 1028, 1236, 512, 55, 575,
+ 373, 55, 715, 267, 327, 327, 327, 327, 327, 327,
+ 327, 1437, 53, 408, 53, 327, 374, 55, 1238, 55,
+ 1039, 327, 327, 327, 327, 327, 327, 328, 329, 329,
+ 329, 329, 329, 329, 713, 55, 799, 1437, 330, 408,
+ 804, 786, 1437, 53, 330, 330, 330, 330, 330, 330,
+ 248, 331, 331, 331, 331, 331, 331, 331, 332, 332,
+ 332, 332, 332, 332, 332, 507, 516, 786, 1437, 332,
+ 1244, 55, 55, 660, 663, 332, 332, 332, 332, 332,
+
+ 332, 334, 335, 335, 335, 335, 335, 335, 335, 55,
+ 55, 808, 1246, 336, 1051, 1252, 798, 1254, 1063, 336,
+ 336, 336, 336, 336, 336, 339, 336, 336, 336, 336,
+ 336, 336, 336, 343, 344, 344, 344, 344, 344, 344,
+ 344, 345, 620, 396, 614, 346, 1185, 347, 397, 1286,
+ 622, 346, 346, 346, 346, 346, 346, 398, 615, 399,
+ 400, 1437, 401, 428, 429, 429, 429, 429, 429, 429,
+ 55, 614, 55, 347, 263, 351, 351, 351, 351, 351,
+ 351, 351, 265, 1113, 615, 1437, 352, 1437, 55, 1333,
+ 55, 616, 352, 352, 352, 352, 352, 352, 353, 354,
+
+ 354, 354, 354, 354, 354, 617, 1335, 800, 1358, 355,
+ 1362, 1437, 55, 1366, 55, 355, 355, 355, 355, 355,
+ 355, 403, 616, 404, 404, 404, 404, 404, 404, 404,
+ 55, 617, 55, 805, 404, 806, 1437, 55, 55, 726,
+ 404, 404, 404, 404, 404, 404, 405, 406, 406, 406,
+ 406, 406, 406, 406, 1370, 55, 55, 55, 407, 809,
+ 408, 1374, 1437, 1390, 407, 407, 407, 407, 407, 407,
+ 491, 491, 491, 491, 491, 491, 491, 521, 522, 522,
+ 522, 522, 522, 522, 673, 724, 408, 409, 407, 407,
+ 407, 407, 407, 407, 407, 53, 1412, 1437, 674, 407,
+
+ 1437, 55, 728, 1213, 673, 407, 407, 407, 407, 407,
+ 407, 411, 412, 412, 412, 412, 412, 412, 1437, 55,
+ 426, 1437, 413, 1437, 674, 1437, 1437, 55, 413, 413,
+ 413, 413, 413, 413, 253, 414, 414, 414, 414, 414,
+ 414, 414, 1210, 426, 1437, 55, 415, 1437, 1437, 857,
+ 1437, 1437, 415, 415, 415, 415, 415, 415, 53, 415,
+ 415, 415, 415, 415, 415, 415, 418, 419, 419, 419,
+ 419, 419, 419, 1207, 1437, 857, 1437, 420, 426, 55,
+ 55, 55, 1204, 420, 420, 420, 420, 420, 420, 424,
+ 425, 425, 425, 425, 425, 425, 426, 55, 55, 55,
+
+ 427, 426, 885, 886, 887, 55, 427, 427, 427, 427,
+ 427, 427, 343, 430, 430, 430, 430, 430, 430, 430,
+ 345, 668, 53, 55, 431, 1201, 55, 55, 889, 821,
+ 431, 431, 431, 431, 431, 431, 432, 433, 433, 433,
+ 433, 433, 433, 426, 55, 55, 426, 434, 53, 891,
+ 892, 55, 55, 434, 434, 434, 434, 434, 434, 263,
+ 439, 439, 439, 439, 439, 439, 439, 265, 677, 55,
+ 55, 440, 894, 973, 1113, 55, 824, 440, 440, 440,
+ 440, 440, 440, 441, 442, 442, 442, 442, 442, 442,
+ 442, 443, 688, 55, 426, 444, 1437, 445, 994, 973,
+
+ 827, 444, 444, 444, 444, 444, 444, 525, 526, 526,
+ 526, 526, 526, 526, 594, 595, 595, 595, 595, 595,
+ 595, 426, 1437, 445, 454, 1278, 1437, 1213, 455, 1437,
+ 55, 456, 55, 682, 457, 682, 458, 459, 460, 461,
+ 488, 488, 488, 488, 488, 488, 488, 683, 55, 1437,
+ 55, 488, 1437, 990, 55, 1437, 721, 488, 488, 488,
+ 488, 488, 488, 489, 490, 490, 490, 490, 490, 490,
+ 53, 793, 55, 683, 491, 1437, 1437, 1437, 1437, 795,
+ 491, 491, 491, 491, 491, 491, 405, 492, 492, 492,
+ 492, 492, 492, 492, 493, 493, 493, 493, 493, 493,
+
+ 493, 1210, 1437, 1437, 1437, 493, 1437, 55, 55, 55,
+ 55, 493, 493, 493, 493, 493, 493, 410, 495, 495,
+ 495, 495, 495, 495, 495, 55, 55, 55, 55, 496,
+ 1207, 251, 1437, 996, 1204, 496, 496, 496, 496, 496,
+ 496, 602, 603, 603, 603, 603, 603, 603, 606, 607,
+ 607, 607, 607, 607, 607, 55, 684, 251, 496, 496,
+ 496, 496, 496, 496, 496, 1437, 1201, 1044, 1437, 496,
+ 685, 1056, 1278, 55, 723, 496, 496, 496, 496, 496,
+ 496, 497, 497, 497, 497, 497, 497, 497, 53, 1185,
+ 801, 1437, 498, 1044, 1437, 1437, 685, 1056, 498, 498,
+
+ 498, 498, 498, 498, 53, 498, 498, 498, 498, 498,
+ 498, 498, 343, 501, 501, 501, 501, 501, 501, 501,
+ 502, 1437, 684, 982, 503, 1063, 347, 426, 1213, 864,
+ 503, 503, 503, 503, 503, 503, 1437, 693, 694, 694,
+ 694, 694, 694, 694, 696, 697, 697, 697, 697, 697,
+ 697, 55, 347, 507, 508, 508, 508, 508, 508, 508,
+ 508, 509, 1437, 1059, 1057, 510, 1051, 511, 426, 55,
+ 1210, 510, 510, 510, 510, 510, 510, 700, 701, 701,
+ 701, 701, 701, 701, 751, 752, 752, 752, 752, 752,
+ 752, 787, 55, 511, 343, 514, 514, 514, 514, 514,
+
+ 514, 514, 502, 852, 1047, 788, 515, 1045, 1437, 1176,
+ 55, 55, 515, 515, 515, 515, 515, 515, 516, 517,
+ 517, 517, 517, 517, 517, 517, 518, 803, 1039, 55,
+ 519, 788, 520, 1089, 1437, 1176, 519, 519, 519, 519,
+ 519, 519, 759, 760, 760, 760, 760, 760, 760, 763,
+ 764, 764, 764, 764, 764, 764, 787, 55, 520, 441,
+ 527, 527, 527, 527, 527, 527, 527, 443, 426, 1207,
+ 1437, 528, 1437, 55, 841, 55, 789, 528, 528, 528,
+ 528, 528, 528, 529, 530, 530, 530, 530, 530, 530,
+ 790, 55, 890, 1035, 531, 1092, 1437, 55, 1437, 55,
+
+ 531, 531, 531, 531, 531, 531, 569, 789, 570, 570,
+ 570, 570, 570, 570, 570, 55, 790, 55, 1033, 570,
+ 1093, 1437, 1028, 426, 55, 570, 570, 570, 570, 570,
+ 570, 571, 572, 572, 572, 572, 572, 572, 572, 1204,
+ 832, 1188, 55, 573, 1191, 574, 832, 1437, 1003, 573,
+ 573, 573, 573, 573, 573, 771, 772, 772, 772, 772,
+ 772, 772, 774, 775, 775, 775, 775, 775, 775, 837,
+ 55, 574, 571, 573, 573, 573, 573, 573, 573, 573,
+ 1437, 841, 1024, 838, 573, 1437, 1019, 426, 55, 1006,
+ 573, 573, 573, 573, 573, 573, 410, 576, 576, 576,
+
+ 576, 576, 576, 576, 852, 864, 1437, 895, 577, 838,
+ 1437, 1437, 1009, 1012, 577, 577, 577, 577, 577, 577,
+ 53, 577, 577, 577, 577, 577, 577, 577, 578, 578,
+ 578, 578, 578, 578, 578, 1201, 1437, 426, 1115, 579,
+ 1437, 1437, 1235, 1243, 1220, 579, 579, 579, 579, 579,
+ 579, 53, 579, 579, 579, 579, 579, 579, 579, 582,
+ 583, 583, 583, 583, 583, 583, 1437, 1437, 1235, 1243,
+ 584, 1251, 1437, 55, 55, 55, 584, 584, 584, 584,
+ 584, 584, 343, 430, 430, 430, 430, 430, 430, 430,
+ 502, 55, 55, 55, 431, 1332, 55, 1251, 1437, 837,
+
+ 431, 431, 431, 431, 431, 431, 585, 586, 586, 586,
+ 586, 586, 586, 1437, 55, 1189, 1190, 587, 1096, 1194,
+ 55, 1332, 1213, 587, 587, 587, 587, 587, 587, 591,
+ 592, 592, 592, 592, 592, 592, 426, 1210, 55, 1437,
+ 593, 1207, 1204, 1201, 55, 55, 593, 593, 593, 593,
+ 593, 593, 507, 596, 596, 596, 596, 596, 596, 596,
+ 509, 980, 55, 55, 597, 1096, 980, 55, 55, 982,
+ 597, 597, 597, 597, 597, 597, 598, 599, 599, 599,
+ 599, 599, 599, 426, 1192, 55, 55, 600, 1185, 982,
+ 55, 55, 55, 600, 600, 600, 600, 600, 600, 516,
+
+ 608, 608, 608, 608, 608, 608, 608, 518, 55, 55,
+ 55, 609, 793, 1341, 1273, 55, 976, 609, 609, 609,
+ 609, 609, 609, 610, 611, 611, 611, 611, 611, 611,
+ 426, 1019, 974, 55, 612, 1361, 1342, 1065, 55, 1201,
+ 612, 612, 612, 612, 612, 612, 441, 618, 618, 618,
+ 618, 618, 618, 618, 443, 1028, 55, 1365, 619, 1369,
+ 1373, 1361, 426, 1204, 619, 619, 619, 619, 619, 619,
+ 620, 621, 621, 621, 621, 621, 621, 621, 622, 1039,
+ 1343, 1012, 623, 1365, 624, 1369, 1373, 1207, 623, 623,
+ 623, 623, 623, 623, 778, 779, 779, 779, 779, 779,
+
+ 779, 694, 694, 694, 694, 694, 694, 694, 55, 846,
+ 624, 648, 648, 648, 648, 648, 648, 648, 1411, 1051,
+ 1419, 1420, 648, 847, 1053, 55, 55, 1210, 648, 648,
+ 648, 648, 648, 648, 649, 649, 649, 649, 649, 649,
+ 649, 888, 1063, 55, 1411, 649, 1419, 1420, 1421, 847,
+ 1213, 649, 649, 649, 649, 649, 649, 571, 650, 650,
+ 650, 650, 650, 650, 650, 651, 651, 651, 651, 651,
+ 651, 651, 1113, 1183, 1421, 1422, 651, 1423, 55, 55,
+ 1278, 1185, 651, 651, 651, 651, 651, 651, 410, 653,
+ 653, 653, 653, 653, 653, 653, 55, 55, 426, 1009,
+
+ 654, 1422, 1428, 1423, 1434, 1274, 654, 654, 654, 654,
+ 654, 654, 53, 654, 654, 654, 654, 654, 654, 654,
+ 655, 655, 655, 655, 655, 655, 655, 1183, 1428, 1041,
+ 1434, 656, 426, 1006, 1030, 1437, 426, 656, 656, 656,
+ 656, 656, 656, 53, 656, 656, 656, 656, 656, 656,
+ 656, 507, 659, 659, 659, 659, 659, 659, 659, 660,
+ 55, 846, 848, 661, 1003, 511, 55, 1021, 848, 661,
+ 661, 661, 661, 661, 661, 1437, 849, 426, 55, 1115,
+ 426, 1096, 1437, 1012, 55, 55, 1009, 55, 1006, 55,
+ 802, 511, 516, 662, 662, 662, 662, 662, 662, 662,
+
+ 663, 1437, 849, 55, 664, 55, 520, 55, 1437, 55,
+ 664, 664, 664, 664, 664, 664, 810, 807, 1003, 319,
+ 815, 815, 815, 815, 815, 815, 815, 55, 858, 858,
+ 860, 55, 520, 668, 669, 669, 669, 669, 669, 669,
+ 669, 670, 859, 1437, 861, 671, 1088, 672, 1096, 55,
+ 860, 671, 671, 671, 671, 671, 671, 772, 772, 772,
+ 772, 772, 772, 772, 1437, 55, 989, 982, 859, 1437,
+ 861, 974, 795, 672, 507, 675, 675, 675, 675, 675,
+ 675, 675, 660, 55, 864, 975, 676, 1065, 1012, 55,
+ 1437, 1388, 676, 676, 676, 676, 676, 676, 677, 678,
+
+ 678, 678, 678, 678, 678, 678, 679, 55, 688, 860,
+ 680, 975, 681, 858, 852, 1053, 680, 680, 680, 680,
+ 680, 680, 870, 871, 871, 871, 871, 871, 871, 873,
+ 874, 874, 874, 874, 874, 874, 974, 55, 681, 516,
+ 686, 686, 686, 686, 686, 686, 686, 663, 1009, 677,
+ 1437, 687, 848, 846, 841, 55, 991, 687, 687, 687,
+ 687, 687, 687, 688, 689, 689, 689, 689, 689, 689,
+ 689, 690, 1041, 992, 1006, 691, 1437, 692, 668, 55,
+ 55, 691, 691, 691, 691, 691, 691, 877, 878, 878,
+ 878, 878, 878, 878, 837, 832, 1030, 55, 55, 1003,
+
+ 976, 976, 55, 692, 620, 702, 702, 702, 702, 702,
+ 702, 702, 622, 893, 977, 1437, 703, 1091, 1021, 918,
+ 55, 903, 703, 703, 703, 703, 703, 703, 704, 705,
+ 705, 705, 705, 705, 705, 985, 1012, 1009, 1006, 706,
+ 977, 1437, 1003, 1001, 903, 706, 706, 706, 706, 706,
+ 706, 53, 53, 53, 53, 53, 53, 53, 793, 982,
+ 795, 620, 53, 55, 55, 55, 55, 55, 53, 53,
+ 53, 53, 53, 53, 922, 923, 923, 923, 923, 923,
+ 923, 55, 55, 55, 55, 55, 708, 726, 789, 727,
+ 727, 727, 727, 727, 727, 727, 986, 987, 988, 993,
+
+ 727, 995, 1340, 55, 55, 55, 727, 727, 727, 727,
+ 727, 727, 930, 931, 931, 931, 931, 931, 931, 1024,
+ 1024, 55, 55, 55, 53, 728, 729, 729, 729, 729,
+ 729, 729, 729, 1025, 1437, 1087, 1090, 729, 1195, 787,
+ 866, 827, 854, 729, 729, 729, 729, 729, 729, 934,
+ 935, 935, 935, 935, 935, 935, 824, 843, 821, 1025,
+ 1437, 53, 650, 650, 650, 650, 650, 650, 650, 942,
+ 943, 943, 943, 943, 943, 943, 945, 946, 946, 946,
+ 946, 946, 946, 949, 950, 950, 950, 950, 950, 950,
+ 958, 959, 959, 959, 959, 959, 959, 53, 651, 651,
+
+ 651, 651, 651, 651, 651, 834, 918, 903, 827, 651,
+ 824, 821, 903, 795, 622, 651, 651, 651, 651, 651,
+ 651, 730, 331, 331, 331, 331, 331, 331, 331, 253,
+ 732, 732, 732, 732, 732, 732, 732, 688, 866, 827,
+ 516, 733, 684, 682, 677, 854, 824, 733, 733, 733,
+ 733, 733, 733, 53, 733, 733, 733, 733, 733, 733,
+ 733, 736, 737, 737, 737, 737, 737, 737, 507, 673,
+ 668, 843, 738, 821, 834, 831, 747, 735, 738, 738,
+ 738, 738, 738, 738, 507, 596, 596, 596, 596, 596,
+ 596, 596, 660, 827, 824, 821, 597, 819, 735, 620,
+
+ 795, 1033, 597, 597, 597, 597, 597, 597, 739, 740,
+ 740, 740, 740, 740, 740, 1034, 622, 441, 616, 741,
+ 614, 690, 663, 679, 660, 741, 741, 741, 741, 741,
+ 741, 516, 608, 608, 608, 608, 608, 608, 608, 663,
+ 670, 1034, 747, 609, 735, 663, 660, 735, 1033, 609,
+ 609, 609, 609, 609, 609, 742, 743, 743, 743, 743,
+ 743, 743, 1437, 53, 53, 53, 744, 722, 53, 53,
+ 716, 622, 744, 744, 744, 744, 744, 744, 748, 749,
+ 749, 749, 749, 749, 749, 426, 443, 516, 1437, 750,
+ 690, 663, 343, 512, 507, 750, 750, 750, 750, 750,
+
+ 750, 668, 753, 753, 753, 753, 753, 753, 753, 670,
+ 679, 660, 670, 754, 667, 590, 581, 663, 660, 754,
+ 754, 754, 754, 754, 754, 755, 756, 756, 756, 756,
+ 756, 756, 426, 658, 581, 571, 757, 569, 647, 646,
+ 645, 644, 757, 757, 757, 757, 757, 757, 677, 765,
+ 765, 765, 765, 765, 765, 765, 679, 643, 642, 641,
+ 766, 640, 639, 638, 637, 636, 766, 766, 766, 766,
+ 766, 766, 767, 768, 768, 768, 768, 768, 768, 426,
+ 635, 634, 633, 769, 632, 631, 630, 629, 628, 769,
+ 769, 769, 769, 769, 769, 688, 780, 780, 780, 780,
+
+ 780, 780, 780, 690, 627, 626, 625, 781, 441, 622,
+ 443, 437, 518, 781, 781, 781, 781, 781, 781, 782,
+ 783, 783, 783, 783, 783, 783, 426, 502, 509, 590,
+ 784, 581, 502, 581, 575, 575, 784, 784, 784, 784,
+ 784, 784, 620, 791, 791, 791, 791, 791, 791, 791,
+ 622, 568, 567, 566, 792, 565, 564, 563, 562, 561,
+ 792, 792, 792, 792, 792, 792, 793, 794, 794, 794,
+ 794, 794, 794, 794, 795, 560, 316, 225, 796, 559,
+ 797, 558, 557, 556, 796, 796, 796, 796, 796, 796,
+ 961, 962, 962, 962, 962, 962, 962, 965, 966, 966,
+
+ 966, 966, 966, 966, 1035, 1035, 797, 55, 1045, 811,
+ 811, 811, 811, 811, 811, 811, 555, 554, 1036, 1437,
+ 811, 553, 1046, 552, 551, 55, 811, 811, 811, 811,
+ 811, 811, 812, 812, 812, 812, 812, 812, 812, 550,
+ 549, 548, 545, 812, 1036, 1437, 542, 541, 1046, 812,
+ 812, 812, 812, 812, 812, 813, 814, 814, 814, 814,
+ 814, 814, 540, 539, 538, 537, 815, 536, 55, 535,
+ 534, 533, 815, 815, 815, 815, 815, 815, 253, 816,
+ 816, 816, 816, 816, 816, 816, 55, 443, 265, 426,
+ 817, 343, 518, 502, 509, 1387, 817, 817, 817, 817,
+
+ 817, 817, 53, 817, 817, 817, 817, 817, 817, 817,
+ 668, 820, 820, 820, 820, 820, 820, 820, 821, 426,
+ 506, 423, 822, 417, 672, 502, 500, 417, 822, 822,
+ 822, 822, 822, 822, 871, 871, 871, 871, 871, 871,
+ 871, 943, 943, 943, 943, 943, 943, 943, 1045, 409,
+ 672, 677, 823, 823, 823, 823, 823, 823, 823, 824,
+ 403, 1047, 1437, 825, 487, 681, 486, 1047, 1057, 825,
+ 825, 825, 825, 825, 825, 1048, 485, 484, 483, 482,
+ 481, 1437, 1058, 480, 479, 478, 477, 55, 1437, 1057,
+ 476, 681, 688, 826, 826, 826, 826, 826, 826, 826,
+
+ 827, 1048, 475, 1437, 828, 55, 692, 1437, 1058, 1059,
+ 828, 828, 828, 828, 828, 828, 959, 959, 959, 959,
+ 959, 959, 959, 1060, 1386, 472, 471, 468, 1059, 1437,
+ 1177, 467, 692, 832, 833, 833, 833, 833, 833, 833,
+ 833, 834, 1437, 466, 1178, 835, 465, 836, 464, 1060,
+ 1177, 835, 835, 835, 835, 835, 835, 1069, 1070, 1070,
+ 1070, 1070, 1070, 1070, 1437, 114, 463, 462, 1437, 1179,
+ 1178, 1179, 453, 836, 668, 839, 839, 839, 839, 839,
+ 839, 839, 821, 1180, 452, 1437, 840, 451, 450, 449,
+ 1437, 448, 840, 840, 840, 840, 840, 840, 841, 842,
+
+ 842, 842, 842, 842, 842, 842, 843, 447, 446, 1180,
+ 844, 1437, 845, 263, 443, 265, 844, 844, 844, 844,
+ 844, 844, 1072, 1073, 1073, 1073, 1073, 1073, 1073, 1076,
+ 1077, 1077, 1077, 1077, 1077, 1077, 1223, 426, 845, 677,
+ 850, 850, 850, 850, 850, 850, 850, 824, 345, 423,
+ 1224, 851, 417, 417, 410, 410, 402, 851, 851, 851,
+ 851, 851, 851, 852, 853, 853, 853, 853, 853, 853,
+ 853, 854, 55, 55, 1223, 855, 1224, 856, 395, 394,
+ 391, 855, 855, 855, 855, 855, 855, 390, 1437, 389,
+ 55, 55, 1119, 1120, 1120, 1120, 1120, 1120, 1120, 1228,
+
+ 388, 1084, 1085, 856, 688, 862, 862, 862, 862, 862,
+ 862, 862, 827, 1229, 1437, 387, 863, 386, 385, 384,
+ 383, 382, 863, 863, 863, 863, 863, 863, 864, 865,
+ 865, 865, 865, 865, 865, 865, 866, 55, 1228, 1229,
+ 867, 381, 868, 380, 379, 55, 867, 867, 867, 867,
+ 867, 867, 1437, 378, 377, 55, 1125, 1126, 1126, 1126,
+ 1126, 1126, 1126, 55, 376, 1230, 1086, 375, 868, 793,
+ 879, 879, 879, 879, 879, 879, 879, 795, 1437, 1231,
+ 370, 880, 1415, 369, 298, 368, 1230, 880, 880, 880,
+ 880, 880, 880, 881, 882, 882, 882, 882, 882, 882,
+
+ 1437, 367, 366, 365, 883, 1231, 364, 363, 357, 265,
+ 883, 883, 883, 883, 883, 883, 55, 1236, 896, 896,
+ 896, 896, 896, 896, 896, 345, 1437, 261, 342, 896,
+ 258, 1237, 338, 252, 55, 896, 896, 896, 896, 896,
+ 896, 897, 897, 897, 897, 897, 897, 897, 246, 137,
+ 326, 325, 897, 324, 319, 298, 318, 1237, 897, 897,
+ 897, 897, 897, 897, 575, 898, 898, 898, 898, 898,
+ 898, 898, 317, 316, 315, 314, 899, 313, 408, 312,
+ 311, 310, 899, 899, 899, 899, 899, 899, 1129, 1130,
+ 1130, 1130, 1130, 1130, 1130, 1135, 1136, 1136, 1136, 1136,
+
+ 1136, 1136, 309, 1236, 408, 899, 899, 899, 899, 899,
+ 899, 899, 308, 307, 306, 305, 899, 1437, 304, 301,
+ 300, 299, 899, 899, 899, 899, 899, 899, 253, 900,
+ 900, 900, 900, 900, 900, 900, 298, 297, 296, 295,
+ 901, 294, 293, 1437, 292, 291, 901, 901, 901, 901,
+ 901, 901, 53, 901, 901, 901, 901, 901, 901, 901,
+ 904, 905, 905, 905, 905, 905, 905, 290, 289, 288,
+ 287, 906, 286, 285, 284, 283, 137, 906, 906, 906,
+ 906, 906, 906, 668, 753, 753, 753, 753, 753, 753,
+ 753, 821, 282, 281, 280, 754, 279, 278, 277, 276,
+
+ 1238, 754, 754, 754, 754, 754, 754, 907, 908, 908,
+ 908, 908, 908, 908, 1239, 275, 274, 273, 909, 272,
+ 271, 270, 269, 268, 909, 909, 909, 909, 909, 909,
+ 677, 765, 765, 765, 765, 765, 765, 765, 824, 265,
+ 1239, 253, 766, 258, 245, 244, 243, 1238, 766, 766,
+ 766, 766, 766, 766, 910, 911, 911, 911, 911, 911,
+ 911, 1437, 242, 241, 240, 912, 239, 238, 237, 236,
+ 233, 912, 912, 912, 912, 912, 912, 688, 780, 780,
+ 780, 780, 780, 780, 780, 827, 230, 1437, 227, 781,
+ 226, 225, 224, 221, 1244, 781, 781, 781, 781, 781,
+
+ 781, 913, 914, 914, 914, 914, 914, 914, 1245, 220,
+ 219, 218, 915, 217, 216, 215, 214, 213, 915, 915,
+ 915, 915, 915, 915, 919, 920, 920, 920, 920, 920,
+ 920, 426, 212, 211, 1245, 921, 210, 209, 208, 207,
+ 206, 921, 921, 921, 921, 921, 921, 832, 924, 924,
+ 924, 924, 924, 924, 924, 834, 202, 201, 191, 925,
+ 190, 189, 186, 185, 184, 925, 925, 925, 925, 925,
+ 925, 926, 927, 927, 927, 927, 927, 927, 426, 183,
+ 182, 181, 928, 180, 179, 175, 174, 173, 928, 928,
+ 928, 928, 928, 928, 841, 936, 936, 936, 936, 936,
+
+ 936, 936, 843, 172, 171, 170, 937, 169, 168, 167,
+ 166, 165, 937, 937, 937, 937, 937, 937, 938, 939,
+ 939, 939, 939, 939, 939, 426, 164, 163, 162, 940,
+ 161, 160, 159, 154, 145, 940, 940, 940, 940, 940,
+ 940, 852, 951, 951, 951, 951, 951, 951, 951, 854,
+ 144, 139, 89, 952, 59, 47, 45, 1437, 1437, 952,
+ 952, 952, 952, 952, 952, 953, 954, 954, 954, 954,
+ 954, 954, 426, 1437, 1437, 1437, 955, 1437, 1437, 1437,
+ 1437, 1437, 955, 955, 955, 955, 955, 955, 864, 967,
+ 967, 967, 967, 967, 967, 967, 866, 1437, 1437, 1437,
+
+ 968, 1437, 1437, 1437, 1437, 1437, 968, 968, 968, 968,
+ 968, 968, 969, 970, 970, 970, 970, 970, 970, 426,
+ 1437, 1437, 1437, 971, 1437, 1437, 1437, 1437, 1437, 971,
+ 971, 971, 971, 971, 971, 793, 978, 978, 978, 978,
+ 978, 978, 978, 795, 1437, 1437, 1437, 979, 1437, 1437,
+ 1437, 1437, 1437, 979, 979, 979, 979, 979, 979, 980,
+ 981, 981, 981, 981, 981, 981, 981, 982, 1437, 1437,
+ 1437, 983, 1437, 984, 1437, 1437, 1437, 983, 983, 983,
+ 983, 983, 983, 1138, 1139, 1139, 1139, 1139, 1139, 1139,
+ 1142, 1143, 1143, 1143, 1143, 1143, 1143, 1437, 1437, 984,
+
+ 55, 575, 997, 997, 997, 997, 997, 997, 997, 1437,
+ 1437, 1437, 1437, 998, 1437, 1437, 1437, 1437, 55, 998,
+ 998, 998, 998, 998, 998, 53, 998, 998, 998, 998,
+ 998, 998, 998, 55, 253, 999, 999, 999, 999, 999,
+ 999, 999, 1149, 1150, 1150, 1150, 1150, 1150, 1150, 1437,
+ 1437, 55, 832, 1002, 1002, 1002, 1002, 1002, 1002, 1002,
+ 1003, 1437, 1437, 1437, 1004, 1437, 836, 1437, 1437, 1437,
+ 1004, 1004, 1004, 1004, 1004, 1004, 1152, 1153, 1153, 1153,
+ 1153, 1153, 1153, 1156, 1157, 1157, 1157, 1157, 1157, 1157,
+ 1437, 1437, 836, 841, 1005, 1005, 1005, 1005, 1005, 1005,
+
+ 1005, 1006, 1437, 1437, 1437, 1007, 1437, 845, 1437, 1437,
+ 1437, 1007, 1007, 1007, 1007, 1007, 1007, 1163, 1164, 1164,
+ 1164, 1164, 1164, 1164, 1166, 1167, 1167, 1167, 1167, 1167,
+ 1167, 1437, 1437, 845, 852, 1008, 1008, 1008, 1008, 1008,
+ 1008, 1008, 1009, 1437, 1437, 1437, 1010, 1437, 856, 1437,
+ 1437, 1437, 1010, 1010, 1010, 1010, 1010, 1010, 1170, 1171,
+ 1171, 1171, 1171, 1171, 1171, 1070, 1070, 1070, 1070, 1070,
+ 1070, 1070, 55, 1437, 856, 864, 1011, 1011, 1011, 1011,
+ 1011, 1011, 1011, 1012, 1437, 1244, 1246, 1013, 1437, 868,
+ 55, 1437, 1437, 1013, 1013, 1013, 1013, 1013, 1013, 1437,
+
+ 1247, 1193, 1215, 1216, 1216, 1216, 1216, 1216, 1216, 1437,
+ 1246, 1437, 1437, 1437, 1252, 868, 1015, 1016, 1016, 1016,
+ 1016, 1016, 1016, 1017, 1437, 1437, 1247, 1018, 1253, 1437,
+ 1437, 1437, 1437, 1018, 1018, 1018, 1018, 1018, 1018, 1019,
+ 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1021, 1437, 1437,
+ 1437, 1022, 1437, 1023, 1253, 1437, 1437, 1022, 1022, 1022,
+ 1022, 1022, 1022, 1136, 1136, 1136, 1136, 1136, 1136, 1136,
+ 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1252, 1437, 1023,
+ 832, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1003, 1437,
+ 1437, 1437, 1027, 1437, 1437, 1437, 1437, 1437, 1027, 1027,
+
+ 1027, 1027, 1027, 1027, 1028, 1029, 1029, 1029, 1029, 1029,
+ 1029, 1029, 1030, 1437, 1437, 1437, 1031, 1437, 1032, 1437,
+ 1437, 1254, 1031, 1031, 1031, 1031, 1031, 1031, 1164, 1164,
+ 1164, 1164, 1164, 1164, 1164, 1255, 1437, 1437, 1437, 1437,
+ 1254, 1437, 1286, 1437, 1032, 841, 1037, 1037, 1037, 1037,
+ 1037, 1037, 1037, 1006, 1437, 1437, 1287, 1038, 1437, 1437,
+ 1437, 1255, 1437, 1038, 1038, 1038, 1038, 1038, 1038, 1039,
+ 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1041, 1437, 1437,
+ 1437, 1042, 1287, 1043, 1437, 1437, 1437, 1042, 1042, 1042,
+ 1042, 1042, 1042, 1260, 1261, 1261, 1261, 1261, 1261, 1261,
+
+ 1263, 1264, 1264, 1264, 1264, 1264, 1264, 1286, 1437, 1043,
+ 852, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1009, 1437,
+ 1437, 1437, 1050, 1437, 1437, 1437, 1437, 1437, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1051, 1052, 1052, 1052, 1052, 1052,
+ 1052, 1052, 1053, 1437, 1437, 1437, 1054, 1437, 1055, 1437,
+ 1437, 1437, 1054, 1054, 1054, 1054, 1054, 1054, 1267, 1268,
+ 1268, 1268, 1268, 1268, 1268, 1292, 1293, 1293, 1293, 1293,
+ 1293, 1293, 1333, 1437, 1055, 864, 1061, 1061, 1061, 1061,
+ 1061, 1061, 1061, 1012, 1437, 1437, 1334, 1062, 1437, 1437,
+ 1437, 1437, 55, 1062, 1062, 1062, 1062, 1062, 1062, 1063,
+
+ 1064, 1064, 1064, 1064, 1064, 1064, 1064, 1065, 55, 1437,
+ 55, 1066, 1334, 1067, 1437, 1437, 1437, 1066, 1066, 1066,
+ 1066, 1066, 1066, 1275, 1437, 1437, 55, 1297, 1298, 1298,
+ 1298, 1298, 1298, 1298, 1437, 1437, 1333, 1276, 1437, 1067,
+ 980, 1078, 1078, 1078, 1078, 1078, 1078, 1078, 982, 1437,
+ 1437, 1437, 1079, 1437, 1437, 1437, 1437, 1335, 1079, 1079,
+ 1079, 1079, 1079, 1079, 1080, 1081, 1081, 1081, 1081, 1081,
+ 1081, 1336, 1437, 1437, 1437, 1082, 1437, 1437, 1437, 1437,
+ 1437, 1082, 1082, 1082, 1082, 1082, 1082, 55, 575, 1094,
+ 1094, 1094, 1094, 1094, 1094, 1094, 1437, 1336, 1437, 1437,
+
+ 901, 1437, 1437, 1437, 1437, 55, 901, 901, 901, 901,
+ 901, 901, 53, 901, 901, 901, 901, 901, 901, 901,
+ 55, 253, 999, 999, 999, 999, 999, 999, 999, 1300,
+ 1301, 1301, 1301, 1301, 1301, 1301, 1437, 1335, 55, 1097,
+ 1098, 1098, 1098, 1098, 1098, 1098, 1437, 1437, 1437, 1437,
+ 1099, 1437, 1437, 1437, 1437, 1437, 1099, 1099, 1099, 1099,
+ 1099, 1099, 832, 924, 924, 924, 924, 924, 924, 924,
+ 1003, 1437, 1437, 1437, 925, 1437, 1437, 1437, 1437, 1358,
+ 925, 925, 925, 925, 925, 925, 1100, 1101, 1101, 1101,
+ 1101, 1101, 1101, 1359, 1437, 1437, 1437, 1102, 1437, 1437,
+
+ 1437, 1437, 1437, 1102, 1102, 1102, 1102, 1102, 1102, 841,
+ 936, 936, 936, 936, 936, 936, 936, 1006, 1437, 1359,
+ 1437, 937, 1437, 1437, 1437, 1437, 1358, 937, 937, 937,
+ 937, 937, 937, 1103, 1104, 1104, 1104, 1104, 1104, 1104,
+ 1437, 1437, 1437, 1437, 1105, 1437, 1437, 1437, 1437, 1437,
+ 1105, 1105, 1105, 1105, 1105, 1105, 852, 951, 951, 951,
+ 951, 951, 951, 951, 1009, 1437, 1437, 1437, 952, 1437,
+ 1437, 1437, 1437, 1362, 952, 952, 952, 952, 952, 952,
+ 1106, 1107, 1107, 1107, 1107, 1107, 1107, 1363, 1437, 1437,
+ 1437, 1108, 1437, 1437, 1437, 1437, 1437, 1108, 1108, 1108,
+
+ 1108, 1108, 1108, 864, 967, 967, 967, 967, 967, 967,
+ 967, 1012, 1437, 1363, 1437, 968, 1437, 1437, 1437, 1437,
+ 1362, 968, 968, 968, 968, 968, 968, 1109, 1110, 1110,
+ 1110, 1110, 1110, 1110, 1437, 1437, 1437, 1437, 1111, 1437,
+ 1437, 1437, 1437, 1437, 1111, 1111, 1111, 1111, 1111, 1111,
+ 1113, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1115, 1437,
+ 1437, 1437, 1116, 1437, 1117, 1437, 1437, 1437, 1116, 1116,
+ 1116, 1116, 1116, 1116, 1306, 1307, 1307, 1307, 1307, 1307,
+ 1307, 1309, 1310, 1310, 1310, 1310, 1310, 1310, 1366, 1437,
+ 1117, 1019, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1021,
+
+ 1437, 1437, 1367, 1122, 1437, 1437, 1437, 1437, 1437, 1122,
+ 1122, 1122, 1122, 1122, 1122, 1028, 1131, 1131, 1131, 1131,
+ 1131, 1131, 1131, 1030, 1437, 1437, 1437, 1132, 1367, 1437,
+ 1437, 1437, 1437, 1132, 1132, 1132, 1132, 1132, 1132, 1039,
+ 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1041, 1437, 1437,
+ 1437, 1145, 1437, 1437, 1437, 1437, 1437, 1145, 1145, 1145,
+ 1145, 1145, 1145, 1051, 1158, 1158, 1158, 1158, 1158, 1158,
+ 1158, 1053, 1437, 1437, 1437, 1159, 1437, 1437, 1437, 1437,
+ 1437, 1159, 1159, 1159, 1159, 1159, 1159, 1063, 1172, 1172,
+ 1172, 1172, 1172, 1172, 1172, 1065, 1437, 1437, 1437, 1173,
+
+ 1437, 1437, 1437, 1437, 1437, 1173, 1173, 1173, 1173, 1173,
+ 1173, 980, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 982,
+ 1437, 1437, 1437, 1182, 1437, 1437, 1437, 1437, 1437, 1182,
+ 1182, 1182, 1182, 1182, 1182, 1183, 1184, 1184, 1184, 1184,
+ 1184, 1184, 1184, 1185, 1437, 1437, 1437, 1186, 1437, 1187,
+ 1437, 1437, 1437, 1186, 1186, 1186, 1186, 1186, 1186, 1315,
+ 1316, 1316, 1316, 1316, 1316, 1316, 1318, 1319, 1319, 1319,
+ 1319, 1319, 1319, 1437, 1437, 1187, 55, 575, 492, 492,
+ 492, 492, 492, 492, 492, 1324, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1437, 1366, 55, 1196, 1197, 1197, 1197, 1197,
+
+ 1197, 1197, 1198, 1437, 1437, 1437, 1199, 1437, 1437, 1437,
+ 1437, 1437, 1199, 1199, 1199, 1199, 1199, 1199, 1019, 1200,
+ 1200, 1200, 1200, 1200, 1200, 1200, 1201, 1437, 1437, 1437,
+ 1202, 1437, 1023, 1437, 1437, 1437, 1202, 1202, 1202, 1202,
+ 1202, 1202, 1327, 1328, 1328, 1328, 1328, 1328, 1328, 1261,
+ 1261, 1261, 1261, 1261, 1261, 1261, 1437, 1437, 1023, 1028,
+ 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1204, 1437, 1437,
+ 1437, 1205, 1437, 1032, 1437, 1437, 1437, 1205, 1205, 1205,
+ 1205, 1205, 1205, 1352, 1353, 1353, 1353, 1353, 1353, 1353,
+ 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1437, 1437, 1032,
+
+ 1039, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1207, 1437,
+ 1437, 1437, 1208, 1437, 1043, 1437, 1437, 1437, 1208, 1208,
+ 1208, 1208, 1208, 1208, 1307, 1307, 1307, 1307, 1307, 1307,
+ 1307, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1370, 1437,
+ 1043, 1051, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1210,
+ 1437, 1370, 1371, 1211, 1437, 1055, 1437, 1437, 1437, 1211,
+ 1211, 1211, 1211, 1211, 1211, 1437, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1437, 1437, 1437, 1437, 1437, 1371, 1374,
+ 1437, 1055, 1063, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
+ 1213, 1437, 1374, 1375, 1214, 1437, 1067, 1437, 1437, 1437,
+
+ 1214, 1214, 1214, 1214, 1214, 1214, 1437, 1378, 1379, 1379,
+ 1379, 1379, 1379, 1379, 1437, 1437, 1437, 1437, 1437, 1375,
+ 1390, 1437, 1067, 1113, 1217, 1217, 1217, 1217, 1217, 1217,
+ 1217, 1115, 1437, 1437, 1391, 1218, 1437, 1437, 1437, 1437,
+ 1437, 1218, 1218, 1218, 1218, 1218, 1218, 1019, 1225, 1225,
+ 1225, 1225, 1225, 1225, 1225, 1201, 1437, 1437, 1437, 1226,
+ 1391, 1437, 1437, 1437, 1437, 1226, 1226, 1226, 1226, 1226,
+ 1226, 1028, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1204,
+ 1437, 1437, 1437, 1233, 1437, 1437, 1437, 1437, 1437, 1233,
+ 1233, 1233, 1233, 1233, 1233, 1039, 1240, 1240, 1240, 1240,
+
+ 1240, 1240, 1240, 1207, 1437, 1437, 1437, 1241, 1437, 1437,
+ 1437, 1437, 1437, 1241, 1241, 1241, 1241, 1241, 1241, 1051,
+ 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1210, 1437, 1437,
+ 1437, 1249, 1437, 1437, 1437, 1437, 1437, 1249, 1249, 1249,
+ 1249, 1249, 1249, 1063, 1256, 1256, 1256, 1256, 1256, 1256,
+ 1256, 1213, 1437, 1437, 1437, 1257, 1437, 1437, 1437, 1437,
+ 1437, 1257, 1257, 1257, 1257, 1257, 1257, 1183, 1269, 1269,
+ 1269, 1269, 1269, 1269, 1269, 1185, 1437, 1437, 1437, 1270,
+ 1437, 1437, 1437, 1437, 1437, 1270, 1270, 1270, 1270, 1270,
+ 1270, 1113, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1278,
+
+ 1437, 1437, 1437, 1279, 1437, 1117, 1437, 1437, 1390, 1279,
+ 1279, 1279, 1279, 1279, 1279, 1381, 1382, 1382, 1382, 1382,
+ 1382, 1382, 1437, 1392, 1393, 1393, 1393, 1393, 1393, 1393,
+ 1437, 1117, 1019, 1121, 1121, 1121, 1121, 1121, 1121, 1121,
+ 1201, 1437, 1437, 1437, 1122, 1437, 1437, 1437, 1437, 1437,
+ 1122, 1122, 1122, 1122, 1122, 1122, 1028, 1131, 1131, 1131,
+ 1131, 1131, 1131, 1131, 1204, 1437, 1437, 1437, 1132, 1437,
+ 1437, 1437, 1437, 1437, 1132, 1132, 1132, 1132, 1132, 1132,
+ 1039, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1207, 1437,
+ 1437, 1437, 1145, 1437, 1437, 1437, 1437, 1437, 1145, 1145,
+
+ 1145, 1145, 1145, 1145, 1051, 1158, 1158, 1158, 1158, 1158,
+ 1158, 1158, 1210, 1437, 1437, 1437, 1159, 1437, 1437, 1437,
+ 1437, 1437, 1159, 1159, 1159, 1159, 1159, 1159, 1063, 1172,
+ 1172, 1172, 1172, 1172, 1172, 1172, 1213, 1437, 1437, 1437,
+ 1173, 1437, 1437, 1437, 1437, 1437, 1173, 1173, 1173, 1173,
+ 1173, 1173, 1113, 1288, 1288, 1288, 1288, 1288, 1288, 1288,
+ 1278, 1437, 1437, 1437, 1289, 1437, 1437, 1437, 1437, 1437,
+ 1289, 1289, 1289, 1289, 1289, 1289, 1183, 1337, 1337, 1337,
+ 1337, 1337, 1337, 1337, 1185, 1437, 1437, 1437, 1338, 1437,
+ 1437, 1437, 1437, 1437, 1338, 1338, 1338, 1338, 1338, 1338,
+
+ 1113, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1278, 1437,
+ 1437, 1437, 1218, 1437, 1437, 1437, 1437, 1437, 1218, 1218,
+ 1218, 1218, 1218, 1218, 1396, 1397, 1397, 1397, 1397, 1397,
+ 1397, 1400, 1401, 1401, 1401, 1401, 1401, 1401, 1404, 1405,
+ 1405, 1405, 1405, 1405, 1405, 1408, 1409, 1409, 1409, 1409,
+ 1409, 1409, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1412,
+ 1412, 1416, 1417, 1417, 1417, 1417, 1417, 1417, 1437, 1437,
+ 1437, 1437, 1437, 1413, 1437, 1393, 1393, 1393, 1393, 1393,
+ 1393, 1393, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1401,
+ 1401, 1401, 1401, 1401, 1401, 1401, 1437, 1437, 1437, 1413,
+
+ 1437, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1409, 1409,
+ 1409, 1409, 1409, 1409, 1409, 1425, 1426, 1426, 1426, 1426,
+ 1426, 1426, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1426,
+ 1426, 1426, 1426, 1426, 1426, 1426, 46, 1437, 1437, 1437,
+ 1437, 46, 46, 46, 64, 1437, 64, 64, 64, 64,
+ 64, 64, 64, 146, 1437, 146, 153, 153, 153, 257,
+ 257, 257, 266, 266, 266, 337, 337, 337, 340, 340,
+ 340, 341, 341, 341, 348, 348, 348, 346, 346, 346,
+ 352, 352, 352, 356, 1437, 356, 416, 416, 416, 421,
+ 421, 421, 422, 422, 422, 431, 431, 431, 435, 1437,
+
+ 435, 436, 436, 436, 350, 350, 1437, 1437, 350, 440,
+ 440, 440, 444, 444, 444, 340, 340, 340, 499, 499,
+ 499, 503, 503, 503, 504, 504, 504, 505, 505, 505,
+ 348, 348, 348, 510, 510, 510, 429, 429, 1437, 1437,
+ 429, 515, 515, 515, 519, 519, 519, 523, 1437, 523,
+ 524, 524, 524, 528, 528, 528, 532, 1437, 532, 580,
+ 580, 580, 431, 431, 431, 588, 588, 588, 589, 589,
+ 589, 597, 597, 597, 601, 1437, 601, 604, 1437, 604,
+ 605, 605, 605, 609, 609, 609, 613, 1437, 613, 522,
+ 522, 1437, 1437, 522, 526, 526, 1437, 1437, 526, 619,
+
+ 619, 619, 623, 623, 623, 532, 532, 1437, 532, 504,
+ 504, 504, 657, 657, 657, 661, 661, 661, 664, 664,
+ 664, 665, 665, 665, 666, 666, 666, 671, 671, 671,
+ 595, 595, 1437, 1437, 595, 676, 676, 676, 680, 680,
+ 680, 601, 601, 1437, 601, 603, 603, 1437, 1437, 603,
+ 604, 604, 1437, 604, 605, 605, 607, 607, 1437, 1437,
+ 607, 687, 687, 687, 691, 691, 691, 613, 613, 1437,
+ 613, 695, 1437, 695, 698, 1437, 698, 699, 699, 699,
+ 703, 703, 703, 707, 1437, 707, 734, 734, 734, 597,
+ 597, 597, 609, 609, 609, 745, 745, 745, 746, 746,
+
+ 746, 754, 754, 754, 758, 1437, 758, 761, 1437, 761,
+ 762, 762, 762, 766, 766, 766, 770, 1437, 770, 773,
+ 1437, 773, 776, 1437, 776, 777, 777, 777, 781, 781,
+ 781, 785, 1437, 785, 694, 1437, 1437, 694, 695, 695,
+ 1437, 695, 697, 697, 1437, 1437, 697, 698, 698, 1437,
+ 698, 699, 699, 701, 701, 1437, 1437, 701, 792, 792,
+ 792, 796, 796, 796, 707, 707, 1437, 707, 53, 53,
+ 53, 1437, 53, 53, 665, 665, 665, 818, 818, 818,
+ 822, 822, 822, 825, 825, 825, 828, 828, 828, 829,
+ 829, 829, 830, 830, 830, 835, 835, 835, 752, 752,
+
+ 1437, 1437, 752, 840, 840, 840, 844, 844, 844, 758,
+ 758, 1437, 758, 760, 760, 1437, 1437, 760, 761, 761,
+ 1437, 761, 762, 762, 764, 764, 1437, 1437, 764, 851,
+ 851, 851, 855, 855, 855, 770, 770, 1437, 770, 772,
+ 1437, 1437, 772, 773, 773, 1437, 773, 775, 775, 1437,
+ 1437, 775, 776, 776, 1437, 776, 777, 777, 779, 779,
+ 1437, 1437, 779, 863, 863, 863, 867, 867, 867, 785,
+ 785, 1437, 785, 869, 1437, 869, 872, 1437, 872, 875,
+ 1437, 875, 876, 876, 876, 880, 880, 880, 884, 1437,
+ 884, 53, 53, 53, 1437, 53, 53, 902, 902, 902,
+
+ 754, 754, 754, 766, 766, 766, 781, 781, 781, 916,
+ 916, 916, 917, 917, 917, 925, 925, 925, 929, 1437,
+ 929, 932, 1437, 932, 933, 933, 933, 937, 937, 937,
+ 941, 1437, 941, 944, 1437, 944, 947, 1437, 947, 948,
+ 948, 948, 952, 952, 952, 956, 1437, 956, 957, 1437,
+ 957, 960, 1437, 960, 963, 1437, 963, 964, 964, 964,
+ 968, 968, 968, 972, 1437, 972, 869, 1437, 869, 871,
+ 1437, 1437, 871, 872, 872, 1437, 872, 874, 874, 1437,
+ 1437, 874, 875, 875, 1437, 875, 876, 876, 878, 878,
+ 1437, 1437, 878, 979, 979, 979, 983, 983, 983, 884,
+
+ 884, 1437, 884, 53, 53, 53, 1437, 53, 53, 829,
+ 829, 829, 1000, 1000, 1000, 1004, 1004, 1004, 1007, 1007,
+ 1007, 1010, 1010, 1010, 1013, 1013, 1013, 1014, 1014, 1014,
+ 1022, 1022, 1022, 923, 923, 1437, 1437, 923, 1027, 1027,
+ 1027, 1031, 1031, 1031, 929, 929, 1437, 929, 931, 931,
+ 1437, 1437, 931, 932, 932, 1437, 932, 933, 933, 935,
+ 935, 1437, 1437, 935, 1038, 1038, 1038, 1042, 1042, 1042,
+ 941, 941, 1437, 941, 943, 1437, 1437, 943, 944, 944,
+ 1437, 944, 946, 946, 1437, 1437, 946, 947, 947, 1437,
+ 947, 948, 948, 950, 950, 1437, 1437, 950, 1050, 1050,
+
+ 1050, 1054, 1054, 1054, 956, 956, 1437, 956, 957, 1437,
+ 957, 959, 1437, 1437, 959, 960, 960, 1437, 960, 962,
+ 962, 1437, 1437, 962, 963, 963, 1437, 963, 964, 964,
+ 966, 966, 1437, 1437, 966, 1062, 1062, 1062, 1066, 1066,
+ 1066, 972, 972, 1437, 972, 1068, 1437, 1068, 1071, 1437,
+ 1071, 1074, 1437, 1074, 1075, 1075, 1075, 1079, 1079, 1079,
+ 1083, 1437, 1083, 53, 53, 53, 1437, 53, 53, 1095,
+ 1095, 1095, 925, 925, 925, 937, 937, 937, 952, 952,
+ 952, 968, 968, 968, 1112, 1112, 1112, 1118, 1118, 1118,
+ 1116, 1116, 1116, 1123, 1123, 1123, 1122, 1122, 1122, 1124,
+
+ 1437, 1124, 1127, 1437, 1127, 1128, 1128, 1128, 1133, 1133,
+ 1133, 1132, 1132, 1132, 1134, 1437, 1134, 1137, 1437, 1137,
+ 1140, 1437, 1140, 1141, 1141, 1141, 1146, 1146, 1146, 1145,
+ 1145, 1145, 1147, 1437, 1147, 1148, 1437, 1148, 1151, 1437,
+ 1151, 1154, 1437, 1154, 1155, 1155, 1155, 1160, 1160, 1160,
+ 1159, 1159, 1159, 1161, 1437, 1161, 1162, 1437, 1162, 1165,
+ 1437, 1165, 1168, 1437, 1168, 1169, 1169, 1169, 1174, 1174,
+ 1174, 1173, 1173, 1173, 1175, 1437, 1175, 1068, 1437, 1068,
+ 1070, 1437, 1437, 1070, 1071, 1071, 1437, 1071, 1073, 1073,
+ 1437, 1437, 1073, 1074, 1074, 1437, 1074, 1075, 1075, 1077,
+
+ 1077, 1437, 1437, 1077, 1182, 1182, 1182, 1186, 1186, 1186,
+ 1083, 1083, 1437, 1083, 53, 53, 53, 1437, 53, 53,
+ 1014, 1014, 1014, 1202, 1202, 1202, 1205, 1205, 1205, 1208,
+ 1208, 1208, 1211, 1211, 1211, 1214, 1214, 1214, 1219, 1219,
+ 1219, 1218, 1218, 1218, 1221, 1437, 1221, 1222, 1222, 1222,
+ 1120, 1120, 1437, 1437, 1120, 1226, 1226, 1226, 1227, 1227,
+ 1227, 1124, 1124, 1437, 1124, 1126, 1126, 1437, 1437, 1126,
+ 1127, 1127, 1437, 1127, 1128, 1128, 1130, 1130, 1437, 1437,
+ 1130, 1233, 1233, 1233, 1234, 1234, 1234, 1134, 1134, 1437,
+ 1134, 1136, 1437, 1437, 1136, 1137, 1137, 1437, 1137, 1139,
+
+ 1139, 1437, 1437, 1139, 1140, 1140, 1437, 1140, 1141, 1141,
+ 1143, 1143, 1437, 1437, 1143, 1241, 1241, 1241, 1242, 1242,
+ 1242, 1147, 1147, 1437, 1147, 1148, 1437, 1148, 1150, 1437,
+ 1437, 1150, 1151, 1151, 1437, 1151, 1153, 1153, 1437, 1437,
+ 1153, 1154, 1154, 1437, 1154, 1155, 1155, 1157, 1157, 1437,
+ 1437, 1157, 1249, 1249, 1249, 1250, 1250, 1250, 1161, 1161,
+ 1437, 1161, 1162, 1437, 1162, 1164, 1437, 1437, 1164, 1165,
+ 1165, 1437, 1165, 1167, 1167, 1437, 1437, 1167, 1168, 1168,
+ 1437, 1168, 1169, 1169, 1171, 1171, 1437, 1437, 1171, 1257,
+ 1257, 1257, 1258, 1258, 1258, 1175, 1175, 1437, 1175, 1259,
+
+ 1437, 1259, 1262, 1437, 1262, 1265, 1437, 1265, 1266, 1266,
+ 1266, 1271, 1437, 1271, 1270, 1270, 1270, 1272, 1437, 1272,
+ 53, 53, 53, 1437, 53, 53, 1280, 1437, 1280, 1279,
+ 1279, 1279, 1281, 1437, 1281, 1122, 1122, 1122, 1282, 1437,
+ 1282, 1132, 1132, 1132, 1283, 1437, 1283, 1145, 1145, 1145,
+ 1284, 1437, 1284, 1159, 1159, 1159, 1285, 1437, 1285, 1173,
+ 1173, 1173, 1216, 1216, 1437, 1437, 1216, 1289, 1289, 1289,
+ 1290, 1290, 1290, 348, 348, 348, 1221, 1221, 1437, 1221,
+ 1291, 1291, 1291, 1294, 1437, 1294, 1295, 1295, 1295, 1296,
+ 1296, 1296, 1299, 1437, 1299, 1302, 1437, 1302, 1303, 1303,
+
+ 1303, 1304, 1304, 1304, 1305, 1437, 1305, 1308, 1437, 1308,
+ 1311, 1437, 1311, 1312, 1312, 1312, 1313, 1313, 1313, 1314,
+ 1437, 1314, 1317, 1437, 1317, 1320, 1437, 1320, 1321, 1321,
+ 1321, 1322, 1322, 1322, 1323, 1437, 1323, 1326, 1437, 1326,
+ 1329, 1437, 1329, 1330, 1330, 1330, 1331, 1331, 1331, 1259,
+ 1437, 1259, 1261, 1437, 1437, 1261, 1262, 1262, 1437, 1262,
+ 1264, 1264, 1437, 1437, 1264, 1265, 1265, 1437, 1265, 1266,
+ 1266, 1268, 1268, 1437, 1437, 1268, 1338, 1338, 1338, 1339,
+ 1437, 1339, 1272, 1272, 1437, 1272, 53, 53, 53, 1437,
+ 53, 53, 1344, 1344, 1344, 1218, 1218, 1218, 1346, 1437,
+
+ 1346, 1347, 1437, 1347, 1348, 1437, 1348, 1349, 1437, 1349,
+ 1350, 1437, 1350, 1351, 1437, 1351, 1354, 1437, 1354, 1355,
+ 1355, 1355, 1356, 1356, 1356, 1357, 1437, 1357, 1293, 1293,
+ 1437, 1437, 1293, 1294, 1294, 1437, 1294, 1295, 1295, 1360,
+ 1437, 1360, 1298, 1437, 1437, 1298, 1299, 1299, 1437, 1299,
+ 1301, 1301, 1437, 1437, 1301, 1302, 1302, 1437, 1302, 1303,
+ 1303, 1364, 1437, 1364, 1305, 1437, 1305, 1307, 1437, 1437,
+ 1307, 1308, 1308, 1437, 1308, 1310, 1310, 1437, 1437, 1310,
+ 1311, 1311, 1437, 1311, 1312, 1312, 1368, 1437, 1368, 1314,
+ 1437, 1314, 1316, 1437, 1437, 1316, 1317, 1317, 1437, 1317,
+
+ 1319, 1319, 1437, 1437, 1319, 1320, 1320, 1437, 1320, 1321,
+ 1321, 1372, 1437, 1372, 1323, 1437, 1323, 1325, 1437, 1437,
+ 1325, 1326, 1326, 1437, 1326, 1328, 1328, 1437, 1437, 1328,
+ 1329, 1329, 1437, 1329, 1330, 1330, 1376, 1437, 1376, 1377,
+ 1437, 1377, 1380, 1437, 1380, 1383, 1437, 1383, 1384, 1384,
+ 1384, 1385, 1437, 1385, 53, 53, 53, 1437, 53, 53,
+ 1389, 1437, 1389, 1291, 1437, 1291, 1296, 1437, 1296, 1304,
+ 1437, 1304, 1313, 1437, 1313, 1322, 1437, 1322, 1331, 1437,
+ 1331, 1353, 1353, 1437, 1437, 1353, 1354, 1354, 1437, 1354,
+ 1355, 1355, 1345, 1437, 1345, 1394, 1437, 1394, 1395, 1437,
+
+ 1395, 1398, 1437, 1398, 1399, 1437, 1399, 1402, 1437, 1402,
+ 1403, 1437, 1403, 1406, 1437, 1406, 1407, 1437, 1407, 1410,
+ 1437, 1410, 1379, 1437, 1437, 1379, 1382, 1382, 1437, 1437,
+ 1382, 1414, 1437, 1414, 1356, 1437, 1356, 1418, 1437, 1418,
+ 1393, 1437, 1437, 1393, 1397, 1437, 1437, 1397, 1401, 1437,
+ 1437, 1401, 1405, 1437, 1437, 1405, 1409, 1437, 1437, 1409,
+ 1424, 1437, 1424, 1427, 1437, 1427, 1417, 1437, 1437, 1417,
+ 1429, 1437, 1429, 1430, 1437, 1430, 1431, 1437, 1431, 1432,
+ 1437, 1432, 1433, 1437, 1433, 1426, 1437, 1437, 1426, 1435,
+ 1437, 1435, 1436, 1437, 1436, 3, 1437, 1437, 1437, 1437,
+
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437
+ } ;
+
+static yyconst flex_int16_t yy_chk[7450] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 4, 7, 15, 4, 7, 4, 7,
+ 9, 4, 7, 9, 34, 9, 17, 17, 9, 19,
+ 19, 4, 7, 34, 24, 27, 27, 100, 9, 4,
+ 7, 15, 12, 100, 128, 12, 9, 12, 24, 23,
+ 12, 23, 23, 26, 28, 24, 23, 26, 1258, 28,
+
+ 12, 23, 128, 26, 29, 23, 26, 23, 12, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 627,
+ 29, 92, 14, 14, 14, 627, 92, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 16, 36, 25, 16, 132, 16, 36, 36,
+ 16, 36, 36, 101, 25, 96, 132, 25, 101, 22,
+ 16, 25, 22, 39, 22, 39, 238, 22, 16, 20,
+ 20, 20, 20, 20, 20, 20, 20, 22, 33, 39,
+ 1262, 123, 33, 20, 35, 22, 39, 1265, 96, 37,
+
+ 238, 33, 33, 37, 123, 33, 35, 33, 35, 104,
+ 35, 37, 104, 35, 104, 237, 37, 237, 37, 20,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 32, 32, 317, 21, 208, 1266, 149, 317, 97, 21,
+ 21, 21, 21, 21, 21, 31, 32, 208, 31, 31,
+ 32, 31, 130, 31, 32, 31, 32, 31, 38, 41,
+ 31, 130, 149, 32, 38, 97, 38, 41, 38, 385,
+ 97, 41, 38, 41, 38, 38, 44, 253, 253, 44,
+ 629, 44, 385, 629, 44, 62, 62, 62, 62, 62,
+ 62, 62, 63, 157, 44, 63, 628, 63, 1270, 388,
+
+ 63, 628, 44, 48, 48, 48, 48, 48, 48, 48,
+ 63, 1272, 260, 388, 48, 410, 410, 1278, 63, 157,
+ 48, 48, 48, 48, 48, 48, 49, 49, 49, 49,
+ 49, 49, 49, 83, 575, 575, 329, 49, 260, 270,
+ 270, 270, 270, 49, 49, 49, 49, 49, 49, 50,
+ 50, 50, 50, 50, 50, 50, 50, 439, 1279, 270,
+ 83, 50, 329, 354, 412, 439, 83, 50, 50, 50,
+ 50, 50, 50, 52, 52, 52, 52, 52, 52, 52,
+ 52, 54, 54, 54, 54, 54, 54, 54, 419, 354,
+ 412, 333, 54, 533, 533, 533, 533, 425, 54, 54,
+
+ 54, 54, 54, 54, 56, 333, 634, 56, 634, 56,
+ 349, 637, 56, 350, 419, 56, 56, 56, 56, 56,
+ 56, 56, 56, 425, 349, 637, 56, 350, 433, 490,
+ 56, 333, 56, 56, 56, 56, 56, 56, 147, 458,
+ 147, 147, 147, 147, 147, 147, 147, 460, 458, 1289,
+ 349, 147, 530, 350, 433, 490, 460, 147, 147, 147,
+ 147, 147, 147, 148, 148, 148, 148, 148, 148, 148,
+ 148, 514, 524, 626, 626, 148, 583, 148, 530, 514,
+ 524, 148, 148, 148, 148, 148, 148, 252, 252, 252,
+ 252, 252, 252, 252, 263, 263, 263, 263, 263, 263,
+
+ 263, 428, 583, 148, 150, 150, 150, 150, 150, 150,
+ 150, 150, 586, 592, 1290, 428, 150, 599, 611, 645,
+ 645, 1294, 150, 150, 150, 150, 150, 150, 151, 151,
+ 151, 151, 151, 151, 151, 151, 151, 618, 586, 592,
+ 151, 428, 1295, 599, 611, 618, 151, 151, 151, 151,
+ 151, 151, 152, 152, 152, 152, 152, 152, 152, 152,
+ 154, 154, 154, 154, 154, 154, 154, 154, 635, 1299,
+ 652, 154, 635, 1302, 631, 636, 708, 154, 154, 154,
+ 154, 154, 154, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 631, 636, 708, 156, 652, 156, 654, 287,
+
+ 710, 156, 156, 156, 156, 156, 156, 287, 339, 339,
+ 339, 339, 339, 339, 339, 1303, 1308, 429, 710, 494,
+ 287, 711, 632, 156, 246, 246, 246, 246, 246, 246,
+ 246, 429, 632, 494, 654, 246, 287, 716, 1311, 711,
+ 1312, 246, 246, 246, 246, 246, 246, 248, 248, 248,
+ 248, 248, 248, 248, 630, 716, 711, 429, 248, 494,
+ 716, 693, 705, 630, 248, 248, 248, 248, 248, 248,
+ 249, 249, 249, 249, 249, 249, 249, 249, 251, 251,
+ 251, 251, 251, 251, 251, 675, 686, 693, 705, 251,
+ 1317, 709, 720, 675, 686, 251, 251, 251, 251, 251,
+
+ 251, 254, 254, 254, 254, 254, 254, 254, 254, 709,
+ 720, 720, 1320, 254, 1321, 1326, 709, 1329, 1330, 254,
+ 254, 254, 254, 254, 254, 256, 256, 256, 256, 256,
+ 256, 256, 256, 259, 259, 259, 259, 259, 259, 259,
+ 259, 259, 791, 322, 521, 259, 1338, 259, 322, 1354,
+ 791, 259, 259, 259, 259, 259, 259, 322, 521, 322,
+ 322, 737, 322, 343, 343, 343, 343, 343, 343, 343,
+ 722, 522, 712, 259, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 1355, 521, 522, 264, 737, 722, 1380,
+ 712, 525, 264, 264, 264, 264, 264, 264, 265, 265,
+
+ 265, 265, 265, 265, 265, 525, 1383, 712, 1394, 265,
+ 1398, 522, 717, 1402, 718, 265, 265, 265, 265, 265,
+ 265, 327, 526, 327, 327, 327, 327, 327, 327, 327,
+ 717, 525, 718, 717, 327, 718, 526, 723, 721, 727,
+ 327, 327, 327, 327, 327, 327, 328, 328, 328, 328,
+ 328, 328, 328, 328, 1406, 723, 721, 727, 328, 721,
+ 328, 1410, 526, 1418, 328, 328, 328, 328, 328, 328,
+ 409, 409, 409, 409, 409, 409, 409, 437, 437, 437,
+ 437, 437, 437, 437, 594, 644, 328, 330, 330, 330,
+ 330, 330, 330, 330, 330, 644, 1427, 740, 594, 330,
+
+ 743, 729, 729, 1257, 595, 330, 330, 330, 330, 330,
+ 330, 334, 334, 334, 334, 334, 334, 334, 595, 729,
+ 1250, 749, 334, 740, 594, 756, 743, 798, 334, 334,
+ 334, 334, 334, 334, 335, 335, 335, 335, 335, 335,
+ 335, 335, 1249, 1242, 595, 798, 335, 749, 768, 771,
+ 783, 756, 335, 335, 335, 335, 335, 335, 336, 336,
+ 336, 336, 336, 336, 336, 336, 338, 338, 338, 338,
+ 338, 338, 338, 1241, 768, 771, 783, 338, 1234, 799,
+ 800, 801, 1233, 338, 338, 338, 338, 338, 338, 342,
+ 342, 342, 342, 342, 342, 342, 342, 799, 800, 801,
+
+ 342, 1227, 799, 800, 801, 803, 342, 342, 342, 342,
+ 342, 342, 344, 344, 344, 344, 344, 344, 344, 344,
+ 344, 839, 814, 803, 344, 1226, 805, 806, 803, 839,
+ 344, 344, 344, 344, 344, 344, 345, 345, 345, 345,
+ 345, 345, 345, 345, 805, 806, 1222, 345, 814, 805,
+ 806, 808, 810, 345, 345, 345, 345, 345, 345, 351,
+ 351, 351, 351, 351, 351, 351, 351, 351, 850, 808,
+ 810, 351, 808, 870, 1221, 892, 850, 351, 351, 351,
+ 351, 351, 351, 353, 353, 353, 353, 353, 353, 353,
+ 353, 353, 862, 892, 1220, 353, 882, 353, 892, 870,
+
+ 862, 353, 353, 353, 353, 353, 353, 441, 441, 441,
+ 441, 441, 441, 441, 507, 507, 507, 507, 507, 507,
+ 507, 1219, 882, 353, 371, 1218, 905, 1214, 371, 908,
+ 895, 371, 889, 602, 371, 603, 371, 371, 371, 371,
+ 403, 403, 403, 403, 403, 403, 403, 602, 895, 603,
+ 889, 403, 905, 889, 896, 908, 640, 403, 403, 403,
+ 403, 403, 403, 405, 405, 405, 405, 405, 405, 405,
+ 640, 978, 896, 602, 405, 603, 911, 914, 920, 978,
+ 405, 405, 405, 405, 405, 405, 406, 406, 406, 406,
+ 406, 406, 406, 406, 408, 408, 408, 408, 408, 408,
+
+ 408, 1211, 911, 914, 920, 408, 927, 894, 897, 901,
+ 988, 408, 408, 408, 408, 408, 408, 411, 411, 411,
+ 411, 411, 411, 411, 411, 894, 897, 901, 988, 411,
+ 1208, 411, 927, 894, 1205, 411, 411, 411, 411, 411,
+ 411, 512, 512, 512, 512, 512, 512, 512, 516, 516,
+ 516, 516, 516, 516, 516, 713, 606, 411, 413, 413,
+ 413, 413, 413, 413, 413, 939, 1202, 942, 954, 413,
+ 606, 958, 1199, 713, 643, 413, 413, 413, 413, 413,
+ 413, 414, 414, 414, 414, 414, 414, 414, 643, 1186,
+ 713, 939, 414, 942, 954, 970, 606, 958, 414, 414,
+
+ 414, 414, 414, 414, 415, 415, 415, 415, 415, 415,
+ 415, 415, 418, 418, 418, 418, 418, 418, 418, 418,
+ 418, 970, 607, 1182, 418, 1175, 418, 1174, 1173, 1169,
+ 418, 418, 418, 418, 418, 418, 607, 614, 614, 614,
+ 614, 614, 614, 614, 616, 616, 616, 616, 616, 616,
+ 616, 996, 418, 424, 424, 424, 424, 424, 424, 424,
+ 424, 424, 607, 1168, 1165, 424, 1161, 424, 1160, 996,
+ 1159, 424, 424, 424, 424, 424, 424, 620, 620, 620,
+ 620, 620, 620, 620, 668, 668, 668, 668, 668, 668,
+ 668, 696, 715, 424, 430, 430, 430, 430, 430, 430,
+
+ 430, 430, 430, 1155, 1154, 696, 430, 1151, 1016, 1069,
+ 715, 991, 430, 430, 430, 430, 430, 430, 432, 432,
+ 432, 432, 432, 432, 432, 432, 432, 715, 1147, 991,
+ 432, 696, 432, 991, 1016, 1069, 432, 432, 432, 432,
+ 432, 432, 673, 673, 673, 673, 673, 673, 673, 677,
+ 677, 677, 677, 677, 677, 677, 697, 804, 432, 442,
+ 442, 442, 442, 442, 442, 442, 442, 442, 1146, 1145,
+ 697, 442, 1081, 994, 1141, 804, 700, 442, 442, 442,
+ 442, 442, 442, 443, 443, 443, 443, 443, 443, 443,
+ 700, 994, 804, 1140, 443, 994, 697, 995, 1081, 1084,
+
+ 443, 443, 443, 443, 443, 443, 488, 701, 488, 488,
+ 488, 488, 488, 488, 488, 995, 700, 1084, 1137, 488,
+ 995, 701, 1134, 1133, 1087, 488, 488, 488, 488, 488,
+ 488, 489, 489, 489, 489, 489, 489, 489, 489, 1132,
+ 1026, 1084, 1087, 489, 1087, 489, 1128, 701, 1026, 489,
+ 489, 489, 489, 489, 489, 682, 682, 682, 682, 682,
+ 682, 682, 684, 684, 684, 684, 684, 684, 684, 751,
+ 809, 489, 491, 491, 491, 491, 491, 491, 491, 491,
+ 1098, 1037, 1127, 751, 491, 1101, 1124, 1123, 809, 1037,
+ 491, 491, 491, 491, 491, 491, 495, 495, 495, 495,
+
+ 495, 495, 495, 495, 1049, 1061, 1098, 809, 495, 751,
+ 1104, 1101, 1049, 1061, 495, 495, 495, 495, 495, 495,
+ 496, 496, 496, 496, 496, 496, 496, 496, 497, 497,
+ 497, 497, 497, 497, 497, 1122, 1104, 1118, 1116, 497,
+ 1107, 1110, 1135, 1149, 1115, 497, 497, 497, 497, 497,
+ 497, 498, 498, 498, 498, 498, 498, 498, 498, 500,
+ 500, 500, 500, 500, 500, 500, 1107, 1110, 1135, 1149,
+ 500, 1163, 1197, 1085, 1086, 1088, 500, 500, 500, 500,
+ 500, 500, 501, 501, 501, 501, 501, 501, 501, 501,
+ 501, 1085, 1086, 1088, 501, 1260, 1091, 1163, 1197, 752,
+
+ 501, 501, 501, 501, 501, 501, 502, 502, 502, 502,
+ 502, 502, 502, 752, 1091, 1085, 1086, 502, 1112, 1091,
+ 1092, 1260, 1111, 502, 502, 502, 502, 502, 502, 506,
+ 506, 506, 506, 506, 506, 506, 506, 1108, 1092, 752,
+ 506, 1105, 1102, 1099, 1188, 1089, 506, 506, 506, 506,
+ 506, 506, 508, 508, 508, 508, 508, 508, 508, 508,
+ 508, 1181, 1188, 1089, 508, 1095, 1083, 1189, 1190, 1181,
+ 508, 508, 508, 508, 508, 508, 509, 509, 509, 509,
+ 509, 509, 509, 509, 1089, 1189, 1190, 509, 1082, 1079,
+ 1191, 1192, 1274, 509, 509, 509, 509, 509, 509, 517,
+
+ 517, 517, 517, 517, 517, 517, 517, 517, 1191, 1192,
+ 1274, 517, 1075, 1274, 1192, 1275, 1074, 517, 517, 517,
+ 517, 517, 517, 518, 518, 518, 518, 518, 518, 518,
+ 518, 1225, 1071, 1275, 518, 1297, 1275, 1066, 1276, 1225,
+ 518, 518, 518, 518, 518, 518, 527, 527, 527, 527,
+ 527, 527, 527, 527, 527, 1232, 1276, 1306, 527, 1315,
+ 1324, 1297, 1065, 1232, 527, 527, 527, 527, 527, 527,
+ 529, 529, 529, 529, 529, 529, 529, 529, 529, 1240,
+ 1276, 1062, 529, 1306, 529, 1315, 1324, 1240, 529, 529,
+ 529, 529, 529, 529, 688, 688, 688, 688, 688, 688,
+
+ 688, 694, 694, 694, 694, 694, 694, 694, 802, 759,
+ 529, 569, 569, 569, 569, 569, 569, 569, 1378, 1248,
+ 1392, 1396, 569, 759, 1054, 1343, 802, 1248, 569, 569,
+ 569, 569, 569, 569, 571, 571, 571, 571, 571, 571,
+ 571, 802, 1256, 1343, 1378, 571, 1392, 1396, 1400, 759,
+ 1256, 571, 571, 571, 571, 571, 571, 572, 572, 572,
+ 572, 572, 572, 572, 572, 574, 574, 574, 574, 574,
+ 574, 574, 1288, 1337, 1400, 1404, 574, 1408, 1193, 1386,
+ 1288, 1337, 574, 574, 574, 574, 574, 574, 576, 576,
+ 576, 576, 576, 576, 576, 576, 1193, 1386, 1053, 1050,
+
+ 576, 1404, 1416, 1408, 1425, 1193, 576, 576, 576, 576,
+ 576, 576, 577, 577, 577, 577, 577, 577, 577, 577,
+ 578, 578, 578, 578, 578, 578, 578, 1384, 1416, 1042,
+ 1425, 578, 1041, 1038, 1031, 1384, 1030, 578, 578, 578,
+ 578, 578, 578, 579, 579, 579, 579, 579, 579, 579,
+ 579, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 714, 760, 763, 582, 1027, 582, 1388, 1022, 764, 582,
+ 582, 582, 582, 582, 582, 760, 763, 1021, 714, 1018,
+ 1017, 1014, 764, 1013, 1388, 724, 1010, 719, 1007, 725,
+ 714, 582, 585, 585, 585, 585, 585, 585, 585, 585,
+
+ 585, 760, 763, 724, 585, 719, 585, 725, 764, 990,
+ 585, 585, 585, 585, 585, 585, 724, 719, 1004, 725,
+ 731, 731, 731, 731, 731, 731, 731, 990, 774, 775,
+ 778, 888, 585, 591, 591, 591, 591, 591, 591, 591,
+ 591, 591, 774, 775, 778, 591, 990, 591, 1000, 888,
+ 779, 591, 591, 591, 591, 591, 591, 772, 772, 772,
+ 772, 772, 772, 772, 779, 1342, 888, 983, 774, 775,
+ 778, 873, 979, 591, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 1342, 972, 873, 596, 971, 968, 1415,
+ 779, 1342, 596, 596, 596, 596, 596, 596, 598, 598,
+
+ 598, 598, 598, 598, 598, 598, 598, 1415, 964, 963,
+ 598, 873, 598, 960, 956, 955, 598, 598, 598, 598,
+ 598, 598, 787, 787, 787, 787, 787, 787, 787, 789,
+ 789, 789, 789, 789, 789, 789, 874, 890, 598, 608,
+ 608, 608, 608, 608, 608, 608, 608, 608, 952, 948,
+ 874, 608, 947, 944, 941, 890, 890, 608, 608, 608,
+ 608, 608, 608, 610, 610, 610, 610, 610, 610, 610,
+ 610, 610, 940, 890, 937, 610, 874, 610, 933, 993,
+ 807, 610, 610, 610, 610, 610, 610, 793, 793, 793,
+ 793, 793, 793, 793, 932, 929, 928, 993, 807, 925,
+
+ 877, 878, 885, 610, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 807, 877, 878, 621, 993, 921, 917,
+ 885, 916, 621, 621, 621, 621, 621, 621, 622, 622,
+ 622, 622, 622, 622, 622, 885, 915, 912, 909, 622,
+ 877, 878, 906, 903, 902, 622, 622, 622, 622, 622,
+ 622, 625, 625, 625, 625, 625, 625, 625, 884, 883,
+ 880, 876, 625, 886, 887, 891, 893, 1273, 625, 625,
+ 625, 625, 625, 625, 832, 832, 832, 832, 832, 832,
+ 832, 886, 887, 891, 893, 1273, 625, 648, 875, 648,
+ 648, 648, 648, 648, 648, 648, 886, 887, 887, 891,
+
+ 648, 893, 1273, 989, 992, 1093, 648, 648, 648, 648,
+ 648, 648, 837, 837, 837, 837, 837, 837, 837, 922,
+ 923, 989, 992, 1093, 648, 649, 649, 649, 649, 649,
+ 649, 649, 649, 922, 923, 989, 992, 649, 1093, 872,
+ 867, 863, 855, 649, 649, 649, 649, 649, 649, 841,
+ 841, 841, 841, 841, 841, 841, 851, 844, 840, 922,
+ 923, 649, 650, 650, 650, 650, 650, 650, 650, 846,
+ 846, 846, 846, 846, 846, 846, 848, 848, 848, 848,
+ 848, 848, 848, 852, 852, 852, 852, 852, 852, 852,
+ 858, 858, 858, 858, 858, 858, 858, 650, 651, 651,
+
+ 651, 651, 651, 651, 651, 835, 830, 829, 828, 651,
+ 825, 822, 818, 796, 792, 651, 651, 651, 651, 651,
+ 651, 653, 653, 653, 653, 653, 653, 653, 653, 655,
+ 655, 655, 655, 655, 655, 655, 655, 785, 784, 781,
+ 777, 655, 776, 773, 770, 769, 766, 655, 655, 655,
+ 655, 655, 655, 656, 656, 656, 656, 656, 656, 656,
+ 656, 658, 658, 658, 658, 658, 658, 658, 762, 761,
+ 758, 757, 658, 754, 750, 747, 746, 745, 658, 658,
+ 658, 658, 658, 658, 659, 659, 659, 659, 659, 659,
+ 659, 659, 659, 744, 741, 738, 659, 735, 734, 707,
+
+ 706, 930, 659, 659, 659, 659, 659, 659, 660, 660,
+ 660, 660, 660, 660, 660, 930, 703, 699, 698, 660,
+ 695, 691, 687, 680, 676, 660, 660, 660, 660, 660,
+ 660, 662, 662, 662, 662, 662, 662, 662, 662, 662,
+ 671, 930, 666, 662, 665, 664, 661, 657, 931, 662,
+ 662, 662, 662, 662, 662, 663, 663, 663, 663, 663,
+ 663, 663, 931, 647, 646, 642, 663, 641, 639, 638,
+ 633, 623, 663, 663, 663, 663, 663, 663, 667, 667,
+ 667, 667, 667, 667, 667, 667, 619, 613, 931, 667,
+ 612, 609, 605, 604, 601, 667, 667, 667, 667, 667,
+
+ 667, 669, 669, 669, 669, 669, 669, 669, 669, 669,
+ 600, 597, 593, 669, 590, 589, 588, 587, 584, 669,
+ 669, 669, 669, 669, 669, 670, 670, 670, 670, 670,
+ 670, 670, 670, 581, 580, 573, 670, 570, 568, 564,
+ 560, 559, 670, 670, 670, 670, 670, 670, 678, 678,
+ 678, 678, 678, 678, 678, 678, 678, 558, 557, 553,
+ 678, 552, 550, 549, 548, 547, 678, 678, 678, 678,
+ 678, 678, 679, 679, 679, 679, 679, 679, 679, 679,
+ 546, 545, 544, 679, 543, 542, 541, 540, 539, 679,
+ 679, 679, 679, 679, 679, 689, 689, 689, 689, 689,
+
+ 689, 689, 689, 689, 536, 535, 534, 689, 532, 531,
+ 528, 523, 519, 689, 689, 689, 689, 689, 689, 690,
+ 690, 690, 690, 690, 690, 690, 690, 515, 510, 505,
+ 690, 504, 503, 499, 493, 492, 690, 690, 690, 690,
+ 690, 690, 702, 702, 702, 702, 702, 702, 702, 702,
+ 702, 487, 486, 485, 702, 484, 483, 482, 481, 480,
+ 702, 702, 702, 702, 702, 702, 704, 704, 704, 704,
+ 704, 704, 704, 704, 704, 479, 478, 477, 704, 475,
+ 704, 472, 471, 470, 704, 704, 704, 704, 704, 704,
+ 860, 860, 860, 860, 860, 860, 860, 864, 864, 864,
+
+ 864, 864, 864, 864, 934, 935, 704, 726, 945, 726,
+ 726, 726, 726, 726, 726, 726, 469, 468, 934, 935,
+ 726, 467, 945, 466, 464, 726, 726, 726, 726, 726,
+ 726, 726, 728, 728, 728, 728, 728, 728, 728, 463,
+ 462, 461, 459, 728, 934, 935, 457, 456, 945, 728,
+ 728, 728, 728, 728, 728, 730, 730, 730, 730, 730,
+ 730, 730, 455, 454, 453, 452, 730, 451, 1341, 449,
+ 448, 447, 730, 730, 730, 730, 730, 730, 732, 732,
+ 732, 732, 732, 732, 732, 732, 1341, 444, 440, 436,
+ 732, 435, 434, 431, 427, 1341, 732, 732, 732, 732,
+
+ 732, 732, 733, 733, 733, 733, 733, 733, 733, 733,
+ 736, 736, 736, 736, 736, 736, 736, 736, 736, 426,
+ 423, 422, 736, 421, 736, 420, 417, 416, 736, 736,
+ 736, 736, 736, 736, 871, 871, 871, 871, 871, 871,
+ 871, 943, 943, 943, 943, 943, 943, 943, 946, 407,
+ 736, 739, 739, 739, 739, 739, 739, 739, 739, 739,
+ 404, 949, 946, 739, 402, 739, 401, 950, 961, 739,
+ 739, 739, 739, 739, 739, 949, 400, 399, 398, 397,
+ 396, 950, 961, 395, 394, 393, 392, 1340, 946, 962,
+ 391, 739, 742, 742, 742, 742, 742, 742, 742, 742,
+
+ 742, 949, 389, 962, 742, 1340, 742, 950, 961, 965,
+ 742, 742, 742, 742, 742, 742, 959, 959, 959, 959,
+ 959, 959, 959, 965, 1340, 387, 386, 384, 966, 962,
+ 1072, 383, 742, 748, 748, 748, 748, 748, 748, 748,
+ 748, 748, 966, 380, 1072, 748, 379, 748, 377, 965,
+ 1073, 748, 748, 748, 748, 748, 748, 974, 974, 974,
+ 974, 974, 974, 974, 1073, 375, 374, 373, 966, 1076,
+ 1072, 1077, 370, 748, 753, 753, 753, 753, 753, 753,
+ 753, 753, 753, 1076, 369, 1077, 753, 367, 366, 365,
+ 1073, 364, 753, 753, 753, 753, 753, 753, 755, 755,
+
+ 755, 755, 755, 755, 755, 755, 755, 362, 357, 1076,
+ 755, 1077, 755, 356, 355, 352, 755, 755, 755, 755,
+ 755, 755, 976, 976, 976, 976, 976, 976, 976, 980,
+ 980, 980, 980, 980, 980, 980, 1119, 348, 755, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765, 346, 341,
+ 1119, 765, 340, 337, 332, 331, 323, 765, 765, 765,
+ 765, 765, 765, 767, 767, 767, 767, 767, 767, 767,
+ 767, 767, 985, 986, 1120, 767, 1119, 767, 321, 320,
+ 315, 767, 767, 767, 767, 767, 767, 313, 1120, 311,
+ 985, 986, 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1125,
+
+ 310, 985, 986, 767, 780, 780, 780, 780, 780, 780,
+ 780, 780, 780, 1125, 1120, 309, 780, 308, 307, 306,
+ 305, 303, 780, 780, 780, 780, 780, 780, 782, 782,
+ 782, 782, 782, 782, 782, 782, 782, 987, 1126, 1125,
+ 782, 302, 782, 301, 296, 1387, 782, 782, 782, 782,
+ 782, 782, 1126, 293, 292, 987, 1024, 1024, 1024, 1024,
+ 1024, 1024, 1024, 1387, 291, 1129, 987, 288, 782, 794,
+ 794, 794, 794, 794, 794, 794, 794, 794, 1126, 1129,
+ 285, 794, 1387, 284, 282, 280, 1130, 794, 794, 794,
+ 794, 794, 794, 795, 795, 795, 795, 795, 795, 795,
+
+ 1130, 279, 278, 276, 795, 1129, 272, 271, 269, 266,
+ 795, 795, 795, 795, 795, 795, 811, 1138, 811, 811,
+ 811, 811, 811, 811, 811, 262, 1130, 261, 258, 811,
+ 257, 1138, 255, 250, 811, 811, 811, 811, 811, 811,
+ 811, 812, 812, 812, 812, 812, 812, 812, 247, 245,
+ 244, 242, 812, 239, 235, 231, 229, 1138, 812, 812,
+ 812, 812, 812, 812, 813, 813, 813, 813, 813, 813,
+ 813, 813, 227, 226, 224, 223, 813, 222, 813, 221,
+ 220, 219, 813, 813, 813, 813, 813, 813, 1028, 1028,
+ 1028, 1028, 1028, 1028, 1028, 1033, 1033, 1033, 1033, 1033,
+
+ 1033, 1033, 218, 1139, 813, 815, 815, 815, 815, 815,
+ 815, 815, 216, 214, 212, 211, 815, 1139, 209, 207,
+ 206, 204, 815, 815, 815, 815, 815, 815, 816, 816,
+ 816, 816, 816, 816, 816, 816, 201, 200, 199, 197,
+ 816, 195, 194, 1139, 191, 190, 816, 816, 816, 816,
+ 816, 816, 817, 817, 817, 817, 817, 817, 817, 817,
+ 819, 819, 819, 819, 819, 819, 819, 188, 187, 186,
+ 185, 819, 184, 183, 182, 181, 180, 819, 819, 819,
+ 819, 819, 819, 820, 820, 820, 820, 820, 820, 820,
+ 820, 820, 179, 177, 176, 820, 173, 172, 171, 170,
+
+ 1142, 820, 820, 820, 820, 820, 820, 821, 821, 821,
+ 821, 821, 821, 821, 1142, 169, 168, 167, 821, 166,
+ 164, 161, 160, 159, 821, 821, 821, 821, 821, 821,
+ 823, 823, 823, 823, 823, 823, 823, 823, 823, 158,
+ 1142, 155, 823, 153, 144, 143, 142, 1143, 823, 823,
+ 823, 823, 823, 823, 824, 824, 824, 824, 824, 824,
+ 824, 1143, 141, 140, 139, 824, 138, 136, 134, 133,
+ 131, 824, 824, 824, 824, 824, 824, 826, 826, 826,
+ 826, 826, 826, 826, 826, 826, 129, 1143, 127, 826,
+ 126, 125, 124, 122, 1152, 826, 826, 826, 826, 826,
+
+ 826, 827, 827, 827, 827, 827, 827, 827, 1152, 121,
+ 120, 119, 827, 118, 117, 115, 113, 112, 827, 827,
+ 827, 827, 827, 827, 831, 831, 831, 831, 831, 831,
+ 831, 831, 111, 110, 1152, 831, 109, 108, 107, 106,
+ 105, 831, 831, 831, 831, 831, 831, 833, 833, 833,
+ 833, 833, 833, 833, 833, 833, 103, 102, 95, 833,
+ 94, 93, 91, 90, 89, 833, 833, 833, 833, 833,
+ 833, 834, 834, 834, 834, 834, 834, 834, 834, 88,
+ 87, 86, 834, 85, 84, 82, 81, 80, 834, 834,
+ 834, 834, 834, 834, 842, 842, 842, 842, 842, 842,
+
+ 842, 842, 842, 79, 78, 77, 842, 76, 75, 74,
+ 73, 72, 842, 842, 842, 842, 842, 842, 843, 843,
+ 843, 843, 843, 843, 843, 843, 71, 70, 69, 843,
+ 67, 66, 65, 51, 43, 843, 843, 843, 843, 843,
+ 843, 853, 853, 853, 853, 853, 853, 853, 853, 853,
+ 42, 40, 30, 853, 18, 10, 8, 3, 0, 853,
+ 853, 853, 853, 853, 853, 854, 854, 854, 854, 854,
+ 854, 854, 854, 0, 0, 0, 854, 0, 0, 0,
+ 0, 0, 854, 854, 854, 854, 854, 854, 865, 865,
+ 865, 865, 865, 865, 865, 865, 865, 0, 0, 0,
+
+ 865, 0, 0, 0, 0, 0, 865, 865, 865, 865,
+ 865, 865, 866, 866, 866, 866, 866, 866, 866, 866,
+ 0, 0, 0, 866, 0, 0, 0, 0, 0, 866,
+ 866, 866, 866, 866, 866, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 0, 0, 0, 879, 0, 0,
+ 0, 0, 0, 879, 879, 879, 879, 879, 879, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 0, 0,
+ 0, 881, 0, 881, 0, 0, 0, 881, 881, 881,
+ 881, 881, 881, 1035, 1035, 1035, 1035, 1035, 1035, 1035,
+ 1039, 1039, 1039, 1039, 1039, 1039, 1039, 0, 0, 881,
+
+ 898, 898, 898, 898, 898, 898, 898, 898, 898, 0,
+ 0, 0, 0, 898, 0, 0, 0, 0, 898, 898,
+ 898, 898, 898, 898, 898, 899, 899, 899, 899, 899,
+ 899, 899, 899, 900, 900, 900, 900, 900, 900, 900,
+ 900, 900, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 0,
+ 0, 900, 904, 904, 904, 904, 904, 904, 904, 904,
+ 904, 0, 0, 0, 904, 0, 904, 0, 0, 0,
+ 904, 904, 904, 904, 904, 904, 1047, 1047, 1047, 1047,
+ 1047, 1047, 1047, 1051, 1051, 1051, 1051, 1051, 1051, 1051,
+ 0, 0, 904, 907, 907, 907, 907, 907, 907, 907,
+
+ 907, 907, 0, 0, 0, 907, 0, 907, 0, 0,
+ 0, 907, 907, 907, 907, 907, 907, 1057, 1057, 1057,
+ 1057, 1057, 1057, 1057, 1059, 1059, 1059, 1059, 1059, 1059,
+ 1059, 0, 0, 907, 910, 910, 910, 910, 910, 910,
+ 910, 910, 910, 0, 0, 0, 910, 0, 910, 0,
+ 0, 0, 910, 910, 910, 910, 910, 910, 1063, 1063,
+ 1063, 1063, 1063, 1063, 1063, 1070, 1070, 1070, 1070, 1070,
+ 1070, 1070, 1090, 0, 910, 913, 913, 913, 913, 913,
+ 913, 913, 913, 913, 0, 1153, 1156, 913, 0, 913,
+ 1090, 0, 0, 913, 913, 913, 913, 913, 913, 1153,
+
+ 1156, 1090, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 0,
+ 1157, 0, 0, 0, 1166, 913, 918, 918, 918, 918,
+ 918, 918, 918, 918, 1157, 1153, 1156, 918, 1166, 0,
+ 0, 0, 0, 918, 918, 918, 918, 918, 918, 919,
+ 919, 919, 919, 919, 919, 919, 919, 919, 0, 0,
+ 1157, 919, 0, 919, 1166, 0, 0, 919, 919, 919,
+ 919, 919, 919, 1136, 1136, 1136, 1136, 1136, 1136, 1136,
+ 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1167, 0, 919,
+ 924, 924, 924, 924, 924, 924, 924, 924, 924, 0,
+ 0, 1167, 924, 0, 0, 0, 0, 0, 924, 924,
+
+ 924, 924, 924, 924, 926, 926, 926, 926, 926, 926,
+ 926, 926, 926, 0, 0, 0, 926, 1167, 926, 0,
+ 0, 1170, 926, 926, 926, 926, 926, 926, 1164, 1164,
+ 1164, 1164, 1164, 1164, 1164, 1170, 0, 0, 0, 0,
+ 1171, 0, 1215, 0, 926, 936, 936, 936, 936, 936,
+ 936, 936, 936, 936, 1171, 0, 1215, 936, 0, 0,
+ 0, 1170, 0, 936, 936, 936, 936, 936, 936, 938,
+ 938, 938, 938, 938, 938, 938, 938, 938, 0, 0,
+ 1171, 938, 1215, 938, 0, 0, 0, 938, 938, 938,
+ 938, 938, 938, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
+
+ 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1216, 0, 938,
+ 951, 951, 951, 951, 951, 951, 951, 951, 951, 0,
+ 0, 1216, 951, 0, 0, 0, 0, 0, 951, 951,
+ 951, 951, 951, 951, 953, 953, 953, 953, 953, 953,
+ 953, 953, 953, 0, 0, 0, 953, 1216, 953, 0,
+ 0, 0, 953, 953, 953, 953, 953, 953, 1183, 1183,
+ 1183, 1183, 1183, 1183, 1183, 1223, 1223, 1223, 1223, 1223,
+ 1223, 1223, 1263, 0, 953, 967, 967, 967, 967, 967,
+ 967, 967, 967, 967, 0, 0, 1263, 967, 0, 0,
+ 0, 0, 1194, 967, 967, 967, 967, 967, 967, 969,
+
+ 969, 969, 969, 969, 969, 969, 969, 969, 1195, 0,
+ 1194, 969, 1263, 969, 0, 0, 0, 969, 969, 969,
+ 969, 969, 969, 1194, 0, 0, 1195, 1228, 1228, 1228,
+ 1228, 1228, 1228, 1228, 0, 0, 1264, 1195, 0, 969,
+ 981, 981, 981, 981, 981, 981, 981, 981, 981, 0,
+ 1264, 0, 981, 0, 0, 0, 0, 1267, 981, 981,
+ 981, 981, 981, 981, 982, 982, 982, 982, 982, 982,
+ 982, 1267, 0, 0, 0, 982, 1264, 0, 0, 0,
+ 0, 982, 982, 982, 982, 982, 982, 997, 997, 997,
+ 997, 997, 997, 997, 997, 997, 0, 1267, 0, 0,
+
+ 997, 0, 0, 0, 0, 997, 997, 997, 997, 997,
+ 997, 997, 998, 998, 998, 998, 998, 998, 998, 998,
+ 999, 999, 999, 999, 999, 999, 999, 999, 999, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 0, 1268, 999, 1001,
+ 1001, 1001, 1001, 1001, 1001, 1001, 0, 0, 0, 0,
+ 1001, 1268, 0, 0, 0, 0, 1001, 1001, 1001, 1001,
+ 1001, 1001, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002,
+ 1002, 0, 0, 0, 1002, 0, 0, 1268, 0, 1292,
+ 1002, 1002, 1002, 1002, 1002, 1002, 1003, 1003, 1003, 1003,
+ 1003, 1003, 1003, 1292, 0, 0, 0, 1003, 0, 0,
+
+ 0, 0, 0, 1003, 1003, 1003, 1003, 1003, 1003, 1005,
+ 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 0, 1292,
+ 0, 1005, 0, 0, 0, 0, 1293, 1005, 1005, 1005,
+ 1005, 1005, 1005, 1006, 1006, 1006, 1006, 1006, 1006, 1006,
+ 1293, 0, 0, 0, 1006, 0, 0, 0, 0, 0,
+ 1006, 1006, 1006, 1006, 1006, 1006, 1008, 1008, 1008, 1008,
+ 1008, 1008, 1008, 1008, 1008, 0, 1293, 0, 1008, 0,
+ 0, 0, 0, 1300, 1008, 1008, 1008, 1008, 1008, 1008,
+ 1009, 1009, 1009, 1009, 1009, 1009, 1009, 1300, 0, 0,
+ 0, 1009, 0, 0, 0, 0, 0, 1009, 1009, 1009,
+
+ 1009, 1009, 1009, 1011, 1011, 1011, 1011, 1011, 1011, 1011,
+ 1011, 1011, 0, 1300, 0, 1011, 0, 0, 0, 0,
+ 1301, 1011, 1011, 1011, 1011, 1011, 1011, 1012, 1012, 1012,
+ 1012, 1012, 1012, 1012, 1301, 0, 0, 0, 1012, 0,
+ 0, 0, 0, 0, 1012, 1012, 1012, 1012, 1012, 1012,
+ 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 0,
+ 1301, 0, 1015, 0, 1015, 0, 0, 0, 1015, 1015,
+ 1015, 1015, 1015, 1015, 1236, 1236, 1236, 1236, 1236, 1236,
+ 1236, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1309, 0,
+ 1015, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020,
+
+ 0, 0, 1309, 1020, 0, 0, 0, 0, 0, 1020,
+ 1020, 1020, 1020, 1020, 1020, 1029, 1029, 1029, 1029, 1029,
+ 1029, 1029, 1029, 1029, 0, 0, 0, 1029, 1309, 0,
+ 0, 0, 0, 1029, 1029, 1029, 1029, 1029, 1029, 1040,
+ 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, 0, 0,
+ 0, 1040, 0, 0, 0, 0, 0, 1040, 1040, 1040,
+ 1040, 1040, 1040, 1052, 1052, 1052, 1052, 1052, 1052, 1052,
+ 1052, 1052, 0, 0, 0, 1052, 0, 0, 0, 0,
+ 0, 1052, 1052, 1052, 1052, 1052, 1052, 1064, 1064, 1064,
+ 1064, 1064, 1064, 1064, 1064, 1064, 0, 0, 0, 1064,
+
+ 0, 0, 0, 0, 0, 1064, 1064, 1064, 1064, 1064,
+ 1064, 1078, 1078, 1078, 1078, 1078, 1078, 1078, 1078, 1078,
+ 0, 0, 0, 1078, 0, 0, 0, 0, 0, 1078,
+ 1078, 1078, 1078, 1078, 1078, 1080, 1080, 1080, 1080, 1080,
+ 1080, 1080, 1080, 1080, 0, 0, 0, 1080, 0, 1080,
+ 0, 0, 0, 1080, 1080, 1080, 1080, 1080, 1080, 1244,
+ 1244, 1244, 1244, 1244, 1244, 1244, 1246, 1246, 1246, 1246,
+ 1246, 1246, 1246, 0, 0, 1080, 1094, 1094, 1094, 1094,
+ 1094, 1094, 1094, 1094, 1094, 1252, 1252, 1252, 1252, 1252,
+ 1252, 1252, 0, 1310, 1094, 1096, 1096, 1096, 1096, 1096,
+
+ 1096, 1096, 1096, 0, 0, 0, 1096, 1310, 0, 0,
+ 0, 0, 1096, 1096, 1096, 1096, 1096, 1096, 1097, 1097,
+ 1097, 1097, 1097, 1097, 1097, 1097, 1097, 0, 0, 0,
+ 1097, 0, 1097, 1310, 0, 0, 1097, 1097, 1097, 1097,
+ 1097, 1097, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1261,
+ 1261, 1261, 1261, 1261, 1261, 1261, 0, 0, 1097, 1100,
+ 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 0, 0,
+ 0, 1100, 0, 1100, 0, 0, 0, 1100, 1100, 1100,
+ 1100, 1100, 1100, 1286, 1286, 1286, 1286, 1286, 1286, 1286,
+ 1298, 1298, 1298, 1298, 1298, 1298, 1298, 0, 0, 1100,
+
+ 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 0,
+ 0, 0, 1103, 0, 1103, 0, 0, 0, 1103, 1103,
+ 1103, 1103, 1103, 1103, 1307, 1307, 1307, 1307, 1307, 1307,
+ 1307, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1318, 0,
+ 1103, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106,
+ 0, 1319, 1318, 1106, 0, 1106, 0, 0, 0, 1106,
+ 1106, 1106, 1106, 1106, 1106, 1319, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 0, 0, 0, 0, 0, 1318, 1327,
+ 0, 1106, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109,
+ 1109, 1319, 1328, 1327, 1109, 0, 1109, 0, 0, 0,
+
+ 1109, 1109, 1109, 1109, 1109, 1109, 1328, 1333, 1333, 1333,
+ 1333, 1333, 1333, 1333, 0, 0, 0, 0, 0, 1327,
+ 1352, 0, 1109, 1114, 1114, 1114, 1114, 1114, 1114, 1114,
+ 1114, 1114, 1328, 0, 1352, 1114, 0, 0, 0, 0,
+ 0, 1114, 1114, 1114, 1114, 1114, 1114, 1121, 1121, 1121,
+ 1121, 1121, 1121, 1121, 1121, 1121, 0, 0, 0, 1121,
+ 1352, 0, 0, 0, 0, 1121, 1121, 1121, 1121, 1121,
+ 1121, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131,
+ 0, 0, 0, 1131, 0, 0, 0, 0, 0, 1131,
+ 1131, 1131, 1131, 1131, 1131, 1144, 1144, 1144, 1144, 1144,
+
+ 1144, 1144, 1144, 1144, 0, 0, 0, 1144, 0, 0,
+ 0, 0, 0, 1144, 1144, 1144, 1144, 1144, 1144, 1158,
+ 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 0, 0,
+ 0, 1158, 0, 0, 0, 0, 0, 1158, 1158, 1158,
+ 1158, 1158, 1158, 1172, 1172, 1172, 1172, 1172, 1172, 1172,
+ 1172, 1172, 0, 0, 0, 1172, 0, 0, 0, 0,
+ 0, 1172, 1172, 1172, 1172, 1172, 1172, 1184, 1184, 1184,
+ 1184, 1184, 1184, 1184, 1184, 1184, 0, 0, 0, 1184,
+ 0, 0, 0, 0, 0, 1184, 1184, 1184, 1184, 1184,
+ 1184, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196,
+
+ 0, 0, 0, 1196, 0, 1196, 0, 0, 1353, 1196,
+ 1196, 1196, 1196, 1196, 1196, 1335, 1335, 1335, 1335, 1335,
+ 1335, 1335, 1353, 1358, 1358, 1358, 1358, 1358, 1358, 1358,
+ 0, 1196, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200,
+ 1200, 0, 0, 0, 1200, 0, 0, 0, 1353, 0,
+ 1200, 1200, 1200, 1200, 1200, 1200, 1203, 1203, 1203, 1203,
+ 1203, 1203, 1203, 1203, 1203, 0, 0, 0, 1203, 0,
+ 0, 0, 0, 0, 1203, 1203, 1203, 1203, 1203, 1203,
+ 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 0,
+ 0, 0, 1206, 0, 0, 0, 0, 0, 1206, 1206,
+
+ 1206, 1206, 1206, 1206, 1209, 1209, 1209, 1209, 1209, 1209,
+ 1209, 1209, 1209, 0, 0, 0, 1209, 0, 0, 0,
+ 0, 0, 1209, 1209, 1209, 1209, 1209, 1209, 1212, 1212,
+ 1212, 1212, 1212, 1212, 1212, 1212, 1212, 0, 0, 0,
+ 1212, 0, 0, 0, 0, 0, 1212, 1212, 1212, 1212,
+ 1212, 1212, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217,
+ 1217, 0, 0, 0, 1217, 0, 0, 0, 0, 0,
+ 1217, 1217, 1217, 1217, 1217, 1217, 1269, 1269, 1269, 1269,
+ 1269, 1269, 1269, 1269, 1269, 0, 0, 0, 1269, 0,
+ 0, 0, 0, 0, 1269, 1269, 1269, 1269, 1269, 1269,
+
+ 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 0,
+ 0, 0, 1277, 0, 0, 0, 0, 0, 1277, 1277,
+ 1277, 1277, 1277, 1277, 1362, 1362, 1362, 1362, 1362, 1362,
+ 1362, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1370, 1370,
+ 1370, 1370, 1370, 1370, 1370, 1374, 1374, 1374, 1374, 1374,
+ 1374, 1374, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1381,
+ 1382, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 0, 0,
+ 0, 0, 0, 1381, 1382, 1393, 1393, 1393, 1393, 1393,
+ 1393, 1393, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1401,
+ 1401, 1401, 1401, 1401, 1401, 1401, 0, 0, 0, 1381,
+
+ 1382, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1409, 1409,
+ 1409, 1409, 1409, 1409, 1409, 1412, 1412, 1412, 1412, 1412,
+ 1412, 1412, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1426,
+ 1426, 1426, 1426, 1426, 1426, 1426, 1438, 0, 0, 0,
+ 0, 1438, 1438, 1438, 1439, 0, 1439, 1439, 1439, 1439,
+ 1439, 1439, 1439, 1440, 0, 1440, 1441, 1441, 1441, 1442,
+ 1442, 1442, 1443, 1443, 1443, 1444, 1444, 1444, 1445, 1445,
+ 1445, 1446, 1446, 1446, 1447, 1447, 1447, 1448, 1448, 1448,
+ 1449, 1449, 1449, 1450, 0, 1450, 1451, 1451, 1451, 1452,
+ 1452, 1452, 1453, 1453, 1453, 1454, 1454, 1454, 1455, 0,
+
+ 1455, 1456, 1456, 1456, 1457, 1457, 0, 0, 1457, 1458,
+ 1458, 1458, 1459, 1459, 1459, 1460, 1460, 1460, 1461, 1461,
+ 1461, 1462, 1462, 1462, 1463, 1463, 1463, 1464, 1464, 1464,
+ 1465, 1465, 1465, 1466, 1466, 1466, 1467, 1467, 0, 0,
+ 1467, 1468, 1468, 1468, 1469, 1469, 1469, 1470, 0, 1470,
+ 1471, 1471, 1471, 1472, 1472, 1472, 1473, 0, 1473, 1474,
+ 1474, 1474, 1475, 1475, 1475, 1476, 1476, 1476, 1477, 1477,
+ 1477, 1478, 1478, 1478, 1479, 0, 1479, 1480, 0, 1480,
+ 1481, 1481, 1481, 1482, 1482, 1482, 1483, 0, 1483, 1484,
+ 1484, 0, 0, 1484, 1485, 1485, 0, 0, 1485, 1486,
+
+ 1486, 1486, 1487, 1487, 1487, 1488, 1488, 0, 1488, 1489,
+ 1489, 1489, 1490, 1490, 1490, 1491, 1491, 1491, 1492, 1492,
+ 1492, 1493, 1493, 1493, 1494, 1494, 1494, 1495, 1495, 1495,
+ 1496, 1496, 0, 0, 1496, 1497, 1497, 1497, 1498, 1498,
+ 1498, 1499, 1499, 0, 1499, 1500, 1500, 0, 0, 1500,
+ 1501, 1501, 0, 1501, 1502, 1502, 1503, 1503, 0, 0,
+ 1503, 1504, 1504, 1504, 1505, 1505, 1505, 1506, 1506, 0,
+ 1506, 1507, 0, 1507, 1508, 0, 1508, 1509, 1509, 1509,
+ 1510, 1510, 1510, 1511, 0, 1511, 1512, 1512, 1512, 1513,
+ 1513, 1513, 1514, 1514, 1514, 1515, 1515, 1515, 1516, 1516,
+
+ 1516, 1517, 1517, 1517, 1518, 0, 1518, 1519, 0, 1519,
+ 1520, 1520, 1520, 1521, 1521, 1521, 1522, 0, 1522, 1523,
+ 0, 1523, 1524, 0, 1524, 1525, 1525, 1525, 1526, 1526,
+ 1526, 1527, 0, 1527, 1528, 0, 0, 1528, 1529, 1529,
+ 0, 1529, 1530, 1530, 0, 0, 1530, 1531, 1531, 0,
+ 1531, 1532, 1532, 1533, 1533, 0, 0, 1533, 1534, 1534,
+ 1534, 1535, 1535, 1535, 1536, 1536, 0, 1536, 1537, 1537,
+ 1537, 0, 1537, 1537, 1538, 1538, 1538, 1539, 1539, 1539,
+ 1540, 1540, 1540, 1541, 1541, 1541, 1542, 1542, 1542, 1543,
+ 1543, 1543, 1544, 1544, 1544, 1545, 1545, 1545, 1546, 1546,
+
+ 0, 0, 1546, 1547, 1547, 1547, 1548, 1548, 1548, 1549,
+ 1549, 0, 1549, 1550, 1550, 0, 0, 1550, 1551, 1551,
+ 0, 1551, 1552, 1552, 1553, 1553, 0, 0, 1553, 1554,
+ 1554, 1554, 1555, 1555, 1555, 1556, 1556, 0, 1556, 1557,
+ 0, 0, 1557, 1558, 1558, 0, 1558, 1559, 1559, 0,
+ 0, 1559, 1560, 1560, 0, 1560, 1561, 1561, 1562, 1562,
+ 0, 0, 1562, 1563, 1563, 1563, 1564, 1564, 1564, 1565,
+ 1565, 0, 1565, 1566, 0, 1566, 1567, 0, 1567, 1568,
+ 0, 1568, 1569, 1569, 1569, 1570, 1570, 1570, 1571, 0,
+ 1571, 1572, 1572, 1572, 0, 1572, 1572, 1573, 1573, 1573,
+
+ 1574, 1574, 1574, 1575, 1575, 1575, 1576, 1576, 1576, 1577,
+ 1577, 1577, 1578, 1578, 1578, 1579, 1579, 1579, 1580, 0,
+ 1580, 1581, 0, 1581, 1582, 1582, 1582, 1583, 1583, 1583,
+ 1584, 0, 1584, 1585, 0, 1585, 1586, 0, 1586, 1587,
+ 1587, 1587, 1588, 1588, 1588, 1589, 0, 1589, 1590, 0,
+ 1590, 1591, 0, 1591, 1592, 0, 1592, 1593, 1593, 1593,
+ 1594, 1594, 1594, 1595, 0, 1595, 1596, 0, 1596, 1597,
+ 0, 0, 1597, 1598, 1598, 0, 1598, 1599, 1599, 0,
+ 0, 1599, 1600, 1600, 0, 1600, 1601, 1601, 1602, 1602,
+ 0, 0, 1602, 1603, 1603, 1603, 1604, 1604, 1604, 1605,
+
+ 1605, 0, 1605, 1606, 1606, 1606, 0, 1606, 1606, 1607,
+ 1607, 1607, 1608, 1608, 1608, 1609, 1609, 1609, 1610, 1610,
+ 1610, 1611, 1611, 1611, 1612, 1612, 1612, 1613, 1613, 1613,
+ 1614, 1614, 1614, 1615, 1615, 0, 0, 1615, 1616, 1616,
+ 1616, 1617, 1617, 1617, 1618, 1618, 0, 1618, 1619, 1619,
+ 0, 0, 1619, 1620, 1620, 0, 1620, 1621, 1621, 1622,
+ 1622, 0, 0, 1622, 1623, 1623, 1623, 1624, 1624, 1624,
+ 1625, 1625, 0, 1625, 1626, 0, 0, 1626, 1627, 1627,
+ 0, 1627, 1628, 1628, 0, 0, 1628, 1629, 1629, 0,
+ 1629, 1630, 1630, 1631, 1631, 0, 0, 1631, 1632, 1632,
+
+ 1632, 1633, 1633, 1633, 1634, 1634, 0, 1634, 1635, 0,
+ 1635, 1636, 0, 0, 1636, 1637, 1637, 0, 1637, 1638,
+ 1638, 0, 0, 1638, 1639, 1639, 0, 1639, 1640, 1640,
+ 1641, 1641, 0, 0, 1641, 1642, 1642, 1642, 1643, 1643,
+ 1643, 1644, 1644, 0, 1644, 1645, 0, 1645, 1646, 0,
+ 1646, 1647, 0, 1647, 1648, 1648, 1648, 1649, 1649, 1649,
+ 1650, 0, 1650, 1651, 1651, 1651, 0, 1651, 1651, 1652,
+ 1652, 1652, 1653, 1653, 1653, 1654, 1654, 1654, 1655, 1655,
+ 1655, 1656, 1656, 1656, 1657, 1657, 1657, 1658, 1658, 1658,
+ 1659, 1659, 1659, 1660, 1660, 1660, 1661, 1661, 1661, 1662,
+
+ 0, 1662, 1663, 0, 1663, 1664, 1664, 1664, 1665, 1665,
+ 1665, 1666, 1666, 1666, 1667, 0, 1667, 1668, 0, 1668,
+ 1669, 0, 1669, 1670, 1670, 1670, 1671, 1671, 1671, 1672,
+ 1672, 1672, 1673, 0, 1673, 1674, 0, 1674, 1675, 0,
+ 1675, 1676, 0, 1676, 1677, 1677, 1677, 1678, 1678, 1678,
+ 1679, 1679, 1679, 1680, 0, 1680, 1681, 0, 1681, 1682,
+ 0, 1682, 1683, 0, 1683, 1684, 1684, 1684, 1685, 1685,
+ 1685, 1686, 1686, 1686, 1687, 0, 1687, 1688, 0, 1688,
+ 1689, 0, 0, 1689, 1690, 1690, 0, 1690, 1691, 1691,
+ 0, 0, 1691, 1692, 1692, 0, 1692, 1693, 1693, 1694,
+
+ 1694, 0, 0, 1694, 1695, 1695, 1695, 1696, 1696, 1696,
+ 1697, 1697, 0, 1697, 1698, 1698, 1698, 0, 1698, 1698,
+ 1699, 1699, 1699, 1700, 1700, 1700, 1701, 1701, 1701, 1702,
+ 1702, 1702, 1703, 1703, 1703, 1704, 1704, 1704, 1705, 1705,
+ 1705, 1706, 1706, 1706, 1707, 0, 1707, 1708, 1708, 1708,
+ 1709, 1709, 0, 0, 1709, 1710, 1710, 1710, 1711, 1711,
+ 1711, 1712, 1712, 0, 1712, 1713, 1713, 0, 0, 1713,
+ 1714, 1714, 0, 1714, 1715, 1715, 1716, 1716, 0, 0,
+ 1716, 1717, 1717, 1717, 1718, 1718, 1718, 1719, 1719, 0,
+ 1719, 1720, 0, 0, 1720, 1721, 1721, 0, 1721, 1722,
+
+ 1722, 0, 0, 1722, 1723, 1723, 0, 1723, 1724, 1724,
+ 1725, 1725, 0, 0, 1725, 1726, 1726, 1726, 1727, 1727,
+ 1727, 1728, 1728, 0, 1728, 1729, 0, 1729, 1730, 0,
+ 0, 1730, 1731, 1731, 0, 1731, 1732, 1732, 0, 0,
+ 1732, 1733, 1733, 0, 1733, 1734, 1734, 1735, 1735, 0,
+ 0, 1735, 1736, 1736, 1736, 1737, 1737, 1737, 1738, 1738,
+ 0, 1738, 1739, 0, 1739, 1740, 0, 0, 1740, 1741,
+ 1741, 0, 1741, 1742, 1742, 0, 0, 1742, 1743, 1743,
+ 0, 1743, 1744, 1744, 1745, 1745, 0, 0, 1745, 1746,
+ 1746, 1746, 1747, 1747, 1747, 1748, 1748, 0, 1748, 1749,
+
+ 0, 1749, 1750, 0, 1750, 1751, 0, 1751, 1752, 1752,
+ 1752, 1753, 0, 1753, 1754, 1754, 1754, 1755, 0, 1755,
+ 1756, 1756, 1756, 0, 1756, 1756, 1757, 0, 1757, 1758,
+ 1758, 1758, 1759, 0, 1759, 1760, 1760, 1760, 1761, 0,
+ 1761, 1762, 1762, 1762, 1763, 0, 1763, 1764, 1764, 1764,
+ 1765, 0, 1765, 1766, 1766, 1766, 1767, 0, 1767, 1768,
+ 1768, 1768, 1769, 1769, 0, 0, 1769, 1770, 1770, 1770,
+ 1771, 1771, 1771, 1772, 1772, 1772, 1773, 1773, 0, 1773,
+ 1774, 1774, 1774, 1775, 0, 1775, 1776, 1776, 1776, 1777,
+ 1777, 1777, 1778, 0, 1778, 1779, 0, 1779, 1780, 1780,
+
+ 1780, 1781, 1781, 1781, 1782, 0, 1782, 1783, 0, 1783,
+ 1784, 0, 1784, 1785, 1785, 1785, 1786, 1786, 1786, 1787,
+ 0, 1787, 1788, 0, 1788, 1789, 0, 1789, 1790, 1790,
+ 1790, 1791, 1791, 1791, 1792, 0, 1792, 1793, 0, 1793,
+ 1794, 0, 1794, 1795, 1795, 1795, 1796, 1796, 1796, 1797,
+ 0, 1797, 1798, 0, 0, 1798, 1799, 1799, 0, 1799,
+ 1800, 1800, 0, 0, 1800, 1801, 1801, 0, 1801, 1802,
+ 1802, 1803, 1803, 0, 0, 1803, 1804, 1804, 1804, 1805,
+ 0, 1805, 1806, 1806, 0, 1806, 1807, 1807, 1807, 0,
+ 1807, 1807, 1808, 1808, 1808, 1809, 1809, 1809, 1810, 0,
+
+ 1810, 1811, 0, 1811, 1812, 0, 1812, 1813, 0, 1813,
+ 1814, 0, 1814, 1815, 0, 1815, 1816, 0, 1816, 1817,
+ 1817, 1817, 1818, 1818, 1818, 1819, 0, 1819, 1820, 1820,
+ 0, 0, 1820, 1821, 1821, 0, 1821, 1822, 1822, 1823,
+ 0, 1823, 1824, 0, 0, 1824, 1825, 1825, 0, 1825,
+ 1826, 1826, 0, 0, 1826, 1827, 1827, 0, 1827, 1828,
+ 1828, 1829, 0, 1829, 1830, 0, 1830, 1831, 0, 0,
+ 1831, 1832, 1832, 0, 1832, 1833, 1833, 0, 0, 1833,
+ 1834, 1834, 0, 1834, 1835, 1835, 1836, 0, 1836, 1837,
+ 0, 1837, 1838, 0, 0, 1838, 1839, 1839, 0, 1839,
+
+ 1840, 1840, 0, 0, 1840, 1841, 1841, 0, 1841, 1842,
+ 1842, 1843, 0, 1843, 1844, 0, 1844, 1845, 0, 0,
+ 1845, 1846, 1846, 0, 1846, 1847, 1847, 0, 0, 1847,
+ 1848, 1848, 0, 1848, 1849, 1849, 1850, 0, 1850, 1851,
+ 0, 1851, 1852, 0, 1852, 1853, 0, 1853, 1854, 1854,
+ 1854, 1855, 0, 1855, 1856, 1856, 1856, 0, 1856, 1856,
+ 1857, 0, 1857, 1858, 0, 1858, 1859, 0, 1859, 1860,
+ 0, 1860, 1861, 0, 1861, 1862, 0, 1862, 1863, 0,
+ 1863, 1864, 1864, 0, 0, 1864, 1865, 1865, 0, 1865,
+ 1866, 1866, 1867, 0, 1867, 1868, 0, 1868, 1869, 0,
+
+ 1869, 1870, 0, 1870, 1871, 0, 1871, 1872, 0, 1872,
+ 1873, 0, 1873, 1874, 0, 1874, 1875, 0, 1875, 1876,
+ 0, 1876, 1877, 0, 0, 1877, 1878, 1878, 0, 0,
+ 1878, 1879, 0, 1879, 1880, 0, 1880, 1881, 0, 1881,
+ 1882, 0, 0, 1882, 1883, 0, 0, 1883, 1884, 0,
+ 0, 1884, 1885, 0, 0, 1885, 1886, 0, 0, 1886,
+ 1887, 0, 1887, 1888, 0, 1888, 1889, 0, 0, 1889,
+ 1890, 0, 1890, 1891, 0, 1891, 1892, 0, 1892, 1893,
+ 0, 1893, 1894, 0, 1894, 1895, 0, 0, 1895, 1896,
+ 0, 1896, 1897, 0, 1897, 1437, 1437, 1437, 1437, 1437,
+
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int pcap_flex_debug;
+int pcap_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *pcaptext;
+#line 1 "../../freebsd/contrib/libpcap/scanner.l"
+#line 2 "../../freebsd/contrib/libpcap/scanner.l"
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.112 2008-02-06 10:21:30 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <sys/types.h>
+#endif /* WIN32 */
+
+#include <ctype.h>
+#include <string.h>
+
+#include "pcap-int.h"
+
+#include "gencode.h"
+#ifdef INET6
+#ifdef WIN32
+#include <pcap-stdinc.h>
+
+#ifdef __MINGW32__
+#include "ip6_misc.h"
+#endif
+#else /* WIN32 */
+#include <sys/socket.h> /* for "struct sockaddr" in "struct addrinfo" */
+#include <netdb.h> /* for "struct addrinfo" */
+#endif /* WIN32 */
+
+/* Workaround for AIX 4.3 */
+#if !defined(AI_NUMERICHOST)
+#define AI_NUMERICHOST 0x04
+#endif
+#endif /*INET6*/
+#include <pcap/namedb.h>
+#include "tokdefs.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+static int stoi(char *);
+static inline int xdtoi(int);
+
+#ifdef FLEX_SCANNER
+#define YY_NO_INPUT
+#define YY_NO_UNPUT
+static YY_BUFFER_STATE in_buffer;
+#else
+static const char *in_buffer;
+
+#undef getc
+#define getc(fp) (*in_buffer == 0 ? EOF : *in_buffer++)
+#endif
+
+extern YYSTYPE yylval;
+
+#line 2788 "<stdout>"
+
+#define INITIAL 0
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int pcaplex_destroy (void );
+
+int pcapget_debug (void );
+
+void pcapset_debug (int debug_flag );
+
+YY_EXTRA_TYPE pcapget_extra (void );
+
+void pcapset_extra (YY_EXTRA_TYPE user_defined );
+
+FILE *pcapget_in (void );
+
+void pcapset_in (FILE * in_str );
+
+FILE *pcapget_out (void );
+
+void pcapset_out (FILE * out_str );
+
+yy_size_t pcapget_leng (void );
+
+char *pcapget_text (void );
+
+int pcapget_lineno (void );
+
+void pcapset_lineno (int line_number );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int pcapwrap (void );
+#else
+extern int pcapwrap (void );
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+ static void yyunput (int c,char *buf_ptr );
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( pcaptext, pcapleng, 1, pcapout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ size_t n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( pcapin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( pcapin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, pcapin))==0 && ferror(pcapin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(pcapin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int pcaplex (void);
+
+#define YY_DECL int pcaplex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after pcaptext and pcapleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ yy_state_type yy_current_state;
+ char *yy_cp, *yy_bp;
+ int yy_act;
+
+#line 190 "../../freebsd/contrib/libpcap/scanner.l"
+
+#line 2974 "<stdout>"
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! pcapin )
+ pcapin = stdin;
+
+ if ( ! pcapout )
+ pcapout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ pcapensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ pcap_create_buffer(pcapin,YY_BUF_SIZE );
+ }
+
+ pcap_load_buffer_state( );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of pcaptext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+yy_match:
+ do
+ {
+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 1438 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 7396 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 191 "../../freebsd/contrib/libpcap/scanner.l"
+return DST;
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 192 "../../freebsd/contrib/libpcap/scanner.l"
+return SRC;
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 194 "../../freebsd/contrib/libpcap/scanner.l"
+return LINK;
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 195 "../../freebsd/contrib/libpcap/scanner.l"
+return LINK;
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 196 "../../freebsd/contrib/libpcap/scanner.l"
+return ARP;
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 197 "../../freebsd/contrib/libpcap/scanner.l"
+return RARP;
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 198 "../../freebsd/contrib/libpcap/scanner.l"
+return IP;
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 199 "../../freebsd/contrib/libpcap/scanner.l"
+return SCTP;
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 200 "../../freebsd/contrib/libpcap/scanner.l"
+return TCP;
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 201 "../../freebsd/contrib/libpcap/scanner.l"
+return UDP;
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 202 "../../freebsd/contrib/libpcap/scanner.l"
+return ICMP;
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 203 "../../freebsd/contrib/libpcap/scanner.l"
+return IGMP;
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 204 "../../freebsd/contrib/libpcap/scanner.l"
+return IGRP;
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 205 "../../freebsd/contrib/libpcap/scanner.l"
+return PIM;
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 206 "../../freebsd/contrib/libpcap/scanner.l"
+return VRRP;
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 207 "../../freebsd/contrib/libpcap/scanner.l"
+return CARP;
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 208 "../../freebsd/contrib/libpcap/scanner.l"
+return RADIO;
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 210 "../../freebsd/contrib/libpcap/scanner.l"
+return IPV6;
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 211 "../../freebsd/contrib/libpcap/scanner.l"
+return ICMPV6;
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 212 "../../freebsd/contrib/libpcap/scanner.l"
+return AH;
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 213 "../../freebsd/contrib/libpcap/scanner.l"
+return ESP;
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 215 "../../freebsd/contrib/libpcap/scanner.l"
+return ATALK;
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 216 "../../freebsd/contrib/libpcap/scanner.l"
+return AARP;
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 217 "../../freebsd/contrib/libpcap/scanner.l"
+return DECNET;
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 218 "../../freebsd/contrib/libpcap/scanner.l"
+return LAT;
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 219 "../../freebsd/contrib/libpcap/scanner.l"
+return SCA;
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 220 "../../freebsd/contrib/libpcap/scanner.l"
+return MOPRC;
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 221 "../../freebsd/contrib/libpcap/scanner.l"
+return MOPDL;
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 223 "../../freebsd/contrib/libpcap/scanner.l"
+return ISO;
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 224 "../../freebsd/contrib/libpcap/scanner.l"
+return ESIS;
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 225 "../../freebsd/contrib/libpcap/scanner.l"
+return ESIS;
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 226 "../../freebsd/contrib/libpcap/scanner.l"
+return ISIS;
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 227 "../../freebsd/contrib/libpcap/scanner.l"
+return ISIS;
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 228 "../../freebsd/contrib/libpcap/scanner.l"
+return L1;
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 229 "../../freebsd/contrib/libpcap/scanner.l"
+return L2;
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 230 "../../freebsd/contrib/libpcap/scanner.l"
+return IIH;
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 231 "../../freebsd/contrib/libpcap/scanner.l"
+return LSP;
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 232 "../../freebsd/contrib/libpcap/scanner.l"
+return SNP;
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 233 "../../freebsd/contrib/libpcap/scanner.l"
+return CSNP;
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 234 "../../freebsd/contrib/libpcap/scanner.l"
+return PSNP;
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 236 "../../freebsd/contrib/libpcap/scanner.l"
+return CLNP;
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 238 "../../freebsd/contrib/libpcap/scanner.l"
+return STP;
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 240 "../../freebsd/contrib/libpcap/scanner.l"
+return IPX;
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 242 "../../freebsd/contrib/libpcap/scanner.l"
+return NETBEUI;
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 244 "../../freebsd/contrib/libpcap/scanner.l"
+return HOST;
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 245 "../../freebsd/contrib/libpcap/scanner.l"
+return NET;
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 246 "../../freebsd/contrib/libpcap/scanner.l"
+return NETMASK;
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 247 "../../freebsd/contrib/libpcap/scanner.l"
+return PORT;
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 248 "../../freebsd/contrib/libpcap/scanner.l"
+return PORTRANGE;
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 249 "../../freebsd/contrib/libpcap/scanner.l"
+return PROTO;
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 250 "../../freebsd/contrib/libpcap/scanner.l"
+{
+#ifdef NO_PROTOCHAIN
+ bpf_error("%s not supported", pcaptext);
+#else
+ return PROTOCHAIN;
+#endif
+ }
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 258 "../../freebsd/contrib/libpcap/scanner.l"
+return GATEWAY;
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 260 "../../freebsd/contrib/libpcap/scanner.l"
+return TYPE;
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 261 "../../freebsd/contrib/libpcap/scanner.l"
+return SUBTYPE;
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 262 "../../freebsd/contrib/libpcap/scanner.l"
+return DIR;
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 263 "../../freebsd/contrib/libpcap/scanner.l"
+return ADDR1;
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 264 "../../freebsd/contrib/libpcap/scanner.l"
+return ADDR2;
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 265 "../../freebsd/contrib/libpcap/scanner.l"
+return ADDR3;
+ YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 266 "../../freebsd/contrib/libpcap/scanner.l"
+return ADDR4;
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 267 "../../freebsd/contrib/libpcap/scanner.l"
+return RA;
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 268 "../../freebsd/contrib/libpcap/scanner.l"
+return TA;
+ YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 270 "../../freebsd/contrib/libpcap/scanner.l"
+return LESS;
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 271 "../../freebsd/contrib/libpcap/scanner.l"
+return GREATER;
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 272 "../../freebsd/contrib/libpcap/scanner.l"
+return CBYTE;
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 273 "../../freebsd/contrib/libpcap/scanner.l"
+return TK_BROADCAST;
+ YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 274 "../../freebsd/contrib/libpcap/scanner.l"
+return TK_MULTICAST;
+ YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 276 "../../freebsd/contrib/libpcap/scanner.l"
+return AND;
+ YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 277 "../../freebsd/contrib/libpcap/scanner.l"
+return OR;
+ YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 278 "../../freebsd/contrib/libpcap/scanner.l"
+return '!';
+ YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 280 "../../freebsd/contrib/libpcap/scanner.l"
+return LEN;
+ YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 281 "../../freebsd/contrib/libpcap/scanner.l"
+return INBOUND;
+ YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 282 "../../freebsd/contrib/libpcap/scanner.l"
+return OUTBOUND;
+ YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 284 "../../freebsd/contrib/libpcap/scanner.l"
+return VLAN;
+ YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 285 "../../freebsd/contrib/libpcap/scanner.l"
+return MPLS;
+ YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 286 "../../freebsd/contrib/libpcap/scanner.l"
+return PPPOED;
+ YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 287 "../../freebsd/contrib/libpcap/scanner.l"
+return PPPOES;
+ YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 289 "../../freebsd/contrib/libpcap/scanner.l"
+return LANE;
+ YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 290 "../../freebsd/contrib/libpcap/scanner.l"
+return LLC;
+ YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 291 "../../freebsd/contrib/libpcap/scanner.l"
+return METAC;
+ YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 292 "../../freebsd/contrib/libpcap/scanner.l"
+return BCC;
+ YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 293 "../../freebsd/contrib/libpcap/scanner.l"
+return OAM;
+ YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 294 "../../freebsd/contrib/libpcap/scanner.l"
+return OAMF4;
+ YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 295 "../../freebsd/contrib/libpcap/scanner.l"
+return OAMF4EC;
+ YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 296 "../../freebsd/contrib/libpcap/scanner.l"
+return OAMF4SC;
+ YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 297 "../../freebsd/contrib/libpcap/scanner.l"
+return SC;
+ YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 298 "../../freebsd/contrib/libpcap/scanner.l"
+return ILMIC;
+ YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 299 "../../freebsd/contrib/libpcap/scanner.l"
+return VPI;
+ YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 300 "../../freebsd/contrib/libpcap/scanner.l"
+return VCI;
+ YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 301 "../../freebsd/contrib/libpcap/scanner.l"
+return CONNECTMSG;
+ YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 302 "../../freebsd/contrib/libpcap/scanner.l"
+return METACONNECT;
+ YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 304 "../../freebsd/contrib/libpcap/scanner.l"
+return PF_IFNAME;
+ YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 305 "../../freebsd/contrib/libpcap/scanner.l"
+return PF_RSET;
+ YY_BREAK
+case 93:
+YY_RULE_SETUP
+#line 306 "../../freebsd/contrib/libpcap/scanner.l"
+return PF_RNR;
+ YY_BREAK
+case 94:
+YY_RULE_SETUP
+#line 307 "../../freebsd/contrib/libpcap/scanner.l"
+return PF_SRNR;
+ YY_BREAK
+case 95:
+YY_RULE_SETUP
+#line 308 "../../freebsd/contrib/libpcap/scanner.l"
+return PF_REASON;
+ YY_BREAK
+case 96:
+YY_RULE_SETUP
+#line 309 "../../freebsd/contrib/libpcap/scanner.l"
+return PF_ACTION;
+ YY_BREAK
+case 97:
+YY_RULE_SETUP
+#line 311 "../../freebsd/contrib/libpcap/scanner.l"
+return FISU;
+ YY_BREAK
+case 98:
+YY_RULE_SETUP
+#line 312 "../../freebsd/contrib/libpcap/scanner.l"
+return LSSU;
+ YY_BREAK
+case 99:
+YY_RULE_SETUP
+#line 313 "../../freebsd/contrib/libpcap/scanner.l"
+return LSSU;
+ YY_BREAK
+case 100:
+YY_RULE_SETUP
+#line 314 "../../freebsd/contrib/libpcap/scanner.l"
+return MSU;
+ YY_BREAK
+case 101:
+YY_RULE_SETUP
+#line 315 "../../freebsd/contrib/libpcap/scanner.l"
+return SIO;
+ YY_BREAK
+case 102:
+YY_RULE_SETUP
+#line 316 "../../freebsd/contrib/libpcap/scanner.l"
+return OPC;
+ YY_BREAK
+case 103:
+YY_RULE_SETUP
+#line 317 "../../freebsd/contrib/libpcap/scanner.l"
+return DPC;
+ YY_BREAK
+case 104:
+YY_RULE_SETUP
+#line 318 "../../freebsd/contrib/libpcap/scanner.l"
+return SLS;
+ YY_BREAK
+case 105:
+/* rule 105 can match eol */
+YY_RULE_SETUP
+#line 320 "../../freebsd/contrib/libpcap/scanner.l"
+;
+ YY_BREAK
+case 106:
+YY_RULE_SETUP
+#line 321 "../../freebsd/contrib/libpcap/scanner.l"
+return pcaptext[0];
+ YY_BREAK
+case 107:
+YY_RULE_SETUP
+#line 322 "../../freebsd/contrib/libpcap/scanner.l"
+return GEQ;
+ YY_BREAK
+case 108:
+YY_RULE_SETUP
+#line 323 "../../freebsd/contrib/libpcap/scanner.l"
+return LEQ;
+ YY_BREAK
+case 109:
+YY_RULE_SETUP
+#line 324 "../../freebsd/contrib/libpcap/scanner.l"
+return NEQ;
+ YY_BREAK
+case 110:
+YY_RULE_SETUP
+#line 325 "../../freebsd/contrib/libpcap/scanner.l"
+return '=';
+ YY_BREAK
+case 111:
+YY_RULE_SETUP
+#line 326 "../../freebsd/contrib/libpcap/scanner.l"
+return LSH;
+ YY_BREAK
+case 112:
+YY_RULE_SETUP
+#line 327 "../../freebsd/contrib/libpcap/scanner.l"
+return RSH;
+ YY_BREAK
+case 113:
+YY_RULE_SETUP
+#line 328 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.e = pcap_ether_aton(((char *)pcaptext)+1);
+ return AID; }
+ YY_BREAK
+case 114:
+YY_RULE_SETUP
+#line 330 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.e = pcap_ether_aton((char *)pcaptext);
+ return EID; }
+ YY_BREAK
+case 115:
+YY_RULE_SETUP
+#line 332 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = stoi((char *)pcaptext); return NUM; }
+ YY_BREAK
+case 116:
+YY_RULE_SETUP
+#line 333 "../../freebsd/contrib/libpcap/scanner.l"
+{
+ yylval.s = sdup((char *)pcaptext); return HID; }
+ YY_BREAK
+case 117:
+YY_RULE_SETUP
+#line 335 "../../freebsd/contrib/libpcap/scanner.l"
+{
+#ifdef INET6
+ struct addrinfo hints, *res;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET6;
+ hints.ai_flags = AI_NUMERICHOST;
+ if (getaddrinfo(pcaptext, NULL, &hints, &res))
+ bpf_error("bogus IPv6 address %s", pcaptext);
+ else {
+ freeaddrinfo(res);
+ yylval.s = sdup((char *)pcaptext); return HID6;
+ }
+#else
+ bpf_error("IPv6 address %s not supported", pcaptext);
+#endif /*INET6*/
+ }
+ YY_BREAK
+case 118:
+YY_RULE_SETUP
+#line 351 "../../freebsd/contrib/libpcap/scanner.l"
+{ bpf_error("bogus ethernet address %s", pcaptext); }
+ YY_BREAK
+case 119:
+YY_RULE_SETUP
+#line 352 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 0; return NUM; }
+ YY_BREAK
+case 120:
+YY_RULE_SETUP
+#line 353 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 1; return NUM; }
+ YY_BREAK
+case 121:
+YY_RULE_SETUP
+#line 354 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 0; return NUM; }
+ YY_BREAK
+case 122:
+YY_RULE_SETUP
+#line 355 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 3; return NUM; }
+ YY_BREAK
+case 123:
+YY_RULE_SETUP
+#line 356 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 4; return NUM; }
+ YY_BREAK
+case 124:
+YY_RULE_SETUP
+#line 357 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 5; return NUM; }
+ YY_BREAK
+case 125:
+YY_RULE_SETUP
+#line 358 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 8; return NUM; }
+ YY_BREAK
+case 126:
+YY_RULE_SETUP
+#line 359 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 9; return NUM; }
+ YY_BREAK
+case 127:
+YY_RULE_SETUP
+#line 360 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 10; return NUM; }
+ YY_BREAK
+case 128:
+YY_RULE_SETUP
+#line 361 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 11; return NUM; }
+ YY_BREAK
+case 129:
+YY_RULE_SETUP
+#line 362 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 12; return NUM; }
+ YY_BREAK
+case 130:
+YY_RULE_SETUP
+#line 363 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 13; return NUM; }
+ YY_BREAK
+case 131:
+YY_RULE_SETUP
+#line 364 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 14; return NUM; }
+ YY_BREAK
+case 132:
+YY_RULE_SETUP
+#line 365 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 15; return NUM; }
+ YY_BREAK
+case 133:
+YY_RULE_SETUP
+#line 366 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 16; return NUM; }
+ YY_BREAK
+case 134:
+YY_RULE_SETUP
+#line 367 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 17; return NUM; }
+ YY_BREAK
+case 135:
+YY_RULE_SETUP
+#line 368 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 18; return NUM; }
+ YY_BREAK
+case 136:
+YY_RULE_SETUP
+#line 369 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 13; return NUM; }
+ YY_BREAK
+case 137:
+YY_RULE_SETUP
+#line 370 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 0x01; return NUM; }
+ YY_BREAK
+case 138:
+YY_RULE_SETUP
+#line 371 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 0x02; return NUM; }
+ YY_BREAK
+case 139:
+YY_RULE_SETUP
+#line 372 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 0x04; return NUM; }
+ YY_BREAK
+case 140:
+YY_RULE_SETUP
+#line 373 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 0x08; return NUM; }
+ YY_BREAK
+case 141:
+YY_RULE_SETUP
+#line 374 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 0x10; return NUM; }
+ YY_BREAK
+case 142:
+YY_RULE_SETUP
+#line 375 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 0x20; return NUM; }
+ YY_BREAK
+case 143:
+YY_RULE_SETUP
+#line 376 "../../freebsd/contrib/libpcap/scanner.l"
+{
+ yylval.s = sdup((char *)pcaptext); return ID; }
+ YY_BREAK
+case 144:
+YY_RULE_SETUP
+#line 378 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.s = sdup((char *)pcaptext + 1); return ID; }
+ YY_BREAK
+case 145:
+YY_RULE_SETUP
+#line 379 "../../freebsd/contrib/libpcap/scanner.l"
+{
+ bpf_error("illegal token: %s", pcaptext); }
+ YY_BREAK
+case 146:
+YY_RULE_SETUP
+#line 381 "../../freebsd/contrib/libpcap/scanner.l"
+{ bpf_error("illegal char '%c'", *pcaptext); }
+ YY_BREAK
+case 147:
+YY_RULE_SETUP
+#line 382 "../../freebsd/contrib/libpcap/scanner.l"
+ECHO;
+ YY_BREAK
+#line 3819 "<stdout>"
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed pcapin at a new source and called
+ * pcaplex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = pcapin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( pcapwrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * pcaptext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of pcaplex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ char *source = (yytext_ptr);
+ int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ yy_size_t num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ yy_size_t new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ pcaprealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ pcaprestart(pcapin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) pcaprealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ yy_state_type yy_current_state;
+ char *yy_cp;
+
+ yy_current_state = (yy_start);
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 1438 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ int yy_is_jam;
+ char *yy_cp = (yy_c_buf_p);
+
+ YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 1438 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 1437);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_UNPUT
+ static void yyunput (int c, char * yy_bp )
+{
+ char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
+
+ /* undo effects of setting up pcaptext */
+ *yy_cp = (yy_hold_char);
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ yy_size_t number_to_move = (yy_n_chars) + 2;
+ char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ (yytext_ptr) = yy_bp;
+ (yy_hold_char) = *yy_cp;
+ (yy_c_buf_p) = yy_cp;
+}
+#endif /* ifndef YY_NO_UNPUT */
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ pcaprestart(pcapin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( pcapwrap( ) )
+ return EOF;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve pcaptext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void pcaprestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ pcapensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ pcap_create_buffer(pcapin,YY_BUF_SIZE );
+ }
+
+ pcap_init_buffer(YY_CURRENT_BUFFER,input_file );
+ pcap_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void pcap_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * pcappop_buffer_state();
+ * pcappush_buffer_state(new_buffer);
+ */
+ pcapensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ pcap_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (pcapwrap()) processing, but the only time this flag
+ * is looked at is after pcapwrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void pcap_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ pcapin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE pcap_create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) pcapalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in pcap_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) pcapalloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in pcap_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ pcap_init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with pcap_create_buffer()
+ *
+ */
+ void pcap_delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ pcapfree((void *) b->yy_ch_buf );
+
+ pcapfree((void *) b );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a pcaprestart() or at EOF.
+ */
+ static void pcap_init_buffer (YY_BUFFER_STATE b, FILE * file )
+
+{
+ int oerrno = errno;
+
+ pcap_flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then pcap_init_buffer was _probably_
+ * called from pcaprestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void pcap_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ pcap_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void pcappush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ pcapensure_buffer_stack();
+
+ /* This block is copied from pcap_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from pcap_switch_to_buffer. */
+ pcap_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void pcappop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ pcap_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ pcap_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void pcapensure_buffer_stack (void)
+{
+ yy_size_t num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)pcapalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in pcapensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)pcaprealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in pcapensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE pcap_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) pcapalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in pcap_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ pcap_switch_to_buffer(b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to pcaplex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * pcap_scan_bytes() instead.
+ */
+YY_BUFFER_STATE pcap_scan_string (yyconst char * yystr )
+{
+
+ return pcap_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to pcaplex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE pcap_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ yy_size_t i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) pcapalloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in pcap_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = pcap_scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in pcap_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up pcaptext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ pcaptext[pcapleng] = (yy_hold_char); \
+ (yy_c_buf_p) = pcaptext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ pcapleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int pcapget_lineno (void)
+{
+
+ return pcaplineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *pcapget_in (void)
+{
+ return pcapin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *pcapget_out (void)
+{
+ return pcapout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+yy_size_t pcapget_leng (void)
+{
+ return pcapleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *pcapget_text (void)
+{
+ return pcaptext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void pcapset_lineno (int line_number )
+{
+
+ pcaplineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see pcap_switch_to_buffer
+ */
+void pcapset_in (FILE * in_str )
+{
+ pcapin = in_str ;
+}
+
+void pcapset_out (FILE * out_str )
+{
+ pcapout = out_str ;
+}
+
+int pcapget_debug (void)
+{
+ return pcap_flex_debug;
+}
+
+void pcapset_debug (int bdebug )
+{
+ pcap_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from pcaplex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = 0;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = (char *) 0;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ pcapin = stdin;
+ pcapout = stdout;
+#else
+ pcapin = (FILE *) 0;
+ pcapout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * pcaplex_init()
+ */
+ return 0;
+}
+
+/* pcaplex_destroy is for both reentrant and non-reentrant scanners. */
+int pcaplex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ pcap_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ pcappop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ pcapfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * pcaplex() is called, initialization will occur. */
+ yy_init_globals( );
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+ int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+ int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *pcapalloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *pcaprealloc (void * ptr, yy_size_t size )
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void pcapfree (void * ptr )
+{
+ free( (char *) ptr ); /* see pcaprealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 382 "../../freebsd/contrib/libpcap/scanner.l"
+
+
+void
+lex_init(buf)
+ const char *buf;
+{
+#ifdef FLEX_SCANNER
+ in_buffer = pcap_scan_string(buf);
+#else
+ in_buffer = buf;
+#endif
+}
+
+/*
+ * Do any cleanup necessary after parsing.
+ */
+void
+lex_cleanup()
+{
+#ifdef FLEX_SCANNER
+ if (in_buffer != NULL)
+ pcap_delete_buffer(in_buffer);
+ in_buffer = NULL;
+#endif
+}
+
+/*
+ * Also define a pcapwrap. Note that if we're using flex, it will
+ * define a macro to map this identifier to pcap_wrap.
+ */
+int
+pcapwrap()
+{
+ return 1;
+}
+
+/* Hex digit to integer. */
+static inline int
+xdtoi(c)
+ register int c;
+{
+ if (isdigit(c))
+ return c - '0';
+ else if (islower(c))
+ return c - 'a' + 10;
+ else
+ return c - 'A' + 10;
+}
+
+/*
+ * Convert string to integer. Just like atoi(), but checks for
+ * preceding 0x or 0 and uses hex or octal instead of decimal.
+ */
+static int
+stoi(s)
+ char *s;
+{
+ int base = 10;
+ int n = 0;
+
+ if (*s == '0') {
+ if (s[1] == 'x' || s[1] == 'X') {
+ s += 2;
+ base = 16;
+ }
+ else {
+ base = 8;
+ s += 1;
+ }
+ }
+ while (*s)
+ n = n * base + xdtoi(*s++);
+
+ return n;
+}
+
diff --git a/freebsd/contrib/libpcap/scanner.l b/freebsd/contrib/libpcap/scanner.l
new file mode 100644
index 00000000..4879c1f3
--- /dev/null
+++ b/freebsd/contrib/libpcap/scanner.l
@@ -0,0 +1,455 @@
+%{
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.112 2008-02-06 10:21:30 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <sys/types.h>
+#endif /* WIN32 */
+
+#include <ctype.h>
+#include <string.h>
+
+#include "pcap-int.h"
+
+#include "gencode.h"
+#ifdef INET6
+#ifdef WIN32
+#include <pcap-stdinc.h>
+
+#ifdef __MINGW32__
+#include "ip6_misc.h"
+#endif
+#else /* WIN32 */
+#include <sys/socket.h> /* for "struct sockaddr" in "struct addrinfo" */
+#include <netdb.h> /* for "struct addrinfo" */
+#endif /* WIN32 */
+
+/* Workaround for AIX 4.3 */
+#if !defined(AI_NUMERICHOST)
+#define AI_NUMERICHOST 0x04
+#endif
+#endif /*INET6*/
+#include <pcap/namedb.h>
+#include "tokdefs.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+static int stoi(char *);
+static inline int xdtoi(int);
+
+#ifdef FLEX_SCANNER
+#define YY_NO_INPUT
+#define YY_NO_UNPUT
+static YY_BUFFER_STATE in_buffer;
+#else
+static const char *in_buffer;
+
+#undef getc
+#define getc(fp) (*in_buffer == 0 ? EOF : *in_buffer++)
+#endif
+
+extern YYSTYPE yylval;
+
+%}
+
+N ([0-9]+|(0X|0x)[0-9A-Fa-f]+)
+B ([0-9A-Fa-f][0-9A-Fa-f]?)
+B2 ([0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f])
+W ([0-9A-Fa-f][0-9A-Fa-f]?[0-9A-Fa-f]?[0-9A-Fa-f]?)
+
+%a 18400
+%o 21500
+%e 7600
+%k 4550
+%p 27600
+%n 2000
+
+V680 {W}:{W}:{W}:{W}:{W}:{W}:{W}:{W}
+
+V670 ::{W}:{W}:{W}:{W}:{W}:{W}:{W}
+V671 {W}::{W}:{W}:{W}:{W}:{W}:{W}
+V672 {W}:{W}::{W}:{W}:{W}:{W}:{W}
+V673 {W}:{W}:{W}::{W}:{W}:{W}:{W}
+V674 {W}:{W}:{W}:{W}::{W}:{W}:{W}
+V675 {W}:{W}:{W}:{W}:{W}::{W}:{W}
+V676 {W}:{W}:{W}:{W}:{W}:{W}::{W}
+V677 {W}:{W}:{W}:{W}:{W}:{W}:{W}::
+
+V660 ::{W}:{W}:{W}:{W}:{W}:{W}
+V661 {W}::{W}:{W}:{W}:{W}:{W}
+V662 {W}:{W}::{W}:{W}:{W}:{W}
+V663 {W}:{W}:{W}::{W}:{W}:{W}
+V664 {W}:{W}:{W}:{W}::{W}:{W}
+V665 {W}:{W}:{W}:{W}:{W}::{W}
+V666 {W}:{W}:{W}:{W}:{W}:{W}::
+
+V650 ::{W}:{W}:{W}:{W}:{W}
+V651 {W}::{W}:{W}:{W}:{W}
+V652 {W}:{W}::{W}:{W}:{W}
+V653 {W}:{W}:{W}::{W}:{W}
+V654 {W}:{W}:{W}:{W}::{W}
+V655 {W}:{W}:{W}:{W}:{W}::
+
+V640 ::{W}:{W}:{W}:{W}
+V641 {W}::{W}:{W}:{W}
+V642 {W}:{W}::{W}:{W}
+V643 {W}:{W}:{W}::{W}
+V644 {W}:{W}:{W}:{W}::
+
+V630 ::{W}:{W}:{W}
+V631 {W}::{W}:{W}
+V632 {W}:{W}::{W}
+V633 {W}:{W}:{W}::
+
+V620 ::{W}:{W}
+V621 {W}::{W}
+V622 {W}:{W}::
+
+V610 ::{W}
+V611 {W}::
+
+V600 ::
+
+V6604 {W}:{W}:{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
+
+V6504 ::{W}:{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6514 {W}::{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6524 {W}:{W}::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6534 {W}:{W}:{W}::{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6544 {W}:{W}:{W}:{W}::{W}:{N}\.{N}\.{N}\.{N}
+V6554 {W}:{W}:{W}:{W}:{W}::{N}\.{N}\.{N}\.{N}
+
+V6404 ::{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6414 {W}::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6424 {W}:{W}::{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6434 {W}:{W}:{W}::{W}:{N}\.{N}\.{N}\.{N}
+V6444 {W}:{W}:{W}:{W}::{N}\.{N}\.{N}\.{N}
+
+V6304 ::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6314 {W}::{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6324 {W}:{W}::{W}:{N}\.{N}\.{N}\.{N}
+V6334 {W}:{W}:{W}::{N}\.{N}\.{N}\.{N}
+
+V6204 ::{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6214 {W}::{W}:{N}\.{N}\.{N}\.{N}
+V6224 {W}:{W}::{N}\.{N}\.{N}\.{N}
+
+V6104 ::{W}:{N}\.{N}\.{N}\.{N}
+V6114 {W}::{N}\.{N}\.{N}\.{N}
+
+V6004 ::{N}\.{N}\.{N}\.{N}
+
+
+V6 ({V680}|{V670}|{V671}|{V672}|{V673}|{V674}|{V675}|{V676}|{V677}|{V660}|{V661}|{V662}|{V663}|{V664}|{V665}|{V666}|{V650}|{V651}|{V652}|{V653}|{V654}|{V655}|{V640}|{V641}|{V642}|{V643}|{V644}|{V630}|{V631}|{V632}|{V633}|{V620}|{V621}|{V622}|{V610}|{V611}|{V600}|{V6604}|{V6504}|{V6514}|{V6524}|{V6534}|{V6544}|{V6554}|{V6404}|{V6414}|{V6424}|{V6434}|{V6444}|{V6304}|{V6314}|{V6324}|{V6334}|{V6204}|{V6214}|{V6224}|{V6104}|{V6114}|{V6004})
+
+MAC ({B}:{B}:{B}:{B}:{B}:{B}|{B}\-{B}\-{B}\-{B}\-{B}\-{B}|{B}\.{B}\.{B}\.{B}\.{B}\.{B}|{B2}\.{B2}\.{B2}|{B2}{3})
+
+
+
+%%
+dst return DST;
+src return SRC;
+
+link|ether|ppp|slip return LINK;
+fddi|tr|wlan return LINK;
+arp return ARP;
+rarp return RARP;
+ip return IP;
+sctp return SCTP;
+tcp return TCP;
+udp return UDP;
+icmp return ICMP;
+igmp return IGMP;
+igrp return IGRP;
+pim return PIM;
+vrrp return VRRP;
+carp return CARP;
+radio return RADIO;
+
+ip6 return IPV6;
+icmp6 return ICMPV6;
+ah return AH;
+esp return ESP;
+
+atalk return ATALK;
+aarp return AARP;
+decnet return DECNET;
+lat return LAT;
+sca return SCA;
+moprc return MOPRC;
+mopdl return MOPDL;
+
+iso return ISO;
+esis return ESIS;
+es-is return ESIS;
+isis return ISIS;
+is-is return ISIS;
+l1 return L1;
+l2 return L2;
+iih return IIH;
+lsp return LSP;
+snp return SNP;
+csnp return CSNP;
+psnp return PSNP;
+
+clnp return CLNP;
+
+stp return STP;
+
+ipx return IPX;
+
+netbeui return NETBEUI;
+
+host return HOST;
+net return NET;
+mask return NETMASK;
+port return PORT;
+portrange return PORTRANGE;
+proto return PROTO;
+protochain {
+#ifdef NO_PROTOCHAIN
+ bpf_error("%s not supported", yytext);
+#else
+ return PROTOCHAIN;
+#endif
+ }
+
+gateway return GATEWAY;
+
+type return TYPE;
+subtype return SUBTYPE;
+direction|dir return DIR;
+address1|addr1 return ADDR1;
+address2|addr2 return ADDR2;
+address3|addr3 return ADDR3;
+address4|addr4 return ADDR4;
+ra return RA;
+ta return TA;
+
+less return LESS;
+greater return GREATER;
+byte return CBYTE;
+broadcast return TK_BROADCAST;
+multicast return TK_MULTICAST;
+
+and|"&&" return AND;
+or|"||" return OR;
+not return '!';
+
+len|length return LEN;
+inbound return INBOUND;
+outbound return OUTBOUND;
+
+vlan return VLAN;
+mpls return MPLS;
+pppoed return PPPOED;
+pppoes return PPPOES;
+
+lane return LANE;
+llc return LLC;
+metac return METAC;
+bcc return BCC;
+oam return OAM;
+oamf4 return OAMF4;
+oamf4ec return OAMF4EC;
+oamf4sc return OAMF4SC;
+sc return SC;
+ilmic return ILMIC;
+vpi return VPI;
+vci return VCI;
+connectmsg return CONNECTMSG;
+metaconnect return METACONNECT;
+
+on|ifname return PF_IFNAME;
+rset|ruleset return PF_RSET;
+rnr|rulenum return PF_RNR;
+srnr|subrulenum return PF_SRNR;
+reason return PF_REASON;
+action return PF_ACTION;
+
+fisu return FISU;
+lssu return LSSU;
+lsu return LSSU;
+msu return MSU;
+sio return SIO;
+opc return OPC;
+dpc return DPC;
+sls return SLS;
+
+[ \r\n\t] ;
+[+\-*/:\[\]!<>()&|=] return yytext[0];
+">=" return GEQ;
+"<=" return LEQ;
+"!=" return NEQ;
+"==" return '=';
+"<<" return LSH;
+">>" return RSH;
+${B} { yylval.e = pcap_ether_aton(((char *)yytext)+1);
+ return AID; }
+{MAC} { yylval.e = pcap_ether_aton((char *)yytext);
+ return EID; }
+{N} { yylval.i = stoi((char *)yytext); return NUM; }
+({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) {
+ yylval.s = sdup((char *)yytext); return HID; }
+{V6} {
+#ifdef INET6
+ struct addrinfo hints, *res;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET6;
+ hints.ai_flags = AI_NUMERICHOST;
+ if (getaddrinfo(yytext, NULL, &hints, &res))
+ bpf_error("bogus IPv6 address %s", yytext);
+ else {
+ freeaddrinfo(res);
+ yylval.s = sdup((char *)yytext); return HID6;
+ }
+#else
+ bpf_error("IPv6 address %s not supported", yytext);
+#endif /*INET6*/
+ }
+{B}:+({B}:+)+ { bpf_error("bogus ethernet address %s", yytext); }
+icmptype { yylval.i = 0; return NUM; }
+icmpcode { yylval.i = 1; return NUM; }
+icmp-echoreply { yylval.i = 0; return NUM; }
+icmp-unreach { yylval.i = 3; return NUM; }
+icmp-sourcequench { yylval.i = 4; return NUM; }
+icmp-redirect { yylval.i = 5; return NUM; }
+icmp-echo { yylval.i = 8; return NUM; }
+icmp-routeradvert { yylval.i = 9; return NUM; }
+icmp-routersolicit { yylval.i = 10; return NUM; }
+icmp-timxceed { yylval.i = 11; return NUM; }
+icmp-paramprob { yylval.i = 12; return NUM; }
+icmp-tstamp { yylval.i = 13; return NUM; }
+icmp-tstampreply { yylval.i = 14; return NUM; }
+icmp-ireq { yylval.i = 15; return NUM; }
+icmp-ireqreply { yylval.i = 16; return NUM; }
+icmp-maskreq { yylval.i = 17; return NUM; }
+icmp-maskreply { yylval.i = 18; return NUM; }
+tcpflags { yylval.i = 13; return NUM; }
+tcp-fin { yylval.i = 0x01; return NUM; }
+tcp-syn { yylval.i = 0x02; return NUM; }
+tcp-rst { yylval.i = 0x04; return NUM; }
+tcp-push { yylval.i = 0x08; return NUM; }
+tcp-ack { yylval.i = 0x10; return NUM; }
+tcp-urg { yylval.i = 0x20; return NUM; }
+[A-Za-z0-9]([-_.A-Za-z0-9]*[.A-Za-z0-9])? {
+ yylval.s = sdup((char *)yytext); return ID; }
+"\\"[^ !()\n\t]+ { yylval.s = sdup((char *)yytext + 1); return ID; }
+[^ \[\]\t\n\-_.A-Za-z0-9!<>()&|=]+ {
+ bpf_error("illegal token: %s", yytext); }
+. { bpf_error("illegal char '%c'", *yytext); }
+%%
+void
+lex_init(buf)
+ const char *buf;
+{
+#ifdef FLEX_SCANNER
+ in_buffer = yy_scan_string(buf);
+#else
+ in_buffer = buf;
+#endif
+}
+
+/*
+ * Do any cleanup necessary after parsing.
+ */
+void
+lex_cleanup()
+{
+#ifdef FLEX_SCANNER
+ if (in_buffer != NULL)
+ yy_delete_buffer(in_buffer);
+ in_buffer = NULL;
+#endif
+}
+
+/*
+ * Also define a yywrap. Note that if we're using flex, it will
+ * define a macro to map this identifier to pcap_wrap.
+ */
+int
+yywrap()
+{
+ return 1;
+}
+
+/* Hex digit to integer. */
+static inline int
+xdtoi(c)
+ register int c;
+{
+ if (isdigit(c))
+ return c - '0';
+ else if (islower(c))
+ return c - 'a' + 10;
+ else
+ return c - 'A' + 10;
+}
+
+/*
+ * Convert string to integer. Just like atoi(), but checks for
+ * preceding 0x or 0 and uses hex or octal instead of decimal.
+ */
+static int
+stoi(s)
+ char *s;
+{
+ int base = 10;
+ int n = 0;
+
+ if (*s == '0') {
+ if (s[1] == 'x' || s[1] == 'X') {
+ s += 2;
+ base = 16;
+ }
+ else {
+ base = 8;
+ s += 1;
+ }
+ }
+ while (*s)
+ n = n * base + xdtoi(*s++);
+
+ return n;
+}
diff --git a/freebsd/contrib/libpcap/sf-pcap-ng.c b/freebsd/contrib/libpcap/sf-pcap-ng.c
new file mode 100644
index 00000000..f2ee14cb
--- /dev/null
+++ b/freebsd/contrib/libpcap/sf-pcap-ng.c
@@ -0,0 +1,1111 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * sf-pcap-ng.c - pcap-ng-file-format-specific code from savefile.c
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header$ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/types.h>
+#endif /* WIN32 */
+
+#include <errno.h>
+#include <memory.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pcap-int.h"
+
+#include "pcap-common.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "sf-pcap-ng.h"
+
+/*
+ * Block types.
+ */
+
+/*
+ * Common part at the beginning of all blocks.
+ */
+struct block_header {
+ bpf_u_int32 block_type;
+ bpf_u_int32 total_length;
+};
+
+/*
+ * Common trailer at the end of all blocks.
+ */
+struct block_trailer {
+ bpf_u_int32 total_length;
+};
+
+/*
+ * Common options.
+ */
+#define OPT_ENDOFOPT 0 /* end of options */
+#define OPT_COMMENT 1 /* comment string */
+
+/*
+ * Option header.
+ */
+struct option_header {
+ u_short option_code;
+ u_short option_length;
+};
+
+/*
+ * Structures for the part of each block type following the common
+ * part.
+ */
+
+/*
+ * Section Header Block.
+ */
+#define BT_SHB 0x0A0D0D0A
+
+struct section_header_block {
+ bpf_u_int32 byte_order_magic;
+ u_short major_version;
+ u_short minor_version;
+ u_int64_t section_length;
+ /* followed by options and trailer */
+};
+
+/*
+ * Byte-order magic value.
+ */
+#define BYTE_ORDER_MAGIC 0x1A2B3C4D
+
+/*
+ * Current version number. If major_version isn't PCAP_NG_VERSION_MAJOR,
+ * that means that this code can't read the file.
+ */
+#define PCAP_NG_VERSION_MAJOR 1
+
+/*
+ * Interface Description Block.
+ */
+#define BT_IDB 0x00000001
+
+struct interface_description_block {
+ u_short linktype;
+ u_short reserved;
+ bpf_u_int32 snaplen;
+ /* followed by options and trailer */
+};
+
+/*
+ * Options in the IDB.
+ */
+#define IF_NAME 2 /* interface name string */
+#define IF_DESCRIPTION 3 /* interface description string */
+#define IF_IPV4ADDR 4 /* interface's IPv4 address and netmask */
+#define IF_IPV6ADDR 5 /* interface's IPv6 address and prefix length */
+#define IF_MACADDR 6 /* interface's MAC address */
+#define IF_EUIADDR 7 /* interface's EUI address */
+#define IF_SPEED 8 /* interface's speed, in bits/s */
+#define IF_TSRESOL 9 /* interface's time stamp resolution */
+#define IF_TZONE 10 /* interface's time zone */
+#define IF_FILTER 11 /* filter used when capturing on interface */
+#define IF_OS 12 /* string OS on which capture on this interface was done */
+#define IF_FCSLEN 13 /* FCS length for this interface */
+#define IF_TSOFFSET 14 /* time stamp offset for this interface */
+
+/*
+ * Enhanced Packet Block.
+ */
+#define BT_EPB 0x00000006
+
+struct enhanced_packet_block {
+ bpf_u_int32 interface_id;
+ bpf_u_int32 timestamp_high;
+ bpf_u_int32 timestamp_low;
+ bpf_u_int32 caplen;
+ bpf_u_int32 len;
+ /* followed by packet data, options, and trailer */
+};
+
+/*
+ * Simple Packet Block.
+ */
+#define BT_SPB 0x00000003
+
+struct simple_packet_block {
+ bpf_u_int32 len;
+ /* followed by packet data and trailer */
+};
+
+/*
+ * Packet Block.
+ */
+#define BT_PB 0x00000002
+
+struct packet_block {
+ u_short interface_id;
+ u_short drops_count;
+ bpf_u_int32 timestamp_high;
+ bpf_u_int32 timestamp_low;
+ bpf_u_int32 caplen;
+ bpf_u_int32 len;
+ /* followed by packet data, options, and trailer */
+};
+
+/*
+ * Block cursor - used when processing the contents of a block.
+ * Contains a pointer into the data being processed and a count
+ * of bytes remaining in the block.
+ */
+struct block_cursor {
+ u_char *data;
+ size_t data_remaining;
+ bpf_u_int32 block_type;
+};
+
+static int pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr,
+ u_char **data);
+
+static int
+read_bytes(FILE *fp, void *buf, size_t bytes_to_read, int fail_on_eof,
+ char *errbuf)
+{
+ size_t amt_read;
+
+ amt_read = fread(buf, 1, bytes_to_read, fp);
+ if (amt_read != bytes_to_read) {
+ if (ferror(fp)) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ } else {
+ if (amt_read == 0 && !fail_on_eof)
+ return (0); /* EOF */
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "truncated dump file; tried to read %lu bytes, only got %lu",
+ (unsigned long)bytes_to_read,
+ (unsigned long)amt_read);
+ }
+ return (-1);
+ }
+ return (1);
+}
+
+static int
+read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
+{
+ int status;
+ struct block_header bhdr;
+
+ status = read_bytes(fp, &bhdr, sizeof(bhdr), 0, errbuf);
+ if (status <= 0)
+ return (status); /* error or EOF */
+
+ if (p->sf.swapped) {
+ bhdr.block_type = SWAPLONG(bhdr.block_type);
+ bhdr.total_length = SWAPLONG(bhdr.total_length);
+ }
+
+ /*
+ * Is this block "too big"?
+ *
+ * We choose 16MB as "too big", for now, so that we handle
+ * "reasonably" large buffers but don't chew up all the
+ * memory if we read a malformed file.
+ */
+ if (bhdr.total_length > 16*1024*1024) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "pcap-ng block size %u > maximum %u",
+ bhdr.total_length, 16*1024*1024);
+ return (-1);
+ }
+
+ /*
+ * Is this block "too small" - i.e., is it shorter than a block
+ * header plus a block trailer?
+ */
+ if (bhdr.total_length < sizeof(struct block_header) +
+ sizeof(struct block_trailer)) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "block in pcap-ng dump file has a length of %u < %lu",
+ bhdr.total_length,
+ (unsigned long)(sizeof(struct block_header) + sizeof(struct block_trailer)));
+ return (-1);
+ }
+
+ /*
+ * Is the buffer big enough?
+ */
+ if (p->bufsize < bhdr.total_length) {
+ /*
+ * No - make it big enough.
+ */
+ p->buffer = realloc(p->buffer, bhdr.total_length);
+ if (p->buffer == NULL) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
+ return (-1);
+ }
+ }
+
+ /*
+ * Copy the stuff we've read to the buffer, and read the rest
+ * of the block.
+ */
+ memcpy(p->buffer, &bhdr, sizeof(bhdr));
+ if (read_bytes(fp, p->buffer + sizeof(bhdr),
+ bhdr.total_length - sizeof(bhdr), 1, errbuf) == -1)
+ return (-1);
+
+ /*
+ * Initialize the cursor.
+ */
+ cursor->data = p->buffer + sizeof(bhdr);
+ cursor->data_remaining = bhdr.total_length - sizeof(bhdr) -
+ sizeof(struct block_trailer);
+ cursor->block_type = bhdr.block_type;
+ return (1);
+}
+
+static void *
+get_from_block_data(struct block_cursor *cursor, size_t chunk_size,
+ char *errbuf)
+{
+ void *data;
+
+ /*
+ * Make sure we have the specified amount of data remaining in
+ * the block data.
+ */
+ if (cursor->data_remaining < chunk_size) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "block of type %u in pcap-ng dump file is too short",
+ cursor->block_type);
+ return (NULL);
+ }
+
+ /*
+ * Return the current pointer, and skip past the chunk.
+ */
+ data = cursor->data;
+ cursor->data += chunk_size;
+ cursor->data_remaining -= chunk_size;
+ return (data);
+}
+
+static struct option_header *
+get_opthdr_from_block_data(pcap_t *p, struct block_cursor *cursor, char *errbuf)
+{
+ struct option_header *opthdr;
+
+ opthdr = get_from_block_data(cursor, sizeof(*opthdr), errbuf);
+ if (opthdr == NULL) {
+ /*
+ * Option header is cut short.
+ */
+ return (NULL);
+ }
+
+ /*
+ * Byte-swap it if necessary.
+ */
+ if (p->sf.swapped) {
+ opthdr->option_code = SWAPSHORT(opthdr->option_code);
+ opthdr->option_length = SWAPSHORT(opthdr->option_length);
+ }
+
+ return (opthdr);
+}
+
+static void *
+get_optvalue_from_block_data(struct block_cursor *cursor,
+ struct option_header *opthdr, char *errbuf)
+{
+ size_t padded_option_len;
+ void *optvalue;
+
+ /* Pad option length to 4-byte boundary */
+ padded_option_len = opthdr->option_length;
+ padded_option_len = ((padded_option_len + 3)/4)*4;
+
+ optvalue = get_from_block_data(cursor, padded_option_len, errbuf);
+ if (optvalue == NULL) {
+ /*
+ * Option value is cut short.
+ */
+ return (NULL);
+ }
+
+ return (optvalue);
+}
+
+static int
+process_idb_options(pcap_t *p, struct block_cursor *cursor, u_int *tsresol,
+ u_int64_t *tsoffset, char *errbuf)
+{
+ struct option_header *opthdr;
+ void *optvalue;
+ int saw_tsresol, saw_tsoffset;
+ u_char tsresol_opt;
+ u_int i;
+
+ saw_tsresol = 0;
+ saw_tsoffset = 0;
+ while (cursor->data_remaining != 0) {
+ /*
+ * Get the option header.
+ */
+ opthdr = get_opthdr_from_block_data(p, cursor, errbuf);
+ if (opthdr == NULL) {
+ /*
+ * Option header is cut short.
+ */
+ return (-1);
+ }
+
+ /*
+ * Get option value.
+ */
+ optvalue = get_optvalue_from_block_data(cursor, opthdr,
+ errbuf);
+ if (optvalue == NULL) {
+ /*
+ * Option value is cut short.
+ */
+ return (-1);
+ }
+
+ switch (opthdr->option_code) {
+
+ case OPT_ENDOFOPT:
+ if (opthdr->option_length != 0) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Interface Description Block has opt_endofopt option with length %u != 0",
+ opthdr->option_length);
+ return (-1);
+ }
+ goto done;
+
+ case IF_TSRESOL:
+ if (opthdr->option_length != 1) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Interface Description Block has if_tsresol option with length %u != 1",
+ opthdr->option_length);
+ return (-1);
+ }
+ if (saw_tsresol) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Interface Description Block has more than one if_tsresol option");
+ return (-1);
+ }
+ saw_tsresol = 1;
+ tsresol_opt = *(u_int *)optvalue;
+ if (tsresol_opt & 0x80) {
+ /*
+ * Resolution is negative power of 2.
+ */
+ *tsresol = 1 << (tsresol_opt & 0x7F);
+ } else {
+ /*
+ * Resolution is negative power of 10.
+ */
+ *tsresol = 1;
+ for (i = 0; i < tsresol_opt; i++)
+ *tsresol *= 10;
+ }
+ if (*tsresol == 0) {
+ /*
+ * Resolution is too high.
+ */
+ if (tsresol_opt & 0x80) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Interface Description Block if_tsresol option resolution 2^-%u is too high",
+ tsresol_opt & 0x7F);
+ } else {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Interface Description Block if_tsresol option resolution 10^-%u is too high",
+ tsresol_opt);
+ }
+ return (-1);
+ }
+ break;
+
+ case IF_TSOFFSET:
+ if (opthdr->option_length != 8) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Interface Description Block has if_tsoffset option with length %u != 8",
+ opthdr->option_length);
+ return (-1);
+ }
+ if (saw_tsoffset) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Interface Description Block has more than one if_tsoffset option");
+ return (-1);
+ }
+ saw_tsoffset = 1;
+ memcpy(tsoffset, optvalue, sizeof(*tsoffset));
+ if (p->sf.swapped)
+ *tsoffset = SWAPLL(*tsoffset);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+done:
+ return (0);
+}
+
+/*
+ * Check whether this is a pcap-ng savefile and, if it is, extract the
+ * relevant information from the header.
+ */
+int
+pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
+{
+ size_t amt_read;
+ bpf_u_int32 total_length;
+ bpf_u_int32 byte_order_magic;
+ struct block_header *bhdrp;
+ struct section_header_block *shbp;
+ int status;
+ struct block_cursor cursor;
+ struct interface_description_block *idbp;
+
+ /*
+ * Check whether the first 4 bytes of the file are the block
+ * type for a pcap-ng savefile.
+ */
+ if (magic != BT_SHB) {
+ /*
+ * XXX - check whether this looks like what the block
+ * type would be after being munged by mapping between
+ * UN*X and DOS/Windows text file format and, if it
+ * does, look for the byte-order magic number in
+ * the appropriate place and, if we find it, report
+ * this as possibly being a pcap-ng file transferred
+ * between UN*X and Windows in text file format?
+ */
+ return (0); /* nope */
+ }
+
+ /*
+ * OK, they are. However, that's just \n\r\r\n, so it could,
+ * conceivably, be an ordinary text file.
+ *
+ * It could not, however, conceivably be any other type of
+ * capture file, so we can read the rest of the putative
+ * Section Header Block; put the block type in the common
+ * header, read the rest of the common header and the
+ * fixed-length portion of the SHB, and look for the byte-order
+ * magic value.
+ */
+ amt_read = fread(&total_length, 1, sizeof(total_length), fp);
+ if (amt_read < sizeof(total_length)) {
+ if (ferror(fp)) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ return (-1); /* fail */
+ }
+
+ /*
+ * Possibly a weird short text file, so just say
+ * "not pcap-ng".
+ */
+ return (0);
+ }
+ amt_read = fread(&byte_order_magic, 1, sizeof(byte_order_magic), fp);
+ if (amt_read < sizeof(byte_order_magic)) {
+ if (ferror(fp)) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ return (-1); /* fail */
+ }
+
+ /*
+ * Possibly a weird short text file, so just say
+ * "not pcap-ng".
+ */
+ return (0);
+ }
+ if (byte_order_magic != BYTE_ORDER_MAGIC) {
+ byte_order_magic = SWAPLONG(byte_order_magic);
+ if (byte_order_magic != BYTE_ORDER_MAGIC) {
+ /*
+ * Not a pcap-ng file.
+ */
+ return (0);
+ }
+ p->sf.swapped = 1;
+ total_length = SWAPLONG(total_length);
+ }
+
+ /*
+ * Check the sanity of the total length.
+ */
+ if (total_length < sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer)) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Section Header Block in pcap-ng dump file has a length of %u < %lu",
+ total_length,
+ (unsigned long)(sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer)));
+ return (-1);
+ }
+
+ /*
+ * Allocate a buffer into which to read blocks. We default to
+ * the maximum of:
+ *
+ * the total length of the SHB for which we read the header;
+ *
+ * 2K, which should be more than large enough for an Enhanced
+ * Packet Block containing a full-size Ethernet frame, and
+ * leaving room for some options.
+ *
+ * If we find a bigger block, we reallocate the buffer.
+ */
+ p->bufsize = 2048;
+ if (p->bufsize < total_length)
+ p->bufsize = total_length;
+ p->buffer = malloc(p->bufsize);
+ if (p->buffer == NULL) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
+ return (-1);
+ }
+
+ /*
+ * Copy the stuff we've read to the buffer, and read the rest
+ * of the SHB.
+ */
+ bhdrp = (struct block_header *)p->buffer;
+ shbp = (struct section_header_block *)(p->buffer + sizeof(struct block_header));
+ bhdrp->block_type = magic;
+ bhdrp->total_length = total_length;
+ shbp->byte_order_magic = byte_order_magic;
+ if (read_bytes(fp,
+ p->buffer + (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)),
+ total_length - (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)),
+ 1, errbuf) == -1)
+ goto fail;
+
+ if (p->sf.swapped) {
+ /*
+ * Byte-swap the fields we've read.
+ */
+ shbp->major_version = SWAPSHORT(shbp->major_version);
+ shbp->minor_version = SWAPSHORT(shbp->minor_version);
+
+ /*
+ * XXX - we don't care about the section length.
+ */
+ }
+ if (shbp->major_version != PCAP_NG_VERSION_MAJOR) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "unknown pcap-ng savefile major version number %u",
+ shbp->major_version);
+ goto fail;
+ }
+ p->sf.version_major = shbp->major_version;
+ p->sf.version_minor = shbp->minor_version;
+
+ /*
+ * Set the default time stamp resolution and offset.
+ */
+ p->sf.tsresol = 1000000; /* microsecond resolution */
+ p->sf.tsscale = 1; /* multiply by 1 to scale to microseconds */
+ p->sf.tsoffset = 0; /* absolute timestamps */
+
+ /*
+ * Now start looking for an Interface Description Block.
+ */
+ for (;;) {
+ /*
+ * Read the next block.
+ */
+ status = read_block(fp, p, &cursor, errbuf);
+ if (status == 0) {
+ /* EOF - no IDB in this file */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "the capture file has no Interface Description Blocks");
+ goto fail;
+ }
+ if (status == -1)
+ goto fail; /* error */
+ switch (cursor.block_type) {
+
+ case BT_IDB:
+ /*
+ * Get a pointer to the fixed-length portion of the
+ * IDB.
+ */
+ idbp = get_from_block_data(&cursor, sizeof(*idbp),
+ errbuf);
+ if (idbp == NULL)
+ goto fail; /* error */
+
+ /*
+ * Byte-swap it if necessary.
+ */
+ if (p->sf.swapped) {
+ idbp->linktype = SWAPSHORT(idbp->linktype);
+ idbp->snaplen = SWAPLONG(idbp->snaplen);
+ }
+
+ /*
+ * Count this interface.
+ */
+ p->sf.ifcount++;
+
+ /*
+ * Now look for various time stamp options, so
+ * we know how to interpret the time stamps.
+ */
+ if (process_idb_options(p, &cursor, &p->sf.tsresol,
+ &p->sf.tsoffset, errbuf) == -1)
+ goto fail;
+
+ /*
+ * Compute the scaling factor to convert the
+ * sub-second part of the time stamp to
+ * microseconds.
+ */
+ if (p->sf.tsresol > 1000000) {
+ /*
+ * Higher than microsecond resolution;
+ * scale down to microseconds.
+ */
+ p->sf.tsscale = (p->sf.tsresol / 1000000);
+ } else {
+ /*
+ * Lower than microsecond resolution;
+ * scale up to microseconds.
+ */
+ p->sf.tsscale = (1000000 / p->sf.tsresol);
+ }
+ goto done;
+
+ case BT_EPB:
+ case BT_SPB:
+ case BT_PB:
+ /*
+ * Saw a packet before we saw any IDBs. That's
+ * not valid, as we don't know what link-layer
+ * encapsulation the packet has.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "the capture file has a packet block before any Interface Description Blocks");
+ goto fail;
+
+ default:
+ /*
+ * Just ignore it.
+ */
+ break;
+ }
+ }
+
+done:
+ p->tzoff = 0; /* XXX - not used in pcap */
+ p->snapshot = idbp->snaplen;
+ p->linktype = linktype_to_dlt(idbp->linktype);
+ p->linktype_ext = 0;
+
+ p->sf.next_packet_op = pcap_ng_next_packet;
+
+ return (1);
+
+fail:
+ free(p->buffer);
+ return (-1);
+}
+
+/*
+ * Read and return the next packet from the savefile. Return the header
+ * in hdr and a pointer to the contents in data. Return 0 on success, 1
+ * if there were no more packets, and -1 on an error.
+ */
+static int
+pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
+{
+ struct block_cursor cursor;
+ int status;
+ struct enhanced_packet_block *epbp;
+ struct simple_packet_block *spbp;
+ struct packet_block *pbp;
+ bpf_u_int32 interface_id = 0xFFFFFFFF;
+ struct interface_description_block *idbp;
+ struct section_header_block *shbp;
+ FILE *fp = p->sf.rfile;
+ u_int tsresol;
+ u_int64_t tsoffset;
+ u_int64_t t, sec, frac;
+
+ /*
+ * Look for an Enhanced Packet Block, a Simple Packet Block,
+ * or a Packet Block.
+ */
+ for (;;) {
+ /*
+ * Read the block type and length; those are common
+ * to all blocks.
+ */
+ status = read_block(fp, p, &cursor, p->errbuf);
+ if (status == 0)
+ return (1); /* EOF */
+ if (status == -1)
+ return (-1); /* error */
+ switch (cursor.block_type) {
+
+ case BT_EPB:
+ /*
+ * Get a pointer to the fixed-length portion of the
+ * EPB.
+ */
+ epbp = get_from_block_data(&cursor, sizeof(*epbp),
+ p->errbuf);
+ if (epbp == NULL)
+ return (-1); /* error */
+
+ /*
+ * Byte-swap it if necessary.
+ */
+ if (p->sf.swapped) {
+ /* these were written in opposite byte order */
+ interface_id = SWAPLONG(epbp->interface_id);
+ hdr->caplen = SWAPLONG(epbp->caplen);
+ hdr->len = SWAPLONG(epbp->len);
+ t = ((u_int64_t)SWAPLONG(epbp->timestamp_high)) << 32 |
+ SWAPLONG(epbp->timestamp_low);
+ } else {
+ interface_id = epbp->interface_id;
+ hdr->caplen = epbp->caplen;
+ hdr->len = epbp->len;
+ t = ((u_int64_t)epbp->timestamp_high) << 32 |
+ epbp->timestamp_low;
+ }
+ goto found;
+
+ case BT_SPB:
+ /*
+ * Get a pointer to the fixed-length portion of the
+ * SPB.
+ */
+ spbp = get_from_block_data(&cursor, sizeof(*spbp),
+ p->errbuf);
+ if (spbp == NULL)
+ return (-1); /* error */
+
+ /*
+ * SPB packets are assumed to have arrived on
+ * the first interface.
+ */
+ interface_id = 0;
+
+ /*
+ * Byte-swap it if necessary.
+ */
+ if (p->sf.swapped) {
+ /* these were written in opposite byte order */
+ hdr->len = SWAPLONG(spbp->len);
+ } else
+ hdr->len = spbp->len;
+
+ /*
+ * The SPB doesn't give the captured length;
+ * it's the minimum of the snapshot length
+ * and the packet length.
+ */
+ hdr->caplen = hdr->len;
+ if (hdr->caplen > p->snapshot)
+ hdr->caplen = p->snapshot;
+ t = 0; /* no time stamps */
+ goto found;
+
+ case BT_PB:
+ /*
+ * Get a pointer to the fixed-length portion of the
+ * PB.
+ */
+ pbp = get_from_block_data(&cursor, sizeof(*pbp),
+ p->errbuf);
+ if (pbp == NULL)
+ return (-1); /* error */
+
+ /*
+ * Byte-swap it if necessary.
+ */
+ if (p->sf.swapped) {
+ /* these were written in opposite byte order */
+ interface_id = SWAPSHORT(pbp->interface_id);
+ hdr->caplen = SWAPLONG(pbp->caplen);
+ hdr->len = SWAPLONG(pbp->len);
+ t = ((u_int64_t)SWAPLONG(pbp->timestamp_high)) << 32 |
+ SWAPLONG(pbp->timestamp_low);
+ } else {
+ interface_id = pbp->interface_id;
+ hdr->caplen = pbp->caplen;
+ hdr->len = pbp->len;
+ t = ((u_int64_t)pbp->timestamp_high) << 32 |
+ pbp->timestamp_low;
+ }
+ goto found;
+
+ case BT_IDB:
+ /*
+ * Interface Description Block. Get a pointer
+ * to its fixed-length portion.
+ */
+ idbp = get_from_block_data(&cursor, sizeof(*idbp),
+ p->errbuf);
+ if (idbp == NULL)
+ return (-1); /* error */
+
+ /*
+ * Byte-swap it if necessary.
+ */
+ if (p->sf.swapped) {
+ idbp->linktype = SWAPSHORT(idbp->linktype);
+ idbp->snaplen = SWAPLONG(idbp->snaplen);
+ }
+
+ /*
+ * If the link-layer type or snapshot length
+ * differ from the ones for the first IDB we
+ * saw, quit.
+ *
+ * XXX - just discard packets from those
+ * interfaces?
+ */
+ if (p->linktype != idbp->linktype) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "an interface has a type %u different from the type of the first interface",
+ idbp->linktype);
+ return (-1);
+ }
+ if (p->snapshot != idbp->snaplen) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "an interface has a snapshot length %u different from the type of the first interface",
+ idbp->snaplen);
+ return (-1);
+ }
+
+ /*
+ * Count this interface.
+ */
+ p->sf.ifcount++;
+
+ /*
+ * Set the default time stamp resolution and offset.
+ */
+ tsresol = 1000000; /* microsecond resolution */
+ tsoffset = 0; /* absolute timestamps */
+
+ /*
+ * Now look for various time stamp options, to
+ * make sure they're the same.
+ *
+ * XXX - we could, in theory, handle multiple
+ * different resolutions and offsets, but we
+ * don't do so for now.
+ */
+ if (process_idb_options(p, &cursor, &tsresol, &tsoffset,
+ p->errbuf) == -1)
+ return (-1);
+ if (tsresol != p->sf.tsresol) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "an interface has a time stamp resolution different from the time stamp resolution of the first interface");
+ return (-1);
+ }
+ if (tsoffset != p->sf.tsoffset) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "an interface has a time stamp offset different from the time stamp offset of the first interface");
+ return (-1);
+ }
+ break;
+
+ case BT_SHB:
+ /*
+ * Section Header Block. Get a pointer
+ * to its fixed-length portion.
+ */
+ shbp = get_from_block_data(&cursor, sizeof(*shbp),
+ p->errbuf);
+ if (shbp == NULL)
+ return (-1); /* error */
+
+ /*
+ * Assume the byte order of this section is
+ * the same as that of the previous section.
+ * We'll check for that later.
+ */
+ if (p->sf.swapped) {
+ shbp->byte_order_magic =
+ SWAPLONG(shbp->byte_order_magic);
+ shbp->major_version =
+ SWAPSHORT(shbp->major_version);
+ }
+
+ /*
+ * Make sure the byte order doesn't change;
+ * pcap_is_swapped() shouldn't change its
+ * return value in the middle of reading a capture.
+ */
+ switch (shbp->byte_order_magic) {
+
+ case BYTE_ORDER_MAGIC:
+ /*
+ * OK.
+ */
+ break;
+
+ case SWAPLONG(BYTE_ORDER_MAGIC):
+ /*
+ * Byte order changes.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "the file has sections with different byte orders");
+ return (-1);
+
+ default:
+ /*
+ * Not a valid SHB.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "the file has a section with a bad byte order magic field");
+ return (-1);
+ }
+
+ /*
+ * Make sure the major version is the version
+ * we handle.
+ */
+ if (shbp->major_version != PCAP_NG_VERSION_MAJOR) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "unknown pcap-ng savefile major version number %u",
+ shbp->major_version);
+ return (-1);
+ }
+
+ /*
+ * Reset the interface count; this section should
+ * have its own set of IDBs. If any of them
+ * don't have the same interface type, snapshot
+ * length, or resolution as the first interface
+ * we saw, we'll fail. (And if we don't see
+ * any IDBs, we'll fail when we see a packet
+ * block.)
+ */
+ p->sf.ifcount = 0;
+ break;
+
+ default:
+ /*
+ * Not a packet block, IDB, or SHB; ignore it.
+ */
+ break;
+ }
+ }
+
+found:
+ /*
+ * Is the interface ID an interface we know?
+ */
+ if (interface_id >= p->sf.ifcount) {
+ /*
+ * Yes. Fail.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "a packet arrived on interface %u, but there's no Interface Description Block for that interface",
+ interface_id);
+ return (-1);
+ }
+
+ /*
+ * Convert the time stamp to a struct timeval.
+ */
+ sec = t / p->sf.tsresol + p->sf.tsoffset;
+ frac = t % p->sf.tsresol;
+ if (p->sf.tsresol > 1000000) {
+ /*
+ * Higher than microsecond resolution; scale down to
+ * microseconds.
+ */
+ frac /= p->sf.tsscale;
+ } else {
+ /*
+ * Lower than microsecond resolution; scale up to
+ * microseconds.
+ */
+ frac *= p->sf.tsscale;
+ }
+ hdr->ts.tv_sec = sec;
+ hdr->ts.tv_usec = frac;
+
+ /*
+ * Get a pointer to the packet data.
+ */
+ *data = get_from_block_data(&cursor, hdr->caplen, p->errbuf);
+ if (*data == NULL)
+ return (-1);
+
+ if (p->sf.swapped) {
+ /*
+ * Convert pseudo-headers from the byte order of
+ * the host on which the file was saved to our
+ * byte order, as necessary.
+ */
+ switch (p->linktype) {
+
+ case DLT_USB_LINUX:
+ swap_linux_usb_header(hdr, *data, 0);
+ break;
+
+ case DLT_USB_LINUX_MMAPPED:
+ swap_linux_usb_header(hdr, *data, 1);
+ break;
+ }
+ }
+
+ return (0);
+}
diff --git a/freebsd/contrib/libpcap/sf-pcap-ng.h b/freebsd/contrib/libpcap/sf-pcap-ng.h
new file mode 100644
index 00000000..cc551824
--- /dev/null
+++ b/freebsd/contrib/libpcap/sf-pcap-ng.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * sf-pcap-ng.h - pcap-ng-file-format-specific routines
+ *
+ * Used to read pcap-ng savefiles.
+ */
+
+#ifndef sf_pcap_ng_h
+#define sf_pcap_ng_h
+
+extern int pcap_ng_check_header(pcap_t *, bpf_u_int32, FILE *, char *);
+
+#endif
diff --git a/freebsd/contrib/libpcap/sf-pcap.c b/freebsd/contrib/libpcap/sf-pcap.c
new file mode 100644
index 00000000..6f967c58
--- /dev/null
+++ b/freebsd/contrib/libpcap/sf-pcap.c
@@ -0,0 +1,620 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * sf-pcap.c - libpcap-file-format-specific code from savefile.c
+ * Extraction/creation by Jeffrey Mogul, DECWRL
+ * Modified by Steve McCanne, LBL.
+ *
+ * Used to save the received packet headers, after filtering, to
+ * a file, and then read them later.
+ * The first record in the file contains saved values for the machine
+ * dependent values so we can print the dump file on any architecture.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header$ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/types.h>
+#endif /* WIN32 */
+
+#include <errno.h>
+#include <memory.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pcap-int.h"
+
+#include "pcap-common.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "sf-pcap.h"
+
+/*
+ * Setting O_BINARY on DOS/Windows is a bit tricky
+ */
+#if defined(WIN32)
+ #define SET_BINMODE(f) _setmode(_fileno(f), _O_BINARY)
+#elif defined(MSDOS)
+ #if defined(__HIGHC__)
+ #define SET_BINMODE(f) setmode(f, O_BINARY)
+ #else
+ #define SET_BINMODE(f) setmode(fileno(f), O_BINARY)
+ #endif
+#endif
+
+/*
+ * Standard libpcap format.
+ */
+#define TCPDUMP_MAGIC 0xa1b2c3d4
+
+/*
+ * Alexey Kuznetzov's modified libpcap format.
+ */
+#define KUZNETZOV_TCPDUMP_MAGIC 0xa1b2cd34
+
+/*
+ * Reserved for Francisco Mesquita <francisco.mesquita@radiomovel.pt>
+ * for another modified format.
+ */
+#define FMESQUITA_TCPDUMP_MAGIC 0xa1b234cd
+
+/*
+ * Navtel Communcations' format, with nanosecond timestamps,
+ * as per a request from Dumas Hwang <dumas.hwang@navtelcom.com>.
+ */
+#define NAVTEL_TCPDUMP_MAGIC 0xa12b3c4d
+
+/*
+ * Normal libpcap format, except for seconds/nanoseconds timestamps,
+ * as per a request by Ulf Lamping <ulf.lamping@web.de>
+ */
+#define NSEC_TCPDUMP_MAGIC 0xa1b23c4d
+
+/*
+ * Mechanism for storing information about a capture in the upper
+ * 6 bits of a linktype value in a capture file.
+ *
+ * LT_LINKTYPE_EXT(x) extracts the additional information.
+ *
+ * The rest of the bits are for a value describing the link-layer
+ * value. LT_LINKTYPE(x) extracts that value.
+ */
+#define LT_LINKTYPE(x) ((x) & 0x03FFFFFF)
+#define LT_LINKTYPE_EXT(x) ((x) & 0xFC000000)
+
+static int pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **datap);
+
+/*
+ * Check whether this is a pcap savefile and, if it is, extract the
+ * relevant information from the header.
+ */
+int
+pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
+{
+ struct pcap_file_header hdr;
+ size_t amt_read;
+
+ /*
+ * Check whether the first 4 bytes of the file are the magic
+ * number for a pcap savefile, or for a byte-swapped pcap
+ * savefile.
+ */
+ if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC) {
+ magic = SWAPLONG(magic);
+ if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC)
+ return (0); /* nope */
+ p->sf.swapped = 1;
+ }
+
+ /*
+ * They are. Put the magic number in the header, and read
+ * the rest of the header.
+ */
+ hdr.magic = magic;
+ amt_read = fread(((char *)&hdr) + sizeof hdr.magic, 1,
+ sizeof(hdr) - sizeof(hdr.magic), fp);
+ if (amt_read != sizeof(hdr) - sizeof(hdr.magic)) {
+ if (ferror(fp)) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ } else {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "truncated dump file; tried to read %lu file header bytes, only got %lu",
+ (unsigned long)sizeof(hdr),
+ (unsigned long)amt_read);
+ }
+ return (-1);
+ }
+
+ /*
+ * If it's a byte-swapped capture file, byte-swap the header.
+ */
+ if (p->sf.swapped) {
+ hdr.version_major = SWAPSHORT(hdr.version_major);
+ hdr.version_minor = SWAPSHORT(hdr.version_minor);
+ hdr.thiszone = SWAPLONG(hdr.thiszone);
+ hdr.sigfigs = SWAPLONG(hdr.sigfigs);
+ hdr.snaplen = SWAPLONG(hdr.snaplen);
+ hdr.linktype = SWAPLONG(hdr.linktype);
+ }
+
+ if (hdr.version_major < PCAP_VERSION_MAJOR) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "archaic pcap savefile format");
+ return (-1);
+ }
+ p->sf.version_major = hdr.version_major;
+ p->sf.version_minor = hdr.version_minor;
+ p->tzoff = hdr.thiszone;
+ p->snapshot = hdr.snaplen;
+ p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype));
+ p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype);
+
+ p->sf.next_packet_op = pcap_next_packet;
+
+ /*
+ * We interchanged the caplen and len fields at version 2.3,
+ * in order to match the bpf header layout. But unfortunately
+ * some files were written with version 2.3 in their headers
+ * but without the interchanged fields.
+ *
+ * In addition, DG/UX tcpdump writes out files with a version
+ * number of 543.0, and with the caplen and len fields in the
+ * pre-2.3 order.
+ */
+ switch (hdr.version_major) {
+
+ case 2:
+ if (hdr.version_minor < 3)
+ p->sf.lengths_swapped = SWAPPED;
+ else if (hdr.version_minor == 3)
+ p->sf.lengths_swapped = MAYBE_SWAPPED;
+ else
+ p->sf.lengths_swapped = NOT_SWAPPED;
+ break;
+
+ case 543:
+ p->sf.lengths_swapped = SWAPPED;
+ break;
+
+ default:
+ p->sf.lengths_swapped = NOT_SWAPPED;
+ break;
+ }
+
+ if (magic == KUZNETZOV_TCPDUMP_MAGIC) {
+ /*
+ * XXX - the patch that's in some versions of libpcap
+ * changes the packet header but not the magic number,
+ * and some other versions with this magic number have
+ * some extra debugging information in the packet header;
+ * we'd have to use some hacks^H^H^H^H^Hheuristics to
+ * detect those variants.
+ *
+ * Ethereal does that, but it does so by trying to read
+ * the first two packets of the file with each of the
+ * record header formats. That currently means it seeks
+ * backwards and retries the reads, which doesn't work
+ * on pipes. We want to be able to read from a pipe, so
+ * that strategy won't work; we'd have to buffer some
+ * data ourselves and read from that buffer in order to
+ * make that work.
+ */
+ p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr);
+
+ if (p->linktype == DLT_EN10MB) {
+ /*
+ * This capture might have been done in raw mode
+ * or cooked mode.
+ *
+ * If it was done in cooked mode, p->snapshot was
+ * passed to recvfrom() as the buffer size, meaning
+ * that the most packet data that would be copied
+ * would be p->snapshot. However, a faked Ethernet
+ * header would then have been added to it, so the
+ * most data that would be in a packet in the file
+ * would be p->snapshot + 14.
+ *
+ * We can't easily tell whether the capture was done
+ * in raw mode or cooked mode, so we'll assume it was
+ * cooked mode, and add 14 to the snapshot length.
+ * That means that, for a raw capture, the snapshot
+ * length will be misleading if you use it to figure
+ * out why a capture doesn't have all the packet data,
+ * but there's not much we can do to avoid that.
+ */
+ p->snapshot += 14;
+ }
+ } else
+ p->sf.hdrsize = sizeof(struct pcap_sf_pkthdr);
+
+ /*
+ * Allocate a buffer for the packet data.
+ */
+ p->bufsize = p->snapshot;
+ if (p->bufsize <= 0) {
+ /*
+ * Bogus snapshot length; use 64KiB as a fallback.
+ */
+ p->bufsize = 65536;
+ }
+ p->buffer = malloc(p->bufsize);
+ if (p->buffer == NULL) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
+ return (-1);
+ }
+
+ return (1);
+}
+
+/*
+ * Read and return the next packet from the savefile. Return the header
+ * in hdr and a pointer to the contents in data. Return 0 on success, 1
+ * if there were no more packets, and -1 on an error.
+ */
+static int
+pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
+{
+ struct pcap_sf_patched_pkthdr sf_hdr;
+ FILE *fp = p->sf.rfile;
+ size_t amt_read;
+ bpf_u_int32 t;
+
+ /*
+ * Read the packet header; the structure we use as a buffer
+ * is the longer structure for files generated by the patched
+ * libpcap, but if the file has the magic number for an
+ * unpatched libpcap we only read as many bytes as the regular
+ * header has.
+ */
+ amt_read = fread(&sf_hdr, 1, p->sf.hdrsize, fp);
+ if (amt_read != p->sf.hdrsize) {
+ if (ferror(fp)) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ return (-1);
+ } else {
+ if (amt_read != 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "truncated dump file; tried to read %lu header bytes, only got %lu",
+ (unsigned long)p->sf.hdrsize,
+ (unsigned long)amt_read);
+ return (-1);
+ }
+ /* EOF */
+ return (1);
+ }
+ }
+
+ if (p->sf.swapped) {
+ /* these were written in opposite byte order */
+ hdr->caplen = SWAPLONG(sf_hdr.caplen);
+ hdr->len = SWAPLONG(sf_hdr.len);
+ hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec);
+ hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec);
+ } else {
+ hdr->caplen = sf_hdr.caplen;
+ hdr->len = sf_hdr.len;
+ hdr->ts.tv_sec = sf_hdr.ts.tv_sec;
+ hdr->ts.tv_usec = sf_hdr.ts.tv_usec;
+ }
+ /* Swap the caplen and len fields, if necessary. */
+ switch (p->sf.lengths_swapped) {
+
+ case NOT_SWAPPED:
+ break;
+
+ case MAYBE_SWAPPED:
+ if (hdr->caplen <= hdr->len) {
+ /*
+ * The captured length is <= the actual length,
+ * so presumably they weren't swapped.
+ */
+ break;
+ }
+ /* FALLTHROUGH */
+
+ case SWAPPED:
+ t = hdr->caplen;
+ hdr->caplen = hdr->len;
+ hdr->len = t;
+ break;
+ }
+
+ if (hdr->caplen > p->bufsize) {
+ /*
+ * This can happen due to Solaris 2.3 systems tripping
+ * over the BUFMOD problem and not setting the snapshot
+ * correctly in the savefile header. If the caplen isn't
+ * grossly wrong, try to salvage.
+ */
+ static u_char *tp = NULL;
+ static size_t tsize = 0;
+
+ if (hdr->caplen > 65535) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "bogus savefile header");
+ return (-1);
+ }
+
+ if (tsize < hdr->caplen) {
+ tsize = ((hdr->caplen + 1023) / 1024) * 1024;
+ if (tp != NULL)
+ free((u_char *)tp);
+ tp = (u_char *)malloc(tsize);
+ if (tp == NULL) {
+ tsize = 0;
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "BUFMOD hack malloc");
+ return (-1);
+ }
+ }
+ amt_read = fread((char *)tp, 1, hdr->caplen, fp);
+ if (amt_read != hdr->caplen) {
+ if (ferror(fp)) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ } else {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "truncated dump file; tried to read %u captured bytes, only got %lu",
+ hdr->caplen, (unsigned long)amt_read);
+ }
+ return (-1);
+ }
+ /*
+ * We can only keep up to p->bufsize bytes. Since
+ * caplen > p->bufsize is exactly how we got here,
+ * we know we can only keep the first p->bufsize bytes
+ * and must drop the remainder. Adjust caplen accordingly,
+ * so we don't get confused later as to how many bytes we
+ * have to play with.
+ */
+ hdr->caplen = p->bufsize;
+ memcpy(p->buffer, (char *)tp, p->bufsize);
+ } else {
+ /* read the packet itself */
+ amt_read = fread(p->buffer, 1, hdr->caplen, fp);
+ if (amt_read != hdr->caplen) {
+ if (ferror(fp)) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ } else {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "truncated dump file; tried to read %u captured bytes, only got %lu",
+ hdr->caplen, (unsigned long)amt_read);
+ }
+ return (-1);
+ }
+ }
+ *data = p->buffer;
+
+ if (p->sf.swapped) {
+ /*
+ * Convert pseudo-headers from the byte order of
+ * the host on which the file was saved to our
+ * byte order, as necessary.
+ */
+ switch (p->linktype) {
+
+ case DLT_USB_LINUX:
+ swap_linux_usb_header(hdr, *data, 0);
+ break;
+
+ case DLT_USB_LINUX_MMAPPED:
+ swap_linux_usb_header(hdr, *data, 1);
+ break;
+ }
+ }
+
+ return (0);
+}
+
+static int
+sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen)
+{
+ struct pcap_file_header hdr;
+
+ hdr.magic = TCPDUMP_MAGIC;
+ hdr.version_major = PCAP_VERSION_MAJOR;
+ hdr.version_minor = PCAP_VERSION_MINOR;
+
+ hdr.thiszone = thiszone;
+ hdr.snaplen = snaplen;
+ hdr.sigfigs = 0;
+ hdr.linktype = linktype;
+
+ if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1)
+ return (-1);
+
+ return (0);
+}
+
+/*
+ * Output a packet to the initialized dump file.
+ */
+void
+pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
+{
+ register FILE *f;
+ struct pcap_sf_pkthdr sf_hdr;
+
+ f = (FILE *)user;
+ sf_hdr.ts.tv_sec = h->ts.tv_sec;
+ sf_hdr.ts.tv_usec = h->ts.tv_usec;
+ sf_hdr.caplen = h->caplen;
+ sf_hdr.len = h->len;
+ /* XXX we should check the return status */
+ (void)fwrite(&sf_hdr, sizeof(sf_hdr), 1, f);
+ (void)fwrite(sp, h->caplen, 1, f);
+}
+
+static pcap_dumper_t *
+pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname)
+{
+
+#if defined(WIN32) || defined(MSDOS)
+ /*
+ * If we're writing to the standard output, put it in binary
+ * mode, as savefiles are binary files.
+ *
+ * Otherwise, we turn off buffering.
+ * XXX - why? And why not on the standard output?
+ */
+ if (f == stdout)
+ SET_BINMODE(f);
+ else
+ setbuf(f, NULL);
+#endif
+ if (sf_write_header(f, linktype, p->tzoff, p->snapshot) == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to %s: %s",
+ fname, pcap_strerror(errno));
+ if (f != stdout)
+ (void)fclose(f);
+ return (NULL);
+ }
+ return ((pcap_dumper_t *)f);
+}
+
+/*
+ * Initialize so that sf_write() will output to the file named 'fname'.
+ */
+pcap_dumper_t *
+pcap_dump_open(pcap_t *p, const char *fname)
+{
+ FILE *f;
+ int linktype;
+
+ /*
+ * If this pcap_t hasn't been activated, it doesn't have a
+ * link-layer type, so we can't use it.
+ */
+ if (!p->activated) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "%s: not-yet-activated pcap_t passed to pcap_dump_open",
+ fname);
+ return (NULL);
+ }
+ linktype = dlt_to_linktype(p->linktype);
+ if (linktype == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "%s: link-layer type %d isn't supported in savefiles",
+ fname, p->linktype);
+ return (NULL);
+ }
+ linktype |= p->linktype_ext;
+
+ if (fname[0] == '-' && fname[1] == '\0') {
+ f = stdout;
+ fname = "standard output";
+ } else {
+#if !defined(WIN32) && !defined(MSDOS)
+ f = fopen(fname, "w");
+#else
+ f = fopen(fname, "wb");
+#endif
+ if (f == NULL) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
+ fname, pcap_strerror(errno));
+ return (NULL);
+ }
+ }
+ return (pcap_setup_dump(p, linktype, f, fname));
+}
+
+/*
+ * Initialize so that sf_write() will output to the given stream.
+ */
+pcap_dumper_t *
+pcap_dump_fopen(pcap_t *p, FILE *f)
+{
+ int linktype;
+
+ linktype = dlt_to_linktype(p->linktype);
+ if (linktype == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "stream: link-layer type %d isn't supported in savefiles",
+ p->linktype);
+ return (NULL);
+ }
+ linktype |= p->linktype_ext;
+
+ return (pcap_setup_dump(p, linktype, f, "stream"));
+}
+
+FILE *
+pcap_dump_file(pcap_dumper_t *p)
+{
+ return ((FILE *)p);
+}
+
+long
+pcap_dump_ftell(pcap_dumper_t *p)
+{
+ return (ftell((FILE *)p));
+}
+
+int
+pcap_dump_flush(pcap_dumper_t *p)
+{
+
+ if (fflush((FILE *)p) == EOF)
+ return (-1);
+ else
+ return (0);
+}
+
+void
+pcap_dump_close(pcap_dumper_t *p)
+{
+
+#ifdef notyet
+ if (ferror((FILE *)p))
+ return-an-error;
+ /* XXX should check return from fclose() too */
+#endif
+ (void)fclose((FILE *)p);
+}
diff --git a/freebsd/contrib/libpcap/sf-pcap.h b/freebsd/contrib/libpcap/sf-pcap.h
new file mode 100644
index 00000000..3b3fbe89
--- /dev/null
+++ b/freebsd/contrib/libpcap/sf-pcap.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * sf-pcap.h - libpcap-file-format-specific routines
+ * Extraction/creation by Jeffrey Mogul, DECWRL
+ * Modified by Steve McCanne, LBL.
+ *
+ * Used to save the received packet headers, after filtering, to
+ * a file, and then read them later.
+ * The first record in the file contains saved values for the machine
+ * dependent values so we can print the dump file on any architecture.
+ */
+
+#ifndef sf_pcap_h
+#define sf_pcap_h
+
+extern int pcap_check_header(pcap_t *, bpf_u_int32, FILE *, char *);
+
+#endif
diff --git a/freebsd/contrib/libpcap/sunatmpos.h b/freebsd/contrib/libpcap/sunatmpos.h
new file mode 100644
index 00000000..916017fa
--- /dev/null
+++ b/freebsd/contrib/libpcap/sunatmpos.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1997 Yen Yen Lim and North Dakota State University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Yen Yen Lim and
+ North Dakota State University
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/sunatmpos.h,v 1.1 2002-07-11 09:06:47 guy Exp $ (LBL)
+ */
+
+/* SunATM header for ATM packet */
+#define SUNATM_DIR_POS 0
+#define SUNATM_VPI_POS 1
+#define SUNATM_VCI_POS 2
+#define SUNATM_PKT_BEGIN_POS 4 /* Start of ATM packet */
+
+/* Protocol type values in the bottom for bits of the byte at SUNATM_DIR_POS. */
+#define PT_LANE 0x01 /* LANE */
+#define PT_LLC 0x02 /* LLC encapsulation */
+#define PT_ILMI 0x05 /* ILMI */
+#define PT_QSAAL 0x06 /* Q.SAAL */