Removing active mapping.

This commit is contained in:
Robin Sommer 2011-03-14 18:31:17 -07:00
parent c92154994a
commit 57fe369c4e
8 changed files with 6 additions and 441 deletions

View file

@ -1,218 +0,0 @@
// $Id: Active.cc 1282 2005-09-07 17:02:02Z vern $
#include "config.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <map>
#include "Active.h"
#include "util.h"
#include "Dict.h"
declare(PDict,string);
typedef PDict(string) MachineMap;
declare(PDict,MachineMap);
typedef PDict(MachineMap) ActiveMap;
declare(PDict,NumericData);
typedef PDict(NumericData) ActiveMapNumeric;
static ActiveMap active_map;
static ActiveMapNumeric active_map_numeric;
static MachineMap default_values;
static NumericData default_values_numeric;
static bool map_was_loaded = false;
bool get_map_result(uint32 ip_addr, const char* key, string& result)
{
const MachineMap* machine_map;
#ifndef ACTIVE_MAPPING
machine_map = &default_values;
#else
HashKey machinekey(ip_addr);
machine_map = active_map.Lookup(&machinekey);
if ( ! machine_map )
machine_map = &default_values;
#endif
HashKey mapkey(key);
string* entry = machine_map->Lookup(&mapkey);
if ( ! entry )
{
entry = default_values.Lookup(&mapkey);
}
if ( ! entry )
{
internal_error("Unknown active mapping entry requested: %s", key);
return false;
}
result = *entry;
return true;
}
bool get_map_result(uint32 ip_addr, const NumericData*& result)
{
#ifndef ACTIVE_MAPPING
result = &default_values_numeric;
return true;
#endif
HashKey machinekey(&ip_addr, 1);
NumericData* entry = active_map_numeric.Lookup(&machinekey);
if ( ! entry )
result = &default_values_numeric;
else
result = entry;
return true;
}
char* chop (char* s)
{
s[strlen(s) - 1] = 0;
return s;
}
map < const char *, ReassemblyPolicy, ltstr > reassem_names;
// Remember to index the table with IP address in network order!
bool load_mapping_table(const char* map_file)
{
reassem_names["BSD"] = RP_BSD;
reassem_names["linux"] = RP_LINUX;
reassem_names["last"] = RP_LAST;
reassem_names["first"] = RP_FIRST;
// Default values are read in from AM file under IP address 0.0.0.0
default_values.Insert(new HashKey("accepts_rst_outside_window"),
new string("no"));
default_values.Insert(new HashKey("accepts_rst_in_window"),
new string("yes"));
default_values.Insert(new HashKey("accepts_rst_in_sequence"),
new string("yes"));
default_values.Insert(new HashKey("mtu"),
new string("0"));
default_values_numeric.path_MTU = 0; // 0 = unknown
default_values_numeric.hops = 0; // 0 = unknown;
default_values_numeric.ip_reassem = RP_UNKNOWN;
default_values_numeric.tcp_reassem = RP_UNKNOWN;
default_values_numeric.accepts_rst_in_window = true;
default_values_numeric.accepts_rst_outside_window = false;
if ( map_file && strlen(map_file) )
{
FILE* f = fopen(map_file, "r");
if ( ! f )
return false;
char buf[512];
if ( ! fgets(buf, sizeof(buf), f) )
error("Error reading mapping file.\n");
int num_fields = atoi(buf);
string* field_names = new string[num_fields];
for ( int i = 0; i < num_fields; ++i )
{
if ( ! fgets(buf, sizeof(buf), f) )
error("Error reading mapping file.\n");
field_names[i] = chop(buf);
}
if ( ! fgets(buf, sizeof(buf), f) )
error("Error reading mapping file.\n");
int num_machines = atoi(buf);
for ( int j = 0; j < num_machines; ++j )
{ // read ip address, parse it
if ( ! fgets(buf, sizeof(buf), f) )
error("Error reading mapping file.\n");
uint32 ip;
in_addr in;
if ( ! inet_aton(chop(buf), &in) )
error("Error reading mapping file.\n");
ip = in.s_addr;
MachineMap* newmap;
NumericData* newnumeric;
if ( ip ) // ip = 0.0.0.0 = default values
{
newmap = new MachineMap;
newnumeric = new NumericData;
}
else
{
newmap = &default_values;
newnumeric = &default_values_numeric;
}
for ( int i = 0; i < num_fields; ++i )
{
if ( ! fgets(buf, sizeof(buf), f) )
error("Error reading mapping file.\n");
string fname = field_names[i];
chop(buf);
// Don't try to parse an unknown value ("").
if ( streq(buf, "") )
continue;
HashKey mapkey(fname.c_str());
newmap->Insert(&mapkey, new string(buf));
if ( fname == "mtu" )
newnumeric->path_MTU = atoi(buf);
else if ( fname == "hops" )
newnumeric->hops = atoi(buf);
else if ( fname == "tcp_segment_overlap" )
newnumeric->tcp_reassem = reassem_names[buf];
else if ( fname == "overlap_policy" )
newnumeric->ip_reassem = reassem_names[buf];
else if ( fname == "accepts_rst_in_window" )
newnumeric->accepts_rst_in_window = streq(buf, "yes");
else if ( fname == "accepts_rst_outside_window" )
newnumeric->accepts_rst_outside_window = streq(buf, "yes");
else if ( fname == "accepts_rst_in_sequence" )
newnumeric->accepts_rst_in_sequence = streq(buf, "yes");
else
warn("unrecognized mapping file tag:", fname.c_str());
}
HashKey machinekey(&ip, 1);
active_map.Insert(&machinekey, newmap);
active_map_numeric.Insert(&machinekey, newnumeric);
}
delete [] field_names;
}
map_was_loaded = true;
return true;
}

View file

@ -1,44 +0,0 @@
// $Id: Active.h 80 2004-07-14 20:15:50Z jason $
#ifndef active_h
#define active_h
#include <string>
using namespace std;
#include "util.h"
enum ReassemblyPolicy {
RP_UNKNOWN,
RP_BSD, // Left-trim to equal or lower offset frags
RP_LINUX, // Left-trim to strictly lower offset frags
RP_FIRST, // Accept only new (no previous value) octets
RP_LAST // Accept all
};
struct NumericData {
ReassemblyPolicy ip_reassem;
ReassemblyPolicy tcp_reassem;
unsigned short path_MTU; // 0 = unknown
unsigned char hops; // 0 = unknown
bool accepts_rst_in_window;
bool accepts_rst_outside_window;
bool accepts_rst_in_sequence;
};
// Return value is whether or not there was a known result for that
// machine (actually, IP address in network order); if not, a default
// is returned. Note that the map data is a string in all cases: the
// numeric form is more efficient and is to be preferred ordinarily.
bool get_map_result(uint32 ip_addr, const char* key, string& result);
// Basically a special case of get_map_result(), but returns numbers
// directly for efficiency reasons, since these are frequently
// looked up. ### Perhaps a better generic mechanism is in order.
bool get_map_result(uint32 ip_addr, const NumericData*& result);
// Reads in AM data from the specified file (basically [IP, policy] tuples)
// Should be called at initialization time.
bool load_mapping_table(const char* map_file);
#endif

View file

@ -242,7 +242,6 @@ set(bro_SRCS
net_util.cc
util.cc
module_util.cc
Active.cc
Analyzer.cc
Anon.cc
ARP.cc

View file

@ -48,15 +48,8 @@ Reassembler::Reassembler(int init_seq, const uint32* ip_addr,
{
blocks = last_block = 0;
trim_seq = last_reassem_seq = init_seq;
const NumericData* host_profile;
get_map_result(ip_addr[0], host_profile); // breaks for IPv6
policy = (arg_type == REASSEM_TCP) ?
host_profile->tcp_reassem : host_profile->ip_reassem;
}
Reassembler::~Reassembler()
{
ClearBlocks();
@ -243,67 +236,7 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, int seq, int upper,
return new_b;
}
// The blocks overlap.
#ifdef ACTIVE_MAPPING
if ( policy != RP_UNKNOWN )
{
if ( seq_delta(seq, b->seq) < 0 )
{ // The new block has a prefix that comes before b.
int prefix_len = seq_delta(b->seq, seq);
new_b = new DataBlock(data, prefix_len, seq, b->prev, b);
if ( b == blocks )
blocks = new_b;
data += prefix_len;
seq += prefix_len;
}
if ( policy == RP_LAST ||
// After handling the prefix block, BSD takes the rest
(policy == RP_BSD && new_b) ||
// Similar, but overwrite for same seq number
(policy == RP_LINUX && (new_b || seq == b->seq)) )
{
DataBlock* bprev = b->prev;
bool b_was_first = b == blocks;
while ( b && b->upper <= upper )
{
DataBlock* next = b->next;
delete b;
b = next;
}
new_b = new DataBlock(data, upper - seq, seq, bprev, b);
if ( b_was_first )
blocks = new_b;
// Trim the next block as needed.
if ( b && seq_delta(new_b->upper, b->seq) > 0 )
{
DataBlock* next_b =
new DataBlock(&b->block[upper - b->seq],
b->upper - upper, upper,
new_b, b->next);
if ( b == last_block )
last_block = next_b;
delete b;
}
}
else
{ // handle the piece that sticks out past b
new_b = b;
int len = upper - b->upper;
if ( len > 0 )
new_b = AddAndCheck(b, b->upper, upper, &data[b->upper - seq]);
}
}
else
{
#endif
// Default behavior - complain about overlaps.
// The blocks overlap, complain.
if ( seq_delta(seq, b->seq) < 0 )
{
// The new block has a prefix that comes before b.
@ -338,10 +271,6 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, int seq, int upper,
(void) AddAndCheck(b, seq, upper, data);
}
#ifdef ACTIVE_MAPPING
} // else branch, for RP_UNKNOWN behavior
#endif
if ( new_b->prev == last_block )
last_block = new_b;
@ -365,7 +294,7 @@ bool Reassembler::DoSerialize(SerialInfo* info) const
// I'm not sure if it makes sense to actually save the buffered data.
// For now, we just remember the seq numbers so that we don't get
// complaints about missing content.
return SERIALIZE(trim_seq) && SERIALIZE(int(policy));
return SERIALIZE(trim_seq) && SERIALIZE(int(0));
}
bool Reassembler::DoUnserialize(UnserialInfo* info)
@ -374,11 +303,10 @@ bool Reassembler::DoUnserialize(UnserialInfo* info)
blocks = last_block = 0;
int p;
if ( ! UNSERIALIZE(&trim_seq) || ! UNSERIALIZE(&p) )
int dummy; // For backwards compatibility.
if ( ! UNSERIALIZE(&trim_seq) || ! UNSERIALIZE(&dummy) )
return false;
policy = ReassemblyPolicy(p);
last_reassem_seq = trim_seq;
return true;

View file

@ -5,7 +5,6 @@
#ifndef reassem_h
#define reassem_h
#include "Active.h"
#include "Obj.h"
class DataBlock {
@ -74,8 +73,6 @@ protected:
int last_reassem_seq;
int trim_seq; // how far we've trimmed
ReassemblyPolicy policy;
static unsigned int total_size;
};

View file

@ -15,7 +15,6 @@
#include "Timer.h"
#include "NetVar.h"
#include "Sessions.h"
#include "Active.h"
#include "OSFinger.h"
#include "ICMP.h"
@ -465,37 +464,9 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
return;
}
// Check for TTL/MTU problems from Active Mapping
#ifdef ACTIVE_MAPPING
const NumericData* numeric = 0;
if ( ip4 )
{
get_map_result(ip4->ip_dst.s_addr, numeric);
if ( numeric->hops && ip4->ip_ttl < numeric->hops )
{
debug_msg("Packet destined for %s had ttl %d but there are %d hops to host.\n",
inet_ntoa(ip4->ip_dst), ip4->ip_ttl, numeric->hops);
return;
}
}
#endif
FragReassembler* f = 0;
uint32 frag_field = ip_hdr->FragField();
#ifdef ACTIVE_MAPPING
if ( ip4 && numeric && numeric->path_MTU && (frag_field & IP_DF) )
{
if ( htons(ip4->ip_len) > numeric->path_MTU )
{
debug_msg("Packet destined for %s has DF flag but its size %d is greater than pmtu of %d\n",
inet_ntoa(ip4->ip_dst), htons(ip4->ip_len), numeric->path_MTU);
return;
}
}
#endif
if ( (frag_field & 0x3fff) != 0 )
{
dump_this_packet = 1; // always record fragments

View file

@ -3,7 +3,6 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "Active.h"
#include "PIA.h"
#include "File.h"
#include "TCP.h"
@ -412,49 +411,6 @@ bool TCP_Analyzer::ProcessRST(double t, TCP_Endpoint* endpoint,
else if ( endpoint->RST_cnt == 0 )
++endpoint->RST_cnt; // Remember we've seen a RST
#ifdef ACTIVE_MAPPING
// if ( peer->state == TCP_ENDPOINT_INACTIVE )
// debug_msg("rst while inactive\n"); // ### Cold-start: what to do?
// else
const NumericData* AM_policy;
get_map_result(ip->DstAddr4(), AM_policy);
if ( base_seq == endpoint->AckSeq() )
; // everyone should accept a RST in sequence
else if ( endpoint->window == 0 )
; // ### Cold Start: we don't know the window,
// so just go along for now
else
{
uint32 right_edge = endpoint->AckSeq() +
(endpoint->window << endpoint->window_scale);
if ( base_seq < right_edge )
{
if ( ! AM_policy->accepts_rst_in_window )
{
#if 0
debug_msg("Machine does not accept RST merely in window; ignoring. t=%.6f,base=%u, ackseq=%u, window=%hd \n",
network_time, base_seq, endpoint->AckSeq(), window);
#endif
return false;
}
}
else if ( ! AM_policy->accepts_rst_outside_window )
{
#if 0
debug_msg("Machine does not accept RST outside window; ignoring. t=%.6f,base=%u, ackseq=%u, window=%hd \n",
network_time, base_seq, endpoint->AckSeq(), window);
#endif
return false;
}
}
#endif
if ( len > 0 )
{
// This now happens often enough that it's

View file

@ -23,7 +23,6 @@ extern "C" void OPENSSL_add_all_algorithms_conf(void);
#include "bsd-getopt-long.h"
#include "input.h"
#include "Active.h"
#include "ScriptAnaly.h"
#include "DNS_Mgr.h"
#include "Frame.h"
@ -136,9 +135,6 @@ void usage()
fprintf(stderr, "bro version %s\n", bro_version());
fprintf(stderr, "usage: %s [options] [file ...]\n", prog);
fprintf(stderr, " <file> | policy file, or read stdin\n");
#ifdef ACTIVE_MAPPING
fprintf(stderr, " -a|--active-mapping <mapfile> | use active mapping results\n");
#endif
fprintf(stderr, " -d|--debug-policy | activate policy file debugging\n");
fprintf(stderr, " -e|--exec <bro code> | augment loaded policies by given code\n");
fprintf(stderr, " -f|--filter <filter> | tcpdump filter\n");
@ -393,9 +389,6 @@ int main(int argc, char** argv)
{"print-id", required_argument, 0, 'I'},
{"status-file", required_argument, 0, 'U'},
#ifdef ACTIVE_MAPPING
{"active-mapping", no_argument, 0, 'a'},
#endif
#ifdef DEBUG
{"debug", required_argument, 0, 'B'},
#endif
@ -441,7 +434,7 @@ int main(int argc, char** argv)
opterr = 0;
char opts[256];
safe_strncpy(opts, "A:a:B:D:e:f:I:i:K:n:p:R:r:s:T:t:U:w:x:X:y:Y:z:CFGHLOPSWdghlv",
safe_strncpy(opts, "A:B:D:e:f:I:i:K:n:p:R:r:s:T:t:U:w:x:X:y:Y:z:CFGHLOPSWdghlv",
sizeof(opts));
#ifdef USE_PERFTOOLS
@ -451,16 +444,6 @@ int main(int argc, char** argv)
int op;
while ( (op = getopt_long(argc, argv, opts, long_opts, &long_optsind)) != EOF )
switch ( op ) {
case 'a':
#ifdef ACTIVE_MAPPING
fprintf(stderr, "Using active mapping file %s.\n", optarg);
active_file = optarg;
#else
fprintf(stderr, "Bro not compiled for active mapping.\n");
exit(1);
#endif
break;
case 'd':
fprintf(stderr, "Policy file debugging ON.\n");
g_policy_debug = true;
@ -709,13 +692,6 @@ int main(int argc, char** argv)
add_input_file(argv[optind++]);
}
if ( ! load_mapping_table(active_file.c_str()) )
{
fprintf(stderr, "Could not load active mapping file %s\n",
active_file.c_str());
exit(1);
}
dns_mgr = new DNS_Mgr(dns_type);
// It would nice if this were configurable. This is similar to the