📄 gencode.c
字号:
*/ insert_load_llprefixlen(root);}voidgen_and(b0, b1) struct block *b0, *b1;{ backpatch(b0, b1->head); b0->sense = !b0->sense; b1->sense = !b1->sense; merge(b1, b0); b1->sense = !b1->sense; b1->head = b0->head;}voidgen_or(b0, b1) struct block *b0, *b1;{ b0->sense = !b0->sense; backpatch(b0, b1->head); b0->sense = !b0->sense; merge(b1, b0); b1->head = b0->head;}voidgen_not(b) struct block *b;{ b->sense = !b->sense;}static struct block *gen_cmp(offrel, offset, size, v) enum e_offrel offrel; u_int offset, size; bpf_int32 v;{ return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JEQ, 0, v);}static struct block *gen_cmp_gt(offrel, offset, size, v) enum e_offrel offrel; u_int offset, size; bpf_int32 v;{ return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGT, 0, v);}static struct block *gen_cmp_ge(offrel, offset, size, v) enum e_offrel offrel; u_int offset, size; bpf_int32 v;{ return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGE, 0, v);}static struct block *gen_cmp_lt(offrel, offset, size, v) enum e_offrel offrel; u_int offset, size; bpf_int32 v;{ return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGE, 1, v);}static struct block *gen_cmp_le(offrel, offset, size, v) enum e_offrel offrel; u_int offset, size; bpf_int32 v;{ return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGT, 1, v);}static struct block *gen_mcmp(offrel, offset, size, v, mask) enum e_offrel offrel; u_int offset, size; bpf_int32 v; bpf_u_int32 mask;{ return gen_ncmp(offrel, offset, size, mask, BPF_JEQ, 0, v);}static struct block *gen_bcmp(offrel, offset, size, v) enum e_offrel offrel; register u_int offset, size; register const u_char *v;{ register struct block *b, *tmp; b = NULL; while (size >= 4) { register const u_char *p = &v[size - 4]; bpf_int32 w = ((bpf_int32)p[0] << 24) | ((bpf_int32)p[1] << 16) | ((bpf_int32)p[2] << 8) | p[3]; tmp = gen_cmp(offrel, offset + size - 4, BPF_W, w); if (b != NULL) gen_and(b, tmp); b = tmp; size -= 4; } while (size >= 2) { register const u_char *p = &v[size - 2]; bpf_int32 w = ((bpf_int32)p[0] << 8) | p[1]; tmp = gen_cmp(offrel, offset + size - 2, BPF_H, w); if (b != NULL) gen_and(b, tmp); b = tmp; size -= 2; } if (size > 0) { tmp = gen_cmp(offrel, offset, BPF_B, (bpf_int32)v[0]); if (b != NULL) gen_and(b, tmp); b = tmp; } return b;}/* * AND the field of size "size" at offset "offset" relative to the header * specified by "offrel" with "mask", and compare it with the value "v" * with the test specified by "jtype"; if "reverse" is true, the test * should test the opposite of "jtype". */static struct block *gen_ncmp(offrel, offset, size, mask, jtype, reverse, v) enum e_offrel offrel; bpf_int32 v; bpf_u_int32 offset, size, mask, jtype; int reverse;{ struct slist *s, *s2; struct block *b; s = gen_load_a(offrel, offset, size); if (mask != 0xffffffff) { s2 = new_stmt(BPF_ALU|BPF_AND|BPF_K); s2->s.k = mask; sappend(s, s2); } b = new_block(JMP(jtype)); b->stmts = s; b->s.k = v; if (reverse && (jtype == BPF_JGT || jtype == BPF_JGE)) gen_not(b); return b;}/* * Various code constructs need to know the layout of the data link * layer. These variables give the necessary offsets from the beginning * of the packet data. * * If the link layer has variable_length headers, the offsets are offsets * from the end of the link-link-layer header, and "reg_ll_size" is * the register number for a register containing the length of the * link-layer header. Otherwise, "reg_ll_size" is -1. */static int reg_ll_size;/* * This is the offset of the beginning of the link-layer header from * the beginning of the raw packet data. * * It's usually 0, except for 802.11 with a fixed-length radio header. * (For 802.11 with a variable-length radio header, we have to generate * code to compute that offset; off_ll is 0 in that case.) */static u_int off_ll;/* * This is the offset of the beginning of the MAC-layer header. * It's usually 0, except for ATM LANE, where it's the offset, relative * to the beginning of the raw packet data, of the Ethernet header. */static u_int off_mac;/* * "off_linktype" is the offset to information in the link-layer header * giving the packet type. This offset is relative to the beginning * of the link-layer header (i.e., it doesn't include off_ll). * * For Ethernet, it's the offset of the Ethernet type field. * * For link-layer types that always use 802.2 headers, it's the * offset of the LLC header. * * For PPP, it's the offset of the PPP type field. * * For Cisco HDLC, it's the offset of the CHDLC type field. * * For BSD loopback, it's the offset of the AF_ value. * * For Linux cooked sockets, it's the offset of the type field. * * It's set to -1 for no encapsulation, in which case, IP is assumed. */static u_int off_linktype;/* * TRUE if the link layer includes an ATM pseudo-header. */static int is_atm = 0;/* * TRUE if "lane" appeared in the filter; it causes us to generate * code that assumes LANE rather than LLC-encapsulated traffic in SunATM. */static int is_lane = 0;/* * These are offsets for the ATM pseudo-header. */static u_int off_vpi;static u_int off_vci;static u_int off_proto;/* * These are offsets for the MTP3 fields. */static u_int off_sio;static u_int off_opc;static u_int off_dpc;static u_int off_sls;/* * This is the offset of the first byte after the ATM pseudo_header, * or -1 if there is no ATM pseudo-header. */static u_int off_payload;/* * These are offsets to the beginning of the network-layer header. * They are relative to the beginning of the link-layer header (i.e., * they don't include off_ll). * * If the link layer never uses 802.2 LLC: * * "off_nl" and "off_nl_nosnap" are the same. * * If the link layer always uses 802.2 LLC: * * "off_nl" is the offset if there's a SNAP header following * the 802.2 header; * * "off_nl_nosnap" is the offset if there's no SNAP header. * * If the link layer is Ethernet: * * "off_nl" is the offset if the packet is an Ethernet II packet * (we assume no 802.3+802.2+SNAP); * * "off_nl_nosnap" is the offset if the packet is an 802.3 packet * with an 802.2 header following it. */static u_int off_nl;static u_int off_nl_nosnap;static int linktype;static voidinit_linktype(p) pcap_t *p;{ linktype = pcap_datalink(p);#ifdef PCAP_FDDIPAD pcap_fddipad = p->fddipad;#endif /* * Assume it's not raw ATM with a pseudo-header, for now. */ off_mac = 0; is_atm = 0; is_lane = 0; off_vpi = -1; off_vci = -1; off_proto = -1; off_payload = -1; /* * And assume we're not doing SS7. */ off_sio = -1; off_opc = -1; off_dpc = -1; off_sls = -1; /* * Also assume it's not 802.11 with a fixed-length radio header. */ off_ll = 0; orig_linktype = -1; orig_nl = -1; label_stack_depth = 0; reg_ll_size = -1; switch (linktype) { case DLT_ARCNET: off_linktype = 2; off_nl = 6; /* XXX in reality, variable! */ off_nl_nosnap = 6; /* no 802.2 LLC */ return; case DLT_ARCNET_LINUX: off_linktype = 4; off_nl = 8; /* XXX in reality, variable! */ off_nl_nosnap = 8; /* no 802.2 LLC */ return; case DLT_EN10MB: off_linktype = 12; off_nl = 14; /* Ethernet II */ off_nl_nosnap = 17; /* 802.3+802.2 */ return; case DLT_SLIP: /* * SLIP doesn't have a link level type. The 16 byte * header is hacked into our SLIP driver. */ off_linktype = -1; off_nl = 16; off_nl_nosnap = 16; /* no 802.2 LLC */ return; case DLT_SLIP_BSDOS: /* XXX this may be the same as the DLT_PPP_BSDOS case */ off_linktype = -1; /* XXX end */ off_nl = 24; off_nl_nosnap = 24; /* no 802.2 LLC */ return; case DLT_NULL: case DLT_LOOP: off_linktype = 0; off_nl = 4; off_nl_nosnap = 4; /* no 802.2 LLC */ return; case DLT_ENC: off_linktype = 0; off_nl = 12; off_nl_nosnap = 12; /* no 802.2 LLC */ return; case DLT_PPP: case DLT_PPP_PPPD: case DLT_C_HDLC: /* BSD/OS Cisco HDLC */ case DLT_PPP_SERIAL: /* NetBSD sync/async serial PPP */ off_linktype = 2; off_nl = 4; off_nl_nosnap = 4; /* no 802.2 LLC */ return; case DLT_PPP_ETHER: /* * This does no include the Ethernet header, and * only covers session state. */ off_linktype = 6; off_nl = 8; off_nl_nosnap = 8; /* no 802.2 LLC */ return; case DLT_PPP_BSDOS: off_linktype = 5; off_nl = 24; off_nl_nosnap = 24; /* no 802.2 LLC */ return; case DLT_FDDI: /* * FDDI doesn't really have a link-level type field. * We set "off_linktype" to the offset of the LLC header. * * To check for Ethernet types, we assume that SSAP = SNAP * is being used and pick out the encapsulated Ethernet type. * XXX - should we generate code to check for SNAP? */ off_linktype = 13;#ifdef PCAP_FDDIPAD off_linktype += pcap_fddipad;#endif off_nl = 21; /* FDDI+802.2+SNAP */ off_nl_nosnap = 16; /* FDDI+802.2 */#ifdef PCAP_FDDIPAD off_nl += pcap_fddipad; off_nl_nosnap += pcap_fddipad;#endif return; case DLT_IEEE802: /* * Token Ring doesn't really have a link-level type field. * We set "off_linktype" to the offset of the LLC header. * * To check for Ethernet types, we assume that SSAP = SNAP * is being used and pick out the encapsulated Ethernet type. * XXX - should we generate code to check for SNAP? * * XXX - the header is actually variable-length. * Some various Linux patched versions gave 38 * as "off_linktype" and 40 as "off_nl"; however, * if a token ring packet has *no* routing * information, i.e. is not source-routed, the correct * values are 20 and 22, as they are in the vanilla code. * * A packet is source-routed iff the uppermost bit * of the first byte of the source address, at an * offset of 8, has the uppermost bit set. If the * packet is source-routed, the total number of bytes * of routing information is 2 plus bits 0x1F00 of * the 16-bit value at an offset of 14 (shifted right * 8 - figure out which byte that is). */ off_linktype = 14; off_nl = 22; /* Token Ring+802.2+SNAP */ off_nl_nosnap = 17; /* Token Ring+802.2 */ return; case DLT_IEEE802_11: /* * 802.11 doesn't really have a link-level type field. * We set "off_linktype" to the offset of the LLC header. * * To check for Ethernet types, we assume that SSAP = SNAP * is being used and pick out the encapsulated Ethernet type. * XXX - should we generate code to check for SNAP? * * XXX - the header is actually variable-length. We * assume a 24-byte link-layer header, as appears in * data frames in networks with no bridges. If the * fromds and tods 802.11 header bits are both set, * it's actually supposed to be 30 bytes. */ off_linktype = 24; off_nl = 32; /* 802.11+802.2+SNAP */ off_nl_nosnap = 27; /* 802.11+802.2 */ return; case DLT_PRISM_HEADER: /* * Same as 802.11, but with an additional header before * the 802.11 header, containing a bunch of additional * information including radio-level information. * * The header is 144 bytes long. * * XXX - same variable-length header problem; at least * the Prism header is fixed-length. */ off_ll = 144; off_linktype = 24; off_nl = 32; /* Prism+802.11+802.2+SNAP */ off_nl_nosnap = 27; /* Prism+802.11+802.2 */ return; case DLT_IEEE802_11_RADIO_AVS: /* * Same as 802.11, but with an additional header before * the 802.11 header, containing a bunch of additional * information including radio-level information. * * The header is 64 bytes long, at least in its * current incarnation. * * XXX - same variable-length header problem, only * more so; this header is also variable-length, * with the length being the 32-bit big-endian * number at an offset of 4 from the beginning * of the radio header. We should handle that the * same way we handle the length at the beginning * of the radiotap header. * * XXX - in Linux, do any drivers that supply an AVS * header supply a link-layer type other than * ARPHRD_IEEE80211_PRISM? If so, we should map that * to DLT_IEEE802_11_RADIO_AVS; if not, or if there are * any drivers that supply an AVS header but supply * an ARPHRD value of ARPHRD_IEEE80211_PRISM, we'll * have to check the header in the generated code to * determine whether it's Prism or AVS. */ off_ll = 64; off_linktype = 24; off_nl = 32; /* Radio+802.11+802.2+SNAP */ off_nl_nosnap = 27; /* Radio+802.11+802.2 */ return; case DLT_IEEE802_11_RADIO: /* * Same as 802.11, but with an additional header before * the 802.11 header, containing a bunch of additional * information including radio-level information. * * The radiotap header is variable length, and we * generate code to compute its length and store it * in a register. These offsets are relative to the * beginning of the 802.11 header. */ off_linktype = 24; off_nl = 32; /* 802.11+802.2+SNAP */ off_nl_nosnap = 27; /* 802.11+802.2 */ return; case DLT_ATM_RFC1483: case DLT_ATM_CLIP: /* Linux ATM defines this */ /* * assume routed, non-ISO PDUs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -