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

📄 gencode.c

📁 用来监视网络通信数据的源代码和应用程序,方便网络程序底层开发.
💻 C
📖 第 1 页 / 共 5 页
字号:
static struct block *
gen_ether_linktype(proto)
	register int proto;
{
	struct block *b0, *b1;

	switch (proto) {

	case LLCSAP_ISONS:
		/*
		 * OSI protocols always use 802.2 encapsulation.
		 * XXX - should we check both the DSAP and the
		 * SSAP, like this, or should we check just the
		 * DSAP?
		 */
		b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU);
		gen_not(b0);
		b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
			     ((LLCSAP_ISONS << 8) | LLCSAP_ISONS));
		gen_and(b0, b1);
		return b1;

	case LLCSAP_IP:
		b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU);
		gen_not(b0);
		b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
			     ((LLCSAP_IP << 8) | LLCSAP_IP));
		gen_and(b0, b1);
		return b1;

	case LLCSAP_NETBEUI:
		/*
		 * NetBEUI always uses 802.2 encapsulation.
		 * XXX - should we check both the DSAP and the
		 * SSAP, like this, or should we check just the
		 * DSAP?
		 */
		b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU);
		gen_not(b0);
		b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
			     ((LLCSAP_NETBEUI << 8) | LLCSAP_NETBEUI));
		gen_and(b0, b1);
		return b1;

	case LLCSAP_IPX:
		/*
		 * Check for;
		 *
		 *	Ethernet_II frames, which are Ethernet
		 *	frames with a frame type of ETHERTYPE_IPX;
		 *
		 *	Ethernet_802.3 frames, which are 802.3
		 *	frames (i.e., the type/length field is
		 *	a length field, <= ETHERMTU, rather than
		 *	a type field) with the first two bytes
		 *	after the Ethernet/802.3 header being
		 *	0xFFFF;
		 *
		 *	Ethernet_802.2 frames, which are 802.3
		 *	frames with an 802.2 LLC header 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.
		 *
		 * XXX - should we generate the same code both
		 * for tests for LLCSAP_IPX and for ETHERTYPE_IPX?
		 */

		/*
		 * This generates code to check both for the
		 * IPX LSAP (Ethernet_802.2) and for Ethernet_802.3.
		 */
		b0 = gen_cmp(off_linktype + 2, BPF_B, (bpf_int32)LLCSAP_IPX);
		b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)0xFFFF);
		gen_or(b0, b1);

		/*
		 * Now we add code to check for SNAP frames with
		 * ETHERTYPE_IPX, i.e. Ethernet_SNAP.
		 */
		b0 = gen_snap(0x000000, ETHERTYPE_IPX, 14);
		gen_or(b0, b1);

		/*
		 * Now we generate code to check for 802.3
		 * frames in general.
		 */
		b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU);
		gen_not(b0);

		/*
		 * Now add the check for 802.3 frames before the
		 * check for Ethernet_802.2 and Ethernet_802.3,
		 * as those checks should only be done on 802.3
		 * frames, not on Ethernet frames.
		 */
		gen_and(b0, b1);

		/*
		 * Now add the check for Ethernet_II frames, and
		 * do that before checking for the other frame
		 * types.
		 */
		b0 = gen_cmp(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 an Ethernet type field less than
		 * 1500, which means it's an 802.3 length field.
		 */
		b0 = gen_cmp_gt(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(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(off_linktype, BPF_H, ETHERMTU);
			gen_not(b0);
			b1 = gen_cmp(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(off_linktype, BPF_H, (bpf_int32)proto);
		}
	}
}

static struct block *
gen_linktype(proto)
	register int proto;
{
	struct block *b0, *b1, *b2;

	switch (linktype) {

	case DLT_EN10MB:
		return gen_ether_linktype(proto);
		break;

	case DLT_C_HDLC:
		switch (proto) {

		case LLCSAP_ISONS:
			proto = (proto << 8 | LLCSAP_ISONS);
			/* fall through */

		default:
			return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto);
			break;
		}
		break;

	case DLT_IEEE802_11:
	case DLT_PRISM_HEADER:
	case DLT_IEEE802_11_RADIO:
	case DLT_FDDI:
	case DLT_IEEE802:
	case DLT_ATM_RFC1483:
	case DLT_ATM_CLIP:
	case DLT_IP_OVER_FC:
		return gen_llc(proto);
		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(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(proto);
			gen_and(b0, b1);
			return b1;
		}

	case DLT_LINUX_SLL:
		switch (proto) {

		case LLCSAP_IP:
			b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
			b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
				     ((LLCSAP_IP << 8) | LLCSAP_IP));
			gen_and(b0, b1);
			return b1;

		case LLCSAP_ISONS:
			/*
			 * OSI protocols always use 802.2 encapsulation.
			 * XXX - should we check both the DSAP and the
			 * LSAP, like this, or should we check just the
			 * DSAP?
			 */
			b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
			b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
				     ((LLCSAP_ISONS << 8) | LLCSAP_ISONS));
			gen_and(b0, b1);
			return b1;

		case LLCSAP_NETBEUI:
			/*
			 * NetBEUI always uses 802.2 encapsulation.
			 * XXX - should we check both the DSAP and the
			 * LSAP, like this, or should we check just the
			 * DSAP?
			 */
			b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
			b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
				     ((LLCSAP_NETBEUI << 8) | LLCSAP_NETBEUI));
			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(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(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(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(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(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(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(off_linktype, BPF_H,
				    LINUX_SLL_P_802_2);
				b1 = gen_cmp(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(off_linktype, BPF_H,
				    (bpf_int32)proto);
			}
		}
		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 */
		}
		break;

	case DLT_PPP:
	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(off_linktype, BPF_H, PPP_IP);
			b1 = gen_cmp(off_linktype, BPF_H, PPP_VJC);
			gen_or(b0, b1);
			b0 = gen_cmp(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;
		}

⌨️ 快捷键说明

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