grammar.y revision 21344
1%{ 2/* 3 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 4 * The Regents of the University of California. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that: (1) source code distributions 8 * retain the above copyright notice and this paragraph in its entirety, (2) 9 * distributions including binary code include the above copyright notice and 10 * this paragraph in its entirety in the documentation or other materials 11 * provided with the distribution, and (3) all advertising materials mentioning 12 * features or use of this software display the following acknowledgement: 13 * ``This product includes software developed by the University of California, 14 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 15 * the University nor the names of its contributors may be used to endorse 16 * or promote products derived from this software without specific prior 17 * written permission. 18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 21 * 22 */ 23#ifndef lint 24static char rcsid[] = 25 "@(#) $Header: grammar.y,v 1.54 96/07/17 00:11:34 leres Exp $ (LBL)"; 26#endif 27 28#include <sys/types.h> 29#include <sys/time.h> 30#include <sys/socket.h> 31 32#if __STDC__ 33struct mbuf; 34struct rtentry; 35#endif 36 37#include <net/if.h> 38 39#include <netinet/in.h> 40#include <net/ethernet.h> 41 42#include <stdio.h> 43 44#include "pcap-int.h" 45 46#include "gencode.h" 47#include <pcap-namedb.h> 48 49#include "gnuc.h" 50#ifdef HAVE_OS_PROTO_H 51#include "os-proto.h" 52#endif 53 54#define QSET(q, p, d, a) (q).proto = (p),\ 55 (q).dir = (d),\ 56 (q).addr = (a) 57 58int n_errors = 0; 59 60static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF }; 61 62static void 63yyerror(char *msg) 64{ 65 ++n_errors; 66 bpf_error(msg); 67 /* NOTREACHED */ 68} 69 70#ifndef YYBISON 71int yyparse(void); 72 73int 74pcap_parse() 75{ 76 return (yyparse()); 77} 78#endif 79 80%} 81 82%union { 83 int i; 84 bpf_u_int32 h; 85 u_char *e; 86 char *s; 87 struct stmt *stmt; 88 struct arth *a; 89 struct { 90 struct qual q; 91 struct block *b; 92 } blk; 93 struct block *rblk; 94} 95 96%type <blk> expr id nid pid term rterm qid 97%type <blk> head 98%type <i> pqual dqual aqual ndaqual 99%type <a> arth narth 100%type <i> byteop pname pnum relop irelop 101%type <blk> and or paren not null prog 102%type <rblk> other 103 104%token DST SRC HOST GATEWAY 105%token NET MASK PORT LESS GREATER PROTO BYTE 106%token ARP RARP IP TCP UDP ICMP IGMP IGRP 107%token ATALK DECNET LAT SCA MOPRC MOPDL 108%token TK_BROADCAST TK_MULTICAST 109%token NUM INBOUND OUTBOUND 110%token LINK 111%token GEQ LEQ NEQ 112%token ID EID HID 113%token LSH RSH 114%token LEN 115%token ISO ESIS ISIS 116 117%type <s> ID 118%type <e> EID 119%type <s> HID 120%type <i> NUM 121 122%left OR AND 123%nonassoc '!' 124%left '|' 125%left '&' 126%left LSH RSH 127%left '+' '-' 128%left '*' '/' 129%nonassoc UMINUS 130%% 131prog: null expr 132{ 133 finish_parse($2.b); 134} 135 | null 136 ; 137null: /* null */ { $$.q = qerr; } 138 ; 139expr: term 140 | expr and term { gen_and($1.b, $3.b); $$ = $3; } 141 | expr and id { gen_and($1.b, $3.b); $$ = $3; } 142 | expr or term { gen_or($1.b, $3.b); $$ = $3; } 143 | expr or id { gen_or($1.b, $3.b); $$ = $3; } 144 ; 145and: AND { $$ = $<blk>0; } 146 ; 147or: OR { $$ = $<blk>0; } 148 ; 149id: nid 150 | pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1, 151 $$.q = $<blk>0.q); } 152 | paren pid ')' { $$ = $2; } 153 ; 154nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); } 155 | HID '/' NUM { $$.b = gen_mcode($1, NULL, $3, 156 $$.q = $<blk>0.q); } 157 | HID MASK HID { $$.b = gen_mcode($1, $3, 0, 158 $$.q = $<blk>0.q); } 159 | HID { 160 /* Decide how to parse HID based on proto */ 161 $$.q = $<blk>0.q; 162 switch ($$.q.proto) { 163 case Q_DECNET: 164 $$.b = gen_ncode($1, 0, $$.q); 165 break; 166 default: 167 $$.b = gen_ncode($1, 0, $$.q); 168 break; 169 } 170 } 171 | EID { $$.b = gen_ecode($1, $$.q = $<blk>0.q); } 172 | not id { gen_not($2.b); $$ = $2; } 173 ; 174not: '!' { $$ = $<blk>0; } 175 ; 176paren: '(' { $$ = $<blk>0; } 177 ; 178pid: nid 179 | qid and id { gen_and($1.b, $3.b); $$ = $3; } 180 | qid or id { gen_or($1.b, $3.b); $$ = $3; } 181 ; 182qid: pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1, 183 $$.q = $<blk>0.q); } 184 | pid 185 ; 186term: rterm 187 | not term { gen_not($2.b); $$ = $2; } 188 ; 189head: pqual dqual aqual { QSET($$.q, $1, $2, $3); } 190 | pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); } 191 | pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); } 192 | pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); } 193 | pqual ndaqual { QSET($$.q, $1, Q_DEFAULT, $2); } 194 ; 195rterm: head id { $$ = $2; } 196 | paren expr ')' { $$.b = $2.b; $$.q = $1.q; } 197 | pname { $$.b = gen_proto_abbrev($1); $$.q = qerr; } 198 | arth relop arth { $$.b = gen_relation($2, $1, $3, 0); 199 $$.q = qerr; } 200 | arth irelop arth { $$.b = gen_relation($2, $1, $3, 1); 201 $$.q = qerr; } 202 | other { $$.b = $1; $$.q = qerr; } 203 ; 204/* protocol level qualifiers */ 205pqual: pname 206 | { $$ = Q_DEFAULT; } 207 ; 208/* 'direction' qualifiers */ 209dqual: SRC { $$ = Q_SRC; } 210 | DST { $$ = Q_DST; } 211 | SRC OR DST { $$ = Q_OR; } 212 | DST OR SRC { $$ = Q_OR; } 213 | SRC AND DST { $$ = Q_AND; } 214 | DST AND SRC { $$ = Q_AND; } 215 ; 216/* address type qualifiers */ 217aqual: HOST { $$ = Q_HOST; } 218 | NET { $$ = Q_NET; } 219 | PORT { $$ = Q_PORT; } 220 ; 221/* non-directional address type qualifiers */ 222ndaqual: GATEWAY { $$ = Q_GATEWAY; } 223 ; 224pname: LINK { $$ = Q_LINK; } 225 | IP { $$ = Q_IP; } 226 | ARP { $$ = Q_ARP; } 227 | RARP { $$ = Q_RARP; } 228 | TCP { $$ = Q_TCP; } 229 | UDP { $$ = Q_UDP; } 230 | ICMP { $$ = Q_ICMP; } 231 | IGMP { $$ = Q_IGMP; } 232 | IGRP { $$ = Q_IGRP; } 233 | ATALK { $$ = Q_ATALK; } 234 | DECNET { $$ = Q_DECNET; } 235 | LAT { $$ = Q_LAT; } 236 | SCA { $$ = Q_SCA; } 237 | MOPDL { $$ = Q_MOPDL; } 238 | MOPRC { $$ = Q_MOPRC; } 239 | ISO { $$ = Q_ISO; } 240 | ESIS { $$ = Q_ESIS; } 241 | ISIS { $$ = Q_ISIS; } 242 ; 243other: pqual TK_BROADCAST { $$ = gen_broadcast($1); } 244 | pqual TK_MULTICAST { $$ = gen_multicast($1); } 245 | LESS NUM { $$ = gen_less($2); } 246 | GREATER NUM { $$ = gen_greater($2); } 247 | BYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); } 248 | INBOUND { $$ = gen_inbound(0); } 249 | OUTBOUND { $$ = gen_inbound(1); } 250 ; 251relop: '>' { $$ = BPF_JGT; } 252 | GEQ { $$ = BPF_JGE; } 253 | '=' { $$ = BPF_JEQ; } 254 ; 255irelop: LEQ { $$ = BPF_JGT; } 256 | '<' { $$ = BPF_JGE; } 257 | NEQ { $$ = BPF_JEQ; } 258 ; 259arth: pnum { $$ = gen_loadi($1); } 260 | narth 261 ; 262narth: pname '[' arth ']' { $$ = gen_load($1, $3, 1); } 263 | pname '[' arth ':' NUM ']' { $$ = gen_load($1, $3, $5); } 264 | arth '+' arth { $$ = gen_arth(BPF_ADD, $1, $3); } 265 | arth '-' arth { $$ = gen_arth(BPF_SUB, $1, $3); } 266 | arth '*' arth { $$ = gen_arth(BPF_MUL, $1, $3); } 267 | arth '/' arth { $$ = gen_arth(BPF_DIV, $1, $3); } 268 | arth '&' arth { $$ = gen_arth(BPF_AND, $1, $3); } 269 | arth '|' arth { $$ = gen_arth(BPF_OR, $1, $3); } 270 | arth LSH arth { $$ = gen_arth(BPF_LSH, $1, $3); } 271 | arth RSH arth { $$ = gen_arth(BPF_RSH, $1, $3); } 272 | '-' arth %prec UMINUS { $$ = gen_neg($2); } 273 | paren narth ')' { $$ = $2; } 274 | LEN { $$ = gen_loadlen(); } 275 ; 276byteop: '&' { $$ = '&'; } 277 | '|' { $$ = '|'; } 278 | '<' { $$ = '<'; } 279 | '>' { $$ = '>'; } 280 | '=' { $$ = '='; } 281 ; 282pnum: NUM 283 | paren pnum ')' { $$ = $2; } 284 ; 285%% 286