From 02e80d9105f66aad7aeaaa8a5efb6a773fb9f6dd Mon Sep 17 00:00:00 2001 From: guy Date: Sun, 18 Nov 2007 02:04:55 +0000 Subject: [PATCH] Support OpenBSD's "addr1", "addr2", "addr3", and "addr4" link-layer address types for 802.11. Support the OpenBSD names for some of the 802.11 frame types. Support OpenBSD's "dir" keyword for 802.11 frame directions. --- gencode.c | 77 ++++++++++++- gencode.h | 200 ++++++++++++++++++++++++++++++---- grammar.y | 182 ++++++++++++++++++++++--------- ieee80211.h | 146 +++++++++++++++++++++++++ scanner.l | 307 ++++++++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 807 insertions(+), 105 deletions(-) create mode 100644 ieee80211.h diff --git a/gencode.c b/gencode.c index da35b4d7..6be39c09 100644 --- a/gencode.c +++ b/gencode.c @@ -21,7 +21,7 @@ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.290.2.11 2007-11-10 21:53:33 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.290.2.12 2007-11-18 02:04:55 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -68,6 +68,7 @@ static const char rcsid[] _U_ = #include "nlpid.h" #include "llc.h" #include "gencode.h" +#include "ieee80211.h" #include "atmuni31.h" #include "sunatmpos.h" #include "ppp.h" @@ -3840,6 +3841,55 @@ gen_wlanhostop(eaddr, dir) gen_and(b1, b0); return b0; + /* + * XXX - add RA, TA, and BSSID keywords? + */ + 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); @@ -7290,6 +7340,31 @@ gen_p80211_type(int type, int mask) 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_IEEE802_11_RADIO_AVS: + case DLT_IEEE802_11_RADIO: + case DLT_PRISM_HEADER: + 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); } diff --git a/gencode.h b/gencode.h index 6fe3eac4..91788657 100644 --- a/gencode.h +++ b/gencode.h @@ -18,11 +18,46 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.36.1.1 1999-10-07 23:46:40 mcr Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.70.2.1 2007-11-18 02:04:55 guy Exp $ (LBL) */ -/*XXX*/ -#include "gnuc.h" +/* + * 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. */ @@ -31,6 +66,8 @@ #define Q_PORT 3 #define Q_GATEWAY 4 #define Q_PROTO 5 +#define Q_PROTOCHAIN 6 +#define Q_PORTRANGE 7 /* Protocol qualifiers. */ @@ -38,19 +75,56 @@ #define Q_IP 2 #define Q_ARP 3 #define Q_RARP 4 -#define Q_TCP 5 -#define Q_UDP 6 -#define Q_ICMP 7 -#define Q_IGMP 8 -#define Q_IGRP 9 +#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_ATALK 10 -#define Q_DECNET 11 -#define Q_LAT 12 -#define Q_SCA 13 -#define Q_MOPRC 14 -#define Q_MOPDL 15 +#define Q_RADIO 40 /* Directional qualifiers. */ @@ -58,12 +132,69 @@ #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_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; }; @@ -72,7 +203,7 @@ struct slist { struct slist *next; }; -/* +/* * A bit vector to represent definition sets. We assume TOT_REGISTERS * is smaller than 8*sizeof(atomset). */ @@ -149,7 +280,11 @@ 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); @@ -160,20 +295,45 @@ 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 **); -#if __STDC__ -__dead void bpf_error(const char *, ...) - __attribute__((volatile, format (printf, 1, 2))); -#endif +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 *, int *); int pcap_parse(void); -void lex_init(char *); +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/grammar.y b/grammar.y index 7678a508..a4922442 100644 --- a/grammar.y +++ b/grammar.y @@ -22,7 +22,7 @@ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.99.2.1 2007-11-14 00:55:37 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.99.2.2 2007-11-18 02:04:55 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -68,9 +68,91 @@ struct rtentry; (q).dir = (d),\ (q).addr = (a) -static const char *ieee80211_mgt_names[] = IEEE80211_MGT_SUBTYPE_NAMES; -static const char *ieee80211_ctl_names[] = IEEE80211_CTL_SUBTYPE_NAMES; -static const char *ieee80211_data_names[] = IEEE80211_DATA_SUBTYPE_NAMES; +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; @@ -194,6 +276,7 @@ pfaction_to_num(const char *action) %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 %token LINK %token GEQ LEQ NEQ %token ID EID HID HID6 AID @@ -212,13 +295,12 @@ pfaction_to_num(const char *action) %token RADIO %token FISU LSSU MSU %token SIO OPC DPC SLS -%token TYPE SUBTYPE %type ID %type EID %type AID %type HID HID6 -%type NUM action reason type subtype type_subtype +%type NUM action reason type subtype type_subtype dir %left OR AND %nonassoc '!' @@ -355,6 +437,10 @@ dqual: SRC { $$ = Q_SRC; } | 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; } ; /* address type qualifiers */ aqual: HOST { $$ = Q_HOST; } @@ -441,71 +527,67 @@ p80211: TYPE type SUBTYPE subtype IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK); } + | DIR dir { $$ = gen_p80211_fcdir($2); } ; type: NUM - | ID { const char *names[] = IEEE80211_TYPE_NAMES; - int i, lim; - lim = (IEEE80211_FC0_TYPE_MASK >> IEEE80211_FC0_TYPE_SHIFT) + 1; - for (i = 0; i < lim; ++i) { - if (pcap_strcasecmp($1, names[i]) == 0) { - $$ = i << IEEE80211_FC0_TYPE_SHIFT; - break; - } - } - if (i == lim) + | ID { $$ = str2tok($1, ieee80211_types); + if ($$ == -1) bpf_error("unknown 802.11 type name"); } ; subtype: NUM - | ID { const char **names; - int i, lim; - if ($-1 == IEEE80211_FC0_TYPE_MGT) - names = ieee80211_mgt_names; - else if ($-1 == IEEE80211_FC0_TYPE_CTL) - names = ieee80211_ctl_names; - else if ($-1 == IEEE80211_FC0_TYPE_DATA) - names = ieee80211_data_names; - else - bpf_error("unknown 802.11 type"); - lim = (IEEE80211_FC0_SUBTYPE_MASK >> IEEE80211_FC0_SUBTYPE_SHIFT) + 1; - for (i = 0; i < lim; ++i) { - if (pcap_strcasecmp($1, names[i]) == 0) { - $$ = i << IEEE80211_FC0_SUBTYPE_SHIFT; + | 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 ($-1 == ieee80211_type_subtypes[i].type) { + types = ieee80211_type_subtypes[i].tok; break; } } - if (i == lim) - bpf_error("unknown 802.11 subtype name"); + + $$ = str2tok($1, types); + if ($$ == -1) + bpf_error("unknown 802.11 subtype name"); } ; -type_subtype: ID { const char **sub_names[] = { - ieee80211_mgt_names, - ieee80211_ctl_names, - ieee80211_data_names - }; - int i, j, lim, sub_lim; - sub_lim = sizeof(sub_names) / sizeof(sub_names[0]); - lim = (IEEE80211_FC0_SUBTYPE_MASK >> IEEE80211_FC0_SUBTYPE_SHIFT) + 1; - for (i = 0; i < sub_lim; ++i) { - const char **names = sub_names[i]; - for (j = 0; j < lim; ++j) { - if (pcap_strcasecmp($1, names[j]) == 0) - break; +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; } - if (j != lim) { - $$ = (i << IEEE80211_FC0_TYPE_SHIFT) | - (j << IEEE80211_FC0_SUBTYPE_SHIFT); + $$ = str2tok($1, ieee80211_type_subtypes[i].tok); + if ($$ != -1) { + $$ |= ieee80211_type_subtypes[i].type; break; } } - if (i == sub_lim) - bpf_error("unknown 802.11 subtype name"); } ; +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); } ; diff --git a/ieee80211.h b/ieee80211.h new file mode 100644 index 00000000..473803d8 --- /dev/null +++ b/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: src/sys/net80211/ieee80211.h,v 1.10 2005/07/22 16:55:27 sam Exp $ + */ +#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/scanner.l b/scanner.l index 89403455..1231eaa1 100644 --- a/scanner.l +++ b/scanner.l @@ -21,23 +21,40 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.56.1.1 1999-10-07 23:46:40 mcr Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.110.2.1 2007-11-18 02:04:55 guy Exp $ (LBL)"; #endif -#include -#include +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include -#include +#include #include "pcap-int.h" #include "gencode.h" -#include +#ifdef INET6 +#ifdef WIN32 +#include + +#ifdef __MINGW32__ +#include "IP6_misc.h" +#endif +#else /* WIN32 */ +#include /* for "struct sockaddr" in "struct addrinfo" */ +#include /* for "struct addrinfo" */ +#endif /* WIN32 */ + +/* Workaround for AIX 4.3 */ +#if !defined(AI_NUMERICHOST) +#define AI_NUMERICHOST 0x04 +#endif +#endif /*INET6*/ +#include #include "tokdefs.h" -#include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -47,22 +64,10 @@ static inline int xdtoi(int); #ifdef FLEX_SCANNER #define YY_NO_UNPUT -#undef YY_INPUT -#define YY_INPUT(buf, result, max)\ - {\ - char *src = in_buffer;\ - int i;\ -\ - if (*src == 0)\ - result = YY_NULL;\ - else {\ - for (i = 0; *src && i < max; ++i)\ - buf[i] = *src++;\ - in_buffer += i;\ - result = i;\ - }\ - } +static YY_BUFFER_STATE in_buffer; #else +static char *in_buffer; + #undef getc #define getc(fp) (*in_buffer == 0 ? EOF : *in_buffer++) #endif @@ -70,48 +75,189 @@ static inline int xdtoi(int); #define yylval pcap_lval extern YYSTYPE yylval; -static char *in_buffer; - %} N ([0-9]+|(0X|0x)[0-9A-Fa-f]+) B ([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}:: -%a 3000 +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}) %% dst return DST; src return SRC; link|ether|ppp|slip return LINK; -fddi 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; +radio return RADIO; + +ip6 { +#ifdef INET6 + return IPV6; +#else + bpf_error("%s not supported", yytext); +#endif + } +icmp6 { +#ifdef INET6 + return ICMPV6; +#else + bpf_error("%s not supported", yytext); +#endif + } +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 MASK; +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; + less return LESS; greater return GREATER; -byte return BYTE; +byte return CBYTE; broadcast return TK_BROADCAST; multicast return TK_MULTICAST; @@ -123,7 +269,43 @@ len|length return LEN; inbound return INBOUND; outbound return OUTBOUND; -[ \n\t] ; +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; @@ -131,24 +313,82 @@ outbound return OUTBOUND; "==" return '='; "<<" return LSH; ">>" return RSH; +${B} { yylval.e = pcap_ether_aton(((char *)yytext)+1); + return AID; } {N} { yylval.i = stoi((char *)yytext); return NUM; } ({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) { yylval.s = sdup((char *)yytext); return HID; } {B}:{B}:{B}:{B}:{B}:{B} { yylval.e = pcap_ether_aton((char *)yytext); return EID; } +{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 { + 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); } -[A-Za-z0-9][-_.A-Za-z0-9]*[.A-Za-z0-9] { +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!<>()&|=]+i { - bpf_error("illegal token: %s\n", yytext); } +[^ \[\]\t\n\-_.A-Za-z0-9!<>()&|=]+ { + bpf_error("illegal token: %s", yytext); } . { bpf_error("illegal char '%c'", *yytext); } %% void lex_init(buf) - char *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 } /* @@ -200,4 +440,3 @@ stoi(s) return n; } - -- 2.39.5