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

📄 dump.c

📁 Firestorm NIDS是一个性能非常高的网络入侵检测系统 (NIDS)。目前
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <string.h>#include <ctype.h>#include <firestorm.h>#include <packet.h>#include <args.h>#include <cleanup.h>#include <alert.h>#include <signature.h>#include <decode.h>#include <target.h>#include <plugin.h>#include <capture.h>#include <config.h>#ifdef HAVE_SYS_UIO_H#include <sys/uio.h>#endifPLUGIN_STD_DEFS();#define MAGIC_LBL 0xa1b2c3d4/* Imported functions */proc_args_parse args_parse;proc_decode_proto decode_proto;/* pcap protocol */struct proto *pcap_dlt=NULL;/* If we don't have libpcap */#ifndef lib_pcap_h#define pcap_file_header	tcpd_file_header#define pcap_pkthdr		tcpd_pkthdr#define PCAP_VERSION_MAJOR	2#define PCAP_VERSION_MINOR	4struct tcpd_file_header{	unsigned int	magic;	unsigned short	version_major;	unsigned short	version_minor;	int		thiszone;	unsigned int	sigfigs;	unsigned int	snaplen;	unsigned int	linktype;};struct tcpd_pkthdr {	struct timeval	ts;	unsigned int	caplen;	unsigned int	len;};#endifstruct dump_priv {	struct proto 	*proto;	unsigned int	hdr;	int		fd;	char		*fn;	unsigned int	id;};/* Arguments */int cb_proto(struct arg *, void *);int cb_file(struct arg *, void *);struct arg dump_args[]={	{"proto", ARGTYPE_STRING, cb_proto},	{"file", ARGTYPE_STRING, cb_file},	{NULL,ARGTYPE_NOP,NULL}};/* Target information */int dump_a(struct generator *, struct packet *, struct alert*, void *);int dump_v(char *, void **);void dump_h(void *);void dump_c(void *);struct target alert_t[]={	target_init("dump", dump_a, dump_v, dump_h, dump_c),	target_null()};struct proto_child *find_proto(struct packet *pkt){	struct proto_child *c;	unsigned int i;	/* Find the first layer in the packet which	 * contains a protocol usable by libpcap */	for(i=0; i<pkt->llen; i++) {		for(c=pcap_dlt->children; c; c=c->next) {			if ( pkt->layer[i].proto==c->proto ) {				return c;			}		}	}	return NULL;}int cb_proto(struct arg *a, void *priv){	struct proto_child *c;	struct dump_priv *p=priv;	if ( !p || !a->val.v_str ) return 0;	if ( p->proto ) {		mesg(M_ERR,"dump: You already specified a protocol!");		return 0;	}	/* Lookup a valid pcap protocol by name */	for(c=pcap_dlt->children; c; c=c->next) {		if ( !strcmp(a->val.v_str, c->proto->name) ) {			p->proto=c->proto;			p->id=c->id;			return 1;		}	}		mesg(M_ERR,"dump: couldn't find libpcap protocol for '%s'",		a->val.v_str);	return 0;}int dump_openfile(struct dump_priv *p){	if ( (p->fd=open(p->fn, O_RDWR|O_CREAT, 00640))<0 ) {		mesg(M_ERR,"dump: %s: open(): %s", p->fn, get_err());		return 0;	}	return 1;}int cb_file(struct arg *a, void *priv){	struct dump_priv *p=priv;	if ( !p ) return 0;	if ( p->fd>=0 ) {		mesg(M_ERR,"dump: You already specified a file!");		return 0;	}	if ( (p->fn=strdup(a->val.v_str))==NULL ) {		mesg(M_ERR,"ascii: strdup: %s", get_err());		return 0;	}	return 1;}/* Actually write the file header to the file */int dump_fheader(struct dump_priv *priv){	struct dump_priv *p=priv;	struct pcap_file_header fh;	fh.magic=MAGIC_LBL;	fh.version_major=PCAP_VERSION_MAJOR;	fh.version_minor=PCAP_VERSION_MINOR;	fh.thiszone=0;	fh.sigfigs=0;	fh.snaplen=65535;	fh.linktype=p->id;	if (write(p->fd, &fh, sizeof(fh)) < sizeof(fh)) {		mesg(M_CRIT,"dump: write(): %s", get_err());		return 2;	}	return 1;}/* FIXME: This could be structured much better */int dump_a(struct generator *gen,	struct packet *pkt, 	struct alert *a,	void *priv){	struct dump_priv *p=priv;	struct proto_child *c;	struct pcap_pkthdr ph;	unsigned int ofs;	unsigned int layer;	struct iovec iov[2];	if ( !pkt ) return 0;	if ( p->proto && p->hdr==1 ) goto fast_path;	/* The file is most likely corrupt by this point */	if ( p->hdr==2 ) {		mesg(M_CRIT,"dump: warning: alert not recorded, "			"previous I/O errors.");		return 0;	}		/* Try find a protocol in order to write the	 * pcap header */	if ( !p->proto ) {		if ( (c=find_proto(pkt)) ) {			p->proto=c->proto;			p->id=c->id;			mesg(M_INFO,"dump: dumping in '%s' format (%u)", 				p->proto->name, p->id);		}else{			mesg(M_CRIT,"dump: warning: alert not recorded, "				"no suitable protocol.");				return 1;		}	}	/* If we haven't already written our header	 * then do so */	if ( !p->hdr ) {		if ( (p->hdr=dump_fheader(p))==2 ) return 0;	}fast_path:	/* Find where to start dumping from */	for(layer=0; layer<pkt->llen; layer++) {		if ( pkt->layer[layer].proto == p->proto ) {			goto dump_packet;		}	}	mesg(M_CRIT,"dump: warning: alert not recorded, "		"no suitable protocol.");	return 1;dump_packet:	/* Figure out how far in to the packet	 * our first byte of data is */	ofs=(unsigned int)(pkt->layer[layer].h.raw-pkt->base);		/* Fill in the packet header */	ph.caplen=pkt->caplen-ofs;	ph.len=pkt->len-ofs;	ph.ts.tv_sec=pkt->time.tv_sec;	ph.ts.tv_usec=pkt->time.tv_usec;	/* Fill in the vectors */	iov[0].iov_base=&ph;	iov[0].iov_len=sizeof(ph);	iov[1].iov_base=pkt->base+ofs;	iov[1].iov_len=ph.caplen;	/* We can write two vectors at once, w00t! */	if ( writev(p->fd, iov, 2) < 		(iov[0].iov_len+iov[1].iov_len) ) {		mesg(M_CRIT,"dump: writev(): %s", get_err());		p->hdr=2;		return 0;	}	return 1;}/* Check file header and decide what to do */int dump_cheader(struct dump_priv *priv){	struct dump_priv *p=priv;	struct pcap_file_header fh;	struct proto_child *c=NULL;	int read_result;	read_result=read(p->fd, &fh, sizeof(fh));	if ( read_result == -1) {		mesg(M_ERR,"dump: read(): %s", get_err());		goto err;	}	/* This case has to be before the next,	 * else empty files become invalid */	if ( read_result == 0 ) return 1;		/* Check the header */	if ( ( read_result < sizeof(fh) ) || ( fh.magic != MAGIC_LBL) ) {		mesg(M_ERR,"dump: bad voodoo magic!");		goto err;	}	/* Magic was valid, check proto id */	for(c=pcap_dlt->children; c; c=c->next) {		if ( fh.linktype==c->id ) {			p->proto=c->proto;			p->id=c->id;			p->hdr=1;			mesg(M_INFO,"dump: Logging in '%s' format", p->proto->name);			if ( lseek(p->fd, 0, SEEK_END)<0 ) {				mesg(M_ERR,"dump: lseek(): %s", get_err());				goto err;			}			return 1;		}	}		mesg(M_ERR,"dump: existing file has unknown "		"protocol (%u) - wimping out",		fh.linktype);err:	close(p->fd);	free(p);	return 0;}int dump_v(char *args, void **ptr){	struct dump_priv *p=NULL;		if ( !args ) return 0;		if ( !(p=calloc(1, sizeof(*p))) ) {		return 0;	}	p->fd=-1;	switch ( args_parse(dump_args, args, p) ) {	case -1:		mesg(M_ERR,"dump: parse error: %s", args);	case 0: /* fall through */		if ( p->fd>=0 ) close(p->fd);		free(p);		return 0;	default:		break;	}	if (!dump_openfile(p)) {		free(p);		return 0;	}	*ptr=p;	return dump_cheader(p);}void dump_h(void *priv){	struct dump_priv *p=priv;	if ( !p ) return;		if ( fsync(p->fd) )		mesg(M_CRIT,"dump: fsync(): %s", get_err());	if ( close(p->fd) )		mesg(M_CRIT,"dump: close(): %s", get_err());	if ( !dump_openfile(p) ) {		mesg(M_CRIT,"dump: error reopening logfile");		return;	}	p->hdr=0;}void dump_c(void *priv){	struct dump_priv *p=priv;	if ( !p ) return;	/* We wan't to warn the user if the whole file	 * didn't get written right for whatever reason */	if ( fsync(p->fd) )		mesg(M_CRIT,"dump: fsync(): %s", get_err());	if ( close(p->fd) )		mesg(M_CRIT,"dump: close(): %s -- "			"stop using NFS you muppet", get_err());	free(p);}int PLUGIN_TARGET (struct target_api *t){	object_check(t);	args_parse=t->args_parse;	if ( !(pcap_dlt=decode_proto("__pcap_dlt")) )		return PLUGIN_ERR_FAIL;	if ( !t->target_add(alert_t) )		return PLUGIN_ERR_FAIL;	return PLUGIN_ERR_OK;}	int PLUGIN_INIT (struct plugin_in *in, struct plugin_out *out){	plugin_check(in, out);		PLUGIN_ID("target.dump", "Log to a tcpdump file");	PLUGIN_VERSION(1,0);	PLUGIN_AUTHOR("Gianni Tedesco", "gianni@scaramanga.co.uk");	PLUGIN_LICENSE("GPL");		if ( !(decode_proto=in->import("decode.proto")) ) {		return PLUGIN_ERR_OBJECT;	}	return PLUGIN_ERR_OK;}int PLUGIN_UNLOAD (int code) {	return PLUGIN_ERR_OK;}

⌨️ 快捷键说明

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