This file is indexed.

/usr/share/bro/policy/misc/capture-loss.bro is in bro-common 2.5-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
##! This script logs evidence regarding the degree to which the packet
##! capture process suffers from measurement loss.  
##! The loss could be due to overload on the host or NIC performing 
##! the packet capture or it could even be beyond the host.  If you are 
##! capturing from a switch with a SPAN port, it's very possible that 
##! the switch itself could be overloaded and dropping packets.
##! Reported loss is computed in terms of the number of "gap events" (ACKs 
##! for a sequence number that's above a gap).

@load base/frameworks/notice

module CaptureLoss;

export {
	redef enum Log::ID += { LOG };
	
	redef enum Notice::Type += {
		## Report if the detected capture loss exceeds the percentage
		## threshold.
		Too_Much_Loss
	};
	
	type Info: record {
		## Timestamp for when the measurement occurred.
		ts:           time     &log;
		## The time delay between this measurement and the last.
		ts_delta:     interval &log;
		## In the event that there are multiple Bro instances logging
		## to the same host, this distinguishes each peer with its
		## individual name.
		peer:         string   &log;
		## Number of missed ACKs from the previous measurement interval.
		gaps:         count    &log;
		## Total number of ACKs seen in the previous measurement interval.
		acks:         count    &log;
		## Percentage of ACKs seen where the data being ACKed wasn't seen.
		percent_lost: double   &log;
	};
	
	## The interval at which capture loss reports are created.
	const watch_interval = 15mins &redef;
	
	## The percentage of missed data that is considered "too much" 
	## when the :bro:enum:`CaptureLoss::Too_Much_Loss` notice should be
	## generated. The value is expressed as a double between 0 and 1 with 1
	## being 100%.
	const too_much_loss: double = 0.1 &redef;
}

event CaptureLoss::take_measurement(last_ts: time, last_acks: count, last_gaps: count)
	{
	if ( last_ts == 0 )
		{
		schedule watch_interval { CaptureLoss::take_measurement(network_time(), 0, 0) };
		return;
		}
	
	local now = network_time();
	local g = get_gap_stats();
	local acks = g$ack_events - last_acks;
	local gaps = g$gap_events - last_gaps;
	local pct_lost = (acks == 0) ? 0.0 : (100 * (1.0 * gaps) / (1.0 * acks));
	local info: Info = [$ts=now,
	                    $ts_delta=now-last_ts,
	                    $peer=peer_description,
	                    $acks=acks, $gaps=gaps, 
	                    $percent_lost=pct_lost];
	
	if ( pct_lost >= too_much_loss*100 )
		NOTICE([$note=Too_Much_Loss, 
		        $msg=fmt("The capture loss script detected an estimated loss rate above %.3f%%", pct_lost)]);
	
	Log::write(LOG, info);
	schedule watch_interval { CaptureLoss::take_measurement(now, g$ack_events, g$gap_events) };
	}

event bro_init() &priority=5
	{
	Log::create_stream(LOG, [$columns=Info, $path="capture_loss"]);

	# We only schedule the event if we are capturing packets.
	if ( reading_live_traffic() || reading_traces() )
		schedule watch_interval { CaptureLoss::take_measurement(network_time(), 0, 0) };
	}