diff options
-rw-r--r-- | example/ndpiReader.c | 17 | ||||
-rw-r--r-- | example/ndpi_util.c | 260 | ||||
-rw-r--r-- | libndpi.sym | 7 | ||||
-rw-r--r-- | src/include/ndpi_api.h | 56 | ||||
-rw-r--r-- | src/lib/ndpi_content_match.c.inc | 1 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 47 | ||||
-rw-r--r-- | src/lib/protocols/dns.c | 3 |
7 files changed, 256 insertions, 135 deletions
diff --git a/example/ndpiReader.c b/example/ndpiReader.c index 168bd7b15..618f10524 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -2,6 +2,7 @@ * ndpiReader.c * * Copyright (C) 2011-16 - ntop.org + * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or @@ -40,7 +41,7 @@ #include <signal.h> #include <pthread.h> #include <sys/socket.h> - +#include <assert.h> #include "../config.h" #include "ndpi_api.h" @@ -1302,6 +1303,18 @@ void test_lib() { } } +void automataUnitTest() { + void *automa; + + set_ndpi_malloc(malloc_wrapper), set_ndpi_free(free_wrapper); + assert(automa = ndpi_init_automa()); + assert(ndpi_add_string_to_automa(automa, "hello") == 0); + assert(ndpi_add_string_to_automa(automa, "world") == 0); + ndpi_finalize_automa(automa); + assert(ndpi_match_string(automa, "This is the wonderful world of nDPI") == 0); + + ndpi_free_automa(automa); +} /** @brief MAIN FUNCTION @@ -1310,6 +1323,8 @@ int main(int argc, char **argv) { int i; + automataUnitTest(); + memset(ndpi_thread_info, 0, sizeof(ndpi_thread_info)); memset(&pcap_start, 0, sizeof(pcap_start)); memset(&pcap_end, 0, sizeof(pcap_end)); diff --git a/example/ndpi_util.c b/example/ndpi_util.c index 6a31b5d66..e1135f5d5 100644 --- a/example/ndpi_util.c +++ b/example/ndpi_util.c @@ -86,14 +86,14 @@ static const u_int8_t nDPI_traceLevel = 0; static void (*removeme_free_wrapper)(void*); struct ndpi_workflow * ndpi_workflow_init(const struct ndpi_workflow_prefs * prefs, - pcap_t * pcap_handle, - void * (*malloc_wrapper)(size_t), - void (*free_wrapper)(void*), - ndpi_debug_function_ptr ndpi_debug_printf) { - + pcap_t * pcap_handle, + void * (*malloc_wrapper)(size_t), + void (*free_wrapper)(void*), + ndpi_debug_function_ptr ndpi_debug_printf) { + /* TODO: just needed here to init ndpi malloc wrapper */ - struct ndpi_detection_module_struct * module = ndpi_init_detection_module( - prefs->detection_tick_resolution, malloc_wrapper, free_wrapper, ndpi_debug_printf); + struct ndpi_detection_module_struct * module = ndpi_init_detection_module(prefs->detection_tick_resolution, + malloc_wrapper, free_wrapper, ndpi_debug_printf); struct ndpi_workflow * workflow = ndpi_calloc(1, sizeof(struct ndpi_workflow)); @@ -153,22 +153,22 @@ int ndpi_workflow_node_cmp(const void *a, const void *b) { /* ***************************************************** */ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow, - const u_int8_t version, - u_int16_t vlan_id, - const struct ndpi_iphdr *iph, - const struct ndpi_ipv6hdr *iph6, - u_int16_t ip_offset, - u_int16_t ipsize, - u_int16_t l4_packet_len, - struct ndpi_tcphdr **tcph, - struct ndpi_udphdr **udph, - u_int16_t *sport, u_int16_t *dport, - struct ndpi_id_struct **src, - struct ndpi_id_struct **dst, - u_int8_t *proto, - u_int8_t **payload, - u_int16_t *payload_len, - u_int8_t *src_to_dst_direction) { + const u_int8_t version, + u_int16_t vlan_id, + const struct ndpi_iphdr *iph, + const struct ndpi_ipv6hdr *iph6, + u_int16_t ip_offset, + u_int16_t ipsize, + u_int16_t l4_packet_len, + struct ndpi_tcphdr **tcph, + struct ndpi_udphdr **udph, + u_int16_t *sport, u_int16_t *dport, + struct ndpi_id_struct **src, + struct ndpi_id_struct **dst, + u_int8_t *proto, + u_int8_t **payload, + u_int16_t *payload_len, + u_int8_t *src_to_dst_direction) { u_int32_t idx, l4_offset; u_int32_t lower_ip; u_int32_t upper_ip; @@ -294,7 +294,7 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow if(0) NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_DEBUG, "[NDPI] [%u][%u:%u <-> %u:%u]\n", - iph->protocol, lower_ip, ntohs(lower_port), upper_ip, ntohs(upper_port)); + iph->protocol, lower_ip, ntohs(lower_port), upper_ip, ntohs(upper_port)); idx = (vlan_id + lower_ip + upper_ip + iph->protocol + lower_port + upper_port) % workflow->prefs.num_roots; ret = ndpi_tfind(&flow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp); @@ -369,18 +369,18 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow /* ****************************************************** */ static struct ndpi_flow_info *get_ndpi_flow_info6(struct ndpi_workflow * workflow, - u_int16_t vlan_id, - const struct ndpi_ipv6hdr *iph6, - u_int16_t ip_offset, - struct ndpi_tcphdr **tcph, - struct ndpi_udphdr **udph, - u_int16_t *sport, u_int16_t *dport, - struct ndpi_id_struct **src, - struct ndpi_id_struct **dst, - u_int8_t *proto, - u_int8_t **payload, - u_int16_t *payload_len, - u_int8_t *src_to_dst_direction) { + u_int16_t vlan_id, + const struct ndpi_ipv6hdr *iph6, + u_int16_t ip_offset, + struct ndpi_tcphdr **tcph, + struct ndpi_udphdr **udph, + u_int16_t *sport, u_int16_t *dport, + struct ndpi_id_struct **src, + struct ndpi_id_struct **dst, + u_int8_t *proto, + u_int8_t **payload, + u_int16_t *payload_len, + u_int8_t *src_to_dst_direction) { struct ndpi_iphdr iph; memset(&iph, 0, sizeof(iph)); @@ -396,22 +396,22 @@ static struct ndpi_flow_info *get_ndpi_flow_info6(struct ndpi_workflow * workflo } return(get_ndpi_flow_info(workflow, 6, vlan_id, &iph, iph6, ip_offset, - sizeof(struct ndpi_ipv6hdr), - ntohs(iph6->ip6_ctlun.ip6_un1.ip6_un1_plen), - tcph, udph, sport, dport, - src, dst, proto, payload, payload_len, src_to_dst_direction)); + sizeof(struct ndpi_ipv6hdr), + ntohs(iph6->ip6_ctlun.ip6_un1.ip6_un1_plen), + tcph, udph, sport, dport, + src, dst, proto, payload, payload_len, src_to_dst_direction)); } /* ****************************************************** */ // ipsize = header->len - ip_offset ; rawsize = header->len static unsigned int packet_processing(struct ndpi_workflow * workflow, - const u_int64_t time, - u_int16_t vlan_id, - const struct ndpi_iphdr *iph, - struct ndpi_ipv6hdr *iph6, - u_int16_t ip_offset, - u_int16_t ipsize, u_int16_t rawsize) { + const u_int64_t time, + u_int16_t vlan_id, + const struct ndpi_iphdr *iph, + struct ndpi_ipv6hdr *iph6, + u_int16_t ip_offset, + u_int16_t ipsize, u_int16_t rawsize) { struct ndpi_id_struct *src, *dst; struct ndpi_flow_info *flow; struct ndpi_flow_struct *ndpi_flow = NULL; @@ -424,16 +424,16 @@ static unsigned int packet_processing(struct ndpi_workflow * workflow, if(iph) flow = get_ndpi_flow_info(workflow, 4, vlan_id, iph, NULL, - ip_offset, ipsize, - ntohs(iph->tot_len) - (iph->ihl * 4), - &tcph, &udph, &sport, &dport, - &src, &dst, &proto, - &payload, &payload_len, &src_to_dst_direction); + ip_offset, ipsize, + ntohs(iph->tot_len) - (iph->ihl * 4), + &tcph, &udph, &sport, &dport, + &src, &dst, &proto, + &payload, &payload_len, &src_to_dst_direction); else flow = get_ndpi_flow_info6(workflow, vlan_id, iph6, ip_offset, - &tcph, &udph, &sport, &dport, - &src, &dst, &proto, - &payload, &payload_len, &src_to_dst_direction); + &tcph, &udph, &sport, &dport, + &src, &dst, &proto, + &payload, &payload_len, &src_to_dst_direction); if(flow != NULL) { workflow->stats.ip_packet_count++; @@ -497,8 +497,8 @@ static unsigned int packet_processing(struct ndpi_workflow * workflow, /* ****************************************************** */ void ndpi_workflow_process_packet (struct ndpi_workflow * workflow, - const struct pcap_pkthdr *header, - const u_char *packet) { + const struct pcap_pkthdr *header, + const u_char *packet) { /* * Declare pointers to packet headers */ @@ -569,97 +569,97 @@ void ndpi_workflow_process_packet (struct ndpi_workflow * workflow, datalink_check: switch(datalink_type) { - case DLT_NULL : - if(ntohl(*((u_int32_t*)&packet[eth_offset])) == 2) - type = ETH_P_IP; - else - type = ETH_P_IPV6; - - ip_offset = 4 + eth_offset; - - /* Cisco PPP in HDLC-like framing - 50 */ - case DLT_PPP_SERIAL: - chdlc = (struct ndpi_chdlc *) &packet[eth_offset]; - ip_offset = sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */ - type = ntohs(chdlc->proto_code); - break; + case DLT_NULL : + if(ntohl(*((u_int32_t*)&packet[eth_offset])) == 2) + type = ETH_P_IP; + else + type = ETH_P_IPV6; - /* Cisco PPP with HDLC framing - 104 */ - case DLT_C_HDLC: - chdlc = (struct ndpi_chdlc *) &packet[eth_offset]; - ip_offset = sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */ - type = ntohs(chdlc->proto_code); - break; + ip_offset = 4 + eth_offset; - /* IEEE 802.3 Ethernet - 1 */ - case DLT_EN10MB : - ethernet = (struct ndpi_ethhdr *) &packet[eth_offset]; - ip_offset = sizeof(struct ndpi_ethhdr) + eth_offset; - check = ntohs(ethernet->h_proto); + /* Cisco PPP in HDLC-like framing - 50 */ + case DLT_PPP_SERIAL: + chdlc = (struct ndpi_chdlc *) &packet[eth_offset]; + ip_offset = sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */ + type = ntohs(chdlc->proto_code); + break; + + /* Cisco PPP with HDLC framing - 104 */ + case DLT_C_HDLC: + chdlc = (struct ndpi_chdlc *) &packet[eth_offset]; + ip_offset = sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */ + type = ntohs(chdlc->proto_code); + break; - if(check <= 1500) - pyld_eth_len = check; - else if (check >= 1536) - type = check; + /* IEEE 802.3 Ethernet - 1 */ + case DLT_EN10MB : + ethernet = (struct ndpi_ethhdr *) &packet[eth_offset]; + ip_offset = sizeof(struct ndpi_ethhdr) + eth_offset; + check = ntohs(ethernet->h_proto); - if(pyld_eth_len != 0) { + if(check <= 1500) + pyld_eth_len = check; + else if (check >= 1536) + type = check; + + if(pyld_eth_len != 0) { /* check for LLC layer with SNAP extension */ - if(packet[ip_offset] == SNAP) { - llc = (struct ndpi_llc_header *)(&packet[ip_offset]); - type = llc->snap.proto_ID; - ip_offset += + 8; - } + if(packet[ip_offset] == SNAP) { + llc = (struct ndpi_llc_header *)(&packet[ip_offset]); + type = llc->snap.proto_ID; + ip_offset += + 8; } - break; + } + break; - /* Linux Cooked Capture - 113 */ - case DLT_LINUX_SLL : - type = (packet[eth_offset+14] << 8) + packet[eth_offset+15]; - ip_offset = 16 + eth_offset; - break; + /* Linux Cooked Capture - 113 */ + case DLT_LINUX_SLL : + type = (packet[eth_offset+14] << 8) + packet[eth_offset+15]; + ip_offset = 16 + eth_offset; + break; - /* Radiotap link-layer - 127 */ - case DLT_IEEE802_11_RADIO : - radiotap = (struct ndpi_radiotap_header *) &packet[eth_offset]; - radio_len = radiotap->len; + /* Radiotap link-layer - 127 */ + case DLT_IEEE802_11_RADIO : + radiotap = (struct ndpi_radiotap_header *) &packet[eth_offset]; + radio_len = radiotap->len; - /* Check Bad FCS presence */ - if((radiotap->flags & BAD_FCS) == BAD_FCS) { - workflow->stats.total_discarded_bytes += header->len; - return; - } + /* Check Bad FCS presence */ + if((radiotap->flags & BAD_FCS) == BAD_FCS) { + workflow->stats.total_discarded_bytes += header->len; + return; + } - fcs = header->len - 4; + fcs = header->len - 4; - /* Calculate 802.11 header length (variable) */ - wifi = (struct ndpi_wifi_header*)( packet + eth_offset + radio_len); - fc = wifi->fc; + /* Calculate 802.11 header length (variable) */ + wifi = (struct ndpi_wifi_header*)( packet + eth_offset + radio_len); + fc = wifi->fc; - /* check wifi data presence */ - if(FCF_TYPE(fc) == WIFI_DATA) { - if((FCF_TO_DS(fc) && FCF_FROM_DS(fc) == 0x0) || - (FCF_TO_DS(fc) == 0x0 && FCF_FROM_DS(fc))) - wifi_len = 26; /* + 4 byte fcs */ - } else /* no data frames */ - break; + /* check wifi data presence */ + if(FCF_TYPE(fc) == WIFI_DATA) { + if((FCF_TO_DS(fc) && FCF_FROM_DS(fc) == 0x0) || + (FCF_TO_DS(fc) == 0x0 && FCF_FROM_DS(fc))) + wifi_len = 26; /* + 4 byte fcs */ + } else /* no data frames */ + break; - /* Check ether_type from LLC */ - llc = (struct ndpi_llc_header*)(packet + eth_offset + wifi_len + radio_len); - if(llc->dsap == SNAP) - type = ntohs(llc->snap.proto_ID); + /* Check ether_type from LLC */ + llc = (struct ndpi_llc_header*)(packet + eth_offset + wifi_len + radio_len); + if(llc->dsap == SNAP) + type = ntohs(llc->snap.proto_ID); - /* Set IP header offset */ - ip_offset = wifi_len + radio_len + sizeof(struct ndpi_llc_header) + eth_offset; - break; + /* Set IP header offset */ + ip_offset = wifi_len + radio_len + sizeof(struct ndpi_llc_header) + eth_offset; + break; case DLT_RAW: ip_offset = eth_offset = 0; break; - default: - /* printf("Unknown datalink %d\n", datalink_type); */ - return; - } + default: + /* printf("Unknown datalink %d\n", datalink_type); */ + return; + } /* check ether type */ if(type == VLAN) { @@ -705,7 +705,7 @@ void ndpi_workflow_process_packet (struct ndpi_workflow * workflow, if(cap_warning_used == 0) { if(!workflow->prefs.quiet_mode) - NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_DEBUG, "\n\nWARNING: packet capture size is smaller than packet size, DETECTION MIGHT NOT WORK CORRECTLY\n\n"); + NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_DEBUG, "\n\nWARNING: packet capture size is smaller than packet size, DETECTION MIGHT NOT WORK CORRECTLY\n\n"); cap_warning_used = 1; } } @@ -726,7 +726,7 @@ void ndpi_workflow_process_packet (struct ndpi_workflow * workflow, if(ipv4_frags_warning_used == 0) { if(!workflow->prefs.quiet_mode) - NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_DEBUG, "\n\nWARNING: IPv4 fragments are not handled by this demo (nDPI supports them)\n"); + NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_DEBUG, "\n\nWARNING: IPv4 fragments are not handled by this demo (nDPI supports them)\n"); ipv4_frags_warning_used = 1; } diff --git a/libndpi.sym b/libndpi.sym index 7fd2f920d..2302bfa57 100644 --- a/libndpi.sym +++ b/libndpi.sym @@ -36,3 +36,10 @@ ndpi_malloc ndpi_calloc ndpi_set_detected_protocol ndpi_match_string_subprotocol +ndpi_init_automa +ndpi_free_automa +ndpi_add_string_to_automa +ndpi_finalize_automa +ndpi_match_string +set_ndpi_malloc +set_ndpi_free diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h index a07c96e63..113aa0ea2 100644 --- a/src/include/ndpi_api.h +++ b/src/include/ndpi_api.h @@ -544,6 +544,62 @@ extern "C" { struct ndpi_flow_struct *flow, char *certificate); #endif + /* Wrappers functions */ + /** + * Init Aho-Corasick automata + * + * @return The requested automata, or NULL if an error occurred + * + */ + void* ndpi_init_automa(); + + + /** + * Free Aho-Corasick automata allocated with ndpi_init_automa(); + * + * @par The automata initialized with ndpi_init_automa(); + * @return The requested automata, or NULL if an error occurred + * + */ + void ndpi_free_automa(void *_automa); + + + /** + * Add a string to match to an automata + * + * @par The automata initialized with ndpi_init_automa(); + * @par The (sub)string to search + * @return 0 in case of no error, or -1 if an error occurred. + * + */ + int ndpi_add_string_to_automa(void *_automa, char *str); + + + /** + * Finalize the automa (necessary before start searching) + * + * @par The automata initialized with ndpi_init_automa(); + * + */ + void ndpi_finalize_automa(void *_automa); + + + /** + * Add a string to match to an automata + * + * @par The automata initialized with ndpi_init_automa(); + * @par The (sub)string to search + * @return 0 in case of match, or -1 if no match, or -2 if an error occurred. + * + */ + int ndpi_match_string(void *_automa, char *string_to_match); + + + + /* Utility functions to set ndpi malloc/free wrappers */ + void set_ndpi_malloc(void* (*__ndpi_malloc)(size_t size)); + void set_ndpi_free(void (*__ndpi_free)(void *ptr)); + #ifdef __cplusplus } #endif diff --git a/src/lib/ndpi_content_match.c.inc b/src/lib/ndpi_content_match.c.inc index 458ab1a7a..af6215842 100644 --- a/src/lib/ndpi_content_match.c.inc +++ b/src/lib/ndpi_content_match.c.inc @@ -7533,3 +7533,4 @@ static const char *ndpi_en_impossible_bigrams[] = { "yj", "yq", "yv", "yz", "yw", "zb", "zc", "zg", "zh", "zj", "zn", "zq", "zr", "zs", "zx", "wh", "wk", "wb", "zk", "kp", "zk", "xy", NULL }; + diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 9e8c75c8f..dcc5d8705 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -1681,6 +1681,9 @@ static int ndpi_add_host_ip_subprotocol(struct ndpi_detection_module_struct *ndp #endif +void set_ndpi_malloc(void* (*__ndpi_malloc)(size_t size)) { _ndpi_malloc = __ndpi_malloc; } +void set_ndpi_free(void (*__ndpi_free)(void *ptr)) { _ndpi_free = __ndpi_free; } + /* ******************************************************************** */ struct ndpi_detection_module_struct *ndpi_init_detection_module(u_int32_t ticks_per_second, @@ -1691,8 +1694,7 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(u_int32_t ticks_ struct ndpi_detection_module_struct *ndpi_str; /* TODO global malloc wrappers should not be set here: ndpi_init_detection_module can be called many times */ - _ndpi_malloc = __ndpi_malloc; - _ndpi_free = __ndpi_free; + set_ndpi_malloc(__ndpi_malloc), set_ndpi_free(__ndpi_free); ndpi_str = ndpi_malloc(sizeof(struct ndpi_detection_module_struct)); @@ -1746,6 +1748,47 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(u_int32_t ticks_ /* *********************************************** */ +/* Wrappers */ +void* ndpi_init_automa() { + return(ac_automata_init(ac_match_handler)); +} + +int ndpi_add_string_to_automa(void *_automa, char *str) { + AC_PATTERN_t ac_pattern; + AC_AUTOMATA_t *automa = (AC_AUTOMATA_t*)_automa; + + if(automa == NULL) return(-1); + + ac_pattern.astring = str; + ac_pattern.rep.number = 1; /* Dummy */ + ac_pattern.length = strlen(ac_pattern.astring); + return(ac_automata_add(automa, &ac_pattern) == ACERR_SUCCESS ? 0 : -1); +} + +void ndpi_free_automa(void *_automa) { ac_automata_release((AC_AUTOMATA_t*)_automa); } +void ndpi_finalize_automa(void *_automa) { ac_automata_finalize((AC_AUTOMATA_t*)_automa); } + +/* ****************************************************** */ + +int ndpi_match_string(void *_automa, char *string_to_match) { + int matching_protocol_id = NDPI_PROTOCOL_UNKNOWN; + AC_TEXT_t ac_input_text; + AC_AUTOMATA_t *automa = (AC_AUTOMATA_t*)_automa; + + if((automa == NULL) + || (string_to_match == NULL) + || (string_to_match[0] == '\0')) + return(-2); + + ac_input_text.astring = string_to_match, ac_input_text.length = strlen(string_to_match); + ac_automata_search(automa, &ac_input_text, (void*)&matching_protocol_id); + ac_automata_reset(automa); + + return(matching_protocol_id > 0 ? 0 : -1); +} + +/* *********************************************** */ + static void free_ptree_data(void *data) { ; } /* ****************************************************** */ diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c index 503761137..c54c62f18 100644 --- a/src/lib/protocols/dns.c +++ b/src/lib/protocols/dns.c @@ -117,8 +117,7 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd if(off < flow->packet.payload_packet_len) { flow->host_server_name[j] = flow->packet.payload[off]; - if(j < strlen(flow->host_server_name)) - { + if(j < strlen((char*)flow->host_server_name)) { if(flow->host_server_name[j] < ' ') flow->host_server_name[j] = '.'; j++; |