+
+/** \defgroup geoinfo Geographic info management given an IP address using geoinfo.c
+ * @{ */
+
+/**
+ * \brief Get latitude and longitude
+ * \param ip IP address
+ * \param coord double[2] object (NULL or not) that will contain latitude and longitude
+ * \return 1 if the coordinates were found, -1 otherwise
+ */
+
+int
+AI_geoinfobyaddr ( const char *ip, double **coord )
+{
+ int i, sd, n_read, n_matches;
+ char buf[1024] = { 0 },
+ hostip[INET_ADDRSTRLEN] = { 0 },
+ query[100] = { 0 };
+
+ char **matches = NULL;
+ FILE *fp = NULL;
+ struct hostent *host = NULL;
+ struct sockaddr_in addr;
+
+ if ( *coord == NULL )
+ {
+ if ( !( *coord = (double*) calloc ( 2, sizeof ( double ))))
+ {
+ return -1;
+ }
+ }
+
+ if (( sd = socket ( AF_INET, SOCK_STREAM, IPPROTO_IP )) < 0 )
+ {
+ return -1;
+ }
+
+ if ( !( host = gethostbyname ( "www.hostip.info" )))
+ {
+ return -1;
+ }
+
+ inet_ntop ( AF_INET, host->h_addr_list[0], hostip, sizeof ( hostip ));
+ memset ( &addr, 0, sizeof ( addr ));
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons ( 80 );
+ addr.sin_addr.s_addr = inet_addr ( hostip );
+
+ if ( connect ( sd, (struct sockaddr*) &addr, sizeof ( struct sockaddr )) < 0 )
+ {
+ return -1;
+ }
+
+ if ( !( fp = fdopen ( sd, "r+" )))
+ {
+ close ( sd );
+ return -1;
+ }
+
+ snprintf ( query, sizeof ( query ), "spip=%s&submit=Go", ip );
+ fprintf ( fp,
+ "POST /index.html HTTP/1.1\r\n"
+ "Host: www.hostip.info\r\n"
+ "Content-Length: %u\r\n"
+ "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n"
+ "Connection: close\r\n\r\n"
+ "%s\r\n",
+ strlen ( query ), query
+ );
+
+ do
+ {
+ memset ( buf, 0, sizeof ( buf ));
+ n_read = fread ( buf, sizeof ( buf ), 1, fp );
+
+ if ( preg_match ( "new GLatLng.([^,]+), ([^\\)]+)", buf, &matches, &n_matches ) > 0 )
+ {
+ (*coord)[0] = strtod ( matches[0], NULL );
+ (*coord)[1] = strtod ( matches[1], NULL );
+
+ for ( i=0; i < n_matches; i++ )
+ {
+ free ( matches[i] );
+ }
+
+ free ( matches );
+ matches = NULL;
+
+ fclose ( fp );
+ close ( sd );
+
+ if ( (*coord)[0] == 0.0 && (*coord)[1] == 0.0 )
+ {
+ return -1;
+ } else {
+ return 1;
+ }
+ }
+
+ for ( i=0; i < n_matches; i++ )
+ {
+ free ( matches[i] );
+ }
+
+ free ( matches );
+ matches = NULL;
+ } while ( n_read > 0 );
+
+ fclose ( fp );
+ close ( sd );
+ return -1;
+} /* ----- end of function AI_geoinfobyaddr ----- */
+
+/** @} */
+
diff --git a/htdocs/index.html b/htdocs/index.html
index 2840347..e16b498 100644
--- a/htdocs/index.html
+++ b/htdocs/index.html
@@ -375,7 +375,17 @@ window.onload = function() {
}
content += '' +
- json_element.from + ' | ' + json_element.to + ' | ' +
+ json_element.from;
+
+ if ( parseFloat(json_element.latitude) != 0.0 ||
+ parseFloat(json_element.longitude) != 0.0 )
+ {
+ content += ' (locate)';
+ }
+
+ content += '' + json_element.to + ' | ' +
'' + json_element.date + ' | ';
if ( json_element.clusteredAlerts )
@@ -433,7 +443,18 @@ window.onload = function() {
}
content += '' +
- '' + json_element.clusteredAlerts[j].from + ' | ' +
+ '' + json_element.clusteredAlerts[j].from;
+
+ if ( parseFloat(json_element.clusteredAlerts[j].latitude) != 0.0 ||
+ parseFloat(json_element.clusteredAlerts[j].longitude) != 0.0 )
+ {
+ content += ' (locate)';
+ }
+
+ content += ' | ' +
'' + json_element.clusteredAlerts[j].to + ' | ' +
'' + json_element.clusteredAlerts[j].date + ' | ';
}
diff --git a/spp_ai.h b/spp_ai.h
index f0cbe24..ffdc47e 100644
--- a/spp_ai.h
+++ b/spp_ai.h
@@ -28,6 +28,7 @@
#include "sf_dynamic_preprocessor.h"
#include "uthash.h"
+#include
#include
#define PRIVATE static
@@ -420,6 +421,10 @@ typedef struct _AI_snort_alert {
* and post-conditions*/
AI_hyperalert_info *hyperalert;
+ /** Latitude and longitude of the attacker IP,
+ * if available */
+ double geocoord[2];
+
/* Parent alerts in the chain, if any */
struct _AI_snort_alert **parent_alerts;
@@ -509,6 +514,13 @@ typedef struct {
UT_hash_handle hh;
} AI_alerts_per_neuron;
/*****************************************************************/
+/** Hash table holding analyzed geographical IP info */
+typedef struct {
+ char ip[INET_ADDRSTRLEN];
+ double geocoord[2];
+ UT_hash_handle hh;
+} AI_geoip_cache;
+/*****************************************************************/
/** Enumeration for describing the table in the output database */
@@ -567,6 +579,7 @@ double AI_alert_bayesian_correlation ( const AI_snort_alert*, co
double AI_alert_neural_som_correlation ( const AI_snort_alert*, const AI_snort_alert* );
double AI_neural_correlation_weight ();
double AI_bayesian_correlation_weight ();
+int AI_geoinfobyaddr ( const char*, double** );
void AI_outdb_mutex_initialize ();
void AI_store_alert_to_db ( AI_snort_alert* );