⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gencode.c

📁 Windows XP下的抓包程序实现
💻 C
📖 第 1 页 / 共 5 页
字号:
			 * 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:		/* 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; "gen_ether_linktype()" is used * for that - it handles the D/I/X Ethernet vs. 802.3+802.2 issues. * * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP * value, if <= ETHERMTU.  We use that to determine whether to * match the DSAP or both DSAP and LSAP or to check the OUI and * protocol ID in a SNAP header. */static struct block *gen_llc_linktype(proto)	int proto;{	/*	 * XXX - handle token-ring variable-length header.	 */	switch (proto) {	case LLCSAP_IP:	case LLCSAP_ISONS:	case LLCSAP_NETBEUI:		/*		 * XXX - should we check both the DSAP and the		 * SSAP, like this, or should we check just the		 * DSAP, as we do for other types <= ETHERMTU		 * (i.e., other SAP values)?		 */		return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_u_int32)			     ((proto << 8) | proto));	case LLCSAP_IPX:		/*		 * XXX - are there ever SNAP frames for IPX on		 * non-Ethernet 802.x networks?		 */		return gen_cmp(OR_LINK, off_linktype, BPF_B,		    (bpf_int32)LLCSAP_IPX);	case ETHERTYPE_ATALK:		/*		 * 802.2-encapsulated ETHERTYPE_ATALK packets are		 * SNAP packets with an organization code of		 * 0x080007 (Apple, for Appletalk) and a protocol		 * type of ETHERTYPE_ATALK (Appletalk).		 *		 * XXX - check for an organization code of		 * encapsulated Ethernet as well?		 */		return gen_snap(0x080007, ETHERTYPE_ATALK, off_linktype);	default:		/*		 * XXX - we don't have to check for IPX 802.3		 * here, but should we check for the IPX Ethertype?		 */		if (proto <= ETHERMTU) {			/*			 * This is an LLC SAP value, so check			 * the DSAP.			 */			return gen_cmp(OR_LINK, off_linktype, BPF_B,			    (bpf_int32)proto);		} else {			/*			 * This is an Ethernet type; we assume that it's			 * unlikely that it'll appear in the right place			 * at random, and therefore check only the			 * location that would hold the Ethernet type			 * in a SNAP frame with an organization code of			 * 0x000000 (encapsulated Ethernet).			 *			 * XXX - if we were to check for the SNAP DSAP and			 * LSAP, as per XXX, and were also to check for an			 * organization code of 0x000000 (encapsulated			 * Ethernet), we'd do			 *			 *	return gen_snap(0x000000, proto,			 *	    off_linktype);			 *			 * here; for now, we don't, as per the above.			 * I don't know whether it's worth the extra CPU			 * time to do the right check or not.			 */			return gen_cmp(OR_LINK, off_linktype+6, BPF_H,			    (bpf_int32)proto);		}	}}static struct block *gen_hostop(addr, mask, dir, proto, src_off, dst_off)	bpf_u_int32 addr;	bpf_u_int32 mask;	int dir, proto;	u_int src_off, dst_off;{	struct block *b0, *b1;	u_int offset;	switch (dir) {	case Q_SRC:		offset = src_off;		break;	case Q_DST:		offset = dst_off;		break;	case Q_AND:		b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off);		b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off);		gen_and(b0, b1);		return b1;	case Q_OR:	case Q_DEFAULT:		b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off);		b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off);		gen_or(b0, b1);		return b1;	default:		abort();	}	b0 = gen_linktype(proto);	b1 = gen_mcmp(OR_NET, offset, BPF_W, (bpf_int32)addr, mask);	gen_and(b0, b1);	return b1;}#ifdef INET6static struct block *gen_hostop6(addr, mask, dir, proto, src_off, dst_off)	struct in6_addr *addr;	struct in6_addr *mask;	int dir, proto;	u_int src_off, dst_off;{	struct block *b0, *b1;	u_int offset;	u_int32_t *a, *m;	switch (dir) {	case Q_SRC:		offset = src_off;		break;	case Q_DST:		offset = dst_off;		break;	case Q_AND:		b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off);		b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off);		gen_and(b0, b1);		return b1;	case Q_OR:	case Q_DEFAULT:		b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off);		b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off);		gen_or(b0, b1);		return b1;	default:		abort();	}	/* this order is important */	a = (u_int32_t *)addr;	m = (u_int32_t *)mask;	b1 = gen_mcmp(OR_NET, offset + 12, BPF_W, ntohl(a[3]), ntohl(m[3]));	b0 = gen_mcmp(OR_NET, offset + 8, BPF_W, ntohl(a[2]), ntohl(m[2]));	gen_and(b0, b1);	b0 = gen_mcmp(OR_NET, offset + 4, BPF_W, ntohl(a[1]), ntohl(m[1]));	gen_and(b0, b1);	b0 = gen_mcmp(OR_NET, offset + 0, BPF_W, ntohl(a[0]), ntohl(m[0]));	gen_and(b0, b1);	b0 = gen_linktype(proto);	gen_and(b0, b1);	return b1;}#endif /*INET6*/static struct block *gen_ehostop(ea

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -