| 1/*#define CHASE_CHAIN*/
|
1/* 2 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 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.
| 2/* 3 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 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 * $FreeBSD: head/contrib/libpcap/gencode.c 56891 2000-01-30 00:43:38Z fenner $
|
20 */ 21#ifndef lint 22static const char rcsid[] =
| 23 */ 24#ifndef lint 25static const char rcsid[] =
|
23 "@(#) $Header: gencode.c,v 1.94 98/07/12 13:06:49 leres Exp $ (LBL)";
| 26 "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.100 1999/12/08 19:54:03 mcr Exp $ (LBL)";
|
24#endif 25 26#include <sys/types.h> 27#include <sys/socket.h> 28#include <sys/time.h>
| 27#endif 28 29#include <sys/types.h> 30#include <sys/socket.h> 31#include <sys/time.h>
|
| 32#ifdef __NetBSD__ 33#include <sys/param.h> 34#endif
|
29 30#if __STDC__ 31struct mbuf; 32struct rtentry; 33#endif 34 35#include <net/if.h> 36#include <net/ethernet.h> 37 38#include <netinet/in.h> 39 40#include <stdlib.h> 41#include <memory.h> 42#include <setjmp.h> 43#include <net/if_llc.h> 44#if __STDC__ 45#include <stdarg.h> 46#else 47#include <varargs.h> 48#endif 49 50#include "pcap-int.h" 51 52#include "ethertype.h" 53#include "nlpid.h" 54#include "gencode.h" 55#include "ppp.h" 56#include <pcap-namedb.h>
| 35 36#if __STDC__ 37struct mbuf; 38struct rtentry; 39#endif 40 41#include <net/if.h> 42#include <net/ethernet.h> 43 44#include <netinet/in.h> 45 46#include <stdlib.h> 47#include <memory.h> 48#include <setjmp.h> 49#include <net/if_llc.h> 50#if __STDC__ 51#include <stdarg.h> 52#else 53#include <varargs.h> 54#endif 55 56#include "pcap-int.h" 57 58#include "ethertype.h" 59#include "nlpid.h" 60#include "gencode.h" 61#include "ppp.h" 62#include <pcap-namedb.h>
|
| 63#ifdef INET6 64#include <netdb.h> 65#include <sys/socket.h> 66#endif /*INET6*/
|
57 58#include "gnuc.h" 59#ifdef HAVE_OS_PROTO_H 60#include "os-proto.h" 61#endif 62 63#define JMP(c) ((c)|BPF_JMP|BPF_K) 64 65/* Locals */ 66static jmp_buf top_ctx; 67static pcap_t *bpf_pcap; 68 69/* XXX */ 70#ifdef PCAP_FDDIPAD 71int pcap_fddipad = PCAP_FDDIPAD; 72#else 73int pcap_fddipad; 74#endif 75 76/* VARARGS */ 77__dead void 78#if __STDC__ 79bpf_error(const char *fmt, ...) 80#else 81bpf_error(fmt, va_alist) 82 const char *fmt; 83 va_dcl 84#endif 85{ 86 va_list ap; 87 88#if __STDC__ 89 va_start(ap, fmt); 90#else 91 va_start(ap); 92#endif 93 if (bpf_pcap != NULL) 94 (void)vsprintf(pcap_geterr(bpf_pcap), fmt, ap); 95 va_end(ap); 96 longjmp(top_ctx, 1); 97 /* NOTREACHED */ 98} 99 100static void init_linktype(int); 101 102static int alloc_reg(void); 103static void free_reg(int); 104 105static struct block *root; 106 107/* 108 * We divy out chunks of memory rather than call malloc each time so 109 * we don't have to worry about leaking memory. It's probably 110 * not a big deal if all this memory was wasted but it this ever 111 * goes into a library that would probably not be a good idea. 112 */ 113#define NCHUNKS 16 114#define CHUNK0SIZE 1024 115struct chunk { 116 u_int n_left; 117 void *m; 118}; 119 120static struct chunk chunks[NCHUNKS]; 121static int cur_chunk; 122 123static void *newchunk(u_int); 124static void freechunks(void); 125static inline struct block *new_block(int); 126static inline struct slist *new_stmt(int); 127static struct block *gen_retblk(int); 128static inline void syntax(void); 129 130static void backpatch(struct block *, struct block *); 131static void merge(struct block *, struct block *); 132static struct block *gen_cmp(u_int, u_int, bpf_int32); 133static struct block *gen_mcmp(u_int, u_int, bpf_int32, bpf_u_int32); 134static struct block *gen_bcmp(u_int, u_int, const u_char *); 135static struct block *gen_uncond(int); 136static inline struct block *gen_true(void); 137static inline struct block *gen_false(void); 138static struct block *gen_linktype(int); 139static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int);
| 67 68#include "gnuc.h" 69#ifdef HAVE_OS_PROTO_H 70#include "os-proto.h" 71#endif 72 73#define JMP(c) ((c)|BPF_JMP|BPF_K) 74 75/* Locals */ 76static jmp_buf top_ctx; 77static pcap_t *bpf_pcap; 78 79/* XXX */ 80#ifdef PCAP_FDDIPAD 81int pcap_fddipad = PCAP_FDDIPAD; 82#else 83int pcap_fddipad; 84#endif 85 86/* VARARGS */ 87__dead void 88#if __STDC__ 89bpf_error(const char *fmt, ...) 90#else 91bpf_error(fmt, va_alist) 92 const char *fmt; 93 va_dcl 94#endif 95{ 96 va_list ap; 97 98#if __STDC__ 99 va_start(ap, fmt); 100#else 101 va_start(ap); 102#endif 103 if (bpf_pcap != NULL) 104 (void)vsprintf(pcap_geterr(bpf_pcap), fmt, ap); 105 va_end(ap); 106 longjmp(top_ctx, 1); 107 /* NOTREACHED */ 108} 109 110static void init_linktype(int); 111 112static int alloc_reg(void); 113static void free_reg(int); 114 115static struct block *root; 116 117/* 118 * We divy out chunks of memory rather than call malloc each time so 119 * we don't have to worry about leaking memory. It's probably 120 * not a big deal if all this memory was wasted but it this ever 121 * goes into a library that would probably not be a good idea. 122 */ 123#define NCHUNKS 16 124#define CHUNK0SIZE 1024 125struct chunk { 126 u_int n_left; 127 void *m; 128}; 129 130static struct chunk chunks[NCHUNKS]; 131static int cur_chunk; 132 133static void *newchunk(u_int); 134static void freechunks(void); 135static inline struct block *new_block(int); 136static inline struct slist *new_stmt(int); 137static struct block *gen_retblk(int); 138static inline void syntax(void); 139 140static void backpatch(struct block *, struct block *); 141static void merge(struct block *, struct block *); 142static struct block *gen_cmp(u_int, u_int, bpf_int32); 143static struct block *gen_mcmp(u_int, u_int, bpf_int32, bpf_u_int32); 144static struct block *gen_bcmp(u_int, u_int, const u_char *); 145static struct block *gen_uncond(int); 146static inline struct block *gen_true(void); 147static inline struct block *gen_false(void); 148static struct block *gen_linktype(int); 149static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int);
|
| 150#ifdef INET6 151static struct block *gen_hostop6(struct in6_addr *, struct in6_addr *, int, int, u_int, u_int); 152#endif
|
140static struct block *gen_ehostop(const u_char *, int); 141static struct block *gen_fhostop(const u_char *, int); 142static struct block *gen_dnhostop(bpf_u_int32, int, u_int); 143static struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int);
| 153static struct block *gen_ehostop(const u_char *, int); 154static struct block *gen_fhostop(const u_char *, int); 155static struct block *gen_dnhostop(bpf_u_int32, int, u_int); 156static struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int);
|
| 157#ifdef INET6 158static struct block *gen_host6(struct in6_addr *, struct in6_addr *, int, int); 159#endif
|
144static struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int); 145static struct block *gen_ipfrag(void); 146static struct block *gen_portatom(int, bpf_int32);
| 160static struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int); 161static struct block *gen_ipfrag(void); 162static struct block *gen_portatom(int, bpf_int32);
|
| 163#ifdef INET6 164static struct block *gen_portatom6(int, bpf_int32); 165#endif
|
147struct block *gen_portop(int, int, int); 148static struct block *gen_port(int, int, int);
| 166struct block *gen_portop(int, int, int); 167static struct block *gen_port(int, int, int);
|
| 168#ifdef INET6 169struct block *gen_portop6(int, int, int); 170static struct block *gen_port6(int, int, int); 171#endif
|
149static int lookup_proto(const char *, int); 150static struct block *gen_proto(int, int, int); 151static struct slist *xfer_to_x(struct arth *); 152static struct slist *xfer_to_a(struct arth *); 153static struct block *gen_len(int, int); 154 155static void * 156newchunk(n) 157 u_int n; 158{ 159 struct chunk *cp; 160 int k, size; 161
| 172static int lookup_proto(const char *, int); 173static struct block *gen_proto(int, int, int); 174static struct slist *xfer_to_x(struct arth *); 175static struct slist *xfer_to_a(struct arth *); 176static struct block *gen_len(int, int); 177 178static void * 179newchunk(n) 180 u_int n; 181{ 182 struct chunk *cp; 183 int k, size; 184
|
| 185#ifndef __NetBSD__
|
162 /* XXX Round up to nearest long. */ 163 n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1);
| 186 /* XXX Round up to nearest long. */ 187 n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1);
|
| 188#else 189 /* XXX Round up to structure boundary. */ 190 n = ALIGN(n); 191#endif
|
164 165 cp = &chunks[cur_chunk]; 166 if (n > cp->n_left) { 167 ++cp, k = ++cur_chunk; 168 if (k >= NCHUNKS) 169 bpf_error("out of memory"); 170 size = CHUNK0SIZE << k; 171 cp->m = (void *)malloc(size); 172 memset((char *)cp->m, 0, size); 173 cp->n_left = size; 174 if (n > size) 175 bpf_error("out of memory"); 176 } 177 cp->n_left -= n; 178 return (void *)((char *)cp->m + cp->n_left); 179} 180 181static void 182freechunks() 183{ 184 int i; 185 186 cur_chunk = 0; 187 for (i = 0; i < NCHUNKS; ++i) 188 if (chunks[i].m != NULL) { 189 free(chunks[i].m); 190 chunks[i].m = NULL; 191 } 192} 193 194/* 195 * A strdup whose allocations are freed after code generation is over. 196 */ 197char * 198sdup(s) 199 register const char *s; 200{ 201 int n = strlen(s) + 1; 202 char *cp = newchunk(n); 203 204 strcpy(cp, s); 205 return (cp); 206} 207 208static inline struct block * 209new_block(code) 210 int code; 211{ 212 struct block *p; 213 214 p = (struct block *)newchunk(sizeof(*p)); 215 p->s.code = code; 216 p->head = p; 217 218 return p; 219} 220 221static inline struct slist * 222new_stmt(code) 223 int code; 224{ 225 struct slist *p; 226 227 p = (struct slist *)newchunk(sizeof(*p)); 228 p->s.code = code; 229 230 return p; 231} 232 233static struct block * 234gen_retblk(v) 235 int v; 236{ 237 struct block *b = new_block(BPF_RET|BPF_K); 238 239 b->s.k = v; 240 return b; 241} 242 243static inline void 244syntax() 245{ 246 bpf_error("syntax error in filter expression"); 247} 248 249static bpf_u_int32 netmask; 250static int snaplen;
| 192 193 cp = &chunks[cur_chunk]; 194 if (n > cp->n_left) { 195 ++cp, k = ++cur_chunk; 196 if (k >= NCHUNKS) 197 bpf_error("out of memory"); 198 size = CHUNK0SIZE << k; 199 cp->m = (void *)malloc(size); 200 memset((char *)cp->m, 0, size); 201 cp->n_left = size; 202 if (n > size) 203 bpf_error("out of memory"); 204 } 205 cp->n_left -= n; 206 return (void *)((char *)cp->m + cp->n_left); 207} 208 209static void 210freechunks() 211{ 212 int i; 213 214 cur_chunk = 0; 215 for (i = 0; i < NCHUNKS; ++i) 216 if (chunks[i].m != NULL) { 217 free(chunks[i].m); 218 chunks[i].m = NULL; 219 } 220} 221 222/* 223 * A strdup whose allocations are freed after code generation is over. 224 */ 225char * 226sdup(s) 227 register const char *s; 228{ 229 int n = strlen(s) + 1; 230 char *cp = newchunk(n); 231 232 strcpy(cp, s); 233 return (cp); 234} 235 236static inline struct block * 237new_block(code) 238 int code; 239{ 240 struct block *p; 241 242 p = (struct block *)newchunk(sizeof(*p)); 243 p->s.code = code; 244 p->head = p; 245 246 return p; 247} 248 249static inline struct slist * 250new_stmt(code) 251 int code; 252{ 253 struct slist *p; 254 255 p = (struct slist *)newchunk(sizeof(*p)); 256 p->s.code = code; 257 258 return p; 259} 260 261static struct block * 262gen_retblk(v) 263 int v; 264{ 265 struct block *b = new_block(BPF_RET|BPF_K); 266 267 b->s.k = v; 268 return b; 269} 270 271static inline void 272syntax() 273{ 274 bpf_error("syntax error in filter expression"); 275} 276 277static bpf_u_int32 netmask; 278static int snaplen;
|
| 279int no_optimize;
|
251 252int 253pcap_compile(pcap_t *p, struct bpf_program *program, 254 char *buf, int optimize, bpf_u_int32 mask) 255{ 256 extern int n_errors; 257 int len; 258
| 280 281int 282pcap_compile(pcap_t *p, struct bpf_program *program, 283 char *buf, int optimize, bpf_u_int32 mask) 284{ 285 extern int n_errors; 286 int len; 287
|
| 288 no_optimize = 0;
|
259 n_errors = 0; 260 root = NULL; 261 bpf_pcap = p; 262 if (setjmp(top_ctx)) { 263 freechunks(); 264 return (-1); 265 } 266 267 netmask = mask; 268 snaplen = pcap_snapshot(p); 269 270 lex_init(buf ? buf : ""); 271 init_linktype(pcap_datalink(p)); 272 (void)pcap_parse(); 273 274 if (n_errors) 275 syntax(); 276 277 if (root == NULL) 278 root = gen_retblk(snaplen); 279
| 289 n_errors = 0; 290 root = NULL; 291 bpf_pcap = p; 292 if (setjmp(top_ctx)) { 293 freechunks(); 294 return (-1); 295 } 296 297 netmask = mask; 298 snaplen = pcap_snapshot(p); 299 300 lex_init(buf ? buf : ""); 301 init_linktype(pcap_datalink(p)); 302 (void)pcap_parse(); 303 304 if (n_errors) 305 syntax(); 306 307 if (root == NULL) 308 root = gen_retblk(snaplen); 309
|
| 310 if (optimize && !no_optimize) { 311 bpf_optimize(&root); 312 if (root == NULL || 313 (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0)) 314 bpf_error("expression rejects all packets"); 315 } 316 program->bf_insns = icode_to_fcode(root, &len); 317 program->bf_len = len; 318 319 freechunks(); 320 return (0); 321} 322 323/* 324 * entry point for using the compiler with no pcap open 325 * pass in all the stuff that is needed explicitly instead. 326 */ 327int 328pcap_compile_nopcap(int snaplen_arg, int linktype_arg, 329 struct bpf_program *program, 330 char *buf, int optimize, bpf_u_int32 mask) 331{ 332 extern int n_errors; 333 int len; 334 335 n_errors = 0; 336 root = NULL; 337 bpf_pcap = NULL; 338 if (setjmp(top_ctx)) { 339 freechunks(); 340 return (-1); 341 } 342 343 netmask = mask; 344 345 /* XXX needed? I don't grok the use of globals here. */ 346 snaplen = snaplen_arg; 347 348 lex_init(buf ? buf : ""); 349 init_linktype(linktype_arg); 350 (void)pcap_parse(); 351 352 if (n_errors) 353 syntax(); 354 355 if (root == NULL) 356 root = gen_retblk(snaplen_arg); 357
|
280 if (optimize) { 281 bpf_optimize(&root); 282 if (root == NULL || 283 (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0)) 284 bpf_error("expression rejects all packets"); 285 } 286 program->bf_insns = icode_to_fcode(root, &len); 287 program->bf_len = len; 288 289 freechunks(); 290 return (0); 291} 292 293/* 294 * Backpatch the blocks in 'list' to 'target'. The 'sense' field indicates 295 * which of the jt and jf fields has been resolved and which is a pointer 296 * back to another unresolved block (or nil). At least one of the fields 297 * in each block is already resolved. 298 */ 299static void 300backpatch(list, target) 301 struct block *list, *target; 302{ 303 struct block *next; 304 305 while (list) { 306 if (!list->sense) { 307 next = JT(list); 308 JT(list) = target; 309 } else { 310 next = JF(list); 311 JF(list) = target; 312 } 313 list = next; 314 } 315} 316 317/* 318 * Merge the lists in b0 and b1, using the 'sense' field to indicate 319 * which of jt and jf is the link. 320 */ 321static void 322merge(b0, b1) 323 struct block *b0, *b1; 324{ 325 register struct block **p = &b0; 326 327 /* Find end of list. */ 328 while (*p) 329 p = !((*p)->sense) ? &JT(*p) : &JF(*p); 330 331 /* Concatenate the lists. */ 332 *p = b1; 333} 334 335void 336finish_parse(p) 337 struct block *p; 338{ 339 backpatch(p, gen_retblk(snaplen)); 340 p->sense = !p->sense; 341 backpatch(p, gen_retblk(0)); 342 root = p->head; 343} 344 345void 346gen_and(b0, b1) 347 struct block *b0, *b1; 348{ 349 backpatch(b0, b1->head); 350 b0->sense = !b0->sense; 351 b1->sense = !b1->sense; 352 merge(b1, b0); 353 b1->sense = !b1->sense; 354 b1->head = b0->head; 355} 356 357void 358gen_or(b0, b1) 359 struct block *b0, *b1; 360{ 361 b0->sense = !b0->sense; 362 backpatch(b0, b1->head); 363 b0->sense = !b0->sense; 364 merge(b1, b0); 365 b1->head = b0->head; 366} 367 368void 369gen_not(b) 370 struct block *b; 371{ 372 b->sense = !b->sense; 373} 374 375static struct block * 376gen_cmp(offset, size, v) 377 u_int offset, size; 378 bpf_int32 v; 379{ 380 struct slist *s; 381 struct block *b; 382 383 s = new_stmt(BPF_LD|BPF_ABS|size); 384 s->s.k = offset; 385 386 b = new_block(JMP(BPF_JEQ)); 387 b->stmts = s; 388 b->s.k = v; 389 390 return b; 391} 392 393static struct block * 394gen_mcmp(offset, size, v, mask) 395 u_int offset, size; 396 bpf_int32 v; 397 bpf_u_int32 mask; 398{ 399 struct block *b = gen_cmp(offset, size, v); 400 struct slist *s; 401 402 if (mask != 0xffffffff) { 403 s = new_stmt(BPF_ALU|BPF_AND|BPF_K); 404 s->s.k = mask; 405 b->stmts->next = s; 406 } 407 return b; 408} 409 410static struct block * 411gen_bcmp(offset, size, v) 412 register u_int offset, size; 413 register const u_char *v; 414{ 415 register struct block *b, *tmp; 416 417 b = NULL; 418 while (size >= 4) { 419 register const u_char *p = &v[size - 4]; 420 bpf_int32 w = ((bpf_int32)p[0] << 24) | 421 ((bpf_int32)p[1] << 16) | ((bpf_int32)p[2] << 8) | p[3]; 422 423 tmp = gen_cmp(offset + size - 4, BPF_W, w); 424 if (b != NULL) 425 gen_and(b, tmp); 426 b = tmp; 427 size -= 4; 428 } 429 while (size >= 2) { 430 register const u_char *p = &v[size - 2]; 431 bpf_int32 w = ((bpf_int32)p[0] << 8) | p[1]; 432 433 tmp = gen_cmp(offset + size - 2, BPF_H, w); 434 if (b != NULL) 435 gen_and(b, tmp); 436 b = tmp; 437 size -= 2; 438 } 439 if (size > 0) { 440 tmp = gen_cmp(offset, BPF_B, (bpf_int32)v[0]); 441 if (b != NULL) 442 gen_and(b, tmp); 443 b = tmp; 444 } 445 return b; 446} 447 448/* 449 * Various code constructs need to know the layout of the data link 450 * layer. These variables give the necessary offsets. off_linktype 451 * is set to -1 for no encapsulation, in which case, IP is assumed. 452 */ 453static u_int off_linktype; 454static u_int off_nl; 455static int linktype; 456 457static void 458init_linktype(type) 459 int type; 460{ 461 linktype = type; 462 463 switch (type) { 464 465 case DLT_EN10MB: 466 off_linktype = 12; 467 off_nl = 14; 468 return; 469 470 case DLT_SLIP: 471 /* 472 * SLIP doesn't have a link level type. The 16 byte 473 * header is hacked into our SLIP driver. 474 */ 475 off_linktype = -1; 476 off_nl = 16; 477 return; 478 479 case DLT_SLIP_BSDOS: 480 /* XXX this may be the same as the DLT_PPP_BSDOS case */ 481 off_linktype = -1; 482 /* XXX end */ 483 off_nl = 24; 484 return; 485 486 case DLT_NULL: 487 off_linktype = 0; 488 off_nl = 4; 489 return; 490 491 case DLT_PPP:
| 358 if (optimize) { 359 bpf_optimize(&root); 360 if (root == NULL || 361 (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0)) 362 bpf_error("expression rejects all packets"); 363 } 364 program->bf_insns = icode_to_fcode(root, &len); 365 program->bf_len = len; 366 367 freechunks(); 368 return (0); 369} 370 371/* 372 * Backpatch the blocks in 'list' to 'target'. The 'sense' field indicates 373 * which of the jt and jf fields has been resolved and which is a pointer 374 * back to another unresolved block (or nil). At least one of the fields 375 * in each block is already resolved. 376 */ 377static void 378backpatch(list, target) 379 struct block *list, *target; 380{ 381 struct block *next; 382 383 while (list) { 384 if (!list->sense) { 385 next = JT(list); 386 JT(list) = target; 387 } else { 388 next = JF(list); 389 JF(list) = target; 390 } 391 list = next; 392 } 393} 394 395/* 396 * Merge the lists in b0 and b1, using the 'sense' field to indicate 397 * which of jt and jf is the link. 398 */ 399static void 400merge(b0, b1) 401 struct block *b0, *b1; 402{ 403 register struct block **p = &b0; 404 405 /* Find end of list. */ 406 while (*p) 407 p = !((*p)->sense) ? &JT(*p) : &JF(*p); 408 409 /* Concatenate the lists. */ 410 *p = b1; 411} 412 413void 414finish_parse(p) 415 struct block *p; 416{ 417 backpatch(p, gen_retblk(snaplen)); 418 p->sense = !p->sense; 419 backpatch(p, gen_retblk(0)); 420 root = p->head; 421} 422 423void 424gen_and(b0, b1) 425 struct block *b0, *b1; 426{ 427 backpatch(b0, b1->head); 428 b0->sense = !b0->sense; 429 b1->sense = !b1->sense; 430 merge(b1, b0); 431 b1->sense = !b1->sense; 432 b1->head = b0->head; 433} 434 435void 436gen_or(b0, b1) 437 struct block *b0, *b1; 438{ 439 b0->sense = !b0->sense; 440 backpatch(b0, b1->head); 441 b0->sense = !b0->sense; 442 merge(b1, b0); 443 b1->head = b0->head; 444} 445 446void 447gen_not(b) 448 struct block *b; 449{ 450 b->sense = !b->sense; 451} 452 453static struct block * 454gen_cmp(offset, size, v) 455 u_int offset, size; 456 bpf_int32 v; 457{ 458 struct slist *s; 459 struct block *b; 460 461 s = new_stmt(BPF_LD|BPF_ABS|size); 462 s->s.k = offset; 463 464 b = new_block(JMP(BPF_JEQ)); 465 b->stmts = s; 466 b->s.k = v; 467 468 return b; 469} 470 471static struct block * 472gen_mcmp(offset, size, v, mask) 473 u_int offset, size; 474 bpf_int32 v; 475 bpf_u_int32 mask; 476{ 477 struct block *b = gen_cmp(offset, size, v); 478 struct slist *s; 479 480 if (mask != 0xffffffff) { 481 s = new_stmt(BPF_ALU|BPF_AND|BPF_K); 482 s->s.k = mask; 483 b->stmts->next = s; 484 } 485 return b; 486} 487 488static struct block * 489gen_bcmp(offset, size, v) 490 register u_int offset, size; 491 register const u_char *v; 492{ 493 register struct block *b, *tmp; 494 495 b = NULL; 496 while (size >= 4) { 497 register const u_char *p = &v[size - 4]; 498 bpf_int32 w = ((bpf_int32)p[0] << 24) | 499 ((bpf_int32)p[1] << 16) | ((bpf_int32)p[2] << 8) | p[3]; 500 501 tmp = gen_cmp(offset + size - 4, BPF_W, w); 502 if (b != NULL) 503 gen_and(b, tmp); 504 b = tmp; 505 size -= 4; 506 } 507 while (size >= 2) { 508 register const u_char *p = &v[size - 2]; 509 bpf_int32 w = ((bpf_int32)p[0] << 8) | p[1]; 510 511 tmp = gen_cmp(offset + size - 2, BPF_H, w); 512 if (b != NULL) 513 gen_and(b, tmp); 514 b = tmp; 515 size -= 2; 516 } 517 if (size > 0) { 518 tmp = gen_cmp(offset, BPF_B, (bpf_int32)v[0]); 519 if (b != NULL) 520 gen_and(b, tmp); 521 b = tmp; 522 } 523 return b; 524} 525 526/* 527 * Various code constructs need to know the layout of the data link 528 * layer. These variables give the necessary offsets. off_linktype 529 * is set to -1 for no encapsulation, in which case, IP is assumed. 530 */ 531static u_int off_linktype; 532static u_int off_nl; 533static int linktype; 534 535static void 536init_linktype(type) 537 int type; 538{ 539 linktype = type; 540 541 switch (type) { 542 543 case DLT_EN10MB: 544 off_linktype = 12; 545 off_nl = 14; 546 return; 547 548 case DLT_SLIP: 549 /* 550 * SLIP doesn't have a link level type. The 16 byte 551 * header is hacked into our SLIP driver. 552 */ 553 off_linktype = -1; 554 off_nl = 16; 555 return; 556 557 case DLT_SLIP_BSDOS: 558 /* XXX this may be the same as the DLT_PPP_BSDOS case */ 559 off_linktype = -1; 560 /* XXX end */ 561 off_nl = 24; 562 return; 563 564 case DLT_NULL: 565 off_linktype = 0; 566 off_nl = 4; 567 return; 568 569 case DLT_PPP:
|
| 570#ifdef DLT_CHDLC 571 case DLT_CHDLC: 572#endif
|
492 off_linktype = 2; 493 off_nl = 4; 494 return; 495 496 case DLT_PPP_BSDOS: 497 off_linktype = 5; 498 off_nl = 24; 499 return; 500 501 case DLT_FDDI: 502 /* 503 * FDDI doesn't really have a link-level type field. 504 * We assume that SSAP = SNAP is being used and pick 505 * out the encapsulated Ethernet type. 506 */ 507 off_linktype = 19; 508#ifdef PCAP_FDDIPAD 509 off_linktype += pcap_fddipad; 510#endif 511 off_nl = 21; 512#ifdef PCAP_FDDIPAD 513 off_nl += pcap_fddipad; 514#endif 515 return; 516 517 case DLT_IEEE802: 518 off_linktype = 20; 519 off_nl = 22; 520 return; 521 522 case DLT_ATM_RFC1483: 523 /* 524 * assume routed, non-ISO PDUs 525 * (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00) 526 */ 527 off_linktype = 6; 528 off_nl = 8; 529 return; 530 531 case DLT_RAW: 532 off_linktype = -1; 533 off_nl = 0; 534 return; 535 } 536 bpf_error("unknown data link type 0x%x", linktype); 537 /* NOTREACHED */ 538} 539 540static struct block * 541gen_uncond(rsense) 542 int rsense; 543{ 544 struct block *b; 545 struct slist *s; 546 547 s = new_stmt(BPF_LD|BPF_IMM); 548 s->s.k = !rsense; 549 b = new_block(JMP(BPF_JEQ)); 550 b->stmts = s; 551 552 return b; 553} 554 555static inline struct block * 556gen_true() 557{ 558 return gen_uncond(1); 559} 560 561static inline struct block * 562gen_false() 563{ 564 return gen_uncond(0); 565} 566 567static struct block * 568gen_linktype(proto) 569 register int proto; 570{ 571 struct block *b0, *b1; 572 573 /* If we're not using encapsulation and checking for IP, we're done */ 574 if (off_linktype == -1 && proto == ETHERTYPE_IP) 575 return gen_true(); 576 577 switch (linktype) { 578 579 case DLT_SLIP: 580 return gen_false(); 581 582 case DLT_PPP: 583 if (proto == ETHERTYPE_IP) 584 proto = PPP_IP; /* XXX was 0x21 */
| 573 off_linktype = 2; 574 off_nl = 4; 575 return; 576 577 case DLT_PPP_BSDOS: 578 off_linktype = 5; 579 off_nl = 24; 580 return; 581 582 case DLT_FDDI: 583 /* 584 * FDDI doesn't really have a link-level type field. 585 * We assume that SSAP = SNAP is being used and pick 586 * out the encapsulated Ethernet type. 587 */ 588 off_linktype = 19; 589#ifdef PCAP_FDDIPAD 590 off_linktype += pcap_fddipad; 591#endif 592 off_nl = 21; 593#ifdef PCAP_FDDIPAD 594 off_nl += pcap_fddipad; 595#endif 596 return; 597 598 case DLT_IEEE802: 599 off_linktype = 20; 600 off_nl = 22; 601 return; 602 603 case DLT_ATM_RFC1483: 604 /* 605 * assume routed, non-ISO PDUs 606 * (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00) 607 */ 608 off_linktype = 6; 609 off_nl = 8; 610 return; 611 612 case DLT_RAW: 613 off_linktype = -1; 614 off_nl = 0; 615 return; 616 } 617 bpf_error("unknown data link type 0x%x", linktype); 618 /* NOTREACHED */ 619} 620 621static struct block * 622gen_uncond(rsense) 623 int rsense; 624{ 625 struct block *b; 626 struct slist *s; 627 628 s = new_stmt(BPF_LD|BPF_IMM); 629 s->s.k = !rsense; 630 b = new_block(JMP(BPF_JEQ)); 631 b->stmts = s; 632 633 return b; 634} 635 636static inline struct block * 637gen_true() 638{ 639 return gen_uncond(1); 640} 641 642static inline struct block * 643gen_false() 644{ 645 return gen_uncond(0); 646} 647 648static struct block * 649gen_linktype(proto) 650 register int proto; 651{ 652 struct block *b0, *b1; 653 654 /* If we're not using encapsulation and checking for IP, we're done */ 655 if (off_linktype == -1 && proto == ETHERTYPE_IP) 656 return gen_true(); 657 658 switch (linktype) { 659 660 case DLT_SLIP: 661 return gen_false(); 662 663 case DLT_PPP: 664 if (proto == ETHERTYPE_IP) 665 proto = PPP_IP; /* XXX was 0x21 */
|
| 666#ifdef INET6 667 else if (proto == ETHERTYPE_IPV6) 668 proto = PPP_IPV6; 669#endif
|
585 break; 586 587 case DLT_PPP_BSDOS: 588 switch (proto) { 589 590 case ETHERTYPE_IP: 591 b0 = gen_cmp(off_linktype, BPF_H, PPP_IP); 592 b1 = gen_cmp(off_linktype, BPF_H, PPP_VJC); 593 gen_or(b0, b1); 594 b0 = gen_cmp(off_linktype, BPF_H, PPP_VJNC); 595 gen_or(b1, b0); 596 return b0; 597
| 670 break; 671 672 case DLT_PPP_BSDOS: 673 switch (proto) { 674 675 case ETHERTYPE_IP: 676 b0 = gen_cmp(off_linktype, BPF_H, PPP_IP); 677 b1 = gen_cmp(off_linktype, BPF_H, PPP_VJC); 678 gen_or(b0, b1); 679 b0 = gen_cmp(off_linktype, BPF_H, PPP_VJNC); 680 gen_or(b1, b0); 681 return b0; 682
|
| 683#ifdef INET6 684 case ETHERTYPE_IPV6: 685 proto = PPP_IPV6; 686 /* more to go? */ 687 break; 688#endif 689
|
598 case ETHERTYPE_DN: 599 proto = PPP_DECNET; 600 break; 601 602 case ETHERTYPE_ATALK: 603 proto = PPP_APPLE; 604 break; 605 606 case ETHERTYPE_NS: 607 proto = PPP_NS; 608 break; 609 } 610 break; 611 612 case DLT_NULL: 613 /* XXX */ 614 if (proto == ETHERTYPE_IP) 615 return (gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET)));
| 690 case ETHERTYPE_DN: 691 proto = PPP_DECNET; 692 break; 693 694 case ETHERTYPE_ATALK: 695 proto = PPP_APPLE; 696 break; 697 698 case ETHERTYPE_NS: 699 proto = PPP_NS; 700 break; 701 } 702 break; 703 704 case DLT_NULL: 705 /* XXX */ 706 if (proto == ETHERTYPE_IP) 707 return (gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET)));
|
| 708#ifdef INET6 709 else if (proto == ETHERTYPE_IPV6) 710 return (gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET6))); 711#endif
|
616 else 617 return gen_false(); 618 case DLT_EN10MB: 619 /* 620 * Having to look at SAP's here is quite disgusting, 621 * but given an internal architecture that _knows_ that 622 * it's looking at IP on Ethernet... 623 */ 624 if (proto == LLC_ISO_LSAP) { 625 struct block *b0, *b1; 626 627 b0 = gen_cmp(off_linktype, BPF_H, (long)ETHERMTU); 628 b0->s.code = JMP(BPF_JGT); 629 gen_not(b0); 630 b1 = gen_cmp(off_linktype + 2, BPF_H, (long) 631 ((LLC_ISO_LSAP << 8) | LLC_ISO_LSAP)); 632 gen_and(b0, b1); 633 return b1; 634 } 635 break; 636 } 637 return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto); 638} 639 640static struct block * 641gen_hostop(addr, mask, dir, proto, src_off, dst_off) 642 bpf_u_int32 addr; 643 bpf_u_int32 mask; 644 int dir, proto; 645 u_int src_off, dst_off; 646{ 647 struct block *b0, *b1; 648 u_int offset; 649 650 switch (dir) { 651 652 case Q_SRC: 653 offset = src_off; 654 break; 655 656 case Q_DST: 657 offset = dst_off; 658 break; 659 660 case Q_AND: 661 b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off); 662 b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off); 663 gen_and(b0, b1); 664 return b1; 665 666 case Q_OR: 667 case Q_DEFAULT: 668 b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off); 669 b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off); 670 gen_or(b0, b1); 671 return b1; 672 673 default: 674 abort(); 675 } 676 b0 = gen_linktype(proto); 677 b1 = gen_mcmp(offset, BPF_W, (bpf_int32)addr, mask); 678 gen_and(b0, b1); 679 return b1; 680} 681
| 712 else 713 return gen_false(); 714 case DLT_EN10MB: 715 /* 716 * Having to look at SAP's here is quite disgusting, 717 * but given an internal architecture that _knows_ that 718 * it's looking at IP on Ethernet... 719 */ 720 if (proto == LLC_ISO_LSAP) { 721 struct block *b0, *b1; 722 723 b0 = gen_cmp(off_linktype, BPF_H, (long)ETHERMTU); 724 b0->s.code = JMP(BPF_JGT); 725 gen_not(b0); 726 b1 = gen_cmp(off_linktype + 2, BPF_H, (long) 727 ((LLC_ISO_LSAP << 8) | LLC_ISO_LSAP)); 728 gen_and(b0, b1); 729 return b1; 730 } 731 break; 732 } 733 return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto); 734} 735 736static struct block * 737gen_hostop(addr, mask, dir, proto, src_off, dst_off) 738 bpf_u_int32 addr; 739 bpf_u_int32 mask; 740 int dir, proto; 741 u_int src_off, dst_off; 742{ 743 struct block *b0, *b1; 744 u_int offset; 745 746 switch (dir) { 747 748 case Q_SRC: 749 offset = src_off; 750 break; 751 752 case Q_DST: 753 offset = dst_off; 754 break; 755 756 case Q_AND: 757 b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off); 758 b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off); 759 gen_and(b0, b1); 760 return b1; 761 762 case Q_OR: 763 case Q_DEFAULT: 764 b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off); 765 b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off); 766 gen_or(b0, b1); 767 return b1; 768 769 default: 770 abort(); 771 } 772 b0 = gen_linktype(proto); 773 b1 = gen_mcmp(offset, BPF_W, (bpf_int32)addr, mask); 774 gen_and(b0, b1); 775 return b1; 776} 777
|
| 778#ifdef INET6
|
682static struct block *
| 779static struct block *
|
| 780gen_hostop6(addr, mask, dir, proto, src_off, dst_off) 781 struct in6_addr *addr; 782 struct in6_addr *mask; 783 int dir, proto; 784 u_int src_off, dst_off; 785{ 786 struct block *b0, *b1; 787 u_int offset; 788 u_int32_t *a, *m; 789 790 switch (dir) { 791 792 case Q_SRC: 793 offset = src_off; 794 break; 795 796 case Q_DST: 797 offset = dst_off; 798 break; 799 800 case Q_AND: 801 b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off); 802 b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off); 803 gen_and(b0, b1); 804 return b1; 805 806 case Q_OR: 807 case Q_DEFAULT: 808 b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off); 809 b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off); 810 gen_or(b0, b1); 811 return b1; 812 813 default: 814 abort(); 815 } 816 /* this order is important */ 817 a = (u_int32_t *)addr; 818 m = (u_int32_t *)mask; 819 b1 = gen_mcmp(offset + 12, BPF_W, ntohl(a[3]), ntohl(m[3])); 820 b0 = gen_mcmp(offset + 8, BPF_W, ntohl(a[2]), ntohl(m[2])); 821 gen_and(b0, b1); 822 b0 = gen_mcmp(offset + 4, BPF_W, ntohl(a[1]), ntohl(m[1])); 823 gen_and(b0, b1); 824 b0 = gen_mcmp(offset + 0, BPF_W, ntohl(a[0]), ntohl(m[0])); 825 gen_and(b0, b1); 826 b0 = gen_linktype(proto); 827 gen_and(b0, b1); 828 return b1; 829} 830#endif /*INET6*/ 831 832static struct block *
|
683gen_ehostop(eaddr, dir) 684 register const u_char *eaddr; 685 register int dir; 686{ 687 register struct block *b0, *b1; 688 689 switch (dir) { 690 case Q_SRC: 691 return gen_bcmp(6, 6, eaddr); 692 693 case Q_DST: 694 return gen_bcmp(0, 6, eaddr); 695 696 case Q_AND: 697 b0 = gen_ehostop(eaddr, Q_SRC); 698 b1 = gen_ehostop(eaddr, Q_DST); 699 gen_and(b0, b1); 700 return b1; 701 702 case Q_DEFAULT: 703 case Q_OR: 704 b0 = gen_ehostop(eaddr, Q_SRC); 705 b1 = gen_ehostop(eaddr, Q_DST); 706 gen_or(b0, b1); 707 return b1; 708 } 709 abort(); 710 /* NOTREACHED */ 711} 712 713/* 714 * Like gen_ehostop, but for DLT_FDDI 715 */ 716static struct block * 717gen_fhostop(eaddr, dir) 718 register const u_char *eaddr; 719 register int dir; 720{ 721 struct block *b0, *b1; 722 723 switch (dir) { 724 case Q_SRC: 725#ifdef PCAP_FDDIPAD 726 return gen_bcmp(6 + 1 + pcap_fddipad, 6, eaddr); 727#else 728 return gen_bcmp(6 + 1, 6, eaddr); 729#endif 730 731 case Q_DST: 732#ifdef PCAP_FDDIPAD 733 return gen_bcmp(0 + 1 + pcap_fddipad, 6, eaddr); 734#else 735 return gen_bcmp(0 + 1, 6, eaddr); 736#endif 737 738 case Q_AND: 739 b0 = gen_fhostop(eaddr, Q_SRC); 740 b1 = gen_fhostop(eaddr, Q_DST); 741 gen_and(b0, b1); 742 return b1; 743 744 case Q_DEFAULT: 745 case Q_OR: 746 b0 = gen_fhostop(eaddr, Q_SRC); 747 b1 = gen_fhostop(eaddr, Q_DST); 748 gen_or(b0, b1); 749 return b1; 750 } 751 abort(); 752 /* NOTREACHED */ 753} 754 755/* 756 * This is quite tricky because there may be pad bytes in front of the 757 * DECNET header, and then there are two possible data packet formats that 758 * carry both src and dst addresses, plus 5 packet types in a format that 759 * carries only the src node, plus 2 types that use a different format and 760 * also carry just the src node. 761 * 762 * Yuck. 763 * 764 * Instead of doing those all right, we just look for data packets with 765 * 0 or 1 bytes of padding. If you want to look at other packets, that 766 * will require a lot more hacking. 767 * 768 * To add support for filtering on DECNET "areas" (network numbers) 769 * one would want to add a "mask" argument to this routine. That would 770 * make the filter even more inefficient, although one could be clever 771 * and not generate masking instructions if the mask is 0xFFFF. 772 */ 773static struct block * 774gen_dnhostop(addr, dir, base_off) 775 bpf_u_int32 addr; 776 int dir; 777 u_int base_off; 778{ 779 struct block *b0, *b1, *b2, *tmp; 780 u_int offset_lh; /* offset if long header is received */ 781 u_int offset_sh; /* offset if short header is received */ 782 783 switch (dir) { 784 785 case Q_DST: 786 offset_sh = 1; /* follows flags */ 787 offset_lh = 7; /* flgs,darea,dsubarea,HIORD */ 788 break; 789 790 case Q_SRC: 791 offset_sh = 3; /* follows flags, dstnode */ 792 offset_lh = 15; /* flgs,darea,dsubarea,did,sarea,ssub,HIORD */ 793 break; 794 795 case Q_AND: 796 /* Inefficient because we do our Calvinball dance twice */ 797 b0 = gen_dnhostop(addr, Q_SRC, base_off); 798 b1 = gen_dnhostop(addr, Q_DST, base_off); 799 gen_and(b0, b1); 800 return b1; 801 802 case Q_OR: 803 case Q_DEFAULT: 804 /* Inefficient because we do our Calvinball dance twice */ 805 b0 = gen_dnhostop(addr, Q_SRC, base_off); 806 b1 = gen_dnhostop(addr, Q_DST, base_off); 807 gen_or(b0, b1); 808 return b1; 809 810 default: 811 abort(); 812 } 813 b0 = gen_linktype(ETHERTYPE_DN); 814 /* Check for pad = 1, long header case */ 815 tmp = gen_mcmp(base_off + 2, BPF_H, 816 (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF)); 817 b1 = gen_cmp(base_off + 2 + 1 + offset_lh, 818 BPF_H, (bpf_int32)ntohs(addr)); 819 gen_and(tmp, b1); 820 /* Check for pad = 0, long header case */ 821 tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7); 822 b2 = gen_cmp(base_off + 2 + offset_lh, BPF_H, (bpf_int32)ntohs(addr)); 823 gen_and(tmp, b2); 824 gen_or(b2, b1); 825 /* Check for pad = 1, short header case */ 826 tmp = gen_mcmp(base_off + 2, BPF_H, 827 (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF)); 828 b2 = gen_cmp(base_off + 2 + 1 + offset_sh, 829 BPF_H, (bpf_int32)ntohs(addr)); 830 gen_and(tmp, b2); 831 gen_or(b2, b1); 832 /* Check for pad = 0, short header case */ 833 tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7); 834 b2 = gen_cmp(base_off + 2 + offset_sh, BPF_H, (bpf_int32)ntohs(addr)); 835 gen_and(tmp, b2); 836 gen_or(b2, b1); 837 838 /* Combine with test for linktype */ 839 gen_and(b0, b1); 840 return b1; 841} 842 843static struct block * 844gen_host(addr, mask, proto, dir) 845 bpf_u_int32 addr; 846 bpf_u_int32 mask; 847 int proto; 848 int dir; 849{ 850 struct block *b0, *b1; 851 852 switch (proto) { 853 854 case Q_DEFAULT: 855 b0 = gen_host(addr, mask, Q_IP, dir); 856 b1 = gen_host(addr, mask, Q_ARP, dir); 857 gen_or(b0, b1); 858 b0 = gen_host(addr, mask, Q_RARP, dir); 859 gen_or(b1, b0); 860 return b0; 861 862 case Q_IP: 863 return gen_hostop(addr, mask, dir, ETHERTYPE_IP, 864 off_nl + 12, off_nl + 16); 865 866 case Q_RARP: 867 return gen_hostop(addr, mask, dir, ETHERTYPE_REVARP, 868 off_nl + 14, off_nl + 24); 869 870 case Q_ARP: 871 return gen_hostop(addr, mask, dir, ETHERTYPE_ARP, 872 off_nl + 14, off_nl + 24); 873 874 case Q_TCP: 875 bpf_error("'tcp' modifier applied to host"); 876 877 case Q_UDP: 878 bpf_error("'udp' modifier applied to host"); 879 880 case Q_ICMP: 881 bpf_error("'icmp' modifier applied to host"); 882 883 case Q_IGMP: 884 bpf_error("'igmp' modifier applied to host"); 885 886 case Q_IGRP: 887 bpf_error("'igrp' modifier applied to host"); 888
| 833gen_ehostop(eaddr, dir) 834 register const u_char *eaddr; 835 register int dir; 836{ 837 register struct block *b0, *b1; 838 839 switch (dir) { 840 case Q_SRC: 841 return gen_bcmp(6, 6, eaddr); 842 843 case Q_DST: 844 return gen_bcmp(0, 6, eaddr); 845 846 case Q_AND: 847 b0 = gen_ehostop(eaddr, Q_SRC); 848 b1 = gen_ehostop(eaddr, Q_DST); 849 gen_and(b0, b1); 850 return b1; 851 852 case Q_DEFAULT: 853 case Q_OR: 854 b0 = gen_ehostop(eaddr, Q_SRC); 855 b1 = gen_ehostop(eaddr, Q_DST); 856 gen_or(b0, b1); 857 return b1; 858 } 859 abort(); 860 /* NOTREACHED */ 861} 862 863/* 864 * Like gen_ehostop, but for DLT_FDDI 865 */ 866static struct block * 867gen_fhostop(eaddr, dir) 868 register const u_char *eaddr; 869 register int dir; 870{ 871 struct block *b0, *b1; 872 873 switch (dir) { 874 case Q_SRC: 875#ifdef PCAP_FDDIPAD 876 return gen_bcmp(6 + 1 + pcap_fddipad, 6, eaddr); 877#else 878 return gen_bcmp(6 + 1, 6, eaddr); 879#endif 880 881 case Q_DST: 882#ifdef PCAP_FDDIPAD 883 return gen_bcmp(0 + 1 + pcap_fddipad, 6, eaddr); 884#else 885 return gen_bcmp(0 + 1, 6, eaddr); 886#endif 887 888 case Q_AND: 889 b0 = gen_fhostop(eaddr, Q_SRC); 890 b1 = gen_fhostop(eaddr, Q_DST); 891 gen_and(b0, b1); 892 return b1; 893 894 case Q_DEFAULT: 895 case Q_OR: 896 b0 = gen_fhostop(eaddr, Q_SRC); 897 b1 = gen_fhostop(eaddr, Q_DST); 898 gen_or(b0, b1); 899 return b1; 900 } 901 abort(); 902 /* NOTREACHED */ 903} 904 905/* 906 * This is quite tricky because there may be pad bytes in front of the 907 * DECNET header, and then there are two possible data packet formats that 908 * carry both src and dst addresses, plus 5 packet types in a format that 909 * carries only the src node, plus 2 types that use a different format and 910 * also carry just the src node. 911 * 912 * Yuck. 913 * 914 * Instead of doing those all right, we just look for data packets with 915 * 0 or 1 bytes of padding. If you want to look at other packets, that 916 * will require a lot more hacking. 917 * 918 * To add support for filtering on DECNET "areas" (network numbers) 919 * one would want to add a "mask" argument to this routine. That would 920 * make the filter even more inefficient, although one could be clever 921 * and not generate masking instructions if the mask is 0xFFFF. 922 */ 923static struct block * 924gen_dnhostop(addr, dir, base_off) 925 bpf_u_int32 addr; 926 int dir; 927 u_int base_off; 928{ 929 struct block *b0, *b1, *b2, *tmp; 930 u_int offset_lh; /* offset if long header is received */ 931 u_int offset_sh; /* offset if short header is received */ 932 933 switch (dir) { 934 935 case Q_DST: 936 offset_sh = 1; /* follows flags */ 937 offset_lh = 7; /* flgs,darea,dsubarea,HIORD */ 938 break; 939 940 case Q_SRC: 941 offset_sh = 3; /* follows flags, dstnode */ 942 offset_lh = 15; /* flgs,darea,dsubarea,did,sarea,ssub,HIORD */ 943 break; 944 945 case Q_AND: 946 /* Inefficient because we do our Calvinball dance twice */ 947 b0 = gen_dnhostop(addr, Q_SRC, base_off); 948 b1 = gen_dnhostop(addr, Q_DST, base_off); 949 gen_and(b0, b1); 950 return b1; 951 952 case Q_OR: 953 case Q_DEFAULT: 954 /* Inefficient because we do our Calvinball dance twice */ 955 b0 = gen_dnhostop(addr, Q_SRC, base_off); 956 b1 = gen_dnhostop(addr, Q_DST, base_off); 957 gen_or(b0, b1); 958 return b1; 959 960 default: 961 abort(); 962 } 963 b0 = gen_linktype(ETHERTYPE_DN); 964 /* Check for pad = 1, long header case */ 965 tmp = gen_mcmp(base_off + 2, BPF_H, 966 (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF)); 967 b1 = gen_cmp(base_off + 2 + 1 + offset_lh, 968 BPF_H, (bpf_int32)ntohs(addr)); 969 gen_and(tmp, b1); 970 /* Check for pad = 0, long header case */ 971 tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7); 972 b2 = gen_cmp(base_off + 2 + offset_lh, BPF_H, (bpf_int32)ntohs(addr)); 973 gen_and(tmp, b2); 974 gen_or(b2, b1); 975 /* Check for pad = 1, short header case */ 976 tmp = gen_mcmp(base_off + 2, BPF_H, 977 (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF)); 978 b2 = gen_cmp(base_off + 2 + 1 + offset_sh, 979 BPF_H, (bpf_int32)ntohs(addr)); 980 gen_and(tmp, b2); 981 gen_or(b2, b1); 982 /* Check for pad = 0, short header case */ 983 tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7); 984 b2 = gen_cmp(base_off + 2 + offset_sh, BPF_H, (bpf_int32)ntohs(addr)); 985 gen_and(tmp, b2); 986 gen_or(b2, b1); 987 988 /* Combine with test for linktype */ 989 gen_and(b0, b1); 990 return b1; 991} 992 993static struct block * 994gen_host(addr, mask, proto, dir) 995 bpf_u_int32 addr; 996 bpf_u_int32 mask; 997 int proto; 998 int dir; 999{ 1000 struct block *b0, *b1; 1001 1002 switch (proto) { 1003 1004 case Q_DEFAULT: 1005 b0 = gen_host(addr, mask, Q_IP, dir); 1006 b1 = gen_host(addr, mask, Q_ARP, dir); 1007 gen_or(b0, b1); 1008 b0 = gen_host(addr, mask, Q_RARP, dir); 1009 gen_or(b1, b0); 1010 return b0; 1011 1012 case Q_IP: 1013 return gen_hostop(addr, mask, dir, ETHERTYPE_IP, 1014 off_nl + 12, off_nl + 16); 1015 1016 case Q_RARP: 1017 return gen_hostop(addr, mask, dir, ETHERTYPE_REVARP, 1018 off_nl + 14, off_nl + 24); 1019 1020 case Q_ARP: 1021 return gen_hostop(addr, mask, dir, ETHERTYPE_ARP, 1022 off_nl + 14, off_nl + 24); 1023 1024 case Q_TCP: 1025 bpf_error("'tcp' modifier applied to host"); 1026 1027 case Q_UDP: 1028 bpf_error("'udp' modifier applied to host"); 1029 1030 case Q_ICMP: 1031 bpf_error("'icmp' modifier applied to host"); 1032 1033 case Q_IGMP: 1034 bpf_error("'igmp' modifier applied to host"); 1035 1036 case Q_IGRP: 1037 bpf_error("'igrp' modifier applied to host"); 1038
|
| 1039 case Q_PIM: 1040 bpf_error("'pim' modifier applied to host"); 1041
|
889 case Q_ATALK: 890 bpf_error("ATALK host filtering not implemented"); 891 892 case Q_DECNET: 893 return gen_dnhostop(addr, dir, off_nl); 894 895 case Q_SCA: 896 bpf_error("SCA host filtering not implemented"); 897 898 case Q_LAT: 899 bpf_error("LAT host filtering not implemented"); 900 901 case Q_MOPDL: 902 bpf_error("MOPDL host filtering not implemented"); 903 904 case Q_MOPRC: 905 bpf_error("MOPRC host filtering not implemented"); 906 907 case Q_ISO: 908 bpf_error("ISO host filtering not implemented");
| 1042 case Q_ATALK: 1043 bpf_error("ATALK host filtering not implemented"); 1044 1045 case Q_DECNET: 1046 return gen_dnhostop(addr, dir, off_nl); 1047 1048 case Q_SCA: 1049 bpf_error("SCA host filtering not implemented"); 1050 1051 case Q_LAT: 1052 bpf_error("LAT host filtering not implemented"); 1053 1054 case Q_MOPDL: 1055 bpf_error("MOPDL host filtering not implemented"); 1056 1057 case Q_MOPRC: 1058 bpf_error("MOPRC host filtering not implemented"); 1059 1060 case Q_ISO: 1061 bpf_error("ISO host filtering not implemented");
|
909
| 1062 1063#ifdef INET6 1064 case Q_IPV6: 1065 bpf_error("'ip6' modifier applied to ip host"); 1066 1067 case Q_ICMPV6: 1068 bpf_error("'icmp6' modifier applied to host"); 1069#endif /* INET6 */ 1070 1071 case Q_AH: 1072 bpf_error("'ah' modifier applied to host"); 1073 1074 case Q_ESP: 1075 bpf_error("'esp' modifier applied to host"); 1076
|
910 default: 911 abort(); 912 } 913 /* NOTREACHED */ 914} 915
| 1077 default: 1078 abort(); 1079 } 1080 /* NOTREACHED */ 1081} 1082
|
| 1083#ifdef INET6
|
916static struct block *
| 1084static struct block *
|
| 1085gen_host6(addr, mask, proto, dir) 1086 struct in6_addr *addr; 1087 struct in6_addr *mask; 1088 int proto; 1089 int dir; 1090{ 1091 struct block *b0, *b1; 1092 1093 switch (proto) { 1094 1095 case Q_DEFAULT: 1096 return gen_host6(addr, mask, Q_IPV6, dir); 1097 1098 case Q_IP: 1099 bpf_error("'ip' modifier applied to ip6 host"); 1100 1101 case Q_RARP: 1102 bpf_error("'rarp' modifier applied to ip6 host"); 1103 1104 case Q_ARP: 1105 bpf_error("'arp' modifier applied to ip6 host"); 1106 1107 case Q_TCP: 1108 bpf_error("'tcp' modifier applied to host"); 1109 1110 case Q_UDP: 1111 bpf_error("'udp' modifier applied to host"); 1112 1113 case Q_ICMP: 1114 bpf_error("'icmp' modifier applied to host"); 1115 1116 case Q_IGMP: 1117 bpf_error("'igmp' modifier applied to host"); 1118 1119 case Q_IGRP: 1120 bpf_error("'igrp' modifier applied to host"); 1121 1122 case Q_PIM: 1123 bpf_error("'pim' modifier applied to host"); 1124 1125 case Q_ATALK: 1126 bpf_error("ATALK host filtering not implemented"); 1127 1128 case Q_DECNET: 1129 bpf_error("'decnet' modifier applied to ip6 host"); 1130 1131 case Q_SCA: 1132 bpf_error("SCA host filtering not implemented"); 1133 1134 case Q_LAT: 1135 bpf_error("LAT host filtering not implemented"); 1136 1137 case Q_MOPDL: 1138 bpf_error("MOPDL host filtering not implemented"); 1139 1140 case Q_MOPRC: 1141 bpf_error("MOPRC host filtering not implemented"); 1142 1143 case Q_IPV6: 1144 return gen_hostop6(addr, mask, dir, ETHERTYPE_IPV6, 1145 off_nl + 8, off_nl + 24); 1146 1147 case Q_ICMPV6: 1148 bpf_error("'icmp6' modifier applied to host"); 1149 1150 case Q_AH: 1151 bpf_error("'ah' modifier applied to host"); 1152 1153 case Q_ESP: 1154 bpf_error("'esp' modifier applied to host"); 1155 1156 default: 1157 abort(); 1158 } 1159 /* NOTREACHED */ 1160} 1161#endif /*INET6*/ 1162 1163static struct block *
|
917gen_gateway(eaddr, alist, proto, dir) 918 const u_char *eaddr; 919 bpf_u_int32 **alist; 920 int proto; 921 int dir; 922{ 923 struct block *b0, *b1, *tmp; 924 925 if (dir != 0) 926 bpf_error("direction applied to 'gateway'"); 927 928 switch (proto) { 929 case Q_DEFAULT: 930 case Q_IP: 931 case Q_ARP: 932 case Q_RARP: 933 if (linktype == DLT_EN10MB) 934 b0 = gen_ehostop(eaddr, Q_OR); 935 else if (linktype == DLT_FDDI) 936 b0 = gen_fhostop(eaddr, Q_OR); 937 else 938 bpf_error( 939 "'gateway' supported only on ethernet or FDDI"); 940 941 b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR); 942 while (*alist) { 943 tmp = gen_host(**alist++, 0xffffffff, proto, Q_OR); 944 gen_or(b1, tmp); 945 b1 = tmp; 946 } 947 gen_not(b1); 948 gen_and(b0, b1); 949 return b1; 950 } 951 bpf_error("illegal modifier of 'gateway'"); 952 /* NOTREACHED */ 953} 954 955struct block * 956gen_proto_abbrev(proto) 957 int proto; 958{ 959 struct block *b0, *b1; 960 961 switch (proto) { 962 963 case Q_TCP:
| 1164gen_gateway(eaddr, alist, proto, dir) 1165 const u_char *eaddr; 1166 bpf_u_int32 **alist; 1167 int proto; 1168 int dir; 1169{ 1170 struct block *b0, *b1, *tmp; 1171 1172 if (dir != 0) 1173 bpf_error("direction applied to 'gateway'"); 1174 1175 switch (proto) { 1176 case Q_DEFAULT: 1177 case Q_IP: 1178 case Q_ARP: 1179 case Q_RARP: 1180 if (linktype == DLT_EN10MB) 1181 b0 = gen_ehostop(eaddr, Q_OR); 1182 else if (linktype == DLT_FDDI) 1183 b0 = gen_fhostop(eaddr, Q_OR); 1184 else 1185 bpf_error( 1186 "'gateway' supported only on ethernet or FDDI"); 1187 1188 b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR); 1189 while (*alist) { 1190 tmp = gen_host(**alist++, 0xffffffff, proto, Q_OR); 1191 gen_or(b1, tmp); 1192 b1 = tmp; 1193 } 1194 gen_not(b1); 1195 gen_and(b0, b1); 1196 return b1; 1197 } 1198 bpf_error("illegal modifier of 'gateway'"); 1199 /* NOTREACHED */ 1200} 1201 1202struct block * 1203gen_proto_abbrev(proto) 1204 int proto; 1205{ 1206 struct block *b0, *b1; 1207 1208 switch (proto) { 1209 1210 case Q_TCP:
|
964 b0 = gen_linktype(ETHERTYPE_IP); 965 b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)IPPROTO_TCP); 966 gen_and(b0, b1);
| 1211 b1 = gen_proto(IPPROTO_TCP, Q_IP, Q_DEFAULT); 1212#ifdef INET6 1213 b0 = gen_proto(IPPROTO_TCP, Q_IPV6, Q_DEFAULT); 1214 gen_or(b0, b1); 1215#endif
|
967 break; 968 969 case Q_UDP:
| 1216 break; 1217 1218 case Q_UDP:
|
970 b0 = gen_linktype(ETHERTYPE_IP); 971 b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)IPPROTO_UDP); 972 gen_and(b0, b1);
| 1219 b1 = gen_proto(IPPROTO_UDP, Q_IP, Q_DEFAULT); 1220#ifdef INET6 1221 b0 = gen_proto(IPPROTO_UDP, Q_IPV6, Q_DEFAULT); 1222 gen_or(b0, b1); 1223#endif
|
973 break; 974 975 case Q_ICMP:
| 1224 break; 1225 1226 case Q_ICMP:
|
976 b0 = gen_linktype(ETHERTYPE_IP); 977 b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)IPPROTO_ICMP); 978 gen_and(b0, b1);
| 1227 b1 = gen_proto(IPPROTO_ICMP, Q_IP, Q_DEFAULT);
|
979 break; 980 981 case Q_IGMP:
| 1228 break; 1229 1230 case Q_IGMP:
|
982 b0 = gen_linktype(ETHERTYPE_IP); 983 b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)2); 984 gen_and(b0, b1);
| 1231 b1 = gen_proto(2, Q_IP, Q_DEFAULT);
|
985 break; 986 987#ifndef IPPROTO_IGRP 988#define IPPROTO_IGRP 9 989#endif 990 case Q_IGRP:
| 1232 break; 1233 1234#ifndef IPPROTO_IGRP 1235#define IPPROTO_IGRP 9 1236#endif 1237 case Q_IGRP:
|
991 b0 = gen_linktype(ETHERTYPE_IP); 992 b1 = gen_cmp(off_nl + 9, BPF_B, (long)IPPROTO_IGRP); 993 gen_and(b0, b1);
| 1238 b1 = gen_proto(IPPROTO_IGRP, Q_IP, Q_DEFAULT);
|
994 break; 995
| 1239 break; 1240
|
| 1241#ifndef IPPROTO_PIM 1242#define IPPROTO_PIM 103 1243#endif 1244 1245 case Q_PIM: 1246 b1 = gen_proto(IPPROTO_PIM, Q_IP, Q_DEFAULT); 1247#ifdef INET6 1248 b0 = gen_proto(IPPROTO_PIM, Q_IPV6, Q_DEFAULT); 1249 gen_or(b0, b1); 1250#endif 1251 break; 1252
|
996 case Q_IP: 997 b1 = gen_linktype(ETHERTYPE_IP); 998 break; 999 1000 case Q_ARP: 1001 b1 = gen_linktype(ETHERTYPE_ARP); 1002 break; 1003 1004 case Q_RARP: 1005 b1 = gen_linktype(ETHERTYPE_REVARP); 1006 break; 1007 1008 case Q_LINK: 1009 bpf_error("link layer applied in wrong context"); 1010 1011 case Q_ATALK: 1012 b1 = gen_linktype(ETHERTYPE_ATALK); 1013 break; 1014 1015 case Q_DECNET: 1016 b1 = gen_linktype(ETHERTYPE_DN); 1017 break; 1018 1019 case Q_SCA: 1020 b1 = gen_linktype(ETHERTYPE_SCA); 1021 break; 1022 1023 case Q_LAT: 1024 b1 = gen_linktype(ETHERTYPE_LAT); 1025 break; 1026 1027 case Q_MOPDL: 1028 b1 = gen_linktype(ETHERTYPE_MOPDL); 1029 break; 1030 1031 case Q_MOPRC: 1032 b1 = gen_linktype(ETHERTYPE_MOPRC); 1033 break; 1034
| 1253 case Q_IP: 1254 b1 = gen_linktype(ETHERTYPE_IP); 1255 break; 1256 1257 case Q_ARP: 1258 b1 = gen_linktype(ETHERTYPE_ARP); 1259 break; 1260 1261 case Q_RARP: 1262 b1 = gen_linktype(ETHERTYPE_REVARP); 1263 break; 1264 1265 case Q_LINK: 1266 bpf_error("link layer applied in wrong context"); 1267 1268 case Q_ATALK: 1269 b1 = gen_linktype(ETHERTYPE_ATALK); 1270 break; 1271 1272 case Q_DECNET: 1273 b1 = gen_linktype(ETHERTYPE_DN); 1274 break; 1275 1276 case Q_SCA: 1277 b1 = gen_linktype(ETHERTYPE_SCA); 1278 break; 1279 1280 case Q_LAT: 1281 b1 = gen_linktype(ETHERTYPE_LAT); 1282 break; 1283 1284 case Q_MOPDL: 1285 b1 = gen_linktype(ETHERTYPE_MOPDL); 1286 break; 1287 1288 case Q_MOPRC: 1289 b1 = gen_linktype(ETHERTYPE_MOPRC); 1290 break; 1291
|
| 1292#ifdef INET6 1293 case Q_IPV6: 1294 b1 = gen_linktype(ETHERTYPE_IPV6); 1295 break; 1296 1297#ifndef IPPROTO_ICMPV6 1298#define IPPROTO_ICMPV6 58 1299#endif 1300 case Q_ICMPV6: 1301 b1 = gen_proto(IPPROTO_ICMPV6, Q_IPV6, Q_DEFAULT); 1302 break; 1303#endif /* INET6 */ 1304 1305#ifndef IPPROTO_AH 1306#define IPPROTO_AH 51 1307#endif 1308 case Q_AH: 1309 b1 = gen_proto(IPPROTO_AH, Q_IP, Q_DEFAULT); 1310#ifdef INET6 1311 b0 = gen_proto(IPPROTO_AH, Q_IPV6, Q_DEFAULT); 1312 gen_or(b0, b1); 1313#endif 1314 break; 1315 1316#ifndef IPPROTO_ESP 1317#define IPPROTO_ESP 50 1318#endif 1319 case Q_ESP: 1320 b1 = gen_proto(IPPROTO_ESP, Q_IP, Q_DEFAULT); 1321#ifdef INET6 1322 b0 = gen_proto(IPPROTO_ESP, Q_IPV6, Q_DEFAULT); 1323 gen_or(b0, b1); 1324#endif 1325 break; 1326
|
1035 case Q_ISO: 1036 b1 = gen_linktype(LLC_ISO_LSAP); 1037 break; 1038 1039 case Q_ESIS: 1040 b1 = gen_proto(ISO9542_ESIS, Q_ISO, Q_DEFAULT); 1041 break; 1042 1043 case Q_ISIS: 1044 b1 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT); 1045 break; 1046 1047 default: 1048 abort(); 1049 } 1050 return b1; 1051} 1052 1053static struct block * 1054gen_ipfrag() 1055{ 1056 struct slist *s; 1057 struct block *b; 1058 1059 /* not ip frag */ 1060 s = new_stmt(BPF_LD|BPF_H|BPF_ABS); 1061 s->s.k = off_nl + 6; 1062 b = new_block(JMP(BPF_JSET)); 1063 b->s.k = 0x1fff; 1064 b->stmts = s; 1065 gen_not(b); 1066 1067 return b; 1068} 1069 1070static struct block * 1071gen_portatom(off, v) 1072 int off; 1073 bpf_int32 v; 1074{ 1075 struct slist *s; 1076 struct block *b; 1077 1078 s = new_stmt(BPF_LDX|BPF_MSH|BPF_B); 1079 s->s.k = off_nl; 1080 1081 s->next = new_stmt(BPF_LD|BPF_IND|BPF_H); 1082 s->next->s.k = off_nl + off; 1083 1084 b = new_block(JMP(BPF_JEQ)); 1085 b->stmts = s; 1086 b->s.k = v; 1087 1088 return b; 1089} 1090
| 1327 case Q_ISO: 1328 b1 = gen_linktype(LLC_ISO_LSAP); 1329 break; 1330 1331 case Q_ESIS: 1332 b1 = gen_proto(ISO9542_ESIS, Q_ISO, Q_DEFAULT); 1333 break; 1334 1335 case Q_ISIS: 1336 b1 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT); 1337 break; 1338 1339 default: 1340 abort(); 1341 } 1342 return b1; 1343} 1344 1345static struct block * 1346gen_ipfrag() 1347{ 1348 struct slist *s; 1349 struct block *b; 1350 1351 /* not ip frag */ 1352 s = new_stmt(BPF_LD|BPF_H|BPF_ABS); 1353 s->s.k = off_nl + 6; 1354 b = new_block(JMP(BPF_JSET)); 1355 b->s.k = 0x1fff; 1356 b->stmts = s; 1357 gen_not(b); 1358 1359 return b; 1360} 1361 1362static struct block * 1363gen_portatom(off, v) 1364 int off; 1365 bpf_int32 v; 1366{ 1367 struct slist *s; 1368 struct block *b; 1369 1370 s = new_stmt(BPF_LDX|BPF_MSH|BPF_B); 1371 s->s.k = off_nl; 1372 1373 s->next = new_stmt(BPF_LD|BPF_IND|BPF_H); 1374 s->next->s.k = off_nl + off; 1375 1376 b = new_block(JMP(BPF_JEQ)); 1377 b->stmts = s; 1378 b->s.k = v; 1379 1380 return b; 1381} 1382
|
| 1383#ifdef INET6 1384static struct block * 1385gen_portatom6(off, v) 1386 int off; 1387 bpf_int32 v; 1388{ 1389 return gen_cmp(off_nl + 40 + off, BPF_H, v); 1390} 1391#endif/*INET6*/ 1392
|
1091struct block * 1092gen_portop(port, proto, dir) 1093 int port, proto, dir; 1094{ 1095 struct block *b0, *b1, *tmp; 1096 1097 /* ip proto 'proto' */ 1098 tmp = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)proto); 1099 b0 = gen_ipfrag(); 1100 gen_and(tmp, b0); 1101 1102 switch (dir) { 1103 case Q_SRC: 1104 b1 = gen_portatom(0, (bpf_int32)port); 1105 break; 1106 1107 case Q_DST: 1108 b1 = gen_portatom(2, (bpf_int32)port); 1109 break; 1110 1111 case Q_OR: 1112 case Q_DEFAULT: 1113 tmp = gen_portatom(0, (bpf_int32)port); 1114 b1 = gen_portatom(2, (bpf_int32)port); 1115 gen_or(tmp, b1); 1116 break; 1117 1118 case Q_AND: 1119 tmp = gen_portatom(0, (bpf_int32)port); 1120 b1 = gen_portatom(2, (bpf_int32)port); 1121 gen_and(tmp, b1); 1122 break; 1123 1124 default: 1125 abort(); 1126 } 1127 gen_and(b0, b1); 1128 1129 return b1; 1130} 1131 1132static struct block * 1133gen_port(port, ip_proto, dir) 1134 int port; 1135 int ip_proto; 1136 int dir; 1137{ 1138 struct block *b0, *b1, *tmp; 1139 1140 /* ether proto ip */ 1141 b0 = gen_linktype(ETHERTYPE_IP); 1142 1143 switch (ip_proto) { 1144 case IPPROTO_UDP: 1145 case IPPROTO_TCP: 1146 b1 = gen_portop(port, ip_proto, dir); 1147 break; 1148 1149 case PROTO_UNDEF: 1150 tmp = gen_portop(port, IPPROTO_TCP, dir); 1151 b1 = gen_portop(port, IPPROTO_UDP, dir); 1152 gen_or(tmp, b1); 1153 break; 1154 1155 default: 1156 abort(); 1157 } 1158 gen_and(b0, b1); 1159 return b1; 1160} 1161
| 1393struct block * 1394gen_portop(port, proto, dir) 1395 int port, proto, dir; 1396{ 1397 struct block *b0, *b1, *tmp; 1398 1399 /* ip proto 'proto' */ 1400 tmp = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)proto); 1401 b0 = gen_ipfrag(); 1402 gen_and(tmp, b0); 1403 1404 switch (dir) { 1405 case Q_SRC: 1406 b1 = gen_portatom(0, (bpf_int32)port); 1407 break; 1408 1409 case Q_DST: 1410 b1 = gen_portatom(2, (bpf_int32)port); 1411 break; 1412 1413 case Q_OR: 1414 case Q_DEFAULT: 1415 tmp = gen_portatom(0, (bpf_int32)port); 1416 b1 = gen_portatom(2, (bpf_int32)port); 1417 gen_or(tmp, b1); 1418 break; 1419 1420 case Q_AND: 1421 tmp = gen_portatom(0, (bpf_int32)port); 1422 b1 = gen_portatom(2, (bpf_int32)port); 1423 gen_and(tmp, b1); 1424 break; 1425 1426 default: 1427 abort(); 1428 } 1429 gen_and(b0, b1); 1430 1431 return b1; 1432} 1433 1434static struct block * 1435gen_port(port, ip_proto, dir) 1436 int port; 1437 int ip_proto; 1438 int dir; 1439{ 1440 struct block *b0, *b1, *tmp; 1441 1442 /* ether proto ip */ 1443 b0 = gen_linktype(ETHERTYPE_IP); 1444 1445 switch (ip_proto) { 1446 case IPPROTO_UDP: 1447 case IPPROTO_TCP: 1448 b1 = gen_portop(port, ip_proto, dir); 1449 break; 1450 1451 case PROTO_UNDEF: 1452 tmp = gen_portop(port, IPPROTO_TCP, dir); 1453 b1 = gen_portop(port, IPPROTO_UDP, dir); 1454 gen_or(tmp, b1); 1455 break; 1456 1457 default: 1458 abort(); 1459 } 1460 gen_and(b0, b1); 1461 return b1; 1462} 1463
|
| 1464#ifdef INET6 1465struct block * 1466gen_portop6(port, proto, dir) 1467 int port, proto, dir; 1468{ 1469 struct block *b0, *b1, *tmp; 1470 1471 /* ip proto 'proto' */ 1472 b0 = gen_cmp(off_nl + 6, BPF_B, (bpf_int32)proto); 1473 1474 switch (dir) { 1475 case Q_SRC: 1476 b1 = gen_portatom6(0, (bpf_int32)port); 1477 break; 1478 1479 case Q_DST: 1480 b1 = gen_portatom6(2, (bpf_int32)port); 1481 break; 1482 1483 case Q_OR: 1484 case Q_DEFAULT: 1485 tmp = gen_portatom6(0, (bpf_int32)port); 1486 b1 = gen_portatom6(2, (bpf_int32)port); 1487 gen_or(tmp, b1); 1488 break; 1489 1490 case Q_AND: 1491 tmp = gen_portatom6(0, (bpf_int32)port); 1492 b1 = gen_portatom6(2, (bpf_int32)port); 1493 gen_and(tmp, b1); 1494 break; 1495 1496 default: 1497 abort(); 1498 } 1499 gen_and(b0, b1); 1500 1501 return b1; 1502} 1503 1504static struct block * 1505gen_port6(port, ip_proto, dir) 1506 int port; 1507 int ip_proto; 1508 int dir; 1509{ 1510 struct block *b0, *b1, *tmp; 1511 1512 /* ether proto ip */ 1513 b0 = gen_linktype(ETHERTYPE_IPV6); 1514 1515 switch (ip_proto) { 1516 case IPPROTO_UDP: 1517 case IPPROTO_TCP: 1518 b1 = gen_portop6(port, ip_proto, dir); 1519 break; 1520 1521 case PROTO_UNDEF: 1522 tmp = gen_portop6(port, IPPROTO_TCP, dir); 1523 b1 = gen_portop6(port, IPPROTO_UDP, dir); 1524 gen_or(tmp, b1); 1525 break; 1526 1527 default: 1528 abort(); 1529 } 1530 gen_and(b0, b1); 1531 return b1; 1532} 1533#endif /* INET6 */ 1534
|
1162static int 1163lookup_proto(name, proto) 1164 register const char *name; 1165 register int proto; 1166{ 1167 register int v; 1168 1169 switch (proto) { 1170 1171 case Q_DEFAULT: 1172 case Q_IP: 1173 v = pcap_nametoproto(name); 1174 if (v == PROTO_UNDEF) 1175 bpf_error("unknown ip proto '%s'", name); 1176 break; 1177 1178 case Q_LINK: 1179 /* XXX should look up h/w protocol type based on linktype */ 1180 v = pcap_nametoeproto(name); 1181 if (v == PROTO_UNDEF) 1182 bpf_error("unknown ether proto '%s'", name); 1183 break; 1184 1185 default: 1186 v = PROTO_UNDEF; 1187 break; 1188 } 1189 return v; 1190} 1191
| 1535static int 1536lookup_proto(name, proto) 1537 register const char *name; 1538 register int proto; 1539{ 1540 register int v; 1541 1542 switch (proto) { 1543 1544 case Q_DEFAULT: 1545 case Q_IP: 1546 v = pcap_nametoproto(name); 1547 if (v == PROTO_UNDEF) 1548 bpf_error("unknown ip proto '%s'", name); 1549 break; 1550 1551 case Q_LINK: 1552 /* XXX should look up h/w protocol type based on linktype */ 1553 v = pcap_nametoeproto(name); 1554 if (v == PROTO_UNDEF) 1555 bpf_error("unknown ether proto '%s'", name); 1556 break; 1557 1558 default: 1559 v = PROTO_UNDEF; 1560 break; 1561 } 1562 return v; 1563} 1564
|
| 1565struct stmt * 1566gen_joinsp(s, n) 1567 struct stmt **s; 1568 int n; 1569{ 1570} 1571 1572struct block * 1573gen_protochain(v, proto, dir) 1574 int v; 1575 int proto; 1576 int dir; 1577{ 1578#ifdef NO_PROTOCHAIN 1579 return gen_proto(v, proto, dir); 1580#else 1581 struct block *b0, *b; 1582 struct slist *s[100], *sp; 1583 int fix2, fix3, fix4, fix5; 1584 int ahcheck, again, end; 1585 int i, max; 1586 int reg1 = alloc_reg(); 1587 int reg2 = alloc_reg(); 1588 1589 memset(s, 0, sizeof(s)); 1590 fix2 = fix3 = fix4 = fix5 = 0; 1591 1592 switch (proto) { 1593 case Q_IP: 1594 case Q_IPV6: 1595 break; 1596 case Q_DEFAULT: 1597 b0 = gen_protochain(v, Q_IP, dir); 1598 b = gen_protochain(v, Q_IPV6, dir); 1599 gen_or(b0, b); 1600 return b; 1601 default: 1602 bpf_error("bad protocol applied for 'protochain'"); 1603 /*NOTREACHED*/ 1604 } 1605 1606 no_optimize = 1; /*this code is not compatible with optimzer yet */ 1607 1608 /* 1609 * s[0] is a dummy entry to protect other BPF insn from damaged 1610 * by s[fix] = foo with uninitialized variable "fix". It is somewhat 1611 * hard to find interdependency made by jump table fixup. 1612 */ 1613 i = 0; 1614 s[i] = new_stmt(0); /*dummy*/ 1615 i++; 1616 1617 switch (proto) { 1618 case Q_IP: 1619 b0 = gen_linktype(ETHERTYPE_IP); 1620 1621 /* A = ip->ip_p */ 1622 s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B); 1623 s[i]->s.k = off_nl + 9; 1624 i++; 1625 /* X = ip->ip_hl << 2 */ 1626 s[i] = new_stmt(BPF_LDX|BPF_MSH|BPF_B); 1627 s[i]->s.k = off_nl; 1628 i++; 1629 break; 1630#ifdef INET6 1631 case Q_IPV6: 1632 b0 = gen_linktype(ETHERTYPE_IPV6); 1633 1634 /* A = ip6->ip_nxt */ 1635 s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B); 1636 s[i]->s.k = off_nl + 6; 1637 i++; 1638 /* X = sizeof(struct ip6_hdr) */ 1639 s[i] = new_stmt(BPF_LDX|BPF_IMM); 1640 s[i]->s.k = 40; 1641 i++; 1642 break; 1643#endif 1644 default: 1645 bpf_error("unsupported proto to gen_protochain"); 1646 /*NOTREACHED*/ 1647 } 1648 1649 /* again: if (A == v) goto end; else fall through; */ 1650 again = i; 1651 s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 1652 s[i]->s.k = v; 1653 s[i]->s.jt = NULL; /*later*/ 1654 s[i]->s.jf = NULL; /*update in next stmt*/ 1655 fix5 = i; 1656 i++; 1657 1658#ifndef IPPROTO_NONE 1659#define IPPROTO_NONE 59 1660#endif 1661 /* if (A == IPPROTO_NONE) goto end */ 1662 s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 1663 s[i]->s.jt = NULL; /*later*/ 1664 s[i]->s.jf = NULL; /*update in next stmt*/ 1665 s[i]->s.k = IPPROTO_NONE; 1666 s[fix5]->s.jf = s[i]; 1667 fix2 = i; 1668 i++; 1669 1670#ifdef INET6 1671 if (proto == Q_IPV6) { 1672 int v6start, v6end, v6advance, j; 1673 1674 v6start = i; 1675 /* if (A == IPPROTO_HOPOPTS) goto v6advance */ 1676 s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 1677 s[i]->s.jt = NULL; /*later*/ 1678 s[i]->s.jf = NULL; /*update in next stmt*/ 1679 s[i]->s.k = IPPROTO_HOPOPTS; 1680 s[fix2]->s.jf = s[i]; 1681 i++; 1682 /* if (A == IPPROTO_DSTOPTS) goto v6advance */ 1683 s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 1684 s[i]->s.jt = NULL; /*later*/ 1685 s[i]->s.jf = NULL; /*update in next stmt*/ 1686 s[i]->s.k = IPPROTO_DSTOPTS; 1687 i++; 1688 /* if (A == IPPROTO_ROUTING) goto v6advance */ 1689 s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 1690 s[i]->s.jt = NULL; /*later*/ 1691 s[i]->s.jf = NULL; /*update in next stmt*/ 1692 s[i]->s.k = IPPROTO_ROUTING; 1693 i++; 1694 /* if (A == IPPROTO_FRAGMENT) goto v6advance; else goto ahcheck; */ 1695 s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 1696 s[i]->s.jt = NULL; /*later*/ 1697 s[i]->s.jf = NULL; /*later*/ 1698 s[i]->s.k = IPPROTO_FRAGMENT; 1699 fix3 = i; 1700 v6end = i; 1701 i++; 1702 1703 /* v6advance: */ 1704 v6advance = i; 1705 1706 /* 1707 * in short, 1708 * A = P[X + 1]; 1709 * X = X + (P[X] + 1) * 8; 1710 */ 1711 /* A = X */ 1712 s[i] = new_stmt(BPF_MISC|BPF_TXA); 1713 i++; 1714 /* MEM[reg1] = A */ 1715 s[i] = new_stmt(BPF_ST); 1716 s[i]->s.k = reg1; 1717 i++; 1718 /* A += 1 */ 1719 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 1720 s[i]->s.k = 1; 1721 i++; 1722 /* X = A */ 1723 s[i] = new_stmt(BPF_MISC|BPF_TAX); 1724 i++; 1725 /* A = P[X + packet head]; */ 1726 s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); 1727 s[i]->s.k = off_nl; 1728 i++; 1729 /* MEM[reg2] = A */ 1730 s[i] = new_stmt(BPF_ST); 1731 s[i]->s.k = reg2; 1732 i++; 1733 /* X = MEM[reg1] */ 1734 s[i] = new_stmt(BPF_LDX|BPF_MEM); 1735 s[i]->s.k = reg1; 1736 i++; 1737 /* A = P[X + packet head] */ 1738 s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); 1739 s[i]->s.k = off_nl; 1740 i++; 1741 /* A += 1 */ 1742 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 1743 s[i]->s.k = 1; 1744 i++; 1745 /* A *= 8 */ 1746 s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K); 1747 s[i]->s.k = 8; 1748 i++; 1749 /* X = A; */ 1750 s[i] = new_stmt(BPF_MISC|BPF_TAX); 1751 i++; 1752 /* A = MEM[reg2] */ 1753 s[i] = new_stmt(BPF_LD|BPF_MEM); 1754 s[i]->s.k = reg2; 1755 i++; 1756 1757 /* goto again; (must use BPF_JA for backward jump) */ 1758 s[i] = new_stmt(BPF_JMP|BPF_JA); 1759 s[i]->s.k = again - i - 1; 1760 s[i - 1]->s.jf = s[i]; 1761 i++; 1762 1763 /* fixup */ 1764 for (j = v6start; j <= v6end; j++) 1765 s[j]->s.jt = s[v6advance]; 1766 } else 1767#endif 1768 { 1769 /* nop */ 1770 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 1771 s[i]->s.k = 0; 1772 s[fix2]->s.jf = s[i]; 1773 i++; 1774 } 1775 1776 /* ahcheck: */ 1777 ahcheck = i; 1778 /* if (A == IPPROTO_AH) then fall through; else goto end; */ 1779 s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 1780 s[i]->s.jt = NULL; /*later*/ 1781 s[i]->s.jf = NULL; /*later*/ 1782 s[i]->s.k = IPPROTO_AH; 1783 if (fix3) 1784 s[fix3]->s.jf = s[ahcheck]; 1785 fix4 = i; 1786 i++; 1787 1788 /* 1789 * in short, 1790 * A = P[X + 1]; 1791 * X = X + (P[X] + 2) * 4; 1792 */ 1793 /* A = X */ 1794 s[i - 1]->s.jt = s[i] = new_stmt(BPF_MISC|BPF_TXA); 1795 i++; 1796 /* MEM[reg1] = A */ 1797 s[i] = new_stmt(BPF_ST); 1798 s[i]->s.k = reg1; 1799 i++; 1800 /* A += 1 */ 1801 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 1802 s[i]->s.k = 1; 1803 i++; 1804 /* X = A */ 1805 s[i] = new_stmt(BPF_MISC|BPF_TAX); 1806 i++; 1807 /* A = P[X + packet head]; */ 1808 s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); 1809 s[i]->s.k = off_nl; 1810 i++; 1811 /* MEM[reg2] = A */ 1812 s[i] = new_stmt(BPF_ST); 1813 s[i]->s.k = reg2; 1814 i++; 1815 /* X = MEM[reg1] */ 1816 s[i] = new_stmt(BPF_LDX|BPF_MEM); 1817 s[i]->s.k = reg1; 1818 i++; 1819 /* A = P[X + packet head] */ 1820 s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); 1821 s[i]->s.k = off_nl; 1822 i++; 1823 /* A += 2 */ 1824 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 1825 s[i]->s.k = 2; 1826 i++; 1827 /* A *= 4 */ 1828 s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K); 1829 s[i]->s.k = 4; 1830 i++; 1831 /* X = A; */ 1832 s[i] = new_stmt(BPF_MISC|BPF_TAX); 1833 i++; 1834 /* A = MEM[reg2] */ 1835 s[i] = new_stmt(BPF_LD|BPF_MEM); 1836 s[i]->s.k = reg2; 1837 i++; 1838 1839 /* goto again; (must use BPF_JA for backward jump) */ 1840 s[i] = new_stmt(BPF_JMP|BPF_JA); 1841 s[i]->s.k = again - i - 1; 1842 i++; 1843 1844 /* end: nop */ 1845 end = i; 1846 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 1847 s[i]->s.k = 0; 1848 s[fix2]->s.jt = s[end]; 1849 s[fix4]->s.jf = s[end]; 1850 s[fix5]->s.jt = s[end]; 1851 i++; 1852 1853 /* 1854 * make slist chain 1855 */ 1856 max = i; 1857 for (i = 0; i < max - 1; i++) 1858 s[i]->next = s[i + 1]; 1859 s[max - 1]->next = NULL; 1860 1861 /* 1862 * emit final check 1863 */ 1864 b = new_block(JMP(BPF_JEQ)); 1865 b->stmts = s[1]; /*remember, s[0] is dummy*/ 1866 b->s.k = v; 1867 1868 free_reg(reg1); 1869 free_reg(reg2); 1870 1871 gen_and(b0, b); 1872 return b; 1873#endif 1874} 1875
|
1192static struct block * 1193gen_proto(v, proto, dir) 1194 int v; 1195 int proto; 1196 int dir; 1197{ 1198 struct block *b0, *b1; 1199 1200 if (dir != Q_DEFAULT) 1201 bpf_error("direction applied to 'proto'"); 1202 1203 switch (proto) { 1204 case Q_DEFAULT:
| 1876static struct block * 1877gen_proto(v, proto, dir) 1878 int v; 1879 int proto; 1880 int dir; 1881{ 1882 struct block *b0, *b1; 1883 1884 if (dir != Q_DEFAULT) 1885 bpf_error("direction applied to 'proto'"); 1886 1887 switch (proto) { 1888 case Q_DEFAULT:
|
| 1889#ifdef INET6 1890 b0 = gen_proto(v, Q_IP, dir); 1891 b1 = gen_proto(v, Q_IPV6, dir); 1892 gen_or(b0, b1); 1893 return b1; 1894#else 1895 /*FALLTHROUGH*/ 1896#endif
|
1205 case Q_IP: 1206 b0 = gen_linktype(ETHERTYPE_IP);
| 1897 case Q_IP: 1898 b0 = gen_linktype(ETHERTYPE_IP);
|
| 1899#ifndef CHASE_CHAIN
|
1207 b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)v);
| 1900 b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)v);
|
| 1901#else 1902 b1 = gen_protochain(v, Q_IP); 1903#endif
|
1208 gen_and(b0, b1); 1209 return b1; 1210 1211 case Q_ISO: 1212 b0 = gen_linktype(LLC_ISO_LSAP); 1213 b1 = gen_cmp(off_nl + 3, BPF_B, (long)v); 1214 gen_and(b0, b1); 1215 return b1; 1216 1217 case Q_ARP: 1218 bpf_error("arp does not encapsulate another protocol"); 1219 /* NOTREACHED */ 1220 1221 case Q_RARP: 1222 bpf_error("rarp does not encapsulate another protocol"); 1223 /* NOTREACHED */ 1224 1225 case Q_ATALK: 1226 bpf_error("atalk encapsulation is not specifiable"); 1227 /* NOTREACHED */ 1228 1229 case Q_DECNET: 1230 bpf_error("decnet encapsulation is not specifiable"); 1231 /* NOTREACHED */ 1232 1233 case Q_SCA: 1234 bpf_error("sca does not encapsulate another protocol"); 1235 /* NOTREACHED */ 1236 1237 case Q_LAT: 1238 bpf_error("lat does not encapsulate another protocol"); 1239 /* NOTREACHED */ 1240 1241 case Q_MOPRC: 1242 bpf_error("moprc does not encapsulate another protocol"); 1243 /* NOTREACHED */ 1244 1245 case Q_MOPDL: 1246 bpf_error("mopdl does not encapsulate another protocol"); 1247 /* NOTREACHED */ 1248 1249 case Q_LINK: 1250 return gen_linktype(v); 1251 1252 case Q_UDP: 1253 bpf_error("'udp proto' is bogus"); 1254 /* NOTREACHED */ 1255 1256 case Q_TCP: 1257 bpf_error("'tcp proto' is bogus"); 1258 /* NOTREACHED */ 1259 1260 case Q_ICMP: 1261 bpf_error("'icmp proto' is bogus"); 1262 /* NOTREACHED */ 1263 1264 case Q_IGMP: 1265 bpf_error("'igmp proto' is bogus"); 1266 /* NOTREACHED */ 1267 1268 case Q_IGRP: 1269 bpf_error("'igrp proto' is bogus"); 1270 /* NOTREACHED */ 1271
| 1904 gen_and(b0, b1); 1905 return b1; 1906 1907 case Q_ISO: 1908 b0 = gen_linktype(LLC_ISO_LSAP); 1909 b1 = gen_cmp(off_nl + 3, BPF_B, (long)v); 1910 gen_and(b0, b1); 1911 return b1; 1912 1913 case Q_ARP: 1914 bpf_error("arp does not encapsulate another protocol"); 1915 /* NOTREACHED */ 1916 1917 case Q_RARP: 1918 bpf_error("rarp does not encapsulate another protocol"); 1919 /* NOTREACHED */ 1920 1921 case Q_ATALK: 1922 bpf_error("atalk encapsulation is not specifiable"); 1923 /* NOTREACHED */ 1924 1925 case Q_DECNET: 1926 bpf_error("decnet encapsulation is not specifiable"); 1927 /* NOTREACHED */ 1928 1929 case Q_SCA: 1930 bpf_error("sca does not encapsulate another protocol"); 1931 /* NOTREACHED */ 1932 1933 case Q_LAT: 1934 bpf_error("lat does not encapsulate another protocol"); 1935 /* NOTREACHED */ 1936 1937 case Q_MOPRC: 1938 bpf_error("moprc does not encapsulate another protocol"); 1939 /* NOTREACHED */ 1940 1941 case Q_MOPDL: 1942 bpf_error("mopdl does not encapsulate another protocol"); 1943 /* NOTREACHED */ 1944 1945 case Q_LINK: 1946 return gen_linktype(v); 1947 1948 case Q_UDP: 1949 bpf_error("'udp proto' is bogus"); 1950 /* NOTREACHED */ 1951 1952 case Q_TCP: 1953 bpf_error("'tcp proto' is bogus"); 1954 /* NOTREACHED */ 1955 1956 case Q_ICMP: 1957 bpf_error("'icmp proto' is bogus"); 1958 /* NOTREACHED */ 1959 1960 case Q_IGMP: 1961 bpf_error("'igmp proto' is bogus"); 1962 /* NOTREACHED */ 1963 1964 case Q_IGRP: 1965 bpf_error("'igrp proto' is bogus"); 1966 /* NOTREACHED */ 1967
|
| 1968 case Q_PIM: 1969 bpf_error("'pim proto' is bogus"); 1970 /* NOTREACHED */ 1971 1972#ifdef INET6 1973 case Q_IPV6: 1974 b0 = gen_linktype(ETHERTYPE_IPV6); 1975#ifndef CHASE_CHAIN 1976 b1 = gen_cmp(off_nl + 6, BPF_B, (bpf_int32)v); 1977#else 1978 b1 = gen_protochain(v, Q_IPV6); 1979#endif 1980 gen_and(b0, b1); 1981 return b1; 1982 1983 case Q_ICMPV6: 1984 bpf_error("'icmp6 proto' is bogus"); 1985#endif /* INET6 */ 1986 1987 case Q_AH: 1988 bpf_error("'ah proto' is bogus"); 1989 1990 case Q_ESP: 1991 bpf_error("'ah proto' is bogus"); 1992
|
1272 default: 1273 abort(); 1274 /* NOTREACHED */ 1275 } 1276 /* NOTREACHED */ 1277} 1278 1279struct block * 1280gen_scode(name, q) 1281 register const char *name; 1282 struct qual q; 1283{ 1284 int proto = q.proto; 1285 int dir = q.dir; 1286 int tproto; 1287 u_char *eaddr; 1288 bpf_u_int32 mask, addr, **alist;
| 1993 default: 1994 abort(); 1995 /* NOTREACHED */ 1996 } 1997 /* NOTREACHED */ 1998} 1999 2000struct block * 2001gen_scode(name, q) 2002 register const char *name; 2003 struct qual q; 2004{ 2005 int proto = q.proto; 2006 int dir = q.dir; 2007 int tproto; 2008 u_char *eaddr; 2009 bpf_u_int32 mask, addr, **alist;
|
| 2010#ifdef INET6 2011 int tproto6; 2012 struct sockaddr_in *sin; 2013 struct sockaddr_in6 *sin6; 2014 struct addrinfo *res, *res0; 2015 struct in6_addr mask128; 2016#endif /*INET6*/
|
1289 struct block *b, *tmp; 1290 int port, real_proto; 1291 1292 switch (q.addr) { 1293 1294 case Q_NET: 1295 addr = pcap_nametonetaddr(name); 1296 if (addr == 0) 1297 bpf_error("unknown network '%s'", name); 1298 /* Left justify network addr and calculate its network mask */ 1299 mask = 0xffffffff; 1300 while (addr && (addr & 0xff000000) == 0) { 1301 addr <<= 8; 1302 mask <<= 8; 1303 } 1304 return gen_host(addr, mask, proto, dir); 1305 1306 case Q_DEFAULT: 1307 case Q_HOST: 1308 if (proto == Q_LINK) { 1309 switch (linktype) { 1310 1311 case DLT_EN10MB: 1312 eaddr = pcap_ether_hostton(name); 1313 if (eaddr == NULL) 1314 bpf_error( 1315 "unknown ether host '%s'", name); 1316 return gen_ehostop(eaddr, dir); 1317 1318 case DLT_FDDI: 1319 eaddr = pcap_ether_hostton(name); 1320 if (eaddr == NULL) 1321 bpf_error( 1322 "unknown FDDI host '%s'", name); 1323 return gen_fhostop(eaddr, dir); 1324 1325 default: 1326 bpf_error( 1327 "only ethernet/FDDI supports link-level host name"); 1328 break; 1329 } 1330 } else if (proto == Q_DECNET) { 1331 unsigned short dn_addr = __pcap_nametodnaddr(name); 1332 /* 1333 * I don't think DECNET hosts can be multihomed, so 1334 * there is no need to build up a list of addresses 1335 */ 1336 return (gen_host(dn_addr, 0, proto, dir)); 1337 } else {
| 2017 struct block *b, *tmp; 2018 int port, real_proto; 2019 2020 switch (q.addr) { 2021 2022 case Q_NET: 2023 addr = pcap_nametonetaddr(name); 2024 if (addr == 0) 2025 bpf_error("unknown network '%s'", name); 2026 /* Left justify network addr and calculate its network mask */ 2027 mask = 0xffffffff; 2028 while (addr && (addr & 0xff000000) == 0) { 2029 addr <<= 8; 2030 mask <<= 8; 2031 } 2032 return gen_host(addr, mask, proto, dir); 2033 2034 case Q_DEFAULT: 2035 case Q_HOST: 2036 if (proto == Q_LINK) { 2037 switch (linktype) { 2038 2039 case DLT_EN10MB: 2040 eaddr = pcap_ether_hostton(name); 2041 if (eaddr == NULL) 2042 bpf_error( 2043 "unknown ether host '%s'", name); 2044 return gen_ehostop(eaddr, dir); 2045 2046 case DLT_FDDI: 2047 eaddr = pcap_ether_hostton(name); 2048 if (eaddr == NULL) 2049 bpf_error( 2050 "unknown FDDI host '%s'", name); 2051 return gen_fhostop(eaddr, dir); 2052 2053 default: 2054 bpf_error( 2055 "only ethernet/FDDI supports link-level host name"); 2056 break; 2057 } 2058 } else if (proto == Q_DECNET) { 2059 unsigned short dn_addr = __pcap_nametodnaddr(name); 2060 /* 2061 * I don't think DECNET hosts can be multihomed, so 2062 * there is no need to build up a list of addresses 2063 */ 2064 return (gen_host(dn_addr, 0, proto, dir)); 2065 } else {
|
| 2066#ifndef INET6
|
1338 alist = pcap_nametoaddr(name); 1339 if (alist == NULL || *alist == NULL) 1340 bpf_error("unknown host '%s'", name); 1341 tproto = proto; 1342 if (off_linktype == -1 && tproto == Q_DEFAULT) 1343 tproto = Q_IP; 1344 b = gen_host(**alist++, 0xffffffff, tproto, dir); 1345 while (*alist) { 1346 tmp = gen_host(**alist++, 0xffffffff, 1347 tproto, dir); 1348 gen_or(b, tmp); 1349 b = tmp; 1350 } 1351 return b;
| 2067 alist = pcap_nametoaddr(name); 2068 if (alist == NULL || *alist == NULL) 2069 bpf_error("unknown host '%s'", name); 2070 tproto = proto; 2071 if (off_linktype == -1 && tproto == Q_DEFAULT) 2072 tproto = Q_IP; 2073 b = gen_host(**alist++, 0xffffffff, tproto, dir); 2074 while (*alist) { 2075 tmp = gen_host(**alist++, 0xffffffff, 2076 tproto, dir); 2077 gen_or(b, tmp); 2078 b = tmp; 2079 } 2080 return b;
|
| 2081#else 2082 memset(&mask128, 0xff, sizeof(mask128)); 2083 res0 = res = pcap_nametoaddr(name); 2084 if (res == NULL) 2085 bpf_error("unknown host '%s'", name); 2086 b = tmp = NULL; 2087 tproto = tproto6 = proto; 2088 if (off_linktype == -1 && tproto == Q_DEFAULT) { 2089 tproto = Q_IP; 2090 tproto6 = Q_IPV6; 2091 } 2092 while (res) { 2093 switch (res->ai_family) { 2094 case AF_INET: 2095 sin = (struct sockaddr_in *) 2096 res->ai_addr; 2097 tmp = gen_host(ntohl(sin->sin_addr.s_addr), 2098 0xffffffff, tproto, dir); 2099 break; 2100 case AF_INET6: 2101 sin6 = (struct sockaddr_in6 *) 2102 res->ai_addr; 2103 tmp = gen_host6(&sin6->sin6_addr, 2104 &mask128, tproto6, dir); 2105 break; 2106 } 2107 if (b) 2108 gen_or(b, tmp); 2109 b = tmp; 2110 2111 res = res->ai_next; 2112 } 2113 freeaddrinfo(res0); 2114 return b; 2115#endif /*INET6*/
|
1352 } 1353 1354 case Q_PORT: 1355 if (proto != Q_DEFAULT && proto != Q_UDP && proto != Q_TCP) 1356 bpf_error("illegal qualifier of 'port'"); 1357 if (pcap_nametoport(name, &port, &real_proto) == 0) 1358 bpf_error("unknown port '%s'", name); 1359 if (proto == Q_UDP) { 1360 if (real_proto == IPPROTO_TCP) 1361 bpf_error("port '%s' is tcp", name); 1362 else 1363 /* override PROTO_UNDEF */ 1364 real_proto = IPPROTO_UDP; 1365 } 1366 if (proto == Q_TCP) { 1367 if (real_proto == IPPROTO_UDP) 1368 bpf_error("port '%s' is udp", name); 1369 else 1370 /* override PROTO_UNDEF */ 1371 real_proto = IPPROTO_TCP; 1372 }
| 2116 } 2117 2118 case Q_PORT: 2119 if (proto != Q_DEFAULT && proto != Q_UDP && proto != Q_TCP) 2120 bpf_error("illegal qualifier of 'port'"); 2121 if (pcap_nametoport(name, &port, &real_proto) == 0) 2122 bpf_error("unknown port '%s'", name); 2123 if (proto == Q_UDP) { 2124 if (real_proto == IPPROTO_TCP) 2125 bpf_error("port '%s' is tcp", name); 2126 else 2127 /* override PROTO_UNDEF */ 2128 real_proto = IPPROTO_UDP; 2129 } 2130 if (proto == Q_TCP) { 2131 if (real_proto == IPPROTO_UDP) 2132 bpf_error("port '%s' is udp", name); 2133 else 2134 /* override PROTO_UNDEF */ 2135 real_proto = IPPROTO_TCP; 2136 }
|
| 2137#ifndef INET6
|
1373 return gen_port(port, real_proto, dir);
| 2138 return gen_port(port, real_proto, dir);
|
| 2139#else 2140 { 2141 struct block *b; 2142 b = gen_port(port, real_proto, dir); 2143 gen_or(gen_port6(port, real_proto, dir), b); 2144 return b; 2145 } 2146#endif /* INET6 */
|
1374 1375 case Q_GATEWAY:
| 2147 2148 case Q_GATEWAY:
|
| 2149#ifndef INET6
|
1376 eaddr = pcap_ether_hostton(name); 1377 if (eaddr == NULL) 1378 bpf_error("unknown ether host: %s", name); 1379 1380 alist = pcap_nametoaddr(name); 1381 if (alist == NULL || *alist == NULL) 1382 bpf_error("unknown host '%s'", name); 1383 return gen_gateway(eaddr, alist, proto, dir);
| 2150 eaddr = pcap_ether_hostton(name); 2151 if (eaddr == NULL) 2152 bpf_error("unknown ether host: %s", name); 2153 2154 alist = pcap_nametoaddr(name); 2155 if (alist == NULL || *alist == NULL) 2156 bpf_error("unknown host '%s'", name); 2157 return gen_gateway(eaddr, alist, proto, dir);
|
| 2158#else 2159 bpf_error("'gateway' not supported in this configuration"); 2160#endif /*INET6*/
|
1384 1385 case Q_PROTO: 1386 real_proto = lookup_proto(name, proto); 1387 if (real_proto >= 0) 1388 return gen_proto(real_proto, proto, dir); 1389 else 1390 bpf_error("unknown protocol: %s", name); 1391
| 2161 2162 case Q_PROTO: 2163 real_proto = lookup_proto(name, proto); 2164 if (real_proto >= 0) 2165 return gen_proto(real_proto, proto, dir); 2166 else 2167 bpf_error("unknown protocol: %s", name); 2168
|
| 2169 case Q_PROTOCHAIN: 2170 real_proto = lookup_proto(name, proto); 2171 if (real_proto >= 0) 2172 return gen_protochain(real_proto, proto, dir); 2173 else 2174 bpf_error("unknown protocol: %s", name); 2175 2176
|
1392 case Q_UNDEF: 1393 syntax(); 1394 /* NOTREACHED */ 1395 } 1396 abort(); 1397 /* NOTREACHED */ 1398} 1399 1400struct block * 1401gen_mcode(s1, s2, masklen, q) 1402 register const char *s1, *s2; 1403 register int masklen; 1404 struct qual q; 1405{ 1406 register int nlen, mlen; 1407 bpf_u_int32 n, m; 1408 1409 nlen = __pcap_atoin(s1, &n); 1410 /* Promote short ipaddr */ 1411 n <<= 32 - nlen; 1412 1413 if (s2 != NULL) { 1414 mlen = __pcap_atoin(s2, &m); 1415 /* Promote short ipaddr */ 1416 m <<= 32 - mlen; 1417 if ((n & ~m) != 0) 1418 bpf_error("non-network bits set in \"%s mask %s\"", 1419 s1, s2); 1420 } else { 1421 /* Convert mask len to mask */ 1422 if (masklen > 32) 1423 bpf_error("mask length must be <= 32"); 1424 m = 0xffffffff << (32 - masklen); 1425 if ((n & ~m) != 0) 1426 bpf_error("non-network bits set in \"%s/%d\"", 1427 s1, masklen); 1428 } 1429 1430 switch (q.addr) { 1431 1432 case Q_NET: 1433 return gen_host(n, m, q.proto, q.dir); 1434 1435 default: 1436 bpf_error("Mask syntax for networks only"); 1437 /* NOTREACHED */ 1438 } 1439} 1440 1441struct block * 1442gen_ncode(s, v, q) 1443 register const char *s; 1444 bpf_u_int32 v; 1445 struct qual q; 1446{ 1447 bpf_u_int32 mask; 1448 int proto = q.proto; 1449 int dir = q.dir; 1450 register int vlen; 1451 1452 if (s == NULL) 1453 vlen = 32; 1454 else if (q.proto == Q_DECNET) 1455 vlen = __pcap_atodn(s, &v); 1456 else 1457 vlen = __pcap_atoin(s, &v); 1458 1459 switch (q.addr) { 1460 1461 case Q_DEFAULT: 1462 case Q_HOST: 1463 case Q_NET: 1464 if (proto == Q_DECNET) 1465 return gen_host(v, 0, proto, dir); 1466 else if (proto == Q_LINK) { 1467 bpf_error("illegal link layer address"); 1468 } else { 1469 mask = 0xffffffff; 1470 if (s == NULL && q.addr == Q_NET) { 1471 /* Promote short net number */ 1472 while (v && (v & 0xff000000) == 0) { 1473 v <<= 8; 1474 mask <<= 8; 1475 } 1476 } else { 1477 /* Promote short ipaddr */ 1478 v <<= 32 - vlen; 1479 mask <<= 32 - vlen; 1480 } 1481 return gen_host(v, mask, proto, dir); 1482 } 1483 1484 case Q_PORT: 1485 if (proto == Q_UDP) 1486 proto = IPPROTO_UDP; 1487 else if (proto == Q_TCP) 1488 proto = IPPROTO_TCP; 1489 else if (proto == Q_DEFAULT) 1490 proto = PROTO_UNDEF; 1491 else 1492 bpf_error("illegal qualifier of 'port'"); 1493
| 2177 case Q_UNDEF: 2178 syntax(); 2179 /* NOTREACHED */ 2180 } 2181 abort(); 2182 /* NOTREACHED */ 2183} 2184 2185struct block * 2186gen_mcode(s1, s2, masklen, q) 2187 register const char *s1, *s2; 2188 register int masklen; 2189 struct qual q; 2190{ 2191 register int nlen, mlen; 2192 bpf_u_int32 n, m; 2193 2194 nlen = __pcap_atoin(s1, &n); 2195 /* Promote short ipaddr */ 2196 n <<= 32 - nlen; 2197 2198 if (s2 != NULL) { 2199 mlen = __pcap_atoin(s2, &m); 2200 /* Promote short ipaddr */ 2201 m <<= 32 - mlen; 2202 if ((n & ~m) != 0) 2203 bpf_error("non-network bits set in \"%s mask %s\"", 2204 s1, s2); 2205 } else { 2206 /* Convert mask len to mask */ 2207 if (masklen > 32) 2208 bpf_error("mask length must be <= 32"); 2209 m = 0xffffffff << (32 - masklen); 2210 if ((n & ~m) != 0) 2211 bpf_error("non-network bits set in \"%s/%d\"", 2212 s1, masklen); 2213 } 2214 2215 switch (q.addr) { 2216 2217 case Q_NET: 2218 return gen_host(n, m, q.proto, q.dir); 2219 2220 default: 2221 bpf_error("Mask syntax for networks only"); 2222 /* NOTREACHED */ 2223 } 2224} 2225 2226struct block * 2227gen_ncode(s, v, q) 2228 register const char *s; 2229 bpf_u_int32 v; 2230 struct qual q; 2231{ 2232 bpf_u_int32 mask; 2233 int proto = q.proto; 2234 int dir = q.dir; 2235 register int vlen; 2236 2237 if (s == NULL) 2238 vlen = 32; 2239 else if (q.proto == Q_DECNET) 2240 vlen = __pcap_atodn(s, &v); 2241 else 2242 vlen = __pcap_atoin(s, &v); 2243 2244 switch (q.addr) { 2245 2246 case Q_DEFAULT: 2247 case Q_HOST: 2248 case Q_NET: 2249 if (proto == Q_DECNET) 2250 return gen_host(v, 0, proto, dir); 2251 else if (proto == Q_LINK) { 2252 bpf_error("illegal link layer address"); 2253 } else { 2254 mask = 0xffffffff; 2255 if (s == NULL && q.addr == Q_NET) { 2256 /* Promote short net number */ 2257 while (v && (v & 0xff000000) == 0) { 2258 v <<= 8; 2259 mask <<= 8; 2260 } 2261 } else { 2262 /* Promote short ipaddr */ 2263 v <<= 32 - vlen; 2264 mask <<= 32 - vlen; 2265 } 2266 return gen_host(v, mask, proto, dir); 2267 } 2268 2269 case Q_PORT: 2270 if (proto == Q_UDP) 2271 proto = IPPROTO_UDP; 2272 else if (proto == Q_TCP) 2273 proto = IPPROTO_TCP; 2274 else if (proto == Q_DEFAULT) 2275 proto = PROTO_UNDEF; 2276 else 2277 bpf_error("illegal qualifier of 'port'"); 2278
|
| 2279#ifndef INET6
|
1494 return gen_port((int)v, proto, dir);
| 2280 return gen_port((int)v, proto, dir);
|
| 2281#else 2282 { 2283 struct block *b; 2284 b = gen_port((int)v, proto, dir); 2285 gen_or(gen_port6((int)v, proto, dir), b); 2286 return b; 2287 } 2288#endif /* INET6 */
|
1495 1496 case Q_GATEWAY: 1497 bpf_error("'gateway' requires a name"); 1498 /* NOTREACHED */ 1499 1500 case Q_PROTO: 1501 return gen_proto((int)v, proto, dir); 1502
| 2289 2290 case Q_GATEWAY: 2291 bpf_error("'gateway' requires a name"); 2292 /* NOTREACHED */ 2293 2294 case Q_PROTO: 2295 return gen_proto((int)v, proto, dir); 2296
|
| 2297 case Q_PROTOCHAIN: 2298 return gen_protochain((int)v, proto, dir); 2299
|
1503 case Q_UNDEF: 1504 syntax(); 1505 /* NOTREACHED */ 1506 1507 default: 1508 abort(); 1509 /* NOTREACHED */ 1510 } 1511 /* NOTREACHED */ 1512} 1513
| 2300 case Q_UNDEF: 2301 syntax(); 2302 /* NOTREACHED */ 2303 2304 default: 2305 abort(); 2306 /* NOTREACHED */ 2307 } 2308 /* NOTREACHED */ 2309} 2310
|
| 2311#ifdef INET6
|
1514struct block *
| 2312struct block *
|
| 2313gen_mcode6(s1, s2, masklen, q) 2314 register const char *s1, *s2; 2315 register int masklen; 2316 struct qual q; 2317{ 2318 struct addrinfo *res; 2319 struct in6_addr *addr; 2320 struct in6_addr mask; 2321 struct block *b; 2322 u_int32_t *a, *m; 2323 2324 if (s2) 2325 bpf_error("no mask %s supported", s2); 2326 2327 res = pcap_nametoaddr(s1); 2328 if (!res) 2329 bpf_error("invalid ip6 address %s", s1); 2330 if (res->ai_next) 2331 bpf_error("%s resolved to multiple address", s1); 2332 addr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; 2333 2334 if (sizeof(mask) * 8 < masklen) 2335 bpf_error("mask length must be <= %u", (unsigned int)(sizeof(mask) * 8)); 2336 memset(&mask, 0xff, masklen / 8); 2337 if (masklen % 8) { 2338 mask.s6_addr[masklen / 8] = 2339 (0xff << (8 - masklen % 8)) & 0xff; 2340 } 2341 2342 a = (u_int32_t *)addr; 2343 m = (u_int32_t *)&mask; 2344 if ((a[0] & ~m[0]) || (a[1] & ~m[1]) 2345 || (a[2] & ~m[2]) || (a[3] & ~m[3])) { 2346 bpf_error("non-network bits set in \"%s/%d\"", s1, masklen); 2347 } 2348 2349 switch (q.addr) { 2350 2351 case Q_DEFAULT: 2352 case Q_HOST: 2353 if (masklen != 128) 2354 bpf_error("Mask syntax for networks only"); 2355 /* FALLTHROUGH */ 2356 2357 case Q_NET: 2358 b = gen_host6(addr, &mask, q.proto, q.dir); 2359 freeaddrinfo(res); 2360 return b; 2361 2362 default: 2363 bpf_error("invalid qualifier against IPv6 address"); 2364 /* NOTREACHED */ 2365 } 2366} 2367#endif /*INET6*/ 2368 2369struct block *
|
1515gen_ecode(eaddr, q) 1516 register const u_char *eaddr; 1517 struct qual q; 1518{ 1519 if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) { 1520 if (linktype == DLT_EN10MB) 1521 return gen_ehostop(eaddr, (int)q.dir); 1522 if (linktype == DLT_FDDI) 1523 return gen_fhostop(eaddr, (int)q.dir); 1524 } 1525 bpf_error("ethernet address used in non-ether expression"); 1526 /* NOTREACHED */ 1527} 1528 1529void 1530sappend(s0, s1) 1531 struct slist *s0, *s1; 1532{ 1533 /* 1534 * This is definitely not the best way to do this, but the 1535 * lists will rarely get long. 1536 */ 1537 while (s0->next) 1538 s0 = s0->next; 1539 s0->next = s1; 1540} 1541 1542static struct slist * 1543xfer_to_x(a) 1544 struct arth *a; 1545{ 1546 struct slist *s; 1547 1548 s = new_stmt(BPF_LDX|BPF_MEM); 1549 s->s.k = a->regno; 1550 return s; 1551} 1552 1553static struct slist * 1554xfer_to_a(a) 1555 struct arth *a; 1556{ 1557 struct slist *s; 1558 1559 s = new_stmt(BPF_LD|BPF_MEM); 1560 s->s.k = a->regno; 1561 return s; 1562} 1563 1564struct arth * 1565gen_load(proto, index, size) 1566 int proto; 1567 struct arth *index; 1568 int size; 1569{ 1570 struct slist *s, *tmp; 1571 struct block *b; 1572 int regno = alloc_reg(); 1573 1574 free_reg(index->regno); 1575 switch (size) { 1576 1577 default: 1578 bpf_error("data size must be 1, 2, or 4"); 1579 1580 case 1: 1581 size = BPF_B; 1582 break; 1583 1584 case 2: 1585 size = BPF_H; 1586 break; 1587 1588 case 4: 1589 size = BPF_W; 1590 break; 1591 } 1592 switch (proto) { 1593 default: 1594 bpf_error("unsupported index operation"); 1595 1596 case Q_LINK: 1597 s = xfer_to_x(index); 1598 tmp = new_stmt(BPF_LD|BPF_IND|size); 1599 sappend(s, tmp); 1600 sappend(index->s, s); 1601 break; 1602 1603 case Q_IP: 1604 case Q_ARP: 1605 case Q_RARP: 1606 case Q_ATALK: 1607 case Q_DECNET: 1608 case Q_SCA: 1609 case Q_LAT: 1610 case Q_MOPRC: 1611 case Q_MOPDL:
| 2370gen_ecode(eaddr, q) 2371 register const u_char *eaddr; 2372 struct qual q; 2373{ 2374 if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) { 2375 if (linktype == DLT_EN10MB) 2376 return gen_ehostop(eaddr, (int)q.dir); 2377 if (linktype == DLT_FDDI) 2378 return gen_fhostop(eaddr, (int)q.dir); 2379 } 2380 bpf_error("ethernet address used in non-ether expression"); 2381 /* NOTREACHED */ 2382} 2383 2384void 2385sappend(s0, s1) 2386 struct slist *s0, *s1; 2387{ 2388 /* 2389 * This is definitely not the best way to do this, but the 2390 * lists will rarely get long. 2391 */ 2392 while (s0->next) 2393 s0 = s0->next; 2394 s0->next = s1; 2395} 2396 2397static struct slist * 2398xfer_to_x(a) 2399 struct arth *a; 2400{ 2401 struct slist *s; 2402 2403 s = new_stmt(BPF_LDX|BPF_MEM); 2404 s->s.k = a->regno; 2405 return s; 2406} 2407 2408static struct slist * 2409xfer_to_a(a) 2410 struct arth *a; 2411{ 2412 struct slist *s; 2413 2414 s = new_stmt(BPF_LD|BPF_MEM); 2415 s->s.k = a->regno; 2416 return s; 2417} 2418 2419struct arth * 2420gen_load(proto, index, size) 2421 int proto; 2422 struct arth *index; 2423 int size; 2424{ 2425 struct slist *s, *tmp; 2426 struct block *b; 2427 int regno = alloc_reg(); 2428 2429 free_reg(index->regno); 2430 switch (size) { 2431 2432 default: 2433 bpf_error("data size must be 1, 2, or 4"); 2434 2435 case 1: 2436 size = BPF_B; 2437 break; 2438 2439 case 2: 2440 size = BPF_H; 2441 break; 2442 2443 case 4: 2444 size = BPF_W; 2445 break; 2446 } 2447 switch (proto) { 2448 default: 2449 bpf_error("unsupported index operation"); 2450 2451 case Q_LINK: 2452 s = xfer_to_x(index); 2453 tmp = new_stmt(BPF_LD|BPF_IND|size); 2454 sappend(s, tmp); 2455 sappend(index->s, s); 2456 break; 2457 2458 case Q_IP: 2459 case Q_ARP: 2460 case Q_RARP: 2461 case Q_ATALK: 2462 case Q_DECNET: 2463 case Q_SCA: 2464 case Q_LAT: 2465 case Q_MOPRC: 2466 case Q_MOPDL:
|
| 2467#ifdef INET6 2468 case Q_IPV6: 2469#endif
|
1612 /* XXX Note that we assume a fixed link header here. */ 1613 s = xfer_to_x(index); 1614 tmp = new_stmt(BPF_LD|BPF_IND|size); 1615 tmp->s.k = off_nl; 1616 sappend(s, tmp); 1617 sappend(index->s, s); 1618 1619 b = gen_proto_abbrev(proto); 1620 if (index->b) 1621 gen_and(index->b, b); 1622 index->b = b; 1623 break; 1624 1625 case Q_TCP: 1626 case Q_UDP: 1627 case Q_ICMP: 1628 case Q_IGMP: 1629 case Q_IGRP:
| 2470 /* XXX Note that we assume a fixed link header here. */ 2471 s = xfer_to_x(index); 2472 tmp = new_stmt(BPF_LD|BPF_IND|size); 2473 tmp->s.k = off_nl; 2474 sappend(s, tmp); 2475 sappend(index->s, s); 2476 2477 b = gen_proto_abbrev(proto); 2478 if (index->b) 2479 gen_and(index->b, b); 2480 index->b = b; 2481 break; 2482 2483 case Q_TCP: 2484 case Q_UDP: 2485 case Q_ICMP: 2486 case Q_IGMP: 2487 case Q_IGRP:
|
| 2488 case Q_PIM:
|
1630 s = new_stmt(BPF_LDX|BPF_MSH|BPF_B); 1631 s->s.k = off_nl; 1632 sappend(s, xfer_to_a(index)); 1633 sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); 1634 sappend(s, new_stmt(BPF_MISC|BPF_TAX)); 1635 sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size)); 1636 tmp->s.k = off_nl; 1637 sappend(index->s, s); 1638 1639 gen_and(gen_proto_abbrev(proto), b = gen_ipfrag()); 1640 if (index->b) 1641 gen_and(index->b, b);
| 2489 s = new_stmt(BPF_LDX|BPF_MSH|BPF_B); 2490 s->s.k = off_nl; 2491 sappend(s, xfer_to_a(index)); 2492 sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); 2493 sappend(s, new_stmt(BPF_MISC|BPF_TAX)); 2494 sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size)); 2495 tmp->s.k = off_nl; 2496 sappend(index->s, s); 2497 2498 gen_and(gen_proto_abbrev(proto), b = gen_ipfrag()); 2499 if (index->b) 2500 gen_and(index->b, b);
|
| 2501#ifdef INET6 2502 gen_and(gen_proto_abbrev(Q_IP), b); 2503#endif
|
1642 index->b = b; 1643 break;
| 2504 index->b = b; 2505 break;
|
| 2506#ifdef INET6 2507 case Q_ICMPV6: 2508 bpf_error("IPv6 upper-layer protocol is not supported by proto[x]"); 2509 /*NOTREACHED*/ 2510#endif
|
1644 } 1645 index->regno = regno; 1646 s = new_stmt(BPF_ST); 1647 s->s.k = regno; 1648 sappend(index->s, s); 1649 1650 return index; 1651} 1652 1653struct block * 1654gen_relation(code, a0, a1, reversed) 1655 int code; 1656 struct arth *a0, *a1; 1657 int reversed; 1658{ 1659 struct slist *s0, *s1, *s2; 1660 struct block *b, *tmp; 1661 1662 s0 = xfer_to_x(a1); 1663 s1 = xfer_to_a(a0); 1664 s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X); 1665 b = new_block(JMP(code)); 1666 if (code == BPF_JGT || code == BPF_JGE) { 1667 reversed = !reversed; 1668 b->s.k = 0x80000000; 1669 } 1670 if (reversed) 1671 gen_not(b); 1672 1673 sappend(s1, s2); 1674 sappend(s0, s1); 1675 sappend(a1->s, s0); 1676 sappend(a0->s, a1->s); 1677 1678 b->stmts = a0->s; 1679 1680 free_reg(a0->regno); 1681 free_reg(a1->regno); 1682 1683 /* 'and' together protocol checks */ 1684 if (a0->b) { 1685 if (a1->b) { 1686 gen_and(a0->b, tmp = a1->b); 1687 } 1688 else 1689 tmp = a0->b; 1690 } else 1691 tmp = a1->b; 1692 1693 if (tmp) 1694 gen_and(tmp, b); 1695 1696 return b; 1697} 1698 1699struct arth * 1700gen_loadlen() 1701{ 1702 int regno = alloc_reg(); 1703 struct arth *a = (struct arth *)newchunk(sizeof(*a)); 1704 struct slist *s; 1705 1706 s = new_stmt(BPF_LD|BPF_LEN); 1707 s->next = new_stmt(BPF_ST); 1708 s->next->s.k = regno; 1709 a->s = s; 1710 a->regno = regno; 1711 1712 return a; 1713} 1714 1715struct arth * 1716gen_loadi(val) 1717 int val; 1718{ 1719 struct arth *a; 1720 struct slist *s; 1721 int reg; 1722 1723 a = (struct arth *)newchunk(sizeof(*a)); 1724 1725 reg = alloc_reg(); 1726 1727 s = new_stmt(BPF_LD|BPF_IMM); 1728 s->s.k = val; 1729 s->next = new_stmt(BPF_ST); 1730 s->next->s.k = reg; 1731 a->s = s; 1732 a->regno = reg; 1733 1734 return a; 1735} 1736 1737struct arth * 1738gen_neg(a) 1739 struct arth *a; 1740{ 1741 struct slist *s; 1742 1743 s = xfer_to_a(a); 1744 sappend(a->s, s); 1745 s = new_stmt(BPF_ALU|BPF_NEG); 1746 s->s.k = 0; 1747 sappend(a->s, s); 1748 s = new_stmt(BPF_ST); 1749 s->s.k = a->regno; 1750 sappend(a->s, s); 1751 1752 return a; 1753} 1754 1755struct arth * 1756gen_arth(code, a0, a1) 1757 int code; 1758 struct arth *a0, *a1; 1759{ 1760 struct slist *s0, *s1, *s2; 1761 1762 s0 = xfer_to_x(a1); 1763 s1 = xfer_to_a(a0); 1764 s2 = new_stmt(BPF_ALU|BPF_X|code); 1765 1766 sappend(s1, s2); 1767 sappend(s0, s1); 1768 sappend(a1->s, s0); 1769 sappend(a0->s, a1->s); 1770 1771 free_reg(a1->regno); 1772 1773 s0 = new_stmt(BPF_ST); 1774 a0->regno = s0->s.k = alloc_reg(); 1775 sappend(a0->s, s0); 1776 1777 return a0; 1778} 1779 1780/* 1781 * Here we handle simple allocation of the scratch registers. 1782 * If too many registers are alloc'd, the allocator punts. 1783 */ 1784static int regused[BPF_MEMWORDS]; 1785static int curreg; 1786 1787/* 1788 * Return the next free register. 1789 */ 1790static int 1791alloc_reg() 1792{ 1793 int n = BPF_MEMWORDS; 1794 1795 while (--n >= 0) { 1796 if (regused[curreg]) 1797 curreg = (curreg + 1) % BPF_MEMWORDS; 1798 else { 1799 regused[curreg] = 1; 1800 return curreg; 1801 } 1802 } 1803 bpf_error("too many registers needed to evaluate expression"); 1804 /* NOTREACHED */ 1805} 1806 1807/* 1808 * Return a register to the table so it can 1809 * be used later. 1810 */ 1811static void 1812free_reg(n) 1813 int n; 1814{ 1815 regused[n] = 0; 1816} 1817 1818static struct block * 1819gen_len(jmp, n) 1820 int jmp, n; 1821{ 1822 struct slist *s; 1823 struct block *b; 1824 1825 s = new_stmt(BPF_LD|BPF_LEN); 1826 b = new_block(JMP(jmp)); 1827 b->stmts = s; 1828 b->s.k = n; 1829 1830 return b; 1831} 1832 1833struct block * 1834gen_greater(n) 1835 int n; 1836{ 1837 return gen_len(BPF_JGE, n); 1838} 1839 1840/* 1841 * Actually, this is less than or equal. 1842 */ 1843 1844struct block * 1845gen_less(n) 1846 int n; 1847{ 1848 struct block *b; 1849 1850 b = gen_len(BPF_JGT, n); 1851 gen_not(b); 1852 1853 return b; 1854} 1855 1856struct block * 1857gen_byteop(op, idx, val) 1858 int op, idx, val; 1859{ 1860 struct block *b; 1861 struct slist *s; 1862 1863 switch (op) { 1864 default: 1865 abort(); 1866 1867 case '=': 1868 return gen_cmp((u_int)idx, BPF_B, (bpf_int32)val); 1869 1870 case '<': 1871 b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val); 1872 b->s.code = JMP(BPF_JGE); 1873 gen_not(b); 1874 return b; 1875 1876 case '>': 1877 b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val); 1878 b->s.code = JMP(BPF_JGT); 1879 return b; 1880 1881 case '|': 1882 s = new_stmt(BPF_ALU|BPF_OR|BPF_K); 1883 break; 1884 1885 case '&': 1886 s = new_stmt(BPF_ALU|BPF_AND|BPF_K); 1887 break; 1888 } 1889 s->s.k = val; 1890 b = new_block(JMP(BPF_JEQ)); 1891 b->stmts = s; 1892 gen_not(b); 1893 1894 return b; 1895} 1896 1897struct block * 1898gen_broadcast(proto) 1899 int proto; 1900{ 1901 bpf_u_int32 hostmask; 1902 struct block *b0, *b1, *b2; 1903 static u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 1904 1905 switch (proto) { 1906 1907 case Q_DEFAULT: 1908 case Q_LINK: 1909 if (linktype == DLT_EN10MB) 1910 return gen_ehostop(ebroadcast, Q_DST); 1911 if (linktype == DLT_FDDI) 1912 return gen_fhostop(ebroadcast, Q_DST); 1913 bpf_error("not a broadcast link"); 1914 break; 1915 1916 case Q_IP: 1917 b0 = gen_linktype(ETHERTYPE_IP); 1918 hostmask = ~netmask; 1919 b1 = gen_mcmp(off_nl + 16, BPF_W, (bpf_int32)0, hostmask); 1920 b2 = gen_mcmp(off_nl + 16, BPF_W, 1921 (bpf_int32)(~0 & hostmask), hostmask); 1922 gen_or(b1, b2); 1923 gen_and(b0, b2); 1924 return b2; 1925 } 1926 bpf_error("only ether/ip broadcast filters supported"); 1927} 1928 1929struct block * 1930gen_multicast(proto) 1931 int proto; 1932{ 1933 register struct block *b0, *b1; 1934 register struct slist *s; 1935 1936 switch (proto) { 1937 1938 case Q_DEFAULT: 1939 case Q_LINK: 1940 if (linktype == DLT_EN10MB) { 1941 /* ether[0] & 1 != 0 */ 1942 s = new_stmt(BPF_LD|BPF_B|BPF_ABS); 1943 s->s.k = 0; 1944 b0 = new_block(JMP(BPF_JSET)); 1945 b0->s.k = 1; 1946 b0->stmts = s; 1947 return b0; 1948 } 1949 1950 if (linktype == DLT_FDDI) { 1951 /* XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX */ 1952 /* fddi[1] & 1 != 0 */ 1953 s = new_stmt(BPF_LD|BPF_B|BPF_ABS); 1954 s->s.k = 1; 1955 b0 = new_block(JMP(BPF_JSET)); 1956 b0->s.k = 1; 1957 b0->stmts = s; 1958 return b0; 1959 } 1960 /* Link not known to support multicasts */ 1961 break; 1962 1963 case Q_IP: 1964 b0 = gen_linktype(ETHERTYPE_IP); 1965 b1 = gen_cmp(off_nl + 16, BPF_B, (bpf_int32)224); 1966 b1->s.code = JMP(BPF_JGE); 1967 gen_and(b0, b1); 1968 return b1;
| 2511 } 2512 index->regno = regno; 2513 s = new_stmt(BPF_ST); 2514 s->s.k = regno; 2515 sappend(index->s, s); 2516 2517 return index; 2518} 2519 2520struct block * 2521gen_relation(code, a0, a1, reversed) 2522 int code; 2523 struct arth *a0, *a1; 2524 int reversed; 2525{ 2526 struct slist *s0, *s1, *s2; 2527 struct block *b, *tmp; 2528 2529 s0 = xfer_to_x(a1); 2530 s1 = xfer_to_a(a0); 2531 s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X); 2532 b = new_block(JMP(code)); 2533 if (code == BPF_JGT || code == BPF_JGE) { 2534 reversed = !reversed; 2535 b->s.k = 0x80000000; 2536 } 2537 if (reversed) 2538 gen_not(b); 2539 2540 sappend(s1, s2); 2541 sappend(s0, s1); 2542 sappend(a1->s, s0); 2543 sappend(a0->s, a1->s); 2544 2545 b->stmts = a0->s; 2546 2547 free_reg(a0->regno); 2548 free_reg(a1->regno); 2549 2550 /* 'and' together protocol checks */ 2551 if (a0->b) { 2552 if (a1->b) { 2553 gen_and(a0->b, tmp = a1->b); 2554 } 2555 else 2556 tmp = a0->b; 2557 } else 2558 tmp = a1->b; 2559 2560 if (tmp) 2561 gen_and(tmp, b); 2562 2563 return b; 2564} 2565 2566struct arth * 2567gen_loadlen() 2568{ 2569 int regno = alloc_reg(); 2570 struct arth *a = (struct arth *)newchunk(sizeof(*a)); 2571 struct slist *s; 2572 2573 s = new_stmt(BPF_LD|BPF_LEN); 2574 s->next = new_stmt(BPF_ST); 2575 s->next->s.k = regno; 2576 a->s = s; 2577 a->regno = regno; 2578 2579 return a; 2580} 2581 2582struct arth * 2583gen_loadi(val) 2584 int val; 2585{ 2586 struct arth *a; 2587 struct slist *s; 2588 int reg; 2589 2590 a = (struct arth *)newchunk(sizeof(*a)); 2591 2592 reg = alloc_reg(); 2593 2594 s = new_stmt(BPF_LD|BPF_IMM); 2595 s->s.k = val; 2596 s->next = new_stmt(BPF_ST); 2597 s->next->s.k = reg; 2598 a->s = s; 2599 a->regno = reg; 2600 2601 return a; 2602} 2603 2604struct arth * 2605gen_neg(a) 2606 struct arth *a; 2607{ 2608 struct slist *s; 2609 2610 s = xfer_to_a(a); 2611 sappend(a->s, s); 2612 s = new_stmt(BPF_ALU|BPF_NEG); 2613 s->s.k = 0; 2614 sappend(a->s, s); 2615 s = new_stmt(BPF_ST); 2616 s->s.k = a->regno; 2617 sappend(a->s, s); 2618 2619 return a; 2620} 2621 2622struct arth * 2623gen_arth(code, a0, a1) 2624 int code; 2625 struct arth *a0, *a1; 2626{ 2627 struct slist *s0, *s1, *s2; 2628 2629 s0 = xfer_to_x(a1); 2630 s1 = xfer_to_a(a0); 2631 s2 = new_stmt(BPF_ALU|BPF_X|code); 2632 2633 sappend(s1, s2); 2634 sappend(s0, s1); 2635 sappend(a1->s, s0); 2636 sappend(a0->s, a1->s); 2637 2638 free_reg(a1->regno); 2639 2640 s0 = new_stmt(BPF_ST); 2641 a0->regno = s0->s.k = alloc_reg(); 2642 sappend(a0->s, s0); 2643 2644 return a0; 2645} 2646 2647/* 2648 * Here we handle simple allocation of the scratch registers. 2649 * If too many registers are alloc'd, the allocator punts. 2650 */ 2651static int regused[BPF_MEMWORDS]; 2652static int curreg; 2653 2654/* 2655 * Return the next free register. 2656 */ 2657static int 2658alloc_reg() 2659{ 2660 int n = BPF_MEMWORDS; 2661 2662 while (--n >= 0) { 2663 if (regused[curreg]) 2664 curreg = (curreg + 1) % BPF_MEMWORDS; 2665 else { 2666 regused[curreg] = 1; 2667 return curreg; 2668 } 2669 } 2670 bpf_error("too many registers needed to evaluate expression"); 2671 /* NOTREACHED */ 2672} 2673 2674/* 2675 * Return a register to the table so it can 2676 * be used later. 2677 */ 2678static void 2679free_reg(n) 2680 int n; 2681{ 2682 regused[n] = 0; 2683} 2684 2685static struct block * 2686gen_len(jmp, n) 2687 int jmp, n; 2688{ 2689 struct slist *s; 2690 struct block *b; 2691 2692 s = new_stmt(BPF_LD|BPF_LEN); 2693 b = new_block(JMP(jmp)); 2694 b->stmts = s; 2695 b->s.k = n; 2696 2697 return b; 2698} 2699 2700struct block * 2701gen_greater(n) 2702 int n; 2703{ 2704 return gen_len(BPF_JGE, n); 2705} 2706 2707/* 2708 * Actually, this is less than or equal. 2709 */ 2710 2711struct block * 2712gen_less(n) 2713 int n; 2714{ 2715 struct block *b; 2716 2717 b = gen_len(BPF_JGT, n); 2718 gen_not(b); 2719 2720 return b; 2721} 2722 2723struct block * 2724gen_byteop(op, idx, val) 2725 int op, idx, val; 2726{ 2727 struct block *b; 2728 struct slist *s; 2729 2730 switch (op) { 2731 default: 2732 abort(); 2733 2734 case '=': 2735 return gen_cmp((u_int)idx, BPF_B, (bpf_int32)val); 2736 2737 case '<': 2738 b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val); 2739 b->s.code = JMP(BPF_JGE); 2740 gen_not(b); 2741 return b; 2742 2743 case '>': 2744 b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val); 2745 b->s.code = JMP(BPF_JGT); 2746 return b; 2747 2748 case '|': 2749 s = new_stmt(BPF_ALU|BPF_OR|BPF_K); 2750 break; 2751 2752 case '&': 2753 s = new_stmt(BPF_ALU|BPF_AND|BPF_K); 2754 break; 2755 } 2756 s->s.k = val; 2757 b = new_block(JMP(BPF_JEQ)); 2758 b->stmts = s; 2759 gen_not(b); 2760 2761 return b; 2762} 2763 2764struct block * 2765gen_broadcast(proto) 2766 int proto; 2767{ 2768 bpf_u_int32 hostmask; 2769 struct block *b0, *b1, *b2; 2770 static u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 2771 2772 switch (proto) { 2773 2774 case Q_DEFAULT: 2775 case Q_LINK: 2776 if (linktype == DLT_EN10MB) 2777 return gen_ehostop(ebroadcast, Q_DST); 2778 if (linktype == DLT_FDDI) 2779 return gen_fhostop(ebroadcast, Q_DST); 2780 bpf_error("not a broadcast link"); 2781 break; 2782 2783 case Q_IP: 2784 b0 = gen_linktype(ETHERTYPE_IP); 2785 hostmask = ~netmask; 2786 b1 = gen_mcmp(off_nl + 16, BPF_W, (bpf_int32)0, hostmask); 2787 b2 = gen_mcmp(off_nl + 16, BPF_W, 2788 (bpf_int32)(~0 & hostmask), hostmask); 2789 gen_or(b1, b2); 2790 gen_and(b0, b2); 2791 return b2; 2792 } 2793 bpf_error("only ether/ip broadcast filters supported"); 2794} 2795 2796struct block * 2797gen_multicast(proto) 2798 int proto; 2799{ 2800 register struct block *b0, *b1; 2801 register struct slist *s; 2802 2803 switch (proto) { 2804 2805 case Q_DEFAULT: 2806 case Q_LINK: 2807 if (linktype == DLT_EN10MB) { 2808 /* ether[0] & 1 != 0 */ 2809 s = new_stmt(BPF_LD|BPF_B|BPF_ABS); 2810 s->s.k = 0; 2811 b0 = new_block(JMP(BPF_JSET)); 2812 b0->s.k = 1; 2813 b0->stmts = s; 2814 return b0; 2815 } 2816 2817 if (linktype == DLT_FDDI) { 2818 /* XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX */ 2819 /* fddi[1] & 1 != 0 */ 2820 s = new_stmt(BPF_LD|BPF_B|BPF_ABS); 2821 s->s.k = 1; 2822 b0 = new_block(JMP(BPF_JSET)); 2823 b0->s.k = 1; 2824 b0->stmts = s; 2825 return b0; 2826 } 2827 /* Link not known to support multicasts */ 2828 break; 2829 2830 case Q_IP: 2831 b0 = gen_linktype(ETHERTYPE_IP); 2832 b1 = gen_cmp(off_nl + 16, BPF_B, (bpf_int32)224); 2833 b1->s.code = JMP(BPF_JGE); 2834 gen_and(b0, b1); 2835 return b1;
|
| 2836 2837#ifdef INET6 2838 case Q_IPV6: 2839 b0 = gen_linktype(ETHERTYPE_IPV6); 2840 b1 = gen_cmp(off_nl + 24, BPF_B, (bpf_int32)255); 2841 gen_and(b0, b1); 2842 return b1; 2843#endif /* INET6 */
|
1969 } 1970 bpf_error("only IP multicast filters supported on ethernet/FDDI"); 1971} 1972 1973/* 1974 * generate command for inbound/outbound. It's here so we can 1975 * make it link-type specific. 'dir' = 0 implies "inbound", 1976 * = 1 implies "outbound". 1977 */ 1978struct block * 1979gen_inbound(dir) 1980 int dir; 1981{ 1982 register struct block *b0; 1983 1984 b0 = gen_relation(BPF_JEQ, 1985 gen_load(Q_LINK, gen_loadi(0), 1), 1986 gen_loadi(0), 1987 dir); 1988 return (b0); 1989}
| 2844 } 2845 bpf_error("only IP multicast filters supported on ethernet/FDDI"); 2846} 2847 2848/* 2849 * generate command for inbound/outbound. It's here so we can 2850 * make it link-type specific. 'dir' = 0 implies "inbound", 2851 * = 1 implies "outbound". 2852 */ 2853struct block * 2854gen_inbound(dir) 2855 int dir; 2856{ 2857 register struct block *b0; 2858 2859 b0 = gen_relation(BPF_JEQ, 2860 gen_load(Q_LINK, gen_loadi(0), 1), 2861 gen_loadi(0), 2862 dir); 2863 return (b0); 2864}
|