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

📄 gencode.c

📁 Windows XP下的抓包程序实现
💻 C
📖 第 1 页 / 共 5 页
字号:
		 * (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00)		 *		 * XXX - what about ISO PDUs, e.g. CLNP, ISIS, ESIS,		 * or PPP with the PPP NLPID (e.g., PPPoA)?  The		 * latter would presumably be treated the way PPPoE		 * should be, so you can do "pppoe and udp port 2049"		 * or "pppoa and tcp port 80" and have it check for		 * PPPo{A,E} and a PPP protocol of IP and....		 */		off_linktype = 0;		off_nl = 8;		/* 802.2+SNAP */		off_nl_nosnap = 3;	/* 802.2 */		return;	case DLT_SUNATM:		/*		 * Full Frontal ATM; you get AALn PDUs with an ATM		 * pseudo-header.		 */		is_atm = 1;		off_vpi = SUNATM_VPI_POS;		off_vci = SUNATM_VCI_POS;		off_proto = PROTO_POS;		off_mac = -1;	/* LLC-encapsulated, so no MAC-layer header */		off_payload = SUNATM_PKT_BEGIN_POS;		off_linktype = off_payload;		off_nl = off_payload+8;		/* 802.2+SNAP */		off_nl_nosnap = off_payload+3;	/* 802.2 */		return;	case DLT_RAW:		off_linktype = -1;		off_nl = 0;		off_nl_nosnap = 0;	/* no 802.2 LLC */		return;	case DLT_LINUX_SLL:	/* fake header for Linux cooked socket */		off_linktype = 14;		off_nl = 16;		off_nl_nosnap = 16;	/* no 802.2 LLC */		return;	case DLT_LTALK:		/*		 * LocalTalk does have a 1-byte type field in the LLAP header,		 * but really it just indicates whether there is a "short" or		 * "long" DDP packet following.		 */		off_linktype = -1;		off_nl = 0;		off_nl_nosnap = 0;	/* no 802.2 LLC */		return;	case DLT_IP_OVER_FC:		/*		 * RFC 2625 IP-over-Fibre-Channel doesn't really have a		 * link-level type field.  We set "off_linktype" to the		 * offset of the LLC header.		 *		 * To check for Ethernet types, we assume that SSAP = SNAP		 * is being used and pick out the encapsulated Ethernet type.		 * XXX - should we generate code to check for SNAP? RFC		 * 2625 says SNAP should be used.		 */		off_linktype = 16;		off_nl = 24;		/* IPFC+802.2+SNAP */		off_nl_nosnap = 19;	/* IPFC+802.2 */		return;	case DLT_FRELAY:		/*		 * XXX - we should set this to handle SNAP-encapsulated		 * frames (NLPID of 0x80).		 */		off_linktype = -1;		off_nl = 0;		off_nl_nosnap = 0;	/* no 802.2 LLC */		return;                /*                 * the only BPF-interesting FRF.16 frames are non-control frames;                 * Frame Relay has a variable length link-layer                 * so lets start with offset 4 for now and increments later on (FIXME);                 */	case DLT_MFR:		off_linktype = -1;		off_nl = 4;		off_nl_nosnap = 0;	/* XXX - for now -> no 802.2 LLC */		return;	case DLT_APPLE_IP_OVER_IEEE1394:		off_linktype = 16;		off_nl = 18;		off_nl_nosnap = 18;	/* no 802.2 LLC */		return;	case DLT_LINUX_IRDA:		/*		 * Currently, only raw "link[N:M]" filtering is supported.		 */		off_linktype = -1;		off_nl = -1;		off_nl_nosnap = -1;		return;	case DLT_DOCSIS:		/*		 * Currently, only raw "link[N:M]" filtering is supported.		 */		off_linktype = -1;		off_nl = -1;		off_nl_nosnap = -1;		return;	case DLT_SYMANTEC_FIREWALL:		off_linktype = 6;		off_nl = 44;		/* Ethernet II */		off_nl_nosnap = 44;	/* XXX - what does it do with 802.3 packets? */		return;	case DLT_PFLOG:		off_linktype = 0;		/* XXX read this from pf.h? */		off_nl = PFLOG_HDRLEN;		off_nl_nosnap = PFLOG_HDRLEN;	/* no 802.2 LLC */		return;        case DLT_JUNIPER_MFR:        case DLT_JUNIPER_MLFR:        case DLT_JUNIPER_MLPPP:        case DLT_JUNIPER_PPP:        case DLT_JUNIPER_CHDLC:        case DLT_JUNIPER_FRELAY:                off_linktype = 4;		off_nl = 4;		off_nl_nosnap = -1;	/* no 802.2 LLC */                return;	case DLT_JUNIPER_ATM1:		off_linktype = 4; /* in reality variable between 4-8 */		off_nl = 4;		off_nl_nosnap = 14;		return;	case DLT_JUNIPER_ATM2:		off_linktype = 8; /* in reality variable between 8-12 */		off_nl = 8;		off_nl_nosnap = 18;		return;		/* frames captured on a Juniper PPPoE service PIC		 * contain raw ethernet frames */	case DLT_JUNIPER_PPPOE:        case DLT_JUNIPER_ETHER:		off_linktype = 16;		off_nl = 18;		/* Ethernet II */		off_nl_nosnap = 21;	/* 802.3+802.2 */		return;	case DLT_JUNIPER_PPPOE_ATM:		off_linktype = 4;		off_nl = 6;		off_nl_nosnap = -1;	 /* no 802.2 LLC */		return;	case DLT_JUNIPER_GGSN:		off_linktype = 6;		off_nl = 12;		off_nl_nosnap = -1;	 /* no 802.2 LLC */		return;	case DLT_JUNIPER_ES:		off_linktype = 6;		off_nl = -1;		/* not really a network layer but raw IP adresses */		off_nl_nosnap = -1;	/* no 802.2 LLC */		return;	case DLT_JUNIPER_MONITOR:		off_linktype = 12;		off_nl = 12;		/* raw IP/IP6 header */		off_nl_nosnap = -1;	/* no 802.2 LLC */		return;	case DLT_JUNIPER_SERVICES:		off_linktype = 12;		off_nl = -1;		/* L3 proto location dep. on cookie type */		off_nl_nosnap = -1;	/* no 802.2 LLC */		return;	case DLT_MTP2:		off_sio = 3;		off_opc = 4;		off_dpc = 4;		off_sls = 7;		off_linktype = -1;		off_nl = -1;		off_nl_nosnap = -1;		return;#ifdef DLT_PFSYNC	case DLT_PFSYNC:		off_linktype = -1;		off_nl = 4;		off_nl_nosnap = 4;		return;#endif	case DLT_LINUX_LAPD:		/*		 * Currently, only raw "link[N:M]" filtering is supported.		 */		off_linktype = -1;		off_nl = -1;		off_nl_nosnap = -1;		return;	}	bpf_error("unknown data link type %d", linktype);	/* NOTREACHED */}/* * Load a value relative to the beginning of the link-layer header. * The link-layer header doesn't necessarily begin at the beginning * of the packet data; there might be a variable-length prefix containing * radio information. */static struct slist *gen_load_llrel(offset, size)	u_int offset, size;{	struct slist *s, *s2;	s = gen_llprefixlen();	/*	 * If "s" is non-null, it has code to arrange that the X register	 * contains the length of the prefix preceding the link-layer	 * header.	 *	 * Otherwise, the length of the prefix preceding the link-layer	 * header is "off_ll".	 */	if (s != NULL) {		/*		 * There's a variable-length prefix preceding the		 * link-layer header.  "s" points to a list of statements		 * that put the length of that prefix into the X register.		 * do an indirect load, to use the X register as an offset.		 */		s2 = new_stmt(BPF_LD|BPF_IND|size);		s2->s.k = offset;		sappend(s, s2);	} else {		/*		 * There is no variable-length header preceding the		 * link-layer header; add in off_ll, which, if there's		 * a fixed-length header preceding the link-layer header,		 * is the length of that header.		 */		s = new_stmt(BPF_LD|BPF_ABS|size);		s->s.k = offset + off_ll;	}	return s;}/* * Load a value relative to the beginning of the specified header. */static struct slist *gen_load_a(offrel, offset, size)	enum e_offrel offrel;	u_int offset, size;{	struct slist *s, *s2;	switch (offrel) {	case OR_PACKET:                s = new_stmt(BPF_LD|BPF_ABS|size);                s->s.k = offset;		break;	case OR_LINK:		s = gen_load_llrel(offset, size);		break;	case OR_NET:		s = gen_load_llrel(off_nl + offset, size);		break;	case OR_NET_NOSNAP:		s = gen_load_llrel(off_nl_nosnap + offset, size);		break;	case OR_TRAN_IPV4:		/*		 * Load the X register with the length of the IPv4 header		 * (plus the offset of the link-layer header, if it's		 * preceded by a variable-length header such as a radio		 * header), in bytes.		 */		s = gen_loadx_iphdrlen();		/*		 * Load the item at {offset of the link-layer header} +		 * {offset, relative to the start of the link-layer		 * header, of the IPv4 header} + {length of the IPv4 header} +		 * {specified offset}.		 *		 * (If the link-layer is variable-length, it's included		 * in the value in the X register, and off_ll is 0.)		 */		s2 = new_stmt(BPF_LD|BPF_IND|size);		s2->s.k = off_ll + off_nl + offset;		sappend(s, s2);		break;	case OR_TRAN_IPV6:		s = gen_load_llrel(off_nl + 40 + offset, size);		break;	default:		abort();		return NULL;	}	return s;}/* * Generate code to load into the X register the sum of the length of * the IPv4 header and any variable-length header preceding the link-layer * header. */static struct slist *gen_loadx_iphdrlen(){	struct slist *s, *s2;	s = gen_llprefixlen();	if (s != NULL) {		/*		 * There's a variable-length prefix preceding the		 * link-layer header.  "s" points to a list of statements		 * that put the length of that prefix into the X register.		 * The 4*([k]&0xf) addressing mode can't be used, as we		 * don't have a constant offset, so we have to load the		 * value in question into the A register and add to it		 * the value from the X register.		 */		s2 = new_stmt(BPF_LD|BPF_IND|BPF_B);		s2->s.k = off_nl;		sappend(s, s2);		s2 = new_stmt(BPF_ALU|BPF_AND|BPF_K);		s2->s.k = 0xf;		sappend(s, s2);		s2 = new_stmt(BPF_ALU|BPF_LSH|BPF_K);		s2->s.k = 2;		sappend(s, s2);		/*		 * The A register now contains the length of the		 * IP header.  We need to add to it the length		 * of the prefix preceding the link-layer		 * header, which is still in the X register, and		 * move the result into the X register.		 */		sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));		sappend(s, new_stmt(BPF_MISC|BPF_TAX));	} else {		/*		 * There is no variable-length header preceding the		 * link-layer header; add in off_ll, which, if there's		 * a fixed-length header preceding the link-layer header,		 * is the length of that header.		 */		s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);		s->s.k = off_ll + off_nl;	}	return s;}static struct block *gen_uncond(rsense)	int rsense;{	struct block *b;	struct slist *s;	s = new_stmt(BPF_LD|BPF_IMM);	s->s.k = !rsense;	b = new_block(JMP(BPF_JEQ));	b->stmts = s;	return b;}static inline struct block *gen_true(){	return gen_uncond(1);}static inline struct block *gen_false(){	return gen_uncond(0);}/* * Byte-swap a 32-bit number. * ("htonl()" or "ntohl()" won't work - we want to byte-swap even on * big-endian platforms.) */#define	SWAPLONG(y) \((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))/* * 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/length field or to check the type/length field for * a value <= ETHERMTU to see whether it's a type field and then do * the appropriate test. */static struct block *gen_ether_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_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU);		gen_not(b0);		b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_H, (bpf_int32)			     ((proto << 8) | proto));		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(OR_LINK, off_linktype + 2, BPF_B,		    (bpf_int32)LLCSAP_IPX);		b1 = gen_cmp(OR_LINK, 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(OR_LINK, 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(OR_LINK, off_linktype, BPF_H,		    (bpf_int32)ETHERTYPE_IPX);		gen_or(b0, b1);		return b1;

⌨️ 快捷键说明

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