1 %{ 2 /* $OpenBSD: grammar.y,v 1.4 1996/07/12 13:19:09 mickey Exp $ */ 3 4 /* 5 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 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 */ 25 #ifndef lint 26 static char rcsid[] = 27 "@(#) $Header: /home/cvs/src/lib/libpcap/grammar.y,v 1.4 1996/07/12 13:19:09 mickey Exp $ (LBL)"; 28 #endif 29 30 #include <sys/types.h> 31 #include <sys/time.h> 32 #include <sys/socket.h> 33 34 #if __STDC__ 35 struct mbuf; 36 struct rtentry; 37 #endif 38 39 #include <net/if.h> 40 #include <net/bpf.h> 41 42 #include <netinet/in.h> 43 #include <netinet/if_ether.h> 44 45 #include <stdio.h> 46 #include <pcap.h> 47 #include <pcap-namedb.h> 48 49 #ifdef HAVE_OS_PROTO_H 50 #include "os-proto.h" 51 #endif 52 53 #include "pcap-int.h" 54 #include "gencode.h" 55 56 #define QSET(q, p, d, a) (q).proto = (p),\ 57 (q).dir = (d),\ 58 (q).addr = (a) 59 60 int n_errors = 0; 61 62 static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF }; 63 64 static void 65 yyerror(char *msg) 66 { 67 ++n_errors; 68 bpf_error(msg); 69 /* NOTREACHED */ 70 } 71 72 #ifndef YYBISON 73 int yyparse(void); 74 75 int 76 pcap_parse() 77 { 78 return (yyparse()); 79 } 80 #endif 81 82 %} 83 84 %union { 85 int i; 86 u_long h; 87 u_char *e; 88 char *s; 89 struct stmt *stmt; 90 struct arth *a; 91 struct { 92 struct qual q; 93 struct block *b; 94 } blk; 95 struct block *rblk; 96 } 97 98 %type <blk> expr id nid pid term rterm qid 99 %type <blk> head 100 %type <i> pqual dqual aqual ndaqual 101 %type <a> arth narth 102 %type <i> byteop pname pnum relop irelop 103 %type <blk> and or paren not null prog 104 %type <rblk> other 105 106 %token DST SRC HOST GATEWAY 107 %token NET PORT LESS GREATER PROTO BYTE 108 %token ARP RARP IP TCP UDP ICMP IGMP 109 %token DECNET LAT MOPRC MOPDL 110 %token TK_BROADCAST TK_MULTICAST 111 %token NUM INBOUND OUTBOUND 112 %token LINK 113 %token GEQ LEQ NEQ 114 %token ID EID HID 115 %token LSH RSH 116 %token LEN 117 118 %type <s> ID 119 %type <e> EID 120 %type <h> HID 121 %type <i> NUM 122 123 %left OR AND 124 %nonassoc '!' 125 %left '|' 126 %left '&' 127 %left LSH RSH 128 %left '+' '-' 129 %left '*' '/' 130 %nonassoc UMINUS 131 %% 132 prog: null expr 133 { 134 finish_parse($2.b); 135 } 136 | null 137 ; 138 null: /* null */ { $$.q = qerr; } 139 ; 140 expr: term 141 | expr and term { gen_and($1.b, $3.b); $$ = $3; } 142 | expr and id { gen_and($1.b, $3.b); $$ = $3; } 143 | expr or term { gen_or($1.b, $3.b); $$ = $3; } 144 | expr or id { gen_or($1.b, $3.b); $$ = $3; } 145 ; 146 and: AND { $$ = $<blk>0; } 147 ; 148 or: OR { $$ = $<blk>0; } 149 ; 150 id: nid 151 | pnum { $$.b = gen_ncode((u_long)$1, 152 $$.q = $<blk>0.q); } 153 | paren pid ')' { $$ = $2; } 154 ; 155 nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); } 156 | HID { 157 /* Decide how to parse HID based on proto */ 158 $$.q = $<blk>0.q; 159 switch ($$.q.proto) { 160 case Q_DECNET: 161 $$.b = 162 gen_ncode(__pcap_atodn((char *)$1), 163 $$.q); 164 break; 165 default: 166 $$.b = 167 gen_ncode(__pcap_atoin((char *)$1), 168 $$.q); 169 break; 170 } 171 } 172 | EID { $$.b = gen_ecode($1, $$.q = $<blk>0.q); } 173 | not id { gen_not($2.b); $$ = $2; } 174 ; 175 not: '!' { $$ = $<blk>0; } 176 ; 177 paren: '(' { $$ = $<blk>0; } 178 ; 179 pid: nid 180 | qid and id { gen_and($1.b, $3.b); $$ = $3; } 181 | qid or id { gen_or($1.b, $3.b); $$ = $3; } 182 ; 183 qid: pnum { $$.b = gen_ncode((u_long)$1, 184 $$.q = $<blk>0.q); } 185 | pid 186 ; 187 term: rterm 188 | not term { gen_not($2.b); $$ = $2; } 189 ; 190 head: pqual dqual aqual { QSET($$.q, $1, $2, $3); } 191 | pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); } 192 | pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); } 193 | pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); } 194 | pqual ndaqual { QSET($$.q, $1, Q_DEFAULT, $2); } 195 ; 196 rterm: head id { $$ = $2; } 197 | paren expr ')' { $$.b = $2.b; $$.q = $1.q; } 198 | pname { $$.b = gen_proto_abbrev($1); $$.q = qerr; } 199 | arth relop arth { $$.b = gen_relation($2, $1, $3, 0); 200 $$.q = qerr; } 201 | arth irelop arth { $$.b = gen_relation($2, $1, $3, 1); 202 $$.q = qerr; } 203 | other { $$.b = $1; $$.q = qerr; } 204 ; 205 /* protocol level qualifiers */ 206 pqual: pname 207 | { $$ = Q_DEFAULT; } 208 ; 209 /* 'direction' qualifiers */ 210 dqual: SRC { $$ = Q_SRC; } 211 | DST { $$ = Q_DST; } 212 | SRC OR DST { $$ = Q_OR; } 213 | DST OR SRC { $$ = Q_OR; } 214 | SRC AND DST { $$ = Q_AND; } 215 | DST AND SRC { $$ = Q_AND; } 216 ; 217 /* address type qualifiers */ 218 aqual: HOST { $$ = Q_HOST; } 219 | NET { $$ = Q_NET; } 220 | PORT { $$ = Q_PORT; } 221 ; 222 /* non-directional address type qualifiers */ 223 ndaqual: GATEWAY { $$ = Q_GATEWAY; } 224 ; 225 pname: LINK { $$ = Q_LINK; } 226 | IP { $$ = Q_IP; } 227 | ARP { $$ = Q_ARP; } 228 | RARP { $$ = Q_RARP; } 229 | TCP { $$ = Q_TCP; } 230 | UDP { $$ = Q_UDP; } 231 | ICMP { $$ = Q_ICMP; } 232 | IGMP { $$ = Q_IGMP; } 233 | DECNET { $$ = Q_DECNET; } 234 | LAT { $$ = Q_LAT; } 235 | MOPDL { $$ = Q_MOPDL; } 236 | MOPRC { $$ = Q_MOPRC; } 237 ; 238 other: pqual TK_BROADCAST { $$ = gen_broadcast($1); } 239 | pqual TK_MULTICAST { $$ = gen_multicast($1); } 240 | LESS NUM { $$ = gen_less($2); } 241 | GREATER NUM { $$ = gen_greater($2); } 242 | BYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); } 243 | INBOUND { $$ = gen_inbound(0); } 244 | OUTBOUND { $$ = gen_inbound(1); } 245 ; 246 relop: '>' { $$ = BPF_JGT; } 247 | GEQ { $$ = BPF_JGE; } 248 | '=' { $$ = BPF_JEQ; } 249 ; 250 irelop: LEQ { $$ = BPF_JGT; } 251 | '<' { $$ = BPF_JGE; } 252 | NEQ { $$ = BPF_JEQ; } 253 ; 254 arth: pnum { $$ = gen_loadi($1); } 255 | narth 256 ; 257 narth: pname '[' arth ']' { $$ = gen_load($1, $3, 1); } 258 | pname '[' arth ':' NUM ']' { $$ = gen_load($1, $3, $5); } 259 | arth '+' arth { $$ = gen_arth(BPF_ADD, $1, $3); } 260 | arth '-' arth { $$ = gen_arth(BPF_SUB, $1, $3); } 261 | arth '*' arth { $$ = gen_arth(BPF_MUL, $1, $3); } 262 | arth '/' arth { $$ = gen_arth(BPF_DIV, $1, $3); } 263 | arth '&' arth { $$ = gen_arth(BPF_AND, $1, $3); } 264 | arth '|' arth { $$ = gen_arth(BPF_OR, $1, $3); } 265 | arth LSH arth { $$ = gen_arth(BPF_LSH, $1, $3); } 266 | arth RSH arth { $$ = gen_arth(BPF_RSH, $1, $3); } 267 | '-' arth %prec UMINUS { $$ = gen_neg($2); } 268 | paren narth ')' { $$ = $2; } 269 | LEN { $$ = gen_loadlen(); } 270 ; 271 byteop: '&' { $$ = '&'; } 272 | '|' { $$ = '|'; } 273 | '<' { $$ = '<'; } 274 | '>' { $$ = '>'; } 275 | '=' { $$ = '='; } 276 ; 277 pnum: NUM 278 | paren pnum ')' { $$ = $2; } 279 ; 280 %% 281