1%top { 2/* Must come first for _LARGE_FILE_API on AIX. */ 3#ifdef HAVE_CONFIG_H 4#include <config.h> 5#endif 6 7/* 8 * Must come first to avoid warnings on Windows. 9 * 10 * Flex-generated scanners may only include <inttypes.h> if __STDC_VERSION__ 11 * is defined with a value >= 199901, meaning "full C99", and MSVC may not 12 * define it with that value, because it isn't 100% C99-compliant, even 13 * though it has an <inttypes.h> capable of defining everything the Flex 14 * scanner needs. 15 * 16 * We, however, will include it if we know we have an MSVC version that has 17 * it; this means that we may define the INTn_MAX and UINTn_MAX values in 18 * scanner.c, and then include <stdint.h>, which may define them differently 19 * (same value, but different string of characters), causing compiler warnings. 20 * 21 * If we include it here, and they're defined, that'll prevent scanner.c 22 * from defining them. So we include <pcap/pcap-inttypes.h>, to get 23 * <inttypes.h> if we have it. 24 */ 25#include <pcap/pcap-inttypes.h> 26 27#include "diag-control.h" 28} 29 30/* 31 * We want a reentrant scanner. 32 */ 33%option reentrant 34 35/* 36 * And we need to pass the compiler state to the scanner. 37 */ 38%option extra-type="compiler_state_t *" 39 40/* 41 * We don't use input, so don't generate code for it. 42 */ 43%option noinput 44 45/* 46 * We don't use unput, so don't generate code for it. 47 */ 48%option nounput 49 50/* 51 * We don't read from the terminal. 52 */ 53%option never-interactive 54 55/* 56 * We want to stop processing when we get to the end of the input. 57 */ 58%option noyywrap 59 60/* 61 * We want to generate code that can be used by a reentrant parser 62 * generated by Bison or Berkeley YACC. 63 */ 64%option bison-bridge 65 66%{ 67/* 68 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 69 * The Regents of the University of California. All rights reserved. 70 * 71 * Redistribution and use in source and binary forms, with or without 72 * modification, are permitted provided that: (1) source code distributions 73 * retain the above copyright notice and this paragraph in its entirety, (2) 74 * distributions including binary code include the above copyright notice and 75 * this paragraph in its entirety in the documentation or other materials 76 * provided with the distribution, and (3) all advertising materials mentioning 77 * features or use of this software display the following acknowledgement: 78 * ``This product includes software developed by the University of California, 79 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 80 * the University nor the names of its contributors may be used to endorse 81 * or promote products derived from this software without specific prior 82 * written permission. 83 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 84 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 85 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 86 */ 87 88#include <ctype.h> 89#include <string.h> 90 91#include "pcap-int.h" 92 93#include "gencode.h" 94 95#include "grammar.h" 96 97/* 98 * Earlier versions of Flex don't declare these, so we declare them 99 * ourselves to squelch warnings. 100 */ 101int pcap_get_column(yyscan_t); 102void pcap_set_column(int, yyscan_t); 103 104#ifdef INET6 105 106#ifdef _WIN32 107#include <winsock2.h> 108#include <ws2tcpip.h> 109/* 110 * To quote the MSDN page for getaddrinfo() at 111 * 112 * https://msdn.microsoft.com/en-us/library/windows/desktop/ms738520(v=vs.85).aspx 113 * 114 * "Support for getaddrinfo on Windows 2000 and older versions 115 * The getaddrinfo function was added to the Ws2_32.dll on Windows XP and 116 * later. To execute an application that uses this function on earlier 117 * versions of Windows, then you need to include the Ws2tcpip.h and 118 * Wspiapi.h files. When the Wspiapi.h include file is added, the 119 * getaddrinfo function is defined to the WspiapiGetAddrInfo inline 120 * function in the Wspiapi.h file. At runtime, the WspiapiGetAddrInfo 121 * function is implemented in such a way that if the Ws2_32.dll or the 122 * Wship6.dll (the file containing getaddrinfo in the IPv6 Technology 123 * Preview for Windows 2000) does not include getaddrinfo, then a 124 * version of getaddrinfo is implemented inline based on code in the 125 * Wspiapi.h header file. This inline code will be used on older Windows 126 * platforms that do not natively support the getaddrinfo function." 127 * 128 * We use getaddrinfo(), so we include Wspiapi.h here. 129 */ 130#include <wspiapi.h> 131#else /* _WIN32 */ 132#include <sys/socket.h> /* for "struct sockaddr" in "struct addrinfo" */ 133#include <netdb.h> /* for "struct addrinfo" */ 134#endif /* _WIN32 */ 135 136/* Workaround for AIX 4.3 */ 137#if !defined(AI_NUMERICHOST) 138#define AI_NUMERICHOST 0x04 139#endif 140 141#endif /*INET6*/ 142 143#include <pcap/namedb.h> 144#include "grammar.h" 145 146#ifdef HAVE_OS_PROTO_H 147#include "os-proto.h" 148#endif 149 150static int stoi(char *); 151static inline int xdtoi(int); 152 153/* 154 * Disable diagnostics in the code generated by Flex. 155 */ 156DIAG_OFF_FLEX 157 158%} 159 160N ([0-9]+|(0X|0x)[0-9A-Fa-f]+) 161B ([0-9A-Fa-f][0-9A-Fa-f]?) 162B2 ([0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]) 163W ([0-9A-Fa-f][0-9A-Fa-f]?[0-9A-Fa-f]?[0-9A-Fa-f]?) 164 165%a 18400 166%o 21500 167%e 7600 168%k 4550 169%p 27600 170%n 2000 171 172V680 {W}:{W}:{W}:{W}:{W}:{W}:{W}:{W} 173 174V670 ::{W}:{W}:{W}:{W}:{W}:{W}:{W} 175V671 {W}::{W}:{W}:{W}:{W}:{W}:{W} 176V672 {W}:{W}::{W}:{W}:{W}:{W}:{W} 177V673 {W}:{W}:{W}::{W}:{W}:{W}:{W} 178V674 {W}:{W}:{W}:{W}::{W}:{W}:{W} 179V675 {W}:{W}:{W}:{W}:{W}::{W}:{W} 180V676 {W}:{W}:{W}:{W}:{W}:{W}::{W} 181V677 {W}:{W}:{W}:{W}:{W}:{W}:{W}:: 182 183V660 ::{W}:{W}:{W}:{W}:{W}:{W} 184V661 {W}::{W}:{W}:{W}:{W}:{W} 185V662 {W}:{W}::{W}:{W}:{W}:{W} 186V663 {W}:{W}:{W}::{W}:{W}:{W} 187V664 {W}:{W}:{W}:{W}::{W}:{W} 188V665 {W}:{W}:{W}:{W}:{W}::{W} 189V666 {W}:{W}:{W}:{W}:{W}:{W}:: 190 191V650 ::{W}:{W}:{W}:{W}:{W} 192V651 {W}::{W}:{W}:{W}:{W} 193V652 {W}:{W}::{W}:{W}:{W} 194V653 {W}:{W}:{W}::{W}:{W} 195V654 {W}:{W}:{W}:{W}::{W} 196V655 {W}:{W}:{W}:{W}:{W}:: 197 198V640 ::{W}:{W}:{W}:{W} 199V641 {W}::{W}:{W}:{W} 200V642 {W}:{W}::{W}:{W} 201V643 {W}:{W}:{W}::{W} 202V644 {W}:{W}:{W}:{W}:: 203 204V630 ::{W}:{W}:{W} 205V631 {W}::{W}:{W} 206V632 {W}:{W}::{W} 207V633 {W}:{W}:{W}:: 208 209V620 ::{W}:{W} 210V621 {W}::{W} 211V622 {W}:{W}:: 212 213V610 ::{W} 214V611 {W}:: 215 216V600 :: 217 218V6604 {W}:{W}:{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} 219 220V6504 ::{W}:{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} 221V6514 {W}::{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} 222V6524 {W}:{W}::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} 223V6534 {W}:{W}:{W}::{W}:{W}:{N}\.{N}\.{N}\.{N} 224V6544 {W}:{W}:{W}:{W}::{W}:{N}\.{N}\.{N}\.{N} 225V6554 {W}:{W}:{W}:{W}:{W}::{N}\.{N}\.{N}\.{N} 226 227V6404 ::{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} 228V6414 {W}::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} 229V6424 {W}:{W}::{W}:{W}:{N}\.{N}\.{N}\.{N} 230V6434 {W}:{W}:{W}::{W}:{N}\.{N}\.{N}\.{N} 231V6444 {W}:{W}:{W}:{W}::{N}\.{N}\.{N}\.{N} 232 233V6304 ::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} 234V6314 {W}::{W}:{W}:{N}\.{N}\.{N}\.{N} 235V6324 {W}:{W}::{W}:{N}\.{N}\.{N}\.{N} 236V6334 {W}:{W}:{W}::{N}\.{N}\.{N}\.{N} 237 238V6204 ::{W}:{W}:{N}\.{N}\.{N}\.{N} 239V6214 {W}::{W}:{N}\.{N}\.{N}\.{N} 240V6224 {W}:{W}::{N}\.{N}\.{N}\.{N} 241 242V6104 ::{W}:{N}\.{N}\.{N}\.{N} 243V6114 {W}::{N}\.{N}\.{N}\.{N} 244 245V6004 ::{N}\.{N}\.{N}\.{N} 246 247 248V6 ({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}) 249 250MAC ({B}:{B}:{B}:{B}:{B}:{B}|{B}\-{B}\-{B}\-{B}\-{B}\-{B}|{B}\.{B}\.{B}\.{B}\.{B}\.{B}|{B2}\.{B2}\.{B2}|{B2}{3}) 251 252 253 254%% 255dst return DST; 256src return SRC; 257 258link|ether|ppp|slip return LINK; 259fddi|tr|wlan return LINK; 260arp return ARP; 261rarp return RARP; 262ip return IP; 263sctp return SCTP; 264tcp return TCP; 265udp return UDP; 266icmp return ICMP; 267igmp return IGMP; 268igrp return IGRP; 269pim return PIM; 270vrrp return VRRP; 271carp return CARP; 272radio return RADIO; 273 274ip6 return IPV6; 275icmp6 return ICMPV6; 276ah return AH; 277esp return ESP; 278 279atalk return ATALK; 280aarp return AARP; 281decnet return DECNET; 282lat return LAT; 283sca return SCA; 284moprc return MOPRC; 285mopdl return MOPDL; 286 287iso return ISO; 288esis return ESIS; 289es-is return ESIS; 290isis return ISIS; 291is-is return ISIS; 292l1 return L1; 293l2 return L2; 294iih return IIH; 295lsp return LSP; 296snp return SNP; 297csnp return CSNP; 298psnp return PSNP; 299 300clnp return CLNP; 301 302stp return STP; 303 304ipx return IPX; 305 306netbeui return NETBEUI; 307 308host return HOST; 309net return NET; 310mask return NETMASK; 311port return PORT; 312portrange return PORTRANGE; 313proto return PROTO; 314protochain return PROTOCHAIN; 315 316gateway return GATEWAY; 317 318type return TYPE; 319subtype return SUBTYPE; 320direction|dir return DIR; 321address1|addr1 return ADDR1; 322address2|addr2 return ADDR2; 323address3|addr3 return ADDR3; 324address4|addr4 return ADDR4; 325ra return RA; 326ta return TA; 327 328less return LESS; 329greater return GREATER; 330byte return CBYTE; 331broadcast return TK_BROADCAST; 332multicast return TK_MULTICAST; 333 334and|"&&" return AND; 335or|"||" return OR; 336not return '!'; 337 338len|length return LEN; 339inbound return INBOUND; 340outbound return OUTBOUND; 341 342vlan return VLAN; 343mpls return MPLS; 344pppoed return PPPOED; 345pppoes return PPPOES; 346geneve return GENEVE; 347 348lane return LANE; 349llc return LLC; 350metac return METAC; 351bcc return BCC; 352oam return OAM; 353oamf4 return OAMF4; 354oamf4ec return OAMF4EC; 355oamf4sc return OAMF4SC; 356sc return SC; 357ilmic return ILMIC; 358vpi return VPI; 359vci return VCI; 360connectmsg return CONNECTMSG; 361metaconnect return METACONNECT; 362 363on|ifname return PF_IFNAME; 364rset|ruleset return PF_RSET; 365rnr|rulenum return PF_RNR; 366srnr|subrulenum return PF_SRNR; 367reason return PF_REASON; 368action return PF_ACTION; 369 370fisu return FISU; 371lssu return LSSU; 372lsu return LSSU; 373msu return MSU; 374hfisu return HFISU; 375hlssu return HLSSU; 376hmsu return HMSU; 377sio return SIO; 378opc return OPC; 379dpc return DPC; 380sls return SLS; 381hsio return HSIO; 382hopc return HOPC; 383hdpc return HDPC; 384hsls return HSLS; 385 386[ \r\n\t] ; 387[+\-*/%:\[\]!<>()&|\^=] return yytext[0]; 388">=" return GEQ; 389"<=" return LEQ; 390"!=" return NEQ; 391"==" return '='; 392"<<" return LSH; 393">>" return RSH; 394${B} { yylval->s = sdup(yyextra, yytext); return AID; } 395{MAC} { yylval->s = sdup(yyextra, yytext); return EID; } 396{N} { yylval->i = stoi((char *)yytext); return NUM; } 397({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) { 398 yylval->s = sdup(yyextra, (char *)yytext); return HID; } 399{V6} { 400#ifdef INET6 401 struct addrinfo hints, *res; 402 memset(&hints, 0, sizeof(hints)); 403 hints.ai_family = AF_INET6; 404 hints.ai_flags = AI_NUMERICHOST; 405 if (getaddrinfo(yytext, NULL, &hints, &res)) { 406 bpf_set_error(yyextra, "bogus IPv6 address %s", yytext); 407 yylval->s = NULL; 408 } else { 409 freeaddrinfo(res); 410 yylval->s = sdup(yyextra, (char *)yytext); 411 } 412#else 413 bpf_set_error(yyextra, "IPv6 address %s not supported", yytext); 414 yylval->s = NULL; 415#endif /*INET6*/ 416 return HID6; 417 } 418{B}:+({B}:+)+ { bpf_set_error(yyextra, "bogus ethernet address %s", yytext); yylval->s = NULL; return EID; } 419icmptype { yylval->i = 0; return NUM; } 420icmpcode { yylval->i = 1; return NUM; } 421icmp-echoreply { yylval->i = 0; return NUM; } 422icmp-unreach { yylval->i = 3; return NUM; } 423icmp-sourcequench { yylval->i = 4; return NUM; } 424icmp-redirect { yylval->i = 5; return NUM; } 425icmp-echo { yylval->i = 8; return NUM; } 426icmp-routeradvert { yylval->i = 9; return NUM; } 427icmp-routersolicit { yylval->i = 10; return NUM; } 428icmp-timxceed { yylval->i = 11; return NUM; } 429icmp-paramprob { yylval->i = 12; return NUM; } 430icmp-tstamp { yylval->i = 13; return NUM; } 431icmp-tstampreply { yylval->i = 14; return NUM; } 432icmp-ireq { yylval->i = 15; return NUM; } 433icmp-ireqreply { yylval->i = 16; return NUM; } 434icmp-maskreq { yylval->i = 17; return NUM; } 435icmp-maskreply { yylval->i = 18; return NUM; } 436 437icmp6type { yylval->i = 0; return NUM; } 438icmp6code { yylval->i = 1; return NUM; } 439 440icmp6-echo { yylval->i = 128; return NUM; } 441icmp6-echoreply { yylval->i = 129; return NUM; } 442icmp6-multicastlistenerquery { yylval->i = 130; return NUM; } 443icmp6-multicastlistenerreportv1 { yylval->i = 131; return NUM; } 444icmp6-multicastlistenerdone { yylval->i = 132; return NUM; } 445icmp6-routersolicit { yylval->i = 133; return NUM; } 446icmp6-routeradvert { yylval->i = 134; return NUM; } 447icmp6-neighborsolicit { yylval->i = 135; return NUM; } 448icmp6-neighboradvert { yylval->i = 136; return NUM; } 449icmp6-redirect { yylval->i = 137; return NUM; } 450icmp6-routerrenum { yylval->i = 138; return NUM; } 451icmp6-nodeinformationquery { yylval->i = 139; return NUM; } 452icmp6-nodeinformationresponse { yylval->i = 140; return NUM; } 453icmp6-ineighbordiscoverysolicit { yylval->i = 141; return NUM; } 454icmp6-ineighbordiscoveryadvert { yylval->i = 142; return NUM; } 455icmp6-multicastlistenerreportv2 { yylval->i = 143; return NUM; } 456icmp6-homeagentdiscoveryrequest { yylval->i = 144; return NUM; } 457icmp6-homeagentdiscoveryreply { yylval->i = 145; return NUM; } 458icmp6-mobileprefixsolicit { yylval->i = 146; return NUM; } 459icmp6-mobileprefixadvert { yylval->i = 147; return NUM; } 460icmp6-certpathsolicit { yylval->i = 148; return NUM; } 461icmp6-certpathadvert { yylval->i = 149; return NUM; } 462icmp6-multicastrouteradvert { yylval->i = 151; return NUM; } 463icmp6-multicastroutersolicit { yylval->i = 152; return NUM; } 464icmp6-multicastrouterterm { yylval->i = 153; return NUM; } 465 466tcpflags { yylval->i = 13; return NUM; } 467tcp-fin { yylval->i = 0x01; return NUM; } 468tcp-syn { yylval->i = 0x02; return NUM; } 469tcp-rst { yylval->i = 0x04; return NUM; } 470tcp-push { yylval->i = 0x08; return NUM; } 471tcp-ack { yylval->i = 0x10; return NUM; } 472tcp-urg { yylval->i = 0x20; return NUM; } 473tcp-ece { yylval->i = 0x40; return NUM; } 474tcp-cwr { yylval->i = 0x80; return NUM; } 475[A-Za-z0-9]([-_.A-Za-z0-9]*[.A-Za-z0-9])? { 476 yylval->s = sdup(yyextra, (char *)yytext); return ID; } 477"\\"[^ !()\n\t]+ { yylval->s = sdup(yyextra, (char *)yytext + 1); return ID; } 478. { return LEX_ERROR; } 479%% 480 481/* 482 * Turn diagnostics back on, so we check the code that we've written. 483 */ 484DIAG_ON_FLEX 485 486/* Hex digit to integer. */ 487static inline int 488xdtoi(int c) 489{ 490 if (isdigit(c)) 491 return c - '0'; 492 else if (islower(c)) 493 return c - 'a' + 10; 494 else 495 return c - 'A' + 10; 496} 497 498/* 499 * Convert string to integer. Just like atoi(), but checks for 500 * preceding 0x or 0 and uses hex or octal instead of decimal. 501 */ 502static int 503stoi(char *s) 504{ 505 int base = 10; 506 int n = 0; 507 508 if (*s == '0') { 509 if (s[1] == 'x' || s[1] == 'X') { 510 s += 2; 511 base = 16; 512 } 513 else { 514 base = 8; 515 s += 1; 516 } 517 } 518 while (*s) 519 n = n * base + xdtoi(*s++); 520 521 return n; 522} 523