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

📄 gencode.c

📁 Windows XP下的抓包程序实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/*#define CHASE_CHAIN*//* * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#ifndef lintstatic const char rcsid[] _U_ =    "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.221.2.43 2006/09/13 07:36:19 guy Exp $ (LBL)";#endif#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifdef WIN32#include <pcap-stdinc.h>#else /* WIN32 */#include <sys/types.h>#include <sys/socket.h>#endif /* WIN32 *//* * XXX - why was this included even on UNIX? */#ifdef __MINGW32__#include "IP6_misc.h"#endif#ifndef WIN32#ifdef __NetBSD__#include <sys/param.h>#endif#include <netinet/in.h>#endif /* WIN32 */#include <stdlib.h>#include <string.h>#include <memory.h>#include <setjmp.h>#include <stdarg.h>#ifdef MSDOS#include "pcap-dos.h"#endif#include "pcap-int.h"#include "ethertype.h"#include "nlpid.h"#include "llc.h"#include "gencode.h"#include "atmuni31.h"#include "sunatmpos.h"#include "ppp.h"#include "sll.h"#include "arcnet.h"#include "pf.h"#ifndef offsetof#define offsetof(s, e) ((size_t)&((s *)0)->e)#endif#ifdef INET6#ifndef WIN32#include <netdb.h>	/* for "struct addrinfo" */#endif /* WIN32 */#endif /*INET6*/#include <pcap-namedb.h>#define ETHERMTU	1500#ifndef IPPROTO_SCTP#define IPPROTO_SCTP 132#endif#ifdef HAVE_OS_PROTO_H#include "os-proto.h"#endif#define JMP(c) ((c)|BPF_JMP|BPF_K)/* Locals */static jmp_buf top_ctx;static pcap_t *bpf_pcap;/* Hack for updating VLAN, MPLS, and PPPoE offsets. */static u_int	orig_linktype = -1U, orig_nl = -1U, label_stack_depth = -1U;/* XXX */#ifdef PCAP_FDDIPADstatic int	pcap_fddipad;#endif/* VARARGS */voidbpf_error(const char *fmt, ...){	va_list ap;	va_start(ap, fmt);	if (bpf_pcap != NULL)		(void)vsnprintf(pcap_geterr(bpf_pcap), PCAP_ERRBUF_SIZE,		    fmt, ap);	va_end(ap);	longjmp(top_ctx, 1);	/* NOTREACHED */}static void init_linktype(pcap_t *);static int alloc_reg(void);static void free_reg(int);static struct block *root;/* * Value passed to gen_load_a() to indicate what the offset argument * is relative to. */enum e_offrel {	OR_PACKET,	/* relative to the beginning of the packet */	OR_LINK,	/* relative to the link-layer header */	OR_NET,		/* relative to the network-layer header */	OR_NET_NOSNAP,	/* relative to the network-layer header, with no SNAP header at the link layer */	OR_TRAN_IPV4,	/* relative to the transport-layer header, with IPv4 network layer */	OR_TRAN_IPV6	/* relative to the transport-layer header, with IPv6 network layer */};/* * We divy out chunks of memory rather than call malloc each time so * we don't have to worry about leaking memory.  It's probably * not a big deal if all this memory was wasted but if this ever * goes into a library that would probably not be a good idea. * * XXX - this *is* in a library.... */#define NCHUNKS 16#define CHUNK0SIZE 1024struct chunk {	u_int n_left;	void *m;};static struct chunk chunks[NCHUNKS];static int cur_chunk;static void *newchunk(u_int);static void freechunks(void);static inline struct block *new_block(int);static inline struct slist *new_stmt(int);static struct block *gen_retblk(int);static inline void syntax(void);static void backpatch(struct block *, struct block *);static void merge(struct block *, struct block *);static struct block *gen_cmp(enum e_offrel, u_int, u_int, bpf_int32);static struct block *gen_cmp_gt(enum e_offrel, u_int, u_int, bpf_int32);static struct block *gen_cmp_ge(enum e_offrel, u_int, u_int, bpf_int32);static struct block *gen_cmp_lt(enum e_offrel, u_int, u_int, bpf_int32);static struct block *gen_cmp_le(enum e_offrel, u_int, u_int, bpf_int32);static struct block *gen_mcmp(enum e_offrel, u_int, u_int, bpf_int32,    bpf_u_int32);static struct block *gen_bcmp(enum e_offrel, u_int, u_int, const u_char *);static struct block *gen_ncmp(enum e_offrel, bpf_u_int32, bpf_u_int32,    bpf_u_int32, bpf_u_int32, int, bpf_int32);static struct slist *gen_load_llrel(u_int, u_int);static struct slist *gen_load_a(enum e_offrel, u_int, u_int);static struct slist *gen_loadx_iphdrlen(void);static struct block *gen_uncond(int);static inline struct block *gen_true(void);static inline struct block *gen_false(void);static struct block *gen_ether_linktype(int);static struct block *gen_linux_sll_linktype(int);static void insert_radiotap_load_llprefixlen(struct block *);static void insert_load_llprefixlen(struct block *);static struct slist *gen_llprefixlen(void);static struct block *gen_linktype(int);static struct block *gen_snap(bpf_u_int32, bpf_u_int32, u_int);static struct block *gen_llc_linktype(int);static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int);#ifdef INET6static struct block *gen_hostop6(struct in6_addr *, struct in6_addr *, int, int, u_int, u_int);#endifstatic struct block *gen_ahostop(const u_char *, int);static struct block *gen_ehostop(const u_char *, int);static struct block *gen_fhostop(const u_char *, int);static struct block *gen_thostop(const u_char *, int);static struct block *gen_wlanhostop(const u_char *, int);static struct block *gen_ipfchostop(const u_char *, int);static struct block *gen_dnhostop(bpf_u_int32, int);static struct block *gen_mpls_linktype(int);static struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int, int);#ifdef INET6static struct block *gen_host6(struct in6_addr *, struct in6_addr *, int, int, int);#endif#ifndef INET6static struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int);#endifstatic struct block *gen_ipfrag(void);static struct block *gen_portatom(int, bpf_int32);static struct block *gen_portrangeatom(int, bpf_int32, bpf_int32);#ifdef INET6static struct block *gen_portatom6(int, bpf_int32);static struct block *gen_portrangeatom6(int, bpf_int32, bpf_int32);#endifstruct block *gen_portop(int, int, int);static struct block *gen_port(int, int, int);struct block *gen_portrangeop(int, int, int, int);static struct block *gen_portrange(int, int, int, int);#ifdef INET6struct block *gen_portop6(int, int, int);static struct block *gen_port6(int, int, int);struct block *gen_portrangeop6(int, int, int, int);static struct block *gen_portrange6(int, int, int, int);#endifstatic int lookup_proto(const char *, int);static struct block *gen_protochain(int, int, int);static struct block *gen_proto(int, int, int);static struct slist *xfer_to_x(struct arth *);static struct slist *xfer_to_a(struct arth *);static struct block *gen_mac_multicast(int);static struct block *gen_len(int, int);static struct block *gen_msg_abbrev(int type);static void *newchunk(n)	u_int n;{	struct chunk *cp;	int k;	size_t size;#ifndef __NetBSD__	/* XXX Round up to nearest long. */	n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1);#else	/* XXX Round up to structure boundary. */	n = ALIGN(n);#endif	cp = &chunks[cur_chunk];	if (n > cp->n_left) {		++cp, k = ++cur_chunk;		if (k >= NCHUNKS)			bpf_error("out of memory");		size = CHUNK0SIZE << k;		cp->m = (void *)malloc(size);		if (cp->m == NULL)			bpf_error("out of memory");		memset((char *)cp->m, 0, size);		cp->n_left = size;		if (n > size)			bpf_error("out of memory");	}	cp->n_left -= n;	return (void *)((char *)cp->m + cp->n_left);}static voidfreechunks(){	int i;	cur_chunk = 0;	for (i = 0; i < NCHUNKS; ++i)		if (chunks[i].m != NULL) {			free(chunks[i].m);			chunks[i].m = NULL;		}}/* * A strdup whose allocations are freed after code generation is over. */char *sdup(s)	register const char *s;{	int n = strlen(s) + 1;	char *cp = newchunk(n);	strlcpy(cp, s, n);	return (cp);}static inline struct block *new_block(code)	int code;{	struct block *p;	p = (struct block *)newchunk(sizeof(*p));	p->s.code = code;	p->head = p;	return p;}static inline struct slist *new_stmt(code)	int code;{	struct slist *p;	p = (struct slist *)newchunk(sizeof(*p));	p->s.code = code;	return p;}static struct block *gen_retblk(v)	int v;{	struct block *b = new_block(BPF_RET|BPF_K);	b->s.k = v;	return b;}static inline voidsyntax(){	bpf_error("syntax error in filter expression");}static bpf_u_int32 netmask;static int snaplen;int no_optimize;intpcap_compile(pcap_t *p, struct bpf_program *program,	     char *buf, int optimize, bpf_u_int32 mask){	extern int n_errors;	int len;#ifdef HAVE_REMOTE	/*	   Check if:	   - We are on an remote capture	   - we do not want to capture RPCAP traffic	   	   If so, we have to save the current filter, because we have to add some	   piece of stuff later	*/	if ( (p->rmt_clientside) && (p->rmt_flags & PCAP_OPENFLAG_NOCAPTURE_RPCAP) )	{	int bufferlen;		if (p->currentfilter)			free (p->currentfilter);		if (buf)			bufferlen= strlen(buf) + 1;		else			bufferlen= 1;		p->currentfilter= (char *) malloc( sizeof(char) * bufferlen);		strncpy(p->currentfilter, buf, bufferlen);		p->currentfilter[bufferlen - 1]= 0;	}#endif /* HAVE_REMOTE */	no_optimize = 0;	n_errors = 0;	root = NULL;	bpf_pcap = p;	if (setjmp(top_ctx)) {		lex_cleanup();		freechunks();		return (-1);	}	netmask = mask;	snaplen = pcap_snapshot(p);	if (snaplen == 0) {		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,			 "snaplen of 0 rejects all packets");		return -1;	}	lex_init(buf ? buf : "");	init_linktype(p);	(void)pcap_parse();	if (n_errors)		syntax();	if (root == NULL)		root = gen_retblk(snaplen);	if (optimize && !no_optimize) {		bpf_optimize(&root);		if (root == NULL ||		    (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0))			bpf_error("expression rejects all packets");	}	program->bf_insns = icode_to_fcode(root, &len);	program->bf_len = len;	lex_cleanup();	freechunks();	return (0);}/* * entry point for using the compiler with no pcap open * pass in all the stuff that is needed explicitly instead. */intpcap_compile_nopcap(int snaplen_arg, int linktype_arg,		    struct bpf_program *program,	     char *buf, int optimize, bpf_u_int32 mask){	pcap_t *p;	int ret;	p = pcap_open_dead(linktype_arg, snaplen_arg);	if (p == NULL)		return (-1);	ret = pcap_compile(p, program, buf, optimize, mask);	pcap_close(p);	return (ret);}/* * Clean up a "struct bpf_program" by freeing all the memory allocated * in it. */voidpcap_freecode(struct bpf_program *program){	program->bf_len = 0;	if (program->bf_insns != NULL) {		free((char *)program->bf_insns);		program->bf_insns = NULL;	}}/* * Backpatch the blocks in 'list' to 'target'.  The 'sense' field indicates * which of the jt and jf fields has been resolved and which is a pointer * back to another unresolved block (or nil).  At least one of the fields * in each block is already resolved. */static voidbackpatch(list, target)	struct block *list, *target;{	struct block *next;	while (list) {		if (!list->sense) {			next = JT(list);			JT(list) = target;		} else {			next = JF(list);			JF(list) = target;		}		list = next;	}}/* * Merge the lists in b0 and b1, using the 'sense' field to indicate * which of jt and jf is the link. */static voidmerge(b0, b1)	struct block *b0, *b1;{	register struct block **p = &b0;	/* Find end of list. */	while (*p)		p = !((*p)->sense) ? &JT(*p) : &JF(*p);	/* Concatenate the lists. */	*p = b1;}voidfinish_parse(p)	struct block *p;{	backpatch(p, gen_retblk(snaplen));	p->sense = !p->sense;	backpatch(p, gen_retblk(0));	root = p->head;	/*	 * Insert before the statements of the first (root) block any	 * statements needed to load the lengths of any variable-length	 * headers into registers.	 *	 * XXX - a fancier strategy would be to insert those before the	 * statements of all blocks that use those lengths and that	 * have no predecessors that use them, so that we only compute	 * the lengths if we need them.  There might be even better	 * approaches than that.  However, as we're currently only	 * handling variable-length radiotap headers, and as all	 * filtering expressions other than raw link[M:N] tests	 * require the length of that header, doing more for that	 * header length isn't really worth the effort.

⌨️ 快捷键说明

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