mirror of
https://github.com/optim-enterprises-bv/nDPId.git
synced 2025-10-30 17:57:48 +00:00
All colors are beautiful for py-flow-info.
* instance alias is now mandatory (will be required for future use-cases) Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
This commit is contained in:
49
dependencies/nDPIsrvd.py
vendored
49
dependencies/nDPIsrvd.py
vendored
@@ -8,6 +8,12 @@ import os
|
|||||||
import scapy.all
|
import scapy.all
|
||||||
import stat
|
import stat
|
||||||
import socket
|
import socket
|
||||||
|
try:
|
||||||
|
from colorama import Back, Fore, Style
|
||||||
|
USE_COLORAMA=True
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
print('Python module colorama not found, using fallback.')
|
||||||
|
USE_COLORAMA=False
|
||||||
|
|
||||||
DEFAULT_HOST = '127.0.0.1'
|
DEFAULT_HOST = '127.0.0.1'
|
||||||
DEFAULT_PORT = 7000
|
DEFAULT_PORT = 7000
|
||||||
@@ -34,11 +40,52 @@ FLOW_EVENTS = [ ('Invalid','invalid'), ('New','new'), ('End','end'), ('Idle','id
|
|||||||
('Detected','detected'), ('Detection-Update','detection-update'), ('Not-Detected','not-detected') ]
|
('Detected','detected'), ('Detection-Update','detection-update'), ('Not-Detected','not-detected') ]
|
||||||
|
|
||||||
class TermColor:
|
class TermColor:
|
||||||
|
HINT = '\033[33m'
|
||||||
WARNING = '\033[93m'
|
WARNING = '\033[93m'
|
||||||
FAIL = '\033[91m'
|
FAIL = '\033[91m'
|
||||||
BOLD = '\033[1m'
|
BOLD = '\033[1m'
|
||||||
END = '\033[0m'
|
END = '\033[0m'
|
||||||
BLINK = "\x1b[5m"
|
BLINK = '\x1b[5m'
|
||||||
|
|
||||||
|
if USE_COLORAMA is True:
|
||||||
|
COLOR_TUPLES = [ (Fore.BLUE, [Back.RED, Back.MAGENTA, Back.WHITE]),
|
||||||
|
(Fore.CYAN, [Back.MAGENTA, Back.RED, Back.WHITE]),
|
||||||
|
(Fore.GREEN, [Back.YELLOW, Back.RED, Back.MAGENTA, Back.WHITE]),
|
||||||
|
(Fore.MAGENTA, [Back.CYAN, Back.BLUE, Back.WHITE]),
|
||||||
|
(Fore.RED, [Back.GREEN, Back.BLUE, Back.WHITE]),
|
||||||
|
(Fore.WHITE, [Back.BLACK, Back.MAGENTA, Back.RED, Back.BLUE]),
|
||||||
|
(Fore.YELLOW, [Back.RED, Back.CYAN, Back.BLUE, Back.WHITE]),
|
||||||
|
(Fore.LIGHTBLUE_EX, [Back.LIGHTRED_EX, Back.RED]),
|
||||||
|
(Fore.LIGHTCYAN_EX, [Back.LIGHTMAGENTA_EX, Back.MAGENTA]),
|
||||||
|
(Fore.LIGHTGREEN_EX, [Back.LIGHTYELLOW_EX, Back.YELLOW]),
|
||||||
|
(Fore.LIGHTMAGENTA_EX, [Back.LIGHTCYAN_EX, Back.CYAN]),
|
||||||
|
(Fore.LIGHTRED_EX, [Back.LIGHTGREEN_EX, Back.GREEN]),
|
||||||
|
(Fore.LIGHTWHITE_EX, [Back.LIGHTBLACK_EX, Back.BLACK]),
|
||||||
|
(Fore.LIGHTYELLOW_EX, [Back.LIGHTRED_EX, Back.RED]) ]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def calcColorHash(string):
|
||||||
|
h = 0
|
||||||
|
for char in string:
|
||||||
|
h += ord(char)
|
||||||
|
return h
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getColorsByHash(string):
|
||||||
|
h = TermColor.calcColorHash(string)
|
||||||
|
tuple_index = h % len(TermColor.COLOR_TUPLES)
|
||||||
|
bg_tuple_index = h % len(TermColor.COLOR_TUPLES[tuple_index][1])
|
||||||
|
return (TermColor.COLOR_TUPLES[tuple_index][0],
|
||||||
|
TermColor.COLOR_TUPLES[tuple_index][1][bg_tuple_index])
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def setColorByString(string):
|
||||||
|
if USE_COLORAMA is True:
|
||||||
|
fg_color, bg_color = TermColor.getColorsByHash(string)
|
||||||
|
color_hash = TermColor.calcColorHash(string)
|
||||||
|
return '{}{}{}{}{}'.format(Style.BRIGHT, fg_color, bg_color, string, Style.RESET_ALL)
|
||||||
|
else:
|
||||||
|
return '{}{}{}'.format(TermColor.BOLD, string, TermColor.END)
|
||||||
|
|
||||||
class nDPIsrvdSocket:
|
class nDPIsrvdSocket:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|||||||
@@ -41,9 +41,19 @@ def parse_json_str(json_str):
|
|||||||
else TermColor.FAIL + TermColor.BOLD + TermColor.BLINK + 'RISK' + TermColor.END,
|
else TermColor.FAIL + TermColor.BOLD + TermColor.BLINK + 'RISK' + TermColor.END,
|
||||||
ndpi_frisk[:-2])
|
ndpi_frisk[:-2])
|
||||||
|
|
||||||
|
instance_and_source = ''
|
||||||
|
instance_and_source += '[{}]'.format(TermColor.setColorByString(j['alias']))
|
||||||
|
instance_and_source += '[{}]'.format(TermColor.setColorByString(j['source']))
|
||||||
|
|
||||||
|
flow_event_name = ''
|
||||||
|
if nDPIdEvent.FlowEventName == 'guessed' or nDPIdEvent.FlowEventName == 'undetected':
|
||||||
|
flow_event_name += '{}{:>16}{}'.format(TermColor.HINT, nDPIdEvent.FlowEventPrettyName, TermColor.END)
|
||||||
|
else:
|
||||||
|
flow_event_name += '{:>16}'.format(nDPIdEvent.FlowEventPrettyName)
|
||||||
|
|
||||||
if j['l3_proto'] == 'ip4':
|
if j['l3_proto'] == 'ip4':
|
||||||
print('{:>16}: [{:.>6}] [{}][{:.>5}] [{:.>15}]{} -> [{:.>15}]{} {}' \
|
print('{} {}: [{:.>6}] [{}][{:.>5}] [{:.>15}]{} -> [{:.>15}]{} {}' \
|
||||||
''.format(nDPIdEvent.FlowEventPrettyName,
|
''.format(instance_and_source, flow_event_name,
|
||||||
j['flow_id'], j['l3_proto'], j['l4_proto'],
|
j['flow_id'], j['l3_proto'], j['l4_proto'],
|
||||||
j['src_ip'].lower(),
|
j['src_ip'].lower(),
|
||||||
'[{:.>5}]'.format(j['src_port']) if 'src_port' in j else '',
|
'[{:.>5}]'.format(j['src_port']) if 'src_port' in j else '',
|
||||||
@@ -51,8 +61,8 @@ def parse_json_str(json_str):
|
|||||||
'[{:.>5}]'.format(j['dst_port']) if 'dst_port' in j else '',
|
'[{:.>5}]'.format(j['dst_port']) if 'dst_port' in j else '',
|
||||||
ndpi_proto_categ))
|
ndpi_proto_categ))
|
||||||
elif j['l3_proto'] == 'ip6':
|
elif j['l3_proto'] == 'ip6':
|
||||||
print('{:>16}: [{:.>6}] [{}][{:.>5}] [{:.>39}]{} -> [{:.>39}]{} {}' \
|
print('{} {}: [{:.>6}] [{}][{:.>5}] [{:.>39}]{} -> [{:.>39}]{} {}' \
|
||||||
''.format(nDPIdEvent.FlowEventPrettyName,
|
''.format(instance_and_source, flow_event_name,
|
||||||
j['flow_id'], j['l3_proto'], j['l4_proto'],
|
j['flow_id'], j['l3_proto'], j['l4_proto'],
|
||||||
j['src_ip'].lower(),
|
j['src_ip'].lower(),
|
||||||
'[{:.>5}]'.format(j['src_port']) if 'src_port' in j else '',
|
'[{:.>5}]'.format(j['src_port']) if 'src_port' in j else '',
|
||||||
@@ -63,7 +73,7 @@ def parse_json_str(json_str):
|
|||||||
raise RuntimeError('unsupported l3 protocol: {}'.format(j['l3_proto']))
|
raise RuntimeError('unsupported l3 protocol: {}'.format(j['l3_proto']))
|
||||||
|
|
||||||
if len(ndpi_frisk) > 0:
|
if len(ndpi_frisk) > 0:
|
||||||
print('{:>18}{}'.format('', ndpi_frisk))
|
print('{} {:>18}{}'.format(instance_and_source, '', ndpi_frisk))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
23
nDPId.c
23
nDPId.c
@@ -940,10 +940,7 @@ static void jsonize_basic(struct nDPId_reader_thread * const reader_thread)
|
|||||||
ndpi_serialize_string_int32(&workflow->ndpi_serializer, "thread_id", reader_thread->array_index);
|
ndpi_serialize_string_int32(&workflow->ndpi_serializer, "thread_id", reader_thread->array_index);
|
||||||
ndpi_serialize_string_uint32(&workflow->ndpi_serializer, "packet_id", workflow->packets_captured);
|
ndpi_serialize_string_uint32(&workflow->ndpi_serializer, "packet_id", workflow->packets_captured);
|
||||||
ndpi_serialize_string_string(&workflow->ndpi_serializer, "source", pcap_file_or_interface);
|
ndpi_serialize_string_string(&workflow->ndpi_serializer, "source", pcap_file_or_interface);
|
||||||
if (instance_alias != NULL)
|
|
||||||
{
|
|
||||||
ndpi_serialize_string_string(&workflow->ndpi_serializer, "alias", instance_alias);
|
ndpi_serialize_string_string(&workflow->ndpi_serializer, "alias", instance_alias);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jsonize_daemon(struct nDPId_reader_thread * const reader_thread, enum daemon_event event)
|
static void jsonize_daemon(struct nDPId_reader_thread * const reader_thread, enum daemon_event event)
|
||||||
@@ -2554,7 +2551,9 @@ static int parse_options(int argc, char ** argv)
|
|||||||
"\t-p\tWrite the daemon PID to the given file path.\n"
|
"\t-p\tWrite the daemon PID to the given file path.\n"
|
||||||
"\t-u\tChange UID to the numeric value of user.\n"
|
"\t-u\tChange UID to the numeric value of user.\n"
|
||||||
"\t-g\tChange GID to the numeric value of group.\n"
|
"\t-g\tChange GID to the numeric value of group.\n"
|
||||||
"\t-a\tSet an optional name of this daemon instance which will be part of every JSON message.\n"
|
"\t-a\tSet an alias name of this daemon instance which will be part of every JSON message.\n"
|
||||||
|
"\t \tThis value is required for correct flow handling of multiple instances and should be unique.\n"
|
||||||
|
"\t \tDefaults to your hostname.\n"
|
||||||
"\t-o\t(Carefully) Tune some daemon options. See subopts below.\n\n";
|
"\t-o\t(Carefully) Tune some daemon options. See subopts below.\n\n";
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "hi:IEP:lc:dp:u:g:a:o:")) != -1)
|
while ((opt = getopt(argc, argv, "hi:IEP:lc:dp:u:g:a:o:")) != -1)
|
||||||
@@ -2688,6 +2687,22 @@ static int validate_options(char const * const arg0)
|
|||||||
{
|
{
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
|
if (instance_alias == NULL) {
|
||||||
|
char hname[256];
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
if (gethostname(hname, sizeof(hname)) != 0) {
|
||||||
|
fprintf(stderr, "%s: Could not retrieve your hostname: %s\n", arg0, strerror(errno));
|
||||||
|
retval = 1;
|
||||||
|
} else {
|
||||||
|
instance_alias = strdup(hname);
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: No instance alias given, using your hostname '%s'\n", arg0, instance_alias);
|
||||||
|
if (instance_alias == NULL) {
|
||||||
|
retval = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (max_flows_per_thread < 128 || max_flows_per_thread > nDPId_MAX_FLOWS_PER_THREAD)
|
if (max_flows_per_thread < 128 || max_flows_per_thread > nDPId_MAX_FLOWS_PER_THREAD)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
|||||||
Reference in New Issue
Block a user