progress
This commit is contained in:
		
							parent
							
								
									042f02a74b
								
							
						
					
					
						commit
						c0984b242e
					
				
							
								
								
									
										286
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										286
									
								
								src/main.c
									
									
									
									
									
								
							@ -23,6 +23,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 | 
				
			|||||||
#define GROWTH_FACTOR 2 // wird in mem_expand_dynamically() genutzt, um den Speicher zu vergrößern
 | 
					#define GROWTH_FACTOR 2 // wird in mem_expand_dynamically() genutzt, um den Speicher zu vergrößern
 | 
				
			||||||
#define MAX_FILTERS 100
 | 
					#define MAX_FILTERS 100
 | 
				
			||||||
#define MAX_REQUEST_LENGTH 1024 // das hohe Limit ist erforderlich, da teilweise ausufernde JSON-Requests in nginx auflaufen können.
 | 
					#define MAX_REQUEST_LENGTH 1024 // das hohe Limit ist erforderlich, da teilweise ausufernde JSON-Requests in nginx auflaufen können.
 | 
				
			||||||
 | 
					#define TOP_X 20 // definiert die Anzahl der Einträge, die in den Top-Listen angezeigt werden sollen
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// definiert Variablen für den Filtermodus. FILTER_INCLUDE=0, FILTER_EXCLUDE=1. Verbessert die Lesbarkeit des Codes.
 | 
					// definiert Variablen für den Filtermodus. FILTER_INCLUDE=0, FILTER_EXCLUDE=1. Verbessert die Lesbarkeit des Codes.
 | 
				
			||||||
typedef enum {
 | 
					typedef enum {
 | 
				
			||||||
@ -82,6 +83,12 @@ struct user_agent_filter {
 | 
				
			|||||||
    filter_mode_t mode;
 | 
					    filter_mode_t mode;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Filter für URL-Pfad/Request
 | 
				
			||||||
 | 
					struct url_filter {
 | 
				
			||||||
 | 
					    char pattern[MAX_REQUEST_LENGTH];
 | 
				
			||||||
 | 
					    filter_mode_t mode;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Struktur zum erhalten aller Filtereinträge, kann im Dialogbetrieb bearbeitet werden. Mit Zähler.
 | 
					// Struktur zum erhalten aller Filtereinträge, kann im Dialogbetrieb bearbeitet werden. Mit Zähler.
 | 
				
			||||||
struct filter_system {
 | 
					struct filter_system {
 | 
				
			||||||
    struct status_filter status_filters[MAX_FILTERS];
 | 
					    struct status_filter status_filters[MAX_FILTERS];
 | 
				
			||||||
@ -99,6 +106,9 @@ struct filter_system {
 | 
				
			|||||||
    struct user_agent_filter user_agent_filters[MAX_FILTERS];
 | 
					    struct user_agent_filter user_agent_filters[MAX_FILTERS];
 | 
				
			||||||
    int user_agent_count;
 | 
					    int user_agent_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    struct url_filter url_filters[MAX_FILTERS];
 | 
				
			||||||
 | 
					    int url_count;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    int combination_mode; // 0=AND-Filter oder 1=OR-Filter
 | 
					    int combination_mode; // 0=AND-Filter oder 1=OR-Filter
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -674,6 +684,47 @@ int user_agent_matches(char* user_agent) {
 | 
				
			|||||||
    return 1; // Keine Einschlussfilter, keine zutreffenden Ausschlussfilter, positiver Rückgabewert =1
 | 
					    return 1; // Keine Einschlussfilter, keine zutreffenden Ausschlussfilter, positiver Rückgabewert =1
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Filterfunktion für URL-Pfad. Nimmt den Datensatz entgegen und prüft gegen die gesetzten Filter, gibt dann 0 oder 1 zurück
 | 
				
			||||||
 | 
					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) {
 | 
				
			||||||
 | 
					            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
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // Prüfung im entsprechenden Modus
 | 
				
			||||||
 | 
					    int include_count = 0;
 | 
				
			||||||
 | 
					    int include_matches = 0;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for (int i = 0; i < filters.url_count; i++) {
 | 
				
			||||||
 | 
					        if (filters.url_filters[i].mode == FILTER_INCLUDE) {
 | 
				
			||||||
 | 
					            include_count++;
 | 
				
			||||||
 | 
					            int pattern_found = search_in_string(url_path, filters.url_filters[i].pattern);
 | 
				
			||||||
 | 
					            if (pattern_found) {
 | 
				
			||||||
 | 
					                include_matches++;
 | 
				
			||||||
 | 
					                if (filters.combination_mode == 1) { // OR-Modus
 | 
				
			||||||
 | 
					                    return 1; // Früheres Verlassen der Schleife bei erstem zutreffendem Einschlussfilter im OR-Modus
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Diese Prüfung wird ausgeführt, wenn Einschlussfilter vorhanden sind
 | 
				
			||||||
 | 
					    if (include_count > 0) {
 | 
				
			||||||
 | 
					        if (filters.combination_mode == 0) { // AND-Modus
 | 
				
			||||||
 | 
					            return include_matches == include_count; // Alle Einschlussfilter müssen zutreffen, die Treffer müssen Anzahl der Filter entsprechen
 | 
				
			||||||
 | 
					        } else { // OR-Modus
 | 
				
			||||||
 | 
					            return include_matches > 0; // Ausschlussfilter im ODER-Modus - wenn ein beliebiger Eintrag zum Ausschlussfilter passt, wird 0=negativ zurückgegeben
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return 1; // Keine Einschlussfilter, keine zutreffenden Ausschlussfilter, positiver Rückgabewert =1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Filterfunktion für Zugriffsmethode. Nimmt den Datensatz entgegen und prüft gegen die gesetzten Filter, gibt dann 0 oder 1 zurück
 | 
					// Filterfunktion für Zugriffsmethode. Nimmt den Datensatz entgegen und prüft gegen die gesetzten Filter, gibt dann 0 oder 1 zurück
 | 
				
			||||||
int method_matches(char* request_method) {
 | 
					int method_matches(char* request_method) {
 | 
				
			||||||
    if (filters.method_count == 0) return 1;
 | 
					    if (filters.method_count == 0) return 1;
 | 
				
			||||||
@ -837,18 +888,64 @@ int time_matches(struct simple_time entry_time) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Prüfen aller Filter im AND-Modus oder OR-Modus (combination_mode) pro Log-Eintrag
 | 
					// Prüfen aller Filter im AND-Modus oder OR-Modus (combination_mode) pro Log-Eintrag
 | 
				
			||||||
int passes_filter(int entry_index) {
 | 
					int passes_filter(int entry_index) {
 | 
				
			||||||
 | 
					    if (filters.combination_mode == 0) { // AND-Modus
 | 
				
			||||||
 | 
					        // alle AND-verknüpften Filter müssen zutreffen
 | 
				
			||||||
        int status_match = status_code_matches(all_entries[entry_index].status_code);
 | 
					        int status_match = status_code_matches(all_entries[entry_index].status_code);
 | 
				
			||||||
        int method_match = method_matches(all_entries[entry_index].request_method);
 | 
					        int method_match = method_matches(all_entries[entry_index].request_method);
 | 
				
			||||||
        int ip_match = ip_address_matches(all_entries[entry_index].ip_address);
 | 
					        int ip_match = ip_address_matches(all_entries[entry_index].ip_address);
 | 
				
			||||||
        int time_match = time_matches(all_entries[entry_index].time);
 | 
					        int time_match = time_matches(all_entries[entry_index].time);
 | 
				
			||||||
        int user_agent_match = user_agent_matches(all_entries[entry_index].user_agent);
 | 
					        int user_agent_match = user_agent_matches(all_entries[entry_index].user_agent);
 | 
				
			||||||
    if (filters.combination_mode == 0) {
 | 
					        int url_match = url_matches(all_entries[entry_index].url_path);
 | 
				
			||||||
        return status_match && ip_match && time_match && user_agent_match && method_match;
 | 
					        
 | 
				
			||||||
    } else {
 | 
					        return status_match && ip_match && time_match && user_agent_match && method_match && url_match;
 | 
				
			||||||
        int total_filters = filters.status_count + filters.method_count + filters.ip_count + filters.time_count + filters.user_agent_count;
 | 
					    } else { // OR-Modus
 | 
				
			||||||
 | 
					        // für den geprüften Eintrag muss mindestens eine der Filterkategorien zutreffen. 
 | 
				
			||||||
 | 
					        // Eine Prüfung über Filter1 || Filter2 || etc ist nicht möglich, da auch 
 | 
				
			||||||
 | 
					        // nicht gesetzte Filter hier keine Einschränkng bilden. Daher muss jede KAtegorie einzeln geprüft werden.
 | 
				
			||||||
 | 
					        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 1;
 | 
					        if (total_filters == 0) return 1;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return status_match || method_match || ip_match || time_match || user_agent_match;
 | 
					        int has_passing_filter = 0;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // Jede Filterkategorie wird nur geprüft, wenn auch entsprechende Filter gesetzt sind.
 | 
				
			||||||
 | 
					        if (filters.status_count > 0) {
 | 
				
			||||||
 | 
					            if (status_code_matches(all_entries[entry_index].status_code)) {
 | 
				
			||||||
 | 
					                has_passing_filter = 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (filters.method_count > 0) {
 | 
				
			||||||
 | 
					            if (method_matches(all_entries[entry_index].request_method)) {
 | 
				
			||||||
 | 
					                has_passing_filter = 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (filters.ip_count > 0) {
 | 
				
			||||||
 | 
					            if (ip_address_matches(all_entries[entry_index].ip_address)) {
 | 
				
			||||||
 | 
					                has_passing_filter = 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (filters.time_count > 0) {
 | 
				
			||||||
 | 
					            if (time_matches(all_entries[entry_index].time)) {
 | 
				
			||||||
 | 
					                has_passing_filter = 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (filters.user_agent_count > 0) {
 | 
				
			||||||
 | 
					            if (user_agent_matches(all_entries[entry_index].user_agent)) {
 | 
				
			||||||
 | 
					                has_passing_filter = 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (filters.url_count > 0) {
 | 
				
			||||||
 | 
					            if (url_matches(all_entries[entry_index].url_path)) {
 | 
				
			||||||
 | 
					                has_passing_filter = 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return has_passing_filter;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -874,7 +971,7 @@ void show_status() {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    printf("\n🔍 Aktive Filter-Logik:\n");
 | 
					    printf("\n🔍 Aktive Filter-Logik:\n");
 | 
				
			||||||
    int total_filters = filters.status_count + filters.method_count + filters.ip_count + filters.time_count + filters.user_agent_count;
 | 
					    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) {
 | 
					    if (total_filters == 0) {
 | 
				
			||||||
        printf("   Keine Filter gesetzt → alle Einträge werden angezeigt\n");
 | 
					        printf("   Keine Filter gesetzt → alle Einträge werden angezeigt\n");
 | 
				
			||||||
@ -1037,13 +1134,51 @@ void show_status() {
 | 
				
			|||||||
            printf("\n");
 | 
					            printf("\n");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        if (filters.url_count > 0) {
 | 
				
			||||||
 | 
					            printf("     URL: ");
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            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) {
 | 
					        if (filters.time_count > 0) {
 | 
				
			||||||
            printf("     Time: %d Filter(s) gesetzt\n", filters.time_count);
 | 
					            printf("     Time: %d Filter(s) gesetzt\n", filters.time_count);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        // Zeigt aktuellen Modus
 | 
					        // Zeigt aktuellen Modus
 | 
				
			||||||
        int active_types = (filters.status_count > 0) + (filters.method_count > 0 ) + (filters.ip_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.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 - Ausschlussfilter vorrangig\n", 
 | 
					            printf("\n   %s-Verknüpfung - Ausschlussfilter vorrangig\n", 
 | 
				
			||||||
                   filters.combination_mode == 0 ? "UND" : "ODER");
 | 
					                   filters.combination_mode == 0 ? "UND" : "ODER");
 | 
				
			||||||
@ -1148,7 +1283,7 @@ struct ip_stat {
 | 
				
			|||||||
    int count;
 | 
					    int count;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void show_top_10_ips() {
 | 
					void show_top_x_ips() {
 | 
				
			||||||
    struct ip_stat ip_stats[1000];
 | 
					    struct ip_stat ip_stats[1000];
 | 
				
			||||||
    int unique_ips = 0;
 | 
					    int unique_ips = 0;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
@ -1186,11 +1321,11 @@ void show_top_10_ips() {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    printf("\n=== TOP 10 IP-ADRESSEN ===\n");
 | 
					    printf("\n=== TOP %d IP-ADRESSEN ===\n", TOP_X);
 | 
				
			||||||
    printf("Rang | IP-Adresse       | Anzahl Anfragen\n");
 | 
					    printf("Rang | IP-Adresse       | Anzahl Anfragen\n");
 | 
				
			||||||
    printf("-----|------------------|----------------\n");
 | 
					    printf("-----|------------------|----------------\n");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    int show_count = (unique_ips < 10) ? unique_ips : 10;
 | 
					    int show_count = (unique_ips < TOP_X) ? unique_ips : TOP_X;
 | 
				
			||||||
    for (int i = 0; i < show_count; i++) {
 | 
					    for (int i = 0; i < show_count; i++) {
 | 
				
			||||||
        printf("%-4d | %-16s | %d\n", i + 1, ip_stats[i].ip_address, ip_stats[i].count);
 | 
					        printf("%-4d | %-16s | %d\n", i + 1, ip_stats[i].ip_address, ip_stats[i].count);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -1246,11 +1381,11 @@ void show_top_user_agents() {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    printf("\n=== TOP 10 USER AGENTS ===\n");
 | 
					    printf("\n=== TOP %d USER AGENTS ===\n", TOP_X);
 | 
				
			||||||
    printf("Rang | User Agent                          | Anzahl Anfragen\n");
 | 
					    printf("Rang | User Agent                          | Anzahl Anfragen\n");
 | 
				
			||||||
    printf("-----|--------------------------------------|----------------\n");
 | 
					    printf("-----|--------------------------------------|----------------\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int show_count = (unique_agents < 10) ? unique_agents : 10;
 | 
					    int show_count = (unique_agents < TOP_X) ? unique_agents : TOP_X;
 | 
				
			||||||
    for (int i = 0; i < show_count; i++) {
 | 
					    for (int i = 0; i < show_count; i++) {
 | 
				
			||||||
        printf("%-4d | %-34s | %d\n", i + 1, agent_stats[i].user_agent, agent_stats[i].count);
 | 
					        printf("%-4d | %-34s | %d\n", i + 1, agent_stats[i].user_agent, agent_stats[i].count);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -1327,9 +1462,46 @@ void show_statistics() {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void print_filter_examples() {
 | 
				
			||||||
 | 
					    printf("\nFILTER-DOKUMENTATION\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("\n🔴 EXKLUSIONS-FILTER (immer OR-Logik, unabhängig vom Modus):\n");
 | 
				
			||||||
 | 
					    printf("Beispiel: !('uptime' OR 'scanner')\n");
 | 
				
			||||||
 | 
					    printf("→ Schließt ALLE Einträge aus, die 'uptime' ODER 'scanner' enthalten\n\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("🟢 INKLUSIONS-FILTER im AND-Modus:\n");
 | 
				
			||||||
 | 
					    printf("Beispiel: ('bot' AND 'crawl')\n");
 | 
				
			||||||
 | 
					    printf("→ Zeigt nur Einträge mit BEIDEN Begriffen\n\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("🟡 INKLUSIONS-FILTER im OR-Modus:\n");
 | 
				
			||||||
 | 
					    printf("Beispiel: ('bot' OR 'crawl')\n");
 | 
				
			||||||
 | 
					    printf("→ Zeigt Einträge mit 'bot' ODER 'crawl'\n\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("⚡ KOMBINATION: Exklusion + Inklusion:\n");
 | 
				
			||||||
 | 
					    printf("AND-Modus: !('uptime') AND ('bot' AND 'crawl')\n");
 | 
				
			||||||
 | 
					    printf("OR-Modus:  !('uptime') AND ('bot' OR 'crawl')\n\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("🎯 PRAKTISCHE ANWENDUNGSFÄLLE:\n");
 | 
				
			||||||
 | 
					    printf("Malware-Erkennung:\n");
 | 
				
			||||||
 | 
					    printf("  '.git' OR '.env' OR '/admin'\n");
 | 
				
			||||||
 | 
					    printf("  → Verdächtige Pfad-Zugriffe\n\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("Bot-Traffic bereinigen:\n");
 | 
				
			||||||
 | 
					    printf("  !('bot') AND Status=200 AND Method='GET'\n");
 | 
				
			||||||
 | 
					    printf("  → Nur menschliche, erfolgreiche GET-Anfragen\n\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("Zeitraum-Analyse:\n");
 | 
				
			||||||
 | 
					    printf("  Time='08:00-18:00' AND Status=500\n");
 | 
				
			||||||
 | 
					    printf("  → Server-Fehler nur während Geschäftszeiten\n\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("DDoS-Verdacht:\n");
 | 
				
			||||||
 | 
					    printf("  Status=429 OR Status=503 OR Status=500\n");
 | 
				
			||||||
 | 
					    printf("  → Alle Überlastungs- und Fehler-Codes\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void menu_set_filters() {
 | 
					void menu_set_filters() {
 | 
				
			||||||
    int choice = 0;
 | 
					    int choice = 0;
 | 
				
			||||||
    while (choice != 6) {
 | 
					    while (choice != 7) {
 | 
				
			||||||
        show_status();
 | 
					        show_status();
 | 
				
			||||||
        printf("\n=== FILTER SETZEN ===\n");
 | 
					        printf("\n=== FILTER SETZEN ===\n");
 | 
				
			||||||
        printf("1. Status-Code Filter hinzufügen (exakte Suche)\n");
 | 
					        printf("1. Status-Code Filter hinzufügen (exakte Suche)\n");
 | 
				
			||||||
@ -1337,7 +1509,8 @@ void menu_set_filters() {
 | 
				
			|||||||
        printf("3. Zeitraum Filter hinzufügen (interaktiv)\n");
 | 
					        printf("3. Zeitraum Filter hinzufügen (interaktiv)\n");
 | 
				
			||||||
        printf("4. User-Agent-Filter setzen (Freitext)\n");
 | 
					        printf("4. User-Agent-Filter setzen (Freitext)\n");
 | 
				
			||||||
        printf("5. HTTP-Methode Filter hinzufügen (Freitext)\n");
 | 
					        printf("5. HTTP-Methode Filter hinzufügen (Freitext)\n");
 | 
				
			||||||
        printf("6. Zurück zum Filter-Menü\n");
 | 
					        printf("6. URL-Pfad Filter hinzufügen (Freitext)\n");
 | 
				
			||||||
 | 
					        printf("7. Zurück zum Filter-Menü\n");
 | 
				
			||||||
        printf("Auswahl: ");
 | 
					        printf("Auswahl: ");
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        choice = read_safe_integer();
 | 
					        choice = read_safe_integer();
 | 
				
			||||||
@ -1542,7 +1715,7 @@ void menu_set_filters() {
 | 
				
			|||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            printf("HTTP-Methode eingeben (z.B. 'GET', 'POST', 'PUT'): ");
 | 
					            printf("HTTP-Methode eingeben (z.B. 'GET', 'POST', 'PUT', ... Sonderwert 'MALFORMED'): ");
 | 
				
			||||||
            char pattern[10];
 | 
					            char pattern[10];
 | 
				
			||||||
            if (scanf("%9s", pattern) == 1) {
 | 
					            if (scanf("%9s", pattern) == 1) {
 | 
				
			||||||
                printf("Filter-Typ wählen:\n");
 | 
					                printf("Filter-Typ wählen:\n");
 | 
				
			||||||
@ -1565,15 +1738,43 @@ void menu_set_filters() {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
        } else if (choice == 6) {
 | 
					        } else if (choice == 6) {
 | 
				
			||||||
 | 
					            if (filters.url_count >= MAX_FILTERS) {
 | 
				
			||||||
 | 
					                printf("FEHLER: Maximale Anzahl URL-Filter erreicht (%d)!\n", MAX_FILTERS);
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            printf("URL-Pfad Suchtext eingeben (z.B. '.git', '.php', '/admin'): ");
 | 
				
			||||||
 | 
					            char pattern[MAX_REQUEST_LENGTH];
 | 
				
			||||||
 | 
					            if (scanf("%1023s", pattern) == 1) {
 | 
				
			||||||
 | 
					                printf("Filter-Typ wählen:\n");
 | 
				
			||||||
 | 
					                printf("1. Einschließen (nur URLs mit '%s' anzeigen)\n", pattern);
 | 
				
			||||||
 | 
					                printf("2. Ausschließen (URLs mit '%s' NICHT anzeigen)\n", pattern);
 | 
				
			||||||
 | 
					                printf("Auswahl: ");
 | 
				
			||||||
 | 
					                int filter_type = read_safe_integer();
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                if (filter_type == 1 || filter_type == 2) {
 | 
				
			||||||
 | 
					                    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_count++;
 | 
				
			||||||
 | 
					                    printf("✅ URL-Filter hinzugefügt. Total: %d\n", filters.url_count);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    printf("FEHLER: Ungültiger Filter-Typ!\n");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                printf("FEHLER: Ungültiger Suchtext!\n");
 | 
				
			||||||
 | 
					                clear_input_buffer();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        } else if (choice == 7) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        } else if (choice != -1) {
 | 
					        } else if (choice != -1) {
 | 
				
			||||||
            printf("Ungültige Auswahl! Bitte wählen Sie 1-6.\n");
 | 
					            printf("Ungültige Auswahl! Bitte wählen Sie 1-7.\n");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void menu_delete_filters() {
 | 
					void menu_delete_filters() {
 | 
				
			||||||
    int total_filters = filters.status_count + filters.ip_count + filters.time_count + filters.user_agent_count;
 | 
					    int total_filters = filters.status_count + filters.ip_count + filters.time_count + filters.user_agent_count + filters.method_count + filters.url_count;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (total_filters == 0) {
 | 
					    if (total_filters == 0) {
 | 
				
			||||||
        printf("Keine Filter gesetzt zum Löschen.\n");
 | 
					        printf("Keine Filter gesetzt zum Löschen.\n");
 | 
				
			||||||
@ -1605,6 +1806,11 @@ void menu_delete_filters() {
 | 
				
			|||||||
        printf("%d. User-Agent: \"%s\" %s\n", filter_index++, filters.user_agent_filters[i].pattern, mode_str);
 | 
					        printf("%d. 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)";
 | 
				
			||||||
 | 
					        printf("%d. URL-Pfad: \"%s\" %s\n", filter_index++, filters.url_filters[i].pattern, mode_str);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    for (int i = 0; i < filters.time_count; i++) {
 | 
					    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].mode == FILTER_EXCLUDE) ? "(ausschließen)" : "(einschließen)";
 | 
				
			||||||
        printf("%d. Zeitraum: %02d.%02d.%d %02d:%02d:%02d - %02d.%02d.%d %02d:%02d:%02d %s\n", 
 | 
					        printf("%d. Zeitraum: %02d.%02d.%d %02d:%02d:%02d - %02d.%02d.%d %02d:%02d:%02d %s\n", 
 | 
				
			||||||
@ -1686,6 +1892,18 @@ void menu_delete_filters() {
 | 
				
			|||||||
        current_index++;
 | 
					        current_index++;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int i = 0; i < filters.url_count; i++) {
 | 
				
			||||||
 | 
					        if (current_index == choice) {
 | 
				
			||||||
 | 
					            for (int j = i; j < filters.url_count - 1; j++) {
 | 
				
			||||||
 | 
					                filters.url_filters[j] = filters.url_filters[j + 1];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            filters.url_count--;
 | 
				
			||||||
 | 
					            printf("✅ URL-Filter gelöscht.\n");
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        current_index++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    for (int i = 0; i < filters.time_count; i++) {
 | 
					    for (int i = 0; i < filters.time_count; i++) {
 | 
				
			||||||
        if (current_index == choice) {
 | 
					        if (current_index == choice) {
 | 
				
			||||||
            for (int j = i; j < filters.time_count - 1; j++) {
 | 
					            for (int j = i; j < filters.time_count - 1; j++) {
 | 
				
			||||||
@ -1702,13 +1920,13 @@ void menu_delete_filters() {
 | 
				
			|||||||
void menu_filter_mode() {
 | 
					void menu_filter_mode() {
 | 
				
			||||||
    printf("=== FILTER-MODUS ===\n");
 | 
					    printf("=== FILTER-MODUS ===\n");
 | 
				
			||||||
    printf("Aktueller Modus: %s\n", filters.combination_mode == 0 ? "AND" : "OR");
 | 
					    printf("Aktueller Modus: %s\n", filters.combination_mode == 0 ? "AND" : "OR");
 | 
				
			||||||
    printf("\nDieser Modus bestimmt:\n");
 | 
					    printf("\nACHTUNG:\n");
 | 
				
			||||||
    printf("1. Wie mehrere Filter desselben Typs kombiniert werden\n");
 | 
					    printf("Der Modus wirkt sich nur auf inklusive Filter aus.\n");
 | 
				
			||||||
    printf("2. Wie verschiedene Filter-Typen kombiniert werden\n");
 | 
					    printf("Die exklusiven Filter arbeiten immer im OR-Modus und \nschließen jeden Eintrag aus, der zu einem beliebigen Exklusions-Filter passt.\nExklusions-Filter haben immer Vorrang.\n");
 | 
				
			||||||
    printf("\nBeispiele:\n");
 | 
					    printf("\nAuswahl: \n");
 | 
				
			||||||
    printf("AND: IP=1.2.3.4 UND User-Agent=mozilla (beide müssen zutreffen)\n");
 | 
					    printf("1. AND-Modus\n");
 | 
				
			||||||
    printf("OR:  IP=1.2.3.4 ODER User-Agent=mozilla (einer muss zutreffen)\n");
 | 
					    printf("2. OR-Modus\n");
 | 
				
			||||||
    printf("Auswahl: ");
 | 
					    printf("3. Detaillierte Beispiele\n");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    int choice = read_safe_integer();
 | 
					    int choice = read_safe_integer();
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
@ -1718,6 +1936,8 @@ void menu_filter_mode() {
 | 
				
			|||||||
    } else if (choice == 2) {
 | 
					    } else if (choice == 2) {
 | 
				
			||||||
        filters.combination_mode = 1;
 | 
					        filters.combination_mode = 1;
 | 
				
			||||||
        printf("✅ Filter-Modus auf OR gesetzt.\n");
 | 
					        printf("✅ Filter-Modus auf OR gesetzt.\n");
 | 
				
			||||||
 | 
					    } else if (choice == 3) {
 | 
				
			||||||
 | 
					        print_filter_examples();        
 | 
				
			||||||
    } else if (choice != -1) {
 | 
					    } else if (choice != -1) {
 | 
				
			||||||
        printf("Ungültige Auswahl!\n");
 | 
					        printf("Ungültige Auswahl!\n");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -1729,6 +1949,7 @@ void menu_reset_filters() {
 | 
				
			|||||||
    filters.ip_count = 0;
 | 
					    filters.ip_count = 0;
 | 
				
			||||||
    filters.time_count = 0;
 | 
					    filters.time_count = 0;
 | 
				
			||||||
    filters.user_agent_count = 0;
 | 
					    filters.user_agent_count = 0;
 | 
				
			||||||
 | 
					    filters.url_count = 0;
 | 
				
			||||||
    filters.combination_mode = 0;
 | 
					    filters.combination_mode = 0;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    printf("✅ Alle Filter zurückgesetzt.\n");
 | 
					    printf("✅ Alle Filter zurückgesetzt.\n");
 | 
				
			||||||
@ -1738,12 +1959,13 @@ void menu_filter_management() {
 | 
				
			|||||||
    int choice = 0;
 | 
					    int choice = 0;
 | 
				
			||||||
    while (choice != 5) {
 | 
					    while (choice != 5) {
 | 
				
			||||||
        show_status();
 | 
					        show_status();
 | 
				
			||||||
        printf("\n=== FILTER VERWALTEN ===\n");
 | 
					        printf("\nFILTER VERWALTEN\n");
 | 
				
			||||||
        printf("1. Filter setzen\n");
 | 
					        printf("1. Filter setzen\n");
 | 
				
			||||||
        printf("2. Filter löschen\n");
 | 
					        printf("2. Filter löschen\n");
 | 
				
			||||||
        printf("3. Filter-Modus (AND/OR)\n");
 | 
					        printf("3. Filter-Modus (AND/OR)\n");
 | 
				
			||||||
        printf("4. Filter zurücksetzen\n");
 | 
					        printf("4. Filter zurücksetzen\n");
 | 
				
			||||||
        printf("5. Zurück zum Hauptmenü\n");
 | 
					        printf("5. Zeige Filter-Dokumentation\n");
 | 
				
			||||||
 | 
					        printf("6. Zurück zum Hauptmenü\n");
 | 
				
			||||||
        printf("Auswahl: ");
 | 
					        printf("Auswahl: ");
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        choice = read_safe_integer();
 | 
					        choice = read_safe_integer();
 | 
				
			||||||
@ -1757,9 +1979,11 @@ void menu_filter_management() {
 | 
				
			|||||||
        } else if (choice == 4) {
 | 
					        } else if (choice == 4) {
 | 
				
			||||||
            menu_reset_filters();
 | 
					            menu_reset_filters();
 | 
				
			||||||
        } else if (choice == 5) {
 | 
					        } else if (choice == 5) {
 | 
				
			||||||
 | 
					            print_filter_examples();
 | 
				
			||||||
 | 
					        } else if (choice == 6) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        } else if (choice != -1) {
 | 
					        } else if (choice != -1) {
 | 
				
			||||||
            printf("Ungültige Auswahl! Bitte wählen Sie 1-5.\n");
 | 
					            printf("Ungültige Auswahl! Bitte wählen Sie 1-6.\n");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1768,13 +1992,13 @@ void menu_show_entries() {
 | 
				
			|||||||
    int choice = 0;
 | 
					    int choice = 0;
 | 
				
			||||||
    while (choice != 4) {
 | 
					    while (choice != 4) {
 | 
				
			||||||
        show_status();
 | 
					        show_status();
 | 
				
			||||||
        printf("\n=== EINTRÄGE ANZEIGEN ===\n");
 | 
					        printf("\nANZEIGEN UND EXPORTIEREN\n");
 | 
				
			||||||
        int filtered_count = count_filtered_entries();
 | 
					        int filtered_count = count_filtered_entries();
 | 
				
			||||||
        printf("Aktuell %d gefilterte Einträge verfügbar.\n", filtered_count);
 | 
					        printf("Aktuell %d gefilterte Einträge verfügbar.\n", filtered_count);
 | 
				
			||||||
        printf("1. Vollständig anzeigen\n");
 | 
					        printf("1. Vollständig anzeigen\n");
 | 
				
			||||||
        printf("2. Zu .csv exportieren (Timesketch-kompatibel)\n");
 | 
					        printf("2. Zu .csv exportieren (Timesketch-kompatibel)\n");
 | 
				
			||||||
        printf("3. Top 10 IP-Adressen\n");
 | 
					        printf("3. Top %d IP-Adressen\n", TOP_X);
 | 
				
			||||||
        printf("4. Top 10 User-Agents\n");
 | 
					        printf("4. Top %d User-Agents\n", TOP_X);
 | 
				
			||||||
        printf("5. Zurück zum Hauptmenü\n");
 | 
					        printf("5. Zurück zum Hauptmenü\n");
 | 
				
			||||||
        printf("Auswahl: ");
 | 
					        printf("Auswahl: ");
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
@ -1794,7 +2018,7 @@ void menu_show_entries() {
 | 
				
			|||||||
        } else if (choice == 2) {
 | 
					        } else if (choice == 2) {
 | 
				
			||||||
            export_filtered_entries();
 | 
					            export_filtered_entries();
 | 
				
			||||||
        } else if (choice == 3) {
 | 
					        } else if (choice == 3) {
 | 
				
			||||||
            show_top_10_ips();
 | 
					            show_top_x_ips();
 | 
				
			||||||
        } else if (choice == 4) {
 | 
					        } else if (choice == 4) {
 | 
				
			||||||
            show_top_user_agents();
 | 
					            show_top_user_agents();
 | 
				
			||||||
        } else if (choice == 5) {
 | 
					        } else if (choice == 5) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user