f3fc5a60fe8282e4e21af2162f7e561d018023e3
2 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 static const char rcsid
[] =
23 "@(#) $Header: /usr/local/cvs/linux/tools/build/e100boot/libpcap-0.4/gencode.c,v 1.1 1999/08/26 10:05:22 johana Exp $ (LBL)";
26 #include <sys/types.h>
27 #include <sys/socket.h>
37 #include <netinet/in.h>
38 #include <netinet/if_ether.h>
51 #include "ethertype.h"
54 #include <pcap-namedb.h>
57 #ifdef HAVE_OS_PROTO_H
61 #define JMP(c) ((c)|BPF_JMP|BPF_K)
64 static jmp_buf top_ctx
;
65 static pcap_t
*bpf_pcap
;
69 int pcap_fddipad
= PCAP_FDDIPAD
;
77 bpf_error(const char *fmt
, ...)
79 bpf_error(fmt
, va_alist
)
92 (void)vsprintf(pcap_geterr(bpf_pcap
), fmt
, ap
);
98 static void init_linktype(int);
100 static int alloc_reg(void);
101 static void free_reg(int);
103 static struct block
*root
;
106 * We divy out chunks of memory rather than call malloc each time so
107 * we don't have to worry about leaking memory. It's probably
108 * not a big deal if all this memory was wasted but it this ever
109 * goes into a library that would probably not be a good idea.
112 #define CHUNK0SIZE 1024
118 static struct chunk chunks
[NCHUNKS
];
119 static int cur_chunk
;
121 static void *newchunk(u_int
);
122 static void freechunks(void);
123 static inline struct block
*new_block(int);
124 static inline struct slist
*new_stmt(int);
125 static struct block
*gen_retblk(int);
126 static inline void syntax(void);
128 static void backpatch(struct block
*, struct block
*);
129 static void merge(struct block
*, struct block
*);
130 static struct block
*gen_cmp(u_int
, u_int
, bpf_int32
);
131 static struct block
*gen_mcmp(u_int
, u_int
, bpf_int32
, bpf_u_int32
);
132 static struct block
*gen_bcmp(u_int
, u_int
, const u_char
*);
133 static struct block
*gen_uncond(int);
134 static inline struct block
*gen_true(void);
135 static inline struct block
*gen_false(void);
136 static struct block
*gen_linktype(int);
137 static struct block
*gen_hostop(bpf_u_int32
, bpf_u_int32
, int, int, u_int
, u_int
);
138 static struct block
*gen_ehostop(const u_char
*, int);
139 static struct block
*gen_fhostop(const u_char
*, int);
140 static struct block
*gen_dnhostop(bpf_u_int32
, int, u_int
);
141 static struct block
*gen_host(bpf_u_int32
, bpf_u_int32
, int, int);
142 static struct block
*gen_gateway(const u_char
*, bpf_u_int32
**, int, int);
143 static struct block
*gen_ipfrag(void);
144 static struct block
*gen_portatom(int, bpf_int32
);
145 struct block
*gen_portop(int, int, int);
146 static struct block
*gen_port(int, int, int);
147 static int lookup_proto(const char *, int);
148 static struct block
*gen_proto(int, int, int);
149 static struct slist
*xfer_to_x(struct arth
*);
150 static struct slist
*xfer_to_a(struct arth
*);
151 static struct block
*gen_len(int, int);
160 /* XXX Round up to nearest long. */
161 n
= (n
+ sizeof(long) - 1) & ~(sizeof(long) - 1);
163 cp
= &chunks
[cur_chunk
];
164 if (n
> cp
->n_left
) {
165 ++cp
, k
= ++cur_chunk
;
167 bpf_error("out of memory");
168 size
= CHUNK0SIZE
<< k
;
169 cp
->m
= (void *)malloc(size
);
170 memset((char *)cp
->m
, 0, size
);
173 bpf_error("out of memory");
176 return (void *)((char *)cp
->m
+ cp
->n_left
);
185 for (i
= 0; i
< NCHUNKS
; ++i
)
186 if (chunks
[i
].m
!= NULL
) {
193 * A strdup whose allocations are freed after code generation is over.
197 register const char *s
;
199 int n
= strlen(s
) + 1;
200 char *cp
= newchunk(n
);
206 static inline struct block
*
212 p
= (struct block
*)newchunk(sizeof(*p
));
219 static inline struct slist
*
225 p
= (struct slist
*)newchunk(sizeof(*p
));
231 static struct block
*
235 struct block
*b
= new_block(BPF_RET
|BPF_K
);
244 bpf_error("syntax error in filter expression");
247 static bpf_u_int32 netmask
;
251 pcap_compile(pcap_t
*p
, struct bpf_program
*program
,
252 char *buf
, int optimize
, bpf_u_int32 mask
)
260 if (setjmp(top_ctx
)) {
266 snaplen
= pcap_snapshot(p
);
268 lex_init(buf
? buf
: "");
269 init_linktype(pcap_datalink(p
));
276 root
= gen_retblk(snaplen
);
281 (root
->s
.code
== (BPF_RET
|BPF_K
) && root
->s
.k
== 0))
282 bpf_error("expression rejects all packets");
284 program
->bf_insns
= icode_to_fcode(root
, &len
);
285 program
->bf_len
= len
;
292 * Backpatch the blocks in 'list' to 'target'. The 'sense' field indicates
293 * which of the jt and jf fields has been resolved and which is a pointer
294 * back to another unresolved block (or nil). At least one of the fields
295 * in each block is already resolved.
298 backpatch(list
, target
)
299 struct block
*list
, *target
;
316 * Merge the lists in b0 and b1, using the 'sense' field to indicate
317 * which of jt and jf is the link.
321 struct block
*b0
, *b1
;
323 register struct block
**p
= &b0
;
325 /* Find end of list. */
327 p
= !((*p
)->sense
) ? &JT(*p
) : &JF(*p
);
329 /* Concatenate the lists. */
337 backpatch(p
, gen_retblk(snaplen
));
338 p
->sense
= !p
->sense
;
339 backpatch(p
, gen_retblk(0));
345 struct block
*b0
, *b1
;
347 backpatch(b0
, b1
->head
);
348 b0
->sense
= !b0
->sense
;
349 b1
->sense
= !b1
->sense
;
351 b1
->sense
= !b1
->sense
;
357 struct block
*b0
, *b1
;
359 b0
->sense
= !b0
->sense
;
360 backpatch(b0
, b1
->head
);
361 b0
->sense
= !b0
->sense
;
370 b
->sense
= !b
->sense
;
373 static struct block
*
374 gen_cmp(offset
, size
, v
)
381 s
= new_stmt(BPF_LD
|BPF_ABS
|size
);
384 b
= new_block(JMP(BPF_JEQ
));
391 static struct block
*
392 gen_mcmp(offset
, size
, v
, mask
)
397 struct block
*b
= gen_cmp(offset
, size
, v
);
400 if (mask
!= 0xffffffff) {
401 s
= new_stmt(BPF_ALU
|BPF_AND
|BPF_K
);
408 static struct block
*
409 gen_bcmp(offset
, size
, v
)
410 register u_int offset
, size
;
411 register const u_char
*v
;
413 register struct block
*b
, *tmp
;
417 register const u_char
*p
= &v
[size
- 4];
418 bpf_int32 w
= ((bpf_int32
)p
[0] << 24) |
419 ((bpf_int32
)p
[1] << 16) | ((bpf_int32
)p
[2] << 8) | p
[3];
421 tmp
= gen_cmp(offset
+ size
- 4, BPF_W
, w
);
428 register const u_char
*p
= &v
[size
- 2];
429 bpf_int32 w
= ((bpf_int32
)p
[0] << 8) | p
[1];
431 tmp
= gen_cmp(offset
+ size
- 2, BPF_H
, w
);
438 tmp
= gen_cmp(offset
, BPF_B
, (bpf_int32
)v
[0]);
447 * Various code constructs need to know the layout of the data link
448 * layer. These variables give the necessary offsets. off_linktype
449 * is set to -1 for no encapsulation, in which case, IP is assumed.
451 static u_int off_linktype
;
470 * SLIP doesn't have a link level type. The 16 byte
471 * header is hacked into our SLIP driver.
478 /* XXX this may be the same as the DLT_PPP_BSDOS case */
501 * FDDI doesn't really have a link-level type field.
502 * We assume that SSAP = SNAP is being used and pick
503 * out the encapsulated Ethernet type.
507 off_linktype
+= pcap_fddipad
;
511 off_nl
+= pcap_fddipad
;
520 case DLT_ATM_RFC1483
:
522 * assume routed, non-ISO PDUs
523 * (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00)
534 bpf_error("unknown data link type 0x%x", linktype
);
538 static struct block
*
545 s
= new_stmt(BPF_LD
|BPF_IMM
);
547 b
= new_block(JMP(BPF_JEQ
));
553 static inline struct block
*
556 return gen_uncond(1);
559 static inline struct block
*
562 return gen_uncond(0);
565 static struct block
*
569 struct block
*b0
, *b1
;
571 /* If we're not using encapsulation and checking for IP, we're done */
572 if (off_linktype
== -1 && proto
== ETHERTYPE_IP
)
581 if (proto
== ETHERTYPE_IP
)
582 proto
= PPP_IP
; /* XXX was 0x21 */
589 b0
= gen_cmp(off_linktype
, BPF_H
, PPP_IP
);
590 b1
= gen_cmp(off_linktype
, BPF_H
, PPP_VJC
);
592 b0
= gen_cmp(off_linktype
, BPF_H
, PPP_VJNC
);
600 case ETHERTYPE_ATALK
:
612 if (proto
== ETHERTYPE_IP
)
613 return (gen_cmp(0, BPF_W
, (bpf_int32
)htonl(AF_INET
)));
617 return gen_cmp(off_linktype
, BPF_H
, (bpf_int32
)proto
);
620 static struct block
*
621 gen_hostop(addr
, mask
, dir
, proto
, src_off
, dst_off
)
625 u_int src_off
, dst_off
;
627 struct block
*b0
, *b1
;
641 b0
= gen_hostop(addr
, mask
, Q_SRC
, proto
, src_off
, dst_off
);
642 b1
= gen_hostop(addr
, mask
, Q_DST
, proto
, src_off
, dst_off
);
648 b0
= gen_hostop(addr
, mask
, Q_SRC
, proto
, src_off
, dst_off
);
649 b1
= gen_hostop(addr
, mask
, Q_DST
, proto
, src_off
, dst_off
);
656 b0
= gen_linktype(proto
);
657 b1
= gen_mcmp(offset
, BPF_W
, (bpf_int32
)addr
, mask
);
662 static struct block
*
663 gen_ehostop(eaddr
, dir
)
664 register const u_char
*eaddr
;
667 register struct block
*b0
, *b1
;
671 return gen_bcmp(6, 6, eaddr
);
674 return gen_bcmp(0, 6, eaddr
);
677 b0
= gen_ehostop(eaddr
, Q_SRC
);
678 b1
= gen_ehostop(eaddr
, Q_DST
);
684 b0
= gen_ehostop(eaddr
, Q_SRC
);
685 b1
= gen_ehostop(eaddr
, Q_DST
);
694 * Like gen_ehostop, but for DLT_FDDI
696 static struct block
*
697 gen_fhostop(eaddr
, dir
)
698 register const u_char
*eaddr
;
701 struct block
*b0
, *b1
;
706 return gen_bcmp(6 + 1 + pcap_fddipad
, 6, eaddr
);
708 return gen_bcmp(6 + 1, 6, eaddr
);
713 return gen_bcmp(0 + 1 + pcap_fddipad
, 6, eaddr
);
715 return gen_bcmp(0 + 1, 6, eaddr
);
719 b0
= gen_fhostop(eaddr
, Q_SRC
);
720 b1
= gen_fhostop(eaddr
, Q_DST
);
726 b0
= gen_fhostop(eaddr
, Q_SRC
);
727 b1
= gen_fhostop(eaddr
, Q_DST
);
736 * This is quite tricky because there may be pad bytes in front of the
737 * DECNET header, and then there are two possible data packet formats that
738 * carry both src and dst addresses, plus 5 packet types in a format that
739 * carries only the src node, plus 2 types that use a different format and
740 * also carry just the src node.
744 * Instead of doing those all right, we just look for data packets with
745 * 0 or 1 bytes of padding. If you want to look at other packets, that
746 * will require a lot more hacking.
748 * To add support for filtering on DECNET "areas" (network numbers)
749 * one would want to add a "mask" argument to this routine. That would
750 * make the filter even more inefficient, although one could be clever
751 * and not generate masking instructions if the mask is 0xFFFF.
753 static struct block
*
754 gen_dnhostop(addr
, dir
, base_off
)
759 struct block
*b0
, *b1
, *b2
, *tmp
;
760 u_int offset_lh
; /* offset if long header is received */
761 u_int offset_sh
; /* offset if short header is received */
766 offset_sh
= 1; /* follows flags */
767 offset_lh
= 7; /* flgs,darea,dsubarea,HIORD */
771 offset_sh
= 3; /* follows flags, dstnode */
772 offset_lh
= 15; /* flgs,darea,dsubarea,did,sarea,ssub,HIORD */
776 /* Inefficient because we do our Calvinball dance twice */
777 b0
= gen_dnhostop(addr
, Q_SRC
, base_off
);
778 b1
= gen_dnhostop(addr
, Q_DST
, base_off
);
784 /* Inefficient because we do our Calvinball dance twice */
785 b0
= gen_dnhostop(addr
, Q_SRC
, base_off
);
786 b1
= gen_dnhostop(addr
, Q_DST
, base_off
);
793 b0
= gen_linktype(ETHERTYPE_DN
);
794 /* Check for pad = 1, long header case */
795 tmp
= gen_mcmp(base_off
+ 2, BPF_H
,
796 (bpf_int32
)ntohs(0x0681), (bpf_int32
)ntohs(0x07FF));
797 b1
= gen_cmp(base_off
+ 2 + 1 + offset_lh
,
798 BPF_H
, (bpf_int32
)ntohs(addr
));
800 /* Check for pad = 0, long header case */
801 tmp
= gen_mcmp(base_off
+ 2, BPF_B
, (bpf_int32
)0x06, (bpf_int32
)0x7);
802 b2
= gen_cmp(base_off
+ 2 + offset_lh
, BPF_H
, (bpf_int32
)ntohs(addr
));
805 /* Check for pad = 1, short header case */
806 tmp
= gen_mcmp(base_off
+ 2, BPF_H
,
807 (bpf_int32
)ntohs(0x0281), (bpf_int32
)ntohs(0x07FF));
808 b2
= gen_cmp(base_off
+ 2 + 1 + offset_sh
,
809 BPF_H
, (bpf_int32
)ntohs(addr
));
812 /* Check for pad = 0, short header case */
813 tmp
= gen_mcmp(base_off
+ 2, BPF_B
, (bpf_int32
)0x02, (bpf_int32
)0x7);
814 b2
= gen_cmp(base_off
+ 2 + offset_sh
, BPF_H
, (bpf_int32
)ntohs(addr
));
818 /* Combine with test for linktype */
823 static struct block
*
824 gen_host(addr
, mask
, proto
, dir
)
830 struct block
*b0
, *b1
;
835 b0
= gen_host(addr
, mask
, Q_IP
, dir
);
836 b1
= gen_host(addr
, mask
, Q_ARP
, dir
);
838 b0
= gen_host(addr
, mask
, Q_RARP
, dir
);
843 return gen_hostop(addr
, mask
, dir
, ETHERTYPE_IP
,
844 off_nl
+ 12, off_nl
+ 16);
847 return gen_hostop(addr
, mask
, dir
, ETHERTYPE_REVARP
,
848 off_nl
+ 14, off_nl
+ 24);
851 return gen_hostop(addr
, mask
, dir
, ETHERTYPE_ARP
,
852 off_nl
+ 14, off_nl
+ 24);
855 bpf_error("'tcp' modifier applied to host");
858 bpf_error("'udp' modifier applied to host");
861 bpf_error("'icmp' modifier applied to host");
864 bpf_error("'igmp' modifier applied to host");
867 bpf_error("'igrp' modifier applied to host");
870 bpf_error("ATALK host filtering not implemented");
873 return gen_dnhostop(addr
, dir
, off_nl
);
876 bpf_error("SCA host filtering not implemented");
879 bpf_error("LAT host filtering not implemented");
882 bpf_error("MOPDL host filtering not implemented");
885 bpf_error("MOPRC host filtering not implemented");
893 static struct block
*
894 gen_gateway(eaddr
, alist
, proto
, dir
)
900 struct block
*b0
, *b1
, *tmp
;
903 bpf_error("direction applied to 'gateway'");
910 if (linktype
== DLT_EN10MB
)
911 b0
= gen_ehostop(eaddr
, Q_OR
);
912 else if (linktype
== DLT_FDDI
)
913 b0
= gen_fhostop(eaddr
, Q_OR
);
916 "'gateway' supported only on ethernet or FDDI");
918 b1
= gen_host(**alist
++, 0xffffffff, proto
, Q_OR
);
920 tmp
= gen_host(**alist
++, 0xffffffff, proto
, Q_OR
);
928 bpf_error("illegal modifier of 'gateway'");
933 gen_proto_abbrev(proto
)
936 struct block
*b0
, *b1
;
941 b0
= gen_linktype(ETHERTYPE_IP
);
942 b1
= gen_cmp(off_nl
+ 9, BPF_B
, (bpf_int32
)IPPROTO_TCP
);
947 b0
= gen_linktype(ETHERTYPE_IP
);
948 b1
= gen_cmp(off_nl
+ 9, BPF_B
, (bpf_int32
)IPPROTO_UDP
);
953 b0
= gen_linktype(ETHERTYPE_IP
);
954 b1
= gen_cmp(off_nl
+ 9, BPF_B
, (bpf_int32
)IPPROTO_ICMP
);
959 b0
= gen_linktype(ETHERTYPE_IP
);
960 b1
= gen_cmp(off_nl
+ 9, BPF_B
, (bpf_int32
)2);
965 #define IPPROTO_IGRP 9
968 b0
= gen_linktype(ETHERTYPE_IP
);
969 b1
= gen_cmp(off_nl
+ 9, BPF_B
, (long)IPPROTO_IGRP
);
974 b1
= gen_linktype(ETHERTYPE_IP
);
978 b1
= gen_linktype(ETHERTYPE_ARP
);
982 b1
= gen_linktype(ETHERTYPE_REVARP
);
986 bpf_error("link layer applied in wrong context");
989 b1
= gen_linktype(ETHERTYPE_ATALK
);
993 b1
= gen_linktype(ETHERTYPE_DN
);
997 b1
= gen_linktype(ETHERTYPE_SCA
);
1001 b1
= gen_linktype(ETHERTYPE_LAT
);
1005 b1
= gen_linktype(ETHERTYPE_MOPDL
);
1009 b1
= gen_linktype(ETHERTYPE_MOPRC
);
1018 static struct block
*
1025 s
= new_stmt(BPF_LD
|BPF_H
|BPF_ABS
);
1026 s
->s
.k
= off_nl
+ 6;
1027 b
= new_block(JMP(BPF_JSET
));
1035 static struct block
*
1036 gen_portatom(off
, v
)
1043 s
= new_stmt(BPF_LDX
|BPF_MSH
|BPF_B
);
1046 s
->next
= new_stmt(BPF_LD
|BPF_IND
|BPF_H
);
1047 s
->next
->s
.k
= off_nl
+ off
;
1049 b
= new_block(JMP(BPF_JEQ
));
1057 gen_portop(port
, proto
, dir
)
1058 int port
, proto
, dir
;
1060 struct block
*b0
, *b1
, *tmp
;
1062 /* ip proto 'proto' */
1063 tmp
= gen_cmp(off_nl
+ 9, BPF_B
, (bpf_int32
)proto
);
1069 b1
= gen_portatom(0, (bpf_int32
)port
);
1073 b1
= gen_portatom(2, (bpf_int32
)port
);
1078 tmp
= gen_portatom(0, (bpf_int32
)port
);
1079 b1
= gen_portatom(2, (bpf_int32
)port
);
1084 tmp
= gen_portatom(0, (bpf_int32
)port
);
1085 b1
= gen_portatom(2, (bpf_int32
)port
);
1097 static struct block
*
1098 gen_port(port
, ip_proto
, dir
)
1103 struct block
*b0
, *b1
, *tmp
;
1105 /* ether proto ip */
1106 b0
= gen_linktype(ETHERTYPE_IP
);
1111 b1
= gen_portop(port
, ip_proto
, dir
);
1115 tmp
= gen_portop(port
, IPPROTO_TCP
, dir
);
1116 b1
= gen_portop(port
, IPPROTO_UDP
, dir
);
1128 lookup_proto(name
, proto
)
1129 register const char *name
;
1138 v
= pcap_nametoproto(name
);
1139 if (v
== PROTO_UNDEF
)
1140 bpf_error("unknown ip proto '%s'", name
);
1144 /* XXX should look up h/w protocol type based on linktype */
1145 v
= pcap_nametoeproto(name
);
1146 if (v
== PROTO_UNDEF
)
1147 bpf_error("unknown ether proto '%s'", name
);
1157 static struct block
*
1158 gen_proto(v
, proto
, dir
)
1163 struct block
*b0
, *b1
;
1165 if (dir
!= Q_DEFAULT
)
1166 bpf_error("direction applied to 'proto'");
1171 b0
= gen_linktype(ETHERTYPE_IP
);
1172 b1
= gen_cmp(off_nl
+ 9, BPF_B
, (bpf_int32
)v
);
1177 bpf_error("arp does not encapsulate another protocol");
1181 bpf_error("rarp does not encapsulate another protocol");
1185 bpf_error("atalk encapsulation is not specifiable");
1189 bpf_error("decnet encapsulation is not specifiable");
1193 bpf_error("sca does not encapsulate another protocol");
1197 bpf_error("lat does not encapsulate another protocol");
1201 bpf_error("moprc does not encapsulate another protocol");
1205 bpf_error("mopdl does not encapsulate another protocol");
1209 return gen_linktype(v
);
1212 bpf_error("'udp proto' is bogus");
1216 bpf_error("'tcp proto' is bogus");
1220 bpf_error("'icmp proto' is bogus");
1224 bpf_error("'igmp proto' is bogus");
1228 bpf_error("'igrp proto' is bogus");
1240 register const char *name
;
1243 int proto
= q
.proto
;
1247 bpf_u_int32 mask
, addr
, **alist
;
1248 struct block
*b
, *tmp
;
1249 int port
, real_proto
;
1254 addr
= pcap_nametonetaddr(name
);
1256 bpf_error("unknown network '%s'", name
);
1257 /* Left justify network addr and calculate its network mask */
1259 while (addr
&& (addr
& 0xff000000) == 0) {
1263 return gen_host(addr
, mask
, proto
, dir
);
1267 if (proto
== Q_LINK
) {
1271 eaddr
= pcap_ether_hostton(name
);
1274 "unknown ether host '%s'", name
);
1275 return gen_ehostop(eaddr
, dir
);
1278 eaddr
= pcap_ether_hostton(name
);
1281 "unknown FDDI host '%s'", name
);
1282 return gen_fhostop(eaddr
, dir
);
1286 "only ethernet/FDDI supports link-level host name");
1289 } else if (proto
== Q_DECNET
) {
1290 unsigned short dn_addr
= __pcap_nametodnaddr(name
);
1292 * I don't think DECNET hosts can be multihomed, so
1293 * there is no need to build up a list of addresses
1295 return (gen_host(dn_addr
, 0, proto
, dir
));
1297 alist
= pcap_nametoaddr(name
);
1298 if (alist
== NULL
|| *alist
== NULL
)
1299 bpf_error("unknown host '%s'", name
);
1301 if (off_linktype
== -1 && tproto
== Q_DEFAULT
)
1303 b
= gen_host(**alist
++, 0xffffffff, tproto
, dir
);
1305 tmp
= gen_host(**alist
++, 0xffffffff,
1314 if (proto
!= Q_DEFAULT
&& proto
!= Q_UDP
&& proto
!= Q_TCP
)
1315 bpf_error("illegal qualifier of 'port'");
1316 if (pcap_nametoport(name
, &port
, &real_proto
) == 0)
1317 bpf_error("unknown port '%s'", name
);
1318 if (proto
== Q_UDP
) {
1319 if (real_proto
== IPPROTO_TCP
)
1320 bpf_error("port '%s' is tcp", name
);
1322 /* override PROTO_UNDEF */
1323 real_proto
= IPPROTO_UDP
;
1325 if (proto
== Q_TCP
) {
1326 if (real_proto
== IPPROTO_UDP
)
1327 bpf_error("port '%s' is udp", name
);
1329 /* override PROTO_UNDEF */
1330 real_proto
= IPPROTO_TCP
;
1332 return gen_port(port
, real_proto
, dir
);
1335 eaddr
= pcap_ether_hostton(name
);
1337 bpf_error("unknown ether host: %s", name
);
1339 alist
= pcap_nametoaddr(name
);
1340 if (alist
== NULL
|| *alist
== NULL
)
1341 bpf_error("unknown host '%s'", name
);
1342 return gen_gateway(eaddr
, alist
, proto
, dir
);
1345 real_proto
= lookup_proto(name
, proto
);
1346 if (real_proto
>= 0)
1347 return gen_proto(real_proto
, proto
, dir
);
1349 bpf_error("unknown protocol: %s", name
);
1360 gen_mcode(s1
, s2
, masklen
, q
)
1361 register const char *s1
, *s2
;
1362 register int masklen
;
1365 register int nlen
, mlen
;
1368 nlen
= __pcap_atoin(s1
, &n
);
1369 /* Promote short ipaddr */
1373 mlen
= __pcap_atoin(s2
, &m
);
1374 /* Promote short ipaddr */
1377 bpf_error("non-network bits set in \"%s mask %s\"",
1380 /* Convert mask len to mask */
1382 bpf_error("mask length must be <= 32");
1383 m
= 0xffffffff << (32 - masklen
);
1385 bpf_error("non-network bits set in \"%s/%d\"",
1392 return gen_host(n
, m
, q
.proto
, q
.dir
);
1395 bpf_error("Mask syntax for networks only");
1402 register const char *s
;
1407 int proto
= q
.proto
;
1413 else if (q
.proto
== Q_DECNET
)
1414 vlen
= __pcap_atodn(s
, &v
);
1416 vlen
= __pcap_atoin(s
, &v
);
1423 if (proto
== Q_DECNET
)
1424 return gen_host(v
, 0, proto
, dir
);
1425 else if (proto
== Q_LINK
) {
1426 bpf_error("illegal link layer address");
1429 if (s
== NULL
&& q
.addr
== Q_NET
) {
1430 /* Promote short net number */
1431 while (v
&& (v
& 0xff000000) == 0) {
1436 /* Promote short ipaddr */
1440 return gen_host(v
, mask
, proto
, dir
);
1445 proto
= IPPROTO_UDP
;
1446 else if (proto
== Q_TCP
)
1447 proto
= IPPROTO_TCP
;
1448 else if (proto
== Q_DEFAULT
)
1449 proto
= PROTO_UNDEF
;
1451 bpf_error("illegal qualifier of 'port'");
1453 return gen_port((int)v
, proto
, dir
);
1456 bpf_error("'gateway' requires a name");
1460 return gen_proto((int)v
, proto
, dir
);
1475 register const u_char
*eaddr
;
1478 if ((q
.addr
== Q_HOST
|| q
.addr
== Q_DEFAULT
) && q
.proto
== Q_LINK
) {
1479 if (linktype
== DLT_EN10MB
)
1480 return gen_ehostop(eaddr
, (int)q
.dir
);
1481 if (linktype
== DLT_FDDI
)
1482 return gen_fhostop(eaddr
, (int)q
.dir
);
1484 bpf_error("ethernet address used in non-ether expression");
1490 struct slist
*s0
, *s1
;
1493 * This is definitely not the best way to do this, but the
1494 * lists will rarely get long.
1501 static struct slist
*
1507 s
= new_stmt(BPF_LDX
|BPF_MEM
);
1512 static struct slist
*
1518 s
= new_stmt(BPF_LD
|BPF_MEM
);
1524 gen_load(proto
, index
, size
)
1529 struct slist
*s
, *tmp
;
1531 int regno
= alloc_reg();
1533 free_reg(index
->regno
);
1537 bpf_error("data size must be 1, 2, or 4");
1553 bpf_error("unsupported index operation");
1556 s
= xfer_to_x(index
);
1557 tmp
= new_stmt(BPF_LD
|BPF_IND
|size
);
1559 sappend(index
->s
, s
);
1571 /* XXX Note that we assume a fixed link link header here. */
1572 s
= xfer_to_x(index
);
1573 tmp
= new_stmt(BPF_LD
|BPF_IND
|size
);
1576 sappend(index
->s
, s
);
1578 b
= gen_proto_abbrev(proto
);
1580 gen_and(index
->b
, b
);
1589 s
= new_stmt(BPF_LDX
|BPF_MSH
|BPF_B
);
1591 sappend(s
, xfer_to_a(index
));
1592 sappend(s
, new_stmt(BPF_ALU
|BPF_ADD
|BPF_X
));
1593 sappend(s
, new_stmt(BPF_MISC
|BPF_TAX
));
1594 sappend(s
, tmp
= new_stmt(BPF_LD
|BPF_IND
|size
));
1596 sappend(index
->s
, s
);
1598 gen_and(gen_proto_abbrev(proto
), b
= gen_ipfrag());
1600 gen_and(index
->b
, b
);
1604 index
->regno
= regno
;
1605 s
= new_stmt(BPF_ST
);
1607 sappend(index
->s
, s
);
1613 gen_relation(code
, a0
, a1
, reversed
)
1615 struct arth
*a0
, *a1
;
1618 struct slist
*s0
, *s1
, *s2
;
1619 struct block
*b
, *tmp
;
1623 s2
= new_stmt(BPF_ALU
|BPF_SUB
|BPF_X
);
1624 b
= new_block(JMP(code
));
1625 if (code
== BPF_JGT
|| code
== BPF_JGE
) {
1626 reversed
= !reversed
;
1627 b
->s
.k
= 0x80000000;
1635 sappend(a0
->s
, a1
->s
);
1639 free_reg(a0
->regno
);
1640 free_reg(a1
->regno
);
1642 /* 'and' together protocol checks */
1645 gen_and(a0
->b
, tmp
= a1
->b
);
1661 int regno
= alloc_reg();
1662 struct arth
*a
= (struct arth
*)newchunk(sizeof(*a
));
1665 s
= new_stmt(BPF_LD
|BPF_LEN
);
1666 s
->next
= new_stmt(BPF_ST
);
1667 s
->next
->s
.k
= regno
;
1682 a
= (struct arth
*)newchunk(sizeof(*a
));
1686 s
= new_stmt(BPF_LD
|BPF_IMM
);
1688 s
->next
= new_stmt(BPF_ST
);
1704 s
= new_stmt(BPF_ALU
|BPF_NEG
);
1707 s
= new_stmt(BPF_ST
);
1715 gen_arth(code
, a0
, a1
)
1717 struct arth
*a0
, *a1
;
1719 struct slist
*s0
, *s1
, *s2
;
1723 s2
= new_stmt(BPF_ALU
|BPF_X
|code
);
1728 sappend(a0
->s
, a1
->s
);
1730 free_reg(a1
->regno
);
1732 s0
= new_stmt(BPF_ST
);
1733 a0
->regno
= s0
->s
.k
= alloc_reg();
1740 * Here we handle simple allocation of the scratch registers.
1741 * If too many registers are alloc'd, the allocator punts.
1743 static int regused
[BPF_MEMWORDS
];
1747 * Return the next free register.
1752 int n
= BPF_MEMWORDS
;
1755 if (regused
[curreg
])
1756 curreg
= (curreg
+ 1) % BPF_MEMWORDS
;
1758 regused
[curreg
] = 1;
1762 bpf_error("too many registers needed to evaluate expression");
1767 * Return a register to the table so it can
1777 static struct block
*
1784 s
= new_stmt(BPF_LD
|BPF_LEN
);
1785 b
= new_block(JMP(jmp
));
1796 return gen_len(BPF_JGE
, n
);
1805 b
= gen_len(BPF_JGT
, n
);
1812 gen_byteop(op
, idx
, val
)
1823 return gen_cmp((u_int
)idx
, BPF_B
, (bpf_int32
)val
);
1826 b
= gen_cmp((u_int
)idx
, BPF_B
, (bpf_int32
)val
);
1827 b
->s
.code
= JMP(BPF_JGE
);
1832 b
= gen_cmp((u_int
)idx
, BPF_B
, (bpf_int32
)val
);
1833 b
->s
.code
= JMP(BPF_JGT
);
1837 s
= new_stmt(BPF_ALU
|BPF_OR
|BPF_K
);
1841 s
= new_stmt(BPF_ALU
|BPF_AND
|BPF_K
);
1845 b
= new_block(JMP(BPF_JEQ
));
1853 gen_broadcast(proto
)
1856 bpf_u_int32 hostmask
;
1857 struct block
*b0
, *b1
, *b2
;
1858 static u_char ebroadcast
[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1864 if (linktype
== DLT_EN10MB
)
1865 return gen_ehostop(ebroadcast
, Q_DST
);
1866 if (linktype
== DLT_FDDI
)
1867 return gen_fhostop(ebroadcast
, Q_DST
);
1868 bpf_error("not a broadcast link");
1872 b0
= gen_linktype(ETHERTYPE_IP
);
1873 hostmask
= ~netmask
;
1874 b1
= gen_mcmp(off_nl
+ 16, BPF_W
, (bpf_int32
)0, hostmask
);
1875 b2
= gen_mcmp(off_nl
+ 16, BPF_W
,
1876 (bpf_int32
)(~0 & hostmask
), hostmask
);
1881 bpf_error("only ether/ip broadcast filters supported");
1885 gen_multicast(proto
)
1888 register struct block
*b0
, *b1
;
1889 register struct slist
*s
;
1895 if (linktype
== DLT_EN10MB
) {
1896 /* ether[0] & 1 != 0 */
1897 s
= new_stmt(BPF_LD
|BPF_B
|BPF_ABS
);
1899 b0
= new_block(JMP(BPF_JSET
));
1905 if (linktype
== DLT_FDDI
) {
1906 /* XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX */
1907 /* fddi[1] & 1 != 0 */
1908 s
= new_stmt(BPF_LD
|BPF_B
|BPF_ABS
);
1910 b0
= new_block(JMP(BPF_JSET
));
1915 /* Link not known to support multicasts */
1919 b0
= gen_linktype(ETHERTYPE_IP
);
1920 b1
= gen_cmp(off_nl
+ 16, BPF_B
, (bpf_int32
)224);
1921 b1
->s
.code
= JMP(BPF_JGE
);
1925 bpf_error("only IP multicast filters supported on ethernet/FDDI");
1929 * generate command for inbound/outbound. It's here so we can
1930 * make it link-type specific. 'dir' = 0 implies "inbound",
1931 * = 1 implies "outbound".
1937 register struct block
*b0
;
1939 b0
= gen_relation(BPF_JEQ
,
1940 gen_load(Q_LINK
, gen_loadi(0), 1),
This page took 0.12266 seconds and 3 git commands to generate.