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

📄 gencode.c

📁 用来监视网络通信数据的源代码和应用程序,方便网络程序底层开发.
💻 C
📖 第 1 页 / 共 5 页
字号:
		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.
			 */
			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;
		}
		break;

	case DLT_NULL:
	case DLT_LOOP:
		/*
		 * For DLT_NULL, the link-layer header is a 32-bit
		 * word 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) {
			/*
			 * 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(0, BPF_W, (bpf_int32)proto));

	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(off_linktype, BPF_B,
				(bpf_int32)ARCTYPE_INET6));
#endif /* INET6 */

		case ETHERTYPE_IP:
			b0 = gen_cmp(off_linktype, BPF_B, 
				     (bpf_int32)ARCTYPE_IP);
			b1 = gen_cmp(off_linktype, BPF_B,
				     (bpf_int32)ARCTYPE_IP_OLD);
			gen_or(b0, b1);
			return (b1);

		case ETHERTYPE_ARP:
			b0 = gen_cmp(off_linktype, BPF_B,
				     (bpf_int32)ARCTYPE_ARP);
			b1 = gen_cmp(off_linktype, BPF_B, 
				     (bpf_int32)ARCTYPE_ARP_OLD);
			gen_or(b0, b1);
			return (b1);

		case ETHERTYPE_REVARP:
			return (gen_cmp(off_linktype, BPF_B,
					(bpf_int32)ARCTYPE_REVARP));

		case ETHERTYPE_ATALK:
			return (gen_cmp(off_linktype, BPF_B,
					(bpf_int32)ARCTYPE_ATALK));
		}
		break;

	case DLT_LTALK:
		switch (proto) {
		case ETHERTYPE_ATALK:
			return gen_true();
		default:
			return gen_false();
		}
		break;

	case DLT_FRELAY:
		/*

⌨️ 快捷键说明

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