00001
00002
00003 #include "config.h"
00004
00005 #include <sys/types.h>
00006 #include <sys/socket.h>
00007
00008 #include <netinet/in.h>
00009
00010 #include <arpa/inet.h>
00011
00012 #include <map>
00013
00014 #include "Active.h"
00015 #include "util.h"
00016 #include "Dict.h"
00017
00018 declare(PDict,string);
00019 typedef PDict(string) MachineMap;
00020 declare(PDict,MachineMap);
00021 typedef PDict(MachineMap) ActiveMap;
00022 declare(PDict,NumericData);
00023 typedef PDict(NumericData) ActiveMapNumeric;
00024
00025 static ActiveMap active_map;
00026 static ActiveMapNumeric active_map_numeric;
00027
00028 static MachineMap default_values;
00029 static NumericData default_values_numeric;
00030
00031 static bool map_was_loaded = false;
00032
00033 bool get_map_result(uint32 ip_addr, const char* key, string& result)
00034 {
00035 const MachineMap* machine_map;
00036 #ifndef ACTIVE_MAPPING
00037 machine_map = &default_values;
00038 #else
00039 HashKey machinekey(ip_addr);
00040 machine_map = active_map.Lookup(&machinekey);
00041
00042 if ( ! machine_map )
00043 machine_map = &default_values;
00044 #endif
00045 HashKey mapkey(key);
00046 string* entry = machine_map->Lookup(&mapkey);
00047 if ( ! entry )
00048 {
00049 entry = default_values.Lookup(&mapkey);
00050 }
00051
00052 if ( ! entry )
00053 {
00054 internal_error("Unknown active mapping entry requested: %s", key);
00055 return false;
00056 }
00057
00058 result = *entry;
00059
00060 return true;
00061 }
00062
00063 bool get_map_result(uint32 ip_addr, const NumericData*& result)
00064 {
00065 #ifndef ACTIVE_MAPPING
00066 result = &default_values_numeric;
00067 return true;
00068 #endif
00069 HashKey machinekey(&ip_addr, 1);
00070 NumericData* entry = active_map_numeric.Lookup(&machinekey);
00071
00072 if ( ! entry )
00073 result = &default_values_numeric;
00074 else
00075 result = entry;
00076
00077 return true;
00078 }
00079
00080
00081 char* chop (char* s)
00082 {
00083 s[strlen(s) - 1] = 0;
00084 return s;
00085 }
00086
00087 map < const char *, ReassemblyPolicy, ltstr > reassem_names;
00088
00089
00090 bool load_mapping_table(const char* map_file)
00091 {
00092 reassem_names["BSD"] = RP_BSD;
00093 reassem_names["linux"] = RP_LINUX;
00094 reassem_names["last"] = RP_LAST;
00095 reassem_names["first"] = RP_FIRST;
00096
00097
00098 default_values.Insert(new HashKey("accepts_rst_outside_window"),
00099 new string("no"));
00100 default_values.Insert(new HashKey("accepts_rst_in_window"),
00101 new string("yes"));
00102 default_values.Insert(new HashKey("accepts_rst_in_sequence"),
00103 new string("yes"));
00104 default_values.Insert(new HashKey("mtu"),
00105 new string("0"));
00106
00107 default_values_numeric.path_MTU = 0;
00108 default_values_numeric.hops = 0;
00109 default_values_numeric.ip_reassem = RP_UNKNOWN;
00110 default_values_numeric.tcp_reassem = RP_UNKNOWN;
00111 default_values_numeric.accepts_rst_in_window = true;
00112 default_values_numeric.accepts_rst_outside_window = false;
00113
00114
00115 if ( map_file && strlen(map_file) )
00116 {
00117 FILE* f = fopen(map_file, "r");
00118 if ( ! f )
00119 return false;
00120
00121 char buf[512];
00122 if ( ! fgets(buf, sizeof(buf), f) )
00123 error("Error reading mapping file.\n");
00124
00125 int num_fields = atoi(buf);
00126
00127 string* field_names = new string[num_fields];
00128 for ( int i = 0; i < num_fields; ++i )
00129 {
00130 if ( ! fgets(buf, sizeof(buf), f) )
00131 error("Error reading mapping file.\n");
00132 field_names[i] = chop(buf);
00133 }
00134
00135 if ( ! fgets(buf, sizeof(buf), f) )
00136 error("Error reading mapping file.\n");
00137
00138 int num_machines = atoi(buf);
00139
00140 for ( int j = 0; j < num_machines; ++j )
00141 {
00142 if ( ! fgets(buf, sizeof(buf), f) )
00143 error("Error reading mapping file.\n");
00144
00145 uint32 ip;
00146 in_addr in;
00147 if ( ! inet_aton(chop(buf), &in) )
00148 error("Error reading mapping file.\n");
00149
00150 ip = in.s_addr;
00151
00152 MachineMap* newmap;
00153 NumericData* newnumeric;
00154
00155 if ( ip )
00156 {
00157 newmap = new MachineMap;
00158 newnumeric = new NumericData;
00159 }
00160 else
00161 {
00162 newmap = &default_values;
00163 newnumeric = &default_values_numeric;
00164 }
00165
00166 for ( int i = 0; i < num_fields; ++i )
00167 {
00168 if ( ! fgets(buf, sizeof(buf), f) )
00169 error("Error reading mapping file.\n");
00170
00171 string fname = field_names[i];
00172
00173 chop(buf);
00174
00175
00176 if ( streq(buf, "") )
00177 continue;
00178
00179 HashKey mapkey(fname.c_str());
00180 newmap->Insert(&mapkey, new string(buf));
00181
00182 if ( fname == "mtu" )
00183 newnumeric->path_MTU = atoi(buf);
00184
00185 else if ( fname == "hops" )
00186 newnumeric->hops = atoi(buf);
00187
00188 else if ( fname == "tcp_segment_overlap" )
00189 newnumeric->tcp_reassem = reassem_names[buf];
00190
00191 else if ( fname == "overlap_policy" )
00192 newnumeric->ip_reassem = reassem_names[buf];
00193
00194 else if ( fname == "accepts_rst_in_window" )
00195 newnumeric->accepts_rst_in_window = streq(buf, "yes");
00196
00197 else if ( fname == "accepts_rst_outside_window" )
00198 newnumeric->accepts_rst_outside_window = streq(buf, "yes");
00199
00200 else if ( fname == "accepts_rst_in_sequence" )
00201 newnumeric->accepts_rst_in_sequence = streq(buf, "yes");
00202
00203 else
00204 warn("unrecognized mapping file tag:", fname.c_str());
00205 }
00206
00207 HashKey machinekey(&ip, 1);
00208 active_map.Insert(&machinekey, newmap);
00209 active_map_numeric.Insert(&machinekey, newnumeric);
00210 }
00211
00212 delete [] field_names;
00213 }
00214
00215 map_was_loaded = true;
00216
00217 return true;
00218 }