]>
git.saurik.com Git - apple/network_cmds.git/blob - pcap/gencode.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
24 /* $OpenBSD: gencode.c,v 1.5 1996/09/16 02:33:05 tholo Exp $ */
27 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
28 * The Regents of the University of California. All rights reserved.
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that: (1) source code distributions
32 * retain the above copyright notice and this paragraph in its entirety, (2)
33 * distributions including binary code include the above copyright notice and
34 * this paragraph in its entirety in the documentation or other materials
35 * provided with the distribution, and (3) all advertising materials mentioning
36 * features or use of this software display the following acknowledgement:
37 * ``This product includes software developed by the University of California,
38 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
39 * the University nor the names of its contributors may be used to endorse
40 * or promote products derived from this software without specific prior
42 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
43 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
44 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
48 "@(#) Header: gencode.c,v 1.81 96/06/19 23:09:09 leres Exp (LBL)";
51 #include <sys/types.h>
52 #include <sys/socket.h>
63 #include <netinet/in.h>
64 #include <netinet/if_ether.h>
69 #include <pcap-namedb.h>
77 #ifdef HAVE_OS_PROTO_H
85 #ifndef ETHERTYPE_REVARP
86 #define ETHERTYPE_REVARP 0x8035
88 #ifndef ETHERTYPE_MOPDL
89 #define ETHERTYPE_MOPDL 0x6001
91 #ifndef ETHERTYPE_MOPRC
92 #define ETHERTYPE_MOPRC 0x6002
95 #define ETHERTYPE_DN 0x6003
98 #define ETHERTYPE_LAT 0x6004
101 #define JMP(c) ((c)|BPF_JMP|BPF_K)
104 static jmp_buf top_ctx
;
105 static pcap_t
*bpf_pcap
;
109 int pcap_fddipad
= PCAP_FDDIPAD
;
113 #ifndef DLT_ATM_RFC1483
114 #define DLT_ATM_RFC1483 11
121 bpf_error(const char *fmt
, ...)
123 bpf_error(fmt
, va_alist
)
135 if (bpf_pcap
!= NULL
)
136 (void)vsprintf(pcap_geterr(bpf_pcap
), fmt
, ap
);
142 static void init_linktype(int);
144 static int alloc_reg(void);
145 static void free_reg(int);
147 static struct block
*root
;
150 * We divy out chunks of memory rather than call malloc each time so
151 * we don't have to worry about leaking memory. It's probably
152 * not a big deal if all this memory was wasted but it this ever
153 * goes into a library that would probably not be a good idea.
156 #define CHUNK0SIZE 1024
162 static struct chunk chunks
[NCHUNKS
];
163 static int cur_chunk
;
165 static void *newchunk(u_int
);
166 static void freechunks(void);
167 static __inline
struct block
*new_block(int);
168 static __inline
struct slist
*new_stmt(int);
169 static struct block
*gen_retblk(int);
170 static __inline
void syntax(void);
172 static void backpatch(struct block
*, struct block
*);
173 static void merge(struct block
*, struct block
*);
174 static struct block
*gen_cmp(u_int
, u_int
, bpf_int32
);
175 static struct block
*gen_mcmp(u_int
, u_int
, bpf_int32
, bpf_u_int32
);
176 static struct block
*gen_bcmp(u_int
, u_int
, u_char
*);
177 static struct block
*gen_uncond(int);
178 static __inline
struct block
*gen_true(void);
179 static __inline
struct block
*gen_false(void);
180 static struct block
*gen_linktype(int);
181 static struct block
*gen_hostop(bpf_u_int32
, bpf_u_int32
, int, int, u_int
, u_int
);
182 static struct block
*gen_ehostop(u_char
*, int);
183 static struct block
*gen_fhostop(u_char
*, int);
184 static struct block
*gen_dnhostop(bpf_u_int32
, int, u_int
);
185 static struct block
*gen_host(bpf_u_int32
, bpf_u_int32
, int, int);
186 static struct block
*gen_gateway(u_char
*, bpf_u_int32
**, int, int);
187 static struct block
*gen_ipfrag(void);
188 static struct block
*gen_portatom(int, bpf_int32
);
189 struct block
*gen_portop(int, int, int);
190 static struct block
*gen_port(int, int, int);
191 static int lookup_proto(char *, int);
192 static struct block
*gen_proto(int, int, int);
193 static bpf_u_int32
net_mask(bpf_u_int32
*);
194 static struct slist
*xfer_to_x(struct arth
*);
195 static struct slist
*xfer_to_a(struct arth
*);
196 static struct block
*gen_len(int, int);
205 /* XXX Round up to nearest long. */
206 n
= (n
+ sizeof(long) - 1) & ~(sizeof(long) - 1);
208 cp
= &chunks
[cur_chunk
];
209 if (n
> cp
->n_left
) {
210 ++cp
, k
= ++cur_chunk
;
212 bpf_error("out of memory");
213 size
= CHUNK0SIZE
<< k
;
214 cp
->m
= (void *)malloc(size
);
215 memset((char *)cp
->m
, 0, size
);
218 bpf_error("out of memory");
221 return (void *)((char *)cp
->m
+ cp
->n_left
);
230 for (i
= 0; i
< NCHUNKS
; ++i
)
231 if (chunks
[i
].m
!= NULL
) {
238 * A strdup whose allocations are freed after code generation is over.
244 int n
= strlen(s
) + 1;
245 char *cp
= newchunk(n
);
250 static __inline
struct block
*
256 p
= (struct block
*)newchunk(sizeof(*p
));
263 static __inline
struct slist
*
269 p
= (struct slist
*)newchunk(sizeof(*p
));
275 static struct block
*
279 struct block
*b
= new_block(BPF_RET
|BPF_K
);
288 bpf_error("syntax error in filter expression");
291 static bpf_u_int32 netmask
;
295 pcap_compile(pcap_t
*p
, struct bpf_program
*program
,
296 char *buf
, int optimize
, bpf_u_int32 mask
)
304 if (setjmp(top_ctx
)) {
310 snaplen
= pcap_snapshot(p
);
312 lex_init(buf
? buf
: "");
313 init_linktype(pcap_datalink(p
));
320 root
= gen_retblk(snaplen
);
325 (root
->s
.code
== (BPF_RET
|BPF_K
) && root
->s
.k
== 0))
326 bpf_error("expression rejects all packets");
328 program
->bf_insns
= icode_to_fcode(root
, &len
);
329 program
->bf_len
= len
;
336 * Backpatch the blocks in 'list' to 'target'. The 'sense' field indicates
337 * which of the jt and jf fields has been resolved and which is a pointer
338 * back to another unresolved block (or nil). At least one of the fields
339 * in each block is already resolved.
342 backpatch(list
, target
)
343 struct block
*list
, *target
;
360 * Merge the lists in b0 and b1, using the 'sense' field to indicate
361 * which of jt and jf is the link.
365 struct block
*b0
, *b1
;
367 register struct block
**p
= &b0
;
369 /* Find end of list. */
371 p
= !((*p
)->sense
) ? &JT(*p
) : &JF(*p
);
373 /* Concatenate the lists. */
381 backpatch(p
, gen_retblk(snaplen
));
382 p
->sense
= !p
->sense
;
383 backpatch(p
, gen_retblk(0));
389 struct block
*b0
, *b1
;
391 backpatch(b0
, b1
->head
);
392 b0
->sense
= !b0
->sense
;
393 b1
->sense
= !b1
->sense
;
395 b1
->sense
= !b1
->sense
;
401 struct block
*b0
, *b1
;
403 b0
->sense
= !b0
->sense
;
404 backpatch(b0
, b1
->head
);
405 b0
->sense
= !b0
->sense
;
414 b
->sense
= !b
->sense
;
417 static struct block
*
418 gen_cmp(offset
, size
, v
)
425 s
= new_stmt(BPF_LD
|BPF_ABS
|size
);
428 b
= new_block(JMP(BPF_JEQ
));
435 static struct block
*
436 gen_mcmp(offset
, size
, v
, mask
)
441 struct block
*b
= gen_cmp(offset
, size
, v
);
444 if (mask
!= 0xffffffff) {
445 s
= new_stmt(BPF_ALU
|BPF_AND
|BPF_K
);
452 static struct block
*
453 gen_bcmp(offset
, size
, v
)
457 struct block
*b
, *tmp
;
461 u_char
*p
= &v
[size
- 4];
462 bpf_int32 w
= (p
[0] << 24) | (p
[1] << 16) | (p
[2] << 8) | p
[3];
463 tmp
= gen_cmp(offset
+ size
- 4, BPF_W
, w
);
470 u_char
*p
= &v
[size
- 2];
471 bpf_int32 w
= (p
[0] << 8) | p
[1];
472 tmp
= gen_cmp(offset
+ size
- 2, BPF_H
, w
);
479 tmp
= gen_cmp(offset
, BPF_B
, (bpf_int32
)v
[0]);
488 * Various code constructs need to know the layout of the data link
489 * layer. These variables give the necessary offsets. off_linktype
490 * is set to -1 for no encapsulation, in which case, IP is assumed.
492 static u_int off_linktype
;
511 * SLIP doesn't have a link level type. The 16 byte
512 * header is hacked into our SLIP driver.
530 * FDDI doesn't really have a link-level type field.
531 * We assume that SSAP = SNAP is being used and pick
532 * out the encapsulated Ethernet type.
536 off_linktype
+= pcap_fddipad
;
540 off_nl
+= pcap_fddipad
;
549 case DLT_ATM_RFC1483
:
551 * assume routed, non-ISO PDUs
552 * (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00)
558 bpf_error("unknown data link type 0x%x", linktype
);
562 static struct block
*
569 s
= new_stmt(BPF_LD
|BPF_IMM
);
571 b
= new_block(JMP(BPF_JEQ
));
577 static __inline
struct block
*
580 return gen_uncond(1);
583 static __inline
struct block
*
586 return gen_uncond(0);
589 static struct block
*
595 if (proto
== ETHERTYPE_IP
)
601 if (proto
== ETHERTYPE_IP
)
602 proto
= 0x0021; /* XXX - need ppp.h defs */
607 if (proto
== ETHERTYPE_IP
)
608 return (gen_cmp(0, BPF_W
, (bpf_int32
)AF_INET
));
612 return gen_cmp(off_linktype
, BPF_H
, (bpf_int32
)proto
);
615 static struct block
*
616 gen_hostop(addr
, mask
, dir
, proto
, src_off
, dst_off
)
620 u_int src_off
, dst_off
;
622 struct block
*b0
, *b1
;
636 b0
= gen_hostop(addr
, mask
, Q_SRC
, proto
, src_off
, dst_off
);
637 b1
= gen_hostop(addr
, mask
, Q_DST
, proto
, src_off
, dst_off
);
643 b0
= gen_hostop(addr
, mask
, Q_SRC
, proto
, src_off
, dst_off
);
644 b1
= gen_hostop(addr
, mask
, Q_DST
, proto
, src_off
, dst_off
);
651 b0
= gen_linktype(proto
);
652 b1
= gen_mcmp(offset
, BPF_W
, (bpf_int32
)addr
, mask
);
657 static struct block
*
658 gen_ehostop(eaddr
, dir
)
662 struct block
*b0
, *b1
;
666 return gen_bcmp(6, 6, eaddr
);
669 return gen_bcmp(0, 6, eaddr
);
672 b0
= gen_ehostop(eaddr
, Q_SRC
);
673 b1
= gen_ehostop(eaddr
, Q_DST
);
679 b0
= gen_ehostop(eaddr
, Q_SRC
);
680 b1
= gen_ehostop(eaddr
, Q_DST
);
689 * Like gen_ehostop, but for DLT_FDDI
691 static struct block
*
692 gen_fhostop(eaddr
, dir
)
696 struct block
*b0
, *b1
;
701 return gen_bcmp(6 + 1 + pcap_fddipad
, 6, eaddr
);
703 return gen_bcmp(6 + 1, 6, eaddr
);
708 return gen_bcmp(0 + 1 + pcap_fddipad
, 6, eaddr
);
710 return gen_bcmp(0 + 1, 6, eaddr
);
714 b0
= gen_fhostop(eaddr
, Q_SRC
);
715 b1
= gen_fhostop(eaddr
, Q_DST
);
721 b0
= gen_fhostop(eaddr
, Q_SRC
);
722 b1
= gen_fhostop(eaddr
, Q_DST
);
731 * This is quite tricky because there may be pad bytes in front of the
732 * DECNET header, and then there are two possible data packet formats that
733 * carry both src and dst addresses, plus 5 packet types in a format that
734 * carries only the src node, plus 2 types that use a different format and
735 * also carry just the src node.
739 * Instead of doing those all right, we just look for data packets with
740 * 0 or 1 bytes of padding. If you want to look at other packets, that
741 * will require a lot more hacking.
743 * To add support for filtering on DECNET "areas" (network numbers)
744 * one would want to add a "mask" argument to this routine. That would
745 * make the filter even more inefficient, although one could be clever
746 * and not generate masking instructions if the mask is 0xFFFF.
748 static struct block
*
749 gen_dnhostop(addr
, dir
, base_off
)
754 struct block
*b0
, *b1
, *b2
, *tmp
;
755 u_int offset_lh
; /* offset if long header is received */
756 u_int offset_sh
; /* offset if short header is received */
761 offset_sh
= 1; /* follows flags */
762 offset_lh
= 7; /* flgs,darea,dsubarea,HIORD */
766 offset_sh
= 3; /* follows flags, dstnode */
767 offset_lh
= 15; /* flgs,darea,dsubarea,did,sarea,ssub,HIORD */
771 /* Inefficient because we do our Calvinball dance twice */
772 b0
= gen_dnhostop(addr
, Q_SRC
, base_off
);
773 b1
= gen_dnhostop(addr
, Q_DST
, base_off
);
779 /* Inefficient because we do our Calvinball dance twice */
780 b0
= gen_dnhostop(addr
, Q_SRC
, base_off
);
781 b1
= gen_dnhostop(addr
, Q_DST
, base_off
);
788 b0
= gen_linktype(ETHERTYPE_DN
);
789 /* Check for pad = 1, long header case */
790 tmp
= gen_mcmp(base_off
+ 2, BPF_H
,
791 (bpf_int32
)ntohs(0x0681), (bpf_int32
)ntohs(0x07FF));
792 b1
= gen_cmp(base_off
+ 2 + 1 + offset_lh
,
793 BPF_H
, (bpf_int32
)ntohs(addr
));
795 /* Check for pad = 0, long header case */
796 tmp
= gen_mcmp(base_off
+ 2, BPF_B
, (bpf_int32
)0x06, (bpf_int32
)0x7);
797 b2
= gen_cmp(base_off
+ 2 + offset_lh
, BPF_H
, (bpf_int32
)ntohs(addr
));
800 /* Check for pad = 1, short header case */
801 tmp
= gen_mcmp(base_off
+ 2, BPF_H
,
802 (bpf_int32
)ntohs(0x0281), (bpf_int32
)ntohs(0x07FF));
803 b2
= gen_cmp(base_off
+ 2 + 1 + offset_sh
,
804 BPF_H
, (bpf_int32
)ntohs(addr
));
807 /* Check for pad = 0, short header case */
808 tmp
= gen_mcmp(base_off
+ 2, BPF_B
, (bpf_int32
)0x02, (bpf_int32
)0x7);
809 b2
= gen_cmp(base_off
+ 2 + offset_sh
, BPF_H
, (bpf_int32
)ntohs(addr
));
813 /* Combine with test for linktype */
818 static struct block
*
819 gen_host(addr
, mask
, proto
, dir
)
825 struct block
*b0
, *b1
;
830 b0
= gen_host(addr
, mask
, Q_IP
, dir
);
831 b1
= gen_host(addr
, mask
, Q_ARP
, dir
);
833 b0
= gen_host(addr
, mask
, Q_RARP
, dir
);
838 return gen_hostop(addr
, mask
, dir
, ETHERTYPE_IP
,
839 off_nl
+ 12, off_nl
+ 16);
842 return gen_hostop(addr
, mask
, dir
, ETHERTYPE_REVARP
,
843 off_nl
+ 14, off_nl
+ 24);
846 return gen_hostop(addr
, mask
, dir
, ETHERTYPE_ARP
,
847 off_nl
+ 14, off_nl
+ 24);
850 bpf_error("'tcp' modifier applied to host");
853 bpf_error("'udp' modifier applied to host");
856 bpf_error("'icmp' modifier applied to host");
859 bpf_error("'igmp' modifier applied to host");
862 return gen_dnhostop(addr
, dir
, off_nl
);
865 bpf_error("LAT host filtering not implemented");
868 bpf_error("MOPDL host filtering not implemented");
871 bpf_error("MOPRC host filtering not implemented");
879 static struct block
*
880 gen_gateway(eaddr
, alist
, proto
, dir
)
886 struct block
*b0
, *b1
, *tmp
;
889 bpf_error("direction applied to 'gateway'");
896 if (linktype
== DLT_EN10MB
)
897 b0
= gen_ehostop(eaddr
, Q_OR
);
898 else if (linktype
== DLT_FDDI
)
899 b0
= gen_fhostop(eaddr
, Q_OR
);
902 "'gateway' supported only on ethernet or FDDI");
904 b1
= gen_host(**alist
++, 0xffffffffL
, proto
, Q_OR
);
906 tmp
= gen_host(**alist
++, 0xffffffffL
, proto
, Q_OR
);
914 bpf_error("illegal modifier of 'gateway'");
919 gen_proto_abbrev(proto
)
922 struct block
*b0
, *b1
;
927 b0
= gen_linktype(ETHERTYPE_IP
);
928 b1
= gen_cmp(off_nl
+ 9, BPF_B
, (bpf_int32
)IPPROTO_TCP
);
933 b0
= gen_linktype(ETHERTYPE_IP
);
934 b1
= gen_cmp(off_nl
+ 9, BPF_B
, (bpf_int32
)IPPROTO_UDP
);
939 b0
= gen_linktype(ETHERTYPE_IP
);
940 b1
= gen_cmp(off_nl
+ 9, BPF_B
, (bpf_int32
)IPPROTO_ICMP
);
945 b0
= gen_linktype(ETHERTYPE_IP
);
946 b1
= gen_cmp(off_nl
+ 9, BPF_B
, (bpf_int32
)2);
951 b1
= gen_linktype(ETHERTYPE_IP
);
955 b1
= gen_linktype(ETHERTYPE_ARP
);
959 b1
= gen_linktype(ETHERTYPE_REVARP
);
963 bpf_error("link layer applied in wrong context");
966 b1
= gen_linktype(ETHERTYPE_DN
);
970 b1
= gen_linktype(ETHERTYPE_LAT
);
974 b1
= gen_linktype(ETHERTYPE_MOPDL
);
978 b1
= gen_linktype(ETHERTYPE_MOPRC
);
987 static struct block
*
994 s
= new_stmt(BPF_LD
|BPF_H
|BPF_ABS
);
996 b
= new_block(JMP(BPF_JSET
));
1004 static struct block
*
1005 gen_portatom(off
, v
)
1012 s
= new_stmt(BPF_LDX
|BPF_MSH
|BPF_B
);
1015 s
->next
= new_stmt(BPF_LD
|BPF_IND
|BPF_H
);
1016 s
->next
->s
.k
= off_nl
+ off
;
1018 b
= new_block(JMP(BPF_JEQ
));
1026 gen_portop(port
, proto
, dir
)
1027 int port
, proto
, dir
;
1029 struct block
*b0
, *b1
, *tmp
;
1031 /* ip proto 'proto' */
1032 tmp
= gen_cmp(off_nl
+ 9, BPF_B
, (bpf_int32
)proto
);
1038 b1
= gen_portatom(0, (bpf_int32
)port
);
1042 b1
= gen_portatom(2, (bpf_int32
)port
);
1047 tmp
= gen_portatom(0, (bpf_int32
)port
);
1048 b1
= gen_portatom(2, (bpf_int32
)port
);
1053 tmp
= gen_portatom(0, (bpf_int32
)port
);
1054 b1
= gen_portatom(2, (bpf_int32
)port
);
1066 static struct block
*
1067 gen_port(port
, ip_proto
, dir
)
1072 struct block
*b0
, *b1
, *tmp
;
1074 /* ether proto ip */
1075 b0
= gen_linktype(ETHERTYPE_IP
);
1080 b1
= gen_portop(port
, ip_proto
, dir
);
1084 tmp
= gen_portop(port
, IPPROTO_TCP
, dir
);
1085 b1
= gen_portop(port
, IPPROTO_UDP
, dir
);
1097 lookup_proto(name
, proto
)
1106 v
= pcap_nametoproto(name
);
1107 if (v
== PROTO_UNDEF
)
1108 bpf_error("unknown ip proto '%s'", name
);
1112 /* XXX should look up h/w protocol type based on linktype */
1113 v
= pcap_nametoeproto(name
);
1114 if (v
== PROTO_UNDEF
)
1115 bpf_error("unknown ether proto '%s'", name
);
1125 static struct block
*
1126 gen_proto(v
, proto
, dir
)
1131 struct block
*b0
, *b1
;
1133 if (dir
!= Q_DEFAULT
)
1134 bpf_error("direction applied to 'proto'");
1139 b0
= gen_linktype(ETHERTYPE_IP
);
1140 b1
= gen_cmp(off_nl
+ 9, BPF_B
, (bpf_int32
)v
);
1145 bpf_error("arp does not encapsulate another protocol");
1149 bpf_error("rarp does not encapsulate another protocol");
1153 bpf_error("decnet encapsulation is not specifiable");
1157 bpf_error("lat does not encapsulate another protocol");
1161 bpf_error("moprc does not encapsulate another protocol");
1165 bpf_error("mopdl does not encapsulate another protocol");
1169 return gen_linktype(v
);
1172 bpf_error("'udp proto' is bogus");
1176 bpf_error("'tcp proto' is bogus");
1180 bpf_error("'icmp proto' is bogus");
1184 bpf_error("'igmp proto' is bogus");
1195 * Left justify 'addr' and return its resulting network mask.
1201 register bpf_u_int32 m
= 0xffffffff;
1204 while ((*addr
& 0xff000000) == 0)
1205 *addr
<<= 8, m
<<= 8;
1215 int proto
= q
.proto
;
1218 bpf_u_int32 mask
, addr
, **alist
;
1219 struct block
*b
, *tmp
;
1220 int port
, real_proto
;
1225 addr
= pcap_nametonetaddr(name
);
1227 bpf_error("unknown network '%s'", name
);
1228 mask
= net_mask(&addr
);
1229 return gen_host(addr
, mask
, proto
, dir
);
1233 if (proto
== Q_LINK
) {
1237 eaddr
= pcap_ether_hostton(name
);
1240 "unknown ether host '%s'", name
);
1241 return gen_ehostop(eaddr
, dir
);
1244 eaddr
= pcap_ether_hostton(name
);
1247 "unknown FDDI host '%s'", name
);
1248 return gen_fhostop(eaddr
, dir
);
1252 "only ethernet/FDDI supports link-level host name");
1255 } else if (proto
== Q_DECNET
) {
1256 unsigned short dn_addr
= __pcap_nametodnaddr(name
);
1258 * I don't think DECNET hosts can be multihomed, so
1259 * there is no need to build up a list of addresses
1261 return (gen_host(dn_addr
, 0, proto
, dir
));
1263 alist
= pcap_nametoaddr(name
);
1264 if (alist
== NULL
|| *alist
== NULL
)
1265 bpf_error("unknown host '%s'", name
);
1266 b
= gen_host(**alist
++, 0xffffffffL
, proto
, dir
);
1268 tmp
= gen_host(**alist
++, 0xffffffffL
,
1277 if (proto
!= Q_DEFAULT
&& proto
!= Q_UDP
&& proto
!= Q_TCP
)
1278 bpf_error("illegal qualifier of 'port'");
1279 if (pcap_nametoport(name
, &port
, &real_proto
) == 0)
1280 bpf_error("unknown port '%s'", name
);
1281 if (proto
== Q_UDP
) {
1282 if (real_proto
== IPPROTO_TCP
)
1283 bpf_error("port '%s' is tcp", name
);
1285 /* override PROTO_UNDEF */
1286 real_proto
= IPPROTO_UDP
;
1288 if (proto
== Q_TCP
) {
1289 if (real_proto
== IPPROTO_UDP
)
1290 bpf_error("port '%s' is udp", name
);
1292 /* override PROTO_UNDEF */
1293 real_proto
= IPPROTO_TCP
;
1295 return gen_port(port
, real_proto
, dir
);
1298 eaddr
= pcap_ether_hostton(name
);
1300 bpf_error("unknown ether host: %s", name
);
1302 alist
= pcap_nametoaddr(name
);
1303 if (alist
== NULL
|| *alist
== NULL
)
1304 bpf_error("unknown host '%s'", name
);
1305 return gen_gateway(eaddr
, alist
, proto
, dir
);
1308 real_proto
= lookup_proto(name
, proto
);
1309 if (real_proto
>= 0)
1310 return gen_proto(real_proto
, proto
, dir
);
1312 bpf_error("unknown protocol: %s", name
);
1328 int proto
= q
.proto
;
1336 if (proto
== Q_DECNET
)
1337 return gen_host(v
, 0, proto
, dir
);
1338 else if (proto
== Q_LINK
) {
1339 bpf_error("illegal link layer address");
1341 mask
= net_mask(&v
);
1342 return gen_host(v
, mask
, proto
, dir
);
1347 proto
= IPPROTO_UDP
;
1348 else if (proto
== Q_TCP
)
1349 proto
= IPPROTO_TCP
;
1350 else if (proto
== Q_DEFAULT
)
1351 proto
= PROTO_UNDEF
;
1353 bpf_error("illegal qualifier of 'port'");
1355 return gen_port((int)v
, proto
, dir
);
1358 bpf_error("'gateway' requires a name");
1362 return gen_proto((int)v
, proto
, dir
);
1380 if ((q
.addr
== Q_HOST
|| q
.addr
== Q_DEFAULT
) && q
.proto
== Q_LINK
) {
1381 if (linktype
== DLT_EN10MB
)
1382 return gen_ehostop(eaddr
, (int)q
.dir
);
1383 if (linktype
== DLT_FDDI
)
1384 return gen_fhostop(eaddr
, (int)q
.dir
);
1386 bpf_error("ethernet address used in non-ether expression");
1392 struct slist
*s0
, *s1
;
1395 * This is definitely not the best way to do this, but the
1396 * lists will rarely get long.
1403 static struct slist
*
1409 s
= new_stmt(BPF_LDX
|BPF_MEM
);
1414 static struct slist
*
1420 s
= new_stmt(BPF_LD
|BPF_MEM
);
1426 gen_load(proto
, index
, size
)
1431 struct slist
*s
, *tmp
;
1433 int regno
= alloc_reg();
1435 free_reg(index
->regno
);
1439 bpf_error("data size must be 1, 2, or 4");
1455 bpf_error("unsupported index operation");
1458 s
= xfer_to_x(index
);
1459 tmp
= new_stmt(BPF_LD
|BPF_IND
|size
);
1461 sappend(index
->s
, s
);
1471 /* XXX Note that we assume a fixed link link header here. */
1472 s
= xfer_to_x(index
);
1473 tmp
= new_stmt(BPF_LD
|BPF_IND
|size
);
1476 sappend(index
->s
, s
);
1478 b
= gen_proto_abbrev(proto
);
1480 gen_and(index
->b
, b
);
1488 s
= new_stmt(BPF_LDX
|BPF_MSH
|BPF_B
);
1490 sappend(s
, xfer_to_a(index
));
1491 sappend(s
, new_stmt(BPF_ALU
|BPF_ADD
|BPF_X
));
1492 sappend(s
, new_stmt(BPF_MISC
|BPF_TAX
));
1493 sappend(s
, tmp
= new_stmt(BPF_LD
|BPF_IND
|size
));
1495 sappend(index
->s
, s
);
1497 gen_and(gen_proto_abbrev(proto
), b
= gen_ipfrag());
1499 gen_and(index
->b
, b
);
1503 index
->regno
= regno
;
1504 s
= new_stmt(BPF_ST
);
1506 sappend(index
->s
, s
);
1512 gen_relation(code
, a0
, a1
, reversed
)
1514 struct arth
*a0
, *a1
;
1517 struct slist
*s0
, *s1
, *s2
;
1518 struct block
*b
, *tmp
;
1522 s2
= new_stmt(BPF_ALU
|BPF_SUB
|BPF_X
);
1523 b
= new_block(JMP(code
));
1524 if (code
== BPF_JGT
|| code
== BPF_JGE
) {
1525 reversed
= !reversed
;
1526 b
->s
.k
= 0x80000000;
1534 sappend(a0
->s
, a1
->s
);
1538 free_reg(a0
->regno
);
1539 free_reg(a1
->regno
);
1541 /* 'and' together protocol checks */
1544 gen_and(a0
->b
, tmp
= a1
->b
);
1560 int regno
= alloc_reg();
1561 struct arth
*a
= (struct arth
*)newchunk(sizeof(*a
));
1564 s
= new_stmt(BPF_LD
|BPF_LEN
);
1565 s
->next
= new_stmt(BPF_ST
);
1566 s
->next
->s
.k
= regno
;
1581 a
= (struct arth
*)newchunk(sizeof(*a
));
1585 s
= new_stmt(BPF_LD
|BPF_IMM
);
1587 s
->next
= new_stmt(BPF_ST
);
1603 s
= new_stmt(BPF_ALU
|BPF_NEG
);
1606 s
= new_stmt(BPF_ST
);
1614 gen_arth(code
, a0
, a1
)
1616 struct arth
*a0
, *a1
;
1618 struct slist
*s0
, *s1
, *s2
;
1622 s2
= new_stmt(BPF_ALU
|BPF_X
|code
);
1627 sappend(a0
->s
, a1
->s
);
1629 free_reg(a1
->regno
);
1631 s0
= new_stmt(BPF_ST
);
1632 a0
->regno
= s0
->s
.k
= alloc_reg();
1639 * Here we handle simple allocation of the scratch registers.
1640 * If too many registers are alloc'd, the allocator punts.
1642 static int regused
[BPF_MEMWORDS
];
1646 * Return the next free register.
1651 int n
= BPF_MEMWORDS
;
1654 if (regused
[curreg
])
1655 curreg
= (curreg
+ 1) % BPF_MEMWORDS
;
1657 regused
[curreg
] = 1;
1661 bpf_error("too many registers needed to evaluate expression");
1666 * Return a register to the table so it can
1676 static struct block
*
1683 s
= new_stmt(BPF_LD
|BPF_LEN
);
1684 b
= new_block(JMP(jmp
));
1695 return gen_len(BPF_JGE
, n
);
1704 b
= gen_len(BPF_JGT
, n
);
1711 gen_byteop(op
, idx
, val
)
1722 return gen_cmp((u_int
)idx
, BPF_B
, (bpf_int32
)val
);
1725 b
= gen_cmp((u_int
)idx
, BPF_B
, (bpf_int32
)val
);
1726 b
->s
.code
= JMP(BPF_JGE
);
1731 b
= gen_cmp((u_int
)idx
, BPF_B
, (bpf_int32
)val
);
1732 b
->s
.code
= JMP(BPF_JGT
);
1736 s
= new_stmt(BPF_ALU
|BPF_OR
|BPF_K
);
1740 s
= new_stmt(BPF_ALU
|BPF_AND
|BPF_K
);
1744 b
= new_block(JMP(BPF_JEQ
));
1752 gen_broadcast(proto
)
1755 bpf_u_int32 hostmask
;
1756 struct block
*b0
, *b1
, *b2
;
1757 static u_char ebroadcast
[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1763 if (linktype
== DLT_EN10MB
)
1764 return gen_ehostop(ebroadcast
, Q_DST
);
1765 if (linktype
== DLT_FDDI
)
1766 return gen_fhostop(ebroadcast
, Q_DST
);
1767 bpf_error("not a broadcast link");
1771 b0
= gen_linktype(ETHERTYPE_IP
);
1772 hostmask
= ~netmask
;
1773 b1
= gen_mcmp(off_nl
+ 16, BPF_W
, (bpf_int32
)0, hostmask
);
1774 b2
= gen_mcmp(off_nl
+ 16, BPF_W
,
1775 (bpf_int32
)(~0 & hostmask
), hostmask
);
1780 bpf_error("only ether/ip broadcast filters supported");
1784 gen_multicast(proto
)
1787 register struct block
*b0
, *b1
;
1788 register struct slist
*s
;
1794 if (linktype
== DLT_EN10MB
) {
1795 /* ether[0] & 1 != 0 */
1796 s
= new_stmt(BPF_LD
|BPF_B
|BPF_ABS
);
1798 b0
= new_block(JMP(BPF_JSET
));
1804 if (linktype
== DLT_FDDI
) {
1805 /* XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX */
1806 /* fddi[1] & 1 != 0 */
1807 s
= new_stmt(BPF_LD
|BPF_B
|BPF_ABS
);
1809 b0
= new_block(JMP(BPF_JSET
));
1814 /* Link not known to support multicasts */
1818 b0
= gen_linktype(ETHERTYPE_IP
);
1819 b1
= gen_cmp(off_nl
+ 16, BPF_B
, (bpf_int32
)224);
1820 b1
->s
.code
= JMP(BPF_JGE
);
1824 bpf_error("only IP multicast filters supported on ethernet/FDDI");
1828 * generate command for inbound/outbound. It's here so we can
1829 * make it link-type specific. 'dir' = 0 implies "inbound",
1830 * = 1 implies "outbound".
1836 register struct block
*b0
;
1838 b0
= gen_relation(BPF_JEQ
,
1839 gen_load(Q_LINK
, gen_loadi(0), 1),