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

📄 gencode.c

📁 该软件根据网络数据生成NetFlow记录。NetFlow可用于网络规划、负载均衡、安全监控等
💻 C
📖 第 1 页 / 共 3 页
字号:
			 */			return (gen_host(dn_addr, 0, proto, dir));		} else {			alist = pcap_nametoaddr(name);			if (alist == NULL || *alist == NULL)				bpf_error("unknown host '%s'", name);			tproto = proto;			if (off_linktype == -1 && tproto == Q_DEFAULT)				tproto = Q_IP;			b = gen_host(**alist++, 0xffffffff, tproto, dir);			while (*alist) {				tmp = gen_host(**alist++, 0xffffffff,					       tproto, dir);				gen_or(b, tmp);				b = tmp;			}			return b;		}	case Q_PORT:		if (proto != Q_DEFAULT && proto != Q_UDP && proto != Q_TCP)			bpf_error("illegal qualifier of 'port'");		if (pcap_nametoport(name, &port, &real_proto) == 0)			bpf_error("unknown port '%s'", name);		if (proto == Q_UDP) {			if (real_proto == IPPROTO_TCP)				bpf_error("port '%s' is tcp", name);			else				/* override PROTO_UNDEF */				real_proto = IPPROTO_UDP;		}		if (proto == Q_TCP) {			if (real_proto == IPPROTO_UDP)				bpf_error("port '%s' is udp", name);			else				/* override PROTO_UNDEF */				real_proto = IPPROTO_TCP;		}		return gen_port(port, real_proto, dir);	case Q_GATEWAY:		eaddr = pcap_ether_hostton(name);		if (eaddr == NULL)			bpf_error("unknown ether host: %s", name);		alist = pcap_nametoaddr(name);		if (alist == NULL || *alist == NULL)			bpf_error("unknown host '%s'", name);		return gen_gateway(eaddr, alist, proto, dir);	case Q_PROTO:		real_proto = lookup_proto(name, proto);		if (real_proto >= 0)			return gen_proto(real_proto, proto, dir);		else			bpf_error("unknown protocol: %s", name);	case Q_UNDEF:		syntax();		/* NOTREACHED */	}	abort();	/* NOTREACHED */}struct block *gen_mcode(s1, s2, masklen, q)	register const char *s1, *s2;	register int masklen;	struct qual q;{	register int nlen, mlen;	bpf_u_int32 n, m;	nlen = __pcap_atoin(s1, &n);	/* Promote short ipaddr */	n <<= 32 - nlen;	if (s2 != NULL) {		mlen = __pcap_atoin(s2, &m);		/* Promote short ipaddr */		m <<= 32 - mlen;		if ((n & ~m) != 0)			bpf_error("non-network bits set in \"%s mask %s\"",			    s1, s2);	} else {		/* Convert mask len to mask */		if (masklen > 32)			bpf_error("mask length must be <= 32");		m = 0xffffffff << (32 - masklen);		if ((n & ~m) != 0)			bpf_error("non-network bits set in \"%s/%d\"",			    s1, masklen);	}	switch (q.addr) {	case Q_NET:		return gen_host(n, m, q.proto, q.dir);	default:		bpf_error("Mask syntax for networks only");		/* NOTREACHED */	}}struct block *gen_ncode(s, v, q)	register const char *s;	bpf_u_int32 v;	struct qual q;{	bpf_u_int32 mask;	int proto = q.proto;	int dir = q.dir;	register int vlen;	if (s == NULL)		vlen = 32;	else if (q.proto == Q_DECNET)		vlen = __pcap_atodn(s, &v);	else		vlen = __pcap_atoin(s, &v);	switch (q.addr) {	case Q_DEFAULT:	case Q_HOST:	case Q_NET:		if (proto == Q_DECNET)			return gen_host(v, 0, proto, dir);		else if (proto == Q_LINK) {			bpf_error("illegal link layer address");		} else {			mask = 0xffffffff;			if (s == NULL && q.addr == Q_NET) {				/* Promote short net number */				while (v && (v & 0xff000000) == 0) {					v <<= 8;					mask <<= 8;				}			} else {				/* Promote short ipaddr */				v <<= 32 - vlen;				mask <<= 32 - vlen;			}			return gen_host(v, mask, proto, dir);		}	case Q_PORT:		if (proto == Q_UDP)			proto = IPPROTO_UDP;		else if (proto == Q_TCP)			proto = IPPROTO_TCP;		else if (proto == Q_DEFAULT)			proto = PROTO_UNDEF;		else			bpf_error("illegal qualifier of 'port'");		return gen_port((int)v, proto, dir);	case Q_GATEWAY:		bpf_error("'gateway' requires a name");		/* NOTREACHED */	case Q_PROTO:		return gen_proto((int)v, proto, dir);	case Q_UNDEF:		syntax();		/* NOTREACHED */	default:		abort();		/* NOTREACHED */	}	/* NOTREACHED */}struct block *gen_ecode(eaddr, q)	register const u_char *eaddr;	struct qual q;{	if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {		if (linktype == DLT_EN10MB)			return gen_ehostop(eaddr, (int)q.dir);		if (linktype == DLT_FDDI)			return gen_fhostop(eaddr, (int)q.dir);	}	bpf_error("ethernet address used in non-ether expression");	/* NOTREACHED */}voidsappend(s0, s1)	struct slist *s0, *s1;{	/*	 * This is definitely not the best way to do this, but the	 * lists will rarely get long.	 */	while (s0->next)		s0 = s0->next;	s0->next = s1;}static struct slist *xfer_to_x(a)	struct arth *a;{	struct slist *s;	s = new_stmt(BPF_LDX|BPF_MEM);	s->s.k = a->regno;	return s;}static struct slist *xfer_to_a(a)	struct arth *a;{	struct slist *s;	s = new_stmt(BPF_LD|BPF_MEM);	s->s.k = a->regno;	return s;}struct arth *gen_load(proto, index, size)	int proto;	struct arth *index;	int size;{	struct slist *s, *tmp;	struct block *b;	int regno = alloc_reg();	free_reg(index->regno);	switch (size) {	default:		bpf_error("data size must be 1, 2, or 4");	case 1:		size = BPF_B;		break;	case 2:		size = BPF_H;		break;	case 4:		size = BPF_W;		break;	}	switch (proto) {	default:		bpf_error("unsupported index operation");	case Q_LINK:		s = xfer_to_x(index);		tmp = new_stmt(BPF_LD|BPF_IND|size);		sappend(s, tmp);		sappend(index->s, s);		break;	case Q_IP:	case Q_ARP:	case Q_RARP:	case Q_ATALK:	case Q_DECNET:	case Q_SCA:	case Q_LAT:	case Q_MOPRC:	case Q_MOPDL:		/* XXX Note that we assume a fixed link link header here. */		s = xfer_to_x(index);		tmp = new_stmt(BPF_LD|BPF_IND|size);		tmp->s.k = off_nl;		sappend(s, tmp);		sappend(index->s, s);		b = gen_proto_abbrev(proto);		if (index->b)			gen_and(index->b, b);		index->b = b;		break;	case Q_TCP:	case Q_UDP:	case Q_ICMP:	case Q_IGMP:	case Q_IGRP:		s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);		s->s.k = off_nl;		sappend(s, xfer_to_a(index));		sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));		sappend(s, new_stmt(BPF_MISC|BPF_TAX));		sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size));		tmp->s.k = off_nl;		sappend(index->s, s);		gen_and(gen_proto_abbrev(proto), b = gen_ipfrag());		if (index->b)			gen_and(index->b, b);		index->b = b;		break;	}	index->regno = regno;	s = new_stmt(BPF_ST);	s->s.k = regno;	sappend(index->s, s);	return index;}struct block *gen_relation(code, a0, a1, reversed)	int code;	struct arth *a0, *a1;	int reversed;{	struct slist *s0, *s1, *s2;	struct block *b, *tmp;	s0 = xfer_to_x(a1);	s1 = xfer_to_a(a0);	s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X);	b = new_block(JMP(code));	if (code == BPF_JGT || code == BPF_JGE) {		reversed = !reversed;		b->s.k = 0x80000000;	}	if (reversed)		gen_not(b);	sappend(s1, s2);	sappend(s0, s1);	sappend(a1->s, s0);	sappend(a0->s, a1->s);	b->stmts = a0->s;	free_reg(a0->regno);	free_reg(a1->regno);	/* 'and' together protocol checks */	if (a0->b) {		if (a1->b) {			gen_and(a0->b, tmp = a1->b);		}		else			tmp = a0->b;	} else		tmp = a1->b;	if (tmp)		gen_and(tmp, b);	return b;}struct arth *gen_loadlen(){	int regno = alloc_reg();	struct arth *a = (struct arth *)newchunk(sizeof(*a));	struct slist *s;	s = new_stmt(BPF_LD|BPF_LEN);	s->next = new_stmt(BPF_ST);	s->next->s.k = regno;	a->s = s;	a->regno = regno;	return a;}struct arth *gen_loadi(val)	int val;{	struct arth *a;	struct slist *s;	int reg;	a = (struct arth *)newchunk(sizeof(*a));	reg = alloc_reg();	s = new_stmt(BPF_LD|BPF_IMM);	s->s.k = val;	s->next = new_stmt(BPF_ST);	s->next->s.k = reg;	a->s = s;	a->regno = reg;	return a;}struct arth *gen_neg(a)	struct arth *a;{	struct slist *s;	s = xfer_to_a(a);	sappend(a->s, s);	s = new_stmt(BPF_ALU|BPF_NEG);	s->s.k = 0;	sappend(a->s, s);	s = new_stmt(BPF_ST);	s->s.k = a->regno;	sappend(a->s, s);	return a;}struct arth *gen_arth(code, a0, a1)	int code;	struct arth *a0, *a1;{	struct slist *s0, *s1, *s2;	s0 = xfer_to_x(a1);	s1 = xfer_to_a(a0);	s2 = new_stmt(BPF_ALU|BPF_X|code);	sappend(s1, s2);	sappend(s0, s1);	sappend(a1->s, s0);	sappend(a0->s, a1->s);	free_reg(a1->regno);	s0 = new_stmt(BPF_ST);	a0->regno = s0->s.k = alloc_reg();	sappend(a0->s, s0);	return a0;}/* * Here we handle simple allocation of the scratch registers. * If too many registers are alloc'd, the allocator punts. */static int regused[BPF_MEMWORDS];static int curreg;/* * Return the next free register. */static intalloc_reg(){	int n = BPF_MEMWORDS;	while (--n >= 0) {		if (regused[curreg])			curreg = (curreg + 1) % BPF_MEMWORDS;		else {			regused[curreg] = 1;			return curreg;		}	}	bpf_error("too many registers needed to evaluate expression");	/* NOTREACHED */}/* * Return a register to the table so it can * be used later. */static voidfree_reg(n)	int n;{	regused[n] = 0;}static struct block *gen_len(jmp, n)	int jmp, n;{	struct slist *s;	struct block *b;	s = new_stmt(BPF_LD|BPF_LEN);	b = new_block(JMP(jmp));	b->stmts = s;	b->s.k = n;	return b;}struct block *gen_greater(n)	int n;{	return gen_len(BPF_JGE, n);}struct block *gen_less(n)	int n;{	struct block *b;	b = gen_len(BPF_JGT, n);	gen_not(b);	return b;}struct block *gen_byteop(op, idx, val)	int op, idx, val;{	struct block *b;	struct slist *s;	switch (op) {	default:		abort();	case '=':		return gen_cmp((u_int)idx, BPF_B, (bpf_int32)val);	case '<':		b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val);		b->s.code = JMP(BPF_JGE);		gen_not(b);		return b;	case '>':		b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val);		b->s.code = JMP(BPF_JGT);		return b;	case '|':		s = new_stmt(BPF_ALU|BPF_OR|BPF_K);		break;	case '&':		s = new_stmt(BPF_ALU|BPF_AND|BPF_K);		break;	}	s->s.k = val;	b = new_block(JMP(BPF_JEQ));	b->stmts = s;	gen_not(b);	return b;}struct block *gen_broadcast(proto)	int proto;{	bpf_u_int32 hostmask;	struct block *b0, *b1, *b2;	static u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };	switch (proto) {	case Q_DEFAULT:	case Q_LINK:		if (linktype == DLT_EN10MB)			return gen_ehostop(ebroadcast, Q_DST);		if (linktype == DLT_FDDI)			return gen_fhostop(ebroadcast, Q_DST);		bpf_error("not a broadcast link");		break;	case Q_IP:		b0 = gen_linktype(ETHERTYPE_IP);		hostmask = ~netmask;		b1 = gen_mcmp(off_nl + 16, BPF_W, (bpf_int32)0, hostmask);		b2 = gen_mcmp(off_nl + 16, BPF_W,			      (bpf_int32)(~0 & hostmask), hostmask);		gen_or(b1, b2);		gen_and(b0, b2);		return b2;	}	bpf_error("only ether/ip broadcast filters supported");}struct block *gen_multicast(proto)	int proto;{	register struct block *b0, *b1;	register struct slist *s;	switch (proto) {	case Q_DEFAULT:	case Q_LINK:		if (linktype == DLT_EN10MB) {			/* ether[0] & 1 != 0 */			s = new_stmt(BPF_LD|BPF_B|BPF_ABS);			s->s.k = 0;			b0 = new_block(JMP(BPF_JSET));			b0->s.k = 1;			b0->stmts = s;			return b0;		}		if (linktype == DLT_FDDI) {			/* XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX */			/* fddi[1] & 1 != 0 */			s = new_stmt(BPF_LD|BPF_B|BPF_ABS);			s->s.k = 1;			b0 = new_block(JMP(BPF_JSET));			b0->s.k = 1;			b0->stmts = s;			return b0;		}		/* Link not known to support multicasts */		break;	case Q_IP:		b0 = gen_linktype(ETHERTYPE_IP);		b1 = gen_cmp(off_nl + 16, BPF_B, (bpf_int32)224);		b1->s.code = JMP(BPF_JGE);		gen_and(b0, b1);		return b1;	}	bpf_error("only IP multicast filters supported on ethernet/FDDI");}/* * generate command for inbound/outbound.  It's here so we can * make it link-type specific.  'dir' = 0 implies "inbound", * = 1 implies "outbound". */struct block *gen_inbound(dir)	int dir;{	register struct block *b0;	b0 = gen_relation(BPF_JEQ,			  gen_load(Q_LINK, gen_loadi(0), 1),			  gen_loadi(0),			  dir);	return (b0);}

⌨️ 快捷键说明

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