gencode.c revision 57763
1/*#define CHASE_CHAIN*/
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 57763 2000-03-04 23:57:39Z fenner $
23 */
24#ifndef lint
25static const char rcsid[] =
26    "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.100.2.1 2000/03/01 14:12:54 itojun Exp $ (LBL)";
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
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*/
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
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
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
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
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__
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
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;
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;
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
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
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
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
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
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
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 *
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
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");
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
1077	default:
1078		abort();
1079	}
1080	/* NOTREACHED */
1081}
1082
1083#ifdef INET6
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 *
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:
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
1216		break;
1217
1218	case Q_UDP:
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
1224		break;
1225
1226	case Q_ICMP:
1227		b1 = gen_proto(IPPROTO_ICMP, Q_IP, Q_DEFAULT);
1228		break;
1229
1230	case Q_IGMP:
1231		b1 = gen_proto(2, Q_IP, Q_DEFAULT);
1232		break;
1233
1234#ifndef	IPPROTO_IGRP
1235#define	IPPROTO_IGRP	9
1236#endif
1237	case Q_IGRP:
1238		b1 = gen_proto(IPPROTO_IGRP, Q_IP, Q_DEFAULT);
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
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
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
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
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
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
1897	case Q_IP:
1898		b0 = gen_linktype(ETHERTYPE_IP);
1899#ifndef CHASE_CHAIN
1900		b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)v);
1901#else
1902		b1 = gen_protochain(v, Q_IP);
1903#endif
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
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*/
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
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			for (res = res0; res; res = res->ai_next) {
2093				switch (res->ai_family) {
2094				case AF_INET:
2095					if (tproto == Q_IPV6)
2096						continue;
2097
2098					sin = (struct sockaddr_in *)
2099						res->ai_addr;
2100					tmp = gen_host(ntohl(sin->sin_addr.s_addr),
2101						0xffffffff, tproto, dir);
2102					break;
2103				case AF_INET6:
2104					if (tproto6 == Q_IP)
2105						continue;
2106
2107					sin6 = (struct sockaddr_in6 *)
2108						res->ai_addr;
2109					tmp = gen_host6(&sin6->sin6_addr,
2110						&mask128, tproto6, dir);
2111					break;
2112				}
2113				if (b)
2114					gen_or(b, tmp);
2115				b = tmp;
2116			}
2117			freeaddrinfo(res0);
2118			if (b == NULL) {
2119				bpf_error("unknown host '%s'%s", name,
2120				    (proto == Q_DEFAULT)
2121					? ""
2122					: " for specified address family");
2123			}
2124			return b;
2125#endif /*INET6*/
2126		}
2127
2128	case Q_PORT:
2129		if (proto != Q_DEFAULT && proto != Q_UDP && proto != Q_TCP)
2130			bpf_error("illegal qualifier of 'port'");
2131		if (pcap_nametoport(name, &port, &real_proto) == 0)
2132			bpf_error("unknown port '%s'", name);
2133		if (proto == Q_UDP) {
2134			if (real_proto == IPPROTO_TCP)
2135				bpf_error("port '%s' is tcp", name);
2136			else
2137				/* override PROTO_UNDEF */
2138				real_proto = IPPROTO_UDP;
2139		}
2140		if (proto == Q_TCP) {
2141			if (real_proto == IPPROTO_UDP)
2142				bpf_error("port '%s' is udp", name);
2143			else
2144				/* override PROTO_UNDEF */
2145				real_proto = IPPROTO_TCP;
2146		}
2147#ifndef INET6
2148		return gen_port(port, real_proto, dir);
2149#else
2150	    {
2151		struct block *b;
2152		b = gen_port(port, real_proto, dir);
2153		gen_or(gen_port6(port, real_proto, dir), b);
2154		return b;
2155	    }
2156#endif /* INET6 */
2157
2158	case Q_GATEWAY:
2159#ifndef INET6
2160		eaddr = pcap_ether_hostton(name);
2161		if (eaddr == NULL)
2162			bpf_error("unknown ether host: %s", name);
2163
2164		alist = pcap_nametoaddr(name);
2165		if (alist == NULL || *alist == NULL)
2166			bpf_error("unknown host '%s'", name);
2167		return gen_gateway(eaddr, alist, proto, dir);
2168#else
2169		bpf_error("'gateway' not supported in this configuration");
2170#endif /*INET6*/
2171
2172	case Q_PROTO:
2173		real_proto = lookup_proto(name, proto);
2174		if (real_proto >= 0)
2175			return gen_proto(real_proto, proto, dir);
2176		else
2177			bpf_error("unknown protocol: %s", name);
2178
2179	case Q_PROTOCHAIN:
2180		real_proto = lookup_proto(name, proto);
2181		if (real_proto >= 0)
2182			return gen_protochain(real_proto, proto, dir);
2183		else
2184			bpf_error("unknown protocol: %s", name);
2185
2186
2187	case Q_UNDEF:
2188		syntax();
2189		/* NOTREACHED */
2190	}
2191	abort();
2192	/* NOTREACHED */
2193}
2194
2195struct block *
2196gen_mcode(s1, s2, masklen, q)
2197	register const char *s1, *s2;
2198	register int masklen;
2199	struct qual q;
2200{
2201	register int nlen, mlen;
2202	bpf_u_int32 n, m;
2203
2204	nlen = __pcap_atoin(s1, &n);
2205	/* Promote short ipaddr */
2206	n <<= 32 - nlen;
2207
2208	if (s2 != NULL) {
2209		mlen = __pcap_atoin(s2, &m);
2210		/* Promote short ipaddr */
2211		m <<= 32 - mlen;
2212		if ((n & ~m) != 0)
2213			bpf_error("non-network bits set in \"%s mask %s\"",
2214			    s1, s2);
2215	} else {
2216		/* Convert mask len to mask */
2217		if (masklen > 32)
2218			bpf_error("mask length must be <= 32");
2219		m = 0xffffffff << (32 - masklen);
2220		if ((n & ~m) != 0)
2221			bpf_error("non-network bits set in \"%s/%d\"",
2222			    s1, masklen);
2223	}
2224
2225	switch (q.addr) {
2226
2227	case Q_NET:
2228		return gen_host(n, m, q.proto, q.dir);
2229
2230	default:
2231		bpf_error("Mask syntax for networks only");
2232		/* NOTREACHED */
2233	}
2234}
2235
2236struct block *
2237gen_ncode(s, v, q)
2238	register const char *s;
2239	bpf_u_int32 v;
2240	struct qual q;
2241{
2242	bpf_u_int32 mask;
2243	int proto = q.proto;
2244	int dir = q.dir;
2245	register int vlen;
2246
2247	if (s == NULL)
2248		vlen = 32;
2249	else if (q.proto == Q_DECNET)
2250		vlen = __pcap_atodn(s, &v);
2251	else
2252		vlen = __pcap_atoin(s, &v);
2253
2254	switch (q.addr) {
2255
2256	case Q_DEFAULT:
2257	case Q_HOST:
2258	case Q_NET:
2259		if (proto == Q_DECNET)
2260			return gen_host(v, 0, proto, dir);
2261		else if (proto == Q_LINK) {
2262			bpf_error("illegal link layer address");
2263		} else {
2264			mask = 0xffffffff;
2265			if (s == NULL && q.addr == Q_NET) {
2266				/* Promote short net number */
2267				while (v && (v & 0xff000000) == 0) {
2268					v <<= 8;
2269					mask <<= 8;
2270				}
2271			} else {
2272				/* Promote short ipaddr */
2273				v <<= 32 - vlen;
2274				mask <<= 32 - vlen;
2275			}
2276			return gen_host(v, mask, proto, dir);
2277		}
2278
2279	case Q_PORT:
2280		if (proto == Q_UDP)
2281			proto = IPPROTO_UDP;
2282		else if (proto == Q_TCP)
2283			proto = IPPROTO_TCP;
2284		else if (proto == Q_DEFAULT)
2285			proto = PROTO_UNDEF;
2286		else
2287			bpf_error("illegal qualifier of 'port'");
2288
2289#ifndef INET6
2290		return gen_port((int)v, proto, dir);
2291#else
2292	    {
2293		struct block *b;
2294		b = gen_port((int)v, proto, dir);
2295		gen_or(gen_port6((int)v, proto, dir), b);
2296		return b;
2297	    }
2298#endif /* INET6 */
2299
2300	case Q_GATEWAY:
2301		bpf_error("'gateway' requires a name");
2302		/* NOTREACHED */
2303
2304	case Q_PROTO:
2305		return gen_proto((int)v, proto, dir);
2306
2307	case Q_PROTOCHAIN:
2308		return gen_protochain((int)v, proto, dir);
2309
2310	case Q_UNDEF:
2311		syntax();
2312		/* NOTREACHED */
2313
2314	default:
2315		abort();
2316		/* NOTREACHED */
2317	}
2318	/* NOTREACHED */
2319}
2320
2321#ifdef INET6
2322struct block *
2323gen_mcode6(s1, s2, masklen, q)
2324	register const char *s1, *s2;
2325	register int masklen;
2326	struct qual q;
2327{
2328	struct addrinfo *res;
2329	struct in6_addr *addr;
2330	struct in6_addr mask;
2331	struct block *b;
2332	u_int32_t *a, *m;
2333
2334	if (s2)
2335		bpf_error("no mask %s supported", s2);
2336
2337	res = pcap_nametoaddr(s1);
2338	if (!res)
2339		bpf_error("invalid ip6 address %s", s1);
2340	if (res->ai_next)
2341		bpf_error("%s resolved to multiple address", s1);
2342	addr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
2343
2344	if (sizeof(mask) * 8 < masklen)
2345		bpf_error("mask length must be <= %u", (unsigned int)(sizeof(mask) * 8));
2346	memset(&mask, 0xff, masklen / 8);
2347	if (masklen % 8) {
2348		mask.s6_addr[masklen / 8] =
2349			(0xff << (8 - masklen % 8)) & 0xff;
2350	}
2351
2352	a = (u_int32_t *)addr;
2353	m = (u_int32_t *)&mask;
2354	if ((a[0] & ~m[0]) || (a[1] & ~m[1])
2355	 || (a[2] & ~m[2]) || (a[3] & ~m[3])) {
2356		bpf_error("non-network bits set in \"%s/%d\"", s1, masklen);
2357	}
2358
2359	switch (q.addr) {
2360
2361	case Q_DEFAULT:
2362	case Q_HOST:
2363		if (masklen != 128)
2364			bpf_error("Mask syntax for networks only");
2365		/* FALLTHROUGH */
2366
2367	case Q_NET:
2368		b = gen_host6(addr, &mask, q.proto, q.dir);
2369		freeaddrinfo(res);
2370		return b;
2371
2372	default:
2373		bpf_error("invalid qualifier against IPv6 address");
2374		/* NOTREACHED */
2375	}
2376}
2377#endif /*INET6*/
2378
2379struct block *
2380gen_ecode(eaddr, q)
2381	register const u_char *eaddr;
2382	struct qual q;
2383{
2384	if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
2385		if (linktype == DLT_EN10MB)
2386			return gen_ehostop(eaddr, (int)q.dir);
2387		if (linktype == DLT_FDDI)
2388			return gen_fhostop(eaddr, (int)q.dir);
2389	}
2390	bpf_error("ethernet address used in non-ether expression");
2391	/* NOTREACHED */
2392}
2393
2394void
2395sappend(s0, s1)
2396	struct slist *s0, *s1;
2397{
2398	/*
2399	 * This is definitely not the best way to do this, but the
2400	 * lists will rarely get long.
2401	 */
2402	while (s0->next)
2403		s0 = s0->next;
2404	s0->next = s1;
2405}
2406
2407static struct slist *
2408xfer_to_x(a)
2409	struct arth *a;
2410{
2411	struct slist *s;
2412
2413	s = new_stmt(BPF_LDX|BPF_MEM);
2414	s->s.k = a->regno;
2415	return s;
2416}
2417
2418static struct slist *
2419xfer_to_a(a)
2420	struct arth *a;
2421{
2422	struct slist *s;
2423
2424	s = new_stmt(BPF_LD|BPF_MEM);
2425	s->s.k = a->regno;
2426	return s;
2427}
2428
2429struct arth *
2430gen_load(proto, index, size)
2431	int proto;
2432	struct arth *index;
2433	int size;
2434{
2435	struct slist *s, *tmp;
2436	struct block *b;
2437	int regno = alloc_reg();
2438
2439	free_reg(index->regno);
2440	switch (size) {
2441
2442	default:
2443		bpf_error("data size must be 1, 2, or 4");
2444
2445	case 1:
2446		size = BPF_B;
2447		break;
2448
2449	case 2:
2450		size = BPF_H;
2451		break;
2452
2453	case 4:
2454		size = BPF_W;
2455		break;
2456	}
2457	switch (proto) {
2458	default:
2459		bpf_error("unsupported index operation");
2460
2461	case Q_LINK:
2462		s = xfer_to_x(index);
2463		tmp = new_stmt(BPF_LD|BPF_IND|size);
2464		sappend(s, tmp);
2465		sappend(index->s, s);
2466		break;
2467
2468	case Q_IP:
2469	case Q_ARP:
2470	case Q_RARP:
2471	case Q_ATALK:
2472	case Q_DECNET:
2473	case Q_SCA:
2474	case Q_LAT:
2475	case Q_MOPRC:
2476	case Q_MOPDL:
2477#ifdef INET6
2478	case Q_IPV6:
2479#endif
2480		/* XXX Note that we assume a fixed link header here. */
2481		s = xfer_to_x(index);
2482		tmp = new_stmt(BPF_LD|BPF_IND|size);
2483		tmp->s.k = off_nl;
2484		sappend(s, tmp);
2485		sappend(index->s, s);
2486
2487		b = gen_proto_abbrev(proto);
2488		if (index->b)
2489			gen_and(index->b, b);
2490		index->b = b;
2491		break;
2492
2493	case Q_TCP:
2494	case Q_UDP:
2495	case Q_ICMP:
2496	case Q_IGMP:
2497	case Q_IGRP:
2498	case Q_PIM:
2499		s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
2500		s->s.k = off_nl;
2501		sappend(s, xfer_to_a(index));
2502		sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
2503		sappend(s, new_stmt(BPF_MISC|BPF_TAX));
2504		sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size));
2505		tmp->s.k = off_nl;
2506		sappend(index->s, s);
2507
2508		gen_and(gen_proto_abbrev(proto), b = gen_ipfrag());
2509		if (index->b)
2510			gen_and(index->b, b);
2511#ifdef INET6
2512		gen_and(gen_proto_abbrev(Q_IP), b);
2513#endif
2514		index->b = b;
2515		break;
2516#ifdef INET6
2517	case Q_ICMPV6:
2518		bpf_error("IPv6 upper-layer protocol is not supported by proto[x]");
2519		/*NOTREACHED*/
2520#endif
2521	}
2522	index->regno = regno;
2523	s = new_stmt(BPF_ST);
2524	s->s.k = regno;
2525	sappend(index->s, s);
2526
2527	return index;
2528}
2529
2530struct block *
2531gen_relation(code, a0, a1, reversed)
2532	int code;
2533	struct arth *a0, *a1;
2534	int reversed;
2535{
2536	struct slist *s0, *s1, *s2;
2537	struct block *b, *tmp;
2538
2539	s0 = xfer_to_x(a1);
2540	s1 = xfer_to_a(a0);
2541	s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X);
2542	b = new_block(JMP(code));
2543	if (code == BPF_JGT || code == BPF_JGE) {
2544		reversed = !reversed;
2545		b->s.k = 0x80000000;
2546	}
2547	if (reversed)
2548		gen_not(b);
2549
2550	sappend(s1, s2);
2551	sappend(s0, s1);
2552	sappend(a1->s, s0);
2553	sappend(a0->s, a1->s);
2554
2555	b->stmts = a0->s;
2556
2557	free_reg(a0->regno);
2558	free_reg(a1->regno);
2559
2560	/* 'and' together protocol checks */
2561	if (a0->b) {
2562		if (a1->b) {
2563			gen_and(a0->b, tmp = a1->b);
2564		}
2565		else
2566			tmp = a0->b;
2567	} else
2568		tmp = a1->b;
2569
2570	if (tmp)
2571		gen_and(tmp, b);
2572
2573	return b;
2574}
2575
2576struct arth *
2577gen_loadlen()
2578{
2579	int regno = alloc_reg();
2580	struct arth *a = (struct arth *)newchunk(sizeof(*a));
2581	struct slist *s;
2582
2583	s = new_stmt(BPF_LD|BPF_LEN);
2584	s->next = new_stmt(BPF_ST);
2585	s->next->s.k = regno;
2586	a->s = s;
2587	a->regno = regno;
2588
2589	return a;
2590}
2591
2592struct arth *
2593gen_loadi(val)
2594	int val;
2595{
2596	struct arth *a;
2597	struct slist *s;
2598	int reg;
2599
2600	a = (struct arth *)newchunk(sizeof(*a));
2601
2602	reg = alloc_reg();
2603
2604	s = new_stmt(BPF_LD|BPF_IMM);
2605	s->s.k = val;
2606	s->next = new_stmt(BPF_ST);
2607	s->next->s.k = reg;
2608	a->s = s;
2609	a->regno = reg;
2610
2611	return a;
2612}
2613
2614struct arth *
2615gen_neg(a)
2616	struct arth *a;
2617{
2618	struct slist *s;
2619
2620	s = xfer_to_a(a);
2621	sappend(a->s, s);
2622	s = new_stmt(BPF_ALU|BPF_NEG);
2623	s->s.k = 0;
2624	sappend(a->s, s);
2625	s = new_stmt(BPF_ST);
2626	s->s.k = a->regno;
2627	sappend(a->s, s);
2628
2629	return a;
2630}
2631
2632struct arth *
2633gen_arth(code, a0, a1)
2634	int code;
2635	struct arth *a0, *a1;
2636{
2637	struct slist *s0, *s1, *s2;
2638
2639	s0 = xfer_to_x(a1);
2640	s1 = xfer_to_a(a0);
2641	s2 = new_stmt(BPF_ALU|BPF_X|code);
2642
2643	sappend(s1, s2);
2644	sappend(s0, s1);
2645	sappend(a1->s, s0);
2646	sappend(a0->s, a1->s);
2647
2648	free_reg(a1->regno);
2649
2650	s0 = new_stmt(BPF_ST);
2651	a0->regno = s0->s.k = alloc_reg();
2652	sappend(a0->s, s0);
2653
2654	return a0;
2655}
2656
2657/*
2658 * Here we handle simple allocation of the scratch registers.
2659 * If too many registers are alloc'd, the allocator punts.
2660 */
2661static int regused[BPF_MEMWORDS];
2662static int curreg;
2663
2664/*
2665 * Return the next free register.
2666 */
2667static int
2668alloc_reg()
2669{
2670	int n = BPF_MEMWORDS;
2671
2672	while (--n >= 0) {
2673		if (regused[curreg])
2674			curreg = (curreg + 1) % BPF_MEMWORDS;
2675		else {
2676			regused[curreg] = 1;
2677			return curreg;
2678		}
2679	}
2680	bpf_error("too many registers needed to evaluate expression");
2681	/* NOTREACHED */
2682}
2683
2684/*
2685 * Return a register to the table so it can
2686 * be used later.
2687 */
2688static void
2689free_reg(n)
2690	int n;
2691{
2692	regused[n] = 0;
2693}
2694
2695static struct block *
2696gen_len(jmp, n)
2697	int jmp, n;
2698{
2699	struct slist *s;
2700	struct block *b;
2701
2702	s = new_stmt(BPF_LD|BPF_LEN);
2703	b = new_block(JMP(jmp));
2704	b->stmts = s;
2705	b->s.k = n;
2706
2707	return b;
2708}
2709
2710struct block *
2711gen_greater(n)
2712	int n;
2713{
2714	return gen_len(BPF_JGE, n);
2715}
2716
2717/*
2718 * Actually, this is less than or equal.
2719 */
2720
2721struct block *
2722gen_less(n)
2723	int n;
2724{
2725	struct block *b;
2726
2727	b = gen_len(BPF_JGT, n);
2728	gen_not(b);
2729
2730	return b;
2731}
2732
2733struct block *
2734gen_byteop(op, idx, val)
2735	int op, idx, val;
2736{
2737	struct block *b;
2738	struct slist *s;
2739
2740	switch (op) {
2741	default:
2742		abort();
2743
2744	case '=':
2745		return gen_cmp((u_int)idx, BPF_B, (bpf_int32)val);
2746
2747	case '<':
2748		b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val);
2749		b->s.code = JMP(BPF_JGE);
2750		gen_not(b);
2751		return b;
2752
2753	case '>':
2754		b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val);
2755		b->s.code = JMP(BPF_JGT);
2756		return b;
2757
2758	case '|':
2759		s = new_stmt(BPF_ALU|BPF_OR|BPF_K);
2760		break;
2761
2762	case '&':
2763		s = new_stmt(BPF_ALU|BPF_AND|BPF_K);
2764		break;
2765	}
2766	s->s.k = val;
2767	b = new_block(JMP(BPF_JEQ));
2768	b->stmts = s;
2769	gen_not(b);
2770
2771	return b;
2772}
2773
2774struct block *
2775gen_broadcast(proto)
2776	int proto;
2777{
2778	bpf_u_int32 hostmask;
2779	struct block *b0, *b1, *b2;
2780	static u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2781
2782	switch (proto) {
2783
2784	case Q_DEFAULT:
2785	case Q_LINK:
2786		if (linktype == DLT_EN10MB)
2787			return gen_ehostop(ebroadcast, Q_DST);
2788		if (linktype == DLT_FDDI)
2789			return gen_fhostop(ebroadcast, Q_DST);
2790		bpf_error("not a broadcast link");
2791		break;
2792
2793	case Q_IP:
2794		b0 = gen_linktype(ETHERTYPE_IP);
2795		hostmask = ~netmask;
2796		b1 = gen_mcmp(off_nl + 16, BPF_W, (bpf_int32)0, hostmask);
2797		b2 = gen_mcmp(off_nl + 16, BPF_W,
2798			      (bpf_int32)(~0 & hostmask), hostmask);
2799		gen_or(b1, b2);
2800		gen_and(b0, b2);
2801		return b2;
2802	}
2803	bpf_error("only ether/ip broadcast filters supported");
2804}
2805
2806struct block *
2807gen_multicast(proto)
2808	int proto;
2809{
2810	register struct block *b0, *b1;
2811	register struct slist *s;
2812
2813	switch (proto) {
2814
2815	case Q_DEFAULT:
2816	case Q_LINK:
2817		if (linktype == DLT_EN10MB) {
2818			/* ether[0] & 1 != 0 */
2819			s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
2820			s->s.k = 0;
2821			b0 = new_block(JMP(BPF_JSET));
2822			b0->s.k = 1;
2823			b0->stmts = s;
2824			return b0;
2825		}
2826
2827		if (linktype == DLT_FDDI) {
2828			/* XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX */
2829			/* fddi[1] & 1 != 0 */
2830			s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
2831			s->s.k = 1;
2832			b0 = new_block(JMP(BPF_JSET));
2833			b0->s.k = 1;
2834			b0->stmts = s;
2835			return b0;
2836		}
2837		/* Link not known to support multicasts */
2838		break;
2839
2840	case Q_IP:
2841		b0 = gen_linktype(ETHERTYPE_IP);
2842		b1 = gen_cmp(off_nl + 16, BPF_B, (bpf_int32)224);
2843		b1->s.code = JMP(BPF_JGE);
2844		gen_and(b0, b1);
2845		return b1;
2846
2847#ifdef INET6
2848	case Q_IPV6:
2849		b0 = gen_linktype(ETHERTYPE_IPV6);
2850		b1 = gen_cmp(off_nl + 24, BPF_B, (bpf_int32)255);
2851		gen_and(b0, b1);
2852		return b1;
2853#endif /* INET6 */
2854	}
2855	bpf_error("only IP multicast filters supported on ethernet/FDDI");
2856}
2857
2858/*
2859 * generate command for inbound/outbound.  It's here so we can
2860 * make it link-type specific.  'dir' = 0 implies "inbound",
2861 * = 1 implies "outbound".
2862 */
2863struct block *
2864gen_inbound(dir)
2865	int dir;
2866{
2867	register struct block *b0;
2868
2869	b0 = gen_relation(BPF_JEQ,
2870			  gen_load(Q_LINK, gen_loadi(0), 1),
2871			  gen_loadi(0),
2872			  dir);
2873	return (b0);
2874}
2875