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