<commit_before>"""
This module provides a wrapper around the ping module but adds the ability to scan network ranges.
"""
import os
import re
import zipimport

from . import ping

# This will import the ipaddress library from the modular input library
# Note that the normal import from a zip file didn't work for me on all platforms (Windows and
# Linux) since it wouldn't import sub-modules (like modular_input.contrib). Thus, I had to rely on
# the zipimport method instead. See https://lukemurphey.net/issues/2173
path_to_mod_input_lib = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../modular_input.zip')
importer = zipimport.zipimporter(path_to_mod_input_lib)
modular_input = importer.load_module('modular_input')
ipaddress = modular_input.contrib.ipaddress

DOMAIN_NAME_RE = re.compile('^((?!-))(xn--)?[a-z0-9][a-z0-9-_]{0,61}[a-z0-9]{0,1}\.(xn--)?([a-z0-9\-]{1,61}|[a-z0-9-]{1,30}\.[a-z]{2,})$')

def ping_all(dest, count=1, index=None, sourcetype="ping", source="ping_search_command", logger=None, callback=None):
    """
    Pings the host using the native ping command on the platform and returns a tuple consisting of:

     1) the output string
     2) the return code (0 is the expected return code)
     3) parsed output from the ping command
    """
    results = []

    # Convert the entry to unicode since 
    dest = unicode(dest)

    # Treat this as a domain if it appears to be a domain name
    if DOMAIN_NAME_RE.match(dest):
        _, return_code, result = ping(str(dest), count, sourcetype=sourcetype, source=source, index=index, logger=logger)

        result['return_code'] = return_code

        if callback:
            callback(result)

        results.append(result)

    # Treat this as an IP address otherwise
    else:
        # Parse the ipaddress if necessary
        dest_network = ipaddress.ip_network(dest, strict=False)

        if dest_network.num_addresses == 1:
            _, return_code, result = ping(str(dest_network.network_address), count, index=index, logger=logger)

            result['return_code'] = return_code

            if callback:
                callback(result)

            results.append(result)
        elif dest_network.num_addresses >= 100:
            raise Exception("The number of addresses to ping must be less than 100 but the count requested was %s" % dest_network.num_addresses)
        else:
            for next_dest in dest_network.hosts():
                _, return_code, result = ping(str(next_dest), count, index=index, logger=logger)
                result['return_code'] = return_code

                if callback:
                    callback(result)

                results.append(result)

    return results<commit_msg>Fixing issue where ping search command is overly aggressive<commit_after>"""
This module provides a wrapper around the ping module but adds the ability to scan network ranges.
"""
import os
import re
import zipimport

from . import ping

# This will import the ipaddress library from the modular input library
# Note that the normal import from a zip file didn't work for me on all platforms (Windows and
# Linux) since it wouldn't import sub-modules (like modular_input.contrib). Thus, I had to rely on
# the zipimport method instead. See https://lukemurphey.net/issues/2173
path_to_mod_input_lib = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../modular_input.zip')
importer = zipimport.zipimporter(path_to_mod_input_lib)
modular_input = importer.load_module('modular_input')
ipaddress = modular_input.contrib.ipaddress

DOMAIN_NAME_RE = re.compile('^((?!-))(xn--)?[a-z0-9][a-z0-9-_]{0,61}[a-z0-9]{0,1}\.(xn--)?([a-z0-9\-]{1,61}|[a-z0-9-]{1,30}\.[a-z]{2,})$')

def ping_all(dest, count=1, index=None, sourcetype="ping", source="ping_search_command", logger=None, callback=None):
    """
    Pings the host using the native ping command on the platform and returns a tuple consisting of:

     1) the output string
     2) the return code (0 is the expected return code)
     3) parsed output from the ping command
    """
    results = []

    # Convert the entry to unicode since 
    dest = unicode(dest)

    # Try to treat this as an IP address by default
    try:
        # Parse the ipaddress if necessary
        dest_network = ipaddress.ip_network(dest, strict=False)

        if dest_network.num_addresses == 1:
            _, return_code, result = ping(str(dest_network.network_address), count, index=index, logger=logger)

            result['return_code'] = return_code

            if callback:
                callback(result)

            results.append(result)
        elif dest_network.num_addresses >= 100:
            raise Exception("The number of addresses to ping must be less than 100 but the count requested was %s" % dest_network.num_addresses)
        else:
            for next_dest in dest_network.hosts():
                _, return_code, result = ping(str(next_dest), count, index=index, logger=logger)
                result['return_code'] = return_code

                if callback:
                    callback(result)

                results.append(result)
    except ValueError:
        # Otherwise, treat this as a domain if it appears to be a domain name
        _, return_code, result = ping(str(dest), count, sourcetype=sourcetype, source=source, index=index, logger=logger)

        result['return_code'] = return_code

        if callback:
            callback(result)

        results.append(result)

    return results
{'fraction_non_alphanumeric': 0.10332908859377843, 'fraction_numerical': 0.013825723121702747, 'mean_word_length': 3.063562453806356, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2127553', 'n_tokens_mistral': 1687, 'n_tokens_neox': 1578, 'n_words': 497}