progress
This commit is contained in:
parent
87eb2c34d9
commit
80504583a4
338
src/main.c
338
src/main.c
@ -32,13 +32,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
#define TOP_X 20 // definiert die Anzahl der Einträge, die in den Top-Listen angezeigt werden sollen
|
||||
#define SUSPICIOUS_REQUEST_LEN_THRESHOLD 256
|
||||
|
||||
// definiert Variablen für den Filtermodus. FILTER_INCLUDE=0, FILTER_EXCLUDE=1. Verbessert die Lesbarkeit des Codes.
|
||||
// TODO entfernen?
|
||||
typedef enum {
|
||||
FILTER_INCLUDE,
|
||||
FILTER_EXCLUDE
|
||||
} filter_mode_t;
|
||||
|
||||
// struct für die Darstellung von Timestamps. Die granulare Trennung in verschiedene int-Werte macht die spätere Verarbeitung modular anpassbar/erweiterbar und erleichtert die Verarbeitung.
|
||||
struct simple_time {
|
||||
int day;
|
||||
@ -68,47 +61,47 @@ struct log_entry {
|
||||
// Struktur für einen Status-Filtereintrag mit Inhalt & Modus
|
||||
struct status_filter {
|
||||
int code;
|
||||
filter_mode_t mode;
|
||||
int filter_exclude_flag;
|
||||
};
|
||||
|
||||
struct method_filter {
|
||||
char pattern[10];
|
||||
filter_mode_t mode;
|
||||
int filter_exclude_flag;
|
||||
};
|
||||
|
||||
// für IP-Adressen
|
||||
struct ip_filter {
|
||||
char ip_address[50];
|
||||
filter_mode_t mode;
|
||||
int filter_exclude_flag;
|
||||
};
|
||||
|
||||
// für Zeit, Start- und Endzeit
|
||||
struct time_filter {
|
||||
struct simple_time start_time;
|
||||
struct simple_time end_time;
|
||||
filter_mode_t mode;
|
||||
int filter_exclude_flag;
|
||||
};
|
||||
|
||||
// Filter für User-Agent
|
||||
struct user_agent_filter {
|
||||
char pattern[256];
|
||||
filter_mode_t mode;
|
||||
int filter_exclude_flag;
|
||||
};
|
||||
|
||||
// Filter für URL-Pfad/Request
|
||||
struct url_filter {
|
||||
char pattern[MAX_REQUEST_LENGTH];
|
||||
filter_mode_t mode;
|
||||
int filter_exclude_flag;
|
||||
};
|
||||
|
||||
struct annotation_flag_filter {
|
||||
int annotation_flag_is_present;
|
||||
filter_mode_t mode;
|
||||
int filter_exclude_flag;
|
||||
};
|
||||
|
||||
struct annotation_filter {
|
||||
char pattern[64];
|
||||
filter_mode_t mode;
|
||||
int filter_exclude_flag;
|
||||
};
|
||||
|
||||
// Struktur zum erhalten aller Filtereinträge, kann im Dialogbetrieb bearbeitet werden. Mit Zähler.
|
||||
@ -140,12 +133,20 @@ struct filter_system {
|
||||
int combination_mode; // 0=AND-Filter oder 1=OR-Filter
|
||||
};
|
||||
|
||||
// Definition einer Datenstruktur für die IP-Adressen Topliste
|
||||
struct ip_stat {
|
||||
char ip_address[50];
|
||||
int count;
|
||||
};
|
||||
|
||||
// Initialisierung eines Arrays für die Logeinträge und weiterer Startvariablen
|
||||
struct log_entry *all_entries = NULL;
|
||||
int max_entries = 0;
|
||||
int total_entries = 0;
|
||||
int suspicious_patterns_count = 0;
|
||||
struct filter_system filters = {0};
|
||||
// für -v option
|
||||
int flag_verbose = 0;
|
||||
|
||||
// Hilfsfunktion für die Erkennung von Leerzeichen
|
||||
int is_space(char c) {
|
||||
@ -246,7 +247,7 @@ void cleanup_memory(){
|
||||
|
||||
// sauberes Schließen und bereinigen bei Fehlerstatus, sofern Speicher nicht alloziert werden kann
|
||||
void cleanup_and_exit(){
|
||||
printf("Programmende. Speicher wird freigegeben und mit NULL überschrieben.\n");
|
||||
if (flag_verbose) printf("DEBUG: Programmende. Speicher wird freigegeben und mit NULL überschrieben.\n");
|
||||
cleanup_memory();
|
||||
exit(1);
|
||||
}
|
||||
@ -258,7 +259,7 @@ void mem_expand_dynamically(){
|
||||
int old_max = max_entries;
|
||||
max_entries = max_entries * GROWTH_FACTOR;
|
||||
|
||||
printf("DEBUG: Dynamische Speichererweiterung von %d auf %d Einträge um Faktor %f\n", old_max, max_entries, GROWTH_FACTOR);
|
||||
if (flag_verbose) printf("DEBUG: Dynamische Speichererweiterung von %d auf %d Einträge um Faktor %f\n", old_max, max_entries, GROWTH_FACTOR);
|
||||
|
||||
struct log_entry *new_ptr = realloc(all_entries, max_entries * sizeof(struct log_entry));
|
||||
|
||||
@ -269,7 +270,7 @@ void mem_expand_dynamically(){
|
||||
}
|
||||
|
||||
all_entries = new_ptr;
|
||||
printf("DEBUG: Speicher erfolgreich erweitert auf %lu Bytes\n", (unsigned long)(max_entries * sizeof(struct log_entry)));
|
||||
if (flag_verbose) printf("DEBUG: Speicher erfolgreich erweitert auf %lu Bytes\n", (unsigned long)(max_entries * sizeof(struct log_entry)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -283,7 +284,7 @@ void allocate_initial_memory(){
|
||||
exit(1); // cleanup_and_exit() nicht nötig, da der Speicherbereich nicht beschrieben wurde - use-after-free unproblematisch
|
||||
}
|
||||
|
||||
printf("DEBUG: Speicher erfolgreich alloziert für %d Log-Einträge (%lu Bytes)\n", max_entries, (unsigned long)(max_entries * sizeof(struct log_entry)));
|
||||
if (flag_verbose) printf("DEBUG: Speicher erfolgreich alloziert für %d Log-Einträge (%lu Bytes)\n", max_entries, (unsigned long)(max_entries * sizeof(struct log_entry)));
|
||||
}
|
||||
|
||||
void get_current_timestamp(char* buffer, int buffer_size) {
|
||||
@ -311,24 +312,30 @@ int is_directory(char* path) {
|
||||
|
||||
// Hilfsfunktion zum prüfen, ob es sich um eine plausible nginx-Logdatei handelt (Metrik: Dateiname - BESSER: Regex oder Magic Bytes?)
|
||||
int is_log_file(char* filename) {
|
||||
char* log_pos = strstr(filename, ".log"); // Sucht und findet den Pointer auf die Startposition des Suchstrings
|
||||
if (log_pos == NULL) return 0;
|
||||
|
||||
char* after_log = log_pos + 4;
|
||||
|
||||
if (*after_log == '\0') return 1; // true, wenn die Datei mit .log endet
|
||||
|
||||
if (*after_log == '.') {
|
||||
after_log++;
|
||||
if (*after_log == '\0') return 0; // false, wenn die Datei mit einem Punkt nach .log endet
|
||||
|
||||
while (*after_log != '\0') {
|
||||
if (*after_log < '0' || *after_log > '9') return 0; // wenn was anderes als Zahlen nach dem . kommen, gib False zurück
|
||||
after_log++;
|
||||
}
|
||||
return 1; // true, wenn nach .log. noch Zahlen vorhanden sind, wie typisch bei NGINX-Logrotation
|
||||
// versteckte Dateien sowie . oder .. überspringen
|
||||
if (filename[0] == '.') {
|
||||
return 0;
|
||||
}
|
||||
return 0; // false, wenn nichts zutrifft
|
||||
|
||||
// Mögliche Bestandteile von NGINX-Logfile-Dateinamen
|
||||
char* log_patterns[] = {
|
||||
".log",
|
||||
"access",
|
||||
"error",
|
||||
"combined",
|
||||
"redirect",
|
||||
NULL
|
||||
};
|
||||
|
||||
// Vergleich der vorhandenen Dateinamen mit den Suchmustern
|
||||
for (int i = 0; log_patterns[i] != NULL; i++) {
|
||||
if (strstr(filename, log_patterns[i]) != NULL) {
|
||||
if ((strstr(filename, "error")!= NULL)||(strstr(filename, ".gz")!= NULL)) continue;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Funktion zum suchen eines Suchbegriffs innerhalb eines Strings (lowercase)
|
||||
@ -374,12 +381,25 @@ int search_in_string(char* raw_string, char* search_string) {
|
||||
|
||||
|
||||
// Fügt eine Annotation zu einem bestimmten Eintrag hinzu
|
||||
// https://stackoverflow.com/questions/5901181/c-string-append
|
||||
void annotate_entry(int index, char* annotation_string) {
|
||||
if (index >= 0 && index < total_entries) {
|
||||
strncpy(all_entries[index].annotation, annotation_string, sizeof(all_entries[index].annotation) - 1);
|
||||
all_entries[index].annotation[sizeof(all_entries[index].annotation) - 1] = '\0';
|
||||
all_entries[index].annotated_flag = 1;
|
||||
//printf("DEBUG: Annotation zu Eintrag %d: %s\n", index, annotation_string);
|
||||
if (all_entries[index].annotation== NULL){
|
||||
strncpy(all_entries[index].annotation, annotation_string, sizeof(all_entries[index].annotation) - 1);
|
||||
all_entries[index].annotation[sizeof(all_entries[index].annotation) - 1] = '\0';
|
||||
all_entries[index].annotated_flag = 1;
|
||||
} else {
|
||||
char * new_str ;
|
||||
if((new_str = malloc(strlen(all_entries[index].annotation)+strlen(",")+strlen(annotation_string)+1)) != NULL){
|
||||
new_str[0] = '\0'; // ensures the memory is an empty string
|
||||
strcat(new_str,",");
|
||||
strcat(new_str,annotation_string);
|
||||
strncpy(all_entries[index].annotation, new_str, sizeof(all_entries[index].annotation) - 1);
|
||||
all_entries[index].annotation[sizeof(all_entries[index].annotation) - 1] = '\0';
|
||||
free(new_str);
|
||||
new_str=NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,7 +407,7 @@ void annotate_entry(int index, char* annotation_string) {
|
||||
|
||||
// TRANSPARENZ: Diese Funktion ist KI-generiert
|
||||
void annotate_suspicious_entries(struct log_entry* dataset) {
|
||||
printf("DEBUG: Prüfe %d Einträge auf verdächtige Muster...\n", total_entries);
|
||||
if (flag_verbose) printf("DEBUG: Prüfe %d Einträge auf verdächtige Muster...\n", total_entries);
|
||||
|
||||
for (int i = 0; i < total_entries; i++) {
|
||||
// Initialisierung der Annotation falls noch nicht gesetzt
|
||||
@ -616,7 +636,7 @@ void annotate_suspicious_entries(struct log_entry* dataset) {
|
||||
}
|
||||
}
|
||||
|
||||
printf("DEBUG: Analyse abgeschlossen. %d verdächtige Muster erkannt.\n", suspicious_patterns_count);
|
||||
if (flag_verbose) printf("DEBUG: Analyse abgeschlossen. %d verdächtige Muster erkannt.\n", suspicious_patterns_count);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -921,8 +941,8 @@ void load_log_file(char* path) {
|
||||
char full_path[512];
|
||||
|
||||
if (is_directory(path)) {
|
||||
printf("DEBUG: Verzeichnis erkannt: %s\n", path);
|
||||
printf("DEBUG: Suche nach .log Dateien...\n");
|
||||
if (flag_verbose) printf("DEBUG: Verzeichnis erkannt: %s\n", path);
|
||||
if (flag_verbose) printf("DEBUG: Suche nach .log Dateien...\n");
|
||||
|
||||
DIR* dir = opendir(path);
|
||||
if (dir == NULL) {
|
||||
@ -962,7 +982,7 @@ void load_log_file(char* path) {
|
||||
printf("INFO: Insgesamt %d .log Dateien verarbeitet.\n", files_found);
|
||||
}
|
||||
} else {
|
||||
printf("DEBUG: Einzelne Datei erkannt: %s\n", path);
|
||||
if (flag_verbose) printf("DEBUG: Einzelne Datei erkannt: %s\n", path);
|
||||
if (strstr(path, ".gz") != NULL) {
|
||||
load_gz_file(path);
|
||||
} else {
|
||||
@ -972,9 +992,8 @@ void load_log_file(char* path) {
|
||||
|
||||
printf("INFO: Erfolgreich %d Einträge insgesamt geladen.\n", total_entries);
|
||||
// die aufgerufene Funktion ist KI-generiert und annotiert verdächtige Requests automatisch.
|
||||
// TODO
|
||||
annotate_suspicious_entries(all_entries);
|
||||
printf("DEBUG: Aktueller Speicherverbrauch: %lu Bytes für %d Einträge\n",
|
||||
if (flag_verbose) printf("DEBUG: Aktueller Speicherverbrauch: %lu Bytes für %d Einträge\n",
|
||||
(unsigned long)(max_entries * sizeof(struct log_entry)), max_entries);
|
||||
}
|
||||
|
||||
@ -983,7 +1002,7 @@ int user_agent_matches(char* user_agent) {
|
||||
if (filters.user_agent_count == 0) return 1;
|
||||
// Ausschluss-Filter geht vor
|
||||
for (int i = 0; i < filters.user_agent_count; i++) {
|
||||
if (filters.user_agent_filters[i].mode == FILTER_EXCLUDE) {
|
||||
if (filters.user_agent_filters[i].filter_exclude_flag == 1) {
|
||||
int pattern_found = search_in_string(user_agent, filters.user_agent_filters[i].pattern);
|
||||
if (pattern_found) {
|
||||
return 0; // früheres Verlassen der Schleife, sobald Ausschlussfilter zutrifft
|
||||
@ -995,7 +1014,7 @@ int user_agent_matches(char* user_agent) {
|
||||
int include_matches = 0;
|
||||
|
||||
for (int i = 0; i < filters.user_agent_count; i++) {
|
||||
if (filters.user_agent_filters[i].mode == FILTER_INCLUDE) {
|
||||
if (filters.user_agent_filters[i].filter_exclude_flag == 0) {
|
||||
include_count++;
|
||||
int pattern_found = search_in_string(user_agent, filters.user_agent_filters[i].pattern);
|
||||
if (pattern_found) {
|
||||
@ -1024,7 +1043,7 @@ int url_matches(char* url_path) {
|
||||
if (filters.url_count == 0) return 1;
|
||||
// Ausschluss-Filter geht vor
|
||||
for (int i = 0; i < filters.url_count; i++) {
|
||||
if (filters.url_filters[i].mode == FILTER_EXCLUDE) {
|
||||
if (filters.url_filters[i].filter_exclude_flag == 1) {
|
||||
int pattern_found = search_in_string(url_path, filters.url_filters[i].pattern);
|
||||
if (pattern_found) {
|
||||
return 0; // früheres Verlassen der Schleife, sobald Ausschlussfilter zutrifft
|
||||
@ -1036,7 +1055,7 @@ int url_matches(char* url_path) {
|
||||
int include_matches = 0;
|
||||
|
||||
for (int i = 0; i < filters.url_count; i++) {
|
||||
if (filters.url_filters[i].mode == FILTER_INCLUDE) {
|
||||
if (filters.url_filters[i].filter_exclude_flag == 0) {
|
||||
include_count++;
|
||||
int pattern_found = search_in_string(url_path, filters.url_filters[i].pattern);
|
||||
if (pattern_found) {
|
||||
@ -1065,7 +1084,7 @@ int method_matches(char* request_method) {
|
||||
if (filters.method_count == 0) return 1;
|
||||
// Ausschluss-Filter geht vor
|
||||
for (int i = 0; i < filters.method_count; i++) {
|
||||
if (filters.method_filters[i].mode == FILTER_EXCLUDE) {
|
||||
if (filters.method_filters[i].filter_exclude_flag == 1) {
|
||||
int pattern_found = search_in_string(request_method, filters.method_filters[i].pattern);
|
||||
if (pattern_found) {
|
||||
return 0; // früheres Verlassen der Schleife, sobald Ausschlussfilter zutrifft
|
||||
@ -1077,7 +1096,7 @@ int method_matches(char* request_method) {
|
||||
int include_matches = 0;
|
||||
|
||||
for (int i = 0; i < filters.method_count; i++) {
|
||||
if (filters.method_filters[i].mode == FILTER_INCLUDE) {
|
||||
if (filters.method_filters[i].filter_exclude_flag == 0) {
|
||||
include_count++;
|
||||
int pattern_found = search_in_string(request_method, filters.method_filters[i].pattern);
|
||||
if (pattern_found) {
|
||||
@ -1105,7 +1124,7 @@ int status_code_matches(int status_code) {
|
||||
if (filters.status_count == 0) return 1;
|
||||
// Ausschluss-Filter prüfen: immer übergeordnet gültig
|
||||
for (int i = 0; i < filters.status_count; i++) {
|
||||
if (filters.status_filters[i].mode == FILTER_EXCLUDE) {
|
||||
if (filters.status_filters[i].filter_exclude_flag == 1) {
|
||||
if (filters.status_filters[i].code == status_code) {
|
||||
return 0;
|
||||
}
|
||||
@ -1117,7 +1136,7 @@ int status_code_matches(int status_code) {
|
||||
int include_matches = 0;
|
||||
|
||||
for (int i = 0; i < filters.status_count; i++) {
|
||||
if (filters.status_filters[i].mode == FILTER_INCLUDE) {
|
||||
if (filters.status_filters[i].filter_exclude_flag == 0) {
|
||||
include_count++;
|
||||
if (filters.status_filters[i].code == status_code) {
|
||||
include_matches++;
|
||||
@ -1144,7 +1163,7 @@ int ip_address_matches(char* ip_address) {
|
||||
|
||||
// Prüfen der Ausschlussfilter, sind dem Rest vorgelagert
|
||||
for (int i = 0; i < filters.ip_count; i++) {
|
||||
if (filters.ip_filters[i].mode == FILTER_EXCLUDE) {
|
||||
if (filters.ip_filters[i].filter_exclude_flag == 1) {
|
||||
if (strcmp(filters.ip_filters[i].ip_address, ip_address) == 0) {
|
||||
return 0; // zutreffender Ausschlussfilter führt zu negativem Rückgabewert
|
||||
}
|
||||
@ -1156,7 +1175,7 @@ int ip_address_matches(char* ip_address) {
|
||||
int include_matches = 0;
|
||||
|
||||
for (int i = 0; i < filters.ip_count; i++) {
|
||||
if (filters.ip_filters[i].mode == FILTER_INCLUDE) {
|
||||
if (filters.ip_filters[i].filter_exclude_flag == 0) {
|
||||
include_count++;
|
||||
if (strcmp(filters.ip_filters[i].ip_address, ip_address) == 0) {
|
||||
include_matches++;
|
||||
@ -1179,14 +1198,14 @@ int ip_address_matches(char* ip_address) {
|
||||
}
|
||||
|
||||
int is_annotated(int annotated_flag){
|
||||
if (filters.annotation_flag_filter.mode == FILTER_EXCLUDE && filters.annotation_flag_filter_enabled == 1 && annotated_flag == 1) {
|
||||
if (filters.annotation_flag_filter.filter_exclude_flag == 1 && filters.annotation_flag_filter_enabled == 1 && annotated_flag == 1) {
|
||||
return 0; // zutreffender Ausschlussfilter führt zu negativem Rückgabewert
|
||||
}
|
||||
else if (filters.annotation_flag_filter.mode == FILTER_INCLUDE && filters.annotation_flag_filter_enabled == 1 && annotated_flag == 1) {
|
||||
else if (filters.annotation_flag_filter.filter_exclude_flag == 0 && filters.annotation_flag_filter_enabled == 1 && annotated_flag == 1) {
|
||||
return 1; // zutreffender Einschlussfilter führt zu positivem Rückgabewert
|
||||
}
|
||||
// nichtannotiert, aber inklusiver Filter aktiv -> Eintrag nicht anzeigen
|
||||
else if (annotated_flag == 0 && filters.annotation_flag_filter.mode == FILTER_INCLUDE && filters.annotation_flag_filter_enabled == 1){
|
||||
else if (annotated_flag == 0 && filters.annotation_flag_filter.filter_exclude_flag == 0 && filters.annotation_flag_filter_enabled == 1){
|
||||
return 0;
|
||||
}
|
||||
// Filter nicht aktiv, positiver Rückgabewert
|
||||
@ -1198,7 +1217,7 @@ int annotation_matches(char* annotation) {
|
||||
if (filters.annotation_count == 0) return 1;
|
||||
// Ausschluss-Filter geht vor
|
||||
for (int i = 0; i < filters.annotation_count; i++) {
|
||||
if (filters.annotation_filters[i].mode == FILTER_EXCLUDE) {
|
||||
if (filters.annotation_filters[i].filter_exclude_flag == 1) {
|
||||
int pattern_found = search_in_string(annotation, filters.annotation_filters[i].pattern);
|
||||
if (pattern_found) {
|
||||
return 0; // früheres Verlassen der Schleife, sobald Ausschlussfilter zutrifft
|
||||
@ -1210,7 +1229,7 @@ int annotation_matches(char* annotation) {
|
||||
int include_matches = 0;
|
||||
|
||||
for (int i = 0; i < filters.annotation_count; i++) {
|
||||
if (filters.annotation_filters[i].mode == FILTER_INCLUDE) {
|
||||
if (filters.annotation_filters[i].filter_exclude_flag == 0) {
|
||||
include_count++;
|
||||
int pattern_found = search_in_string(annotation, filters.annotation_filters[i].pattern);
|
||||
if (pattern_found) {
|
||||
@ -1240,7 +1259,7 @@ int time_matches(struct simple_time entry_time) {
|
||||
|
||||
// Übergeordneter Ausschlussfilter
|
||||
for (int i = 0; i < filters.time_count; i++) {
|
||||
if (filters.time_filters[i].mode == FILTER_EXCLUDE) {
|
||||
if (filters.time_filters[i].filter_exclude_flag == 1) {
|
||||
int in_range = (compare_times(entry_time, filters.time_filters[i].start_time) >= 0 &&
|
||||
compare_times(entry_time, filters.time_filters[i].end_time) <= 0);
|
||||
if (in_range) {
|
||||
@ -1253,7 +1272,7 @@ int time_matches(struct simple_time entry_time) {
|
||||
int include_count = 0;
|
||||
int include_matches = 0;
|
||||
for (int i = 0; i < filters.time_count; i++) {
|
||||
if (filters.time_filters[i].mode == FILTER_INCLUDE) {
|
||||
if (filters.time_filters[i].filter_exclude_flag == 0) {
|
||||
include_count++;
|
||||
int in_range = (compare_times(entry_time, filters.time_filters[i].start_time) >= 0 &&
|
||||
compare_times(entry_time, filters.time_filters[i].end_time) <= 0);
|
||||
@ -1387,7 +1406,7 @@ void export_filtered_entries(char *filepath) {
|
||||
}
|
||||
|
||||
// CSV-Kopfzeile für Timesketch-Kompatibilität
|
||||
fprintf(file, "datetime,timestamp_desc,ip_address,method,url_path,status_code,bytes_sent,user_agent,source_file,parsing_timestamp,annotation\n");
|
||||
fprintf(file, "datetime,message,timestamp_desc,ip_address,method,url_path,status_code,bytes_sent,user_agent,parsing_timestamp,tag\n");
|
||||
|
||||
int exported_count = 0;
|
||||
char iso_datetime[32];
|
||||
@ -1396,20 +1415,44 @@ void export_filtered_entries(char *filepath) {
|
||||
if (passes_filter(i)) {
|
||||
format_iso8601_time(all_entries[i].time, iso_datetime, sizeof(iso_datetime));
|
||||
|
||||
// https://stackoverflow.com/questions/5901181/c-string-append
|
||||
// https://www.quora.com/How-can-we-count-the-number-of-special-characters-in-a-string-in-the-C-language-using-fgets
|
||||
char* tag_str;
|
||||
int num_delimiters = 0;
|
||||
int c=0;
|
||||
while(all_entries[i].annotation[c]!='\0'){
|
||||
num_delimiters++;
|
||||
}
|
||||
if (tag_str=malloc(sizeof(all_entries[i].annotation)+sizeof("[ ]")+(sizeof(','))*num_delimiters)+1)!=NULL){
|
||||
tag_str[0] = '\0';
|
||||
|
||||
fprintf(file, "\"%s\",\"HTTP Access Log\",\"%s\",\"%s\",\"%s\",%d,%d,\"%s\",\"%s\",\"%s\"\n",
|
||||
iso_datetime,
|
||||
|
||||
char* token = strtok(all_entries[i].annotation, ",");
|
||||
if (!token) return;
|
||||
strcat(tag_str, "[ ");
|
||||
for (i=0;i<num_delimiters;i++){
|
||||
strcat(tag_str, "\"");
|
||||
strcat(tag_str, strtok(NULL, ","));
|
||||
strcat(tag_str, '"');
|
||||
}
|
||||
strcat(tag_str, " ]");
|
||||
}
|
||||
|
||||
fprintf(file, "\"%s\",\"%s\",\"HTTP Access Log\",\"%s\",\"%s\",\"%s\",%d,%d,\"%s\",\"%s\",\"%s\"\n",
|
||||
iso_datetime, // datetime
|
||||
all_entries[i].source_file, // message
|
||||
all_entries[i].ip_address,
|
||||
all_entries[i].request_method,
|
||||
all_entries[i].url_path,
|
||||
all_entries[i].status_code,
|
||||
all_entries[i].bytes_sent,
|
||||
all_entries[i].user_agent,
|
||||
all_entries[i].source_file,
|
||||
all_entries[i].parsing_timestamp,
|
||||
all_entries[i].annotation
|
||||
tag_str
|
||||
//all_entries[i].annotation // tag
|
||||
);
|
||||
|
||||
free(tag_str);
|
||||
tag_str=NULL;
|
||||
exported_count++;
|
||||
}
|
||||
}
|
||||
@ -1418,10 +1461,6 @@ void export_filtered_entries(char *filepath) {
|
||||
printf("INFO: %d Logeinträge erfolgreich als Timesketch-kompatible CSV-Datei nach '%s' exportiert.\n", exported_count, filename);
|
||||
}
|
||||
|
||||
struct ip_stat {
|
||||
char ip_address[50];
|
||||
int count;
|
||||
};
|
||||
|
||||
// zeigt alle annotierten Einträge detailliert an
|
||||
void show_annotated_entries() {
|
||||
@ -1461,27 +1500,36 @@ void show_annotated_entries() {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO doku
|
||||
// top-IP-Adressen sortieren nach Aufkommen und anzeigen
|
||||
void show_top_x_ips(){
|
||||
// initialisieren von 1000 Datenstrukturen mit einem char ip_address[50] und int count (oben definiert)
|
||||
struct ip_stat ip_stats[1000];
|
||||
// lokaler Zähler
|
||||
int unique_ips = 0;
|
||||
|
||||
// iterieren über alle IP-Adressen, die im Filterset sind
|
||||
for (int i = 0; i < total_entries; i++) {
|
||||
if (!passes_filter(i)) continue;
|
||||
|
||||
// IP lokal speichern
|
||||
char* current_ip = all_entries[i].ip_address;
|
||||
|
||||
// initialisieren des Index - -1 heißt bisher nie aufgetreten
|
||||
int found_index = -1;
|
||||
for (int j = 0; j < unique_ips; j++) {
|
||||
// Wenn die IP-Adresse im Vergeichsdatensatz gefunden wird, wird der index entsprechend gesetzt/erstellt
|
||||
if (strcmp(ip_stats[j].ip_address, current_ip) == 0) {
|
||||
found_index = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// wenn ein neuer index erstellt wurde (IP-Adresse war noch nicht in der Datenstruktur) oder gefunden wurde...
|
||||
if (found_index >= 0) {
|
||||
// inkrementieren des counters für Anzahl wie oft gefunden
|
||||
ip_stats[found_index].count++;
|
||||
} else {
|
||||
// wenn nicht gefunden (found_index == -1) wird die IP mit count = 1 neu angelegt
|
||||
if (unique_ips < 1000) {
|
||||
strcpy(ip_stats[unique_ips].ip_address, current_ip);
|
||||
ip_stats[unique_ips].count = 1;
|
||||
@ -1490,6 +1538,8 @@ void show_top_x_ips(){
|
||||
}
|
||||
}
|
||||
|
||||
// iterieren über alle unique ips
|
||||
// Bubble sort: https://www.proggen.org/doku.php?id=training:sorting:bubblesort:solution
|
||||
for (int i = 0; i < unique_ips - 1; i++) {
|
||||
for (int j = 0; j < unique_ips - i - 1; j++) {
|
||||
if (ip_stats[j].count < ip_stats[j + 1].count) {
|
||||
@ -1500,6 +1550,7 @@ void show_top_x_ips(){
|
||||
}
|
||||
}
|
||||
|
||||
// visuelle Darstellung
|
||||
printf("\nTOP %d IP-ADRESSEN\n", TOP_X);
|
||||
printf("Rang | IP-Adresse | Anzahl Anfragen\n");
|
||||
printf("-----|------------------|----------------\n");
|
||||
@ -1516,7 +1567,7 @@ void show_top_x_ips(){
|
||||
}
|
||||
}
|
||||
|
||||
// TODO doku
|
||||
// gleiche Mechanik wie in show_top_x_ips - könnte wahrscheinlich vereinheitlicht werden
|
||||
void show_top_user_agents(){
|
||||
struct user_agent_stat {
|
||||
char user_agent[256];
|
||||
@ -1633,7 +1684,7 @@ void print_filter_args(){
|
||||
printf("--status=");
|
||||
for (int i = 0; i < filters.status_count; i++) {
|
||||
if (i > 0) {printf(",");};
|
||||
if (filters.status_filters[i].mode == FILTER_EXCLUDE) printf("!");
|
||||
if (filters.status_filters[i].filter_exclude_flag == 1) printf("!");
|
||||
printf("%d", filters.status_filters[i].code);
|
||||
}
|
||||
printf(" ");
|
||||
@ -1643,7 +1694,7 @@ void print_filter_args(){
|
||||
printf("--method=");
|
||||
for (int i = 0; i < filters.method_count; i++) {
|
||||
if (i > 0) {printf(",");}
|
||||
if (filters.method_filters[i].mode == FILTER_EXCLUDE) printf("!");
|
||||
if (filters.method_filters[i].filter_exclude_flag == 1) printf("!");
|
||||
printf("%s", filters.method_filters[i].pattern);
|
||||
}
|
||||
printf(" ");
|
||||
@ -1653,7 +1704,7 @@ void print_filter_args(){
|
||||
printf("--ip=");
|
||||
for (int i = 0; i < filters.ip_count; i++) {
|
||||
if (i > 0) {printf(",");};
|
||||
if (filters.ip_filters[i].mode == FILTER_EXCLUDE) printf("!");
|
||||
if (filters.ip_filters[i].filter_exclude_flag == 1) printf("!");
|
||||
printf("%s", filters.ip_filters[i].ip_address);
|
||||
}
|
||||
printf(" ");
|
||||
@ -1663,7 +1714,7 @@ void print_filter_args(){
|
||||
printf("--useragent=");
|
||||
for (int i = 0; i < filters.user_agent_count; i++) {
|
||||
if (i > 0) {printf(",");};
|
||||
if (filters.user_agent_filters[i].mode == FILTER_EXCLUDE) printf("!");
|
||||
if (filters.user_agent_filters[i].filter_exclude_flag == 1) printf("!");
|
||||
printf("%s", filters.user_agent_filters[i].pattern);
|
||||
}
|
||||
printf(" ");
|
||||
@ -1673,7 +1724,7 @@ void print_filter_args(){
|
||||
printf("--url=");
|
||||
for (int i = 0; i < filters.url_count; i++) {
|
||||
if (i > 0) {printf(",");};
|
||||
if (filters.url_filters[i].mode == FILTER_EXCLUDE) printf("!");
|
||||
if (filters.url_filters[i].filter_exclude_flag == 1) printf("!");
|
||||
printf("%s", filters.url_filters[i].pattern);
|
||||
}
|
||||
printf(" ");
|
||||
@ -1683,7 +1734,7 @@ void print_filter_args(){
|
||||
printf("--timerange=");
|
||||
for(int i =0; i < filters.time_count;i++){
|
||||
if(i > 0) {printf(",");};
|
||||
if (filters.time_filters[i].mode == FILTER_EXCLUDE) {printf("!");};
|
||||
if (filters.time_filters[i].filter_exclude_flag == 1) {printf("!");};
|
||||
// die führenden 0 sind hier wichtig
|
||||
printf("%04d-%02d-%02d-%02d-%02d-%02d:%04d-%02d-%02d-%02d-%02d-%02d ",
|
||||
filters.time_filters[i].start_time.year,
|
||||
@ -1704,7 +1755,7 @@ void print_filter_args(){
|
||||
// macht nicht viel Sinn, diese hier zu integrieren, so lang der User nicht weiß, wie die Annotationen lauten
|
||||
if (filters.annotation_flag_filter_enabled) {
|
||||
printf("--annotated=");
|
||||
if (filters.annotation_flag_filter.mode == FILTER_EXCLUDE) printf("!");
|
||||
if (filters.annotation_flag_filter.filter_exclude_flag == 1) printf("!");
|
||||
printf("true ");
|
||||
}
|
||||
|
||||
@ -1712,7 +1763,7 @@ void print_filter_args(){
|
||||
printf("--annotation=");
|
||||
for (int i = 0; i < filters.annotation_count; i++) {
|
||||
if (i > 0) printf(",");
|
||||
if (filters.annotation_filters[i].mode == FILTER_EXCLUDE) printf("!");
|
||||
if (filters.annotation_filters[i].filter_exclude_flag == 1) printf("!");
|
||||
printf("%s", filters.annotation_filters[i].pattern);
|
||||
}
|
||||
printf(" ");
|
||||
@ -1982,7 +2033,7 @@ int menu_set_filters(){
|
||||
if (filter_type < 0) continue;
|
||||
|
||||
filters.status_filters[filters.status_count].code = status;
|
||||
filters.status_filters[filters.status_count].mode = (filter_type == 2) ? FILTER_EXCLUDE : FILTER_INCLUDE;
|
||||
filters.status_filters[filters.status_count].filter_exclude_flag = (filter_type == 2) ? 1 : 0;
|
||||
filters.status_count++;
|
||||
printf("Status-Code Filter hinzugefügt. Gesamt: %d\n", filters.status_count);
|
||||
|
||||
@ -2004,7 +2055,7 @@ int menu_set_filters(){
|
||||
if (filter_type < 0) continue;
|
||||
|
||||
strcpy(filters.ip_filters[filters.ip_count].ip_address, ip);
|
||||
filters.ip_filters[filters.ip_count].mode = (filter_type == 2) ? FILTER_EXCLUDE : FILTER_INCLUDE;
|
||||
filters.ip_filters[filters.ip_count].filter_exclude_flag = (filter_type == 2) ? 1 : 0;
|
||||
filters.ip_count++;
|
||||
printf("IP-Filter hinzugefügt. Gesamt: %d\n", filters.ip_count);
|
||||
|
||||
@ -2076,7 +2127,7 @@ int menu_set_filters(){
|
||||
new_time_filter.end_time.minute = end_minute;
|
||||
new_time_filter.end_time.second = end_second;
|
||||
|
||||
new_time_filter.mode = (filter_type == 2) ? FILTER_EXCLUDE : FILTER_INCLUDE;
|
||||
new_time_filter.filter_exclude_flag = (filter_type == 2) ? 1 : 0;
|
||||
|
||||
filters.time_filters[filters.time_count] = new_time_filter;
|
||||
filters.time_count++;
|
||||
@ -2101,7 +2152,7 @@ int menu_set_filters(){
|
||||
if (filter_type < 0) continue;
|
||||
|
||||
strcpy(filters.user_agent_filters[filters.user_agent_count].pattern, pattern);
|
||||
filters.user_agent_filters[filters.user_agent_count].mode = (filter_type == 2) ? FILTER_EXCLUDE : FILTER_INCLUDE;
|
||||
filters.user_agent_filters[filters.user_agent_count].filter_exclude_flag = (filter_type == 2) ? 1 : 0;
|
||||
filters.user_agent_count++;
|
||||
printf("User-Agent Filter hinzugefügt. Gesamt: %d\n", filters.user_agent_count);
|
||||
|
||||
@ -2123,7 +2174,7 @@ int menu_set_filters(){
|
||||
if (filter_type < 0) continue;
|
||||
|
||||
strcpy(filters.method_filters[filters.method_count].pattern, pattern);
|
||||
filters.method_filters[filters.method_count].mode = (filter_type == 2) ? FILTER_EXCLUDE : FILTER_INCLUDE;
|
||||
filters.method_filters[filters.method_count].filter_exclude_flag = (filter_type == 2) ? 1 : 0;
|
||||
filters.method_count++;
|
||||
printf("Method-Filter hinzugefügt. Gesamt: %d\n", filters.method_count);
|
||||
|
||||
@ -2145,7 +2196,7 @@ int menu_set_filters(){
|
||||
if (filter_type < 0) continue;
|
||||
|
||||
strcpy(filters.url_filters[filters.url_count].pattern, pattern);
|
||||
filters.url_filters[filters.url_count].mode = (filter_type == 2) ? FILTER_EXCLUDE : FILTER_INCLUDE;
|
||||
filters.url_filters[filters.url_count].filter_exclude_flag = (filter_type == 2) ? 1 : 0;
|
||||
filters.url_count++;
|
||||
printf("URL-Filter hinzugefügt. Gesamt: %d\n", filters.url_count);
|
||||
} else if (choice == 7) {
|
||||
@ -2155,7 +2206,7 @@ int menu_set_filters(){
|
||||
|
||||
int filter_type = safe_read_integer("Auswahl: ", 1, 2);
|
||||
if (filter_type < 0) continue;
|
||||
filters.annotation_flag_filter.mode = (filter_type == 2) ? FILTER_EXCLUDE : FILTER_INCLUDE;
|
||||
filters.annotation_flag_filter.filter_exclude_flag = (filter_type == 2) ? 1 : 0;
|
||||
filters.annotation_flag_filter_enabled = 1;
|
||||
} else if (choice == 8) {
|
||||
if (filters.annotation_count >= MAX_FILTERS) {
|
||||
@ -2175,7 +2226,7 @@ int menu_set_filters(){
|
||||
if (filter_type < 0) continue;
|
||||
|
||||
strcpy(filters.annotation_filters[filters.annotation_count].pattern, pattern);
|
||||
filters.annotation_filters[filters.annotation_count].mode = (filter_type == 2) ? FILTER_EXCLUDE : FILTER_INCLUDE;
|
||||
filters.annotation_filters[filters.annotation_count].filter_exclude_flag = (filter_type == 2) ? 1 : 0;
|
||||
filters.annotation_count++;
|
||||
printf("Annotations-Filter hinzugefügt. Gesamt: %d\n", filters.annotation_count);
|
||||
} else if (choice == -2) {
|
||||
@ -2203,32 +2254,32 @@ void menu_delete_filters(){
|
||||
int filter_index = 1;
|
||||
|
||||
for (int i = 0; i < filters.status_count; i++) {
|
||||
char* mode_str = (filters.status_filters[i].mode == FILTER_EXCLUDE) ? "ausschließen" : "einschließen";
|
||||
char* mode_str = (filters.status_filters[i].filter_exclude_flag == 1) ? "ausschließen" : "einschließen";
|
||||
printf("%2d. Status-Code: %d (%s)\n", filter_index++, filters.status_filters[i].code, mode_str);
|
||||
}
|
||||
|
||||
for (int i = 0; i < filters.method_count; i++) {
|
||||
char* mode_str = (filters.method_filters[i].mode == FILTER_EXCLUDE) ? "ausschließen" : "einschließen";
|
||||
char* mode_str = (filters.method_filters[i].filter_exclude_flag == 1) ? "ausschließen" : "einschließen";
|
||||
printf("%2d. HTTP-Methode: \"%s\" (%s)\n", filter_index++, filters.method_filters[i].pattern, mode_str);
|
||||
}
|
||||
|
||||
for (int i = 0; i < filters.ip_count; i++) {
|
||||
char* mode_str = (filters.ip_filters[i].mode == FILTER_EXCLUDE) ? "ausschließen" : "einschließen";
|
||||
char* mode_str = (filters.ip_filters[i].filter_exclude_flag == 1) ? "ausschließen" : "einschließen";
|
||||
printf("%2d. IP-Adresse: %s (%s)\n", filter_index++, filters.ip_filters[i].ip_address, mode_str);
|
||||
}
|
||||
|
||||
for (int i = 0; i < filters.user_agent_count; i++) {
|
||||
char* mode_str = (filters.user_agent_filters[i].mode == FILTER_EXCLUDE) ? "ausschließen" : "einschließen";
|
||||
char* mode_str = (filters.user_agent_filters[i].filter_exclude_flag == 1) ? "ausschließen" : "einschließen";
|
||||
printf("%2d. User-Agent: \"%s\" (%s)\n", filter_index++, filters.user_agent_filters[i].pattern, mode_str);
|
||||
}
|
||||
|
||||
for (int i = 0; i < filters.url_count; i++) {
|
||||
char* mode_str = (filters.url_filters[i].mode == FILTER_EXCLUDE) ? "ausschließen" : "einschließen";
|
||||
char* mode_str = (filters.url_filters[i].filter_exclude_flag == 1) ? "ausschließen" : "einschließen";
|
||||
printf("%2d. URL-Pfad: \"%s\" (%s)\n", filter_index++, filters.url_filters[i].pattern, mode_str);
|
||||
}
|
||||
|
||||
for (int i = 0; i < filters.time_count; i++) {
|
||||
char* mode_str = (filters.time_filters[i].mode == FILTER_EXCLUDE) ? "ausschließen" : "einschließen";
|
||||
char* mode_str = (filters.time_filters[i].filter_exclude_flag == 1) ? "ausschließen" : "einschließen";
|
||||
printf("%2d. Zeitraum: %02d.%02d.%d %02d:%02d:%02d - %02d.%02d.%d %02d:%02d:%02d (%s)\n",
|
||||
filter_index++,
|
||||
filters.time_filters[i].start_time.day,
|
||||
@ -2247,12 +2298,12 @@ void menu_delete_filters(){
|
||||
}
|
||||
|
||||
if (filters.annotation_flag_filter_enabled){
|
||||
char* mode_str = (filters.annotation_flag_filter.mode == FILTER_EXCLUDE) ? "ausschließen" : "einschließen";
|
||||
char* mode_str = (filters.annotation_flag_filter.filter_exclude_flag == 1) ? "ausschließen" : "einschließen";
|
||||
printf("%2d. Annotierte Einträge %s", filter_index++, mode_str);
|
||||
}
|
||||
|
||||
for (int i = 0; i < filters.annotation_count; i++) {
|
||||
char* mode_str = (filters.annotation_filters[i].mode == FILTER_EXCLUDE) ? "ausschließen" : "einschließen";
|
||||
char* mode_str = (filters.annotation_filters[i].filter_exclude_flag == 1) ? "ausschließen" : "einschließen";
|
||||
printf("%2d. Annotations-Filter: \"%s\" (%s)\n", filter_index++, filters.annotation_filters[i].pattern, mode_str);
|
||||
}
|
||||
|
||||
@ -2531,7 +2582,7 @@ void menu_show_entries(){
|
||||
}
|
||||
|
||||
// Funktionen zum setzen der Filter (existierende Datenstrukturen)
|
||||
void add_parsed_status_filter(char* value, filter_mode_t mode) {
|
||||
void add_parsed_status_filter(char* value, int filter_exclude_flag) {
|
||||
if (filters.status_count >= MAX_FILTERS) {
|
||||
printf("WARNING: MAX_FILTERS überschritten, ignoriere: %s\n", value);
|
||||
return;
|
||||
@ -2539,7 +2590,7 @@ void add_parsed_status_filter(char* value, filter_mode_t mode) {
|
||||
// Kovertierung des Statuscodes zu long mit Error handling
|
||||
char* endptr;
|
||||
int status_code = strtol(value, &endptr, 10);
|
||||
if (*endptr != '\n'){
|
||||
if (*endptr != '\0'){
|
||||
printf("ERROR: Ungültiger Wert im Statuscode-Filter: %s", value);
|
||||
}
|
||||
if (status_code < 100 || status_code > 599) {
|
||||
@ -2549,13 +2600,13 @@ void add_parsed_status_filter(char* value, filter_mode_t mode) {
|
||||
|
||||
// setzen des Filters
|
||||
filters.status_filters[filters.status_count].code = status_code;
|
||||
filters.status_filters[filters.status_count].mode = mode;
|
||||
filters.status_filters[filters.status_count].filter_exclude_flag = filter_exclude_flag;
|
||||
filters.status_count++;
|
||||
|
||||
printf("DEBUG: Filter hinzugefügt: %s%d\n", mode == FILTER_EXCLUDE ? "!" : "", status_code);
|
||||
if (flag_verbose) printf("DEBUG: Filter hinzugefügt: %s%d\n", filter_exclude_flag == 1 ? "!" : "", status_code);
|
||||
}
|
||||
|
||||
void add_parsed_ip_filter(char* value, filter_mode_t mode) {
|
||||
void add_parsed_ip_filter(char* value, int filter_exclude_flag) {
|
||||
if (filters.ip_count >= MAX_FILTERS) {
|
||||
printf("WARNING: MAX_FILTERS überschritten, ignoriere: %s\n", value);
|
||||
return;
|
||||
@ -2569,14 +2620,14 @@ void add_parsed_ip_filter(char* value, filter_mode_t mode) {
|
||||
|
||||
// setzen des Filters
|
||||
strcpy(filters.ip_filters[filters.ip_count].ip_address, value);
|
||||
filters.ip_filters[filters.ip_count].mode = mode;
|
||||
filters.ip_filters[filters.ip_count].filter_exclude_flag = filter_exclude_flag;
|
||||
filters.ip_count++;
|
||||
|
||||
printf("DEBUG: IP-Adressfilter hinzugefügt: %s%s\n", mode == FILTER_EXCLUDE ? "!" : "", value);
|
||||
if (flag_verbose) printf("DEBUG: IP-Adressfilter hinzugefügt: %s%s\n", filter_exclude_flag == 1 ? "!" : "", value);
|
||||
}
|
||||
|
||||
// gleiche Mechanik wie bei IP-Adresse
|
||||
void add_parsed_method_filter(char* value, filter_mode_t mode) {
|
||||
void add_parsed_method_filter(char* value, int filter_exclude_flag) {
|
||||
if (filters.method_count >= MAX_FILTERS) {
|
||||
printf("WARNING: MAX_FILTERS überschritten, ignoriere: %s\n", value);
|
||||
return;
|
||||
@ -2588,14 +2639,14 @@ void add_parsed_method_filter(char* value, filter_mode_t mode) {
|
||||
}
|
||||
|
||||
strcpy(filters.method_filters[filters.method_count].pattern, value);
|
||||
filters.method_filters[filters.method_count].mode = mode;
|
||||
filters.method_filters[filters.method_count].filter_exclude_flag = filter_exclude_flag;
|
||||
filters.method_count++;
|
||||
|
||||
printf("DEBUG: Methoden-Filter hinzugefügt: %s%s\n", mode == FILTER_EXCLUDE ? "!" : "", value);
|
||||
if (flag_verbose) printf("DEBUG: Methoden-Filter hinzugefügt: %s%s\n", filter_exclude_flag == 1 ? "!" : "", value);
|
||||
}
|
||||
|
||||
// gleiche Mechanik wie bei IP-Adresse
|
||||
void add_parsed_useragent_filter(char* value, filter_mode_t mode) {
|
||||
void add_parsed_useragent_filter(char* value, int filter_exclude_flag) {
|
||||
if (filters.user_agent_count >= MAX_FILTERS) {
|
||||
printf("WARNING: MAX_FILTERS überschritten, ignoriere: %s\n", value);
|
||||
return;
|
||||
@ -2607,14 +2658,14 @@ void add_parsed_useragent_filter(char* value, filter_mode_t mode) {
|
||||
}
|
||||
|
||||
strcpy(filters.user_agent_filters[filters.user_agent_count].pattern, value);
|
||||
filters.user_agent_filters[filters.user_agent_count].mode = mode;
|
||||
filters.user_agent_filters[filters.user_agent_count].filter_exclude_flag = filter_exclude_flag;
|
||||
filters.user_agent_count++;
|
||||
|
||||
printf("DEBUG: User Agent Filter hinzugefügt: %s%s\n", mode == FILTER_EXCLUDE ? "!" : "", value);
|
||||
if (flag_verbose) printf("DEBUG: User Agent Filter hinzugefügt: %s%s\n", filter_exclude_flag == 1 ? "!" : "", value);
|
||||
}
|
||||
|
||||
// gleiche Mechanik wie bei IP-Adresse
|
||||
void add_parsed_url_filter(char* value, filter_mode_t mode) {
|
||||
void add_parsed_url_filter(char* value, int filter_exclude_flag) {
|
||||
if (filters.url_count >= MAX_FILTERS) {
|
||||
printf("WARNING: MAX_FILTERS überschritten, ignoriere: %s\n", value);
|
||||
return;
|
||||
@ -2626,14 +2677,14 @@ void add_parsed_url_filter(char* value, filter_mode_t mode) {
|
||||
}
|
||||
|
||||
strcpy(filters.url_filters[filters.url_count].pattern, value);
|
||||
filters.url_filters[filters.url_count].mode = mode;
|
||||
filters.url_filters[filters.url_count].filter_exclude_flag = filter_exclude_flag;
|
||||
filters.url_count++;
|
||||
|
||||
printf("DEBUG: URL/Payload-Filter hinzugefügt: %s%s\n", mode == FILTER_EXCLUDE ? "!" : "", value);
|
||||
if (flag_verbose) printf("DEBUG: URL/Payload-Filter hinzugefügt: %s%s\n", filter_exclude_flag == 1 ? "!" : "", value);
|
||||
}
|
||||
|
||||
// Parsen des Timestamp-Filters ist etwas komplexer, da er in die Datenstruktur geschrieben werden muss.
|
||||
void add_parsed_timerange_filter(char* value, filter_mode_t mode) {
|
||||
void add_parsed_timerange_filter(char* value, int filter_exclude_flag) {
|
||||
if (filters.time_count >= MAX_FILTERS) {
|
||||
printf("WARNING: MAX_FILTERS überschritten, ignoriere: %s\n", value);
|
||||
return;
|
||||
@ -2760,14 +2811,14 @@ void add_parsed_timerange_filter(char* value, filter_mode_t mode) {
|
||||
new_time_filter.end_time.minute = end_minute;
|
||||
new_time_filter.end_time.second = end_second;
|
||||
|
||||
new_time_filter.mode = mode;
|
||||
new_time_filter.filter_exclude_flag = filter_exclude_flag;
|
||||
|
||||
// Logik hier: der neue Filter wird stets an einen neuen Index geschrieben. Dieser ergibt sich aus der aktuellen ANZAHL der existierenden Zeitfilter. Das funktioniert, weil der index bei 0 beginnt
|
||||
filters.time_filters[filters.time_count] = new_time_filter;
|
||||
filters.time_count++;
|
||||
|
||||
printf("DEBUG: Zeitraum-Filter hinzugefügt (%s): %04d-%02d-%02d %02d:%02d:%02d bis %04d-%02d-%02d %02d:%02d:%02d\n",
|
||||
mode == FILTER_EXCLUDE ? "ausschließen" : "einschließen",
|
||||
if (flag_verbose) printf("DEBUG: Zeitraum-Filter hinzugefügt (%s): %04d-%02d-%02d %02d:%02d:%02d bis %04d-%02d-%02d %02d:%02d:%02d\n",
|
||||
filter_exclude_flag == 1 ? "ausschließen" : "einschließen",
|
||||
new_time_filter.start_time.year, new_time_filter.start_time.month, new_time_filter.start_time.day,
|
||||
new_time_filter.start_time.hour, new_time_filter.start_time.minute, new_time_filter.start_time.second,
|
||||
new_time_filter.end_time.year, new_time_filter.end_time.month, new_time_filter.end_time.day,
|
||||
@ -2775,25 +2826,25 @@ void add_parsed_timerange_filter(char* value, filter_mode_t mode) {
|
||||
}
|
||||
|
||||
// recht einfache Mechanik für den Bool´schen Filter für annotierte Einträge
|
||||
void add_parsed_annotated_filter(char* value, filter_mode_t mode) {
|
||||
void add_parsed_annotated_filter(char* value, int filter_exclude_flag) {
|
||||
if (strcmp(value, "true") == 0) {
|
||||
filters.annotation_flag_filter.annotation_flag_is_present = 1;
|
||||
filters.annotation_flag_filter.mode = mode;
|
||||
filters.annotation_flag_filter.filter_exclude_flag = filter_exclude_flag;
|
||||
filters.annotation_flag_filter_enabled = 1;
|
||||
printf("DEBUG: Annotations-Flag-Filter hinzugefügt: %s%s\n", mode == FILTER_EXCLUDE ? "!" : "", value);
|
||||
if (flag_verbose) printf("DEBUG: Annotations-Flag-Filter hinzugefügt: %s%s\n", filter_exclude_flag == 1 ? "!" : "", value);
|
||||
// falls doch mal jemand false eingibt
|
||||
} else if (strcmp(value, "false") == 0) {
|
||||
filters.annotation_flag_filter.annotation_flag_is_present = 0;
|
||||
filters.annotation_flag_filter.mode = mode;
|
||||
filters.annotation_flag_filter.filter_exclude_flag = filter_exclude_flag;
|
||||
filters.annotation_flag_filter_enabled = 1;
|
||||
printf("DEBUG: Annotations-Flag-Filter hinzugefügt: %s%s\n", mode == FILTER_EXCLUDE ? "!" : "", value);
|
||||
if (flag_verbose) printf("DEBUG: Annotations-Flag-Filter hinzugefügt: %s%s\n", filter_exclude_flag == 1 ? "!" : "", value);
|
||||
} else {
|
||||
printf("WARNING: Ungültiger Wert für --annotated Filter: %s (nur 'true' unterstützt)\n", value);
|
||||
}
|
||||
}
|
||||
|
||||
// Wieder gleiche Mechanik wie beim User Agent etc
|
||||
void add_parsed_annotation_filter(char* value, filter_mode_t mode) {
|
||||
void add_parsed_annotation_filter(char* value, int filter_exclude_flag) {
|
||||
if (filters.annotation_count >= MAX_FILTERS) {
|
||||
printf("WARNING: MAX_FILTERS überschritten, ignoriere: %s\n", value);
|
||||
return;
|
||||
@ -2805,11 +2856,11 @@ void add_parsed_annotation_filter(char* value, filter_mode_t mode) {
|
||||
}
|
||||
|
||||
strcpy(filters.annotation_filters[filters.annotation_count].pattern, value);
|
||||
filters.annotation_filters[filters.annotation_count].mode = mode;
|
||||
filters.annotation_filters[filters.annotation_count].filter_exclude_flag = filter_exclude_flag;
|
||||
filters.annotation_count++;
|
||||
|
||||
printf("DEBUG: Annotations-Filter hinzugefügt: %s%s\n",
|
||||
mode == FILTER_EXCLUDE ? "!" : "", value);
|
||||
if (flag_verbose) printf("DEBUG: Annotations-Filter hinzugefügt: %s%s\n",
|
||||
filter_exclude_flag == 1 ? "!" : "", value);
|
||||
}
|
||||
|
||||
// Funktion zum Parsen der Filter-Werte, die mit --<Filtertyp>=<Werte,Komma-getrennt> übergeben werden.
|
||||
@ -2828,31 +2879,31 @@ void parse_filter_values(char* values_str, char* filter_type) {
|
||||
// Sollte der Nutzer Leerzeichen verwendet haben, müssen diese übersprungen werden
|
||||
while (*token == ' ') token++;
|
||||
// setzen des Modus, Standard inklusiv
|
||||
filter_mode_t mode = FILTER_INCLUDE;
|
||||
int filter_exclude_flag = 0;
|
||||
// ..mit !-Präfix exklusiv.
|
||||
if (*token == '!') {
|
||||
mode = FILTER_EXCLUDE;
|
||||
filter_exclude_flag = 1;
|
||||
token++; // den Pointer vom ! weiteriterieren, dieser ist nicht Teil des Filters
|
||||
}
|
||||
|
||||
if (strlen(token) > 0) {
|
||||
// wenn das token Werte hat, werden die entsprechenden Funktionen aufgerufen, die die Filter setzen
|
||||
if (strcmp(filter_type, "status") == 0) {
|
||||
add_parsed_status_filter(token, mode);
|
||||
add_parsed_status_filter(token, filter_exclude_flag);
|
||||
} else if (strcmp(filter_type, "ip") == 0) {
|
||||
add_parsed_ip_filter(token, mode);
|
||||
add_parsed_ip_filter(token, filter_exclude_flag);
|
||||
} else if (strcmp(filter_type, "method") == 0) {
|
||||
add_parsed_method_filter(token, mode);
|
||||
add_parsed_method_filter(token, filter_exclude_flag);
|
||||
} else if (strcmp(filter_type, "useragent") == 0) {
|
||||
add_parsed_useragent_filter(token, mode);
|
||||
add_parsed_useragent_filter(token, filter_exclude_flag);
|
||||
} else if (strcmp(filter_type, "url") == 0) {
|
||||
add_parsed_url_filter(token, mode);
|
||||
add_parsed_url_filter(token, filter_exclude_flag);
|
||||
} else if (strcmp(filter_type, "timerange") == 0) {
|
||||
add_parsed_timerange_filter(token, mode);
|
||||
add_parsed_timerange_filter(token, filter_exclude_flag);
|
||||
} else if (strcmp(filter_type, "annotated") == 0) {
|
||||
add_parsed_annotated_filter(token, mode);
|
||||
add_parsed_annotated_filter(token, filter_exclude_flag);
|
||||
} else if (strcmp(filter_type, "annotation") == 0) {
|
||||
add_parsed_annotation_filter(token, mode);
|
||||
add_parsed_annotation_filter(token, filter_exclude_flag);
|
||||
}
|
||||
}
|
||||
// nächste Iteration - nächstes token einlesen, damit die while-Schleife weiteriteriert
|
||||
@ -2903,10 +2954,10 @@ int parse_filter_argument(char* arg) {
|
||||
} else if (strstr(filter_type, "mode") != NULL) {
|
||||
if (strstr(values, "and") != NULL || strstr(values, "AND") != NULL) {
|
||||
filters.combination_mode = 0;
|
||||
printf("DEBUG: AND-Modus gesetzt\n");
|
||||
if (flag_verbose) printf("DEBUG: AND-Modus gesetzt\n");
|
||||
} else if (strstr(values, "or") != NULL || strstr(values, "OR") != NULL) {
|
||||
filters.combination_mode = 1;
|
||||
printf("DEBUG: OR-Modus gesetzt\n");
|
||||
if (flag_verbose) printf("DEBUG: OR-Modus gesetzt\n");
|
||||
} else {
|
||||
printf("WARNING: ungültiger Modus-Wert: %s ('and' oder 'oder' möglich)\n", values);
|
||||
}
|
||||
@ -3010,6 +3061,7 @@ int main(int argc, char* argv[]) {
|
||||
int flag_interactive = 0;
|
||||
int flag_export = 0;
|
||||
int flag_help = 0;
|
||||
// int flag_verbose = 0; - global definiert
|
||||
|
||||
char export_filename[90];
|
||||
int flag_has_filename = 0;
|
||||
@ -3039,6 +3091,8 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
} else if (strcmp(argv[i], "-h")==0) {
|
||||
flag_help = 1;
|
||||
} else if (strcmp(argv[i], "-v")==0) {
|
||||
flag_verbose = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3074,7 +3128,7 @@ int main(int argc, char* argv[]) {
|
||||
} else if (choice == 3) {
|
||||
export_filtered_entries(0);
|
||||
} else if (choice == 4) {
|
||||
printf("Programmende\n");
|
||||
if (flag_verbose) printf("DEBUG: Programmende\n");
|
||||
break;
|
||||
} else if (choice == -4) {
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user