/usr/share/bro/base/utils/site.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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | ##! Definitions describing a site - which networks and DNS zones are "local"
##! and "neighbors", and servers running particular services.
@load ./patterns
module Site;
export {
## Address space that is considered private and unrouted.
## By default it has RFC defined non-routable IPv4 address space.
const private_address_space: set[subnet] = {
10.0.0.0/8,
192.168.0.0/16,
172.16.0.0/12,
100.64.0.0/10, # RFC6598 Carrier Grade NAT
127.0.0.0/8,
[fe80::]/10,
[::1]/128,
} &redef;
## Networks that are considered "local". Note that BroControl sets
## this automatically.
const local_nets: set[subnet] &redef;
## This is used for retrieving the subnet when using multiple entries in
## :bro:id:`Site::local_nets`. It's populated automatically from there.
## A membership query can be done with an
## :bro:type:`addr` and the table will yield the subnet it was found
## within.
global local_nets_table: table[subnet] of subnet = {};
## Networks that are considered "neighbors".
const neighbor_nets: set[subnet] &redef;
## If local network administrators are known and they have responsibility
## for defined address space, then a mapping can be defined here between
## networks for which they have responsibility and a set of email
## addresses.
const local_admins: table[subnet] of set[string] = {} &redef;
## DNS zones that are considered "local".
const local_zones: set[string] &redef;
## DNS zones that are considered "neighbors".
const neighbor_zones: set[string] &redef;
## Function that returns true if an address corresponds to one of
## the local networks, false if not.
## The function inspects :bro:id:`Site::local_nets`.
global is_local_addr: function(a: addr): bool;
## Function that returns true if an address corresponds to one of
## the neighbor networks, false if not.
## The function inspects :bro:id:`Site::neighbor_nets`.
global is_neighbor_addr: function(a: addr): bool;
## Function that returns true if an address corresponds to one of
## the private/unrouted networks, false if not.
## The function inspects :bro:id:`Site::private_address_space`.
global is_private_addr: function(a: addr): bool;
## Function that returns true if a host name is within a local
## DNS zone.
## The function inspects :bro:id:`Site::local_zones`.
global is_local_name: function(name: string): bool;
## Function that returns true if a host name is within a neighbor
## DNS zone.
## The function inspects :bro:id:`Site::neighbor_zones`.
global is_neighbor_name: function(name: string): bool;
## Function that returns a comma-separated list of email addresses
## that are considered administrators for the IP address provided as
## an argument.
## The function inspects :bro:id:`Site::local_admins`.
global get_emails: function(a: addr): string;
}
# Please ignore, this is an interally used variable.
global local_dns_suffix_regex: pattern = /MATCH_NOTHING/;
global local_dns_neighbor_suffix_regex: pattern = /MATCH_NOTHING/;
function is_local_addr(a: addr): bool
{
return a in local_nets;
}
function is_neighbor_addr(a: addr): bool
{
return a in neighbor_nets;
}
function is_private_addr(a: addr): bool
{
return a in private_address_space;
}
function is_local_name(name: string): bool
{
return local_dns_suffix_regex in name;
}
function is_neighbor_name(name: string): bool
{
return local_dns_neighbor_suffix_regex in name;
}
# This is a hack for doing a for loop.
const one_to_32: vector of count = {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};
# TODO: make this work with IPv6
function find_all_emails(ip: addr): set[string]
{
if ( ip !in local_admins ) return set();
local output_values: set[string] = set();
local tmp_subnet: subnet;
local i: count;
local emails: string;
for ( i in one_to_32 )
{
tmp_subnet = mask_addr(ip, one_to_32[i]);
for ( email in local_admins[tmp_subnet] )
{
for ( email in local_admins[tmp_subnet] )
{
if ( email != "" )
add output_values[email];
}
}
}
return output_values;
}
function fmt_email_string(emails: set[string]): string
{
local output="";
for( email in emails )
{
if ( output == "" )
output = email;
else
output = fmt("%s, %s", output, email);
}
return output;
}
function get_emails(a: addr): string
{
return fmt_email_string(find_all_emails(a));
}
event bro_init() &priority=10
{
# Double backslashes are needed due to string parsing.
local_dns_suffix_regex = set_to_regex(local_zones, "(^\\.?|\\.)(~~)$");
local_dns_neighbor_suffix_regex = set_to_regex(neighbor_zones, "(^\\.?|\\.)(~~)$");
# Create the local_nets mapping table.
for ( cidr in Site::local_nets )
local_nets_table[cidr] = cidr;
}
|