Add nDPI protocol analyzer and integrate with handshake analysis
This commit is contained in:
121
protocol_analyzer.c
Normal file
121
protocol_analyzer.c
Normal file
@@ -0,0 +1,121 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pcap.h>
|
||||
#include <ndpi_api.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/udp.h>
|
||||
|
||||
struct ndpi_detection_module_struct *ndpi_struct = NULL;
|
||||
struct ndpi_flow_struct *ndpi_flow = NULL;
|
||||
struct ndpi_id_struct *src_id = NULL, *dst_id = NULL;
|
||||
|
||||
void init_ndpi() {
|
||||
NDPI_PROTOCOL_BITMASK all;
|
||||
|
||||
ndpi_struct = ndpi_init_detection_module();
|
||||
if (ndpi_struct == NULL) {
|
||||
printf("ERROR: ndpi_init_detection_module failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Enable all protocols
|
||||
NDPI_BITMASK_SET_ALL(all);
|
||||
ndpi_set_protocol_detection_bitmask2(ndpi_struct, &all);
|
||||
|
||||
ndpi_finalize_initialization(ndpi_struct);
|
||||
|
||||
// Allocate flow and ID structures
|
||||
ndpi_flow = calloc(1, NDPI_DETECTION_ONLY_IPV4_FLOW_SIZE);
|
||||
src_id = calloc(1, NDPI_ID_SIZE);
|
||||
dst_id = calloc(1, NDPI_ID_SIZE);
|
||||
}
|
||||
|
||||
void cleanup_ndpi() {
|
||||
if (ndpi_flow) free(ndpi_flow);
|
||||
if (src_id) free(src_id);
|
||||
if (dst_id) free(dst_id);
|
||||
if (ndpi_struct) ndpi_exit_detection_module(ndpi_struct);
|
||||
}
|
||||
|
||||
void analyze_packet_from_hex(const char* hex_data) {
|
||||
// Convert hex string to binary data
|
||||
size_t hex_len = strlen(hex_data);
|
||||
if (hex_len % 2 != 0) {
|
||||
printf("ERROR: Invalid hex data length\n");
|
||||
return;
|
||||
}
|
||||
|
||||
size_t bin_len = hex_len / 2;
|
||||
unsigned char *packet_data = malloc(bin_len);
|
||||
|
||||
for (size_t i = 0; i < bin_len; i++) {
|
||||
sscanf(hex_data + 2*i, "%2hhx", &packet_data[i]);
|
||||
}
|
||||
|
||||
// Basic IP header parsing
|
||||
struct iphdr *ip_header = (struct iphdr*)packet_data;
|
||||
if (bin_len < sizeof(struct iphdr) || ip_header->version != 4) {
|
||||
printf("ERROR: Not a valid IPv4 packet\n");
|
||||
free(packet_data);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t src_ip = ntohl(ip_header->saddr);
|
||||
uint32_t dst_ip = ntohl(ip_header->daddr);
|
||||
uint16_t src_port = 0, dst_port = 0;
|
||||
|
||||
// Extract ports for TCP/UDP
|
||||
if (ip_header->protocol == IPPROTO_TCP) {
|
||||
struct tcphdr *tcp_header = (struct tcphdr*)(packet_data + (ip_header->ihl * 4));
|
||||
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));
|
||||
src_port = ntohs(udp_header->source);
|
||||
dst_port = ntohs(udp_header->dest);
|
||||
}
|
||||
|
||||
// Reset flow for new analysis
|
||||
memset(ndpi_flow, 0, NDPI_DETECTION_ONLY_IPV4_FLOW_SIZE);
|
||||
|
||||
// Perform nDPI detection
|
||||
ndpi_protocol protocol = ndpi_detection_process_packet(
|
||||
ndpi_struct, ndpi_flow, packet_data, bin_len,
|
||||
0, /* timestamp */
|
||||
src_id, dst_id
|
||||
);
|
||||
|
||||
// Output results in JSON format for easy parsing
|
||||
printf("{\n");
|
||||
printf(" \"src_ip\": \"%u.%u.%u.%u\",\n",
|
||||
(src_ip >> 24) & 0xFF, (src_ip >> 16) & 0xFF,
|
||||
(src_ip >> 8) & 0xFF, src_ip & 0xFF);
|
||||
printf(" \"dst_ip\": \"%u.%u.%u.%u\",\n",
|
||||
(dst_ip >> 24) & 0xFF, (dst_ip >> 16) & 0xFF,
|
||||
(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(" \"confidence\": %u\n", protocol.confidence);
|
||||
printf("}\n");
|
||||
|
||||
free(packet_data);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s <hex_packet_data>\n", argv[0]);
|
||||
printf("Example: %s \"4500003c...\"\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
init_ndpi();
|
||||
analyze_packet_from_hex(argv[1]);
|
||||
cleanup_ndpi();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user