Added IPv6 support for -I / -E.

* added another Python search path and try-catch ModuleNotFoundError again
 * run_tests.sh checks for OpenBSD netcat (required for -q)

Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
This commit is contained in:
Toni Uhlig
2021-04-10 23:43:19 +02:00
parent ba586e1ecf
commit 131cf5385b
8 changed files with 288 additions and 156 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

416
nDPId.c
View File

@@ -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];
}
#endif
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;
}
/*
* 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)
size_t ifnamelen = strnlen(ifa->ifa_name, IFNAMSIZ);
if (strncmp(ifa->ifa_name, pcap_dev, IFNAMSIZ) == 0 && ifnamelen == strnlen(pcap_dev, IFNAMSIZ))
{
case AF_INET:
type = L3_IP;
break;
case AF_INET6:
type = L3_IP6;
break;
default:
continue;
found_dev = 1;
switch (ifa->ifa_addr->sa_family)
{
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;
}
}
}
if (strcmp(ifa->ifa_name, pcap_dev) == 0 && ifnamelen == strlen(pcap_dev))
{
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)
{
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;
}
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;
}
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)
{
syslog(LOG_DAEMON | LOG_ERR,
"Interface %s does not have any IPv4 / IPv6 address set, -I / -E won't work.",
pcap_dev);
retval = 1;
}
freeifaddrs(ifaddrs);
if (sock >= 0)
{
close(sock);
}
return 1;
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)
{

View File

@@ -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]'