コード例 #1
0
def run():
    """
    Main entry point of the application
    """
    version = get_version()
    args = parse_arguments()

    IO.initialize(args.colorless)
    IO.print(get_main_banner(version))

    if not is_linux():
        IO.error('run under linux.')
        return

    if not is_privileged():
        IO.error('run as root.')
        return

    args = process_arguments(args)

    if args is None:
        return
    
    if initialize(args.interface):
        IO.spacer()        
        menu = MainMenu(version, args.interface, args.gateway_ip, args.gateway_mac, args.netmask)
        menu.start()
        cleanup(args.interface)
コード例 #2
0
ファイル: main_menu.py プロジェクト: DSlite/FP-IDS
    def _hosts_handler(self, args):
        """
        Handles 'hosts' command-line argument
        Displays discovered hosts
        """
        table_data = [[
            '{}ID{}'.format(IO.Style.BRIGHT, IO.Style.RESET_ALL),
            '{}IP address{}'.format(IO.Style.BRIGHT, IO.Style.RESET_ALL),
            '{}MAC address{}'.format(IO.Style.BRIGHT, IO.Style.RESET_ALL),
            '{}Hostname{}'.format(IO.Style.BRIGHT, IO.Style.RESET_ALL),
            '{}Status{}'.format(IO.Style.BRIGHT, IO.Style.RESET_ALL)
        ]]

        with self.hosts_lock:
            for host in self.hosts:
                table_data.append([
                    '{}{}{}'.format(IO.Fore.LIGHTYELLOW_EX,
                                    self._get_host_id(host, lock=False),
                                    IO.Style.RESET_ALL), host.ip, host.mac,
                    host.name,
                    host.pretty_status()
                ])

        table = SingleTable(table_data, 'Hosts')

        if not args.force and not table.ok:
            IO.error(
                'table does not fit terminal. resize or decrease font size. you can also force the display (--force).'
            )
            return

        IO.spacer()
        IO.print(table.table)
        IO.spacer()
コード例 #3
0
ファイル: main_menu.py プロジェクト: DSlite/FP-IDS
    def _limit_handler(self, args):
        """
        Handles 'limit' command-line argument
        Limits bandwith of host to specified rate
        """
        hosts = self._get_hosts_by_ids(args.id)
        if hosts is None or len(hosts) == 0:
            return

        try:
            rate = BitRate.from_rate_string(args.rate)
        except Exception:
            IO.error('limit rate is invalid.')
            return

        direction = self._parse_direction_args(args)
        discordText = "```"

        for host in hosts:
            self.arp_spoofer.add(host)
            self.limiter.limit(host, direction, rate)
            self.bandwidth_monitor.add(host)

            IO.ok('{}{}{r} {} {}limited{r} to {}.'.format(
                IO.Fore.LIGHTYELLOW_EX,
                host.ip,
                Direction.pretty_direction(direction),
                IO.Fore.LIGHTRED_EX,
                rate,
                r=IO.Style.RESET_ALL))
            discordText += '{} pada IP {} dilimit menjadi {}\n'.format(
                Direction.pretty_direction(direction), host.ip, rate)

        discordText += '```'
        IO.discord(discordText)
コード例 #4
0
ファイル: main_menu.py プロジェクト: DSlite/FP-IDS
    def _scan_handler(self, args):
        """
        Handles 'scan' command-line argument
        (Re)scans for hosts on the network
        """
        if args.iprange:
            iprange = self._parse_iprange(args.iprange)
            if iprange is None:
                IO.error('invalid ip range.')
                return
        else:
            iprange = None

        with self.hosts_lock:
            for host in self.hosts:
                self._free_host(host)

        IO.spacer()
        IO.discord("Scanning...")
        hosts = self.host_scanner.scan(iprange)

        hosts = [host for host in hosts if host not in self.hosts]

        self.hosts_lock.acquire()
        self.hosts += hosts
        self.hosts_lock.release()

        IO.ok('{}{}{} hosts discovered.'.format(IO.Fore.LIGHTYELLOW_EX,
                                                len(hosts),
                                                IO.Style.RESET_ALL))
        IO.spacer()
        IO.discord("{} hosts terdeteksi".format(len(hosts)))
コード例 #5
0
    def _hosts_handler(self, args):
        """
        Handles 'hosts' command-line argument
        Displays discovered hosts
        """
        table_data = [[
            '{}ID{}'.format(IO.Style.BRIGHT, IO.Style.RESET_ALL),
            '{}IP-Address{}'.format(IO.Style.BRIGHT, IO.Style.RESET_ALL),
            '{}MAC-Address{}'.format(IO.Style.BRIGHT, IO.Style.RESET_ALL),
            '{}Hostname{}'.format(IO.Style.BRIGHT, IO.Style.RESET_ALL),
            '{}Status{}'.format(IO.Style.BRIGHT, IO.Style.RESET_ALL)
        ]]

        for i, host in enumerate(self.hosts):
            table_data.append([
                '{}{}{}'.format(IO.Fore.LIGHTYELLOW_EX, i, IO.Style.RESET_ALL),
                host.ip, host.mac, host.name if host.name is not None else '',
                host.pretty_status()
            ])

        table = SingleTable(table_data, 'Hosts')

        if not table.ok:
            IO.error(
                'table does not fit terminal. resize or decrease font size.')
            return

        IO.spacer()
        IO.print(table.table)
        IO.spacer()
コード例 #6
0
ファイル: main_menu.py プロジェクト: sohambakore/evillimiter
    def _limit_handler(self, args):
        """
        Handles 'limit' command-line argument
        Limits bandwith of host to specified rate
        """
        hosts = self._get_hosts_by_ids(args.id)
        rate = NetRate(args.rate)
        direction = self._parse_direction_args(args)

        if not rate.is_valid():
            IO.error('limit rate is invalid.')
            return

        if hosts is not None and len(hosts) > 0:
            for host in hosts:
                if not host.spoofed:
                    self.arp_spoofer.add(host)
                self.limiter.limit(host, direction, rate)

                IO.ok('{}{}{r} {} {}limited{r} to {}.'.format(
                    IO.Fore.LIGHTYELLOW_EX,
                    host.ip,
                    Direction.pretty_direction(direction),
                    IO.Fore.LIGHTRED_EX,
                    rate,
                    r=IO.Style.RESET_ALL))
コード例 #7
0
    def _scan_handler(self, args):
        """
        Handles 'scan' command-line argument
        (Re)scans for hosts on the network
        """
        if args.iprange:
            try:
                if '-' in args.iprange:
                    iprange = list(
                        netaddr.iter_iprange(*args.iprange.split('-')))
                else:
                    iprange = list(netaddr.IPNetwork(args.iprange))
            except netaddr.core.AddrFormatError:
                IO.error('ip range invalid.')
                return
        else:
            iprange = None

        for host in self.hosts:
            self._free_host(host)

        IO.spacer()

        self.hosts = self.host_scanner.scan(iprange)

        IO.ok('{}{}{} hosts discovered.'.format(IO.Fore.LIGHTYELLOW_EX,
                                                len(self.hosts),
                                                IO.Style.RESET_ALL))
        IO.spacer()
コード例 #8
0
ファイル: evillimiter.py プロジェクト: u53r55/evillimiter
def process_arguments(args):
    """
    Processes the specified command-line arguments, adds them to a named tuple
    and returns.
    Executes actions specified in the command line, e.g. flush network settings
    """
    if args.interface is None:
        interface = netutils.get_default_interface()
        if interface is None:
            IO.error('default interface could not be resolved. specify manually (-i).')
            return
    else:
        interface = args.interface
        if not netutils.exists_interface(interface):
            IO.error('interface {}{}{} does not exist.'.format(IO.Fore.LIGHTYELLOW_EX, interface, IO.Style.RESET_ALL))
            return

    IO.ok('interface: {}{}{}'.format(IO.Fore.LIGHTYELLOW_EX, interface, IO.Style.RESET_ALL))

    if args.gateway is None:
        gateway_ip = netutils.get_default_gateway()
        if gateway_ip is None:
            IO.error('default gateway address could not be resolved. specify manually (-g).')
            return
    else:
        gateway_ip = args.gateway

    IO.ok('gateway ip: {}{}{}'.format(IO.Fore.LIGHTYELLOW_EX, gateway_ip, IO.Style.RESET_ALL))

    gateway_mac = netutils.get_mac_by_ip(interface, gateway_ip)
    if gateway_mac is None:
        IO.error('gateway mac address could not be resolved.')
        return

    IO.ok('gateway mac: {}{}{}'.format(IO.Fore.LIGHTYELLOW_EX, gateway_mac, IO.Style.RESET_ALL))

    if args.netmask is None:
        netmask = netutils.get_default_netmask(interface)
        if netmask is None:
            IO.error('netmask could not be resolved. specify manually (-n).')
            return
    else:
        netmask = args.netmask

    IO.ok('netmask: {}{}{}'.format(IO.Fore.LIGHTYELLOW_EX, netmask, IO.Style.RESET_ALL))

    if args.flush:
        netutils.flush_network_settings(interface)
        IO.spacer()
        IO.ok('flushed network settings')

    return InitialArguments(interface=interface, gateway_ip=gateway_ip, gateway_mac=gateway_mac, netmask=netmask)
コード例 #9
0
    def _add_handler(self, args):
        """
        Handles 'add' command-line argument
        Adds custom host to host list
        """
        ip = args.ip
        if not netutils.validate_ip_address(ip):
            IO.error('invalid ip address.')
            return

        if args.mac:
            mac = args.mac
            if not netutils.validate_mac_address(mac):
                IO.error('invalid mac address.')
                return
        else:
            mac = netutils.get_mac_by_ip(self.interface, ip)
            if mac is None:
                IO.error('unable to resolve mac address. specify manually (--mac).')
                return

        name = None
        try:
            host_info = socket.gethostbyaddr(ip)
            name = None if host_info is None else host_info[0]
        except socket.herror:
            pass

        host = Host(ip, mac, name)
        if host in self.hosts:
            IO.error('host does already exist.')
            return

        self.hosts.append(host)   
        IO.ok('host added.') 
コード例 #10
0
ファイル: main_menu.py プロジェクト: willyrgf/evillimiter
    def _get_host_by_id(self, id_):
        try:
            identifier = int(id_)
        except ValueError:
            IO.error('identifier is not an integer.')
            return

        if len(self.hosts) == 0 or identifier not in range(len(self.hosts)):
            IO.error('no host with id {}{}{}.'.format(IO.Fore.LIGHTYELLOW_EX,
                                                      identifier,
                                                      IO.Style.RESET_ALL))
            return

        return self.hosts[identifier]
コード例 #11
0
def initialize(interface):
    """
    Sets up requirements, e.g. IP-Forwarding, 3rd party applications
    """
    if not netutils.create_qdisc_root(interface):
        IO.spacer()
        IO.error('qdisc root handle could not be created. maybe flush network settings (--flush).')
        return False

    if not netutils.enable_ip_forwarding():
        IO.spacer()
        IO.error('ip forwarding could not be enabled.')
        return False

    return True
コード例 #12
0
    def _limit_handler(self, args):
        """
        Handles 'limit' command-line argument
        Limits bandwith of host to specified rate
        """
        hosts = self._get_hosts_by_ids(args.id)
        rate = args.rate

        if hosts is not None and len(hosts) > 0:
            for host in hosts:
                if not host.spoofed:
                    self.arp_spoofer.add(host)

                if netutils.validate_netrate_string(rate):
                    self.limiter.limit(host, rate)
                else:
                    IO.error('limit rate is invalid.')
                    return
                
                IO.ok('{}{}{} limited{} to {}.'.format(IO.Fore.LIGHTYELLOW_EX, host.ip, IO.Fore.LIGHTRED_EX, IO.Style.RESET_ALL, rate))
コード例 #13
0
    def _get_hosts_by_ids(self, ids_string):
        if ids_string == 'all':
            return self.hosts.copy()

        try:
            ids = [int(x) for x in ids_string.split(',')]
        except ValueError:
            IO.error('\'{}\' are invalid IDs.'.format(ids_string))
            return

        hosts = []

        for id_ in ids:
            if len(self.hosts) == 0 or id_ not in range(len(self.hosts)):
                IO.error('no host with id {}{}{}.'.format(
                    IO.Fore.LIGHTYELLOW_EX, id_, IO.Style.RESET_ALL))
                return
            if self.hosts[id_] not in hosts:
                hosts.append(self.hosts[id_])

        return hosts
コード例 #14
0
    def _get_hosts_by_ids(self, ids_string):
        if ids_string == 'all':
            return self.hosts.copy()

        ids = ids_string.split(',')
        hosts = set()

        for id_ in ids:
            is_mac = netutils.validate_mac_address(id_)
            is_ip = netutils.validate_ip_address(id_)
            is_id_ = id_.isdigit()

            if not is_mac and not is_ip and not is_id_:
                IO.error('invalid identifier(s): \'{}\'.'.format(ids_string))
                return

            if is_mac or is_ip:
                found = False
                for host in self.hosts:
                    if host.mac == id_.lower() or host.ip == id_:
                        found = True
                        hosts.add(host)
                        break
                if not found:
                    IO.error('no host matching {}{}{}.'.format(IO.Fore.LIGHTYELLOW_EX, id_, IO.Style.RESET_ALL))
                    return
            else:
                id_ = int(id_)
                if len(self.hosts) == 0 or id_ not in range(len(self.hosts)):
                    IO.error('no host with id {}{}{}.'.format(IO.Fore.LIGHTYELLOW_EX, id_, IO.Style.RESET_ALL))
                    return
                hosts.add(self.hosts[id_])

        return hosts
コード例 #15
0
ファイル: main_menu.py プロジェクト: DSlite/FP-IDS
 def _watch_set_handler(self, args):
     """
     Handles 'watch set' command-line argument
     Modifies settings of the reconnection reconnection watcher
     """
     if args.attribute.lower() in ('range', 'iprange', 'ip_range'):
         iprange = self._parse_iprange(args.value)
         if iprange is not None:
             self.host_watcher.iprange = iprange
         else:
             IO.error('invalid ip range.')
     elif args.attribute.lower() in ('interval'):
         if args.value.isdigit():
             self.host_watcher.interval = int(args.value)
         else:
             IO.error('invalid interval.')
     else:
         IO.error('{}{}{} is an invalid settings attribute.'.format(
             IO.Fore.LIGHTYELLOW_EX, args.attribute, IO.Style.RESET_ALL))
コード例 #16
0
    def parse(self, command):
        """
        Parses a given list of arguments
        """
        names = [
            x.name for x in (self._flag_commands + self._parameter_commands)
        ]
        result_dict = dict.fromkeys(names, None)

        # indicates whether or not to skip the next command argument
        skip_next = False

        for i, arg in enumerate(command):
            if skip_next:
                skip_next = False
                continue

            if i == 0:
                # check if the first argument is a subparser
                for sp in self._subparsers:
                    if sp.identifier == arg:
                        # if subparser present, parse arguments there
                        result = sp.subparser.parse(command[(i + 1):])
                        if result is not None and sp.handler is not None:
                            # call the subparser's handler if available
                            sp.handler(result)

                        return result

            # indicates whether or not the argument has been processed
            is_arg_processed = False

            for cmd in self._flag_commands:
                if cmd.identifier == arg:
                    if cmd.type == CommandParser.CommandType.FLAG_COMMAND:
                        # if its a flag, set the flag to true
                        result_dict[cmd.name] = True
                        is_arg_processed = True
                        break
                    elif cmd.type == CommandParser.CommandType.PARAMETERIZED_FLAG_COMMAND:
                        if (len(command) - 1) < (i + 1):
                            # no more command arguments to process
                            IO.error(
                                'parameter for flag {}{}{} is missing'.format(
                                    IO.Fore.LIGHTYELLOW_EX, cmd.name,
                                    IO.Style.RESET_ALL))
                            return

                        # if parameterized flag, set value to next argument
                        value = command[i + 1]
                        result_dict[cmd.name] = value

                        # skip the next argument (already processed)
                        skip_next = True

                        is_arg_processed = True
                        break

            if not is_arg_processed:
                for cmd in self._parameter_commands:
                    # parameter command, since a flag could not be found
                    if result_dict[cmd.name] is None:
                        # set parameter value
                        result_dict[cmd.name] = arg
                        is_arg_processed = True
                        break

            if not is_arg_processed:
                IO.error('{}{}{} is an unknown command.'.format(
                    IO.Fore.LIGHTYELLOW_EX, arg, IO.Style.RESET_ALL))
                return

        # check if there are any parameters missing
        for cmd in self._parameter_commands:
            if result_dict[cmd.name] is None:
                IO.error('parameter {}{}{} is missing'.format(
                    IO.Fore.LIGHTYELLOW_EX, cmd.name, IO.Style.RESET_ALL))
                return

        # set unspecified flags to False instead of None
        for cmd in self._flag_commands:
            if cmd.type == CommandParser.CommandType.FLAG_COMMAND:
                if result_dict[cmd.name] is None:
                    result_dict[cmd.name] = False

        result_tuple = collections.namedtuple('ParseResult',
                                              sorted(result_dict))
        return result_tuple(**result_dict)
コード例 #17
0
ファイル: main_menu.py プロジェクト: DSlite/FP-IDS
    def _auto_handler(self, args):
        def get_bandwidth_results():
            with self.hosts_lock:
                return [
                    x for x in [(y, self.bandwidth_monitor.get(y))
                                for y in self.hosts] if x[1] is not None
                ]

        def display(stdscr, interval):
            host_results = get_bandwidth_results()
            hname_max_len = max([len(x[0].name) for x in host_results])

            header_off = [('ID', 5), ('IP address', 18),
                          ('Hostname', hname_max_len + 2), ('Status', 8),
                          ('Current (per s)', 20), ('Total', 16),
                          ('Packets', 0)]

            y_rst = 1
            x_rst = 2

            while True:
                y_off = y_rst
                x_off = x_rst

                stdscr.clear()

                for header in header_off:
                    stdscr.addstr(y_off, x_off, header[0])
                    x_off += header[1]

                y_off += 2
                x_off = x_rst

                for host, result in host_results:
                    if not host.limited and int(
                            ValueConverter.byte_to_bit(
                                result.download_total_size.value)
                    ) > max_bit.rate:
                        IO.discord("""```
IP: {}
MAC: {}
NAME: {}
Dilimit menjadi {} karena melebihi batas maksimum {}```
                        """.format(host.ip, host.mac, host.name, rate,
                                   max_bit))
                        self.limiter.limit(host, 3, rate)

                    result_data = [
                        str(self._get_host_id(host)), host.ip, host.name,
                        "Limited" if host.limited else "Free",
                        '{}↑ {}↓'.format(result.upload_rate,
                                         result.download_rate),
                        '{}↑ {}↓'.format(result.upload_total_size,
                                         result.download_total_size),
                        '{}↑ {}↓'.format(result.upload_total_count,
                                         result.download_total_count)
                    ]

                    for j, string in enumerate(result_data):
                        stdscr.addstr(y_off, x_off, string)
                        x_off += header_off[j][1]

                    y_off += 1
                    x_off = x_rst

                y_off += 2
                stdscr.addstr(y_off, x_off, 'press \'ctrl+c\' to exit.')

                try:
                    stdscr.refresh()
                    time.sleep(interval)
                    host_results = get_bandwidth_results()
                except KeyboardInterrupt:
                    IO.discord("Monitoring dihentikan...")
                    for host in hosts:
                        self._free_host(host)
                    return

        hosts = self._get_hosts_by_ids("all")

        if hosts is not None and len(hosts) > 0:
            for host in hosts:
                self._free_host(host)
                self.arp_spoofer.add(host)
                self.bandwidth_monitor.add(host)
                self.host_watcher.add(host)
        else:
            IO.error("no hosts to be monitored")
            return

        try:
            max_bit = BitRate.from_rate_string(args.maximum)
            rate = BitRate.from_rate_string(args.rate)
        except Exception:
            IO.error('maximum bit is invalid.')
            return

        interval = 0.5  # in s
        if args.interval:
            if not args.interval.isdigit():
                IO.error('invalid interval.')
                return

            interval = int(args.interval) / 1000  # from ms to s

        try:
            IO.discord(
                "Melakukan monitoring pada sistem...\nLimit host menjadi **{}** jika melebihi batas maksimum **{}**"
                .format(args.rate, args.maximum))
            curses.wrapper(display, interval)
        except curses.error:
            IO.error('monitor error occurred. maybe terminal too small?')
コード例 #18
0
ファイル: main_menu.py プロジェクト: DSlite/FP-IDS
    def _analyze_handler(self, args):
        hosts = self._get_hosts_by_ids(args.id)
        if hosts is None or len(hosts) == 0:
            IO.error('no hosts to be analyzed.')
            return

        duration = 30  # in s
        if args.duration:
            if not args.duration.isdigit():
                IO.error('invalid duration.')
                return

            duration = int(args.duration)

        hosts_to_be_freed = set()
        host_values = {}

        for host in hosts:
            if not host.spoofed:
                hosts_to_be_freed.add(host)

            self.arp_spoofer.add(host)
            self.bandwidth_monitor.add(host)

            host_result = self.bandwidth_monitor.get(host)
            host_values[host] = {}
            host_values[host]['prev'] = (host_result.upload_total_size,
                                         host_result.download_total_size)

        IO.ok('analyzing traffic for {}s.'.format(duration))
        time.sleep(duration)

        error_occurred = False
        for host in hosts:
            host_result = self.bandwidth_monitor.get(host)

            if host_result is None:
                # host reconnected during analysis
                IO.error('host reconnected during analysis.')
                error_occurred = True
            else:
                host_values[host]['current'] = (
                    host_result.upload_total_size,
                    host_result.download_total_size)

        IO.ok('cleaning up...')
        for host in hosts_to_be_freed:
            self._free_host(host)

        if error_occurred:
            return

        upload_chart = BarChart(max_bar_length=29)
        download_chart = BarChart(max_bar_length=29)

        for host in hosts:
            upload_value = host_values[host]['current'][0] - host_values[host][
                'prev'][0]
            download_value = host_values[host]['current'][1] - host_values[
                host]['prev'][1]

            prefix = '{}{}{} ({}, {})'.format(IO.Fore.LIGHTYELLOW_EX,
                                              self._get_host_id(host),
                                              IO.Style.RESET_ALL, host.ip,
                                              host.name)

            upload_chart.add_value(upload_value.value, prefix, upload_value)
            download_chart.add_value(download_value.value, prefix,
                                     download_value)

        upload_table = SingleTable([[upload_chart.get()]], 'Upload')
        download_table = SingleTable([[download_chart.get()]], 'Download')

        upload_table.inner_heading_row_border = False
        download_table.inner_heading_row_border = False

        IO.spacer()
        IO.print(upload_table.table)
        IO.print(download_table.table)
        IO.spacer()
コード例 #19
0
def locate_bin(name):
    try:
        return output_suppressed('which {}'.format(name)).replace('\n', '')
    except subprocess.CalledProcessError:
        IO.error('missing util: {}, check your PATH'.format(name))
コード例 #20
0
ファイル: main_menu.py プロジェクト: yotabits/evillimiter
    def _monitor_handler(self, args):
        """
        Handles 'monitor' command-line argument
        Monitors hosts bandwidth usage
        """
        def get_bandwidth_results():
            return [
                x for x in [(y, self.bandwidth_monitor.get(y))
                            for y in self.hosts] if x[1] is not None
            ]

        def display(stdscr, interval):
            host_results = get_bandwidth_results()
            hname_max_len = max([len(x[0].name) for x in host_results])

            header_off = [('ID', 5), ('IP-Address', 18),
                          ('Hostname', hname_max_len + 2),
                          ('Current (per s)', 20), ('Total', 16),
                          ('Packets', 0)]

            y_rst = 1
            x_rst = 2

            while True:
                y_off = y_rst
                x_off = x_rst

                stdscr.clear()

                for header in header_off:
                    stdscr.addstr(y_off, x_off, header[0])
                    x_off += header[1]

                y_off += 2
                x_off = x_rst

                for i, (host, result) in enumerate(host_results):
                    result_data = [
                        str(i), host.ip, host.name,
                        '{}↑ {}↓'.format(result.upload_rate,
                                         result.download_rate),
                        '{}↑ {}↓'.format(result.upload_total_size,
                                         result.download_total_size),
                        '{}↑ {}↓'.format(result.upload_total_count,
                                         result.download_total_count)
                    ]

                    for j, string in enumerate(result_data):
                        stdscr.addstr(y_off, x_off, string)
                        x_off += header_off[j][1]

                    y_off += 1
                    x_off = x_rst

                y_off += 2
                stdscr.addstr(y_off, x_off, 'press \'ctrl+c\' to exit.')

                try:
                    stdscr.refresh()
                    time.sleep(interval)
                    host_results = get_bandwidth_results()
                except KeyboardInterrupt:
                    return

        interval = 0.5  # in s
        if args.interval:
            if not args.interval.isdigit():
                IO.error('invalid interval.')
                return

            interval = int(args.interval) / 1000  # from ms to s

        if len(get_bandwidth_results()) == 0:
            IO.error('no hosts to be monitored.')
            return

        try:
            curses.wrapper(display, interval)
        except curses.error:
            IO.error('monitor error occurred. maybe terminal too small?')