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

📄 gencode.c

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

	case Q_DST:
		/*
		 * Oh, yuk.
		 *
		 *	For control frames, there is no DA.
		 *
		 *	For management frames, DA is at an
		 *	offset of 4 from the beginning of
		 *	the packet.
		 *
		 *	For data frames, DA is at an offset
		 *	of 4 from the beginning of the packet
		 *	if To DS is clear and at an offset of
		 *	16 from the beginning of the packet
		 *	if To DS is set.
		 */

		/*
		 * Generate the tests to be done for data frames.
		 *
		 * First, check for To DS set, i.e. "link[1] & 0x01".
		 */
		s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
		s->s.k = 1;
		b1 = new_block(JMP(BPF_JSET));
		b1->s.k = 0x01;	/* To DS */
		b1->stmts = s;

		/*
		 * If To DS is set, the DA is at 16.
		 */
		b0 = gen_bcmp(16, 6, eaddr);
		gen_and(b1, b0);

		/*
		 * Now, check for To DS not set, i.e. check
		 * "!(link[1] & 0x01)".
		 */
		s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
		s->s.k = 1;
		b2 = new_block(JMP(BPF_JSET));
		b2->s.k = 0x01;	/* To DS */
		b2->stmts = s;
		gen_not(b2);

		/*
		 * If To DS is not set, the DA is at 4.
		 */
		b1 = gen_bcmp(4, 6, eaddr);
		gen_and(b2, b1);

		/*
		 * Now OR together the last two checks.  That gives
		 * the complete set of checks for data frames.
		 */
		gen_or(b1, b0);

		/*
		 * Now check for a data frame.
		 * I.e, check "link[0] & 0x08".
		 */
		s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
		s->s.k = 0;
		b1 = new_block(JMP(BPF_JSET));
		b1->s.k = 0x08;
		b1->stmts = s;

		/*
		 * AND that with the checks done for data frames.
		 */
		gen_and(b1, b0);

		/*
		 * If the high-order bit of the type value is 0, this
		 * is a management frame.
		 * I.e, check "!(link[0] & 0x08)".
		 */
		s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
		s->s.k = 0;
		b2 = new_block(JMP(BPF_JSET));
		b2->s.k = 0x08;
		b2->stmts = s;
		gen_not(b2);

		/*
		 * For management frames, the DA is at 4.
		 */
		b1 = gen_bcmp(4, 6, eaddr);
		gen_and(b2, b1);

		/*
		 * OR that with the checks done for data frames.
		 * That gives the checks done for management and
		 * data frames.
		 */
		gen_or(b1, b0);

		/*
		 * If the low-order bit of the type value is 1,
		 * this is either a control frame or a frame
		 * with a reserved type, and thus not a
		 * frame with an SA.
		 *
		 * I.e., check "!(link[0] & 0x04)".
		 */
		s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
		s->s.k = 0;
		b1 = new_block(JMP(BPF_JSET));
		b1->s.k = 0x04;
		b1->stmts = s;
		gen_not(b1);

		/*
		 * AND that with the checks for data and management
		 * frames.
		 */
		gen_and(b1, b0);
		return b0;

	case Q_AND:
		b0 = gen_wlanhostop(eaddr, Q_SRC);
		b1 = gen_wlanhostop(eaddr, Q_DST);
		gen_and(b0, b1);
		return b1;

	case Q_DEFAULT:
	case Q_OR:
		b0 = gen_wlanhostop(eaddr, Q_SRC);
		b1 = gen_wlanhostop(eaddr, Q_DST);
		gen_or(b0, b1);
		return b1;
	}
	abort();
	/* NOTREACHED */
}

/*
 * Like gen_ehostop, but for RFC 2625 IP-over-Fibre-Channel.
 * (We assume that the addresses are IEEE 48-bit MAC addresses,
 * as the RFC states.)
 */
static struct block *
gen_ipfchostop(eaddr, dir)
	register const u_char *eaddr;
	register int dir;
{
	register struct block *b0, *b1;

	switch (dir) {
	case Q_SRC:
		return gen_bcmp(10, 6, eaddr);

	case Q_DST:
		return gen_bcmp(2, 6, eaddr);

	case Q_AND:
		b0 = gen_ipfchostop(eaddr, Q_SRC);
		b1 = gen_ipfchostop(eaddr, Q_DST);
		gen_and(b0, b1);
		return b1;

	case Q_DEFAULT:
	case Q_OR:
		b0 = gen_ipfchostop(eaddr, Q_SRC);
		b1 = gen_ipfchostop(eaddr, Q_DST);
		gen_or(b0, b1);
		return b1;
	}
	abort();
	/* NOTREACHED */
}

/*
 * This is quite tricky because there may be pad bytes in front of the
 * DECNET header, and then there are two possible data packet formats that
 * carry both src and dst addresses, plus 5 packet types in a format that
 * carries only the src node, plus 2 types that use a different format and
 * also carry just the src node.
 *
 * Yuck.
 *
 * Instead of doing those all right, we just look for data packets with
 * 0 or 1 bytes of padding.  If you want to look at other packets, that
 * will require a lot more hacking.
 *
 * To add support for filtering on DECNET "areas" (network numbers)
 * one would want to add a "mask" argument to this routine.  That would
 * make the filter even more inefficient, although one could be clever
 * and not generate masking instructions if the mask is 0xFFFF.
 */
static struct block *
gen_dnhostop(addr, dir, base_off)
	bpf_u_int32 addr;
	int dir;
	u_int base_off;
{
	struct block *b0, *b1, *b2, *tmp;
	u_int offset_lh;	/* offset if long header is received */
	u_int offset_sh;	/* offset if short header is received */

	switch (dir) {

	case Q_DST:
		offset_sh = 1;	/* follows flags */
		offset_lh = 7;	/* flgs,darea,dsubarea,HIORD */
		break;

	case Q_SRC:
		offset_sh = 3;	/* follows flags, dstnode */
		offset_lh = 15;	/* flgs,darea,dsubarea,did,sarea,ssub,HIORD */
		break;

	case Q_AND:
		/* Inefficient because we do our Calvinball dance twice */
		b0 = gen_dnhostop(addr, Q_SRC, base_off);
		b1 = gen_dnhostop(addr, Q_DST, base_off);
		gen_and(b0, b1);
		return b1;

	case Q_OR:
	case Q_DEFAULT:
		/* Inefficient because we do our Calvinball dance twice */
		b0 = gen_dnhostop(addr, Q_SRC, base_off);
		b1 = gen_dnhostop(addr, Q_DST, base_off);
		gen_or(b0, b1);
		return b1;

	case Q_ISO:
	        bpf_error("ISO host filtering not implemented");

	default:
		abort();
	}
	b0 = gen_linktype(ETHERTYPE_DN);
	/* Check for pad = 1, long header case */
	tmp = gen_mcmp(base_off + 2, BPF_H,
	    (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF));
	b1 = gen_cmp(base_off + 2 + 1 + offset_lh,
	    BPF_H, (bpf_int32)ntohs(addr));
	gen_and(tmp, b1);
	/* Check for pad = 0, long header case */
	tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7);
	b2 = gen_cmp(base_off + 2 + offset_lh, BPF_H, (bpf_int32)ntohs(addr));
	gen_and(tmp, b2);
	gen_or(b2, b1);
	/* Check for pad = 1, short header case */
	tmp = gen_mcmp(base_off + 2, BPF_H,
	    (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF));
	b2 = gen_cmp(base_off + 2 + 1 + offset_sh,
	    BPF_H, (bpf_int32)ntohs(addr));
	gen_and(tmp, b2);
	gen_or(b2, b1);
	/* Check for pad = 0, short header case */
	tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7);
	b2 = gen_cmp(base_off + 2 + offset_sh, BPF_H, (bpf_int32)ntohs(addr));
	gen_and(tmp, b2);
	gen_or(b2, b1);

	/* Combine with test for linktype */
	gen_and(b0, b1);
	return b1;
}

static struct block *
gen_host(addr, mask, proto, dir)
	bpf_u_int32 addr;
	bpf_u_int32 mask;
	int proto;
	int dir;
{
	struct block *b0, *b1;

	switch (proto) {

	case Q_DEFAULT:
		b0 = gen_host(addr, mask, Q_IP, dir);
		if (off_linktype != -1) {
		    b1 = gen_host(addr, mask, Q_ARP, dir);
		    gen_or(b0, b1);
		    b0 = gen_host(addr, mask, Q_RARP, dir);
		    gen_or(b1, b0);
		}
		return b0;

	case Q_IP:
		return gen_hostop(addr, mask, dir, ETHERTYPE_IP,
				  off_nl + 12, off_nl + 16);

	case Q_RARP:
		return gen_hostop(addr, mask, dir, ETHERTYPE_REVARP,
				  off_nl + 14, off_nl + 24);

	case Q_ARP:
		return gen_hostop(addr, mask, dir, ETHERTYPE_ARP,
				  off_nl + 14, off_nl + 24);

	case Q_TCP:
		bpf_error("'tcp' modifier applied to host");

	case Q_SCTP:
		bpf_error("'sctp' modifier applied to host");

	case Q_UDP:
		bpf_error("'udp' modifier applied to host");

	case Q_ICMP:
		bpf_error("'icmp' modifier applied to host");

	case Q_IGMP:
		bpf_error("'igmp' modifier applied to host");

	case Q_IGRP:
		bpf_error("'igrp' modifier applied to host");

	case Q_PIM:
		bpf_error("'pim' modifier applied to host");

	case Q_VRRP:
		bpf_error("'vrrp' modifier applied to host");

	case Q_ATALK:
		bpf_error("ATALK host filtering not implemented");

	case Q_AARP:
		bpf_error("AARP host filtering not implemented");

	case Q_DECNET:
		return gen_dnhostop(addr, dir, off_nl);

	case Q_SCA:
		bpf_error("SCA host filtering not implemented");

	case Q_LAT:
		bpf_error("LAT host filtering not implemented");

	case Q_MOPDL:
		bpf_error("MOPDL host filtering not implemented");

	case Q_MOPRC:
		bpf_error("MOPRC host filtering not implemented");

#ifdef INET6
	case Q_IPV6:
		bpf_error("'ip6' modifier applied to ip host");

	case Q_ICMPV6:
		bpf_error("'icmp6' modifier applied to host");
#endif /* INET6 */

	case Q_AH:
		bpf_error("'ah' modifier applied to host");

	case Q_ESP:
		bpf_error("'esp' modifier applied to host");

	case Q_ISO:
		bpf_error("ISO host filtering not implemented");

	case Q_ESIS:
		bpf_error("'esis' modifier applied to host");

	case Q_ISIS:
		bpf_error("'isis' modifier applied to host");

	case Q_CLNP:
		bpf_error("'clnp' modifier applied to host");

	case Q_STP:
		bpf_error("'stp' modifier applied to host");

	case Q_IPX:
		bpf_error("IPX host filtering not implemented");

	case Q_NETBEUI:
		bpf_error("'netbeui' modifier applied to host");

	default:
		abort();
	}
	/* NOTREACHED */
}

#ifdef INET6
static struct block *
gen_host6(addr, mask, proto, dir)
	struct in6_addr *addr;
	struct in6_addr *mask;
	int proto;
	int dir;
{
	switch (proto) {

	case Q_DEFAULT:
		return gen_host6(addr, mask, Q_IPV6, dir);

	case Q_IP:
		bpf_error("'ip' modifier applied to ip6 host");

	case Q_RARP:
		bpf_error("'rarp' modifier applied to ip6 host");

	case Q_ARP:
		bpf_error("'arp' modifier applied to ip6 host");

	case Q_SCTP:
		bpf_error("'sctp' modifier applied to host");

	case Q_TCP:
		bpf_error("'tcp' modifier applied to host");

	case Q_UDP:
		bpf_error("'udp' modifier applied to host");

	case Q_ICMP:
		bpf_error("'icmp' modifier applied to host");

	case Q_IGMP:
		bpf_error("'igmp' modifier applied to host");

	case Q_IGRP:
		bpf_error("'igrp' modifier applied to host");

	case Q_PIM:
		bpf_error("'pim' modifier applied to host");

	case Q_VRRP:
		bpf_error("'vrrp' modifier applied to host");

	case Q_ATALK:
		bpf_error("ATALK host filtering not implemented");

	case Q_AARP:
		bpf_error("AARP host filtering not implemented");

	case Q_DECNET:
		bpf_error("'decnet' modifier applied to ip6 host");

	case Q_SCA:
		bpf_error("SCA host filtering not implemented");

	case Q_LAT:
		bpf_error("LAT host filtering not implemented");

	case Q_MOPDL:
		bpf_error("MOPDL host filtering not implemented");

	case Q_MOPRC:
		bpf_error("MOPRC host filtering not implemented");

	case Q_IPV6:
		return gen_hostop6(addr, mask, dir, ETHERTYPE_IPV6,
				  off_nl + 8, off_nl + 24);

	case Q_ICMPV6:
		bpf_error("'icmp6' modifier applied to host");

	case Q_AH:
		bpf_error("'ah' modifier applied to host");

	case Q_ESP:
		bpf_error("'esp' modifier applied to host");

	case Q_ISO:
		bpf_error("ISO host filtering not implemented");

	case Q_ESIS:
		bpf_error("'esis' modifier applied to host");

	case Q_ISIS:
		bpf_error("'isis' modifier applied to host");

	case Q_CLNP:
		bpf_error("'clnp' modifier applied to host");

	case Q_STP:
		bpf_error("'stp' modifier applied to host");

	case Q_IPX:
		bpf_error("IPX host filtering not implemented");

	case Q_NETBEUI:
		bpf_error("'netbeui' modifier applied to host");

	default:
		abort();
	}
	/* NOTREACHED */
}
#endif /*INET6*/

#ifndef INET6
static struct block *
gen_gateway(eaddr, alist, proto, dir)
	const u_char *eaddr;
	bpf_u_int32 **alist;
	int proto;
	int dir;
{
	struct block *b0, *b1, *tmp;

	if (dir != 0)
		bpf_error("direction applied to 'gateway'");

	switch (proto) {
	case Q_DEFAULT:
	case Q_IP:
	case Q_ARP:
	case Q_RARP:
		if (linktype == DLT_EN10MB)
			b0 = gen_ehostop(eaddr, Q_OR);
		else if (linktype == DLT_FDDI)
			b0 = gen_fhostop(eaddr, Q_OR);
		else if (linktype == DLT_IEEE802)
			b0 = gen_thostop(eaddr, Q_OR);
		else if (linktype == DLT_IEEE802_11)
			b0 = gen_wlanhostop(eaddr, Q_OR);
		else if (linktype == DLT_SUNATM && is_lane) {
			/*
			 * Check that the packet doesn't begin with an
			 * LE Control marker.  (We've already generated
			 * a test for LANE.)
			 */
			b1 = gen_cmp(SUNATM_PKT_BEGIN_POS, BPF_H, 0xFF00);
			gen_not(b1);

			/*
			 * Now check the MAC address.
			 */
			b0 = gen_ehostop(eaddr, Q_OR);
			gen_and(b1, b0);
		} else if (linktype == DLT_IP_OVER_FC)
			b0 = gen_ipfchostop(eaddr, Q_OR);
		else
			bpf_error(
			    "'gateway' supported only on ethernet/FDDI/token ring/802.11/Fibre Channel");

		b1 = gen_host(**alist++, 0xffffffff, p

⌨️ 快捷键说明

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