29 #include <arpa/inet.h>
49 #ifdef WITH_PLUGIN_SIXT
53 #include "corsaro_geodb.h"
73 #define CORSARO_GEODB_MAGIC 0x474F4442
76 #define PLUGIN_NAME "geodb"
79 #define MAXMIND_NAME \
80 (corsaro_geo_get_provider_name(CORSARO_GEO_PROVIDER_MAXMIND))
83 #define NETACQ_EDGE_NAME \
84 (corsaro_geo_get_provider_name(CORSARO_GEO_PROVIDER_NETACQ_EDGE))
87 #define DEFAULT_PROVIDER_NAME MAXMIND_NAME
90 #define BUFFER_LEN 1024
118 #define MAXMIND_HEADER_ROW_CNT 2
187 #define NETACQ_EDGE_HEADER_ROW_CNT 1
190 #define LOCATIONS_FILE_NAME "GeoLiteCity-Location.csv.gz"
193 #define BLOCKS_FILE_NAME "GeoLiteCity-Blocks.csv.gz"
196 kh_int_hash_func, kh_int_hash_equal)
203 #ifdef WITH_PLUGIN_SIXT
204 CORSARO_PLUGIN_GENERATE_PTRS_FT(corsaro_geodb),
212 struct corsaro_geodb_state_t {
217 char *locations_file;
221 struct csv_parser parser;
231 khash_t(u16u16) *country_continent;
235 #define STATE(corsaro) \
236 (CORSARO_PLUGIN_STATE(corsaro, geodb, CORSARO_PLUGIN_ID_GEODB))
239 #define PLUGIN(corsaro) \
240 (CORSARO_PLUGIN_PLUGIN(corsaro, CORSARO_PLUGIN_ID_GEODB))
246 "plugin usage: %s [-p format] (-l locations -b blocks)|(-d directory)\n"
247 " -d directory containing blocks and location files\n"
248 " -b blocks file (must be used with -l)\n"
249 " -l locations file (must be used with -b)\n"
250 " -p database format (default: %s)\n"
251 " format must be one of:\n"
266 struct corsaro_geodb_state_t *state =
STATE(corsaro);
268 char *directory = NULL;
271 assert(plugin->
argc > 0 && plugin->
argv != NULL);
273 if(plugin->
argc == 1)
282 while((opt = getopt(plugin->
argc, plugin->
argv,
"b:d:l:p:?")) >= 0)
291 state->blocks_file = strdup(optarg);
299 state->locations_file = strdup(optarg);
314 fprintf(stderr,
"ERROR: invalid database format (%s)\n",
329 if(directory != NULL)
332 if(state->locations_file != NULL || state->blocks_file != NULL)
334 fprintf(stderr,
"WARNING: both directory and file name specified.\n");
337 if(state->locations_file != NULL)
339 free(state->locations_file);
340 state->locations_file = NULL;
343 if(state->blocks_file != NULL)
345 free(state->blocks_file);
346 state->blocks_file = NULL;
351 if(directory[strlen(directory)-1] ==
'/')
353 directory[strlen(directory)-1] =
'\0';
357 if((state->locations_file = malloc(
363 "could not malloc location file string");
367 if((state->blocks_file = malloc(
373 "could not malloc blocks file string");
379 ptr = stpncpy(state->locations_file, directory, strlen(directory));
384 ptr = stpncpy(state->blocks_file, directory, strlen(directory));
390 if(state->locations_file == NULL || state->blocks_file == NULL)
392 fprintf(stderr,
"ERROR: %s requires either '-d' or both '-b' and '-l'\n",
398 if(state->provider_id == 0)
407 static void parse_maxmind_location_cell(
void *s,
size_t i,
void *data)
410 struct corsaro_geodb_state_t *state =
STATE(corsaro);
412 char *tok = (
char*)s;
429 switch(state->current_column)
433 tmp->
id = strtol(tok, &end, 10);
434 if (end == tok || *end !=
'\0' || errno == ERANGE)
436 corsaro_log(__func__, corsaro,
"Invalid ID Value (%s)", tok);
437 state->parser.status = CSV_EUSER;
444 if(tok == NULL || strlen(tok) != 2)
446 corsaro_log(__func__, corsaro,
"Invalid Country Code (%s)", tok);
447 state->parser.status = CSV_EUSER;
450 state->cntry_code = (tok[0]<<8) | tok[1];
456 if(tok == NULL || strlen(tok) == 0)
463 memcpy(tmp->
region, tok, 2);
469 tmp->
city = strndup(tok, strlen(tok));
474 tmp->
post_code = strndup(tok, strlen(tok));
480 if (end == tok || *end !=
'\0' || errno == ERANGE)
482 corsaro_log(__func__, corsaro,
"Invalid Latitude Value (%s)", tok);
483 state->parser.status = CSV_EUSER;
491 if (end == tok || *end !=
'\0' || errno == ERANGE)
493 corsaro_log(__func__, corsaro,
"Invalid Longitude Value (%s)", tok);
494 state->parser.status = CSV_EUSER;
504 if (end == tok || *end !=
'\0' || errno == ERANGE)
506 corsaro_log(__func__, corsaro,
"Invalid Metro Value (%s)", tok);
507 state->parser.status = CSV_EUSER;
518 if (end == tok || *end !=
'\0' || errno == ERANGE)
521 "Invalid Area Code Value (%s)", tok);
522 state->parser.status = CSV_EUSER;
529 corsaro_log(__func__, corsaro,
"Invalid Maxmind Location Column (%d:%d)",
530 state->current_line, state->current_column);
531 state->parser.status = CSV_EUSER;
537 state->current_column++;
544 struct corsaro_geodb_state_t *state =
STATE(corsaro);
552 state->current_line++;
561 "ERROR: Expecting %d columns in the locations file, "
562 "but actually got %d",
564 state->parser.status = CSV_EUSER;
569 if((khiter = kh_get(u16u16, state->country_continent, state->cntry_code)) ==
570 kh_end(state->country_continent))
572 corsaro_log(__func__, corsaro,
"ERROR: Invalid country code (%s) (%x)",
573 state->tmp_record.country_code,
575 state->parser.status = CSV_EUSER;
579 state->tmp_record.continent_code =
580 kh_value(state->country_continent, khiter);
588 state->tmp_record.id)) == NULL)
590 corsaro_log(__func__, corsaro,
"ERROR: Could not initialize geo record");
591 state->parser.status = CSV_EUSER;
600 state->current_line++;
602 state->current_column = 0;
606 state->cntry_code = 0;
615 struct corsaro_geodb_state_t *state =
STATE(corsaro);
617 char *tok = (
char*)s;
634 switch(state->current_column)
638 tmp->
id = strtol(tok, &end, 10);
639 if (end == tok || *end !=
'\0' || errno == ERANGE)
641 corsaro_log(__func__, corsaro,
"Invalid ID Value (%s)", tok);
642 state->parser.status = CSV_EUSER;
654 tmp->
city = strndup(tok, strlen(tok));
670 if (end == tok || *end !=
'\0' || errno == ERANGE)
672 corsaro_log(__func__, corsaro,
"Invalid Metro Value (%s)", tok);
673 state->parser.status = CSV_EUSER;
681 if (end == tok || *end !=
'\0' || errno == ERANGE)
683 corsaro_log(__func__, corsaro,
"Invalid Latitude Value (%s)", tok);
684 state->parser.status = CSV_EUSER;
692 if (end == tok || *end !=
'\0' || errno == ERANGE)
694 corsaro_log(__func__, corsaro,
"Invalid Longitude Value (%s)", tok);
695 state->parser.status = CSV_EUSER;
701 tmp->
post_code = strndup(tok, strlen(tok));
713 if (end == tok || *end !=
'\0' || errno == ERANGE)
716 "Invalid Continent Code Value (%s)", tok);
717 state->parser.status = CSV_EUSER;
724 if(tok == NULL || strlen(tok) != 2)
726 corsaro_log(__func__, corsaro,
"Invalid Country Code (%s)", tok);
728 "Invalid Net Acuity Edge Location Column (%d:%d)",
729 state->current_line, state->current_column);
730 state->parser.status = CSV_EUSER;
749 "Invalid Net Acuity Edge Location Column (%d:%d)",
750 state->current_line, state->current_column);
751 state->parser.status = CSV_EUSER;
757 state->current_column++;
766 struct corsaro_geodb_state_t *state =
STATE(corsaro);
772 state->current_line++;
781 "ERROR: Expecting %d columns in the locations file, "
782 "but actually got %d",
784 state->parser.status = CSV_EUSER;
789 state->tmp_record.id)) == NULL)
791 corsaro_log(__func__, corsaro,
"ERROR: Could not initialize geo record");
792 state->parser.status = CSV_EUSER;
801 state->current_line++;
803 state->current_column = 0;
807 state->cntry_code = 0;
815 struct corsaro_geodb_state_t *state =
STATE(corsaro);
820 void (*cell_callback)(
void *s,
size_t i,
void *data);
821 void (*row_callback)(
int c,
void *data);
822 const char *provider_name;
823 switch(
STATE(corsaro)->provider_id)
826 cell_callback = parse_maxmind_location_cell;
838 corsaro_log(__func__, corsaro,
"Invalid provider type");
843 state->current_column = 0;
844 state->current_line = 0;
846 state->cntry_code = 0;
849 int options = CSV_STRICT | CSV_REPALL_NL | CSV_STRICT_FINI |
850 CSV_APPEND_NULL | CSV_EMPTY_IS_NULL;
852 csv_init(&(state->parser), options);
856 if(csv_parse(&(state->parser), buffer, read,
862 "Error parsing %s Location file", provider_name);
865 csv_strerror(csv_error(&(state->parser))));
870 if(csv_fini(&(state->parser),
876 "Error parsing %s Location file", provider_name);
879 csv_strerror(csv_error(&(state->parser))));
883 csv_free(&(state->parser));
892 struct corsaro_geodb_state_t *state =
STATE(corsaro);
893 char *tok = (
char*)s;
897 switch(
STATE(corsaro)->provider_id)
908 corsaro_log(__func__, corsaro,
"Invalid provider type");
909 state->parser.status = CSV_EUSER;
913 if(state->current_line < skip)
918 switch(state->current_column)
922 state->block_lower.addr = strtol(tok, &end, 10);
923 if (end == tok || *end !=
'\0' || errno == ERANGE)
925 corsaro_log(__func__, corsaro,
"Invalid Start IP Value (%s)", tok);
926 state->parser.status = CSV_EUSER;
932 state->block_upper.addr = strtol(tok, &end, 10);
933 if (end == tok || *end !=
'\0' || errno == ERANGE)
935 corsaro_log(__func__, corsaro,
"Invalid End IP Value (%s)", tok);
936 state->parser.status = CSV_EUSER;
942 state->block_id = strtol(tok, &end, 10);
943 if (end == tok || *end !=
'\0' || errno == ERANGE)
945 corsaro_log(__func__, corsaro,
"Invalid ID Value (%s)", tok);
946 state->parser.status = CSV_EUSER;
951 corsaro_log(__func__, corsaro,
"Invalid Blocks Column (%d:%d)",
952 state->current_line, state->current_column);
953 state->parser.status = CSV_EUSER;
958 state->current_column++;
961 static void parse_blocks_row(
int c,
void *data)
964 struct corsaro_geodb_state_t *state =
STATE(corsaro);
972 switch(
STATE(corsaro)->provider_id)
983 corsaro_log(__func__, corsaro,
"Invalid provider type");
984 state->parser.status = CSV_EUSER;
987 if(state->current_line < skip)
989 state->current_line++;
999 "ERROR: Expecting %d columns in the blocks file, "
1000 "but actually got %d",
1002 state->parser.status = CSV_EUSER;
1006 assert(state->block_id > 0);
1009 if(ip_range_to_prefix(state->block_lower,
1014 "ERROR: Could not convert range to pfxs");
1015 state->parser.status = CSV_EUSER;
1018 assert(pfx_list != NULL);
1022 state->block_id)) == NULL)
1025 "ERROR: Missing record for location %d",
1027 state->parser.status = CSV_EUSER;
1032 while(pfx_list != NULL)
1041 "ERROR: Failed to associate record");
1042 state->parser.status = CSV_EUSER;
1049 pfx_list = pfx_list->
next;
1055 state->current_line++;
1057 state->current_column = 0;
1063 struct corsaro_geodb_state_t *state =
STATE(corsaro);
1068 state->current_column = 0;
1069 state->current_line = 0;
1070 state->block_id = 0;
1071 state->block_lower.masklen = 32;
1072 state->block_upper.masklen = 32;
1075 int options = CSV_STRICT | CSV_REPALL_NL | CSV_STRICT_FINI |
1076 CSV_APPEND_NULL | CSV_EMPTY_IS_NULL;
1078 csv_init(&(state->parser), options);
1083 if(csv_parse(&(state->parser), buffer, read,
1089 "Error parsing Blocks file");
1092 csv_strerror(csv_error(&(state->parser))));
1097 if(csv_fini(&(state->parser),
1103 "Error parsing Maxmind Location file");
1106 csv_strerror(csv_error(&(state->parser))));
1110 csv_free(&(state->parser));
1119 struct corsaro_geodb_state_t *plugin_state =
STATE(corsaro);
1128 plugin_state->provider,
1136 struct in_addr addr;
1137 addr.s_addr = src_ip;
1139 fprintf(stdout,
"src: %s\n",
1144 assert(provider != NULL);
1160 return &corsaro_geodb_plugin;
1181 struct corsaro_geodb_state_t *state;
1187 const char **countries;
1188 const char **continents;
1189 uint16_t cntry_code = 0;
1190 uint16_t cont_code = 0;
1195 assert(plugin != NULL);
1197 if((state =
malloc_zero(
sizeof(
struct corsaro_geodb_state_t))) == NULL)
1200 "could not malloc corsaro_maxmind_state_t");
1211 assert(state->locations_file != NULL && state->blocks_file != NULL
1212 && state->provider_id > 0);
1215 if((state->provider =
1221 corsaro_log(__func__, corsaro,
"could not register as a geolocation"
1227 state->country_continent = kh_init(u16u16);
1230 assert(country_cnt == continent_cnt);
1231 for(i=0; i< country_cnt; i++)
1233 cntry_code = (countries[i][0]<<8) | countries[i][1];
1234 cont_code = (continents[i][0]<<8) | continents[i][1];
1237 khiter = kh_put(u16u16, state->country_continent, cntry_code, &khret);
1238 kh_value(state->country_continent, khiter) = cont_code;
1246 "failed to open location file '%s'", state->locations_file);
1253 corsaro_log(__func__, corsaro,
"failed to parse locations file");
1264 "failed to open blocks file '%s'", state->blocks_file);
1271 corsaro_log(__func__, corsaro,
"failed to parse blocks file");
1306 struct corsaro_geodb_state_t *state =
STATE(corsaro);
1309 if(state->provider != NULL)
1312 state->provider = NULL;
1315 if(state->locations_file != NULL)
1317 free(state->locations_file);
1318 state->locations_file = NULL;
1321 if(state->blocks_file != NULL)
1323 free(state->blocks_file);
1324 state->blocks_file = NULL;
1370 libtrace_packet_t *ltpacket =
LT_PKT(packet);
1371 libtrace_ip_t *ip_hdr = NULL;
1374 if((ip_hdr = trace_get_ip(ltpacket)) == NULL)
1383 #ifdef WITH_PLUGIN_SIXT
1385 int corsaro_geodb_process_flowtuple(
corsaro_t *corsaro,
1386 corsaro_flowtuple_t *flowtuple,
1394 int corsaro_geodb_process_flowtuple_class_start(
corsaro_t *corsaro,
1395 corsaro_flowtuple_class_start_t *
class)
1402 int corsaro_geodb_process_flowtuple_class_end(
corsaro_t *corsaro,
1403 corsaro_flowtuple_class_end_t *
class)
Structure representing the start or end of an interval.
uint32_t id
A unique ID for this record (used to join the Blocks and Locations Files)
An opaque structure defining an corsaro input file.
#define DEFAULT_PROVIDER_NAME
The default provider name.
static int read_blocks(corsaro_t *corsaro, corsaro_file_in_t *file)
Read a blocks file (maxmind or netacq)
Header file dealing with the corsaro plugin manager.
char * conn_speed
Connection Speed/Type.
Default Geolocation data-structure.
static void usage(corsaro_plugin_t *plugin)
Print usage information to stderr.
Header file dealing with the corsaro logging sub-system.
Total number of columns in the locations table.
#define PLUGIN_NAME
The name of this plugin.
A reusable opaque structure for corsaro to read an input record into.
void corsaro_geo_free_provider(corsaro_t *corsaro, corsaro_geo_provider_t *provider)
Free the given geolocation provider object.
static int process_generic(corsaro_t *corsaro, corsaro_packet_state_t *state, uint32_t src_ip)
Common code between process_packet and process_flowtuple.
int corsaro_geo_get_maxmind_iso2_list(const char ***countries)
Get a list of all possible ISO-3166-1 2 character country codes that maxmind uses.
char ** argv
Array of plugin arguments This is populated by the plugin manager in corsaro_plugin_enable_plugin.
int corsaro_geodb_close_input(corsaro_in_t *corsaro)
Implements the close_input function of the plugin API.
#define LT_PKT(corsaro_packet)
Convenience macro to get to the libtrace packet inside an corsaro packet.
Geolocation data from Net Acuity Edge.
Total number of columns in locations table.
int corsaro_geodb_close_output(corsaro_t *corsaro)
Implements the close_output function of the plugin API.
enum blocks_cols blocks_cols_t
The columns in the maxmind locations CSV file.
This provider should be the default geolocation result.
void corsaro_geo_provider_add_record(corsaro_geo_provider_t *provider, corsaro_geo_record_t *record)
Add the given geolocation record to the head of the given geolocation provider object.
static void parse_maxmind_location_row(int c, void *data)
Handle an end-of-row event from the CSV parser.
Total number of columns in blocks table.
Structure which represents a geolocation provider.
static int read_locations(corsaro_t *corsaro, corsaro_file_in_t *file)
Read a locations file.
corsaro_geo_record_t * corsaro_geo_provider_lookup_record(corsaro_t *corsaro, corsaro_geo_provider_t *provider, uint32_t addr)
Look up the given address in the provider's datastructure.
char country_code[3]
2 character string which holds the ISO2 country code
Header file which exports corsaro_flowtuple plugin API.
static libtrace_packet_t * packet
A pointer to a libtrace packet.
void corsaro_plugin_free_state(corsaro_plugin_manager_t *manager, corsaro_plugin_t *plugin)
Free the state for a plugin.
void corsaro_geo_dump_record(corsaro_geo_record_t *record)
Dump the given geolocation record to stdout (for debugging)
Header file for common utility functions.
A lightweight wrapper around a libtrace packet.
corsaro_plugin_manager_t * plugin_manager
A pointer to the corsaro plugin manager state.
#define MAXMIND_HEADER_ROW_CNT
The number of header rows in the maxmind CSV files.
ip_prefix_t prefix
The prefix that this element represents.
#define CORSARO_PLUGIN_GENERATE_PTRS(plugin)
Convenience macro that defines all the function pointers for the corsaro plugin API.
An element in a linked list of IP prefixes.
int corsaro_geo_get_maxmind_country_continent_list(const char ***continents)
Get a mapping of continent codes that maxmind uses.
void corsaro_plugin_register_state(corsaro_plugin_manager_t *manager, corsaro_plugin_t *plugin, void *state)
Register the state for a plugin.
#define BLOCKS_FILE_NAME
The default file name for the blocks file.
uint8_t masklen
The length of the prefix mask.
uint32_t corsaro_flowtuple_get_source_ip(corsaro_flowtuple_t *flowtuple)
Convenience function to get the source IP address from a FlowTuple.
int corsaro_geo_provider_clear(corsaro_geo_provider_t *provider)
Remove all the existing records from the given geolocation provider.
void corsaro_file_rclose(corsaro_file_in_t *file)
Closes an corsaro input file and frees the reader structure.
corsaro_geo_record_t * corsaro_geo_next_record(corsaro_geo_provider_t *provider, corsaro_geo_record_t *record)
Retrieve the next geolocation provider record in the list.
netacq_edge_locations_cols
The columns in the netacq_edge locations CSV file.
static void parse_blocks_cell(void *s, size_t i, void *data)
Parse a blocks cell.
#define CORSARO_PLUGIN_GENERATE_TAIL
Convenience macro that defines all the 'remaining' blank fields in a corsaro plugin object...
void * malloc_zero(const size_t size)
Allocate memory and set it to zero.
#define STATE(corsaro)
Extends the generic plugin state convenience macro in corsaro_plugin.h.
#define LOCATIONS_FILE_NAME
The default file name for the locations file.
static corsaro_in_record_t * record
A pointer to a corsaro record.
int argc
Count of arguments in argv.
Geolocation Database Lookup Plugin.
int corsaro_geodb_init_input(corsaro_in_t *corsaro)
Implements the init_input function of the plugin API.
double latitude
Latitude of the city.
double longitude
Longitude of the city.
corsaro_plugin_t * corsaro_geodb_alloc(corsaro_t *corsaro)
Implements the alloc function of the plugin API.
Geolocation data from Maxmind (Geo or GeoLite)
corsaro_packet_state_t state
The corsaro state associated with this packet.
blocks_cols
The columns in the maxmind locations CSV file.
corsaro_geo_record_t * corsaro_geo_get_record(corsaro_geo_provider_t *provider, uint32_t id)
Get the geolocation record for the given id.
off_t corsaro_file_rread(corsaro_file_in_t *file, void *buffer, off_t len)
Reads from an corsaro input file into the provided buffer.
KHASH_INIT(u16u16, uint16_t, uint16_t, 1, kh_int_hash_func, kh_int_hash_equal)
Common plugin information across all instances.
int corsaro_geodb_init_output(corsaro_t *corsaro)
Implements the init_output function of the plugin API.
corsaro_geo_provider_t * corsaro_geo_get_default(corsaro_t *corsaro)
Retrieve the provider object for the default geolocation provider.
#define MAXMIND_NAME
The name of the maxmind provider.
int corsaro_geodb_probe_filename(const char *fname)
Implements the probe_filename function of the plugin API.
corsaro_geo_provider_t * corsaro_geo_init_provider(corsaro_t *corsaro, corsaro_geo_provider_id_t provider_id, corsaro_geo_datastructure_id_t ds_id, corsaro_geo_provider_default_t set_default)
Allocate a geolocation provider object in the packet state.
char region[3]
2 character string which represents the region the city is in
uint32_t area_code
Area code.
char * post_code
String which contains the postal code.
int corsaro_geo_provider_associate_record(corsaro_t *corsaro, corsaro_geo_provider_t *provider, uint32_t addr, uint8_t mask, corsaro_geo_record_t *record)
Register a new prefix to record mapping for the given provider.
static int parse_args(corsaro_t *corsaro)
Parse the arguments given to the plugin.
Structure which contains a geolocation record.
int corsaro_geodb_start_interval(corsaro_t *corsaro, corsaro_interval_t *int_start)
Implements the start_interval function of the plugin API.
#define NETACQ_EDGE_HEADER_ROW_CNT
The number of header rows in the netacq edge CSV files.
uint32_t metro_code
Metro code.
struct ip_prefix_list * next
The next prefix in the list.
Corsaro state for a packet.
enum maxmind_locations_cols maxmind_locations_cols_t
The columns in the maxmind locations CSV file.
enum netacq_edge_locations_cols netacq_edge_locations_cols_t
The columns in the netacq_edge locations CSV file.
int continent_code
Continent Code.
int corsaro_geodb_process_packet(corsaro_t *corsaro, corsaro_packet_t *packet)
Implements the process_packet function of the plugin API.
#define BUFFER_LEN
The length of the static line buffer.
Represents a IPv4 prefix e.g.
uint32_t addr
The address component of the prefix.
corsaro_file_in_t * corsaro_file_ropen(const char *filename)
Creates a new corsaro file reader and opens the provided file for reading.
int corsaro_geodb_end_interval(corsaro_t *corsaro, corsaro_interval_t *int_end)
Implements the end_interval function of the plugin API.
void corsaro_log(const char *func, corsaro_t *corsaro, const char *format,...)
Write a formatted string to the logfile associated with an corsaro object.
off_t corsaro_geodb_read_global_data_record(corsaro_in_t *corsaro, corsaro_in_record_type_t *record_type, corsaro_in_record_t *record)
Implements the read_global_data_record function of the plugin API.
int corsaro_geodb_probe_magic(corsaro_in_t *corsaro, corsaro_file_in_t *file)
Implements the probe_magic function of the plugin API.
#define NETACQ_EDGE_NAME
The name of the netacq edge provider.
#define PLUGIN(corsaro)
Extends the generic plugin plugin convenience macro in corsaro_plugin.h.
char * city
String which contains the city name.
enum corsaro_geo_provider_id corsaro_geo_provider_id_t
A unique identifier for each geolocation provider that corsaro supports.
maxmind_locations_cols
The columns in the maxmind locations CSV file.
#define CORSARO_GEODB_MAGIC
The magic number for this plugin - "GODB".
enum corsaro_in_record_type corsaro_in_record_type_t
Corsaro input record types.
Header file dealing with the corsaro geolocation subsystem.
An corsaro packet processing plugin.
static void parse_netacq_edge_location_row(int c, void *data)
Handle an end-of-row event from the CSV parser.
off_t corsaro_geodb_read_record(struct corsaro_in *corsaro, corsaro_in_record_type_t *record_type, corsaro_in_record_t *record)
Implements the read_record function of the plugin API.
static void parse_netacq_edge_location_cell(void *s, size_t i, void *data)
Parse a netacq location cell.
corsaro_geo_record_t * corsaro_geo_init_record(corsaro_geo_provider_t *provider, uint32_t id)
Allocate an empty geolocation record for the given id.
Header file dealing with the internal corsaro functions.