gencode.c
来自「Ubuntu packages of security software。 相」· C语言 代码 · 共 2,637 行 · 第 1/5 页
C
2,637 行
case DLT_IEEE802_11_RADIO: return gen_radiotap_llprefixlen(); default: return NULL; }}/* * Generate code to match a particular packet type by matching the * link-layer type field or fields in the 802.2 LLC header. * * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP * value, if <= ETHERMTU. */static struct block *gen_linktype(proto) register int proto;{ struct block *b0, *b1, *b2; /* are we checking MPLS-encapsulated packets? */ if (label_stack_depth > 0) { switch (proto) { case ETHERTYPE_IP: case PPP_IP: /* FIXME add other L3 proto IDs */ return gen_mpls_linktype(Q_IP); case ETHERTYPE_IPV6: case PPP_IPV6: /* FIXME add other L3 proto IDs */ return gen_mpls_linktype(Q_IPV6); default: bpf_error("unsupported protocol over mpls"); /* NOTREACHED */ } } switch (linktype) { case DLT_EN10MB: return gen_ether_linktype(proto); /*NOTREACHED*/ break; case DLT_C_HDLC: switch (proto) { case LLCSAP_ISONS: proto = (proto << 8 | LLCSAP_ISONS); /* fall through */ default: return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto); /*NOTREACHED*/ break; } break; case DLT_PPI: case DLT_FDDI: case DLT_IEEE802: case DLT_IEEE802_11: case DLT_IEEE802_11_RADIO_AVS: case DLT_IEEE802_11_RADIO: case DLT_PRISM_HEADER: case DLT_ATM_RFC1483: case DLT_ATM_CLIP: case DLT_IP_OVER_FC: return gen_llc_linktype(proto); /*NOTREACHED*/ break; case DLT_SUNATM: /* * If "is_lane" is set, check for a LANE-encapsulated * version of this protocol, otherwise check for an * LLC-encapsulated version of this protocol. * * We assume LANE means Ethernet, not Token Ring. */ if (is_lane) { /* * Check that the packet doesn't begin with an * LE Control marker. (We've already generated * a test for LANE.) */ b0 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H, 0xFF00); gen_not(b0); /* * Now generate an Ethernet test. */ b1 = gen_ether_linktype(proto); gen_and(b0, b1); return b1; } else { /* * Check for LLC encapsulation and then check the * protocol. */ b0 = gen_atmfield_code(A_PROTOTYPE, PT_LLC, BPF_JEQ, 0); b1 = gen_llc_linktype(proto); gen_and(b0, b1); return b1; } /*NOTREACHED*/ break; case DLT_LINUX_SLL: return gen_linux_sll_linktype(proto); /*NOTREACHED*/ break; case DLT_SLIP: case DLT_SLIP_BSDOS: case DLT_RAW: /* * These types don't provide any type field; packets * are always IPv4 or IPv6. * * XXX - for IPv4, check for a version number of 4, and, * for IPv6, check for a version number of 6? */ switch (proto) { case ETHERTYPE_IP: /* Check for a version number of 4. */ return gen_mcmp(OR_LINK, 0, BPF_B, 0x40, 0xF0);#ifdef INET6 case ETHERTYPE_IPV6: /* Check for a version number of 6. */ return gen_mcmp(OR_LINK, 0, BPF_B, 0x60, 0xF0);#endif default: return gen_false(); /* always false */ } /*NOTREACHED*/ break; case DLT_PPP: case DLT_PPP_PPPD: case DLT_PPP_SERIAL: case DLT_PPP_ETHER: /* * We use Ethernet protocol types inside libpcap; * map them to the corresponding PPP protocol types. */ switch (proto) { case ETHERTYPE_IP: proto = PPP_IP; break;#ifdef INET6 case ETHERTYPE_IPV6: proto = PPP_IPV6; break;#endif case ETHERTYPE_DN: proto = PPP_DECNET; break; case ETHERTYPE_ATALK: proto = PPP_APPLE; break; case ETHERTYPE_NS: proto = PPP_NS; break; case LLCSAP_ISONS: proto = PPP_OSI; break; case LLCSAP_8021D: /* * I'm assuming the "Bridging PDU"s that go * over PPP are Spanning Tree Protocol * Bridging PDUs. */ proto = PPP_BRPDU; break; case LLCSAP_IPX: proto = PPP_IPX; break; } break; case DLT_PPP_BSDOS: /* * We use Ethernet protocol types inside libpcap; * map them to the corresponding PPP protocol types. */ switch (proto) { case ETHERTYPE_IP: b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_IP); b1 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_VJC); gen_or(b0, b1); b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_VJNC); gen_or(b1, b0); return b0;#ifdef INET6 case ETHERTYPE_IPV6: proto = PPP_IPV6; /* more to go? */ break;#endif case ETHERTYPE_DN: proto = PPP_DECNET; break; case ETHERTYPE_ATALK: proto = PPP_APPLE; break; case ETHERTYPE_NS: proto = PPP_NS; break; case LLCSAP_ISONS: proto = PPP_OSI; break; case LLCSAP_8021D: /* * I'm assuming the "Bridging PDU"s that go * over PPP are Spanning Tree Protocol * Bridging PDUs. */ proto = PPP_BRPDU; break; case LLCSAP_IPX: proto = PPP_IPX; break; } break; case DLT_NULL: case DLT_LOOP: case DLT_ENC: /* * For DLT_NULL, the link-layer header is a 32-bit * word containing an AF_ value in *host* byte order, * and for DLT_ENC, the link-layer header begins * with a 32-bit work containing an AF_ value in * host byte order. * * In addition, if we're reading a saved capture file, * the host byte order in the capture may not be the * same as the host byte order on this machine. * * For DLT_LOOP, the link-layer header is a 32-bit * word containing an AF_ value in *network* byte order. * * XXX - AF_ values may, unfortunately, be platform- * dependent; for example, FreeBSD's AF_INET6 is 24 * whilst NetBSD's and OpenBSD's is 26. * * This means that, when reading a capture file, just * checking for our AF_INET6 value won't work if the * capture file came from another OS. */ switch (proto) { case ETHERTYPE_IP: proto = AF_INET; break;#ifdef INET6 case ETHERTYPE_IPV6: proto = AF_INET6; break;#endif default: /* * Not a type on which we support filtering. * XXX - support those that have AF_ values * #defined on this platform, at least? */ return gen_false(); } if (linktype == DLT_NULL || linktype == DLT_ENC) { /* * The AF_ value is in host byte order, but * the BPF interpreter will convert it to * network byte order. * * If this is a save file, and it's from a * machine with the opposite byte order to * ours, we byte-swap the AF_ value. * * Then we run it through "htonl()", and * generate code to compare against the result. */ if (bpf_pcap->sf.rfile != NULL && bpf_pcap->sf.swapped) proto = SWAPLONG(proto); proto = htonl(proto); } return (gen_cmp(OR_LINK, 0, BPF_W, (bpf_int32)proto)); case DLT_PFLOG: /* * af field is host byte order in contrast to the rest of * the packet. */ if (proto == ETHERTYPE_IP) return (gen_cmp(OR_LINK, offsetof(struct pfloghdr, af), BPF_B, (bpf_int32)AF_INET));#ifdef INET6 else if (proto == ETHERTYPE_IPV6) return (gen_cmp(OR_LINK, offsetof(struct pfloghdr, af), BPF_B, (bpf_int32)AF_INET6));#endif /* INET6 */ else return gen_false(); /*NOTREACHED*/ break; case DLT_ARCNET: case DLT_ARCNET_LINUX: /* * XXX should we check for first fragment if the protocol * uses PHDS? */ switch (proto) { default: return gen_false();#ifdef INET6 case ETHERTYPE_IPV6: return (gen_cmp(OR_LINK, off_linktype, BPF_B, (bpf_int32)ARCTYPE_INET6));#endif /* INET6 */ case ETHERTYPE_IP: b0 = gen_cmp(OR_LINK, off_linktype, BPF_B, (bpf_int32)ARCTYPE_IP); b1 = gen_cmp(OR_LINK, off_linktype, BPF_B, (bpf_int32)ARCTYPE_IP_OLD); gen_or(b0, b1); return (b1); case ETHERTYPE_ARP: b0 = gen_cmp(OR_LINK, off_linktype, BPF_B, (bpf_int32)ARCTYPE_ARP); b1 = gen_cmp(OR_LINK, off_linktype, BPF_B, (bpf_int32)ARCTYPE_ARP_OLD); gen_or(b0, b1); return (b1); case ETHERTYPE_REVARP: return (gen_cmp(OR_LINK, off_linktype, BPF_B, (bpf_int32)ARCTYPE_REVARP)); case ETHERTYPE_ATALK: return (gen_cmp(OR_LINK, off_linktype, BPF_B, (bpf_int32)ARCTYPE_ATALK)); } /*NOTREACHED*/ break; case DLT_LTALK: switch (proto) { case ETHERTYPE_ATALK: return gen_true(); default: return gen_false(); } /*NOTREACHED*/ break; case DLT_FRELAY: /* * XXX - assumes a 2-byte Frame Relay header with * DLCI and flags. What if the address is longer? */ switch (proto) { case ETHERTYPE_IP: /* * Check for the special NLPID for IP. */ return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | 0xcc);#ifdef INET6 case ETHERTYPE_IPV6: /* * Check for the special NLPID for IPv6. */ return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | 0x8e);#endif case LLCSAP_ISONS: /* * Check for several OSI protocols. * * Frame Relay packets typically have an OSI * NLPID at the beginning; we check for each * of them. * * What we check for is the NLPID and a frame * control field of UI, i.e. 0x03 followed * by the NLPID. */ b0 = gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | ISO8473_CLNP); b1 = gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | ISO9542_ESIS); b2 = gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | ISO10589_ISIS); gen_or(b1, b2); gen_or(b0, b2); return b2; default: return gen_false(); } /*NOTREACHED*/ break; case DLT_JUNIPER_MFR: case DLT_JUNIPER_MLFR: case DLT_JUNIPER_MLPPP: case DLT_JUNIPER_ATM1: case DLT_JUNIPER_ATM2: case DLT_JUNIPER_PPPOE: case DLT_JUNIPER_PPPOE_ATM: case DLT_JUNIPER_GGSN: case DLT_JUNIPER_ES: case DLT_JUNIPER_MONITOR: case DLT_JUNIPER_SERVICES: case DLT_JUNIPER_ETHER: case DLT_JUNIPER_PPP: case DLT_JUNIPER_FRELAY: case DLT_JUNIPER_CHDLC: case DLT_JUNIPER_VP: /* just lets verify the magic number for now - * on ATM we may have up to 6 different encapsulations on the wire * and need a lot of heuristics to figure out that the payload * might be; * * FIXME encapsulation specific BPF_ filters */ return gen_mcmp(OR_LINK, 0, BPF_W, 0x4d474300, 0xffffff00); /* compare the magic number */ case DLT_LINUX_IRDA: bpf_error("IrDA link-layer type filtering not implemented"); case DLT_DOCSIS: bpf_error("DOCSIS link-layer type filtering not implemented"); case DLT_LINUX_LAPD: bpf_error("LAPD link-layer type filtering not implemented"); } /* * All the types that have no encapsulation should either be * handled as DLT_SLIP, DLT_SLIP_BSDOS, and DLT_RAW are, if * all packets are IP packets, or should be handled in some * special case, if none of them are (if some are and some * aren't, the lack of encapsulation is a problem, as we'd * have to find some other way of determining the packet type). * * Therefore, if "off_linktype" is -1, there's an error. */ if (off_linktype == (u_int)-1) abort(); /* * Any type not handled above should always have an Ethernet * type at an offset of "off_linktype". (PPP is partially * handled above - the protocol type is mapped from the * Ethernet and LLC types we use internally to the corresponding * PPP type - but the PPP type is always specified by a value * at "off_linktype", so we don't have to do the code generation * above.) */ return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);}/* * Check for an LLC SNAP packet with a given organization code and * protocol type; we check the entire contents of the 802.2 LLC and * snap headers, checking for DSAP and SSAP of SNAP and a control * field of 0x03 in the LLC header, and for the specified organization * code and protocol type in the SNAP header. */static struct block *gen_snap(orgcode, ptype, offset) bpf_u_int32 orgcode; bpf_u_int32 ptype; u_int offset;{ u_char snapblock[8]; snapblock[0] = LLCSAP_SNAP; /* DSAP = SNAP */ snapblock[1] = LLCSAP_SNAP; /* SSAP = SNAP */ snapblock[2] = 0x03; /* control = UI */ snapblock[3] = (orgcode >> 16); /* upper 8 bits of organization code */ snapblock[4] = (orgcode >> 8); /* middle 8 bits of organization code */ snapblock[5] = (orgcode >> 0); /* lower 8 bits of organization code */ snapblock[6] = (ptype >> 8); /* upper 8 bits of protocol type */ snapblock[7] = (ptype >> 0); /* lower 8 bits of protocol type */ return gen_bcmp(OR_LINK, offset, 8, snapblock);}/* * Generate code to match a particular packet type, for link-layer types * using 802.2 LLC headers. * * This is *NOT* used for Ethernet;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?