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

📄 alert.c

📁 Firestorm NIDS是一个性能非常高的网络入侵检测系统 (NIDS)。目前
💻 C
字号:
/** This file is part of Firestorm NIDS* Copyright (c) 2002 Gianni Tedesco* This program is released under the terms of the GNU GPL version 2** This code handles alerts, it mainly just calls functions in* elog_write.c.** Functions:*  o alert_cleanup() - final log rotation*  o alert_hup() - rotate log on demand*  o alert_init() - register cleanup handler*  o cb_dir() - set log spool directory path*  o cb_stormwall() - set stormwall mode*  o alert_conf_hook() - do the args_parse()*  o alert_conf_go() - print messages call spool_open()*  o alert_ratelimit() - token bucket filter*  o alert_do_ratelimit() - wrapper to do the correct ratelimit*  o alert() - exported API, do an alert*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <signal.h>#include <sys/stat.h>#include <fcntl.h>#include <netinet/in.h>#include <sys/uio.h>#include <firestorm.h>#include <packet.h>#include <elog.h>#include <elog_write.h>#include <alert.h>#include <signature.h>#include <decode.h>#include <cleanup.h>#include <sensor.h>#include <args.h>#include <capture.h>#include <target.h>/* Output file descriptor */struct elog_spool *spool=NULL;void alert_cleanup(int code, void *priv){	mesg(M_INFO,"alert: flushing logfiles");	spool_delete(spool);}/* By sending a SIGHUP firestorm can cause * a log rotation at any time */void alert_hup(void){	if ( !spool_isempty(spool) )		spool_rotate(spool, 1);}void alert_init(void){	if ( !(spool=spool_new()) )		cleanup(EXIT_ERR, "alert: spool_new(): %s",			get_err());	cleanup_add(alert_cleanup, NULL);}int cb_dir(struct arg *a, void *priv){	struct elog_spool *s=priv;	static char sw[]=".stormwall";	int l;	if ( !s )		return 0;	if ( !a->val.v_str )		return 0;	if ( *a->val.v_str==0 )		return 0;	if ( s->rotate_fn )		return 0;	l=strlen(a->val.v_str);	/* We add a slash unconditionally */	if ( a->val.v_str[l-1]=='/' ) {		a->val.v_str[l-1]=0;		l-=1;	}	/* Allocate for the log dir */	if ( !(s->log_dir=malloc(l + ALERT_FNLEN + 2)) ) {		return 0;	}	s->rotate_fn=s->log_dir + l + 1;	sprintf(s->log_dir, "%s/", a->val.v_str);	/* Allocate enough space for the whole filename */	if ( !(s->alert_fn=malloc(l + strlen(ALERT_FN) + 2)) ) {		free(s->log_dir);		return 0;	}	/* Figure out stormwall fifo filename */	if ( !(s->fifo_fn=malloc(l+sizeof(sw)+2)) ) {		free(s->alert_fn);		free(s->log_dir);		return 0;	}	/* Generate the filenames */	sprintf(s->alert_fn, "%s/%s", a->val.v_str, ALERT_FN);	sprintf(s->fifo_fn, "%s/%s", a->val.v_str, sw);	return 1;}int cb_stormwall(struct arg *a, void *priv){	struct elog_spool *s=priv;	if ( !s )		return 0;	if ( !strcmp("none", a->val.v_str) ) {		s->stormwall=STORMWALL_NONE;	}else if ( !strcmp("wait", a->val.v_str) ) {		s->stormwall=STORMWALL_WAIT;	}else if ( !strcmp("fail", a->val.v_str) ) {		s->stormwall=STORMWALL_FAIL;	}else{		mesg(M_ERR, "output: stormwall can be one of 'none',"			"'wait' or 'fail'");		return 0;	}	return 1;}/* Config file hook for setting up output mechanisms */void alert_conf_hook(char *args){	struct arg the_args[]={		{"dir", ARGTYPE_STRING, cb_dir},		{"stormwall", ARGTYPE_STRING, cb_stormwall},		{"size", ARGTYPE_PBYTES, NULL, {vp_bytes:&spool->max_bytes}},		{"minutes", ARGTYPE_PUINT, NULL, {vp_uint:&spool->max_time}},		{"buf", ARGTYPE_PBYTES, NULL, {vp_bytes:&spool->buf_sz}},		{NULL, ARGTYPE_NOP, NULL}	};	if ( !args )		return;	switch ( args_parse(the_args, args, spool) ) {	case -1:		mesg(M_ERR, "output: parse error: %s", args);		/* fall through */	case 0:		cleanup(EXIT_ERR,"output: failed");		return;	default:		break;	}	if ( !spool_set_buf(spool, spool->buf_sz) )		cleanup(EXIT_ERR, "output: unable to allocate buffer");	if ( !spool->alert_fn )		cleanup(EXIT_ERR, "output: no dir specified: %s", args);	if ( spool->max_bytes ) {		mesg(M_INFO,"alert: %s: max log size: %uKB",			spool->log_dir, spool->max_bytes/1024);	}	if ( spool->max_time ) {		spool->max_time*=60;		mesg(M_INFO,"alert: %s: max log age: %u hrs %u mins",			spool->log_dir,			spool->max_time/(60*60),			(spool->max_time%(60*60))/60);	}	mesg(M_INFO, "alert: %s: %sbuffered output: %uKB buffer",		spool->log_dir,		spool->buf_sz ? "" : "non-",		spool->buf_sz/1024);}/* Set everything up from configuration */void alert_conf_go(void){	if ( !spool_check_old(spool) ) {		cleanup(EXIT_ERR, "there was a problem opening the logfile");		return;	}	stormwall_open(spool);}/* Token bucket rate-limiting filter. Return values: * returns -1 if events are coming in too fast * returns zero if rate is normal * returns n>0 if rate is normal but some were dropped */static inline intalert_ratelimit(struct packet *pkt, struct tokenbucket *a){	unsigned long h;	int ret;	if ( !a->cost ) return 0;	/* Build a single time value with 0.01s resolution */	h=pkt->time.tv_sec * RATE_SEC;	h+=pkt->time.tv_usec / (1000000UL/RATE_SEC);	a->toks += h - a->last_msg;	a->last_msg=h;	if ( a->toks > a->burst )		a->toks=a->burst;	if ( a->toks >= a->cost ) {		ret=a->missed;		a->missed=0;		a->toks -= a->cost;		return ret;	}	a->missed++;	return -1;}/* return zero for OK, -1 to suppress */static inline intalert_do_ratelimit(struct generator *gen,			struct packet *pkt,			struct alert *a){	int missed;	struct tokenbucket *tb;	char *s1, *s2;	/* Alert specific tocken buckets take	 * precedence over generator-wide ones */	if ( a->t.cost ) {		tb=&a->t;		s1="alert";		s2=a->alert;	}else{		if ( !(tb=gen->t) )			return 0;		s1="generator";		s2=gen->name;	}	switch ( (missed=alert_ratelimit(pkt,tb)) ) {	case -1:		return -1;	case 0:		return 0;	default:		mesg(M_DEBUG, "alert: [%s] %s: %i alerts suppressed",			s1, s2, missed);		return 0;	}}/* This is where alerts come to after rate-limiting */void alert(struct generator *gen, struct packet *pkt, struct alert *a){	struct event_alert ev={.gen=gen, .pkt=pkt, .a=a};	if ( !pkt )		return;	/* Alerts can be supressed */	if ( alert_do_ratelimit(gen, pkt, a)<0 )		return;	/* write the packet */	spool_packet(spool, &ev);}

⌨️ 快捷键说明

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