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

📄 gencode.c

📁 Windows XP下的抓包程序实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	case ETHERTYPE_ATALK:	case ETHERTYPE_AARP:		/*		 * EtherTalk (AppleTalk protocols on Ethernet link		 * layer) may use 802.2 encapsulation.		 */		/*		 * Check for 802.2 encapsulation (EtherTalk phase 2?);		 * we check for an Ethernet type field less than		 * 1500, which means it's an 802.3 length field.		 */		b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU);		gen_not(b0);		/*		 * 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).		 *		 * 802.2-encapsulated ETHERTYPE_AARP packets are		 * SNAP packets with an organization code of		 * 0x000000 (encapsulated Ethernet) and a protocol		 * type of ETHERTYPE_AARP (Appletalk ARP).		 */		if (proto == ETHERTYPE_ATALK)			b1 = gen_snap(0x080007, ETHERTYPE_ATALK, 14);		else	/* proto == ETHERTYPE_AARP */			b1 = gen_snap(0x000000, ETHERTYPE_AARP, 14);		gen_and(b0, b1);		/*		 * Check for Ethernet encapsulation (Ethertalk		 * phase 1?); we just check for the Ethernet		 * protocol type.		 */		b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);		gen_or(b0, b1);		return b1;	default:		if (proto <= ETHERMTU) {			/*			 * This is an LLC SAP value, so the frames			 * that match would be 802.2 frames.			 * Check that the frame is an 802.2 frame			 * (i.e., that the length/type field is			 * a length field, <= ETHERMTU) and			 * then check the DSAP.			 */			b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU);			gen_not(b0);			b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_B,			    (bpf_int32)proto);			gen_and(b0, b1);			return b1;		} else {			/*			 * This is an Ethernet type, so compare			 * the length/type field with it (if			 * the frame is an 802.2 frame, the length			 * field will be <= ETHERMTU, and, as			 * "proto" is > ETHERMTU, this test			 * will fail and the frame won't match,			 * which is what we want).			 */			return gen_cmp(OR_LINK, off_linktype, BPF_H,			    (bpf_int32)proto);		}	}}/* * Generate code to match a particular packet type. * * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP * value, if <= ETHERMTU.  We use that to determine whether to * match the type field or to check the type field for the special * LINUX_SLL_P_802_2 value and then do the appropriate test. */static struct block *gen_linux_sll_linktype(proto)	register int proto;{	struct block *b0, *b1;	switch (proto) {	case LLCSAP_ISONS:	case LLCSAP_IP:	case LLCSAP_NETBEUI:		/*		 * OSI protocols and NetBEUI always use 802.2 encapsulation,		 * so we check the DSAP and SSAP.		 *		 * LLCSAP_IP checks for IP-over-802.2, rather		 * than IP-over-Ethernet or IP-over-SNAP.		 *		 * 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)?		 */		b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2);		b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_H, (bpf_int32)			     ((proto << 8) | proto));		gen_and(b0, b1);		return b1;	case LLCSAP_IPX:		/*		 *	Ethernet_II frames, which are Ethernet		 *	frames with a frame type of ETHERTYPE_IPX;		 *		 *	Ethernet_802.3 frames, which have a frame		 *	type of LINUX_SLL_P_802_3;		 *		 *	Ethernet_802.2 frames, which are 802.3		 *	frames with an 802.2 LLC header (i.e, have		 *	a frame type of LINUX_SLL_P_802_2) and		 *	with the IPX LSAP as the DSAP in the LLC		 *	header;		 *		 *	Ethernet_SNAP frames, which are 802.3		 *	frames with an LLC header and a SNAP		 *	header and with an OUI of 0x000000		 *	(encapsulated Ethernet) and a protocol		 *	ID of ETHERTYPE_IPX in the SNAP header.		 *		 * First, do the checks on LINUX_SLL_P_802_2		 * frames; generate the check for either		 * Ethernet_802.2 or Ethernet_SNAP frames, and		 * then put a check for LINUX_SLL_P_802_2 frames		 * before it.		 */		b0 = gen_cmp(OR_LINK, off_linktype + 2, BPF_B,		    (bpf_int32)LLCSAP_IPX);		b1 = gen_snap(0x000000, ETHERTYPE_IPX,		    off_linktype + 2);		gen_or(b0, b1);		b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2);		gen_and(b0, b1);		/*		 * Now check for 802.3 frames and OR that with		 * the previous test.		 */		b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_3);		gen_or(b0, b1);		/*		 * Now add the check for Ethernet_II frames, and		 * do that before checking for the other frame		 * types.		 */		b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,		    (bpf_int32)ETHERTYPE_IPX);		gen_or(b0, b1);		return b1;	case ETHERTYPE_ATALK:	case ETHERTYPE_AARP:		/*		 * EtherTalk (AppleTalk protocols on Ethernet link		 * layer) may use 802.2 encapsulation.		 */		/*		 * Check for 802.2 encapsulation (EtherTalk phase 2?);		 * we check for the 802.2 protocol type in the		 * "Ethernet type" field.		 */		b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2);		/*		 * 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).		 *		 * 802.2-encapsulated ETHERTYPE_AARP packets are		 * SNAP packets with an organization code of		 * 0x000000 (encapsulated Ethernet) and a protocol		 * type of ETHERTYPE_AARP (Appletalk ARP).		 */		if (proto == ETHERTYPE_ATALK)			b1 = gen_snap(0x080007, ETHERTYPE_ATALK,			    off_linktype + 2);		else	/* proto == ETHERTYPE_AARP */			b1 = gen_snap(0x000000, ETHERTYPE_AARP,			    off_linktype + 2);		gen_and(b0, b1);		/*		 * Check for Ethernet encapsulation (Ethertalk		 * phase 1?); we just check for the Ethernet		 * protocol type.		 */		b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);		gen_or(b0, b1);		return b1;	default:		if (proto <= ETHERMTU) {			/*			 * This is an LLC SAP value, so the frames			 * that match would be 802.2 frames.			 * Check for the 802.2 protocol type			 * in the "Ethernet type" field, and			 * then check the DSAP.			 */			b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,			    LINUX_SLL_P_802_2);			b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_B,			     (bpf_int32)proto);			gen_and(b0, b1);			return b1;		} else {			/*			 * This is an Ethernet type, so compare			 * the length/type field with it (if			 * the frame is an 802.2 frame, the length			 * field will be <= ETHERMTU, and, as			 * "proto" is > ETHERMTU, this test			 * will fail and the frame won't match,			 * which is what we want).			 */			return gen_cmp(OR_LINK, off_linktype, BPF_H,			    (bpf_int32)proto);		}	}}static voidinsert_radiotap_load_llprefixlen(b)	struct block *b;{	struct slist *s1, *s2;	/*	 * Prepend to the statements in this block code to load the	 * length of the radiotap header into the register assigned	 * to hold that length, if one has been assigned.	 */	if (reg_ll_size != -1) {		/*		 * The 2 bytes at offsets of 2 and 3 from the beginning		 * of the radiotap header are the length of the radiotap		 * header; unfortunately, it's little-endian, so we have		 * to load it a byte at a time and construct the value.		 */		/*		 * Load the high-order byte, at an offset of 3, shift it		 * left a byte, and put the result in the X register.		 */		s1 = new_stmt(BPF_LD|BPF_B|BPF_ABS);		s1->s.k = 3;		s2 = new_stmt(BPF_ALU|BPF_LSH|BPF_K);		sappend(s1, s2);		s2->s.k = 8;		s2 = new_stmt(BPF_MISC|BPF_TAX);		sappend(s1, s2);		/*		 * Load the next byte, at an offset of 2, and OR the		 * value from the X register into it.		 */		s2 = new_stmt(BPF_LD|BPF_B|BPF_ABS);		sappend(s1, s2);		s2->s.k = 2;		s2 = new_stmt(BPF_ALU|BPF_OR|BPF_X);		sappend(s1, s2);		/*		 * Now allocate a register to hold that value and store		 * it.		 */		s2 = new_stmt(BPF_ST);		s2->s.k = reg_ll_size;		sappend(s1, s2);		/*		 * Now move it into the X register.		 */		s2 = new_stmt(BPF_MISC|BPF_TAX);		sappend(s1, s2);		/*		 * Now append all the existing statements in this		 * block to these statements.		 */		sappend(s1, b->stmts);		b->stmts = s1;	}}static voidinsert_load_llprefixlen(b)	struct block *b;{	switch (linktype) {	case DLT_IEEE802_11_RADIO:		insert_radiotap_load_llprefixlen(b);	}}static struct slist *gen_radiotap_llprefixlen(void){	struct slist *s;	if (reg_ll_size == -1) {		/*		 * We haven't yet assigned a register for the length		 * of the radiotap header; allocate one.		 */		reg_ll_size = alloc_reg();	}	/*	 * Load the register containing the radiotap length	 * into the X register.	 */	s = new_stmt(BPF_LDX|BPF_MEM);	s->s.k = reg_ll_size;	return s;}/* * Generate code to compute the link-layer header length, if necessary, * putting it into the X register, and to return either a pointer to a * "struct slist" for the list of statements in that code, or NULL if * no code is necessary. */static struct slist *gen_llprefixlen(void){	switch (linktype) {	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_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 IP.		 *		 * 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:#ifdef INET6		case ETHERTYPE_IPV6:#endif			return gen_true();		/* always true */		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

⌨️ 快捷键说明

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