progress
This commit is contained in:
parent
4db2cb753a
commit
654641c87a
743
src/main.c
743
src/main.c
@ -624,7 +624,7 @@ void load_log_file(char* path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Funktion zum suchen eines Suchbegriffs innerhalb eines Strings (lowercase)
|
// Funktion zum suchen eines Suchbegriffs innerhalb eines Strings (lowercase)
|
||||||
int search_in_string(const char* raw_string, const char* search_string) {
|
int search_in_string(char* raw_string, char* search_string) {
|
||||||
char raw_string_lower[512]; // Puffer zum Speichern des zu durchsuchenden Strings
|
char raw_string_lower[512]; // Puffer zum Speichern des zu durchsuchenden Strings
|
||||||
char search_string_lower[256]; // Puffer zum Speichern des Suchbegriffs
|
char search_string_lower[256]; // Puffer zum Speichern des Suchbegriffs
|
||||||
|
|
||||||
@ -1199,6 +1199,78 @@ void show_filtered_entries(int num_shown) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_filter_args() {
|
||||||
|
int total_filters = filters.status_count + filters.method_count + filters.ip_count + filters.time_count + filters.user_agent_count + filters.url_count;
|
||||||
|
|
||||||
|
if (total_filters == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("-f ");
|
||||||
|
|
||||||
|
if (filters.status_count > 0) {
|
||||||
|
printf("--status=");
|
||||||
|
for (int i = 0; i < filters.status_count; i++) {
|
||||||
|
if (i > 0) printf(",");
|
||||||
|
if (filters.status_filters[i].mode == FILTER_EXCLUDE) printf("!");
|
||||||
|
printf("%d", filters.status_filters[i].code);
|
||||||
|
}
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filters.method_count > 0) {
|
||||||
|
printf("--method=");
|
||||||
|
for (int i = 0; i < filters.method_count; i++) {
|
||||||
|
if (i > 0) printf(",");
|
||||||
|
if (filters.method_filters[i].mode == FILTER_EXCLUDE) printf("!");
|
||||||
|
printf("%s", filters.method_filters[i].pattern);
|
||||||
|
}
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filters.ip_count > 0) {
|
||||||
|
printf("--ip=");
|
||||||
|
for (int i = 0; i < filters.ip_count; i++) {
|
||||||
|
if (i > 0) printf(",");
|
||||||
|
if (filters.ip_filters[i].mode == FILTER_EXCLUDE) printf("!");
|
||||||
|
printf("%s", filters.ip_filters[i].ip_address);
|
||||||
|
}
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filters.user_agent_count > 0) {
|
||||||
|
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("!");
|
||||||
|
printf("%s", filters.user_agent_filters[i].pattern);
|
||||||
|
}
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filters.url_count > 0) {
|
||||||
|
printf("--url=");
|
||||||
|
for (int i = 0; i < filters.url_count; i++) {
|
||||||
|
if (i > 0) printf(",");
|
||||||
|
if (filters.url_filters[i].mode == FILTER_EXCLUDE) printf("!");
|
||||||
|
printf("%s", filters.url_filters[i].pattern);
|
||||||
|
}
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filters.combination_mode == 1) {
|
||||||
|
printf("--mode=or ");
|
||||||
|
}else {
|
||||||
|
printf("--mode=and ");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
if (filters.time_count > 0) {
|
||||||
|
printf("HINWEIS: %d Zeitraum-Filter sind aktiv, aber nur im interaktiven Modus verfügbar.\n", filters.time_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void show_status() {
|
void show_status() {
|
||||||
printf("\nPREVIEW:\n");
|
printf("\nPREVIEW:\n");
|
||||||
@ -1218,209 +1290,14 @@ void show_status() {
|
|||||||
if (total_filters == 0) {
|
if (total_filters == 0) {
|
||||||
printf(" -> keine Filter gesetzt\n");
|
printf(" -> keine Filter gesetzt\n");
|
||||||
} else {
|
} else {
|
||||||
printf(" Modus: %s\n", filters.combination_mode == 0 ? "AND" : "OR");
|
printf("\n ");
|
||||||
|
print_filter_args();
|
||||||
|
printf("\n <Verwendbar als Startargument>\n");
|
||||||
printf(" Ausschlussfilter (!) haben Vorrang, dann Einschlussfilter\n");
|
printf(" Ausschlussfilter (!) haben Vorrang, dann Einschlussfilter\n");
|
||||||
printf("\n Gesetzt:\n");
|
|
||||||
|
|
||||||
if (filters.status_count > 0) {
|
int active_types = (filters.status_count > 0) + (filters.method_count > 0 ) + (filters.ip_count > 0) + (filters.user_agent_count > 0) + (filters.time_count > 0) + (filters.url_count > 0);
|
||||||
printf(" -> Status: ");
|
|
||||||
|
|
||||||
int excludes = 0, includes = 0;
|
|
||||||
for (int i = 0; i < filters.status_count; i++) {
|
|
||||||
if (filters.status_filters[i].mode == FILTER_EXCLUDE) excludes++;
|
|
||||||
else includes++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (excludes > 0) {
|
|
||||||
printf("!(");
|
|
||||||
int first = 1;
|
|
||||||
for (int i = 0; i < filters.status_count; i++) {
|
|
||||||
if (filters.status_filters[i].mode == FILTER_EXCLUDE) {
|
|
||||||
if (!first) printf(" OR ");
|
|
||||||
printf("%d", filters.status_filters[i].code);
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf(")");
|
|
||||||
if (includes > 0) printf(" AND ");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (includes > 0) {
|
|
||||||
if (includes > 1) printf("(");
|
|
||||||
int first = 1;
|
|
||||||
for (int i = 0; i < filters.status_count; i++) {
|
|
||||||
if (filters.status_filters[i].mode == FILTER_INCLUDE) {
|
|
||||||
if (!first) printf(" %s ", filters.combination_mode == 0 ? "AND" : "OR");
|
|
||||||
printf("%d", filters.status_filters[i].code);
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (includes > 1) printf(")");
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filters.method_count > 0) {
|
|
||||||
printf(" -> Request-Method: ");
|
|
||||||
|
|
||||||
int excludes = 0, includes = 0;
|
|
||||||
for (int i = 0; i < filters.method_count; i++) {
|
|
||||||
if (filters.method_filters[i].mode == FILTER_EXCLUDE) excludes++;
|
|
||||||
else includes++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (excludes > 0) {
|
|
||||||
printf("!(");
|
|
||||||
int first = 1;
|
|
||||||
for (int i = 0; i < filters.method_count; i++) {
|
|
||||||
if (filters.method_filters[i].mode == FILTER_EXCLUDE) {
|
|
||||||
if (!first) printf(" OR ");
|
|
||||||
printf("%s", filters.method_filters[i].pattern);
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf(")");
|
|
||||||
if (includes > 0) printf(" AND ");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (includes > 0) {
|
|
||||||
if (includes > 1) printf("(");
|
|
||||||
int first = 1;
|
|
||||||
for (int i = 0; i < filters.method_count; i++) {
|
|
||||||
if (filters.method_filters[i].mode == FILTER_INCLUDE) {
|
|
||||||
if (!first) printf(" %s ", filters.combination_mode == 0 ? "AND" : "OR");
|
|
||||||
printf("%s", filters.method_filters[i].pattern);
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (includes > 1) printf(")");
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filters.ip_count > 0) {
|
|
||||||
printf(" -> IP-Adresse: ");
|
|
||||||
|
|
||||||
int excludes = 0, includes = 0;
|
|
||||||
for (int i = 0; i < filters.ip_count; i++) {
|
|
||||||
if (filters.ip_filters[i].mode == FILTER_EXCLUDE) excludes++;
|
|
||||||
else includes++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (excludes > 0) {
|
|
||||||
printf("!(");
|
|
||||||
int first = 1;
|
|
||||||
for (int i = 0; i < filters.ip_count; i++) {
|
|
||||||
if (filters.ip_filters[i].mode == FILTER_EXCLUDE) {
|
|
||||||
if (!first) printf(" OR ");
|
|
||||||
printf("%s", filters.ip_filters[i].ip_address);
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf(")");
|
|
||||||
if (includes > 0) printf(" AND ");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (includes > 0) {
|
|
||||||
if (includes > 1) printf("(");
|
|
||||||
int first = 1;
|
|
||||||
for (int i = 0; i < filters.ip_count; i++) {
|
|
||||||
if (filters.ip_filters[i].mode == FILTER_INCLUDE) {
|
|
||||||
if (!first) printf(" %s ", filters.combination_mode == 0 ? "AND" : "OR");
|
|
||||||
printf("%s", filters.ip_filters[i].ip_address);
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (includes > 1) printf(")");
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filters.user_agent_count > 0) {
|
|
||||||
printf(" -> UserAgent: ");
|
|
||||||
|
|
||||||
int excludes = 0, includes = 0;
|
|
||||||
for (int i = 0; i < filters.user_agent_count; i++) {
|
|
||||||
if (filters.user_agent_filters[i].mode == FILTER_EXCLUDE) excludes++;
|
|
||||||
else includes++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (excludes > 0) {
|
|
||||||
printf("!(");
|
|
||||||
int first = 1;
|
|
||||||
for (int i = 0; i < filters.user_agent_count; i++) {
|
|
||||||
if (filters.user_agent_filters[i].mode == FILTER_EXCLUDE) {
|
|
||||||
if (!first) printf(" OR ");
|
|
||||||
printf("\"%s\"", filters.user_agent_filters[i].pattern);
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf(")");
|
|
||||||
if (includes > 0) printf(" AND ");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (includes > 0) {
|
|
||||||
if (includes > 1) printf("(");
|
|
||||||
int first = 1;
|
|
||||||
for (int i = 0; i < filters.user_agent_count; i++) {
|
|
||||||
if (filters.user_agent_filters[i].mode == FILTER_INCLUDE) {
|
|
||||||
if (!first) printf(" %s ", filters.combination_mode == 0 ? "AND" : "OR");
|
|
||||||
printf("\"%s\"", filters.user_agent_filters[i].pattern);
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (includes > 1) printf(")");
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filters.url_count > 0) {
|
|
||||||
printf(" -> Payload/Pfad: ");
|
|
||||||
|
|
||||||
int excludes = 0, includes = 0;
|
|
||||||
for (int i = 0; i < filters.url_count; i++) {
|
|
||||||
if (filters.url_filters[i].mode == FILTER_EXCLUDE) excludes++;
|
|
||||||
else includes++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (excludes > 0) {
|
|
||||||
printf("!(");
|
|
||||||
int first = 1;
|
|
||||||
for (int i = 0; i < filters.url_count; i++) {
|
|
||||||
if (filters.url_filters[i].mode == FILTER_EXCLUDE) {
|
|
||||||
if (!first) printf(" OR ");
|
|
||||||
printf("\"%s\"", filters.url_filters[i].pattern);
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf(")");
|
|
||||||
if (includes > 0) printf(" AND ");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (includes > 0) {
|
|
||||||
if (includes > 1) printf("(");
|
|
||||||
int first = 1;
|
|
||||||
for (int i = 0; i < filters.url_count; i++) {
|
|
||||||
if (filters.url_filters[i].mode == FILTER_INCLUDE) {
|
|
||||||
if (!first) printf(" %s ", filters.combination_mode == 0 ? "AND" : "OR");
|
|
||||||
printf("\"%s\"", filters.url_filters[i].pattern);
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (includes > 1) printf(")");
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filters.time_count > 0) {
|
|
||||||
printf(" -> Zeitraum: %d Filter gesetzt\n", filters.time_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
int active_types = (filters.status_count > 0) + (filters.method_count > 0 ) + (filters.ip_count > 0) +
|
|
||||||
(filters.user_agent_count > 0) + (filters.time_count > 0) + (filters.url_count > 0);
|
|
||||||
if (active_types > 1) {
|
if (active_types > 1) {
|
||||||
printf("\n%s-Verknüpfung (nur Einschlussfilter)\n",
|
printf(" %s-Verknüpfung (nur Einschlussfilter, Ausschlussfilter sind stets ODER-verknüpft)\n", filters.combination_mode == 0 ? "UND" : "ODER");
|
||||||
filters.combination_mode == 0 ? "UND" : "ODER");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1480,7 +1357,7 @@ int handle_menu_shortcuts(int choice) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// überall wo integer aus String-Input gelesen werden müssen. basiert auf strtol, was gegen Buffer Overflow sicher sein soll
|
// überall wo integer aus String-Input gelesen werden müssen. basiert auf strtol, was gegen Buffer Overflow sicher sein soll
|
||||||
int safe_read_integer(const char* prompt, int min_val, int max_val) {
|
int safe_read_integer(char* prompt, int min_val, int max_val) {
|
||||||
char input[50];
|
char input[50];
|
||||||
int value;
|
int value;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
@ -1516,7 +1393,7 @@ int safe_read_integer(const char* prompt, int min_val, int max_val) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int safe_read_string(const char* prompt, char* buffer, int buffer_size) {
|
int safe_read_string(char* prompt, char* buffer, int buffer_size) {
|
||||||
while (1) {
|
while (1) {
|
||||||
printf("%s", prompt);
|
printf("%s", prompt);
|
||||||
if (scanf("%s", buffer) != 1) {
|
if (scanf("%s", buffer) != 1) {
|
||||||
@ -1539,9 +1416,11 @@ int safe_read_string(const char* prompt, char* buffer, int buffer_size) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Menü mit standardisierter Navigation
|
||||||
int read_menu_input() {
|
int read_menu_input() {
|
||||||
char input[10];
|
char input[10];
|
||||||
if (scanf("%9s", input) != 1) {
|
// scanf braucht eine Begrenzung, %s würde alle Zeichen in stdin lesen - buffer overflow
|
||||||
|
if (scanf("%5s", input) != 1) {
|
||||||
clear_input_buffer();
|
clear_input_buffer();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1552,113 +1431,20 @@ int read_menu_input() {
|
|||||||
if (strcmp(input, "q") == 0 || strcmp(input, "Q") == 0) return -4;
|
if (strcmp(input, "q") == 0 || strcmp(input, "Q") == 0) return -4;
|
||||||
|
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
//string to long
|
||||||
long number = strtol(input, &endptr, 10);
|
long number = strtol(input, &endptr, 10);
|
||||||
|
// Prüfen, ob Eingabe erfolgreich zu Zahl umgewandelt werden konnte - endptr speichert das Zeichen, das nicht mehr gepasst hat - muss also Nullterminator sein
|
||||||
if (*endptr != '\0' || number < 0 || number > 999) {
|
if (*endptr != '\0' || number < 0 || number > 999) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return (int)number;
|
return (int)number;
|
||||||
}
|
}
|
||||||
|
|
||||||
void show_stats() {
|
|
||||||
int filtered_count = count_filtered_entries();
|
|
||||||
int count_200 = 0, count_300 = 0, count_400 = 0, count_500 = 0;
|
|
||||||
int count_get = 0, count_post = 0, count_atypical = 0, count_other = 0;
|
|
||||||
long total_bytes = 0;
|
|
||||||
int unique_ips = 0;
|
|
||||||
|
|
||||||
char ip_list[1000][50];
|
|
||||||
int ip_count = 0;
|
|
||||||
|
|
||||||
struct simple_time earliest_time = {31, 12, 9999, 23, 59, 59};
|
|
||||||
struct simple_time latest_time = {1, 1, 1970, 0, 0, 0};
|
|
||||||
|
|
||||||
for (int i = 0; i < total_entries; i++) {
|
|
||||||
if (passes_filter(i)) {
|
|
||||||
if (all_entries[i].status_code >= 200 && all_entries[i].status_code < 300) count_200++;
|
|
||||||
else if (all_entries[i].status_code >= 300 && all_entries[i].status_code < 400) count_300++;
|
|
||||||
else if (all_entries[i].status_code >= 400 && all_entries[i].status_code < 500) count_400++;
|
|
||||||
else if (all_entries[i].status_code >= 500) count_500++;
|
|
||||||
|
|
||||||
if (strcmp(all_entries[i].request_method, "GET") == 0) count_get++;
|
|
||||||
else if (strcmp(all_entries[i].request_method, "POST") == 0) count_post++;
|
|
||||||
else if (strcmp(all_entries[i].request_method, "ATYPICAL") == 0) count_atypical++;
|
|
||||||
else count_other++;
|
|
||||||
|
|
||||||
total_bytes += all_entries[i].bytes_sent;
|
|
||||||
|
|
||||||
int ip_exists = 0;
|
|
||||||
for (int j = 0; j < ip_count; j++) {
|
|
||||||
if (strcmp(ip_list[j], all_entries[i].ip_address) == 0) {
|
|
||||||
ip_exists = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!ip_exists && ip_count < 1000) {
|
|
||||||
strcpy(ip_list[ip_count], all_entries[i].ip_address);
|
|
||||||
ip_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (compare_times(all_entries[i].time, earliest_time) < 0) {
|
|
||||||
earliest_time = all_entries[i].time;
|
|
||||||
}
|
|
||||||
if (compare_times(all_entries[i].time, latest_time) > 0) {
|
|
||||||
latest_time = all_entries[i].time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unique_ips = ip_count;
|
|
||||||
|
|
||||||
printf("\nDATENANALYSE\n");
|
|
||||||
printf(" Gesamte Einträge: %d\n Gefilterte Einträge: %d (%.1f%%)\n Eindeutige IPs: %d\n",
|
|
||||||
total_entries, filtered_count,
|
|
||||||
total_entries > 0 ? (filtered_count * 100.0 / total_entries) : 0.0, unique_ips);
|
|
||||||
|
|
||||||
if (filtered_count > 0) {
|
|
||||||
printf(" Ø Anfragen pro IP: %.1f\n", (double)filtered_count / unique_ips);
|
|
||||||
|
|
||||||
printf(" Zeitspanne: %02d.%02d.%d %02d:%02d:%02d - %02d.%02d.%d %02d:%02d:%02d\n",
|
|
||||||
earliest_time.day, earliest_time.month, earliest_time.year,
|
|
||||||
earliest_time.hour, earliest_time.minute, earliest_time.second,
|
|
||||||
latest_time.day, latest_time.month, latest_time.year,
|
|
||||||
latest_time.hour, latest_time.minute, latest_time.second);
|
|
||||||
|
|
||||||
int total_minutes = (latest_time.year - earliest_time.year) * 525600 +
|
|
||||||
(latest_time.month - earliest_time.month) * 43800 +
|
|
||||||
(latest_time.day - earliest_time.day) * 1440 +
|
|
||||||
(latest_time.hour - earliest_time.hour) * 60 +
|
|
||||||
(latest_time.minute - earliest_time.minute);
|
|
||||||
|
|
||||||
if (total_minutes > 0) {
|
|
||||||
printf(" Ø Anfragen/Minute: %.2f", (double)filtered_count / total_minutes);
|
|
||||||
if (total_minutes >= 60) {
|
|
||||||
printf("\n Ø Anfragen/Stunde: %.2f", (double)filtered_count * 60 / total_minutes);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(" Status-Codes:\n 2xx:%d (%.1f%%)\n 3xx:%d (%.1f%%)\n 4xx:%d (%.1f%%)\n 5xx:%d (%.1f%%)\n",
|
|
||||||
count_200, count_200 * 100.0 / filtered_count,
|
|
||||||
count_300, count_300 * 100.0 / filtered_count,
|
|
||||||
count_400, count_400 * 100.0 / filtered_count,
|
|
||||||
count_500, count_500 * 100.0 / filtered_count);
|
|
||||||
|
|
||||||
printf(" HTTP-Methoden:\n GET:%d (%.1f%%)\n POST:%d (%.1f%%)\n Andere:%d (%.1f%%)\n",
|
|
||||||
count_get, count_get * 100.0 / filtered_count,
|
|
||||||
count_post, count_post * 100.0 / filtered_count,
|
|
||||||
count_other, count_other * 100.0 / filtered_count);
|
|
||||||
|
|
||||||
printf(" Datenumfang:\n %ld Bytes total\n Ø %.1f Bytes/Anfrage\n Fehlerrate: %.1f%%\n",
|
|
||||||
total_bytes, (double)total_bytes / filtered_count,
|
|
||||||
((count_400 + count_500) * 100.0) / filtered_count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void show_main_menu() {
|
void show_main_menu() {
|
||||||
printf("\nHAUPTMENÜ\n");
|
printf("\nHAUPTMENÜ\n");
|
||||||
printf("1. Filter verwalten\n");
|
printf("1. Filter verwalten\n");
|
||||||
printf("2. Daten anzeigen und exportieren\n");
|
printf("2. Daten anzeigen und exportieren\n");
|
||||||
printf("3. Statistiken anzeigen\n");
|
printf("3. Export (CSV, Timesketch-kompatibel)\n");
|
||||||
printf("4. Programm beenden\n");
|
printf("4. Programm beenden\n");
|
||||||
printf("Navigation: [b]Zurück [m]Hauptmenü [q]Beenden\n");
|
printf("Navigation: [b]Zurück [m]Hauptmenü [q]Beenden\n");
|
||||||
printf("Auswahl: ");
|
printf("Auswahl: ");
|
||||||
@ -1666,6 +1452,7 @@ void show_main_menu() {
|
|||||||
|
|
||||||
int menu_set_filters() {
|
int menu_set_filters() {
|
||||||
int choice = 0;
|
int choice = 0;
|
||||||
|
// Standardnavigation aus read_menu_input
|
||||||
while (choice != -2 && choice != -3) {
|
while (choice != -2 && choice != -3) {
|
||||||
show_status();
|
show_status();
|
||||||
|
|
||||||
@ -1735,7 +1522,7 @@ int menu_set_filters() {
|
|||||||
struct time_filter new_time_filter = {0};
|
struct time_filter new_time_filter = {0};
|
||||||
|
|
||||||
printf("STARTZEIT:\n");
|
printf("STARTZEIT:\n");
|
||||||
int start_year = safe_read_integer("Jahr (z.B. 2023): ", 1970, 2100);
|
int start_year = safe_read_integer("Jahr (z.B. 2025): ", 1970, 2100);
|
||||||
if (start_year < 0) continue;
|
if (start_year < 0) continue;
|
||||||
|
|
||||||
int start_month = safe_read_integer("Monat (1-12): ", 1, 12);
|
int start_month = safe_read_integer("Monat (1-12): ", 1, 12);
|
||||||
@ -2089,6 +1876,7 @@ void menu_reset_filters() {
|
|||||||
|
|
||||||
void menu_filter_management() {
|
void menu_filter_management() {
|
||||||
int choice = 0;
|
int choice = 0;
|
||||||
|
// Standardnavigation aus read_menu_input
|
||||||
while (choice != -2 && choice != -3) {
|
while (choice != -2 && choice != -3) {
|
||||||
show_status();
|
show_status();
|
||||||
|
|
||||||
@ -2128,6 +1916,7 @@ void menu_filter_management() {
|
|||||||
void menu_show_entries() {
|
void menu_show_entries() {
|
||||||
int choice = 0;
|
int choice = 0;
|
||||||
int supress_preview = 0;
|
int supress_preview = 0;
|
||||||
|
// Standardnavigation aus read_menu_input()
|
||||||
while (choice != -2 && choice != -3) {
|
while (choice != -2 && choice != -3) {
|
||||||
if (supress_preview == 0) {
|
if (supress_preview == 0) {
|
||||||
show_status();
|
show_status();
|
||||||
@ -2180,10 +1969,112 @@ void menu_show_entries() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Funktionen zum setzen der Filter (existierende Datenstrukturen)
|
||||||
|
void add_status_filter(char* value, filter_mode_t mode) {
|
||||||
|
if (filters.status_count >= MAX_FILTERS) {
|
||||||
|
printf("WARNING: MAX_FILTERS überschritten, ignoriere: %s\n", value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Kovertierung des Statuscodes zu long mit Error handling
|
||||||
|
char* endptr;
|
||||||
|
int status_code = strtol(value, &endptr, 10);
|
||||||
|
if (*endptr != '\n' ){
|
||||||
|
printf("ERROR: Ungültiger Wert im Statuscode-Filter: %s", value);
|
||||||
|
}
|
||||||
|
if (status_code < 100 || status_code > 599) {
|
||||||
|
printf("WARNING: Invalid status code: %s (must be 100-599)\n", value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setzen des Filters
|
||||||
|
filters.status_filters[filters.status_count].code = status_code;
|
||||||
|
filters.status_filters[filters.status_count].mode = mode;
|
||||||
|
filters.status_count++;
|
||||||
|
|
||||||
|
printf("DEBUG: Filter hinzugefügt: %s%d\n", mode == FILTER_EXCLUDE ? "!" : "", status_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_ip_filter(char* value, filter_mode_t mode) {
|
||||||
|
if (filters.ip_count >= MAX_FILTERS) {
|
||||||
|
printf("WARNING: MAX_FILTERS überschritten, ignoriere: %s\n", value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// einfache Plausibilitätsprüfung hinsichtlich der Länge
|
||||||
|
if (strlen(value) >= sizeof(filters.ip_filters[0].ip_address)) {
|
||||||
|
printf("WARNING: IP-Adresse zu lang: %s\n", value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setzen des Filters
|
||||||
|
strcpy(filters.ip_filters[filters.ip_count].ip_address, value);
|
||||||
|
filters.ip_filters[filters.ip_count].mode = mode;
|
||||||
|
filters.ip_count++;
|
||||||
|
|
||||||
|
printf("DEBUG: IP-Adressfilter hinzugefügt: %s%s\n", mode == FILTER_EXCLUDE ? "!" : "", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// gleiche Mechanik wie bei IP-Adresse
|
||||||
|
void add_method_filter(char* value, filter_mode_t mode) {
|
||||||
|
if (filters.method_count >= MAX_FILTERS) {
|
||||||
|
printf("WARNING: MAX_FILTERS überschritten, ignoriere: %s\n", value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(value) >= sizeof(filters.method_filters[0].pattern)) {
|
||||||
|
printf("WARNING: Methoden-Filterwert zu lang: %s\n", value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(filters.method_filters[filters.method_count].pattern, value);
|
||||||
|
filters.method_filters[filters.method_count].mode = mode;
|
||||||
|
filters.method_count++;
|
||||||
|
|
||||||
|
printf("DEBUG: Methoden-Filter hinzugefügt: %s%s\n", mode == FILTER_EXCLUDE ? "!" : "", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// gleiche Mechanik wie bei IP-Adresse
|
||||||
|
void add_useragent_filter(char* value, filter_mode_t mode) {
|
||||||
|
if (filters.user_agent_count >= MAX_FILTERS) {
|
||||||
|
printf("WARNING: MAX_FILTERS überschritten, ignoriere: %s\n", value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(value) >= sizeof(filters.user_agent_filters[0].pattern)) {
|
||||||
|
printf("WARNING: User agent Filterwert zu lang: %s\n", value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(filters.user_agent_filters[filters.user_agent_count].pattern, value);
|
||||||
|
filters.user_agent_filters[filters.user_agent_count].mode = mode;
|
||||||
|
filters.user_agent_count++;
|
||||||
|
|
||||||
|
printf("DEBUG: User Agent Filter hinzugefügt: %s%s\n", mode == FILTER_EXCLUDE ? "!" : "", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// gleiche Mechanik wie bei IP-Adresse
|
||||||
|
void add_url_filter(char* value, filter_mode_t mode) {
|
||||||
|
if (filters.url_count >= MAX_FILTERS) {
|
||||||
|
printf("WARNING: MAX_FILTERS überschritten, ignoriere: %s\n", value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(value) >= sizeof(filters.url_filters[0].pattern)) {
|
||||||
|
printf("WARNING: URL/Payload Filterwert zu lang: %s\n", value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(filters.url_filters[filters.url_count].pattern, value);
|
||||||
|
filters.url_filters[filters.url_count].mode = mode;
|
||||||
|
filters.url_count++;
|
||||||
|
|
||||||
|
printf("DEBUG: URL/Payload-Filter hinzugefügt: %s%s\n", mode == FILTER_EXCLUDE ? "!" : "", value);
|
||||||
|
}
|
||||||
|
|
||||||
// Funktion zum Parsen der Filter-Werte, die mit --<Filtertyp>=<Werte,Komma-getrennt> übergeben werden.
|
// Funktion zum Parsen der Filter-Werte, die mit --<Filtertyp>=<Werte,Komma-getrennt> übergeben werden.
|
||||||
// values_str sind die Werte hinter dem =, filter_type die Werte vor dem =
|
// values_str sind die Werte hinter dem =, filter_type die Werte vor dem =
|
||||||
// filter_type wird von parse_filter_argument() übergeben
|
// filter_type wird von parse_filter_argument() übergeben
|
||||||
void parse_filter_values(const char* values_str, const char* filter_type) {
|
void parse_filter_values(char* values_str, char* filter_type) {
|
||||||
char values_local[1024];
|
char values_local[1024];
|
||||||
// Werte in lokale Variable einlesen, Nullterminator setzen
|
// Werte in lokale Variable einlesen, Nullterminator setzen
|
||||||
strncpy(values_local, values_str, sizeof(values_local) - 1);
|
strncpy(values_local, values_str, sizeof(values_local) - 1);
|
||||||
@ -2222,192 +2113,56 @@ void parse_filter_values(const char* values_str, const char* filter_type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Funktionen zum setzen der Filter (existierende Datenstrukturen)
|
|
||||||
void add_status_filter(const char* value, filter_mode_t mode) {
|
|
||||||
if (filters.status_count >= MAX_FILTERS) {
|
|
||||||
printf("WARNING: MAX_FILTERS überschritten, ignoriere: %s\n", value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Kovertierung des Statuscodes zu long mit Error handling
|
|
||||||
int status_code = strtol(value, &endptr, 10);
|
|
||||||
if (endptr != '\n' ){
|
|
||||||
printf("ERROR: Ungültiger Wert im Statuscode-Filter: %s", value);
|
|
||||||
}
|
|
||||||
if (status_code < 100 || status_code > 599) {
|
|
||||||
printf("WARNING: Invalid status code: %s (must be 100-599)\n", value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// setzen des Filters
|
|
||||||
filters.status_filters[filters.status_count].code = status_code;
|
|
||||||
filters.status_filters[filters.status_count].mode = mode;
|
|
||||||
filters.status_count++;
|
|
||||||
|
|
||||||
printf("DEBUG: Filter hinzugefügt: %s%d\n", mode == FILTER_EXCLUDE ? "!" : "", status_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_ip_filter(const char* value, filter_mode_t mode) {
|
|
||||||
if (filters.ip_count >= MAX_FILTERS) {
|
|
||||||
printf("WARNING: MAX_FILTERS überschritten, ignoriere: %s\n", value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// einfache Plausibilitätsprüfung hinsichtlich der Länge
|
|
||||||
if (strlen(value) >= sizeof(filters.ip_filters[0].ip_address)) {
|
|
||||||
printf("WARNING: IP-Adresse zu lang: %s\n", value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// setzen des Filters
|
|
||||||
strcpy(filters.ip_filters[filters.ip_count].ip_address, value);
|
|
||||||
filters.ip_filters[filters.ip_count].mode = mode;
|
|
||||||
filters.ip_count++;
|
|
||||||
|
|
||||||
printf("DEBUG: IP-Adressfilter hinzugefügt: %s%s\n", mode == FILTER_EXCLUDE ? "!" : "", value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// gleiche Mechanik wie bei IP-Adresse
|
|
||||||
void add_method_filter(const char* value, filter_mode_t mode) {
|
|
||||||
if (filters.method_count >= MAX_FILTERS) {
|
|
||||||
printf("WARNING: MAX_FILTERS überschritten, ignoriere: %s\n", value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(value) >= sizeof(filters.method_filters[0].pattern)) {
|
|
||||||
printf("WARNING: Methoden-Filterwert zu lang: %s\n", value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy(filters.method_filters[filters.method_count].pattern, value);
|
|
||||||
filters.method_filters[filters.method_count].mode = mode;
|
|
||||||
filters.method_count++;
|
|
||||||
|
|
||||||
printf("DEBUG: Methoden-Filter hinzugefügt: %s%s\n", mode == FILTER_EXCLUDE ? "!" : "", value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// gleiche Mechanik wie bei IP-Adresse
|
|
||||||
void add_useragent_filter(const char* value, filter_mode_t mode) {
|
|
||||||
if (filters.user_agent_count >= MAX_FILTERS) {
|
|
||||||
printf("WARNING: MAX_FILTERS überschritten, ignoriere: %s\n", value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(value) >= sizeof(filters.user_agent_filters[0].pattern)) {
|
|
||||||
printf("WARNING: User agent Filterwert zu lang: %s\n", value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy(filters.user_agent_filters[filters.user_agent_count].pattern, value);
|
|
||||||
filters.user_agent_filters[filters.user_agent_count].mode = mode;
|
|
||||||
filters.user_agent_count++;
|
|
||||||
|
|
||||||
printf("DEBUG: User Agent Filter hinzugefügt: %s%s\n", mode == FILTER_EXCLUDE ? "!" : "", value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// gleiche Mechanik wie bei IP-Adresse
|
|
||||||
void add_url_filter(const char* value, filter_mode_t mode) {
|
|
||||||
if (filters.url_count >= MAX_FILTERS) {
|
|
||||||
printf("WARNING: MAX_FILTERS überschritten, ignoriere: %s\n", value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(value) >= sizeof(filters.url_filters[0].pattern)) {
|
|
||||||
printf("WARNING: URL/Payload Filterwert zu lang: %s\n", value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy(filters.url_filters[filters.url_count].pattern, value);
|
|
||||||
filters.url_filters[filters.url_count].mode = mode;
|
|
||||||
filters.url_count++;
|
|
||||||
|
|
||||||
printf("DEBUG: URL/Payload-Filter hinzugefügt: %s%s\n", mode == FILTER_EXCLUDE ? "!" : "", value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter-Argument Parser
|
// Filter-Argument Parser
|
||||||
int parse_filter_argument(const char* arg) {
|
int parse_filter_argument(char* arg) {
|
||||||
if (!starts_with(arg, "--")) {
|
if (!starts_with(arg, "--")) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// = finden
|
// = finden, strchr gibt den Pointer auf das = zurück
|
||||||
const char* equals_pos = strchr(arg, '=');
|
char* equals_pos = strchr(arg, '=');
|
||||||
if (equals_pos == NULL) {
|
if (equals_pos == NULL) {
|
||||||
printf("WARNING: Invalid filter format (missing =): %s\n", arg);
|
printf("WARNING: Ungültiges Filter-Format, kein '=' gefunden: %s\n", arg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter-Typ parsen
|
//int filterstr_start = arg -2;
|
||||||
int type_len = equals_pos - arg - 2; // Position anpassen,
|
// filter-Typ parsen: 1. Länge des Strings errechnen (Position des '=' abzüglich Startposition des Strings, abzüglich 2 (für die '--' am Anfang))
|
||||||
|
int filterstr_length = equals_pos - arg -2;
|
||||||
|
// 2.
|
||||||
char filter_type[50];
|
char filter_type[50];
|
||||||
strncpy(filter_type, arg + 2, type_len);
|
strncpy(filter_type, arg +2, filterstr_length);
|
||||||
filter_type[type_len] = '\0';
|
filter_type[filterstr_length] = '\0';
|
||||||
|
|
||||||
// Extract values (after =)
|
// Filter-Werte (nach den =)
|
||||||
const char* values = equals_pos + 1;
|
char* values = equals_pos + 1;
|
||||||
|
|
||||||
// Parse based on filter type
|
if (strstr(filter_type, "status") != NULL) {
|
||||||
if (strcmp(filter_type, "status") == 0) {
|
parse_filter_values(values, "status");
|
||||||
parse_filter_values(values, add_status_filter);
|
} else if (strstr(filter_type, "ip") != NULL) {
|
||||||
} else if (strcmp(filter_type, "ip") == 0) {
|
parse_filter_values(values, "ip");
|
||||||
parse_filter_values(values, add_ip_filter);
|
} else if (strstr(filter_type, "method") != NULL) {
|
||||||
} else if (strcmp(filter_type, "method") == 0) {
|
parse_filter_values(values, "method");
|
||||||
parse_filter_values(values, add_method_filter);
|
} else if (strstr(filter_type, "useragent") != NULL) {
|
||||||
} else if (strcmp(filter_type, "useragent") == 0) {
|
parse_filter_values(values, "useragent");
|
||||||
parse_filter_values(values, add_useragent_filter);
|
} else if (strstr(filter_type, "url") != NULL) {
|
||||||
} else if (strcmp(filter_type, "url") == 0) {
|
parse_filter_values(values, "url");
|
||||||
parse_filter_values(values, add_url_filter);
|
} else if (strstr(filter_type, "mode") != NULL) {
|
||||||
} else if (strcmp(filter_type, "mode") == 0) {
|
if (strstr(values, "and") != NULL || strstr(values, "AND") != NULL) {
|
||||||
if (strcmp(values, "and") == 0 || strcmp(values, "AND") == 0) {
|
|
||||||
filters.combination_mode = 0;
|
filters.combination_mode = 0;
|
||||||
printf("Set filter combination mode: AND\n");
|
printf("DEBUG: AND-Modus gesetzt\n");
|
||||||
} else if (strcmp(values, "or") == 0 || strcmp(values, "OR") == 0) {
|
} else if (strstr(values, "or") != NULL || strstr(values, "OR") != NULL) {
|
||||||
filters.combination_mode = 1;
|
filters.combination_mode = 1;
|
||||||
printf("Set filter combination mode: OR\n");
|
printf("DEBUG: OR-Modus gesetzt\n");
|
||||||
} else {
|
} else {
|
||||||
printf("WARNING: Invalid mode value: %s (use 'and' or 'or')\n", values);
|
printf("WARNING: ungültiger Modus-Wert: %s ('and' oder 'oder' möglich)\n", values);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("WARNING: Unknown filter type: %s\n", filter_type);
|
printf("WARNING: Unbekannter Filtertyp: %s\n", filter_type);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1; // Successfully parsed
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
// Add this to your main() function after allocate_initial_memory()
|
|
||||||
void parse_command_line_filters(int argc, char* argv[]) {
|
|
||||||
int has_filter_flag = 0;
|
|
||||||
|
|
||||||
// First, check if -f flag is present
|
|
||||||
for (int i = 2; i < argc; i++) {
|
|
||||||
if (strcmp(argv[i], "-f") == 0) {
|
|
||||||
has_filter_flag = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!has_filter_flag) {
|
|
||||||
return; // No filter flag, skip filter parsing
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Parsing command line filters...\n");
|
|
||||||
|
|
||||||
// Parse all filter arguments
|
|
||||||
for (int i = 2; i < argc; i++) {
|
|
||||||
if (starts_with(argv[i], "--")) {
|
|
||||||
parse_filter_argument(argv[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show summary of parsed filters
|
|
||||||
int total_filters = filters.status_count + filters.method_count + filters.ip_count +
|
|
||||||
filters.time_count + filters.user_agent_count + filters.url_count;
|
|
||||||
|
|
||||||
if (total_filters > 0) {
|
|
||||||
printf("Successfully parsed %d filters from command line.\n", total_filters);
|
|
||||||
} else {
|
|
||||||
printf("No valid filters found in command line arguments.\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_help(char* binary) {
|
void print_help(char* binary) {
|
||||||
@ -2415,6 +2170,7 @@ void print_help(char* binary) {
|
|||||||
printf("Verwendung:\n");
|
printf("Verwendung:\n");
|
||||||
printf(" %s <LOGDATEI|VERZEICHNIS> -i Interaktiver Modus (Filter/Analyse/Export)\n", binary);
|
printf(" %s <LOGDATEI|VERZEICHNIS> -i Interaktiver Modus (Filter/Analyse/Export)\n", binary);
|
||||||
printf(" %s <LOGDATEI|VERZEICHNIS> -e <DATEINAME(optional)> Export generieren\n", binary);
|
printf(" %s <LOGDATEI|VERZEICHNIS> -e <DATEINAME(optional)> Export generieren\n", binary);
|
||||||
|
printf(" %s <LOGDATEI|VERZEICHNIS> -f [FILTER...] Mit Kommandozeilen-Filtern\n", binary);
|
||||||
printf(" %s -h Diese Hilfe anzeigen\n", binary);
|
printf(" %s -h Diese Hilfe anzeigen\n", binary);
|
||||||
|
|
||||||
printf("\nArgumente:\n");
|
printf("\nArgumente:\n");
|
||||||
@ -2425,8 +2181,29 @@ void print_help(char* binary) {
|
|||||||
printf(" -i Startet interaktiven Modus mit Filtern (Status, Methode, IP, Zeitraum,\n");
|
printf(" -i Startet interaktiven Modus mit Filtern (Status, Methode, IP, Zeitraum,\n");
|
||||||
printf(" User-Agent, URL-Teilstring), Vorschau, Statistiken und CSV-Export (Timesketch).\n");
|
printf(" User-Agent, URL-Teilstring), Vorschau, Statistiken und CSV-Export (Timesketch).\n");
|
||||||
printf(" -e Generiert Timesketch-kompatible CSV-Datei, nimmt optional Dateinamen entgegen.\n");
|
printf(" -e Generiert Timesketch-kompatible CSV-Datei, nimmt optional Dateinamen entgegen.\n");
|
||||||
|
printf(" -f Aktiviert Kommandozeilen-Filter. Muss von Filter-Argumenten gefolgt werden.\n");
|
||||||
printf(" -h Zeigt diese Hilfe an.\n");
|
printf(" -h Zeigt diese Hilfe an.\n");
|
||||||
|
|
||||||
|
printf("\nKOMMNDOZEILEN-FILTER (nur mit -f Flag):\n");
|
||||||
|
printf(" --status=CODE[,CODE...] HTTP-Status-Codes (z.B. 200,404,500)\n");
|
||||||
|
printf(" --ip=ADRESSE[,ADRESSE...] IP-Adressen (exakte Übereinstimmung)\n");
|
||||||
|
printf(" --method=METHODE[,METHODE...] HTTP-Methoden (z.B. GET,POST,ATYPICAL)\n");
|
||||||
|
printf(" --useragent=TEXT[,TEXT...] User-Agent Teilstrings (z.B. bot,crawler)\n");
|
||||||
|
printf(" --url=PFAD[,PFAD...] URL-Pfad Teilstrings (z.B. .git,.php,wp-)\n");
|
||||||
|
printf(" --mode=MODE Filtermodus: 'and' oder 'or' (Standard: and)\n");
|
||||||
|
|
||||||
|
printf("\nFILTER-SYNTAX:\n");
|
||||||
|
printf(" Einschluss: Wert (nur Einträge MIT diesem Wert)\n");
|
||||||
|
printf(" Ausschluss: !Wert (alle Einträge OHNE diesen Wert)\n");
|
||||||
|
printf(" Mehrere: Wert1,Wert2 (kommagetrennt, keine Leerzeichen)\n");
|
||||||
|
printf(" Gemischt: Wert1,!Wert2 (Wert1 einschließen, Wert2 ausschließen)\n");
|
||||||
|
|
||||||
|
printf("\nFILTER-LOGIK:\n");
|
||||||
|
printf(" - Ausschluss-Filter (!) haben IMMER Vorrang vor Einschluss-Filtern\n");
|
||||||
|
printf(" - AND-Modus: ALLE Einschluss-Filter pro Kategorie müssen zutreffen\n");
|
||||||
|
printf(" - OR-Modus: MINDESTENS EIN Einschluss-Filter pro Kategorie muss zutreffen\n");
|
||||||
|
printf(" - Ausschluss-Filter arbeiten kategorie-intern immer im OR-Modus\n");
|
||||||
|
|
||||||
printf("\nUnterstützte Eingaben:\n");
|
printf("\nUnterstützte Eingaben:\n");
|
||||||
printf(" - Normale NGINX-Access-Logs: *.log\n");
|
printf(" - Normale NGINX-Access-Logs: *.log\n");
|
||||||
printf(" - Rotierte Logs: *.log.1, *.log.2, ... (rein textbasiert)\n");
|
printf(" - Rotierte Logs: *.log.1, *.log.2, ... (rein textbasiert)\n");
|
||||||
@ -2443,12 +2220,6 @@ void print_help(char* binary) {
|
|||||||
printf("\nBeispielzeile (eine Zeile pro Request):\n");
|
printf("\nBeispielzeile (eine Zeile pro Request):\n");
|
||||||
printf(" 0.0.0.0 - - [31/Aug/2025:00:11:42 +0000] \"GET /.git/config HTTP/1.1\" 400 255 \"-\" \"Mozilla/5.0\" \"-\"\n");
|
printf(" 0.0.0.0 - - [31/Aug/2025:00:11:42 +0000] \"GET /.git/config HTTP/1.1\" 400 255 \"-\" \"Mozilla/5.0\" \"-\"\n");
|
||||||
|
|
||||||
printf("\nBeispiele:\n");
|
|
||||||
printf(" - Einzeldatei analysieren:\n");
|
|
||||||
printf(" %s /var/log/nginx/access.log -i\n", binary);
|
|
||||||
printf(" - Verzeichnis mit mehreren .log / .log.N Dateien:\n");
|
|
||||||
printf(" %s /var/log/nginx/ -i\n", binary);
|
|
||||||
|
|
||||||
printf("\nCSV-Export (Timesketch-kompatibel):\n");
|
printf("\nCSV-Export (Timesketch-kompatibel):\n");
|
||||||
printf(" Spalten: datetime, timestamp_desc, ip_address, method, url_path, status_code,\n");
|
printf(" Spalten: datetime, timestamp_desc, ip_address, method, url_path, status_code,\n");
|
||||||
printf(" bytes_sent, user_agent, source_file, parsing_timestamp\n");
|
printf(" bytes_sent, user_agent, source_file, parsing_timestamp\n");
|
||||||
@ -2457,9 +2228,9 @@ void print_help(char* binary) {
|
|||||||
printf(" - Parser erwartet das obige Standardformat. Abweichungen können zum Abbruch führen.\n");
|
printf(" - Parser erwartet das obige Standardformat. Abweichungen können zum Abbruch führen.\n");
|
||||||
printf(" - Zeitzone aus dem Log wird gelesen, aber intern als einfache Felder verarbeitet.\n");
|
printf(" - Zeitzone aus dem Log wird gelesen, aber intern als einfache Felder verarbeitet.\n");
|
||||||
printf(" - ATYPICAL-Methode: für fehlerhafte/binäre Requests innerhalb der \"request\"-Spalte.\n");
|
printf(" - ATYPICAL-Methode: für fehlerhafte/binäre Requests innerhalb der \"request\"-Spalte.\n");
|
||||||
|
printf(" - Zeitraum-Filter sind nur im interaktiven Modus verfügbar (nicht über -f).\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
print_help(argv[0]);
|
print_help(argv[0]);
|
||||||
@ -2472,7 +2243,6 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
int flag_interactive = 0;
|
int flag_interactive = 0;
|
||||||
int flag_export = 0;
|
int flag_export = 0;
|
||||||
int flag_filters = 0;
|
|
||||||
int flag_help = 0;
|
int flag_help = 0;
|
||||||
|
|
||||||
char export_filename[90];
|
char export_filename[90];
|
||||||
@ -2491,8 +2261,15 @@ int main(int argc, char* argv[]) {
|
|||||||
flag_has_filename = 1;
|
flag_has_filename = 1;
|
||||||
i++; // Schleife weiter iterieren
|
i++; // Schleife weiter iterieren
|
||||||
}
|
}
|
||||||
} else if (strcmp(argv[i], "--filters")==0) {
|
} else if (strcmp(argv[i], "-f")==0) {
|
||||||
flag_filters = 1;
|
// parsen der nachfolgenden Argumente --ip= usw.
|
||||||
|
for (int j = i + 1; j < argc; j++) {
|
||||||
|
if (starts_with(argv[j], "--")) {
|
||||||
|
parse_filter_argument(argv[j]);
|
||||||
|
}else{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else if (strcmp(argv[i], "-h")==0) {
|
} else if (strcmp(argv[i], "-h")==0) {
|
||||||
flag_help = 1;
|
flag_help = 1;
|
||||||
@ -2506,18 +2283,14 @@ int main(int argc, char* argv[]) {
|
|||||||
load_log_file(argv[1]);
|
load_log_file(argv[1]);
|
||||||
|
|
||||||
if (total_entries == 0) {
|
if (total_entries == 0) {
|
||||||
printf("Keine gültigen Log-Einträge gefunden. Überprüfen Sie den Pfad und die Dateiformate.\n");
|
printf("ERROR: Keine gültigen Log-Einträge gefunden. Überprüfen Sie den Pfad und die Dateiformate.\n");
|
||||||
cleanup_memory();
|
cleanup_memory();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
int choice = 0;
|
int choice = 0;
|
||||||
int stats_show = 0;
|
// Standardnavigation aus read_menu_input
|
||||||
while (choice != 4 && choice != -4) {
|
while (choice != 4 && choice != -4) {
|
||||||
show_status();
|
show_status();
|
||||||
if (stats_show == 1) {
|
|
||||||
show_stats();
|
|
||||||
stats_show = 0;
|
|
||||||
}
|
|
||||||
show_main_menu();
|
show_main_menu();
|
||||||
|
|
||||||
choice = read_menu_input();
|
choice = read_menu_input();
|
||||||
@ -2533,7 +2306,7 @@ int main(int argc, char* argv[]) {
|
|||||||
} else if (choice == 2) {
|
} else if (choice == 2) {
|
||||||
menu_show_entries();
|
menu_show_entries();
|
||||||
} else if (choice == 3) {
|
} else if (choice == 3) {
|
||||||
stats_show = 1;
|
export_filtered_entries(0);
|
||||||
} else if (choice == 4) {
|
} else if (choice == 4) {
|
||||||
printf("Programmende\n");
|
printf("Programmende\n");
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user