'The function for retrieving and parsing whois information for an IP
address via port 43/tcp (WHOIS).
Args:
inc_raw: Boolean for whether to include the raw results in the
returned dictionary.
retry_count: The number of times to retry in case socket errors,
timeouts, connection resets, etc. are encountered.
response: Optional response object, this bypasses the Whois lookup.
get_referral: Boolean for whether to retrieve referral whois
information, if available.
extra_blacklist: A list of blacklisted whois servers in addition to
the global BLACKLIST.
ignore_referral_errors: Boolean for whether to ignore and continue
when an exception is encountered on referral whois lookups.
asn_data: Optional ASN result object, this bypasses the ASN lookup.
field_list: If provided, a list of fields to parse:
[\'name\', \'handle\', \'description\', \'country\', \'state\', \'city\',
\'address\', \'postal_code\', \'emails\', \'created\', \'updated\']
is_offline: Boolean for whether to perform lookups offline. If
True, response and asn_data must be provided. Primarily used
for testing.
Returns:
Dictionary:
:query: The IP address (String)
:asn: The Autonomous System Number (String)
:asn_date: The ASN Allocation date (String)
:asn_registry: The assigned ASN registry (String)
:asn_cidr: The assigned ASN CIDR (String)
:asn_country_code: The assigned ASN country code (String)
:nets: Dictionaries containing network information which consists
of the fields listed in the NIC_WHOIS dictionary. (List)
:raw: Raw whois results if the inc_raw parameter is True. (String)
:referral: Dictionary of referral whois information if get_referral
is True and the server isn\'t blacklisted. Consists of fields
listed in the RWHOIS dictionary.
:raw_referral: Raw referral whois results if the inc_raw parameter
is True. (String)'

def lookup(self, inc_raw=False, retry_count=3, response=None, get_referral=False, extra_blacklist=None, ignore_referral_errors=False, asn_data=None, field_list=None, is_offline=False):

    results = {'query': self._net.address_str, 'nets': [], 'raw': None, 'referral': None, 'raw_referral': None}
    referral_server = None
    referral_port = 0
    if ((response is None) or ((not is_offline) and (asn_data['asn_registry'] is not 'arin'))):
        log.debug('Response    not    given,    perform    WHOIS    lookup    for    {0}'.format(self._net.address_str))
        response = self._net.get_whois(asn_registry=asn_data['asn_registry'], retry_count=retry_count, extra_blacklist=extra_blacklist)
        if get_referral:
            for match in re.finditer('^ReferralServer:[^\\S\\n]+(.+:[0-9]+)$', response, re.MULTILINE):
                try:
                    temp = match.group(1)
                    if ('rwhois://' not in temp):
                        raise ValueError
                    temp = temp.replace('rwhois://', '').split(':')
                    if (int(temp[1]) > 65535):
                        raise ValueError
                    referral_server = temp[0]
                    referral_port = int(temp[1])
                except (ValueError, KeyError):
                    continue
                break
    if (get_referral and referral_server):
        log.debug('Perform    referral    WHOIS    lookup')
        response_ref = None
        try:
            response_ref = self._net.get_whois(asn_registry='', retry_count=retry_count, server=referral_server, port=referral_port, extra_blacklist=extra_blacklist)
        except (BlacklistError, WhoisLookupError):
            if ignore_referral_errors:
                pass
            else:
                raise
        if response_ref:
            log.debug('Parsing    referral    WHOIS    data')
            if inc_raw:
                results['raw_referral'] = response_ref
            temp_rnet = self._parse_fields(response_ref, RWHOIS['fields'], field_list=field_list)
            results['referral'] = temp_rnet
    if inc_raw:
        results['raw'] = response
    nets = []
    if (asn_data['asn_registry'] == 'arin'):
        nets_response = self._get_nets_arin(response)
    elif (asn_data['asn_registry'] == 'lacnic'):
        nets_response = self._get_nets_lacnic(response)
    else:
        nets_response = self._get_nets_other(response)
    nets.extend(nets_response)
    log.debug('Parsing    WHOIS    data')
    for (index, net) in enumerate(nets):
        section_end = None
        if ((index + 1) < len(nets)):
            section_end = nets[(index + 1)]['start']
        try:
            dt_format = RIR_WHOIS[results['asn_registry']]['dt_format']
        except KeyError:
            dt_format = None
        temp_net = self._parse_fields(response, RIR_WHOIS[asn_data['asn_registry']]['fields'], section_end, net['end'], dt_format, field_list)
        net.update(temp_net)
        del net['start'], net['end']
    results['nets'] = nets
    return results
