diff --git a/protocol_analyzer.c b/protocol_analyzer.c index 9b83957..6d9b948 100644 --- a/protocol_analyzer.c +++ b/protocol_analyzer.c @@ -57,33 +57,75 @@ void analyze_packet_from_hex(const char* hex_data) { uint32_t src_ip = ntohl(ip_header->saddr); uint32_t dst_ip = ntohl(ip_header->daddr); uint16_t src_port = 0, dst_port = 0; + uint8_t protocol_type = ip_header->protocol; - // Extract ports for TCP/UDP - if (ip_header->protocol == IPPROTO_TCP) { - struct tcphdr *tcp_header = (struct tcphdr*)(packet_data + (ip_header->ihl * 4)); + // Extract ports and payload + unsigned char *payload = NULL; + size_t payload_len = 0; + size_t header_len = ip_header->ihl * 4; + + if (protocol_type == IPPROTO_TCP) { + if (bin_len < header_len + sizeof(struct tcphdr)) { + printf("ERROR: Incomplete TCP packet\n"); + free(packet_data); + return; + } + struct tcphdr *tcp_header = (struct tcphdr*)(packet_data + header_len); src_port = ntohs(tcp_header->source); dst_port = ntohs(tcp_header->dest); - } else if (ip_header->protocol == IPPROTO_UDP) { - struct udphdr *udp_header = (struct udphdr*)(packet_data + (ip_header->ihl * 4)); + + size_t tcp_header_len = tcp_header->doff * 4; + if (bin_len > header_len + tcp_header_len) { + payload = packet_data + header_len + tcp_header_len; + payload_len = bin_len - header_len - tcp_header_len; + } + } else if (protocol_type == IPPROTO_UDP) { + if (bin_len < header_len + sizeof(struct udphdr)) { + printf("ERROR: Incomplete UDP packet\n"); + free(packet_data); + return; + } + struct udphdr *udp_header = (struct udphdr*)(packet_data + header_len); src_port = ntohs(udp_header->source); dst_port = ntohs(udp_header->dest); + + if (bin_len > header_len + sizeof(struct udphdr)) { + payload = packet_data + header_len + sizeof(struct udphdr); + payload_len = bin_len - header_len - sizeof(struct udphdr); + } } - // Reset flow for new analysis - memset(ndpi_flow, 0, ndpi_detection_get_sizeof_ndpi_flow_struct()); + // Manual protocol detection on payload + char *detected_protocol = "Unknown"; + char *detected_category = "Unspecified"; - // Create flow input info - struct ndpi_flow_input_info input_info; - memset(&input_info, 0, sizeof(input_info)); + if (payload && payload_len > 0) { + // BitTorrent detection - look for protocol handshake + if (payload_len >= 20 && payload[0] == 19 && + memcmp(payload + 1, "BitTorrent protocol", 19) == 0) { + detected_protocol = "BitTorrent"; + detected_category = "P2P"; + } + // HTTP detection + else if (payload_len >= 4 && (memcmp(payload, "GET ", 4) == 0 || + memcmp(payload, "POST", 4) == 0 || + memcmp(payload, "HTTP", 4) == 0)) { + detected_protocol = "HTTP"; + detected_category = "Web"; + } + // TLS detection - look for TLS handshake + else if (payload_len >= 6 && payload[0] == 0x16 && payload[1] == 0x03) { + detected_protocol = "TLS"; + detected_category = "Web"; + } + // SSH detection + else if (payload_len >= 4 && memcmp(payload, "SSH-", 4) == 0) { + detected_protocol = "SSH"; + detected_category = "RemoteAccess"; + } + } - // Perform nDPI detection - ndpi_protocol protocol = ndpi_detection_process_packet( - ndpi_struct, ndpi_flow, packet_data, bin_len, - 0, /* timestamp */ - &input_info - ); - - // Output results in JSON format for easy parsing + // Output results printf("{\n"); printf(" \"src_ip\": \"%u.%u.%u.%u\",\n", (src_ip >> 24) & 0xFF, (src_ip >> 16) & 0xFF, @@ -93,8 +135,9 @@ void analyze_packet_from_hex(const char* hex_data) { (dst_ip >> 8) & 0xFF, dst_ip & 0xFF); printf(" \"src_port\": %u,\n", src_port); printf(" \"dst_port\": %u,\n", dst_port); - printf(" \"protocol\": \"%s\",\n", ndpi_protocol2name(ndpi_struct, protocol, NULL, 0)); - printf(" \"category\": \"%s\"\n", ndpi_category_get_name(ndpi_struct, protocol.category)); + printf(" \"protocol\": \"%s\",\n", detected_protocol); + printf(" \"category\": \"%s\",\n", detected_category); + printf(" \"payload_len\": %zu\n", payload_len); printf("}\n"); free(packet_data);