gencode.c revision 17684
1/* 2 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 */ 21#ifndef lint 22static char rcsid[] = 23 "@(#) $Header: gencode.c,v 1.88 96/07/23 01:30:41 leres Exp $ (LBL)"; 24#endif 25 26#include <sys/types.h> 27#include <sys/socket.h> 28#include <sys/time.h> 29 30#if __STDC__ 31struct mbuf; 32struct rtentry; 33#endif 34 35#include <net/if.h> 36 37#include <netinet/in.h> 38#include <netinet/if_ether.h> 39 40#include <stdlib.h> 41#include <memory.h> 42#include <setjmp.h> 43#if __STDC__ 44#include <stdarg.h> 45#else 46#include <varargs.h> 47#endif 48 49#include "pcap-int.h" 50 51#include "ethertype.h" 52#include "gencode.h" 53#include <pcap-namedb.h> 54 55#include "gnuc.h" 56#ifdef HAVE_OS_PROTO_H 57#include "os-proto.h" 58#endif 59 60#define JMP(c) ((c)|BPF_JMP|BPF_K) 61 62/* Locals */ 63static jmp_buf top_ctx; 64static pcap_t *bpf_pcap; 65 66/* XXX */ 67#ifdef PCAP_FDDIPAD 68int pcap_fddipad = PCAP_FDDIPAD; 69#else 70int pcap_fddipad; 71#endif 72 73/* VARARGS */ 74__dead void 75#if __STDC__ 76bpf_error(const char *fmt, ...) 77#else 78bpf_error(fmt, va_alist) 79 const char *fmt; 80 va_dcl 81#endif 82{ 83 va_list ap; 84 85#if __STDC__ 86 va_start(ap, fmt); 87#else 88 va_start(ap); 89#endif 90 if (bpf_pcap != NULL) 91 (void)vsprintf(pcap_geterr(bpf_pcap), fmt, ap); 92 va_end(ap); 93 longjmp(top_ctx, 1); 94 /* NOTREACHED */ 95} 96 97static void init_linktype(int); 98 99static int alloc_reg(void); 100static void free_reg(int); 101 102static struct block *root; 103 104/* 105 * We divy out chunks of memory rather than call malloc each time so 106 * we don't have to worry about leaking memory. It's probably 107 * not a big deal if all this memory was wasted but it this ever 108 * goes into a library that would probably not be a good idea. 109 */ 110#define NCHUNKS 16 111#define CHUNK0SIZE 1024 112struct chunk { 113 u_int n_left; 114 void *m; 115}; 116 117static struct chunk chunks[NCHUNKS]; 118static int cur_chunk; 119 120static void *newchunk(u_int); 121static void freechunks(void); 122static inline struct block *new_block(int); 123static inline struct slist *new_stmt(int); 124static struct block *gen_retblk(int); 125static inline void syntax(void); 126 127static void backpatch(struct block *, struct block *); 128static void merge(struct block *, struct block *); 129static struct block *gen_cmp(u_int, u_int, bpf_int32); 130static struct block *gen_mcmp(u_int, u_int, bpf_int32, bpf_u_int32); 131static struct block *gen_bcmp(u_int, u_int, const u_char *); 132static struct block *gen_uncond(int); 133static inline struct block *gen_true(void); 134static inline struct block *gen_false(void); 135static struct block *gen_linktype(int); 136static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int); 137static struct block *gen_ehostop(const u_char *, int); 138static struct block *gen_fhostop(const u_char *, int); 139static struct block *gen_dnhostop(bpf_u_int32, int, u_int); 140static struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int); 141static struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int); 142static struct block *gen_ipfrag(void); 143static struct block *gen_portatom(int, bpf_int32); 144struct block *gen_portop(int, int, int); 145static struct block *gen_port(int, int, int); 146static int lookup_proto(const char *, int); 147static struct block *gen_proto(int, int, int); 148static struct slist *xfer_to_x(struct arth *); 149static struct slist *xfer_to_a(struct arth *); 150static struct block *gen_len(int, int); 151 152static void * 153newchunk(n) 154 u_int n; 155{ 156 struct chunk *cp; 157 int k, size; 158 159 /* XXX Round up to nearest long. */ 160 n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1); 161 162 cp = &chunks[cur_chunk]; 163 if (n > cp->n_left) { 164 ++cp, k = ++cur_chunk; 165 if (k >= NCHUNKS) 166 bpf_error("out of memory"); 167 size = CHUNK0SIZE << k; 168 cp->m = (void *)malloc(size); 169 memset((char *)cp->m, 0, size); 170 cp->n_left = size; 171 if (n > size) 172 bpf_error("out of memory"); 173 } 174 cp->n_left -= n; 175 return (void *)((char *)cp->m + cp->n_left); 176} 177 178static void 179freechunks() 180{ 181 int i; 182 183 cur_chunk = 0; 184 for (i = 0; i < NCHUNKS; ++i) 185 if (chunks[i].m != NULL) { 186 free(chunks[i].m); 187 chunks[i].m = NULL; 188 } 189} 190 191/* 192 * A strdup whose allocations are freed after code generation is over. 193 */ 194char * 195sdup(s) 196 register const char *s; 197{ 198 int n = strlen(s) + 1; 199 char *cp = newchunk(n); 200 201 strcpy(cp, s); 202 return (cp); 203} 204 205static inline struct block * 206new_block(code) 207 int code; 208{ 209 struct block *p; 210 211 p = (struct block *)newchunk(sizeof(*p)); 212 p->s.code = code; 213 p->head = p; 214 215 return p; 216} 217 218static inline struct slist * 219new_stmt(code) 220 int code; 221{ 222 struct slist *p; 223 224 p = (struct slist *)newchunk(sizeof(*p)); 225 p->s.code = code; 226 227 return p; 228} 229 230static struct block * 231gen_retblk(v) 232 int v; 233{ 234 struct block *b = new_block(BPF_RET|BPF_K); 235 236 b->s.k = v; 237 return b; 238} 239 240static inline void 241syntax() 242{ 243 bpf_error("syntax error in filter expression"); 244} 245 246static bpf_u_int32 netmask; 247static int snaplen; 248 249int 250pcap_compile(pcap_t *p, struct bpf_program *program, 251 char *buf, int optimize, bpf_u_int32 mask) 252{ 253 extern int n_errors; 254 int len; 255 256 n_errors = 0; 257 root = NULL; 258 bpf_pcap = p; 259 if (setjmp(top_ctx)) { 260 freechunks(); 261 return (-1); 262 } 263 264 netmask = mask; 265 snaplen = pcap_snapshot(p); 266 267 lex_init(buf ? buf : ""); 268 init_linktype(pcap_datalink(p)); 269 (void)pcap_parse(); 270 271 if (n_errors) 272 syntax(); 273 274 if (root == NULL) 275 root = gen_retblk(snaplen); 276 277 if (optimize) { 278 bpf_optimize(&root); 279 if (root == NULL || 280 (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0)) 281 bpf_error("expression rejects all packets"); 282 } 283 program->bf_insns = icode_to_fcode(root, &len); 284 program->bf_len = len; 285 286 freechunks(); 287 return (0); 288} 289 290/* 291 * Backpatch the blocks in 'list' to 'target'. The 'sense' field indicates 292 * which of the jt and jf fields has been resolved and which is a pointer 293 * back to another unresolved block (or nil). At least one of the fields 294 * in each block is already resolved. 295 */ 296static void 297backpatch(list, target) 298 struct block *list, *target; 299{ 300 struct block *next; 301 302 while (list) { 303 if (!list->sense) { 304 next = JT(list); 305 JT(list) = target; 306 } else { 307 next = JF(list); 308 JF(list) = target; 309 } 310 list = next; 311 } 312} 313 314/* 315 * Merge the lists in b0 and b1, using the 'sense' field to indicate 316 * which of jt and jf is the link. 317 */ 318static void 319merge(b0, b1) 320 struct block *b0, *b1; 321{ 322 register struct block **p = &b0; 323 324 /* Find end of list. */ 325 while (*p) 326 p = !((*p)->sense) ? &JT(*p) : &JF(*p); 327 328 /* Concatenate the lists. */ 329 *p = b1; 330} 331 332void 333finish_parse(p) 334 struct block *p; 335{ 336 backpatch(p, gen_retblk(snaplen)); 337 p->sense = !p->sense; 338 backpatch(p, gen_retblk(0)); 339 root = p->head; 340} 341 342void 343gen_and(b0, b1) 344 struct block *b0, *b1; 345{ 346 backpatch(b0, b1->head); 347 b0->sense = !b0->sense; 348 b1->sense = !b1->sense; 349 merge(b1, b0); 350 b1->sense = !b1->sense; 351 b1->head = b0->head; 352} 353 354void 355gen_or(b0, b1) 356 struct block *b0, *b1; 357{ 358 b0->sense = !b0->sense; 359 backpatch(b0, b1->head); 360 b0->sense = !b0->sense; 361 merge(b1, b0); 362 b1->head = b0->head; 363} 364 365void 366gen_not(b) 367 struct block *b; 368{ 369 b->sense = !b->sense; 370} 371 372static struct block * 373gen_cmp(offset, size, v) 374 u_int offset, size; 375 bpf_int32 v; 376{ 377 struct slist *s; 378 struct block *b; 379 380 s = new_stmt(BPF_LD|BPF_ABS|size); 381 s->s.k = offset; 382 383 b = new_block(JMP(BPF_JEQ)); 384 b->stmts = s; 385 b->s.k = v; 386 387 return b; 388} 389 390static struct block * 391gen_mcmp(offset, size, v, mask) 392 u_int offset, size; 393 bpf_int32 v; 394 bpf_u_int32 mask; 395{ 396 struct block *b = gen_cmp(offset, size, v); 397 struct slist *s; 398 399 if (mask != 0xffffffff) { 400 s = new_stmt(BPF_ALU|BPF_AND|BPF_K); 401 s->s.k = mask; 402 b->stmts->next = s; 403 } 404 return b; 405} 406 407static struct block * 408gen_bcmp(offset, size, v) 409 register u_int offset, size; 410 register const u_char *v; 411{ 412 register struct block *b, *tmp; 413 414 b = NULL; 415 while (size >= 4) { 416 register const u_char *p = &v[size - 4]; 417 bpf_int32 w = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; 418 419 tmp = gen_cmp(offset + size - 4, BPF_W, w); 420 if (b != NULL) 421 gen_and(b, tmp); 422 b = tmp; 423 size -= 4; 424 } 425 while (size >= 2) { 426 register const u_char *p = &v[size - 2]; 427 bpf_int32 w = (p[0] << 8) | p[1]; 428 429 tmp = gen_cmp(offset + size - 2, BPF_H, w); 430 if (b != NULL) 431 gen_and(b, tmp); 432 b = tmp; 433 size -= 2; 434 } 435 if (size > 0) { 436 tmp = gen_cmp(offset, BPF_B, (bpf_int32)v[0]); 437 if (b != NULL) 438 gen_and(b, tmp); 439 b = tmp; 440 } 441 return b; 442} 443 444/* 445 * Various code constructs need to know the layout of the data link 446 * layer. These variables give the necessary offsets. off_linktype 447 * is set to -1 for no encapsulation, in which case, IP is assumed. 448 */ 449static u_int off_linktype; 450static u_int off_nl; 451static int linktype; 452 453static void 454init_linktype(type) 455 int type; 456{ 457 linktype = type; 458 459 switch (type) { 460 461 case DLT_EN10MB: 462 off_linktype = 12; 463 off_nl = 14; 464 return; 465 466 case DLT_SLIP: 467 /* 468 * SLIP doesn't have a link level type. The 16 byte 469 * header is hacked into our SLIP driver. 470 */ 471 off_linktype = -1; 472 off_nl = 16; 473 return; 474 475 case DLT_NULL: 476 off_linktype = 0; 477 off_nl = 4; 478 return; 479 480 case DLT_PPP: 481 off_linktype = 2; 482 off_nl = 4; 483 return; 484 485 case DLT_FDDI: 486 /* 487 * FDDI doesn't really have a link-level type field. 488 * We assume that SSAP = SNAP is being used and pick 489 * out the encapsulated Ethernet type. 490 */ 491 off_linktype = 19; 492#ifdef PCAP_FDDIPAD 493 off_linktype += pcap_fddipad; 494#endif 495 off_nl = 21; 496#ifdef PCAP_FDDIPAD 497 off_nl += pcap_fddipad; 498#endif 499 return; 500 501 case DLT_IEEE802: 502 off_linktype = 20; 503 off_nl = 22; 504 return; 505 506 case DLT_ATM_RFC1483: 507 /* 508 * assume routed, non-ISO PDUs 509 * (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00) 510 */ 511 off_linktype = 6; 512 off_nl = 8; 513 return; 514 } 515 bpf_error("unknown data link type 0x%x", linktype); 516 /* NOTREACHED */ 517} 518 519static struct block * 520gen_uncond(rsense) 521 int rsense; 522{ 523 struct block *b; 524 struct slist *s; 525 526 s = new_stmt(BPF_LD|BPF_IMM); 527 s->s.k = !rsense; 528 b = new_block(JMP(BPF_JEQ)); 529 b->stmts = s; 530 531 return b; 532} 533 534static inline struct block * 535gen_true() 536{ 537 return gen_uncond(1); 538} 539 540static inline struct block * 541gen_false() 542{ 543 return gen_uncond(0); 544} 545 546static struct block * 547gen_linktype(proto) 548 int proto; 549{ 550 switch (linktype) { 551 case DLT_SLIP: 552 if (proto == ETHERTYPE_IP) 553 return gen_true(); 554 else 555 return gen_false(); 556 557 case DLT_PPP: 558 if (proto == ETHERTYPE_IP) 559 proto = 0x0021; /* XXX - need ppp.h defs */ 560 break; 561 562 case DLT_NULL: 563 /* XXX */ 564 if (proto == ETHERTYPE_IP) 565 return (gen_cmp(0, BPF_W, (bpf_int32)AF_INET)); 566 else 567 return gen_false(); 568 } 569 return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto); 570} 571 572static struct block * 573gen_hostop(addr, mask, dir, proto, src_off, dst_off) 574 bpf_u_int32 addr; 575 bpf_u_int32 mask; 576 int dir, proto; 577 u_int src_off, dst_off; 578{ 579 struct block *b0, *b1; 580 u_int offset; 581 582 switch (dir) { 583 584 case Q_SRC: 585 offset = src_off; 586 break; 587 588 case Q_DST: 589 offset = dst_off; 590 break; 591 592 case Q_AND: 593 b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off); 594 b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off); 595 gen_and(b0, b1); 596 return b1; 597 598 case Q_OR: 599 case Q_DEFAULT: 600 b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off); 601 b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off); 602 gen_or(b0, b1); 603 return b1; 604 605 default: 606 abort(); 607 } 608 b0 = gen_linktype(proto); 609 b1 = gen_mcmp(offset, BPF_W, (bpf_int32)addr, mask); 610 gen_and(b0, b1); 611 return b1; 612} 613 614static struct block * 615gen_ehostop(eaddr, dir) 616 register const u_char *eaddr; 617 register int dir; 618{ 619 register struct block *b0, *b1; 620 621 switch (dir) { 622 case Q_SRC: 623 return gen_bcmp(6, 6, eaddr); 624 625 case Q_DST: 626 return gen_bcmp(0, 6, eaddr); 627 628 case Q_AND: 629 b0 = gen_ehostop(eaddr, Q_SRC); 630 b1 = gen_ehostop(eaddr, Q_DST); 631 gen_and(b0, b1); 632 return b1; 633 634 case Q_DEFAULT: 635 case Q_OR: 636 b0 = gen_ehostop(eaddr, Q_SRC); 637 b1 = gen_ehostop(eaddr, Q_DST); 638 gen_or(b0, b1); 639 return b1; 640 } 641 abort(); 642 /* NOTREACHED */ 643} 644 645/* 646 * Like gen_ehostop, but for DLT_FDDI 647 */ 648static struct block * 649gen_fhostop(eaddr, dir) 650 register const u_char *eaddr; 651 register int dir; 652{ 653 struct block *b0, *b1; 654 655 switch (dir) { 656 case Q_SRC: 657#ifdef PCAP_FDDIPAD 658 return gen_bcmp(6 + 1 + pcap_fddipad, 6, eaddr); 659#else 660 return gen_bcmp(6 + 1, 6, eaddr); 661#endif 662 663 case Q_DST: 664#ifdef PCAP_FDDIPAD 665 return gen_bcmp(0 + 1 + pcap_fddipad, 6, eaddr); 666#else 667 return gen_bcmp(0 + 1, 6, eaddr); 668#endif 669 670 case Q_AND: 671 b0 = gen_fhostop(eaddr, Q_SRC); 672 b1 = gen_fhostop(eaddr, Q_DST); 673 gen_and(b0, b1); 674 return b1; 675 676 case Q_DEFAULT: 677 case Q_OR: 678 b0 = gen_fhostop(eaddr, Q_SRC); 679 b1 = gen_fhostop(eaddr, Q_DST); 680 gen_or(b0, b1); 681 return b1; 682 } 683 abort(); 684 /* NOTREACHED */ 685} 686 687/* 688 * This is quite tricky because there may be pad bytes in front of the 689 * DECNET header, and then there are two possible data packet formats that 690 * carry both src and dst addresses, plus 5 packet types in a format that 691 * carries only the src node, plus 2 types that use a different format and 692 * also carry just the src node. 693 * 694 * Yuck. 695 * 696 * Instead of doing those all right, we just look for data packets with 697 * 0 or 1 bytes of padding. If you want to look at other packets, that 698 * will require a lot more hacking. 699 * 700 * To add support for filtering on DECNET "areas" (network numbers) 701 * one would want to add a "mask" argument to this routine. That would 702 * make the filter even more inefficient, although one could be clever 703 * and not generate masking instructions if the mask is 0xFFFF. 704 */ 705static struct block * 706gen_dnhostop(addr, dir, base_off) 707 bpf_u_int32 addr; 708 int dir; 709 u_int base_off; 710{ 711 struct block *b0, *b1, *b2, *tmp; 712 u_int offset_lh; /* offset if long header is received */ 713 u_int offset_sh; /* offset if short header is received */ 714 715 switch (dir) { 716 717 case Q_DST: 718 offset_sh = 1; /* follows flags */ 719 offset_lh = 7; /* flgs,darea,dsubarea,HIORD */ 720 break; 721 722 case Q_SRC: 723 offset_sh = 3; /* follows flags, dstnode */ 724 offset_lh = 15; /* flgs,darea,dsubarea,did,sarea,ssub,HIORD */ 725 break; 726 727 case Q_AND: 728 /* Inefficient because we do our Calvinball dance twice */ 729 b0 = gen_dnhostop(addr, Q_SRC, base_off); 730 b1 = gen_dnhostop(addr, Q_DST, base_off); 731 gen_and(b0, b1); 732 return b1; 733 734 case Q_OR: 735 case Q_DEFAULT: 736 /* Inefficient because we do our Calvinball dance twice */ 737 b0 = gen_dnhostop(addr, Q_SRC, base_off); 738 b1 = gen_dnhostop(addr, Q_DST, base_off); 739 gen_or(b0, b1); 740 return b1; 741 742 default: 743 abort(); 744 } 745 b0 = gen_linktype(ETHERTYPE_DN); 746 /* Check for pad = 1, long header case */ 747 tmp = gen_mcmp(base_off + 2, BPF_H, 748 (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF)); 749 b1 = gen_cmp(base_off + 2 + 1 + offset_lh, 750 BPF_H, (bpf_int32)ntohs(addr)); 751 gen_and(tmp, b1); 752 /* Check for pad = 0, long header case */ 753 tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7); 754 b2 = gen_cmp(base_off + 2 + offset_lh, BPF_H, (bpf_int32)ntohs(addr)); 755 gen_and(tmp, b2); 756 gen_or(b2, b1); 757 /* Check for pad = 1, short header case */ 758 tmp = gen_mcmp(base_off + 2, BPF_H, 759 (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF)); 760 b2 = gen_cmp(base_off + 2 + 1 + offset_sh, 761 BPF_H, (bpf_int32)ntohs(addr)); 762 gen_and(tmp, b2); 763 gen_or(b2, b1); 764 /* Check for pad = 0, short header case */ 765 tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7); 766 b2 = gen_cmp(base_off + 2 + offset_sh, BPF_H, (bpf_int32)ntohs(addr)); 767 gen_and(tmp, b2); 768 gen_or(b2, b1); 769 770 /* Combine with test for linktype */ 771 gen_and(b0, b1); 772 return b1; 773} 774 775static struct block * 776gen_host(addr, mask, proto, dir) 777 bpf_u_int32 addr; 778 bpf_u_int32 mask; 779 int proto; 780 int dir; 781{ 782 struct block *b0, *b1; 783 784 switch (proto) { 785 786 case Q_DEFAULT: 787 b0 = gen_host(addr, mask, Q_IP, dir); 788 b1 = gen_host(addr, mask, Q_ARP, dir); 789 gen_or(b0, b1); 790 b0 = gen_host(addr, mask, Q_RARP, dir); 791 gen_or(b1, b0); 792 return b0; 793 794 case Q_IP: 795 return gen_hostop(addr, mask, dir, ETHERTYPE_IP, 796 off_nl + 12, off_nl + 16); 797 798 case Q_RARP: 799 return gen_hostop(addr, mask, dir, ETHERTYPE_REVARP, 800 off_nl + 14, off_nl + 24); 801 802 case Q_ARP: 803 return gen_hostop(addr, mask, dir, ETHERTYPE_ARP, 804 off_nl + 14, off_nl + 24); 805 806 case Q_TCP: 807 bpf_error("'tcp' modifier applied to host"); 808 809 case Q_UDP: 810 bpf_error("'udp' modifier applied to host"); 811 812 case Q_ICMP: 813 bpf_error("'icmp' modifier applied to host"); 814 815 case Q_IGMP: 816 bpf_error("'igmp' modifier applied to host"); 817 818 case Q_IGRP: 819 bpf_error("'igrp' modifier applied to host"); 820 821 case Q_ATALK: 822 bpf_error("ATALK host filtering not implemented"); 823 824 case Q_DECNET: 825 return gen_dnhostop(addr, dir, off_nl); 826 827 case Q_SCA: 828 bpf_error("SCA host filtering not implemented"); 829 830 case Q_LAT: 831 bpf_error("LAT host filtering not implemented"); 832 833 case Q_MOPDL: 834 bpf_error("MOPDL host filtering not implemented"); 835 836 case Q_MOPRC: 837 bpf_error("MOPRC host filtering not implemented"); 838 839 default: 840 abort(); 841 } 842 /* NOTREACHED */ 843} 844 845static struct block * 846gen_gateway(eaddr, alist, proto, dir) 847 const u_char *eaddr; 848 bpf_u_int32 **alist; 849 int proto; 850 int dir; 851{ 852 struct block *b0, *b1, *tmp; 853 854 if (dir != 0) 855 bpf_error("direction applied to 'gateway'"); 856 857 switch (proto) { 858 case Q_DEFAULT: 859 case Q_IP: 860 case Q_ARP: 861 case Q_RARP: 862 if (linktype == DLT_EN10MB) 863 b0 = gen_ehostop(eaddr, Q_OR); 864 else if (linktype == DLT_FDDI) 865 b0 = gen_fhostop(eaddr, Q_OR); 866 else 867 bpf_error( 868 "'gateway' supported only on ethernet or FDDI"); 869 870 b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR); 871 while (*alist) { 872 tmp = gen_host(**alist++, 0xffffffff, proto, Q_OR); 873 gen_or(b1, tmp); 874 b1 = tmp; 875 } 876 gen_not(b1); 877 gen_and(b0, b1); 878 return b1; 879 } 880 bpf_error("illegal modifier of 'gateway'"); 881 /* NOTREACHED */ 882} 883 884struct block * 885gen_proto_abbrev(proto) 886 int proto; 887{ 888 struct block *b0, *b1; 889 890 switch (proto) { 891 892 case Q_TCP: 893 b0 = gen_linktype(ETHERTYPE_IP); 894 b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)IPPROTO_TCP); 895 gen_and(b0, b1); 896 break; 897 898 case Q_UDP: 899 b0 = gen_linktype(ETHERTYPE_IP); 900 b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)IPPROTO_UDP); 901 gen_and(b0, b1); 902 break; 903 904 case Q_ICMP: 905 b0 = gen_linktype(ETHERTYPE_IP); 906 b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)IPPROTO_ICMP); 907 gen_and(b0, b1); 908 break; 909 910 case Q_IGMP: 911 b0 = gen_linktype(ETHERTYPE_IP); 912 b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)2); 913 gen_and(b0, b1); 914 break; 915 916#ifndef IPPROTO_IGRP 917#define IPPROTO_IGRP 9 918#endif 919 case Q_IGRP: 920 b0 = gen_linktype(ETHERTYPE_IP); 921 b1 = gen_cmp(off_nl + 9, BPF_B, (long)IPPROTO_IGRP); 922 gen_and(b0, b1); 923 break; 924 925 case Q_IP: 926 b1 = gen_linktype(ETHERTYPE_IP); 927 break; 928 929 case Q_ARP: 930 b1 = gen_linktype(ETHERTYPE_ARP); 931 break; 932 933 case Q_RARP: 934 b1 = gen_linktype(ETHERTYPE_REVARP); 935 break; 936 937 case Q_LINK: 938 bpf_error("link layer applied in wrong context"); 939 940 case Q_ATALK: 941 b1 = gen_linktype(ETHERTYPE_ATALK); 942 break; 943 944 case Q_DECNET: 945 b1 = gen_linktype(ETHERTYPE_DN); 946 break; 947 948 case Q_SCA: 949 b1 = gen_linktype(ETHERTYPE_SCA); 950 break; 951 952 case Q_LAT: 953 b1 = gen_linktype(ETHERTYPE_LAT); 954 break; 955 956 case Q_MOPDL: 957 b1 = gen_linktype(ETHERTYPE_MOPDL); 958 break; 959 960 case Q_MOPRC: 961 b1 = gen_linktype(ETHERTYPE_MOPRC); 962 break; 963 964 default: 965 abort(); 966 } 967 return b1; 968} 969 970static struct block * 971gen_ipfrag() 972{ 973 struct slist *s; 974 struct block *b; 975 976 /* not ip frag */ 977 s = new_stmt(BPF_LD|BPF_H|BPF_ABS); 978 s->s.k = off_nl + 6; 979 b = new_block(JMP(BPF_JSET)); 980 b->s.k = 0x1fff; 981 b->stmts = s; 982 gen_not(b); 983 984 return b; 985} 986 987static struct block * 988gen_portatom(off, v) 989 int off; 990 bpf_int32 v; 991{ 992 struct slist *s; 993 struct block *b; 994 995 s = new_stmt(BPF_LDX|BPF_MSH|BPF_B); 996 s->s.k = off_nl; 997 998 s->next = new_stmt(BPF_LD|BPF_IND|BPF_H); 999 s->next->s.k = off_nl + off; 1000 1001 b = new_block(JMP(BPF_JEQ)); 1002 b->stmts = s; 1003 b->s.k = v; 1004 1005 return b; 1006} 1007 1008struct block * 1009gen_portop(port, proto, dir) 1010 int port, proto, dir; 1011{ 1012 struct block *b0, *b1, *tmp; 1013 1014 /* ip proto 'proto' */ 1015 tmp = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)proto); 1016 b0 = gen_ipfrag(); 1017 gen_and(tmp, b0); 1018 1019 switch (dir) { 1020 case Q_SRC: 1021 b1 = gen_portatom(0, (bpf_int32)port); 1022 break; 1023 1024 case Q_DST: 1025 b1 = gen_portatom(2, (bpf_int32)port); 1026 break; 1027 1028 case Q_OR: 1029 case Q_DEFAULT: 1030 tmp = gen_portatom(0, (bpf_int32)port); 1031 b1 = gen_portatom(2, (bpf_int32)port); 1032 gen_or(tmp, b1); 1033 break; 1034 1035 case Q_AND: 1036 tmp = gen_portatom(0, (bpf_int32)port); 1037 b1 = gen_portatom(2, (bpf_int32)port); 1038 gen_and(tmp, b1); 1039 break; 1040 1041 default: 1042 abort(); 1043 } 1044 gen_and(b0, b1); 1045 1046 return b1; 1047} 1048 1049static struct block * 1050gen_port(port, ip_proto, dir) 1051 int port; 1052 int ip_proto; 1053 int dir; 1054{ 1055 struct block *b0, *b1, *tmp; 1056 1057 /* ether proto ip */ 1058 b0 = gen_linktype(ETHERTYPE_IP); 1059 1060 switch (ip_proto) { 1061 case IPPROTO_UDP: 1062 case IPPROTO_TCP: 1063 b1 = gen_portop(port, ip_proto, dir); 1064 break; 1065 1066 case PROTO_UNDEF: 1067 tmp = gen_portop(port, IPPROTO_TCP, dir); 1068 b1 = gen_portop(port, IPPROTO_UDP, dir); 1069 gen_or(tmp, b1); 1070 break; 1071 1072 default: 1073 abort(); 1074 } 1075 gen_and(b0, b1); 1076 return b1; 1077} 1078 1079static int 1080lookup_proto(name, proto) 1081 register const char *name; 1082 register int proto; 1083{ 1084 register int v; 1085 1086 switch (proto) { 1087 1088 case Q_DEFAULT: 1089 case Q_IP: 1090 v = pcap_nametoproto(name); 1091 if (v == PROTO_UNDEF) 1092 bpf_error("unknown ip proto '%s'", name); 1093 break; 1094 1095 case Q_LINK: 1096 /* XXX should look up h/w protocol type based on linktype */ 1097 v = pcap_nametoeproto(name); 1098 if (v == PROTO_UNDEF) 1099 bpf_error("unknown ether proto '%s'", name); 1100 break; 1101 1102 default: 1103 v = PROTO_UNDEF; 1104 break; 1105 } 1106 return v; 1107} 1108 1109static struct block * 1110gen_proto(v, proto, dir) 1111 int v; 1112 int proto; 1113 int dir; 1114{ 1115 struct block *b0, *b1; 1116 1117 if (dir != Q_DEFAULT) 1118 bpf_error("direction applied to 'proto'"); 1119 1120 switch (proto) { 1121 case Q_DEFAULT: 1122 case Q_IP: 1123 b0 = gen_linktype(ETHERTYPE_IP); 1124 b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)v); 1125 gen_and(b0, b1); 1126 return b1; 1127 1128 case Q_ARP: 1129 bpf_error("arp does not encapsulate another protocol"); 1130 /* NOTREACHED */ 1131 1132 case Q_RARP: 1133 bpf_error("rarp does not encapsulate another protocol"); 1134 /* NOTREACHED */ 1135 1136 case Q_ATALK: 1137 bpf_error("atalk encapsulation is not specifiable"); 1138 /* NOTREACHED */ 1139 1140 case Q_DECNET: 1141 bpf_error("decnet encapsulation is not specifiable"); 1142 /* NOTREACHED */ 1143 1144 case Q_SCA: 1145 bpf_error("sca does not encapsulate another protocol"); 1146 /* NOTREACHED */ 1147 1148 case Q_LAT: 1149 bpf_error("lat does not encapsulate another protocol"); 1150 /* NOTREACHED */ 1151 1152 case Q_MOPRC: 1153 bpf_error("moprc does not encapsulate another protocol"); 1154 /* NOTREACHED */ 1155 1156 case Q_MOPDL: 1157 bpf_error("mopdl does not encapsulate another protocol"); 1158 /* NOTREACHED */ 1159 1160 case Q_LINK: 1161 return gen_linktype(v); 1162 1163 case Q_UDP: 1164 bpf_error("'udp proto' is bogus"); 1165 /* NOTREACHED */ 1166 1167 case Q_TCP: 1168 bpf_error("'tcp proto' is bogus"); 1169 /* NOTREACHED */ 1170 1171 case Q_ICMP: 1172 bpf_error("'icmp proto' is bogus"); 1173 /* NOTREACHED */ 1174 1175 case Q_IGMP: 1176 bpf_error("'igmp proto' is bogus"); 1177 /* NOTREACHED */ 1178 1179 case Q_IGRP: 1180 bpf_error("'igrp proto' is bogus"); 1181 /* NOTREACHED */ 1182 1183 default: 1184 abort(); 1185 /* NOTREACHED */ 1186 } 1187 /* NOTREACHED */ 1188} 1189 1190struct block * 1191gen_scode(name, q) 1192 register const char *name; 1193 struct qual q; 1194{ 1195 int proto = q.proto; 1196 int dir = q.dir; 1197 u_char *eaddr; 1198 bpf_u_int32 mask, addr, **alist; 1199 struct block *b, *tmp; 1200 int port, real_proto; 1201 1202 switch (q.addr) { 1203 1204 case Q_NET: 1205 addr = pcap_nametonetaddr(name); 1206 if (addr == 0) 1207 bpf_error("unknown network '%s'", name); 1208 /* Left justify network addr and calculate its network mask */ 1209 mask = 0xffffffff; 1210 while (addr && (addr & 0xff000000) == 0) { 1211 addr <<= 8; 1212 mask <<= 8; 1213 } 1214 return gen_host(addr, mask, proto, dir); 1215 1216 case Q_DEFAULT: 1217 case Q_HOST: 1218 if (proto == Q_LINK) { 1219 switch (linktype) { 1220 1221 case DLT_EN10MB: 1222 eaddr = pcap_ether_hostton(name); 1223 if (eaddr == NULL) 1224 bpf_error( 1225 "unknown ether host '%s'", name); 1226 return gen_ehostop(eaddr, dir); 1227 1228 case DLT_FDDI: 1229 eaddr = pcap_ether_hostton(name); 1230 if (eaddr == NULL) 1231 bpf_error( 1232 "unknown FDDI host '%s'", name); 1233 return gen_fhostop(eaddr, dir); 1234 1235 default: 1236 bpf_error( 1237 "only ethernet/FDDI supports link-level host name"); 1238 break; 1239 } 1240 } else if (proto == Q_DECNET) { 1241 unsigned short dn_addr = __pcap_nametodnaddr(name); 1242 /* 1243 * I don't think DECNET hosts can be multihomed, so 1244 * there is no need to build up a list of addresses 1245 */ 1246 return (gen_host(dn_addr, 0, proto, dir)); 1247 } else { 1248 alist = pcap_nametoaddr(name); 1249 if (alist == NULL || *alist == NULL) 1250 bpf_error("unknown host '%s'", name); 1251 b = gen_host(**alist++, 0xffffffff, proto, dir); 1252 while (*alist) { 1253 tmp = gen_host(**alist++, 0xffffffff, 1254 proto, dir); 1255 gen_or(b, tmp); 1256 b = tmp; 1257 } 1258 return b; 1259 } 1260 1261 case Q_PORT: 1262 if (proto != Q_DEFAULT && proto != Q_UDP && proto != Q_TCP) 1263 bpf_error("illegal qualifier of 'port'"); 1264 if (pcap_nametoport(name, &port, &real_proto) == 0) 1265 bpf_error("unknown port '%s'", name); 1266 if (proto == Q_UDP) { 1267 if (real_proto == IPPROTO_TCP) 1268 bpf_error("port '%s' is tcp", name); 1269 else 1270 /* override PROTO_UNDEF */ 1271 real_proto = IPPROTO_UDP; 1272 } 1273 if (proto == Q_TCP) { 1274 if (real_proto == IPPROTO_UDP) 1275 bpf_error("port '%s' is udp", name); 1276 else 1277 /* override PROTO_UNDEF */ 1278 real_proto = IPPROTO_TCP; 1279 } 1280 return gen_port(port, real_proto, dir); 1281 1282 case Q_GATEWAY: 1283 eaddr = pcap_ether_hostton(name); 1284 if (eaddr == NULL) 1285 bpf_error("unknown ether host: %s", name); 1286 1287 alist = pcap_nametoaddr(name); 1288 if (alist == NULL || *alist == NULL) 1289 bpf_error("unknown host '%s'", name); 1290 return gen_gateway(eaddr, alist, proto, dir); 1291 1292 case Q_PROTO: 1293 real_proto = lookup_proto(name, proto); 1294 if (real_proto >= 0) 1295 return gen_proto(real_proto, proto, dir); 1296 else 1297 bpf_error("unknown protocol: %s", name); 1298 1299 case Q_UNDEF: 1300 syntax(); 1301 /* NOTREACHED */ 1302 } 1303 abort(); 1304 /* NOTREACHED */ 1305} 1306 1307struct block * 1308gen_mcode(s1, s2, masklen, q) 1309 register const char *s1, *s2; 1310 register int masklen; 1311 struct qual q; 1312{ 1313 register int nlen, mlen; 1314 bpf_u_int32 n, m; 1315 1316 nlen = __pcap_atoin(s1, &n); 1317 /* Promote short ipaddr */ 1318 n <<= 32 - nlen; 1319 1320 if (s2 != NULL) { 1321 mlen = __pcap_atoin(s2, &m); 1322 /* Promote short ipaddr */ 1323 m <<= 32 - mlen; 1324 } else { 1325 /* Convert mask len to mask */ 1326 if (masklen > 32) 1327 bpf_error("mask length must be <= 32"); 1328 m = 0xffffffff << (32 - masklen); 1329 } 1330 1331 switch (q.addr) { 1332 1333 case Q_NET: 1334 return gen_host(n, m, q.proto, q.dir); 1335 1336 default: 1337 bpf_error("Mask syntax for networks only"); 1338 /* NOTREACHED */ 1339 } 1340} 1341 1342struct block * 1343gen_ncode(s, v, q) 1344 register const char *s; 1345 bpf_u_int32 v; 1346 struct qual q; 1347{ 1348 bpf_u_int32 mask; 1349 int proto = q.proto; 1350 int dir = q.dir; 1351 register int vlen; 1352 1353 if (s == NULL) 1354 vlen = 32; 1355 else if (q.proto == Q_DECNET) 1356 vlen = __pcap_atodn(s, &v); 1357 else 1358 vlen = __pcap_atoin(s, &v); 1359 1360 switch (q.addr) { 1361 1362 case Q_DEFAULT: 1363 case Q_HOST: 1364 case Q_NET: 1365 if (proto == Q_DECNET) 1366 return gen_host(v, 0, proto, dir); 1367 else if (proto == Q_LINK) { 1368 bpf_error("illegal link layer address"); 1369 } else { 1370 mask = 0xffffffff; 1371 if (s == NULL && q.addr == Q_NET) { 1372 /* Promote short net number */ 1373 while (v && (v & 0xff000000) == 0) { 1374 v <<= 8; 1375 mask <<= 8; 1376 } 1377 } else { 1378 /* Promote short ipaddr */ 1379 v <<= 32 - vlen; 1380 mask <<= 32 - vlen; 1381 } 1382 return gen_host(v, mask, proto, dir); 1383 } 1384 1385 case Q_PORT: 1386 if (proto == Q_UDP) 1387 proto = IPPROTO_UDP; 1388 else if (proto == Q_TCP) 1389 proto = IPPROTO_TCP; 1390 else if (proto == Q_DEFAULT) 1391 proto = PROTO_UNDEF; 1392 else 1393 bpf_error("illegal qualifier of 'port'"); 1394 1395 return gen_port((int)v, proto, dir); 1396 1397 case Q_GATEWAY: 1398 bpf_error("'gateway' requires a name"); 1399 /* NOTREACHED */ 1400 1401 case Q_PROTO: 1402 return gen_proto((int)v, proto, dir); 1403 1404 case Q_UNDEF: 1405 syntax(); 1406 /* NOTREACHED */ 1407 1408 default: 1409 abort(); 1410 /* NOTREACHED */ 1411 } 1412 /* NOTREACHED */ 1413} 1414 1415struct block * 1416gen_ecode(eaddr, q) 1417 register const u_char *eaddr; 1418 struct qual q; 1419{ 1420 if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) { 1421 if (linktype == DLT_EN10MB) 1422 return gen_ehostop(eaddr, (int)q.dir); 1423 if (linktype == DLT_FDDI) 1424 return gen_fhostop(eaddr, (int)q.dir); 1425 } 1426 bpf_error("ethernet address used in non-ether expression"); 1427 /* NOTREACHED */ 1428} 1429 1430void 1431sappend(s0, s1) 1432 struct slist *s0, *s1; 1433{ 1434 /* 1435 * This is definitely not the best way to do this, but the 1436 * lists will rarely get long. 1437 */ 1438 while (s0->next) 1439 s0 = s0->next; 1440 s0->next = s1; 1441} 1442 1443static struct slist * 1444xfer_to_x(a) 1445 struct arth *a; 1446{ 1447 struct slist *s; 1448 1449 s = new_stmt(BPF_LDX|BPF_MEM); 1450 s->s.k = a->regno; 1451 return s; 1452} 1453 1454static struct slist * 1455xfer_to_a(a) 1456 struct arth *a; 1457{ 1458 struct slist *s; 1459 1460 s = new_stmt(BPF_LD|BPF_MEM); 1461 s->s.k = a->regno; 1462 return s; 1463} 1464 1465struct arth * 1466gen_load(proto, index, size) 1467 int proto; 1468 struct arth *index; 1469 int size; 1470{ 1471 struct slist *s, *tmp; 1472 struct block *b; 1473 int regno = alloc_reg(); 1474 1475 free_reg(index->regno); 1476 switch (size) { 1477 1478 default: 1479 bpf_error("data size must be 1, 2, or 4"); 1480 1481 case 1: 1482 size = BPF_B; 1483 break; 1484 1485 case 2: 1486 size = BPF_H; 1487 break; 1488 1489 case 4: 1490 size = BPF_W; 1491 break; 1492 } 1493 switch (proto) { 1494 default: 1495 bpf_error("unsupported index operation"); 1496 1497 case Q_LINK: 1498 s = xfer_to_x(index); 1499 tmp = new_stmt(BPF_LD|BPF_IND|size); 1500 sappend(s, tmp); 1501 sappend(index->s, s); 1502 break; 1503 1504 case Q_IP: 1505 case Q_ARP: 1506 case Q_RARP: 1507 case Q_ATALK: 1508 case Q_DECNET: 1509 case Q_SCA: 1510 case Q_LAT: 1511 case Q_MOPRC: 1512 case Q_MOPDL: 1513 /* XXX Note that we assume a fixed link link header here. */ 1514 s = xfer_to_x(index); 1515 tmp = new_stmt(BPF_LD|BPF_IND|size); 1516 tmp->s.k = off_nl; 1517 sappend(s, tmp); 1518 sappend(index->s, s); 1519 1520 b = gen_proto_abbrev(proto); 1521 if (index->b) 1522 gen_and(index->b, b); 1523 index->b = b; 1524 break; 1525 1526 case Q_TCP: 1527 case Q_UDP: 1528 case Q_ICMP: 1529 case Q_IGMP: 1530 case Q_IGRP: 1531 s = new_stmt(BPF_LDX|BPF_MSH|BPF_B); 1532 s->s.k = off_nl; 1533 sappend(s, xfer_to_a(index)); 1534 sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); 1535 sappend(s, new_stmt(BPF_MISC|BPF_TAX)); 1536 sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size)); 1537 tmp->s.k = off_nl; 1538 sappend(index->s, s); 1539 1540 gen_and(gen_proto_abbrev(proto), b = gen_ipfrag()); 1541 if (index->b) 1542 gen_and(index->b, b); 1543 index->b = b; 1544 break; 1545 } 1546 index->regno = regno; 1547 s = new_stmt(BPF_ST); 1548 s->s.k = regno; 1549 sappend(index->s, s); 1550 1551 return index; 1552} 1553 1554struct block * 1555gen_relation(code, a0, a1, reversed) 1556 int code; 1557 struct arth *a0, *a1; 1558 int reversed; 1559{ 1560 struct slist *s0, *s1, *s2; 1561 struct block *b, *tmp; 1562 1563 s0 = xfer_to_x(a1); 1564 s1 = xfer_to_a(a0); 1565 s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X); 1566 b = new_block(JMP(code)); 1567 if (code == BPF_JGT || code == BPF_JGE) { 1568 reversed = !reversed; 1569 b->s.k = 0x80000000; 1570 } 1571 if (reversed) 1572 gen_not(b); 1573 1574 sappend(s1, s2); 1575 sappend(s0, s1); 1576 sappend(a1->s, s0); 1577 sappend(a0->s, a1->s); 1578 1579 b->stmts = a0->s; 1580 1581 free_reg(a0->regno); 1582 free_reg(a1->regno); 1583 1584 /* 'and' together protocol checks */ 1585 if (a0->b) { 1586 if (a1->b) { 1587 gen_and(a0->b, tmp = a1->b); 1588 } 1589 else 1590 tmp = a0->b; 1591 } else 1592 tmp = a1->b; 1593 1594 if (tmp) 1595 gen_and(tmp, b); 1596 1597 return b; 1598} 1599 1600struct arth * 1601gen_loadlen() 1602{ 1603 int regno = alloc_reg(); 1604 struct arth *a = (struct arth *)newchunk(sizeof(*a)); 1605 struct slist *s; 1606 1607 s = new_stmt(BPF_LD|BPF_LEN); 1608 s->next = new_stmt(BPF_ST); 1609 s->next->s.k = regno; 1610 a->s = s; 1611 a->regno = regno; 1612 1613 return a; 1614} 1615 1616struct arth * 1617gen_loadi(val) 1618 int val; 1619{ 1620 struct arth *a; 1621 struct slist *s; 1622 int reg; 1623 1624 a = (struct arth *)newchunk(sizeof(*a)); 1625 1626 reg = alloc_reg(); 1627 1628 s = new_stmt(BPF_LD|BPF_IMM); 1629 s->s.k = val; 1630 s->next = new_stmt(BPF_ST); 1631 s->next->s.k = reg; 1632 a->s = s; 1633 a->regno = reg; 1634 1635 return a; 1636} 1637 1638struct arth * 1639gen_neg(a) 1640 struct arth *a; 1641{ 1642 struct slist *s; 1643 1644 s = xfer_to_a(a); 1645 sappend(a->s, s); 1646 s = new_stmt(BPF_ALU|BPF_NEG); 1647 s->s.k = 0; 1648 sappend(a->s, s); 1649 s = new_stmt(BPF_ST); 1650 s->s.k = a->regno; 1651 sappend(a->s, s); 1652 1653 return a; 1654} 1655 1656struct arth * 1657gen_arth(code, a0, a1) 1658 int code; 1659 struct arth *a0, *a1; 1660{ 1661 struct slist *s0, *s1, *s2; 1662 1663 s0 = xfer_to_x(a1); 1664 s1 = xfer_to_a(a0); 1665 s2 = new_stmt(BPF_ALU|BPF_X|code); 1666 1667 sappend(s1, s2); 1668 sappend(s0, s1); 1669 sappend(a1->s, s0); 1670 sappend(a0->s, a1->s); 1671 1672 free_reg(a1->regno); 1673 1674 s0 = new_stmt(BPF_ST); 1675 a0->regno = s0->s.k = alloc_reg(); 1676 sappend(a0->s, s0); 1677 1678 return a0; 1679} 1680 1681/* 1682 * Here we handle simple allocation of the scratch registers. 1683 * If too many registers are alloc'd, the allocator punts. 1684 */ 1685static int regused[BPF_MEMWORDS]; 1686static int curreg; 1687 1688/* 1689 * Return the next free register. 1690 */ 1691static int 1692alloc_reg() 1693{ 1694 int n = BPF_MEMWORDS; 1695 1696 while (--n >= 0) { 1697 if (regused[curreg]) 1698 curreg = (curreg + 1) % BPF_MEMWORDS; 1699 else { 1700 regused[curreg] = 1; 1701 return curreg; 1702 } 1703 } 1704 bpf_error("too many registers needed to evaluate expression"); 1705 /* NOTREACHED */ 1706} 1707 1708/* 1709 * Return a register to the table so it can 1710 * be used later. 1711 */ 1712static void 1713free_reg(n) 1714 int n; 1715{ 1716 regused[n] = 0; 1717} 1718 1719static struct block * 1720gen_len(jmp, n) 1721 int jmp, n; 1722{ 1723 struct slist *s; 1724 struct block *b; 1725 1726 s = new_stmt(BPF_LD|BPF_LEN); 1727 b = new_block(JMP(jmp)); 1728 b->stmts = s; 1729 b->s.k = n; 1730 1731 return b; 1732} 1733 1734struct block * 1735gen_greater(n) 1736 int n; 1737{ 1738 return gen_len(BPF_JGE, n); 1739} 1740 1741struct block * 1742gen_less(n) 1743 int n; 1744{ 1745 struct block *b; 1746 1747 b = gen_len(BPF_JGT, n); 1748 gen_not(b); 1749 1750 return b; 1751} 1752 1753struct block * 1754gen_byteop(op, idx, val) 1755 int op, idx, val; 1756{ 1757 struct block *b; 1758 struct slist *s; 1759 1760 switch (op) { 1761 default: 1762 abort(); 1763 1764 case '=': 1765 return gen_cmp((u_int)idx, BPF_B, (bpf_int32)val); 1766 1767 case '<': 1768 b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val); 1769 b->s.code = JMP(BPF_JGE); 1770 gen_not(b); 1771 return b; 1772 1773 case '>': 1774 b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val); 1775 b->s.code = JMP(BPF_JGT); 1776 return b; 1777 1778 case '|': 1779 s = new_stmt(BPF_ALU|BPF_OR|BPF_K); 1780 break; 1781 1782 case '&': 1783 s = new_stmt(BPF_ALU|BPF_AND|BPF_K); 1784 break; 1785 } 1786 s->s.k = val; 1787 b = new_block(JMP(BPF_JEQ)); 1788 b->stmts = s; 1789 gen_not(b); 1790 1791 return b; 1792} 1793 1794struct block * 1795gen_broadcast(proto) 1796 int proto; 1797{ 1798 bpf_u_int32 hostmask; 1799 struct block *b0, *b1, *b2; 1800 static u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 1801 1802 switch (proto) { 1803 1804 case Q_DEFAULT: 1805 case Q_LINK: 1806 if (linktype == DLT_EN10MB) 1807 return gen_ehostop(ebroadcast, Q_DST); 1808 if (linktype == DLT_FDDI) 1809 return gen_fhostop(ebroadcast, Q_DST); 1810 bpf_error("not a broadcast link"); 1811 break; 1812 1813 case Q_IP: 1814 b0 = gen_linktype(ETHERTYPE_IP); 1815 hostmask = ~netmask; 1816 b1 = gen_mcmp(off_nl + 16, BPF_W, (bpf_int32)0, hostmask); 1817 b2 = gen_mcmp(off_nl + 16, BPF_W, 1818 (bpf_int32)(~0 & hostmask), hostmask); 1819 gen_or(b1, b2); 1820 gen_and(b0, b2); 1821 return b2; 1822 } 1823 bpf_error("only ether/ip broadcast filters supported"); 1824} 1825 1826struct block * 1827gen_multicast(proto) 1828 int proto; 1829{ 1830 register struct block *b0, *b1; 1831 register struct slist *s; 1832 1833 switch (proto) { 1834 1835 case Q_DEFAULT: 1836 case Q_LINK: 1837 if (linktype == DLT_EN10MB) { 1838 /* ether[0] & 1 != 0 */ 1839 s = new_stmt(BPF_LD|BPF_B|BPF_ABS); 1840 s->s.k = 0; 1841 b0 = new_block(JMP(BPF_JSET)); 1842 b0->s.k = 1; 1843 b0->stmts = s; 1844 return b0; 1845 } 1846 1847 if (linktype == DLT_FDDI) { 1848 /* XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX */ 1849 /* fddi[1] & 1 != 0 */ 1850 s = new_stmt(BPF_LD|BPF_B|BPF_ABS); 1851 s->s.k = 1; 1852 b0 = new_block(JMP(BPF_JSET)); 1853 b0->s.k = 1; 1854 b0->stmts = s; 1855 return b0; 1856 } 1857 /* Link not known to support multicasts */ 1858 break; 1859 1860 case Q_IP: 1861 b0 = gen_linktype(ETHERTYPE_IP); 1862 b1 = gen_cmp(off_nl + 16, BPF_B, (bpf_int32)224); 1863 b1->s.code = JMP(BPF_JGE); 1864 gen_and(b0, b1); 1865 return b1; 1866 } 1867 bpf_error("only IP multicast filters supported on ethernet/FDDI"); 1868} 1869 1870/* 1871 * generate command for inbound/outbound. It's here so we can 1872 * make it link-type specific. 'dir' = 0 implies "inbound", 1873 * = 1 implies "outbound". 1874 */ 1875struct block * 1876gen_inbound(dir) 1877 int dir; 1878{ 1879 register struct block *b0; 1880 1881 b0 = gen_relation(BPF_JEQ, 1882 gen_load(Q_LINK, gen_loadi(0), 1), 1883 gen_loadi(0), 1884 dir); 1885 return (b0); 1886} 1887