summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dependencies/nDPIsrvd.py4
-rwxr-xr-xexamples/py-flow-info/flow-info.py1
-rwxr-xr-xexamples/py-flow-undetected-to-pcap/flow-undetected-to-pcap.py1
-rwxr-xr-xexamples/py-json-stdout/json-stdout.py1
-rwxr-xr-xexamples/py-risky-flow-to-pcap/risky-flow-to-pcap.py1
-rwxr-xr-xexamples/py-schema-validation/py-schema-validation.py1
-rw-r--r--nDPId.c410
-rwxr-xr-xtest/run_tests.sh19
8 files changed, 285 insertions, 153 deletions
diff --git a/dependencies/nDPIsrvd.py b/dependencies/nDPIsrvd.py
index d8cccc266..643a1a7e5 100644
--- a/dependencies/nDPIsrvd.py
+++ b/dependencies/nDPIsrvd.py
@@ -349,12 +349,14 @@ def defaultArgumentParser():
return parser
def validateAddress(args):
+ tcp_addr_set = False
address = None
if args.host is None:
address_tcpip = (DEFAULT_HOST, DEFAULT_PORT)
else:
address_tcpip = (args.host, args.port)
+ tcp_addr_set = True
if args.unix is None:
address_unix = DEFAULT_UNIX
@@ -366,7 +368,7 @@ def validateAddress(args):
possible_sock_mode = os.stat(address_unix).st_mode
except:
pass
- if stat.S_ISSOCK(possible_sock_mode):
+ if tcp_addr_set == False and stat.S_ISSOCK(possible_sock_mode):
address = address_unix
else:
address = address_tcpip
diff --git a/examples/py-flow-info/flow-info.py b/examples/py-flow-info/flow-info.py
index 6f90ec7fa..acb811f65 100755
--- a/examples/py-flow-info/flow-info.py
+++ b/examples/py-flow-info/flow-info.py
@@ -3,6 +3,7 @@
import os
import sys
+sys.path.append(os.path.dirname(sys.argv[0]) + '/../share/nDPId')
sys.path.append(os.path.dirname(sys.argv[0]) + '/../usr/share/nDPId')
try:
import nDPIsrvd
diff --git a/examples/py-flow-undetected-to-pcap/flow-undetected-to-pcap.py b/examples/py-flow-undetected-to-pcap/flow-undetected-to-pcap.py
index e5636312f..fcefe847f 100755
--- a/examples/py-flow-undetected-to-pcap/flow-undetected-to-pcap.py
+++ b/examples/py-flow-undetected-to-pcap/flow-undetected-to-pcap.py
@@ -3,6 +3,7 @@
import os
import sys
+sys.path.append(os.path.dirname(sys.argv[0]) + '/../share/nDPId')
sys.path.append(os.path.dirname(sys.argv[0]) + '/../usr/share/nDPId')
try:
import nDPIsrvd
diff --git a/examples/py-json-stdout/json-stdout.py b/examples/py-json-stdout/json-stdout.py
index 8200bf12b..9693ecef6 100755
--- a/examples/py-json-stdout/json-stdout.py
+++ b/examples/py-json-stdout/json-stdout.py
@@ -3,6 +3,7 @@
import os
import sys
+sys.path.append(os.path.dirname(sys.argv[0]) + '/../share/nDPId')
sys.path.append(os.path.dirname(sys.argv[0]) + '/../usr/share/nDPId')
try:
import nDPIsrvd
diff --git a/examples/py-risky-flow-to-pcap/risky-flow-to-pcap.py b/examples/py-risky-flow-to-pcap/risky-flow-to-pcap.py
index 42004eebe..cdf4257c1 100755
--- a/examples/py-risky-flow-to-pcap/risky-flow-to-pcap.py
+++ b/examples/py-risky-flow-to-pcap/risky-flow-to-pcap.py
@@ -4,6 +4,7 @@ import base64
import os
import sys
+sys.path.append(os.path.dirname(sys.argv[0]) + '/../share/nDPId')
sys.path.append(os.path.dirname(sys.argv[0]) + '/../usr/share/nDPId')
try:
import nDPIsrvd
diff --git a/examples/py-schema-validation/py-schema-validation.py b/examples/py-schema-validation/py-schema-validation.py
index e8fc390f1..defba96e9 100755
--- a/examples/py-schema-validation/py-schema-validation.py
+++ b/examples/py-schema-validation/py-schema-validation.py
@@ -3,6 +3,7 @@
import os
import sys
+sys.path.append(os.path.dirname(sys.argv[0]) + '/../share/nDPId')
sys.path.append(os.path.dirname(sys.argv[0]) + '/../usr/share/nDPId')
try:
import nDPIsrvd
diff --git a/nDPId.c b/nDPId.c
index 1d3b92471..daaac15fe 100644
--- a/nDPId.c
+++ b/nDPId.c
@@ -26,8 +26,8 @@
#define UNIX_PATH_MAX 108
#endif
-#if ((NDPI_MAJOR == 3 && NDPI_MINOR < 6) || NDPI_MAJOR < 3) && NDPI_API_VERSION < 4087
-#error "nDPI >= 3.6.0 or API version >= 4087 required"
+#if ((NDPI_MAJOR == 3 && NDPI_MINOR < 5) || NDPI_MAJOR < 3) && NDPI_API_VERSION < 4087
+#error "nDPI >= 3.5.0 or API version >= 4087 required"
#endif
#if !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
@@ -47,7 +47,10 @@ union nDPId_ip {
} v4;
struct
{
- uint64_t ip6[2];
+ union {
+ uint64_t ip[2];
+ uint32_t ip_u32[4];
+ };
} v6;
};
@@ -253,6 +256,7 @@ static char const * const daemon_event_name_table[DAEMON_EVENT_COUNT] = {
static struct nDPId_reader_thread reader_threads[nDPId_MAX_READER_THREADS] = {};
static int nDPId_main_thread_shutdown = 0;
static uint64_t global_flow_id = 1;
+static int ip4_interface_avail = 0, ip6_interface_avail = 0;
#ifdef ENABLE_MEMORY_PROFILING
static uint64_t ndpi_memory_alloc_count = 0;
@@ -265,9 +269,9 @@ static struct
{
/* opts */
char * pcap_file_or_interface;
- union nDPId_ip pcap_dev_ip;
- union nDPId_ip pcap_dev_netmask;
- union nDPId_ip pcap_dev_subnet;
+ union nDPId_ip pcap_dev_ip4, pcap_dev_ip6;
+ union nDPId_ip pcap_dev_netmask4, pcap_dev_netmask6;
+ union nDPId_ip pcap_dev_subnet4, pcap_dev_subnet6;
uint8_t process_internal_initial_direction;
uint8_t process_external_initial_direction;
char * bpf_str;
@@ -333,9 +337,9 @@ static void jsonize_flow_event(struct nDPId_reader_thread * const reader_thread,
struct nDPId_flow_info * const flow,
enum flow_event event);
-static void ip_netmask_to_subnet(union nDPId_ip * ip,
- union nDPId_ip * netmask,
- union nDPId_ip * subnet,
+static void ip_netmask_to_subnet(union nDPId_ip const * const ip,
+ union nDPId_ip const * const netmask,
+ union nDPId_ip * const subnet,
enum nDPId_l3_type type)
{
switch (type)
@@ -344,51 +348,199 @@ static void ip_netmask_to_subnet(union nDPId_ip * ip,
subnet->v4.ip = ip->v4.ip & netmask->v4.ip;
break;
case L3_IP6:
- subnet->v6.ip6[0] = ip->v6.ip6[0] & netmask->v6.ip6[0];
- subnet->v6.ip6[1] = ip->v6.ip6[1] & netmask->v6.ip6[1];
+ subnet->v6.ip[0] = ip->v6.ip[0] & netmask->v6.ip[0];
+ subnet->v6.ip[1] = ip->v6.ip[1] & netmask->v6.ip[1];
break;
}
}
-static int is_ip_in_subnet(union nDPId_ip * cmp_ip,
- union nDPId_ip * netmask,
- union nDPId_ip * cmp_subnet,
- enum nDPId_l3_type type)
+static int is_ip_in_subnet(union nDPId_ip const * const cmp_ip,
+ union nDPId_ip const * const netmask,
+ union nDPId_ip const * const cmp_subnet,
+ enum nDPId_l3_type const type)
{
switch (type)
{
case L3_IP:
return (cmp_ip->v4.ip & netmask->v4.ip) == cmp_subnet->v4.ip;
case L3_IP6:
- return (cmp_ip->v6.ip6[0] & netmask->v6.ip6[0]) == cmp_subnet->v6.ip6[0] &&
- (cmp_ip->v6.ip6[1] & netmask->v6.ip6[1]) == cmp_subnet->v6.ip6[1];
+ return (cmp_ip->v6.ip[0] & netmask->v6.ip[0]) == cmp_subnet->v6.ip[0] &&
+ (cmp_ip->v6.ip[1] & netmask->v6.ip[1]) == cmp_subnet->v6.ip[1];
}
return 0;
}
-static void get_v4_ip_from_sockaddr(struct sockaddr_in * saddr, union nDPId_ip * dest)
+static void get_ip_from_sockaddr(struct sockaddr const * const saddr, union nDPId_ip * dest)
{
- dest->v4.ip = saddr->sin_addr.s_addr;
+ switch (saddr->sa_family)
+ {
+ case AF_INET:
+ dest->v4.ip = ((struct sockaddr_in *)saddr)->sin_addr.s_addr;
+ break;
+ case AF_INET6:
+ dest->v6.ip_u32[0] = ((struct sockaddr_in6 *)saddr)->sin6_addr.s6_addr32[0];
+ dest->v6.ip_u32[1] = ((struct sockaddr_in6 *)saddr)->sin6_addr.s6_addr32[1];
+ dest->v6.ip_u32[2] = ((struct sockaddr_in6 *)saddr)->sin6_addr.s6_addr32[2];
+ dest->v6.ip_u32[3] = ((struct sockaddr_in6 *)saddr)->sin6_addr.s6_addr32[3];
+ break;
+ }
}
-#if 0
-static void get_v6_ip_from_sockaddr(struct sockaddr_in6 * saddr, union nDPId_ip * dest)
+static int get_ip6_address_and_netmask(char const * const ifa_name, size_t ifnamelen)
{
- dest->v6.ip6[0] = *(uint64_t *)&saddr->sin6_addr.s6_addr[0];
- dest->v6.ip6[0] = *(uint64_t *)&saddr->sin6_addr.s6_addr[7];
+ FILE * f;
+ char addr6[INET6_ADDRSTRLEN], netmask6[INET6_ADDRSTRLEN], subnet6[INET6_ADDRSTRLEN], devname[21];
+ struct sockaddr_in6 sap;
+ int plen, scope, dad_status, if_idx, retval = 0;
+ char addr6p[8][5];
+
+ f = fopen("/proc/net/if_inet6", "r");
+ if (f == NULL)
+ {
+ return 1;
+ }
+
+ while (fscanf(f,
+ "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n",
+ addr6p[0],
+ addr6p[1],
+ addr6p[2],
+ addr6p[3],
+ addr6p[4],
+ addr6p[5],
+ addr6p[6],
+ addr6p[7],
+ &if_idx,
+ &plen,
+ &scope,
+ &dad_status,
+ devname) != EOF)
+ {
+ if (strncmp(devname, ifa_name, ifnamelen) == 0)
+ {
+ sprintf(addr6,
+ "%s:%s:%s:%s:%s:%s:%s:%s",
+ addr6p[0],
+ addr6p[1],
+ addr6p[2],
+ addr6p[3],
+ addr6p[4],
+ addr6p[5],
+ addr6p[6],
+ addr6p[7]);
+
+ memset(&sap, 0, sizeof(sap));
+ if (inet_pton(AF_INET6, addr6, (struct sockaddr *)&sap.sin6_addr) != 1)
+ {
+ retval = 1;
+ goto error;
+ }
+ inet_ntop(AF_INET6, &sap.sin6_addr, addr6, sizeof(addr6));
+ sap.sin6_family = AF_INET6;
+ get_ip_from_sockaddr((struct sockaddr *)&sap, &nDPId_options.pcap_dev_ip6);
+
+ memset(&sap, 0, sizeof(sap));
+ memset(&sap.sin6_addr.s6_addr, 0xFF, plen / 8);
+ if (plen < 128 && (plen % 32) != 0)
+ {
+ sap.sin6_addr.s6_addr32[plen / 32] = 0xFFFFFFFF << (32 - (plen % 32));
+ }
+ inet_ntop(AF_INET6, &sap.sin6_addr, netmask6, sizeof(netmask6));
+ sap.sin6_family = AF_INET6;
+ get_ip_from_sockaddr((struct sockaddr *)&sap, &nDPId_options.pcap_dev_netmask6);
+
+ ip_netmask_to_subnet(&nDPId_options.pcap_dev_ip6,
+ &nDPId_options.pcap_dev_netmask6,
+ &nDPId_options.pcap_dev_subnet6,
+ L3_IP6);
+ inet_ntop(AF_INET6, &nDPId_options.pcap_dev_subnet6.v6, subnet6, sizeof(subnet6));
+
+ syslog(LOG_DAEMON,
+ "%s IPv6 address/prefix netmask subnet: %s/%u %s %s",
+ nDPId_options.pcap_file_or_interface,
+ addr6,
+ plen,
+ netmask6,
+ subnet6);
+ }
+ }
+
+error:
+ fclose(f);
+
+ return retval;
+}
+
+static int get_ip4_address_and_netmask(char const * const ifa_name, size_t ifnamelen)
+{
+ int retval = 0;
+ int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
+ struct ifreq ifr;
+
+ if (sock < 0)
+ {
+ retval = 1;
+ goto error;
+ }
+ if (ifnamelen >= sizeof(ifr.ifr_name))
+ {
+ retval = 1;
+ goto error;
+ }
+
+ memset(&ifr, 0, sizeof(ifr));
+ memcpy(ifr.ifr_name, ifa_name, ifnamelen);
+ ifr.ifr_name[ifnamelen] = '\0';
+ ifr.ifr_netmask.sa_family = AF_INET;
+ if (ioctl(sock, SIOCGIFNETMASK, &ifr) == -1)
+ {
+ retval = 1;
+ goto error;
+ }
+ get_ip_from_sockaddr(&ifr.ifr_netmask, &nDPId_options.pcap_dev_netmask4);
+
+ memset(&ifr, 0, sizeof(ifr));
+ memcpy(ifr.ifr_name, ifa_name, ifnamelen);
+ ifr.ifr_name[ifnamelen] = '\0';
+ ifr.ifr_addr.sa_family = AF_INET;
+ if (ioctl(sock, SIOCGIFADDR, &ifr) == -1)
+ {
+ retval = 1;
+ goto error;
+ }
+ get_ip_from_sockaddr(&ifr.ifr_netmask, &nDPId_options.pcap_dev_ip4);
+
+ ip_netmask_to_subnet(&nDPId_options.pcap_dev_ip4,
+ &nDPId_options.pcap_dev_netmask4,
+ &nDPId_options.pcap_dev_subnet4,
+ L3_IP);
+
+ {
+ char addr[INET_ADDRSTRLEN];
+ char netm[INET_ADDRSTRLEN];
+ char subn[INET_ADDRSTRLEN];
+ void * saddr = &nDPId_options.pcap_dev_ip4.v4.ip;
+ void * snetm = &nDPId_options.pcap_dev_netmask4.v4.ip;
+ void * ssubn = &nDPId_options.pcap_dev_subnet4.v4.ip;
+ syslog(LOG_DAEMON,
+ "%s IPv4 address netmask subnet: %s %s %s",
+ nDPId_options.pcap_file_or_interface,
+ inet_ntop(AF_INET, saddr, addr, sizeof(addr)),
+ inet_ntop(AF_INET, snetm, netm, sizeof(netm)),
+ inet_ntop(AF_INET, ssubn, subn, sizeof(subn)));
+ }
+
+error:
+ close(sock);
+ return retval;
}
-#endif
-/*
- * Only IPv4 supported for now!
- * IPv6 support planned via /proc/net/if_inet6
- */
static int get_ip_netmask_from_pcap_dev(char const * const pcap_dev)
{
+ int retval = 0, found_dev = 0;
struct ifaddrs * ifaddrs = NULL;
struct ifaddrs * ifa;
- int sock = -1;
if (getifaddrs(&ifaddrs) != 0 || ifaddrs == NULL)
{
@@ -402,91 +554,45 @@ static int get_ip_netmask_from_pcap_dev(char const * const pcap_dev)
continue;
}
- size_t ifnamelen = strlen(ifa->ifa_name);
- enum nDPId_l3_type type;
-
- switch (ifa->ifa_addr->sa_family)
- {
- case AF_INET:
- type = L3_IP;
- break;
- case AF_INET6:
- type = L3_IP6;
- break;
- default:
- continue;
- }
-
- if (strcmp(ifa->ifa_name, pcap_dev) == 0 && ifnamelen == strlen(pcap_dev))
+ size_t ifnamelen = strnlen(ifa->ifa_name, IFNAMSIZ);
+ if (strncmp(ifa->ifa_name, pcap_dev, IFNAMSIZ) == 0 && ifnamelen == strnlen(pcap_dev, IFNAMSIZ))
{
- if (type == L3_IP6)
- {
- syslog(LOG_DAEMON, "IPv6 network interfaces in combination with -I / -E is not supported for now");
- continue;
- }
-
- sock = socket(ifa->ifa_addr->sa_family, SOCK_DGRAM, IPPROTO_IP);
- struct ifreq ifr;
-
- if (sock < 0)
+ found_dev = 1;
+ switch (ifa->ifa_addr->sa_family)
{
- break;
- }
- if (ifnamelen >= sizeof(ifr.ifr_name))
- {
- break;
- }
-
- memset(&ifr, 0, sizeof(ifr));
- memcpy(ifr.ifr_name, ifa->ifa_name, ifnamelen);
- ifr.ifr_name[ifnamelen] = '\0';
- ifr.ifr_netmask.sa_family = ifa->ifa_addr->sa_family;
- if (ioctl(sock, SIOCGIFNETMASK, &ifr) == -1)
- {
- break;
- }
- get_v4_ip_from_sockaddr((struct sockaddr_in *)&ifr.ifr_netmask, &nDPId_options.pcap_dev_netmask);
-
- memset(&ifr, 0, sizeof(ifr));
- memcpy(ifr.ifr_name, ifa->ifa_name, ifnamelen);
- ifr.ifr_name[ifnamelen] = '\0';
- ifr.ifr_addr.sa_family = ifa->ifa_addr->sa_family;
- if (ioctl(sock, SIOCGIFADDR, &ifr) == -1)
- {
- break;
+ case AF_INET:
+ if (ip4_interface_avail == 0 && get_ip4_address_and_netmask(ifa->ifa_name, ifnamelen) != 0)
+ {
+ retval = 1;
+ }
+ ip4_interface_avail = 1;
+ break;
+ case AF_INET6:
+ if (ip6_interface_avail == 0 && get_ip6_address_and_netmask(ifa->ifa_name, ifnamelen) != 0)
+ {
+ retval = 1;
+ }
+ ip6_interface_avail = 1;
+ break;
+ default:
+ break;
}
- get_v4_ip_from_sockaddr((struct sockaddr_in *)&ifr.ifr_netmask, &nDPId_options.pcap_dev_ip);
-
- ip_netmask_to_subnet(&nDPId_options.pcap_dev_ip,
- &nDPId_options.pcap_dev_netmask,
- &nDPId_options.pcap_dev_subnet,
- type);
-
- char addr[INET_ADDRSTRLEN];
- char netm[INET_ADDRSTRLEN];
- char subn[INET_ADDRSTRLEN];
- void * saddr = &nDPId_options.pcap_dev_ip.v4.ip;
- void * snetm = &nDPId_options.pcap_dev_netmask.v4.ip;
- void * ssubn = &nDPId_options.pcap_dev_subnet.v4.ip;
- syslog(LOG_DAEMON,
- "%s address/netmask/subnet: %s/%s/%s",
- nDPId_options.pcap_file_or_interface,
- inet_ntop(ifa->ifa_addr->sa_family, saddr, addr, sizeof(addr)),
- inet_ntop(ifa->ifa_addr->sa_family, snetm, netm, sizeof(netm)),
- inet_ntop(ifa->ifa_addr->sa_family, ssubn, subn, sizeof(subn)));
-
- freeifaddrs(ifaddrs);
- close(sock);
- return 0;
}
}
- freeifaddrs(ifaddrs);
- if (sock >= 0)
+ if (found_dev != 0 &&
+ (nDPId_options.process_internal_initial_direction != 0 ||
+ nDPId_options.process_external_initial_direction != 0) &&
+ ip4_interface_avail == 0 && ip6_interface_avail == 0)
{
- close(sock);
+ syslog(LOG_DAEMON | LOG_ERR,
+ "Interface %s does not have any IPv4 / IPv6 address set, -I / -E won't work.",
+ pcap_dev);
+ retval = 1;
}
- return 1;
+
+ freeifaddrs(ifaddrs);
+ return retval;
}
#ifdef ENABLE_MEMORY_PROFILING
@@ -756,10 +862,13 @@ static int setup_reader_threads(void)
errno = 0;
if (get_ip_netmask_from_pcap_dev(nDPId_options.pcap_file_or_interface) != 0)
{
- syslog(LOG_DAEMON | LOG_ERR,
- "Could not get netmask for pcap device %s: %s",
- nDPId_options.pcap_file_or_interface,
- strerror(errno));
+ if (errno != 0)
+ {
+ syslog(LOG_DAEMON | LOG_ERR,
+ "Could not get netmask for pcap device %s: %s",
+ nDPId_options.pcap_file_or_interface,
+ strerror(errno));
+ }
return 1;
}
}
@@ -804,8 +913,8 @@ static int ip_tuples_equal(struct nDPId_flow_basic const * const A, struct nDPId
}
else if (A->l3_type == L3_IP6 && B->l3_type == L3_IP6)
{
- return A->src.v6.ip6[0] == B->src.v6.ip6[0] && A->src.v6.ip6[1] == B->src.v6.ip6[1] &&
- A->dst.v6.ip6[0] == B->dst.v6.ip6[0] && A->dst.v6.ip6[1] == B->dst.v6.ip6[1];
+ return A->src.v6.ip[0] == B->src.v6.ip[0] && A->src.v6.ip[1] == B->src.v6.ip[1] &&
+ A->dst.v6.ip[0] == B->dst.v6.ip[0] && A->dst.v6.ip[1] == B->dst.v6.ip[1];
}
return 0;
}
@@ -832,13 +941,13 @@ static int ip_tuples_compare(struct nDPId_flow_basic const * const A, struct nDP
}
else if (A->l3_type == L3_IP6 && B->l3_type == L3_IP6)
{
- if ((A->src.v6.ip6[0] < B->src.v6.ip6[0] && A->src.v6.ip6[1] < B->src.v6.ip6[1]) ||
- (A->dst.v6.ip6[0] < B->dst.v6.ip6[0] && A->dst.v6.ip6[1] < B->dst.v6.ip6[1]))
+ if ((A->src.v6.ip[0] < B->src.v6.ip[0] && A->src.v6.ip[1] < B->src.v6.ip[1]) ||
+ (A->dst.v6.ip[0] < B->dst.v6.ip[0] && A->dst.v6.ip[1] < B->dst.v6.ip[1]))
{
return -1;
}
- if ((A->src.v6.ip6[0] > B->src.v6.ip6[0] && A->src.v6.ip6[1] > B->src.v6.ip6[1]) ||
- (A->dst.v6.ip6[0] > B->dst.v6.ip6[0] && A->dst.v6.ip6[1] > B->dst.v6.ip6[1]))
+ if ((A->src.v6.ip[0] > B->src.v6.ip[0] && A->src.v6.ip[1] > B->src.v6.ip[1]) ||
+ (A->dst.v6.ip[0] > B->dst.v6.ip[0] && A->dst.v6.ip[1] > B->dst.v6.ip[1]))
{
return 1;
}
@@ -1047,11 +1156,11 @@ static void jsonize_l3_l4(struct nDPId_workflow * const workflow, struct nDPId_f
break;
case L3_IP6:
ndpi_serialize_string_string(serializer, "l3_proto", "ip6");
- if (inet_ntop(AF_INET6, &flow->flow_basic.src.v6.ip6[0], src_name, sizeof(src_name)) == NULL)
+ if (inet_ntop(AF_INET6, &flow->flow_basic.src.v6.ip[0], src_name, sizeof(src_name)) == NULL)
{
syslog(LOG_DAEMON | LOG_ERR, "Could not convert IPv6 source ip to string: %s", strerror(errno));
}
- if (inet_ntop(AF_INET6, &flow->flow_basic.dst.v6.ip6[0], dst_name, sizeof(dst_name)) == NULL)
+ if (inet_ntop(AF_INET6, &flow->flow_basic.dst.v6.ip[0], dst_name, sizeof(dst_name)) == NULL)
{
syslog(LOG_DAEMON | LOG_ERR, "Could not convert IPv6 destination ip to string: %s", strerror(errno));
}
@@ -2057,20 +2166,20 @@ static void ndpi_process_packet(uint8_t * const args,
return;
}
- flow_basic.src.v6.ip6[0] = ip6->ip6_src.u6_addr.u6_addr64[0];
- flow_basic.src.v6.ip6[1] = ip6->ip6_src.u6_addr.u6_addr64[1];
- flow_basic.dst.v6.ip6[0] = ip6->ip6_dst.u6_addr.u6_addr64[0];
- flow_basic.dst.v6.ip6[1] = ip6->ip6_dst.u6_addr.u6_addr64[1];
+ flow_basic.src.v6.ip[0] = ip6->ip6_src.u6_addr.u6_addr64[0];
+ flow_basic.src.v6.ip[1] = ip6->ip6_src.u6_addr.u6_addr64[1];
+ flow_basic.dst.v6.ip[0] = ip6->ip6_dst.u6_addr.u6_addr64[0];
+ flow_basic.dst.v6.ip[1] = ip6->ip6_dst.u6_addr.u6_addr64[1];
uint64_t min_addr[2];
- if (flow_basic.src.v6.ip6[0] > flow_basic.dst.v6.ip6[0] && flow_basic.src.v6.ip6[1] > flow_basic.dst.v6.ip6[1])
+ if (flow_basic.src.v6.ip[0] > flow_basic.dst.v6.ip[0] && flow_basic.src.v6.ip[1] > flow_basic.dst.v6.ip[1])
{
- min_addr[0] = flow_basic.dst.v6.ip6[0];
- min_addr[1] = flow_basic.dst.v6.ip6[0];
+ min_addr[0] = flow_basic.dst.v6.ip[0];
+ min_addr[1] = flow_basic.dst.v6.ip[0];
}
else
{
- min_addr[0] = flow_basic.src.v6.ip6[0];
- min_addr[1] = flow_basic.src.v6.ip6[0];
+ min_addr[0] = flow_basic.src.v6.ip[0];
+ min_addr[1] = flow_basic.src.v6.ip[0];
}
thread_index = min_addr[0] + min_addr[1] + ip6->ip6_hdr.ip6_un1_nxt;
}
@@ -2165,8 +2274,8 @@ static void ndpi_process_packet(uint8_t * const args,
(uint8_t *)&flow_basic.hashval,
sizeof(flow_basic.hashval)) != 0)
{
- flow_basic.hashval = flow_basic.src.v6.ip6[0] + flow_basic.src.v6.ip6[1];
- flow_basic.hashval += flow_basic.dst.v6.ip6[0] + flow_basic.dst.v6.ip6[1];
+ flow_basic.hashval = flow_basic.src.v6.ip[0] + flow_basic.src.v6.ip[1];
+ flow_basic.hashval += flow_basic.dst.v6.ip[0] + flow_basic.dst.v6.ip[1];
}
break;
}
@@ -2177,15 +2286,15 @@ static void ndpi_process_packet(uint8_t * const args,
if (tree_result == NULL)
{
/* flow not found in btree: switch src <-> dst and try to find it again */
- uint64_t orig_src_ip[2] = {flow_basic.src.v6.ip6[0], flow_basic.src.v6.ip6[1]};
- uint64_t orig_dst_ip[2] = {flow_basic.dst.v6.ip6[0], flow_basic.dst.v6.ip6[1]};
+ uint64_t orig_src_ip[2] = {flow_basic.src.v6.ip[0], flow_basic.src.v6.ip[1]};
+ uint64_t orig_dst_ip[2] = {flow_basic.dst.v6.ip[0], flow_basic.dst.v6.ip[1]};
uint16_t orig_src_port = flow_basic.src_port;
uint16_t orig_dst_port = flow_basic.dst_port;
- flow_basic.src.v6.ip6[0] = orig_dst_ip[0];
- flow_basic.src.v6.ip6[1] = orig_dst_ip[1];
- flow_basic.dst.v6.ip6[0] = orig_src_ip[0];
- flow_basic.dst.v6.ip6[1] = orig_src_ip[1];
+ flow_basic.src.v6.ip[0] = orig_dst_ip[0];
+ flow_basic.src.v6.ip[1] = orig_dst_ip[1];
+ flow_basic.dst.v6.ip[0] = orig_src_ip[0];
+ flow_basic.dst.v6.ip[1] = orig_src_ip[1];
flow_basic.src_port = orig_dst_port;
flow_basic.dst_port = orig_src_port;
@@ -2195,10 +2304,10 @@ static void ndpi_process_packet(uint8_t * const args,
direction_changed = 1;
}
- flow_basic.src.v6.ip6[0] = orig_src_ip[0];
- flow_basic.src.v6.ip6[1] = orig_src_ip[1];
- flow_basic.dst.v6.ip6[0] = orig_dst_ip[0];
- flow_basic.dst.v6.ip6[1] = orig_dst_ip[1];
+ flow_basic.src.v6.ip[0] = orig_src_ip[0];
+ flow_basic.src.v6.ip[1] = orig_src_ip[1];
+ flow_basic.dst.v6.ip[0] = orig_dst_ip[0];
+ flow_basic.dst.v6.ip[1] = orig_dst_ip[1];
flow_basic.src_port = orig_src_port;
flow_basic.dst_port = orig_dst_port;
}
@@ -2207,12 +2316,22 @@ static void ndpi_process_packet(uint8_t * const args,
{
/* flow still not found, must be new or midstream */
+ union nDPId_ip const * netmask;
+ union nDPId_ip const * subnet;
+ switch (flow_basic.l3_type)
+ {
+ case L3_IP:
+ netmask = &nDPId_options.pcap_dev_netmask4;
+ subnet = &nDPId_options.pcap_dev_subnet4;
+ break;
+ case L3_IP6:
+ netmask = &nDPId_options.pcap_dev_netmask6;
+ subnet = &nDPId_options.pcap_dev_subnet6;
+ break;
+ }
if (nDPId_options.process_internal_initial_direction != 0 && flow_basic.tcp_is_midstream_flow == 0)
{
- if (is_ip_in_subnet(&flow_basic.src,
- &nDPId_options.pcap_dev_netmask,
- &nDPId_options.pcap_dev_subnet,
- flow_basic.l3_type) == 0)
+ if (is_ip_in_subnet(&flow_basic.src, netmask, subnet, flow_basic.l3_type) == 0)
{
if (add_new_flow(workflow, &flow_basic, FT_SKIPPED, hashed_index) == NULL)
{
@@ -2236,10 +2355,7 @@ static void ndpi_process_packet(uint8_t * const args,
}
else if (nDPId_options.process_external_initial_direction != 0 && flow_basic.tcp_is_midstream_flow == 0)
{
- if (is_ip_in_subnet(&flow_basic.src,
- &nDPId_options.pcap_dev_netmask,
- &nDPId_options.pcap_dev_subnet,
- flow_basic.l3_type) != 0)
+ if (is_ip_in_subnet(&flow_basic.src, netmask, subnet, flow_basic.l3_type) != 0)
{
if (add_new_flow(workflow, &flow_basic, FT_SKIPPED, hashed_index) == NULL)
{
diff --git a/test/run_tests.sh b/test/run_tests.sh
index 4b2603eff..ef7a15243 100755
--- a/test/run_tests.sh
+++ b/test/run_tests.sh
@@ -5,12 +5,14 @@ set -e
LINE_SPACES=${LINE_SPACES:-48}
MYDIR="$(realpath "$(dirname ${0})")"
nDPId_test_EXEC="${2:-"$(realpath "${MYDIR}/../nDPId-test")"}"
+JSON_VALIDATOR="${3:-"$(realpath "${MYDIR}/../examples/py-schema-validation/py-schema-validation.py")"}"
-if [ $# -ne 1 -a $# -ne 2 ]; then
+if [ $# -ne 1 -a $# -ne 2 -a $# -ne 3 ]; then
cat <<EOF
-usage: ${0} [path-to-nDPI-source-root] [path-to-nDPId-test-exec]
+usage: ${0} [path-to-nDPI-source-root] [path-to-nDPId-test-exec] [path-to-nDPId-JSON-validator]
path-to-nDPId-test-exec defaults to ${nDPId_test_EXEC}
+ path-to-nDPId-JSON-validator defaults to ${JSON_VALIDATOR}
EOF
exit 2
fi
@@ -21,23 +23,30 @@ LOCKFILE="$(realpath "${0}").lock"
touch "${LOCKFILE}"
exec 42< "${LOCKFILE}"
flock -x -n 42 || {
- printf '%s\n' "Could not aquire file lock for ${0}. Already running instance?";
+ printf '%s\n' "Could not aquire file lock for ${0}. Already running instance?" >&2;
exit 3;
}
function sighandler()
{
+ printf '%s\n' ' Received shutdown SIGNAL, bye' >&2
rm -f "${LOCKFILE}"
exit 4
}
trap sighandler SIGINT SIGTERM
if [ ! -x "${nDPId_test_EXEC}" ]; then
-cat <<EOF
+cat >&2 <<EOF
Required nDPId-test executable does not exist; ${nDPId_test_EXEC}
EOF
exit 5
fi
+nc -h |& head -n1 | grep -qoE '^OpenBSD netcat' || {
+ printf '%s\n' "OpenBSD netcat (nc) version required!" >&2;
+ printf '%s\n' "Your version: $(nc -h |& head -n1)" >&2;
+ exit 6;
+}
+
nDPI_TEST_DIR="${nDPI_SOURCE_ROOT}/tests/pcap"
cat <<EOF
@@ -117,7 +126,7 @@ for out_file in $(ls results/*.out); do
fi
cat "${out_file}" | nc -q 1 -l 127.0.0.1 9000 &
nc_pid=$!
- ${MYDIR}/../examples/py-schema-validation/py-schema-validation.py \
+ ${JSON_VALIDATOR} \
--host 127.0.0.1 --port 9000 2>>"/tmp/nDPId-test-stderr/$(basename ${pcap_file}).out"
if [ $? -eq 0 ]; then
printf ' %s\n' '[OK]'