# $Id: pcap.bro,v 1.1 2003/08/31 00:40:21 vern Exp $

# The set of capture_filters indexed by some user-definable ID.
global capture_filters: table[string] of string &redef;
global restrict_filters: table[string] of string &redef;

# Filter string which is unconditionally or'ed to every pcap filter.
global unrestricted_filter = "" &redef;

redef enum PcapFilterID += {
   DefaultPcapFilter,
};

function add_to_pcap_filter(fold: string, fnew: string, op: string) : string
	{
	if ( fold == "" )
		return fnew;
	else
		return fmt("(%s) %s (%s)", fold, op, fnew);
	}

function join_filters(capture_filter: string, restrict_filter: string): string
	{
	local filter: string;

	if ( capture_filter != "" && restrict_filter != "" )
		filter = fmt( "(%s) and (%s)", capture_filter, restrict_filter );
	else if ( capture_filter != "" )
		filter = capture_filter;

	else if ( restrict_filter != "" )
		filter = restrict_filter;

	else
		filter = "tcp or udp";

	if ( unrestricted_filter != "" )
		filter = fmt( "(%s) or (%s)", unrestricted_filter, filter );

	return filter;
	}

function build_default_pcap_filter() : string
	{
	# Build capture_filter.
	local cfilter = "";

	for ( id in capture_filters )
		cfilter = add_to_pcap_filter(cfilter, capture_filters[id], "or");

	# Build restrict_filter.
	local rfilter = "";
	for ( id in restrict_filters )
		rfilter = add_to_pcap_filter(rfilter, restrict_filters[id], "and");

	return join_filters(cfilter, rfilter);
	}

function install_default_pcap_filter()
	{
	if ( ! install_pcap_filter(DefaultPcapFilter) )
		 log fmt("%.6f Can't install default pcap filter (cmdline override?)", network_time());
	}


event bro_init()
	{
	local default_filter = build_default_pcap_filter();

	if ( ! precompile_pcap_filter(DefaultPcapFilter, default_filter) )
		 {
		 local msg = fmt( "%.6f Can't compile filter %s",
					network_time(), default_filter);
		 log msg;
		 print msg;
		 exit();
		 }

	install_default_pcap_filter();
	}
