summaryrefslogtreecommitdiff
path: root/scanner.l
diff options
context:
space:
mode:
Diffstat (limited to 'scanner.l')
-rw-r--r--scanner.l312
1 files changed, 187 insertions, 125 deletions
diff --git a/scanner.l b/scanner.l
index a247c99..effcf81 100644
--- a/scanner.l
+++ b/scanner.l
@@ -1,3 +1,68 @@
+%top {
+/* Must come first for _LARGE_FILE_API on AIX. */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/*
+ * Must come first to avoid warnings on Windows.
+ *
+ * Flex-generated scanners may only include <inttypes.h> if __STDC_VERSION__
+ * is defined with a value >= 199901, meaning "full C99", and MSVC may not
+ * define it with that value, because it isn't 100% C99-compliant, even
+ * though it has an <inttypes.h> capable of defining everything the Flex
+ * scanner needs.
+ *
+ * We, however, will include it if we know we have an MSVC version that has
+ * it; this means that we may define the INTn_MAX and UINTn_MAX values in
+ * scanner.c, and then include <stdint.h>, which may define them differently
+ * (same value, but different string of characters), causing compiler warnings.
+ *
+ * If we include it here, and they're defined, that'll prevent scanner.c
+ * from defining them. So we include <pcap/pcap-inttypes.h>, to get
+ * <inttypes.h> if we have it.
+ */
+#include <pcap/pcap-inttypes.h>
+
+#include "diag-control.h"
+}
+
+/*
+ * We want a reentrant scanner.
+ */
+%option reentrant
+
+/*
+ * And we need to pass the compiler state to the scanner.
+ */
+%option extra-type="compiler_state_t *"
+
+/*
+ * We don't use input, so don't generate code for it.
+ */
+%option noinput
+
+/*
+ * We don't use unput, so don't generate code for it.
+ */
+%option nounput
+
+/*
+ * We don't read from the terminal.
+ */
+%option never-interactive
+
+/*
+ * We want to stop processing when we get to the end of the input.
+ */
+%option noyywrap
+
+/*
+ * We want to generate code that can be used by a reentrant parser
+ * generated by Bison or Berkeley YACC.
+ */
+%option bison-bridge
+
%{
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
@@ -20,49 +85,63 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#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"
+
+#include "grammar.h"
+
+/*
+ * Earlier versions of Flex don't declare these, so we declare them
+ * ourselves to squelch warnings.
+ */
+int pcap_get_column(yyscan_t);
+void pcap_set_column(int, yyscan_t);
+
#ifdef INET6
-#ifdef WIN32
-#include <pcap-stdinc.h>
-#ifdef __MINGW32__
-#include "ip6_misc.h"
-#endif
-#else /* WIN32 */
+#ifdef _WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+/*
+ * To quote the MSDN page for getaddrinfo() at
+ *
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/ms738520(v=vs.85).aspx
+ *
+ * "Support for getaddrinfo on Windows 2000 and older versions
+ * The getaddrinfo function was added to the Ws2_32.dll on Windows XP and
+ * later. To execute an application that uses this function on earlier
+ * versions of Windows, then you need to include the Ws2tcpip.h and
+ * Wspiapi.h files. When the Wspiapi.h include file is added, the
+ * getaddrinfo function is defined to the WspiapiGetAddrInfo inline
+ * function in the Wspiapi.h file. At runtime, the WspiapiGetAddrInfo
+ * function is implemented in such a way that if the Ws2_32.dll or the
+ * Wship6.dll (the file containing getaddrinfo in the IPv6 Technology
+ * Preview for Windows 2000) does not include getaddrinfo, then a
+ * version of getaddrinfo is implemented inline based on code in the
+ * Wspiapi.h header file. This inline code will be used on older Windows
+ * platforms that do not natively support the getaddrinfo function."
+ *
+ * We use getaddrinfo(), so we include Wspiapi.h here.
+ */
+#include <wspiapi.h>
+#else /* _WIN32 */
#include <sys/socket.h> /* for "struct sockaddr" in "struct addrinfo" */
#include <netdb.h> /* for "struct addrinfo" */
-#endif /* WIN32 */
+#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"
+#include "grammar.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
@@ -71,19 +150,10 @@
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
-
-#define yylval pcap_lval
-extern YYSTYPE yylval;
+/*
+ * Disable diagnostics in the code generated by Flex.
+ */
+DIAG_OFF_FLEX
%}
@@ -241,13 +311,7 @@ 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
- }
+protochain return PROTOCHAIN;
gateway return GATEWAY;
@@ -279,6 +343,7 @@ vlan return VLAN;
mpls return MPLS;
pppoed return PPPOED;
pppoes return PPPOES;
+geneve return GENEVE;
lane return LANE;
llc return LLC;
@@ -326,103 +391,101 @@ hsls return HSLS;
"==" return '=';
"<<" return LSH;
">>" return RSH;
-${B} { yylval.e = pcap_ether_aton(((char *)yytext)+1);
- if (yylval.e == NULL)
- bpf_error("malloc");
- return AID; }
-{MAC} { yylval.e = pcap_ether_aton((char *)yytext);
- if (yylval.e == NULL)
- bpf_error("malloc");
- return EID; }
-{N} { yylval.i = stoi((char *)yytext); return NUM; }
+${B} { yylval->s = sdup(yyextra, yytext); return AID; }
+{MAC} { yylval->s = sdup(yyextra, 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; }
+ yylval->s = sdup(yyextra, (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 {
+ if (getaddrinfo(yytext, NULL, &hints, &res)) {
+ bpf_set_error(yyextra, "bogus IPv6 address %s", yytext);
+ yylval->s = NULL;
+ } else {
freeaddrinfo(res);
- yylval.s = sdup((char *)yytext); return HID6;
+ yylval->s = sdup(yyextra, (char *)yytext);
}
#else
- bpf_error("IPv6 address %s not supported", yytext);
+ bpf_set_error(yyextra, "IPv6 address %s not supported", yytext);
+ yylval->s = NULL;
#endif /*INET6*/
+ return HID6;
}
-{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; }
+{B}:+({B}:+)+ { bpf_set_error(yyextra, "bogus ethernet address %s", yytext); yylval->s = NULL; return EID; }
+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; }
+
+icmp6type { yylval->i = 0; return NUM; }
+icmp6code { yylval->i = 1; return NUM; }
+
+icmp6-echo { yylval->i = 128; return NUM; }
+icmp6-echoreply { yylval->i = 129; return NUM; }
+icmp6-multicastlistenerquery { yylval->i = 130; return NUM; }
+icmp6-multicastlistenerreportv1 { yylval->i = 131; return NUM; }
+icmp6-multicastlistenerdone { yylval->i = 132; return NUM; }
+icmp6-routersolicit { yylval->i = 133; return NUM; }
+icmp6-routeradvert { yylval->i = 134; return NUM; }
+icmp6-neighborsolicit { yylval->i = 135; return NUM; }
+icmp6-neighboradvert { yylval->i = 136; return NUM; }
+icmp6-redirect { yylval->i = 137; return NUM; }
+icmp6-routerrenum { yylval->i = 138; return NUM; }
+icmp6-nodeinformationquery { yylval->i = 139; return NUM; }
+icmp6-nodeinformationresponse { yylval->i = 140; return NUM; }
+icmp6-ineighbordiscoverysolicit { yylval->i = 141; return NUM; }
+icmp6-ineighbordiscoveryadvert { yylval->i = 142; return NUM; }
+icmp6-multicastlistenerreportv2 { yylval->i = 143; return NUM; }
+icmp6-homeagentdiscoveryrequest { yylval->i = 144; return NUM; }
+icmp6-homeagentdiscoveryreply { yylval->i = 145; return NUM; }
+icmp6-mobileprefixsolicit { yylval->i = 146; return NUM; }
+icmp6-mobileprefixadvert { yylval->i = 147; return NUM; }
+icmp6-certpathsolicit { yylval->i = 148; return NUM; }
+icmp6-certpathadvert { yylval->i = 149; return NUM; }
+icmp6-multicastrouteradvert { yylval->i = 151; return NUM; }
+icmp6-multicastroutersolicit { yylval->i = 152; return NUM; }
+icmp6-multicastrouterterm { yylval->i = 153; 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; }
+tcp-ece { yylval->i = 0x40; return NUM; }
+tcp-cwr { yylval->i = 0x80; 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); }
+ yylval->s = sdup(yyextra, (char *)yytext); return ID; }
+"\\"[^ !()\n\t]+ { yylval->s = sdup(yyextra, (char *)yytext + 1); return ID; }
+. { return LEX_ERROR; }
%%
-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.
+ * Turn diagnostics back on, so we check the code that we've written.
*/
-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;
-}
+DIAG_ON_FLEX
/* Hex digit to integer. */
static inline int
-xdtoi(c)
- register int c;
+xdtoi(int c)
{
if (isdigit(c))
return c - '0';
@@ -437,8 +500,7 @@ xdtoi(c)
* preceding 0x or 0 and uses hex or octal instead of decimal.
*/
static int
-stoi(s)
- char *s;
+stoi(char *s)
{
int base = 10;
int n = 0;