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