diff options
-rw-r--r-- | example/protos.txt | 8 | ||||
-rw-r--r-- | src/include/ndpi_typedefs.h | 1 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 50 | ||||
-rw-r--r-- | tests/result/h323-overflow.pcap.out | 14 |
4 files changed, 58 insertions, 15 deletions
diff --git a/example/protos.txt b/example/protos.txt index 7f47009bd..b03c4efd5 100644 --- a/example/protos.txt +++ b/example/protos.txt @@ -6,6 +6,14 @@ udp:5061-5062@SIP tcp:860,udp:860,tcp:3260,udp:3260@iSCSI tcp:3000@ntop +# +# nBPF filters (https://github.com/ntop/PF_RING/tree/dev/userland/nbpf)) +# +# NOTE: they are evaluated in the same order they are defined ! +# +nbpf:"host 192.168.1.1 and port 80"@HomeRouter + + # Subprotocols # Format: # host:"<value>",host:"<value>",.....@<subproto> diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index f9550496c..18a53911d 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1240,6 +1240,7 @@ struct ndpi_detection_module_struct { const struct ndpi_flow_input_info *input_info; #ifdef HAVE_NBPF + u_int8_t num_nbpf_custom_proto; nbpf_filter nbpf_custom_proto[MAX_NBPF_CUSTOM_PROTO]; #endif }; diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index f03f19c7b..d963b563f 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -3103,6 +3103,9 @@ void ndpi_exit_detection_module(struct ndpi_detection_module_struct *ndpi_str) { ndpi_free(ndpi_str->proto_defaults[i].subprotocols); } + for(i = 0; (i < MAX_NBPF_CUSTOM_PROTO) && (ndpi_str->nbpf_custom_proto[i].tree != NULL); i++) + nbpf_free(ndpi_str->nbpf_custom_proto[i].tree); + /* NDPI_PROTOCOL_TINC */ if(ndpi_str->tinc_cache) cache_free((cache_t)(ndpi_str->tinc_cache)); @@ -3617,6 +3620,37 @@ int ndpi_handle_rule(struct ndpi_detection_module_struct *ndpi_str, char *rule, value[max_len] = '\0'; /* remove trailing " */ for(i=0; i<max_len; i++) value[i] = tolower(value[i]); + } else if(strncmp(attr, "nbpf:", 5) == 0) { +#ifdef HAVE_NBPF + char *filter = &attr[5]; + + if(ndpi_str->num_nbpf_custom_proto >= MAX_NBPF_CUSTOM_PROTO) { + NDPI_LOG_ERR(ndpi_str, "nBPF: too many protocols"); + return(-4); /* Too many protocols */ + } + + if(filter[0] == '"') { + u_int len; + + filter = &filter[1]; + len = strlen(filter); + + if(len > 0) + filter[len-1] = '\0'; + } + + if((ndpi_str->nbpf_custom_proto[ndpi_str->num_nbpf_custom_proto].tree = + nbpf_parse(filter, NULL)) == NULL) { + NDPI_LOG_ERR(ndpi_str, "nBPF invalid filter: %s", filter) + return(-5); /* Invalid filter */ + } else + ndpi_str->nbpf_custom_proto[ndpi_str->num_nbpf_custom_proto].l7_protocol = subprotocol_id; + + ndpi_str->num_nbpf_custom_proto++; +#else + NDPI_LOG_ERR(ndpi_str, "nDPI compiled without nBPF support: skipping rule"); + return(-6); +#endif } if(is_tcp || is_udp) { @@ -3900,6 +3934,9 @@ int ndpi_load_malicious_sha1_file(struct ndpi_detection_module_struct *ndpi_str, IP based Subprotocols Format (<value> is IP or CIDR): ip:<value>,ip:<value>,.....@<subproto> + nBPF-based Filters + nbpf:"<nBPF filter>@<proto> + Example: tcp:80,tcp:3128@HTTP udp:139@NETBIOS @@ -6262,12 +6299,6 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct #ifdef HAVE_NBPF if((flow->num_processed_pkts == 1) /* first packet of this flow to be analyzed */ && (ndpi_str->nbpf_custom_proto[0].tree != NULL)) { -#if 0 - const char *filter = "tcp and port 80"; - nbpf_tree_t *tree = nbpf_parse(filter, NULL); - - nbpf_free(tree); -#endif u_int8_t i; nbpf_pkt_info_t t; @@ -6286,9 +6317,12 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct } t.tuple.l3_proto = flow->l4_proto; - t.tuple.l4_src_port = packet->tcp ? packet->tcp->source : packet->udp->source; - t.tuple.l4_dst_port = packet->tcp ? packet->tcp->dest : packet->udp->dest; + if(packet->tcp) + t.tuple.l4_src_port = packet->tcp->source, t.tuple.l4_dst_port = packet->tcp->dest; + else if(packet->udp) + t.tuple.l4_src_port = packet->udp->source, t.tuple.l4_dst_port = packet->udp->dest; + for(i=0; (i<MAX_NBPF_CUSTOM_PROTO) && (ndpi_str->nbpf_custom_proto[i].tree != NULL); i++) { if(nbpf_match(ndpi_str->nbpf_custom_proto[i].tree, &t)) { /* match found */ diff --git a/tests/result/h323-overflow.pcap.out b/tests/result/h323-overflow.pcap.out index f2a8e0bb8..4d0287b16 100644 --- a/tests/result/h323-overflow.pcap.out +++ b/tests/result/h323-overflow.pcap.out @@ -1,8 +1,8 @@ -Guessed flow protos: 1 +Guessed flow protos: 0 DPI Packets (TCP): 1 (1.00 pkts/flow) -Confidence Match by port : 1 (flows) -Num dissector calls: 126 (126.00 diss/flow) +Confidence nBPF : 1 (flows) +Num dissector calls: 0 (0.00 diss/flow) LRU cache ookla: 0/0/0 (insert/search/found) LRU cache bittorrent: 0/0/0 (insert/search/found) LRU cache zoom: 0/0/0 (insert/search/found) @@ -15,10 +15,10 @@ Automa domain: 0/0 (search/found) Automa tls cert: 0/0 (search/found) Automa risk mask: 0/0 (search/found) Automa common alpns: 0/0 (search/found) -Patricia risk mask: 2/0 (search/found) +Patricia risk mask: 0/0 (search/found) Patricia risk: 0/0 (search/found) -Patricia protocols: 2/0 (search/found) +Patricia protocols: 0/0 (search/found) -HTTP 1 58 1 +HomeRouter 1 58 1 - 1 TCP 192.168.1.1:31337 -> 192.168.1.2:80 [proto: 7/HTTP][IP: 0/Unknown][ClearText][Confidence: Match by port][cat: Web/5][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 7/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + 1 TCP 192.168.1.1:31337 -> 192.168.1.2:80 [proto: 316/HomeRouter][IP: 0/Unknown][ClearText][Confidence: nBPF][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 7/0][< 1 sec][Plen Bins: 100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] |