# $Id: alert.bro,v 1.11 2003/07/13 19:24:17 vern Exp $

type Alert: enum {
	Unspecified,	# place-holder - shouldn't be used
};

type alert_info: record {
	alert: Alert;
	msg: string;
	sub: string &optional;	# sub-message

	conn: connection &optional;	# connection associated with alert
	id: conn_id &optional;	# connection-ID, if we don't have a connection handy
	src: addr &optional;	# source address, if we don't have a connection
	source_is_responder: bool &optional;	# if missing or F, alert source is orig.
};

type AlertAction: enum {
	# Similar to WeirdAction in weird.bro.
	ALERT_IGNORE, ALERT_FILE,
	ALERT_LOG_ALWAYS, ALERT_LOG_PER_CONN,
	ALERT_LOG_PER_ORIG, ALERT_LOG_ONCE,
};

# table that maps alerts into a function that should be called
# to determine the action.
global alert_action_filters:
	table[Alert] of function(a: alert_info): AlertAction &redef;

function ignore_alert(a: alert_info): AlertAction
	{
	return ALERT_IGNORE;
	}

global alert_file = open_log_file("alert") &redef;

# This handler is useful for processing alerts after the alert filters
# have been applied and yielded an AlertAction.
#
# It's tempting to make the default handler do the logging and
# printing to alert_file, rather than ALERT.  I hesitate to do that,
# though, because it perhaps could slow down notification, because
# in the absence of event priorities, the event would have to wait
# behind any other already-queued events.
event alert_action(a: alert_info, action: AlertAction)
	{
	}

function ALERT(a: alert_info)
	{
	local action = ALERT_LOG_ALWAYS;

	if ( a$alert in alert_action_filters )
		action = alert_action_filters[a$alert](a);

	if ( action != ALERT_IGNORE )
		log fmt("%s %s", a$alert, a$msg);

	print alert_file, fmt("%.6f %s %s", network_time(), a$alert, a$msg);

	event alert_action(a, action);
	}

# function alert(a: alert_info)
# 	{
# 	local id = a?$id ? a$id : a$conn$id;
# 	local addl = a?$conn ? fmt(" (%s)", a$conn$addl) : "";
# 	local source = (a?$source_is_responder && a$source_is_responder) ?
# 			id$resp_h : id$orig_h;
# 	local msg = a?$sub ? fmt("%s %s", a$message, a$sub) : a$message;
# 
# 	local log_msg = fmt("%s alert: %s (%s)%s", a$analyzer, msg, id_string(id), addl);
# 
# 	log log_msg;
# 	}
